Merge Official Source
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
commit
bae55c0ab3
@ -33,7 +33,7 @@ BPF_TARGET:=bpf$(if $(CONFIG_BIG_ENDIAN),eb,el)
|
|||||||
BPF_HEADERS_DIR:=$(STAGING_DIR)/bpf-headers
|
BPF_HEADERS_DIR:=$(STAGING_DIR)/bpf-headers
|
||||||
|
|
||||||
BPF_KERNEL_INCLUDE := \
|
BPF_KERNEL_INCLUDE := \
|
||||||
-nostdinc -isystem $(TOOLCHAIN_DIR)/include \
|
-nostdinc -isystem $(TOOLCHAIN_INC_DIRS) \
|
||||||
-I$(BPF_HEADERS_DIR)/arch/$(BPF_KARCH)/include \
|
-I$(BPF_HEADERS_DIR)/arch/$(BPF_KARCH)/include \
|
||||||
-I$(BPF_HEADERS_DIR)/arch/$(BPF_KARCH)/include/asm/mach-generic \
|
-I$(BPF_HEADERS_DIR)/arch/$(BPF_KARCH)/include/asm/mach-generic \
|
||||||
-I$(BPF_HEADERS_DIR)/arch/$(BPF_KARCH)/include/generated \
|
-I$(BPF_HEADERS_DIR)/arch/$(BPF_KARCH)/include/generated \
|
||||||
|
@ -22,7 +22,7 @@ HOST_CMAKE_BINARY_DIR = $(HOST_BUILD_DIR)$(if $(CMAKE_BINARY_SUBDIR),/$(CMAKE_BI
|
|||||||
MAKE_PATH = $(firstword $(CMAKE_BINARY_SUBDIR) .)
|
MAKE_PATH = $(firstword $(CMAKE_BINARY_SUBDIR) .)
|
||||||
|
|
||||||
ifeq ($(CONFIG_EXTERNAL_TOOLCHAIN),)
|
ifeq ($(CONFIG_EXTERNAL_TOOLCHAIN),)
|
||||||
cmake_tool=$(TOOLCHAIN_DIR)/bin/$(1)
|
cmake_tool=$(firstword $(TOOLCHAIN_BIN_DIRS))/$(1)
|
||||||
else
|
else
|
||||||
cmake_tool=$(shell command -v $(1))
|
cmake_tool=$(shell command -v $(1))
|
||||||
endif
|
endif
|
||||||
@ -49,7 +49,7 @@ CMAKE_AR:=$(call cmake_tool,$(TARGET_AR))
|
|||||||
CMAKE_NM:=$(call cmake_tool,$(TARGET_NM))
|
CMAKE_NM:=$(call cmake_tool,$(TARGET_NM))
|
||||||
CMAKE_RANLIB:=$(call cmake_tool,$(TARGET_RANLIB))
|
CMAKE_RANLIB:=$(call cmake_tool,$(TARGET_RANLIB))
|
||||||
|
|
||||||
CMAKE_FIND_ROOT_PATH:=$(STAGING_DIR)/usr;$(TOOLCHAIN_DIR)$(if $(CONFIG_EXTERNAL_TOOLCHAIN),;$(CONFIG_TOOLCHAIN_ROOT))
|
CMAKE_FIND_ROOT_PATH:=$(STAGING_DIR)/usr;$(TOOLCHAIN_ROOT_DIR)
|
||||||
CMAKE_HOST_FIND_ROOT_PATH:=$(STAGING_DIR)/host;$(STAGING_DIR_HOSTPKG);$(STAGING_DIR_HOST)
|
CMAKE_HOST_FIND_ROOT_PATH:=$(STAGING_DIR)/host;$(STAGING_DIR_HOSTPKG);$(STAGING_DIR_HOST)
|
||||||
CMAKE_SHARED_LDFLAGS:=-Wl,-Bsymbolic-functions
|
CMAKE_SHARED_LDFLAGS:=-Wl,-Bsymbolic-functions
|
||||||
CMAKE_HOST_INSTALL_PREFIX = $(HOST_BUILD_PREFIX)
|
CMAKE_HOST_INSTALL_PREFIX = $(HOST_BUILD_PREFIX)
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
LINUX_VERSION-6.1 = .57
|
LINUX_VERSION-6.1 = .59
|
||||||
LINUX_KERNEL_HASH-6.1.57 = f9ebfe3ddc5152d87b37e33be30e31875d137433be10a57ce29d2eae7b6e91b1
|
LINUX_KERNEL_HASH-6.1.59 = 627f7724c675036639290fb5c39e3fdeb3d566b80b192c45f4a808ab54c8c0a0
|
||||||
|
@ -108,6 +108,9 @@ define Build/Prepare
|
|||||||
mkdir -p $(PKG_BUILD_DIR)
|
mkdir -p $(PKG_BUILD_DIR)
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
define Build/Quilt
|
||||||
|
endef
|
||||||
|
|
||||||
define Build/Compile/Default
|
define Build/Compile/Default
|
||||||
|
|
||||||
endef
|
endef
|
||||||
|
@ -107,7 +107,7 @@ ucidef_set_bridge_mac() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ucidef_set_network_device_mac() {
|
ucidef_set_network_device_mac() {
|
||||||
json_select_object "network-device"
|
json_select_object "network_device"
|
||||||
json_select_object "${1}"
|
json_select_object "${1}"
|
||||||
json_add_string macaddr "${2}"
|
json_add_string macaddr "${2}"
|
||||||
json_select ..
|
json_select ..
|
||||||
|
61
package/boot/apex/Makefile
Normal file
61
package/boot/apex/Makefile
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
#
|
||||||
|
# Copyright (C) 2006-2023 OpenWrt.org
|
||||||
|
|
||||||
|
include $(TOPDIR)/rules.mk
|
||||||
|
include $(INCLUDE_DIR)/kernel.mk
|
||||||
|
|
||||||
|
PKG_NAME:=apex
|
||||||
|
# This version was created from the stalled and unreleased v1.6.10
|
||||||
|
# with some patches on top.
|
||||||
|
PKG_VERSION:=1.6.10-openwrt
|
||||||
|
PKG_RELEASE:=1
|
||||||
|
|
||||||
|
PKG_SOURCE_PROTO:=git
|
||||||
|
PKG_SOURCE_URL:=https://github.com/linusw/apex.git
|
||||||
|
PKG_SOURCE_VERSION:=483e18aa133d5e25866570c29b124530b2d1e0d3
|
||||||
|
PKG_MIRROR_HASH:=42230bb436f5590447ca55e8befb8927e6ea74c1e6953c043bbbef986c411704
|
||||||
|
|
||||||
|
PKG_TARGETS:=bin
|
||||||
|
PKG_FLAGS:=nonshared
|
||||||
|
PKG_LICENSE:=GPL-2.0
|
||||||
|
PKG_LICENSE_FILES:=COPYING
|
||||||
|
|
||||||
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
|
||||||
|
export GCC_HONOUR_COPTS=s
|
||||||
|
|
||||||
|
define Package/apex
|
||||||
|
SECTION:=boot
|
||||||
|
CATEGORY:=Boot Loaders
|
||||||
|
DEPENDS:=@TARGET_ixp4xx @!IN_SDK
|
||||||
|
DEFAULT:=y
|
||||||
|
TITLE:=Boot loader for NSLU2, FSG3, NAS100D and others
|
||||||
|
endef
|
||||||
|
|
||||||
|
define build_apex
|
||||||
|
$(MAKE) -C $(PKG_BUILD_DIR) \
|
||||||
|
ARCH=arm \
|
||||||
|
$(1)_config
|
||||||
|
$(MAKE) -C $(PKG_BUILD_DIR) \
|
||||||
|
$(TARGET_CONFIGURE_OPTS) \
|
||||||
|
KBUILD_HAVE_NLS=no \
|
||||||
|
ARCH=arm \
|
||||||
|
clean all
|
||||||
|
$(INSTALL_BIN) $(PKG_BUILD_DIR)/apex.bin $(PKG_BUILD_DIR)/out/apex-$(2).bin
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Build/Compile
|
||||||
|
$(INSTALL_DIR) $(PKG_BUILD_DIR)/out
|
||||||
|
$(call build_apex,openwrt-nslu2-armeb,nslu2-armeb)
|
||||||
|
$(call build_apex,openwrt-nslu2-16mb-armeb,nslu2-16mb-armeb)
|
||||||
|
$(call build_apex,openwrt-fsg3-armeb,fsg3-armeb)
|
||||||
|
$(call build_apex,openwrt-nas100d-armeb,nas100d-armeb)
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Build/InstallDev
|
||||||
|
$(INSTALL_DIR) $(STAGING_DIR_IMAGE)/apex
|
||||||
|
$(CP) $(PKG_BUILD_DIR)/out/*.bin $(STAGING_DIR_IMAGE)/apex
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(eval $(call BuildPackage,apex))
|
@ -0,0 +1,47 @@
|
|||||||
|
From 41f225dae30ea6ddcff10f120a9e732f994d3a07 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Nicol=C3=B2=20Veronese?= <nicveronese@gmail.com>
|
||||||
|
Date: Tue, 3 Oct 2023 23:46:52 +0200
|
||||||
|
Subject: [PATCH] spi: mtk_spim: prevent global pll clock override
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
With commit 793e6230118032a099ec42a1ea67f434721edcc0
|
||||||
|
a new system to calculate the SPI clocks has been added.
|
||||||
|
|
||||||
|
Unfortunately, the do_div macro overrides the global
|
||||||
|
priv->pll_clk_rate field. This will cause to have a reduced
|
||||||
|
clock rate on each subsequent SPI call.
|
||||||
|
|
||||||
|
Signed-off-by: Valerio 'ftp21' Mancini <ftp21@ftp21.eu>
|
||||||
|
Signed-off-by: Nicolò Veronese <nicveronese@gmail.com>
|
||||||
|
---
|
||||||
|
drivers/spi/mtk_spim.c | 7 ++++---
|
||||||
|
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/spi/mtk_spim.c
|
||||||
|
+++ b/drivers/spi/mtk_spim.c
|
||||||
|
@@ -409,7 +409,7 @@ static int mtk_spim_transfer_wait(struct
|
||||||
|
{
|
||||||
|
struct udevice *bus = dev_get_parent(slave->dev);
|
||||||
|
struct mtk_spim_priv *priv = dev_get_priv(bus);
|
||||||
|
- u32 sck_l, sck_h, clk_count, reg;
|
||||||
|
+ u32 pll_clk, sck_l, sck_h, clk_count, reg;
|
||||||
|
ulong us = 1;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
@@ -418,11 +418,12 @@ static int mtk_spim_transfer_wait(struct
|
||||||
|
else
|
||||||
|
clk_count = op->data.nbytes;
|
||||||
|
|
||||||
|
+ pll_clk = priv->pll_clk_rate;
|
||||||
|
sck_l = readl(priv->base + SPI_CFG2_REG) >> SPI_CFG2_SCK_LOW_OFFSET;
|
||||||
|
sck_h = readl(priv->base + SPI_CFG2_REG) & SPI_CFG2_SCK_HIGH_MASK;
|
||||||
|
- do_div(priv->pll_clk_rate, sck_l + sck_h + 2);
|
||||||
|
+ do_div(pll_clk, sck_l + sck_h + 2);
|
||||||
|
|
||||||
|
- us = CLK_TO_US(priv->pll_clk_rate, clk_count * 8);
|
||||||
|
+ us = CLK_TO_US(pll_clk, clk_count * 8);
|
||||||
|
us += 1000 * 1000; /* 1s tolerance */
|
||||||
|
|
||||||
|
if (us > UINT_MAX)
|
@ -259,7 +259,7 @@
|
|||||||
+bootmenu_0=Startup system (Default).=run boot_system
|
+bootmenu_0=Startup system (Default).=run boot_system
|
||||||
+bootmenu_1=Load Firmware via TFTP then write to eMMC.=run boot_tftp_firmware ; run bootmenu_confirm_return
|
+bootmenu_1=Load Firmware via TFTP then write to eMMC.=run boot_tftp_firmware ; run bootmenu_confirm_return
|
||||||
+bootmenu_2=Load BL31+U-Boot FIP via TFTP then write to eMMC.=run boot_tftp_write_fip ; run bootmenu_confirm_return
|
+bootmenu_2=Load BL31+U-Boot FIP via TFTP then write to eMMC.=run boot_tftp_write_fip ; run bootmenu_confirm_return
|
||||||
+bootmenu_3=mLoad BL2 preloader via TFTP then write to eMMC.=run boot_tftp_write_bl2 ; run bootmenu_confirm_return
|
+bootmenu_3=Load BL2 preloader via TFTP then write to eMMC.=run boot_tftp_write_bl2 ; run bootmenu_confirm_return
|
||||||
+bootmenu_4=Reboot.=reset
|
+bootmenu_4=Reboot.=reset
|
||||||
+bootmenu_5=Reset all settings to factory defaults.=run reset_factory ; reset
|
+bootmenu_5=Reset all settings to factory defaults.=run reset_factory ; reset
|
||||||
+filesize_to_blk=setexpr cnt $filesize + 0x1ff && setexpr cnt $cnt / 0x200
|
+filesize_to_blk=setexpr cnt $filesize + 0x1ff && setexpr cnt $cnt / 0x200
|
||||||
|
@ -0,0 +1,85 @@
|
|||||||
|
From 1dbc6d3739869af38e6157cd8b9bc4314ca3c9fe Mon Sep 17 00:00:00 2001
|
||||||
|
From: Josua Mayer <josua@solid-run.com>
|
||||||
|
Date: Mon, 18 Jul 2022 20:04:54 +0300
|
||||||
|
Subject: [PATCH 1/2] arm: mvebu: clearfog: read number of ddr channels from
|
||||||
|
tlv data
|
||||||
|
|
||||||
|
Extend the existing tlv vendor extension used for ram size by one byte to
|
||||||
|
also store the number of ddr channels.
|
||||||
|
The length of the tlv entry can indicate whether the new information is
|
||||||
|
present. If not default to single channel.
|
||||||
|
|
||||||
|
Signed-off-by: Josua Mayer <josua@solid-run.com>
|
||||||
|
---
|
||||||
|
board/solidrun/clearfog/clearfog.c | 14 +++++++++++++-
|
||||||
|
board/solidrun/common/tlv_data.c | 7 ++++++-
|
||||||
|
board/solidrun/common/tlv_data.h | 1 +
|
||||||
|
3 files changed, 20 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/board/solidrun/clearfog/clearfog.c b/board/solidrun/clearfog/clearfog.c
|
||||||
|
index 6edb4221551..4f4532b537e 100644
|
||||||
|
--- a/board/solidrun/clearfog/clearfog.c
|
||||||
|
+++ b/board/solidrun/clearfog/clearfog.c
|
||||||
|
@@ -36,7 +36,7 @@ DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
#define BOARD_GPP_POL_LOW 0x0
|
||||||
|
#define BOARD_GPP_POL_MID 0x0
|
||||||
|
|
||||||
|
-static struct tlv_data cf_tlv_data;
|
||||||
|
+static struct tlv_data cf_tlv_data = { 0 };
|
||||||
|
|
||||||
|
static void cf_read_tlv_data(void)
|
||||||
|
{
|
||||||
|
@@ -168,6 +168,18 @@ struct mv_ddr_topology_map *mv_ddr_topology_map_get(void)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ switch (cf_tlv_data.ram_channels) {
|
||||||
|
+ default:
|
||||||
|
+ case 1:
|
||||||
|
+ for (uint8_t i = 0; i < 5; i++)
|
||||||
|
+ ifp->as_bus_params[i].cs_bitmask = 0x1;
|
||||||
|
+ break;
|
||||||
|
+ case 2:
|
||||||
|
+ for (uint8_t i = 0; i < 5; i++)
|
||||||
|
+ ifp->as_bus_params[i].cs_bitmask = 0x3;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* Return the board topology as defined in the board code */
|
||||||
|
return &board_topology_map;
|
||||||
|
}
|
||||||
|
diff --git a/board/solidrun/common/tlv_data.c b/board/solidrun/common/tlv_data.c
|
||||||
|
index 11d6e4a1380..cf5824886c3 100644
|
||||||
|
--- a/board/solidrun/common/tlv_data.c
|
||||||
|
+++ b/board/solidrun/common/tlv_data.c
|
||||||
|
@@ -45,9 +45,14 @@ static void parse_tlv_vendor_ext(struct tlvinfo_tlv *tlv_entry,
|
||||||
|
|
||||||
|
if (val[4] != SR_TLV_CODE_RAM_SIZE)
|
||||||
|
return;
|
||||||
|
- if (tlv_entry->length != 6)
|
||||||
|
+ if (tlv_entry->length < 6)
|
||||||
|
return;
|
||||||
|
td->ram_size = val[5];
|
||||||
|
+
|
||||||
|
+ /* extension with additional data field for number of ddr channels */
|
||||||
|
+ if (tlv_entry->length >= 7) {
|
||||||
|
+ td->ram_channels = val[6];
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
static void parse_tlv_data(u8 *eeprom, struct tlvinfo_header *hdr,
|
||||||
|
diff --git a/board/solidrun/common/tlv_data.h b/board/solidrun/common/tlv_data.h
|
||||||
|
index a1432e4b8e1..be3f782ac4a 100644
|
||||||
|
--- a/board/solidrun/common/tlv_data.h
|
||||||
|
+++ b/board/solidrun/common/tlv_data.h
|
||||||
|
@@ -10,6 +10,7 @@ struct tlv_data {
|
||||||
|
/* Store product name of both SOM and carrier */
|
||||||
|
char tlv_product_name[2][32];
|
||||||
|
unsigned int ram_size;
|
||||||
|
+ uint8_t ram_channels;
|
||||||
|
};
|
||||||
|
|
||||||
|
void read_tlv_data(struct tlv_data *td);
|
||||||
|
--
|
||||||
|
2.35.3
|
||||||
|
|
@ -0,0 +1,31 @@
|
|||||||
|
From b1b4941c2e3e16a21dc15604220725cf7f2de7c5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Josua Mayer <josua@solid-run.com>
|
||||||
|
Date: Wed, 20 Jul 2022 19:10:56 +0300
|
||||||
|
Subject: [PATCH 2/2] arm: mvebu: clearfog: support 512MB memory size from tlv
|
||||||
|
eeprom
|
||||||
|
|
||||||
|
Handle 2GBit memory size value "2" from tlv eeprom on ddr
|
||||||
|
initialisation, to support SoMs with 512MB ddr memory.
|
||||||
|
|
||||||
|
Signed-off-by: Josua Mayer <josua@solid-run.com>
|
||||||
|
---
|
||||||
|
board/solidrun/clearfog/clearfog.c | 3 +++
|
||||||
|
1 file changed, 3 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/board/solidrun/clearfog/clearfog.c b/board/solidrun/clearfog/clearfog.c
|
||||||
|
index 4f4532b537e..6fa2fe5fe3e 100644
|
||||||
|
--- a/board/solidrun/clearfog/clearfog.c
|
||||||
|
+++ b/board/solidrun/clearfog/clearfog.c
|
||||||
|
@@ -159,6 +159,9 @@ struct mv_ddr_topology_map *mv_ddr_topology_map_get(void)
|
||||||
|
cf_read_tlv_data();
|
||||||
|
|
||||||
|
switch (cf_tlv_data.ram_size) {
|
||||||
|
+ case 2:
|
||||||
|
+ ifp->memory_size = MV_DDR_DIE_CAP_2GBIT;
|
||||||
|
+ break;
|
||||||
|
case 4:
|
||||||
|
default:
|
||||||
|
ifp->memory_size = MV_DDR_DIE_CAP_4GBIT;
|
||||||
|
--
|
||||||
|
2.35.3
|
||||||
|
|
@ -42,7 +42,7 @@ MAKE_VARS = \
|
|||||||
CROSS_COMPILE="$(TARGET_CROSS)" \
|
CROSS_COMPILE="$(TARGET_CROSS)" \
|
||||||
SAN_CFLAGS="$(TARGET_CFLAGS) $(TARGET_CPPFLAGS)" \
|
SAN_CFLAGS="$(TARGET_CFLAGS) $(TARGET_CPPFLAGS)" \
|
||||||
LDLIBS="$(TARGET_LDFLAGS)" \
|
LDLIBS="$(TARGET_LDFLAGS)" \
|
||||||
TOOLCHAIN_INCLUDE="$(TOOLCHAIN_DIR)/include" \
|
TOOLCHAIN_INCLUDE="$(TOOLCHAIN_INC_DIRS)" \
|
||||||
VMLINUX_BTF="$(LINUX_DIR)/vmlinux"
|
VMLINUX_BTF="$(LINUX_DIR)/vmlinux"
|
||||||
|
|
||||||
MAKE_FLAGS = \
|
MAKE_FLAGS = \
|
||||||
|
@ -37,6 +37,9 @@ endef
|
|||||||
define Build/Configure
|
define Build/Configure
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
define Build/Quilt
|
||||||
|
endef
|
||||||
|
|
||||||
define Build/Compile
|
define Build/Compile
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
@ -523,6 +523,8 @@ define KernelPackage/crypto-lib-chacha20/arm
|
|||||||
FILES:=$(LINUX_DIR)/arch/arm/crypto/chacha-neon.ko
|
FILES:=$(LINUX_DIR)/arch/arm/crypto/chacha-neon.ko
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
KernelPackage/crypto-lib-chacha20/armeb=$(KernelPackage/crypto-lib-chacha20/arm)
|
||||||
|
|
||||||
define KernelPackage/crypto-lib-chacha20/aarch64
|
define KernelPackage/crypto-lib-chacha20/aarch64
|
||||||
KCONFIG+=CONFIG_CRYPTO_CHACHA20_NEON
|
KCONFIG+=CONFIG_CRYPTO_CHACHA20_NEON
|
||||||
FILES+=$(LINUX_DIR)/arch/arm64/crypto/chacha-neon.ko
|
FILES+=$(LINUX_DIR)/arch/arm64/crypto/chacha-neon.ko
|
||||||
@ -616,6 +618,8 @@ define KernelPackage/crypto-lib-poly1305/arm
|
|||||||
FILES:=$(LINUX_DIR)/arch/arm/crypto/poly1305-arm.ko
|
FILES:=$(LINUX_DIR)/arch/arm/crypto/poly1305-arm.ko
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
KernelPackage/crypto-lib-poly1305/armeb=$(KernelPackage/crypto-lib-poly1305/arm)
|
||||||
|
|
||||||
define KernelPackage/crypto-lib-poly1305/aarch64
|
define KernelPackage/crypto-lib-poly1305/aarch64
|
||||||
KCONFIG+=CONFIG_CRYPTO_POLY1305_NEON
|
KCONFIG+=CONFIG_CRYPTO_POLY1305_NEON
|
||||||
FILES:=$(LINUX_DIR)/arch/arm64/crypto/poly1305-neon.ko
|
FILES:=$(LINUX_DIR)/arch/arm64/crypto/poly1305-neon.ko
|
||||||
|
@ -728,6 +728,22 @@ endef
|
|||||||
|
|
||||||
$(eval $(call KernelPackage,rtc-pcf2127))
|
$(eval $(call KernelPackage,rtc-pcf2127))
|
||||||
|
|
||||||
|
define KernelPackage/rtc-r7301
|
||||||
|
SUBMENU:=$(OTHER_MENU)
|
||||||
|
TITLE:=Epson RTC7301 support
|
||||||
|
DEFAULT:=m if ALL_KMODS && RTC_SUPPORT
|
||||||
|
DEPENDS:=+kmod-regmap-mmio
|
||||||
|
KCONFIG:=CONFIG_RTC_DRV_R7301 \
|
||||||
|
CONFIG_RTC_CLASS=y
|
||||||
|
FILES:=$(LINUX_DIR)/drivers/rtc/rtc-r7301.ko
|
||||||
|
AUTOLOAD:=$(call AutoProbe,rtc-r7301)
|
||||||
|
endef
|
||||||
|
|
||||||
|
define KernelPackage/rtc-r7301/description
|
||||||
|
Kernel module for Epson RTC7301 RTC chip
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(eval $(call KernelPackage,rtc-r7301))
|
||||||
|
|
||||||
define KernelPackage/rtc-rs5c372a
|
define KernelPackage/rtc-rs5c372a
|
||||||
SUBMENU:=$(OTHER_MENU)
|
SUBMENU:=$(OTHER_MENU)
|
||||||
@ -780,6 +796,22 @@ endef
|
|||||||
|
|
||||||
$(eval $(call KernelPackage,rtc-s35390a))
|
$(eval $(call KernelPackage,rtc-s35390a))
|
||||||
|
|
||||||
|
define KernelPackage/rtc-x1205
|
||||||
|
SUBMENU:=$(OTHER_MENU)
|
||||||
|
TITLE:=Xicor Intersil X1205
|
||||||
|
DEFAULT:=m if ALL_KMODS && RTC_SUPPORT
|
||||||
|
DEPENDS:=+kmod-i2c-core
|
||||||
|
KCONFIG:=CONFIG_RTC_DRV_X1205 \
|
||||||
|
CONFIG_RTC_CLASS=y
|
||||||
|
FILES:=$(LINUX_DIR)/drivers/rtc/rtc-x1205.ko
|
||||||
|
AUTOLOAD:=$(call AutoProbe,rtc-x1205)
|
||||||
|
endef
|
||||||
|
|
||||||
|
define KernelPackage/rtc-x1205/description
|
||||||
|
Kernel module for Xicor Intersil X1205 I2C RTC chip
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(eval $(call KernelPackage,rtc-x1205))
|
||||||
|
|
||||||
define KernelPackage/mtdtests
|
define KernelPackage/mtdtests
|
||||||
SUBMENU:=$(OTHER_MENU)
|
SUBMENU:=$(OTHER_MENU)
|
||||||
|
@ -31,17 +31,11 @@ endef
|
|||||||
|
|
||||||
GCC_VERSION=$(shell echo "$(CONFIG_GCC_VERSION)" | sed 's/[^0-9.]*\([0-9.]*\).*/\1/')
|
GCC_VERSION=$(shell echo "$(CONFIG_GCC_VERSION)" | sed 's/[^0-9.]*\([0-9.]*\).*/\1/')
|
||||||
|
|
||||||
ifdef CONFIG_TOOLCHAIN_BIN_PATH
|
|
||||||
TOOLCHAIN_BIN_PATH=$(CONFIG_TOOLCHAIN_BIN_PATH)
|
|
||||||
else
|
|
||||||
TOOLCHAIN_BIN_PATH=$(TOOLCHAIN_DIR)/bin
|
|
||||||
endif
|
|
||||||
|
|
||||||
LNX_CONFIG_OPTS = LNX_MAKEOPTS='$(KERNEL_MAKEOPTS)' MODULE_TYPE=KSLIB modules
|
LNX_CONFIG_OPTS = LNX_MAKEOPTS='$(KERNEL_MAKEOPTS)' MODULE_TYPE=KSLIB modules
|
||||||
|
|
||||||
MAKE_FLAGS+= \
|
MAKE_FLAGS+= \
|
||||||
TARGET_NAME=$(CONFIG_TARGET_NAME) \
|
TARGET_NAME=$(CONFIG_TARGET_NAME) \
|
||||||
TOOL_PATH=$(TOOLCHAIN_BIN_PATH) \
|
TOOL_PATH=$(firstword $(TOOLCHAIN_BIN_DIRS)) \
|
||||||
SYS_PATH=$(LINUX_DIR) \
|
SYS_PATH=$(LINUX_DIR) \
|
||||||
TOOLPREFIX=$(TARGET_CROSS) \
|
TOOLPREFIX=$(TARGET_CROSS) \
|
||||||
KVER=$(LINUX_VERSION) \
|
KVER=$(LINUX_VERSION) \
|
||||||
|
@ -55,10 +55,16 @@ $(call Package/libnl/default)
|
|||||||
DEPENDS:=+libnl-route
|
DEPENDS:=+libnl-route
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
define Package/libnl-cli
|
||||||
|
$(call Package/libnl/default)
|
||||||
|
TITLE:=CLI Netlink Library
|
||||||
|
DEPENDS:=+libnl-genl +libnl-nf
|
||||||
|
endef
|
||||||
|
|
||||||
define Package/libnl
|
define Package/libnl
|
||||||
$(call Package/libnl/default)
|
$(call Package/libnl/default)
|
||||||
TITLE:=Full Netlink Library
|
TITLE:=Full Netlink Library
|
||||||
DEPENDS:=+libnl-genl +libnl-route +libnl-nf
|
DEPENDS:=+libnl-genl +libnl-route +libnl-nf +libnl-cli
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/libnl-core/description
|
define Package/libnl-core/description
|
||||||
@ -77,6 +83,10 @@ define Package/libnl-nf/description
|
|||||||
Netfilter Netlink Library Functions
|
Netfilter Netlink Library Functions
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
define Package/libnl-cli/description
|
||||||
|
CLI Netlink Library Functions
|
||||||
|
endef
|
||||||
|
|
||||||
define Package/libnl/description
|
define Package/libnl/description
|
||||||
Socket handling, connection management, sending and receiving of data,
|
Socket handling, connection management, sending and receiving of data,
|
||||||
message construction and parsing, object caching system, etc.
|
message construction and parsing, object caching system, etc.
|
||||||
@ -98,6 +108,7 @@ define Build/InstallDev
|
|||||||
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-genl-3.so $(1)/usr/lib/libnl-genl.so
|
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-genl-3.so $(1)/usr/lib/libnl-genl.so
|
||||||
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-nf-3.so $(1)/usr/lib/libnl-nf.so
|
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-nf-3.so $(1)/usr/lib/libnl-nf.so
|
||||||
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-route-3.so $(1)/usr/lib/libnl-route.so
|
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-route-3.so $(1)/usr/lib/libnl-route.so
|
||||||
|
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-cli-3.so $(1)/usr/lib/libnl-cli.so
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/libnl-core/install
|
define Package/libnl-core/install
|
||||||
@ -120,6 +131,11 @@ define Package/libnl-nf/install
|
|||||||
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-nf-3.so.* $(1)/usr/lib/
|
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-nf-3.so.* $(1)/usr/lib/
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
define Package/libnl-cli/install
|
||||||
|
$(INSTALL_DIR) $(1)/usr/lib
|
||||||
|
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnl-cli-3.so.* $(1)/usr/lib/
|
||||||
|
endef
|
||||||
|
|
||||||
define Package/libnl/install
|
define Package/libnl/install
|
||||||
:
|
:
|
||||||
endef
|
endef
|
||||||
@ -128,4 +144,5 @@ $(eval $(call BuildPackage,libnl-core))
|
|||||||
$(eval $(call BuildPackage,libnl-genl))
|
$(eval $(call BuildPackage,libnl-genl))
|
||||||
$(eval $(call BuildPackage,libnl-route))
|
$(eval $(call BuildPackage,libnl-route))
|
||||||
$(eval $(call BuildPackage,libnl-nf))
|
$(eval $(call BuildPackage,libnl-nf))
|
||||||
|
$(eval $(call BuildPackage,libnl-cli))
|
||||||
$(eval $(call BuildPackage,libnl))
|
$(eval $(call BuildPackage,libnl))
|
||||||
|
@ -454,6 +454,9 @@ define Build/Prepare
|
|||||||
mkdir -p $(PKG_BUILD_DIR)
|
mkdir -p $(PKG_BUILD_DIR)
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
define Build/Quilt
|
||||||
|
endef
|
||||||
|
|
||||||
LIBGCC_A=$(lastword $(wildcard $(TOOLCHAIN_DIR)/lib/gcc/*/*/libgcc_pic.a))
|
LIBGCC_A=$(lastword $(wildcard $(TOOLCHAIN_DIR)/lib/gcc/*/*/libgcc_pic.a))
|
||||||
LIBGCC_MAP=$(lastword $(wildcard $(TOOLCHAIN_DIR)/lib/gcc/*/*/libgcc.map))
|
LIBGCC_MAP=$(lastword $(wildcard $(TOOLCHAIN_DIR)/lib/gcc/*/*/libgcc.map))
|
||||||
LIBGCC_SO=$(lastword $(wildcard $(TOOLCHAIN_DIR)/lib/libgcc_s.so.*))
|
LIBGCC_SO=$(lastword $(wildcard $(TOOLCHAIN_DIR)/lib/libgcc_s.so.*))
|
||||||
@ -652,12 +655,23 @@ else
|
|||||||
exit 0
|
exit 0
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
define Package/glibc/install
|
||||||
|
endef
|
||||||
|
|
||||||
|
LD_MUSL_NAME = $(notdir $(firstword $(wildcard $(TOOLCHAIN_ROOT_DIR)/lib/libc.so*)))
|
||||||
|
|
||||||
|
define Package/musl/install
|
||||||
|
$(INSTALL_DIR) $(1)/usr/bin
|
||||||
|
$(LN) ../../lib/$(LD_MUSL_NAME) $(1)/usr/bin/ldd
|
||||||
|
endef
|
||||||
|
|
||||||
define Package/libc/install
|
define Package/libc/install
|
||||||
for file in $(call qstrip,$(CONFIG_LIBC_FILE_SPEC)); do \
|
for file in $(call qstrip,$(CONFIG_LIBC_FILE_SPEC)); do \
|
||||||
$(INSTALL_DIR) $(1)/lib ; \
|
$(INSTALL_DIR) $(1)/lib ; \
|
||||||
$(CP) $(call qstrip,$(CONFIG_LIBC_ROOT_DIR))/$$$$file $(1)/lib/ ; \
|
$(CP) $(call qstrip,$(CONFIG_LIBC_ROOT_DIR))/$$$$file $(1)/lib/ ; \
|
||||||
done ; \
|
done ; \
|
||||||
exit 0
|
exit 0
|
||||||
|
$(call Package/$(LIBC)/install,$1)
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/libpthread/install
|
define Package/libpthread/install
|
||||||
|
@ -5,9 +5,9 @@ PKG_RELEASE:=2
|
|||||||
|
|
||||||
PKG_SOURCE_PROTO:=git
|
PKG_SOURCE_PROTO:=git
|
||||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/netifd.git
|
PKG_SOURCE_URL=$(PROJECT_GIT)/project/netifd.git
|
||||||
PKG_SOURCE_DATE:=2023-09-19
|
PKG_SOURCE_DATE:=2023-10-20
|
||||||
PKG_SOURCE_VERSION:=7a58b995fdbecd9beed57e4d66d42cb3cf66aee2
|
PKG_SOURCE_VERSION:=5590a80e2566d378be955f61c287a63fb3bdf329
|
||||||
PKG_MIRROR_HASH:=a460a3b912047f8802eb24bb737084a08dad65b2dd520e5f5e7459379d1fcf8c
|
PKG_MIRROR_HASH:=eef792b4e9fa7a5227cf8c2ec4ed5e6558dd04c119cd9f97561923821fd1aa92
|
||||||
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
||||||
|
|
||||||
PKG_LICENSE:=GPL-2.0
|
PKG_LICENSE:=GPL-2.0
|
||||||
|
@ -568,6 +568,7 @@ dhcp_add() {
|
|||||||
config_get ra_management "$cfg" ra_management
|
config_get ra_management "$cfg" ra_management
|
||||||
config_get ra_preference "$cfg" ra_preference
|
config_get ra_preference "$cfg" ra_preference
|
||||||
config_get dns "$cfg" dns
|
config_get dns "$cfg" dns
|
||||||
|
config_get dns_sl "$cfg" domain
|
||||||
|
|
||||||
config_list_foreach "$cfg" "interface_name" append_interface_name "$ifname"
|
config_list_foreach "$cfg" "interface_name" append_interface_name "$ifname"
|
||||||
|
|
||||||
@ -647,6 +648,13 @@ dhcp_add() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
dhcp_option_append "option6:dns-server,$dnss" "$networkid"
|
dhcp_option_append "option6:dns-server,$dnss" "$networkid"
|
||||||
|
|
||||||
|
if [ -n "$dns_sl" ]; then
|
||||||
|
ddssl=""
|
||||||
|
for dd in $dns_sl; do append ddssl "$dd" ","; done
|
||||||
|
fi
|
||||||
|
|
||||||
|
dhcp_option_append "option6:domain-search,$ddssl" "$networkid"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dhcp_option_add "$cfg" "$networkid" 0
|
dhcp_option_add "$cfg" "$networkid" 0
|
||||||
|
@ -12,9 +12,9 @@ PKG_RELEASE:=5
|
|||||||
|
|
||||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/mdnsd.git
|
PKG_SOURCE_URL=$(PROJECT_GIT)/project/mdnsd.git
|
||||||
PKG_SOURCE_PROTO:=git
|
PKG_SOURCE_PROTO:=git
|
||||||
PKG_SOURCE_DATE:=2023-01-16
|
PKG_SOURCE_DATE:=2023-10-19
|
||||||
PKG_SOURCE_VERSION:=65b3308d13de7d7975444d34389651612e2a4d38
|
PKG_SOURCE_VERSION:=d45c443aa1e6514aab58bbbf9311913e484d31a6
|
||||||
PKG_MIRROR_HASH:=945fdf51a299b68982aab74e8fba5614f2553a7b4c49a3a53b3093ea8aac0279
|
PKG_MIRROR_HASH:=20d91d867f4f34a37c7b2a600327884375f9f16c1ea9bbb3199347d8b617d856
|
||||||
|
|
||||||
PKG_MAINTAINER:=John Crispin <john@phrozen.org>
|
PKG_MAINTAINER:=John Crispin <john@phrozen.org>
|
||||||
PKG_LICENSE:=LGPL-2.1
|
PKG_LICENSE:=LGPL-2.1
|
||||||
|
@ -6,12 +6,12 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=nftables
|
PKG_NAME:=nftables
|
||||||
PKG_VERSION:=1.0.8
|
PKG_VERSION:=1.0.9
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=1
|
||||||
|
|
||||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
|
||||||
PKG_SOURCE_URL:=https://netfilter.org/projects/$(PKG_NAME)/files
|
PKG_SOURCE_URL:=https://netfilter.org/projects/$(PKG_NAME)/files
|
||||||
PKG_HASH:=9373740de41a82dbc98818e0a46a073faeb8a8d0689fa4fa1a74399c32bf3d50
|
PKG_HASH:=a3c304cd9ba061239ee0474f9afb938a9bb99d89b960246f66f0c3a0a85e14cd
|
||||||
|
|
||||||
PKG_MAINTAINER:=
|
PKG_MAINTAINER:=
|
||||||
PKG_LICENSE:=GPL-2.0
|
PKG_LICENSE:=GPL-2.0
|
||||||
|
@ -18,6 +18,9 @@ define Build/Prepare
|
|||||||
mkdir -p $(PKG_BUILD_DIR)
|
mkdir -p $(PKG_BUILD_DIR)
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
define Build/Quilt
|
||||||
|
endef
|
||||||
|
|
||||||
define Build/Compile/Default
|
define Build/Compile/Default
|
||||||
endef
|
endef
|
||||||
Build/Compile = $(Build/Compile/Default)
|
Build/Compile = $(Build/Compile/Default)
|
||||||
|
@ -9,6 +9,7 @@ clear_partialboots() {
|
|||||||
# clear partialboots
|
# clear partialboots
|
||||||
|
|
||||||
case $(board_name) in
|
case $(board_name) in
|
||||||
|
linksys,ea9200|\
|
||||||
linksys,panamera)
|
linksys,panamera)
|
||||||
COMMIT=1
|
COMMIT=1
|
||||||
nvram set partialboots=0
|
nvram set partialboots=0
|
||||||
|
14
rules.mk
14
rules.mk
@ -184,14 +184,14 @@ ifndef DUMP
|
|||||||
-include $(TOOLCHAIN_DIR)/info.mk
|
-include $(TOOLCHAIN_DIR)/info.mk
|
||||||
export GCC_HONOUR_COPTS:=0
|
export GCC_HONOUR_COPTS:=0
|
||||||
TARGET_CROSS:=$(if $(TARGET_CROSS),$(TARGET_CROSS),$(OPTIMIZE_FOR_CPU)-openwrt-linux$(if $(TARGET_SUFFIX),-$(TARGET_SUFFIX))-)
|
TARGET_CROSS:=$(if $(TARGET_CROSS),$(TARGET_CROSS),$(OPTIMIZE_FOR_CPU)-openwrt-linux$(if $(TARGET_SUFFIX),-$(TARGET_SUFFIX))-)
|
||||||
|
TOOLCHAIN_ROOT_DIR:=$(TOPDIR)/staging_dir/$(TOOLCHAIN_DIR_NAME)
|
||||||
|
TOOLCHAIN_BIN_DIRS:=$(TOOLCHAIN_ROOT_DIR)/bin
|
||||||
|
TOOLCHAIN_INC_DIRS:=$(TOOLCHAIN_ROOT_DIR)/usr/include $(TOOLCHAIN_ROOT_DIR)/include
|
||||||
|
TOOLCHAIN_LIB_DIRS:=$(TOOLCHAIN_ROOT_DIR)/usr/lib $(TOOLCHAIN_ROOT_DIR)/lib
|
||||||
TARGET_CFLAGS+= -fhonour-copts
|
TARGET_CFLAGS+= -fhonour-copts
|
||||||
TARGET_CPPFLAGS+= -I$(TOOLCHAIN_DIR)/usr/include
|
|
||||||
ifeq ($(CONFIG_USE_MUSL),y)
|
ifeq ($(CONFIG_USE_MUSL),y)
|
||||||
TARGET_CPPFLAGS+= -I$(TOOLCHAIN_DIR)/include/fortify
|
TOOLCHAIN_INC_DIRS+= $(TOOLCHAIN_DIR)/include/fortify
|
||||||
endif
|
endif
|
||||||
TARGET_CPPFLAGS+= -I$(TOOLCHAIN_DIR)/include
|
|
||||||
TARGET_LDFLAGS+= -L$(TOOLCHAIN_DIR)/usr/lib -L$(TOOLCHAIN_DIR)/lib
|
|
||||||
TARGET_PATH:=$(TOOLCHAIN_DIR)/bin:$(TARGET_PATH)
|
|
||||||
else
|
else
|
||||||
ifeq ($(CONFIG_NATIVE_TOOLCHAIN),)
|
ifeq ($(CONFIG_NATIVE_TOOLCHAIN),)
|
||||||
TARGET_CROSS:=$(call qstrip,$(CONFIG_TOOLCHAIN_PREFIX))
|
TARGET_CROSS:=$(call qstrip,$(CONFIG_TOOLCHAIN_PREFIX))
|
||||||
@ -199,6 +199,8 @@ ifndef DUMP
|
|||||||
TOOLCHAIN_BIN_DIRS:=$(patsubst ./%,$(TOOLCHAIN_ROOT_DIR)/%,$(call qstrip,$(CONFIG_TOOLCHAIN_BIN_PATH)))
|
TOOLCHAIN_BIN_DIRS:=$(patsubst ./%,$(TOOLCHAIN_ROOT_DIR)/%,$(call qstrip,$(CONFIG_TOOLCHAIN_BIN_PATH)))
|
||||||
TOOLCHAIN_INC_DIRS:=$(patsubst ./%,$(TOOLCHAIN_ROOT_DIR)/%,$(call qstrip,$(CONFIG_TOOLCHAIN_INC_PATH)))
|
TOOLCHAIN_INC_DIRS:=$(patsubst ./%,$(TOOLCHAIN_ROOT_DIR)/%,$(call qstrip,$(CONFIG_TOOLCHAIN_INC_PATH)))
|
||||||
TOOLCHAIN_LIB_DIRS:=$(patsubst ./%,$(TOOLCHAIN_ROOT_DIR)/%,$(call qstrip,$(CONFIG_TOOLCHAIN_LIB_PATH)))
|
TOOLCHAIN_LIB_DIRS:=$(patsubst ./%,$(TOOLCHAIN_ROOT_DIR)/%,$(call qstrip,$(CONFIG_TOOLCHAIN_LIB_PATH)))
|
||||||
|
endif
|
||||||
|
endif
|
||||||
ifneq ($(TOOLCHAIN_BIN_DIRS),)
|
ifneq ($(TOOLCHAIN_BIN_DIRS),)
|
||||||
TARGET_PATH:=$(subst $(space),:,$(TOOLCHAIN_BIN_DIRS)):$(TARGET_PATH)
|
TARGET_PATH:=$(subst $(space),:,$(TOOLCHAIN_BIN_DIRS)):$(TARGET_PATH)
|
||||||
endif
|
endif
|
||||||
@ -209,8 +211,6 @@ ifndef DUMP
|
|||||||
TARGET_LDFLAGS+= $(patsubst %,-L%,$(TOOLCHAIN_LIB_DIRS))
|
TARGET_LDFLAGS+= $(patsubst %,-L%,$(TOOLCHAIN_LIB_DIRS))
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
TARGET_LINKER?=bfd
|
TARGET_LINKER?=bfd
|
||||||
TARGET_LDFLAGS+= -fuse-ld=$(TARGET_LINKER)
|
TARGET_LDFLAGS+= -fuse-ld=$(TARGET_LINKER)
|
||||||
|
@ -27,6 +27,7 @@ CFLAGS=""
|
|||||||
TOOLCHAIN="."
|
TOOLCHAIN="."
|
||||||
|
|
||||||
LIBC_TYPE=""
|
LIBC_TYPE=""
|
||||||
|
GCC_VERSION=""
|
||||||
|
|
||||||
|
|
||||||
# Library specs
|
# Library specs
|
||||||
@ -199,6 +200,19 @@ find_bins() {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
find_gcc_version() {
|
||||||
|
if [ -f $TOOLCHAIN/info.mk ]; then
|
||||||
|
GCC_VERSION=$(grep GCC_VERSION $TOOLCHAIN/info.mk | sed 's/GCC_VERSION=//')
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Warning! Can't find info.mk, trying to detect with alternative way."
|
||||||
|
|
||||||
|
# Very fragile detection
|
||||||
|
GCC_VERSION=$(find $TOOLCHAIN/bin | grep -oE "gcc-[0-9]+\.[0-9]+\.[0-9]+$" | \
|
||||||
|
head -1 | sed 's/gcc-//')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
wrap_bin_cc() {
|
wrap_bin_cc() {
|
||||||
local out="$1"
|
local out="$1"
|
||||||
@ -383,6 +397,13 @@ print_config() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ -n "$GCC_VERSION" ]; then
|
||||||
|
echo "CONFIG_EXTERNAL_GCC_VERSION=\"$GCC_VERSION\"" >> "$config"
|
||||||
|
else
|
||||||
|
echo "Can't detect GCC version. Aborting!" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
local lib
|
local lib
|
||||||
for lib in C RT PTHREAD GCC STDCPP SSP GFORTRAN GOMP; do
|
for lib in C RT PTHREAD GCC STDCPP SSP GFORTRAN GOMP; do
|
||||||
local file
|
local file
|
||||||
@ -564,6 +585,7 @@ while [ -n "$1" ]; do
|
|||||||
--config)
|
--config)
|
||||||
if probe_cc; then
|
if probe_cc; then
|
||||||
probe_libc
|
probe_libc
|
||||||
|
find_gcc_version
|
||||||
print_config "$1"
|
print_config "$1"
|
||||||
exit $?
|
exit $?
|
||||||
fi
|
fi
|
||||||
|
@ -3,7 +3,12 @@ define Build/create-uImage-dtb
|
|||||||
-$(STAGING_DIR_HOST)/bin/mkimage -A $(LINUX_KARCH) \
|
-$(STAGING_DIR_HOST)/bin/mkimage -A $(LINUX_KARCH) \
|
||||||
-O linux -T kernel -C none \
|
-O linux -T kernel -C none \
|
||||||
-n '$(call toupper,$(LINUX_KARCH)) $(VERSION_DIST) Linux-$(LINUX_VERSION)' \
|
-n '$(call toupper,$(LINUX_KARCH)) $(VERSION_DIST) Linux-$(LINUX_VERSION)' \
|
||||||
-d "$@.dtb" "$@.dtb.uimage"
|
-d "$(KDIR)/image-$(firstword $(DEVICE_DTS)).dtb" "$@.dtb.uimage"
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Build/prepend-dtb-uImage
|
||||||
|
cat "$@.dtb.uimage" "$@" > "$@.new"
|
||||||
|
mv "$@.new" "$@"
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Build/meraki-header
|
define Build/meraki-header
|
||||||
@ -104,7 +109,7 @@ define Device/netgear_wndr4700
|
|||||||
# append a fake/empty rootfs to fool netgear's uboot
|
# append a fake/empty rootfs to fool netgear's uboot
|
||||||
# CHECK_DNI_FIRMWARE_ROOTFS_INTEGRITY in do_chk_dniimg()
|
# CHECK_DNI_FIRMWARE_ROOTFS_INTEGRITY in do_chk_dniimg()
|
||||||
KERNEL := kernel-bin | lzma -d16 | uImage lzma | pad-offset $$(BLOCKSIZE) 64 | \
|
KERNEL := kernel-bin | lzma -d16 | uImage lzma | pad-offset $$(BLOCKSIZE) 64 | \
|
||||||
append-uImage-fakehdr filesystem | create-uImage-dtb | prepend-dtb
|
append-uImage-fakehdr filesystem | create-uImage-dtb | prepend-dtb-uImage
|
||||||
KERNEL_INITRAMFS := kernel-bin | libdeflate-gzip | MuImage-initramfs gzip
|
KERNEL_INITRAMFS := kernel-bin | libdeflate-gzip | MuImage-initramfs gzip
|
||||||
IMAGE/factory.img := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-ubi | \
|
IMAGE/factory.img := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-ubi | \
|
||||||
netgear-dni | check-size
|
netgear-dni | check-size
|
||||||
|
19
target/linux/armsr/base-files/lib/preinit/79_move_config
Normal file
19
target/linux/armsr/base-files/lib/preinit/79_move_config
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
|
||||||
|
move_config() {
|
||||||
|
local partdev parttype=ext4
|
||||||
|
|
||||||
|
. /lib/upgrade/common.sh
|
||||||
|
|
||||||
|
if export_bootdevice && export_partdevice partdev 1; then
|
||||||
|
part_magic_fat "/dev/$partdev" && parttype=vfat
|
||||||
|
if mount -t $parttype -o rw,noatime "/dev/$partdev" /mnt; then
|
||||||
|
if [ -f "/mnt/$BACKUP_FILE" ]; then
|
||||||
|
mv -f "/mnt/$BACKUP_FILE" /
|
||||||
|
fi
|
||||||
|
umount /mnt
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
boot_hook_add preinit_mount_root move_config
|
@ -36,7 +36,8 @@ platform_check_image() {
|
|||||||
platform_copy_config() {
|
platform_copy_config() {
|
||||||
local partdev parttype=ext4
|
local partdev parttype=ext4
|
||||||
|
|
||||||
if export_partdevice partdev 2; then
|
if export_partdevice partdev 1; then
|
||||||
|
part_magic_fat "/dev/$partdev" && parttype=vfat
|
||||||
mount -t $parttype -o rw,noatime "/dev/$partdev" /mnt
|
mount -t $parttype -o rw,noatime "/dev/$partdev" /mnt
|
||||||
cp -af "$UPGRADE_BACKUP" "/mnt/$BACKUP_FILE"
|
cp -af "$UPGRADE_BACKUP" "/mnt/$BACKUP_FILE"
|
||||||
umount /mnt
|
umount /mnt
|
||||||
|
@ -96,9 +96,8 @@
|
|||||||
|
|
||||||
ath9k0: wifi@0,11 { /* 2.4 GHz */
|
ath9k0: wifi@0,11 { /* 2.4 GHz */
|
||||||
compatible = "pci168c,0029";
|
compatible = "pci168c,0029";
|
||||||
nvmem-cells = <&macaddr_hwinfo_1c>;
|
nvmem-cells = <&macaddr_hwinfo_1c 1>;
|
||||||
nvmem-cell-names = "mac-address";
|
nvmem-cell-names = "mac-address";
|
||||||
mac-address-increment = <1>;
|
|
||||||
reg = <0x8800 0 0 0 0>;
|
reg = <0x8800 0 0 0 0>;
|
||||||
#gpio-cells = <2>;
|
#gpio-cells = <2>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
@ -106,9 +105,8 @@
|
|||||||
|
|
||||||
ath9k1: wifi@0,12 { /* 5 GHz */
|
ath9k1: wifi@0,12 { /* 5 GHz */
|
||||||
compatible = "pci168c,0029";
|
compatible = "pci168c,0029";
|
||||||
nvmem-cells = <&macaddr_hwinfo_1c>;
|
nvmem-cells = <&macaddr_hwinfo_1c 2>;
|
||||||
nvmem-cell-names = "mac-address";
|
nvmem-cell-names = "mac-address";
|
||||||
mac-address-increment = <2>;
|
|
||||||
reg = <0x9000 0 0 0 0>;
|
reg = <0x9000 0 0 0 0>;
|
||||||
#gpio-cells = <2>;
|
#gpio-cells = <2>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
@ -125,7 +123,7 @@
|
|||||||
|
|
||||||
ð0 {
|
ð0 {
|
||||||
status = "okay";
|
status = "okay";
|
||||||
nvmem-cells = <&macaddr_hwinfo_1c>;
|
nvmem-cells = <&macaddr_hwinfo_1c 0>;
|
||||||
nvmem-cell-names = "mac-address";
|
nvmem-cell-names = "mac-address";
|
||||||
|
|
||||||
pll-data = <0x00110000 0x00001099 0x00991099>;
|
pll-data = <0x00110000 0x00001099 0x00991099>;
|
||||||
@ -160,9 +158,22 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
hwinfo: partition@fe0000 {
|
hwinfo: partition@fe0000 {
|
||||||
label = "hwinfo";
|
|
||||||
reg = <0xfe0000 0x10000>;
|
reg = <0xfe0000 0x10000>;
|
||||||
|
compatible = "nvmem-cells";
|
||||||
|
label = "hwinfo";
|
||||||
read-only;
|
read-only;
|
||||||
|
|
||||||
|
nvmem-layout {
|
||||||
|
compatible = "fixed-layout";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
|
||||||
|
macaddr_hwinfo_1c: mac-address@1c {
|
||||||
|
compatible = "mac-base";
|
||||||
|
reg = <0x1c 0x6>;
|
||||||
|
#nvmem-cell-cells = <1>;
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
partition@ff0000 {
|
partition@ff0000 {
|
||||||
@ -173,13 +184,3 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
&hwinfo {
|
|
||||||
compatible = "nvmem-cells";
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <1>;
|
|
||||||
|
|
||||||
macaddr_hwinfo_1c: macaddr@1c {
|
|
||||||
reg = <0x1c 0x6>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
@ -349,7 +349,7 @@ SVN-Revision: 35130
|
|||||||
list_for_each_entry(p, head, list) {
|
list_for_each_entry(p, head, list) {
|
||||||
--- a/net/ipv4/tcp_output.c
|
--- a/net/ipv4/tcp_output.c
|
||||||
+++ b/net/ipv4/tcp_output.c
|
+++ b/net/ipv4/tcp_output.c
|
||||||
@@ -610,48 +610,53 @@ static void tcp_options_write(struct tcp
|
@@ -612,48 +612,53 @@ static void tcp_options_write(struct tcp
|
||||||
u16 options = opts->options; /* mungable copy */
|
u16 options = opts->options; /* mungable copy */
|
||||||
|
|
||||||
if (unlikely(OPTION_MD5 & options)) {
|
if (unlikely(OPTION_MD5 & options)) {
|
||||||
@ -426,7 +426,7 @@ SVN-Revision: 35130
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(opts->num_sack_blocks)) {
|
if (unlikely(opts->num_sack_blocks)) {
|
||||||
@@ -659,16 +664,17 @@ static void tcp_options_write(struct tcp
|
@@ -661,16 +666,17 @@ static void tcp_options_write(struct tcp
|
||||||
tp->duplicate_sack : tp->selective_acks;
|
tp->duplicate_sack : tp->selective_acks;
|
||||||
int this_sack;
|
int this_sack;
|
||||||
|
|
||||||
@ -450,7 +450,7 @@ SVN-Revision: 35130
|
|||||||
}
|
}
|
||||||
|
|
||||||
tp->rx_opt.dsack = 0;
|
tp->rx_opt.dsack = 0;
|
||||||
@@ -681,13 +687,14 @@ static void tcp_options_write(struct tcp
|
@@ -683,13 +689,14 @@ static void tcp_options_write(struct tcp
|
||||||
|
|
||||||
if (foc->exp) {
|
if (foc->exp) {
|
||||||
len = TCPOLEN_EXP_FASTOPEN_BASE + foc->len;
|
len = TCPOLEN_EXP_FASTOPEN_BASE + foc->len;
|
||||||
|
@ -10,7 +10,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
|
|||||||
|
|
||||||
--- a/drivers/gpu/drm/drm_atomic_helper.c
|
--- a/drivers/gpu/drm/drm_atomic_helper.c
|
||||||
+++ b/drivers/gpu/drm/drm_atomic_helper.c
|
+++ b/drivers/gpu/drm/drm_atomic_helper.c
|
||||||
@@ -438,6 +438,11 @@ mode_fixup(struct drm_atomic_state *stat
|
@@ -443,6 +443,11 @@ mode_fixup(struct drm_atomic_state *stat
|
||||||
new_crtc_state =
|
new_crtc_state =
|
||||||
drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);
|
drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ Signed-off-by: Maxime Ripard <maxime@cerno.tech>
|
|||||||
|
|
||||||
--- a/drivers/gpu/drm/drm_atomic_helper.c
|
--- a/drivers/gpu/drm/drm_atomic_helper.c
|
||||||
+++ b/drivers/gpu/drm/drm_atomic_helper.c
|
+++ b/drivers/gpu/drm/drm_atomic_helper.c
|
||||||
@@ -1617,13 +1617,6 @@ drm_atomic_helper_wait_for_vblanks(struc
|
@@ -1626,13 +1626,6 @@ drm_atomic_helper_wait_for_vblanks(struc
|
||||||
int i, ret;
|
int i, ret;
|
||||||
unsigned int crtc_mask = 0;
|
unsigned int crtc_mask = 0;
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ Signed-off-by: Maxime Ripard <maxime@cerno.tech>
|
|||||||
for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
|
for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
|
||||||
if (!new_crtc_state->active)
|
if (!new_crtc_state->active)
|
||||||
continue;
|
continue;
|
||||||
@@ -2273,12 +2266,6 @@ int drm_atomic_helper_setup_commit(struc
|
@@ -2282,12 +2275,6 @@ int drm_atomic_helper_setup_commit(struc
|
||||||
complete_all(&commit->flip_done);
|
complete_all(&commit->flip_done);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1185,7 +1185,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
|
|||||||
}
|
}
|
||||||
--- a/drivers/usb/core/hub.c
|
--- a/drivers/usb/core/hub.c
|
||||||
+++ b/drivers/usb/core/hub.c
|
+++ b/drivers/usb/core/hub.c
|
||||||
@@ -5636,7 +5636,7 @@ static void port_event(struct usb_hub *h
|
@@ -5655,7 +5655,7 @@ static void port_event(struct usb_hub *h
|
||||||
port_dev->over_current_count++;
|
port_dev->over_current_count++;
|
||||||
port_over_current_notify(port_dev);
|
port_over_current_notify(port_dev);
|
||||||
|
|
||||||
|
@ -17615,12 +17615,12 @@ Signed-off-by: Ashish Vara <ashishhvara@gmail.com>
|
|||||||
* For devices with more than one control interface, we assume the
|
* For devices with more than one control interface, we assume the
|
||||||
--- a/sound/usb/quirks.c
|
--- a/sound/usb/quirks.c
|
||||||
+++ b/sound/usb/quirks.c
|
+++ b/sound/usb/quirks.c
|
||||||
@@ -2171,6 +2171,8 @@ static const struct usb_audio_quirk_flag
|
@@ -2175,6 +2175,8 @@ static const struct usb_audio_quirk_flag
|
||||||
QUIRK_FLAG_FIXED_RATE),
|
QUIRK_FLAG_FIXED_RATE),
|
||||||
DEVICE_FLG(0x0ecb, 0x2069, /* JBL Quantum810 Wireless */
|
DEVICE_FLG(0x0ecb, 0x2069, /* JBL Quantum810 Wireless */
|
||||||
QUIRK_FLAG_FIXED_RATE),
|
QUIRK_FLAG_FIXED_RATE),
|
||||||
+ DEVICE_FLG(0x09da, 0x2695, /* A4Tech FHD 1080p webcam */
|
+ DEVICE_FLG(0x09da, 0x2695, /* A4Tech FHD 1080p webcam */
|
||||||
+ QUIRK_FLAG_DISABLE_AUTOSUSPEND | QUIRK_FLAG_GET_SAMPLE_RATE),
|
+ QUIRK_FLAG_DISABLE_AUTOSUSPEND | QUIRK_FLAG_GET_SAMPLE_RATE),
|
||||||
|
DEVICE_FLG(0x1bcf, 0x2283, /* NexiGo N930AF FHD Webcam */
|
||||||
|
QUIRK_FLAG_GET_SAMPLE_RATE),
|
||||||
|
|
||||||
/* Vendor matches */
|
|
||||||
VENDOR_FLG(0x045e, /* MS Lifecam */
|
|
||||||
|
@ -96,7 +96,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int goodix_check_cfg_8(struct goodix_ts_data *ts, const u8 *cfg, int len)
|
static int goodix_check_cfg_8(struct goodix_ts_data *ts, const u8 *cfg, int len)
|
||||||
@@ -1406,6 +1459,11 @@ static void goodix_ts_remove(struct i2c_
|
@@ -1425,6 +1478,11 @@ static void goodix_ts_remove(struct i2c_
|
||||||
{
|
{
|
||||||
struct goodix_ts_data *ts = i2c_get_clientdata(client);
|
struct goodix_ts_data *ts = i2c_get_clientdata(client);
|
||||||
|
|
||||||
@ -108,7 +108,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
|
|||||||
if (ts->load_cfg_from_disk)
|
if (ts->load_cfg_from_disk)
|
||||||
wait_for_completion(&ts->firmware_loading_complete);
|
wait_for_completion(&ts->firmware_loading_complete);
|
||||||
}
|
}
|
||||||
@@ -1421,7 +1479,7 @@ static int __maybe_unused goodix_suspend
|
@@ -1440,7 +1498,7 @@ static int __maybe_unused goodix_suspend
|
||||||
|
|
||||||
/* We need gpio pins to suspend/resume */
|
/* We need gpio pins to suspend/resume */
|
||||||
if (ts->irq_pin_access_method == IRQ_PIN_ACCESS_NONE) {
|
if (ts->irq_pin_access_method == IRQ_PIN_ACCESS_NONE) {
|
||||||
@ -117,7 +117,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1465,7 +1523,7 @@ static int __maybe_unused goodix_resume(
|
@@ -1484,7 +1542,7 @@ static int __maybe_unused goodix_resume(
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (ts->irq_pin_access_method == IRQ_PIN_ACCESS_NONE) {
|
if (ts->irq_pin_access_method == IRQ_PIN_ACCESS_NONE) {
|
||||||
|
@ -50,6 +50,7 @@ bcm53xx_setup_macs()
|
|||||||
offset=1
|
offset=1
|
||||||
;;
|
;;
|
||||||
dlink,dir-885l | \
|
dlink,dir-885l | \
|
||||||
|
linksys,ea9200 | \
|
||||||
linksys,panamera | \
|
linksys,panamera | \
|
||||||
netgear,r7900 | \
|
netgear,r7900 | \
|
||||||
netgear,r8000 | \
|
netgear,r8000 | \
|
||||||
|
@ -1,40 +1,176 @@
|
|||||||
From a18378409fee1cac0f0c58a4770ff557b498c778 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||||
Date: Fri, 1 Sep 2023 10:44:26 +0200
|
Date: Thu, 14 Sep 2023 07:59:09 +0200
|
||||||
Subject: [PATCH] nvmem: brcm_nvram: store a copy of NVRAM content
|
Subject: [PATCH] nvmem: brcm_nvram: store a copy of NVRAM content
|
||||||
MIME-Version: 1.0
|
MIME-Version: 1.0
|
||||||
Content-Type: text/plain; charset=UTF-8
|
Content-Type: text/plain; charset=UTF-8
|
||||||
Content-Transfer-Encoding: 8bit
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
This driver uses MMIO access for reading NVRAM from a flash device.
|
||||||
|
Underneath there is a flash controller that reads data and provides
|
||||||
|
mapping window.
|
||||||
|
|
||||||
|
Using MMIO interface affects controller configuration and may break real
|
||||||
|
controller driver. It was reported by multiple users of devices with
|
||||||
|
NVRAM stored on NAND.
|
||||||
|
|
||||||
|
Modify driver to read & cache NVRAM content during init and use that
|
||||||
|
copy to provide NVMEM data when requested. On NAND flashes due to their
|
||||||
|
alignment NVRAM partitions can be quite big (1 MiB and more) while
|
||||||
|
actual NVRAM content stays quite small (usually 16 to 32 KiB). To avoid
|
||||||
|
allocating so much memory check for actual data length.
|
||||||
|
|
||||||
|
Link: https://lore.kernel.org/linux-mtd/CACna6rwf3_9QVjYcM+847biTX=K0EoWXuXcSMkJO1Vy_5vmVqA@mail.gmail.com/
|
||||||
|
Fixes: 3fef9ed0627a ("nvmem: brcm_nvram: new driver exposing Broadcom's NVRAM")
|
||||||
|
Cc: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||||
|
Cc: Florian Fainelli <florian.fainelli@broadcom.com>
|
||||||
|
Cc: Scott Branden <scott.branden@broadcom.com>
|
||||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||||
---
|
---
|
||||||
drivers/nvmem/brcm_nvram.c | 54 +++++++++++++++++++-------------------
|
drivers/nvmem/brcm_nvram.c | 130 +++++++++++++++++++++++++------------
|
||||||
1 file changed, 27 insertions(+), 27 deletions(-)
|
1 file changed, 90 insertions(+), 40 deletions(-)
|
||||||
|
|
||||||
--- a/drivers/nvmem/brcm_nvram.c
|
--- a/drivers/nvmem/brcm_nvram.c
|
||||||
+++ b/drivers/nvmem/brcm_nvram.c
|
+++ b/drivers/nvmem/brcm_nvram.c
|
||||||
@@ -19,7 +19,7 @@
|
@@ -17,9 +17,20 @@
|
||||||
|
|
||||||
|
#define NVRAM_MAGIC "FLSH"
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * struct brcm_nvram - driver state internal struct
|
||||||
|
+ *
|
||||||
|
+ * @nvmem_size: Size of the whole space available for NVRAM
|
||||||
|
+ * @data: NVRAM data copy stored to avoid poking underlaying flash controller
|
||||||
|
+ * @data_len: NVRAM data size
|
||||||
|
+ * @padding_byte: Padding value used to fill remaining space
|
||||||
|
+ */
|
||||||
struct brcm_nvram {
|
struct brcm_nvram {
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
- void __iomem *base;
|
- void __iomem *base;
|
||||||
|
+ size_t nvmem_size;
|
||||||
+ uint8_t *data;
|
+ uint8_t *data;
|
||||||
|
+ size_t data_len;
|
||||||
|
+ uint8_t padding_byte;
|
||||||
struct nvmem_cell_info *cells;
|
struct nvmem_cell_info *cells;
|
||||||
int ncells;
|
int ncells;
|
||||||
};
|
};
|
||||||
@@ -36,10 +36,8 @@ static int brcm_nvram_read(void *context
|
@@ -36,10 +47,47 @@ static int brcm_nvram_read(void *context
|
||||||
size_t bytes)
|
size_t bytes)
|
||||||
{
|
{
|
||||||
struct brcm_nvram *priv = context;
|
struct brcm_nvram *priv = context;
|
||||||
- u8 *dst = val;
|
- u8 *dst = val;
|
||||||
|
+ size_t to_copy;
|
||||||
|
+
|
||||||
|
+ if (offset + bytes > priv->data_len)
|
||||||
|
+ to_copy = max_t(ssize_t, (ssize_t)priv->data_len - offset, 0);
|
||||||
|
+ else
|
||||||
|
+ to_copy = bytes;
|
||||||
|
+
|
||||||
|
+ memcpy(val, priv->data + offset, to_copy);
|
||||||
|
+
|
||||||
|
+ memset((uint8_t *)val + to_copy, priv->padding_byte, bytes - to_copy);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int brcm_nvram_copy_data(struct brcm_nvram *priv, struct platform_device *pdev)
|
||||||
|
+{
|
||||||
|
+ struct resource *res;
|
||||||
|
+ void __iomem *base;
|
||||||
|
+
|
||||||
|
+ base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
||||||
|
+ if (IS_ERR(base))
|
||||||
|
+ return PTR_ERR(base);
|
||||||
|
+
|
||||||
|
+ priv->nvmem_size = resource_size(res);
|
||||||
|
+
|
||||||
|
+ priv->padding_byte = readb(base + priv->nvmem_size - 1);
|
||||||
|
+ for (priv->data_len = priv->nvmem_size;
|
||||||
|
+ priv->data_len;
|
||||||
|
+ priv->data_len--) {
|
||||||
|
+ if (readb(base + priv->data_len - 1) != priv->padding_byte)
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ WARN(priv->data_len > SZ_128K, "Unexpected (big) NVRAM size: %zu B\n", priv->data_len);
|
||||||
|
|
||||||
- while (bytes--)
|
- while (bytes--)
|
||||||
- *dst++ = readb(priv->base + offset++);
|
- *dst++ = readb(priv->base + offset++);
|
||||||
+ memcpy(val, priv->data + offset, bytes);
|
+ priv->data = devm_kzalloc(priv->dev, priv->data_len, GFP_KERNEL);
|
||||||
|
+ if (!priv->data)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ memcpy_fromio(priv->data, base, priv->data_len);
|
||||||
|
+
|
||||||
|
+ bcm47xx_nvram_init_from_iomem(base, priv->data_len);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -110,35 +108,27 @@ static int brcm_nvram_add_cells(struct b
|
@@ -67,8 +115,13 @@ static int brcm_nvram_add_cells(struct b
|
||||||
|
size_t len)
|
||||||
|
{
|
||||||
|
struct device *dev = priv->dev;
|
||||||
|
- char *var, *value, *eq;
|
||||||
|
+ char *var, *value;
|
||||||
|
+ uint8_t tmp;
|
||||||
|
int idx;
|
||||||
|
+ int err = 0;
|
||||||
|
+
|
||||||
|
+ tmp = priv->data[len - 1];
|
||||||
|
+ priv->data[len - 1] = '\0';
|
||||||
|
|
||||||
|
priv->ncells = 0;
|
||||||
|
for (var = data + sizeof(struct brcm_nvram_header);
|
||||||
|
@@ -78,67 +131,67 @@ static int brcm_nvram_add_cells(struct b
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->cells = devm_kcalloc(dev, priv->ncells, sizeof(*priv->cells), GFP_KERNEL);
|
||||||
|
- if (!priv->cells)
|
||||||
|
- return -ENOMEM;
|
||||||
|
+ if (!priv->cells) {
|
||||||
|
+ err = -ENOMEM;
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
for (var = data + sizeof(struct brcm_nvram_header), idx = 0;
|
||||||
|
var < (char *)data + len && *var;
|
||||||
|
var = value + strlen(value) + 1, idx++) {
|
||||||
|
+ char *eq, *name;
|
||||||
|
+
|
||||||
|
eq = strchr(var, '=');
|
||||||
|
if (!eq)
|
||||||
|
break;
|
||||||
|
*eq = '\0';
|
||||||
|
+ name = devm_kstrdup(dev, var, GFP_KERNEL);
|
||||||
|
+ *eq = '=';
|
||||||
|
+ if (!name) {
|
||||||
|
+ err = -ENOMEM;
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
value = eq + 1;
|
||||||
|
|
||||||
|
- priv->cells[idx].name = devm_kstrdup(dev, var, GFP_KERNEL);
|
||||||
|
- if (!priv->cells[idx].name)
|
||||||
|
- return -ENOMEM;
|
||||||
|
+ priv->cells[idx].name = name;
|
||||||
|
priv->cells[idx].offset = value - (char *)data;
|
||||||
|
priv->cells[idx].bytes = strlen(value);
|
||||||
|
priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name);
|
||||||
|
- if (!strcmp(var, "et0macaddr") ||
|
||||||
|
- !strcmp(var, "et1macaddr") ||
|
||||||
|
- !strcmp(var, "et2macaddr")) {
|
||||||
|
+ if (!strcmp(name, "et0macaddr") ||
|
||||||
|
+ !strcmp(name, "et1macaddr") ||
|
||||||
|
+ !strcmp(name, "et2macaddr")) {
|
||||||
|
priv->cells[idx].raw_len = strlen(value);
|
||||||
|
priv->cells[idx].bytes = ETH_ALEN;
|
||||||
|
priv->cells[idx].read_post_process = brcm_nvram_read_post_process_macaddr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- return 0;
|
||||||
|
+out:
|
||||||
|
+ priv->data[len - 1] = tmp;
|
||||||
|
+ return err;
|
||||||
|
}
|
||||||
|
|
||||||
static int brcm_nvram_parse(struct brcm_nvram *priv)
|
static int brcm_nvram_parse(struct brcm_nvram *priv)
|
||||||
{
|
{
|
||||||
@ -42,7 +178,6 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
|||||||
struct device *dev = priv->dev;
|
struct device *dev = priv->dev;
|
||||||
- struct brcm_nvram_header header;
|
- struct brcm_nvram_header header;
|
||||||
- uint8_t *data;
|
- uint8_t *data;
|
||||||
+ uint8_t tmp;
|
|
||||||
size_t len;
|
size_t len;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
@ -55,74 +190,62 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
|||||||
}
|
}
|
||||||
|
|
||||||
- len = le32_to_cpu(header.len);
|
- len = le32_to_cpu(header.len);
|
||||||
+ len = le32_to_cpu(header->len);
|
-
|
||||||
|
|
||||||
- data = kzalloc(len, GFP_KERNEL);
|
- data = kzalloc(len, GFP_KERNEL);
|
||||||
- if (!data)
|
- if (!data)
|
||||||
- return -ENOMEM;
|
- return -ENOMEM;
|
||||||
-
|
-
|
||||||
- memcpy_fromio(data, priv->base, len);
|
- memcpy_fromio(data, priv->base, len);
|
||||||
- data[len - 1] = '\0';
|
- data[len - 1] = '\0';
|
||||||
+ tmp = priv->data[len - 1];
|
-
|
||||||
+ priv->data[len - 1] = '\0';
|
|
||||||
|
|
||||||
- err = brcm_nvram_add_cells(priv, data, len);
|
- err = brcm_nvram_add_cells(priv, data, len);
|
||||||
- if (err) {
|
- if (err) {
|
||||||
+ err = brcm_nvram_add_cells(priv, priv->data, len);
|
- dev_err(dev, "Failed to add cells: %d\n", err);
|
||||||
+ if (err)
|
|
||||||
dev_err(dev, "Failed to add cells: %d\n", err);
|
|
||||||
- return err;
|
- return err;
|
||||||
- }
|
+ len = le32_to_cpu(header->len);
|
||||||
|
+ if (len > priv->nvmem_size) {
|
||||||
|
+ dev_err(dev, "NVRAM length (%zd) exceeds mapped size (%zd)\n", len, priv->nvmem_size);
|
||||||
|
+ return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
- kfree(data);
|
- kfree(data);
|
||||||
+ priv->data[len - 1] = tmp;
|
+ err = brcm_nvram_add_cells(priv, priv->data, len);
|
||||||
|
+ if (err)
|
||||||
|
+ dev_err(dev, "Failed to add cells: %d\n", err);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -150,8 +140,10 @@ static int brcm_nvram_probe(struct platf
|
@@ -150,7 +203,6 @@ static int brcm_nvram_probe(struct platf
|
||||||
.reg_read = brcm_nvram_read,
|
.reg_read = brcm_nvram_read,
|
||||||
};
|
};
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
- struct resource *res;
|
- struct resource *res;
|
||||||
struct brcm_nvram *priv;
|
struct brcm_nvram *priv;
|
||||||
+ struct resource *res;
|
|
||||||
+ void __iomem *base;
|
|
||||||
+ size_t size;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
@@ -159,21 +211,19 @@ static int brcm_nvram_probe(struct platf
|
||||||
@@ -159,21 +151,29 @@ static int brcm_nvram_probe(struct platf
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
priv->dev = dev;
|
priv->dev = dev;
|
||||||
|
|
||||||
- priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
- priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
||||||
- if (IS_ERR(priv->base))
|
- if (IS_ERR(priv->base))
|
||||||
- return PTR_ERR(priv->base);
|
- return PTR_ERR(priv->base);
|
||||||
+ base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
+ err = brcm_nvram_copy_data(priv, pdev);
|
||||||
+ if (IS_ERR(base))
|
+ if (err)
|
||||||
+ return PTR_ERR(base);
|
+ return err;
|
||||||
+
|
|
||||||
+ size = resource_size(res);
|
|
||||||
+
|
|
||||||
+ priv->data = kzalloc(size, GFP_KERNEL);
|
|
||||||
+ if (!priv->data)
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+
|
|
||||||
+ memcpy_fromio(priv->data, base, size);
|
|
||||||
|
|
||||||
err = brcm_nvram_parse(priv);
|
err = brcm_nvram_parse(priv);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
- bcm47xx_nvram_init_from_iomem(priv->base, resource_size(res));
|
- bcm47xx_nvram_init_from_iomem(priv->base, resource_size(res));
|
||||||
+ bcm47xx_nvram_init_from_iomem(base, size);
|
-
|
||||||
|
|
||||||
config.dev = dev;
|
config.dev = dev;
|
||||||
config.cells = priv->cells;
|
config.cells = priv->cells;
|
||||||
config.ncells = priv->ncells;
|
config.ncells = priv->ncells;
|
||||||
config.priv = priv;
|
config.priv = priv;
|
||||||
- config.size = resource_size(res);
|
- config.size = resource_size(res);
|
||||||
+ config.size = size;
|
+ config.size = priv->nvmem_size;
|
||||||
|
|
||||||
return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &config));
|
return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &config));
|
||||||
}
|
}
|
||||||
|
@ -1,40 +1,176 @@
|
|||||||
From a18378409fee1cac0f0c58a4770ff557b498c778 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||||
Date: Fri, 1 Sep 2023 10:44:26 +0200
|
Date: Thu, 14 Sep 2023 07:59:09 +0200
|
||||||
Subject: [PATCH] nvmem: brcm_nvram: store a copy of NVRAM content
|
Subject: [PATCH] nvmem: brcm_nvram: store a copy of NVRAM content
|
||||||
MIME-Version: 1.0
|
MIME-Version: 1.0
|
||||||
Content-Type: text/plain; charset=UTF-8
|
Content-Type: text/plain; charset=UTF-8
|
||||||
Content-Transfer-Encoding: 8bit
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
This driver uses MMIO access for reading NVRAM from a flash device.
|
||||||
|
Underneath there is a flash controller that reads data and provides
|
||||||
|
mapping window.
|
||||||
|
|
||||||
|
Using MMIO interface affects controller configuration and may break real
|
||||||
|
controller driver. It was reported by multiple users of devices with
|
||||||
|
NVRAM stored on NAND.
|
||||||
|
|
||||||
|
Modify driver to read & cache NVRAM content during init and use that
|
||||||
|
copy to provide NVMEM data when requested. On NAND flashes due to their
|
||||||
|
alignment NVRAM partitions can be quite big (1 MiB and more) while
|
||||||
|
actual NVRAM content stays quite small (usually 16 to 32 KiB). To avoid
|
||||||
|
allocating so much memory check for actual data length.
|
||||||
|
|
||||||
|
Link: https://lore.kernel.org/linux-mtd/CACna6rwf3_9QVjYcM+847biTX=K0EoWXuXcSMkJO1Vy_5vmVqA@mail.gmail.com/
|
||||||
|
Fixes: 3fef9ed0627a ("nvmem: brcm_nvram: new driver exposing Broadcom's NVRAM")
|
||||||
|
Cc: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||||
|
Cc: Florian Fainelli <florian.fainelli@broadcom.com>
|
||||||
|
Cc: Scott Branden <scott.branden@broadcom.com>
|
||||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||||
---
|
---
|
||||||
drivers/nvmem/brcm_nvram.c | 54 +++++++++++++++++++-------------------
|
drivers/nvmem/brcm_nvram.c | 130 +++++++++++++++++++++++++------------
|
||||||
1 file changed, 27 insertions(+), 27 deletions(-)
|
1 file changed, 90 insertions(+), 40 deletions(-)
|
||||||
|
|
||||||
--- a/drivers/nvmem/brcm_nvram.c
|
--- a/drivers/nvmem/brcm_nvram.c
|
||||||
+++ b/drivers/nvmem/brcm_nvram.c
|
+++ b/drivers/nvmem/brcm_nvram.c
|
||||||
@@ -19,7 +19,7 @@
|
@@ -17,9 +17,20 @@
|
||||||
|
|
||||||
|
#define NVRAM_MAGIC "FLSH"
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * struct brcm_nvram - driver state internal struct
|
||||||
|
+ *
|
||||||
|
+ * @nvmem_size: Size of the whole space available for NVRAM
|
||||||
|
+ * @data: NVRAM data copy stored to avoid poking underlaying flash controller
|
||||||
|
+ * @data_len: NVRAM data size
|
||||||
|
+ * @padding_byte: Padding value used to fill remaining space
|
||||||
|
+ */
|
||||||
struct brcm_nvram {
|
struct brcm_nvram {
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
- void __iomem *base;
|
- void __iomem *base;
|
||||||
|
+ size_t nvmem_size;
|
||||||
+ uint8_t *data;
|
+ uint8_t *data;
|
||||||
|
+ size_t data_len;
|
||||||
|
+ uint8_t padding_byte;
|
||||||
struct nvmem_cell_info *cells;
|
struct nvmem_cell_info *cells;
|
||||||
int ncells;
|
int ncells;
|
||||||
};
|
};
|
||||||
@@ -36,10 +36,8 @@ static int brcm_nvram_read(void *context
|
@@ -36,10 +47,47 @@ static int brcm_nvram_read(void *context
|
||||||
size_t bytes)
|
size_t bytes)
|
||||||
{
|
{
|
||||||
struct brcm_nvram *priv = context;
|
struct brcm_nvram *priv = context;
|
||||||
- u8 *dst = val;
|
- u8 *dst = val;
|
||||||
|
+ size_t to_copy;
|
||||||
|
+
|
||||||
|
+ if (offset + bytes > priv->data_len)
|
||||||
|
+ to_copy = max_t(ssize_t, (ssize_t)priv->data_len - offset, 0);
|
||||||
|
+ else
|
||||||
|
+ to_copy = bytes;
|
||||||
|
+
|
||||||
|
+ memcpy(val, priv->data + offset, to_copy);
|
||||||
|
+
|
||||||
|
+ memset((uint8_t *)val + to_copy, priv->padding_byte, bytes - to_copy);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int brcm_nvram_copy_data(struct brcm_nvram *priv, struct platform_device *pdev)
|
||||||
|
+{
|
||||||
|
+ struct resource *res;
|
||||||
|
+ void __iomem *base;
|
||||||
|
+
|
||||||
|
+ base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
||||||
|
+ if (IS_ERR(base))
|
||||||
|
+ return PTR_ERR(base);
|
||||||
|
+
|
||||||
|
+ priv->nvmem_size = resource_size(res);
|
||||||
|
+
|
||||||
|
+ priv->padding_byte = readb(base + priv->nvmem_size - 1);
|
||||||
|
+ for (priv->data_len = priv->nvmem_size;
|
||||||
|
+ priv->data_len;
|
||||||
|
+ priv->data_len--) {
|
||||||
|
+ if (readb(base + priv->data_len - 1) != priv->padding_byte)
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ WARN(priv->data_len > SZ_128K, "Unexpected (big) NVRAM size: %zu B\n", priv->data_len);
|
||||||
|
|
||||||
- while (bytes--)
|
- while (bytes--)
|
||||||
- *dst++ = readb(priv->base + offset++);
|
- *dst++ = readb(priv->base + offset++);
|
||||||
+ memcpy(val, priv->data + offset, bytes);
|
+ priv->data = devm_kzalloc(priv->dev, priv->data_len, GFP_KERNEL);
|
||||||
|
+ if (!priv->data)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ memcpy_fromio(priv->data, base, priv->data_len);
|
||||||
|
+
|
||||||
|
+ bcm47xx_nvram_init_from_iomem(base, priv->data_len);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -110,35 +108,27 @@ static int brcm_nvram_add_cells(struct b
|
@@ -67,8 +115,13 @@ static int brcm_nvram_add_cells(struct b
|
||||||
|
size_t len)
|
||||||
|
{
|
||||||
|
struct device *dev = priv->dev;
|
||||||
|
- char *var, *value, *eq;
|
||||||
|
+ char *var, *value;
|
||||||
|
+ uint8_t tmp;
|
||||||
|
int idx;
|
||||||
|
+ int err = 0;
|
||||||
|
+
|
||||||
|
+ tmp = priv->data[len - 1];
|
||||||
|
+ priv->data[len - 1] = '\0';
|
||||||
|
|
||||||
|
priv->ncells = 0;
|
||||||
|
for (var = data + sizeof(struct brcm_nvram_header);
|
||||||
|
@@ -78,67 +131,67 @@ static int brcm_nvram_add_cells(struct b
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->cells = devm_kcalloc(dev, priv->ncells, sizeof(*priv->cells), GFP_KERNEL);
|
||||||
|
- if (!priv->cells)
|
||||||
|
- return -ENOMEM;
|
||||||
|
+ if (!priv->cells) {
|
||||||
|
+ err = -ENOMEM;
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
for (var = data + sizeof(struct brcm_nvram_header), idx = 0;
|
||||||
|
var < (char *)data + len && *var;
|
||||||
|
var = value + strlen(value) + 1, idx++) {
|
||||||
|
+ char *eq, *name;
|
||||||
|
+
|
||||||
|
eq = strchr(var, '=');
|
||||||
|
if (!eq)
|
||||||
|
break;
|
||||||
|
*eq = '\0';
|
||||||
|
+ name = devm_kstrdup(dev, var, GFP_KERNEL);
|
||||||
|
+ *eq = '=';
|
||||||
|
+ if (!name) {
|
||||||
|
+ err = -ENOMEM;
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
value = eq + 1;
|
||||||
|
|
||||||
|
- priv->cells[idx].name = devm_kstrdup(dev, var, GFP_KERNEL);
|
||||||
|
- if (!priv->cells[idx].name)
|
||||||
|
- return -ENOMEM;
|
||||||
|
+ priv->cells[idx].name = name;
|
||||||
|
priv->cells[idx].offset = value - (char *)data;
|
||||||
|
priv->cells[idx].bytes = strlen(value);
|
||||||
|
priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name);
|
||||||
|
- if (!strcmp(var, "et0macaddr") ||
|
||||||
|
- !strcmp(var, "et1macaddr") ||
|
||||||
|
- !strcmp(var, "et2macaddr")) {
|
||||||
|
+ if (!strcmp(name, "et0macaddr") ||
|
||||||
|
+ !strcmp(name, "et1macaddr") ||
|
||||||
|
+ !strcmp(name, "et2macaddr")) {
|
||||||
|
priv->cells[idx].raw_len = strlen(value);
|
||||||
|
priv->cells[idx].bytes = ETH_ALEN;
|
||||||
|
priv->cells[idx].read_post_process = brcm_nvram_read_post_process_macaddr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- return 0;
|
||||||
|
+out:
|
||||||
|
+ priv->data[len - 1] = tmp;
|
||||||
|
+ return err;
|
||||||
|
}
|
||||||
|
|
||||||
static int brcm_nvram_parse(struct brcm_nvram *priv)
|
static int brcm_nvram_parse(struct brcm_nvram *priv)
|
||||||
{
|
{
|
||||||
@ -42,7 +178,6 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
|||||||
struct device *dev = priv->dev;
|
struct device *dev = priv->dev;
|
||||||
- struct brcm_nvram_header header;
|
- struct brcm_nvram_header header;
|
||||||
- uint8_t *data;
|
- uint8_t *data;
|
||||||
+ uint8_t tmp;
|
|
||||||
size_t len;
|
size_t len;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
@ -55,74 +190,62 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
|||||||
}
|
}
|
||||||
|
|
||||||
- len = le32_to_cpu(header.len);
|
- len = le32_to_cpu(header.len);
|
||||||
+ len = le32_to_cpu(header->len);
|
-
|
||||||
|
|
||||||
- data = kzalloc(len, GFP_KERNEL);
|
- data = kzalloc(len, GFP_KERNEL);
|
||||||
- if (!data)
|
- if (!data)
|
||||||
- return -ENOMEM;
|
- return -ENOMEM;
|
||||||
-
|
-
|
||||||
- memcpy_fromio(data, priv->base, len);
|
- memcpy_fromio(data, priv->base, len);
|
||||||
- data[len - 1] = '\0';
|
- data[len - 1] = '\0';
|
||||||
+ tmp = priv->data[len - 1];
|
-
|
||||||
+ priv->data[len - 1] = '\0';
|
|
||||||
|
|
||||||
- err = brcm_nvram_add_cells(priv, data, len);
|
- err = brcm_nvram_add_cells(priv, data, len);
|
||||||
- if (err) {
|
- if (err) {
|
||||||
+ err = brcm_nvram_add_cells(priv, priv->data, len);
|
- dev_err(dev, "Failed to add cells: %d\n", err);
|
||||||
+ if (err)
|
|
||||||
dev_err(dev, "Failed to add cells: %d\n", err);
|
|
||||||
- return err;
|
- return err;
|
||||||
- }
|
+ len = le32_to_cpu(header->len);
|
||||||
|
+ if (len > priv->nvmem_size) {
|
||||||
|
+ dev_err(dev, "NVRAM length (%zd) exceeds mapped size (%zd)\n", len, priv->nvmem_size);
|
||||||
|
+ return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
- kfree(data);
|
- kfree(data);
|
||||||
+ priv->data[len - 1] = tmp;
|
+ err = brcm_nvram_add_cells(priv, priv->data, len);
|
||||||
|
+ if (err)
|
||||||
|
+ dev_err(dev, "Failed to add cells: %d\n", err);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -150,8 +140,10 @@ static int brcm_nvram_probe(struct platf
|
@@ -150,7 +203,6 @@ static int brcm_nvram_probe(struct platf
|
||||||
.reg_read = brcm_nvram_read,
|
.reg_read = brcm_nvram_read,
|
||||||
};
|
};
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
- struct resource *res;
|
- struct resource *res;
|
||||||
struct brcm_nvram *priv;
|
struct brcm_nvram *priv;
|
||||||
+ struct resource *res;
|
|
||||||
+ void __iomem *base;
|
|
||||||
+ size_t size;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
@@ -159,21 +211,19 @@ static int brcm_nvram_probe(struct platf
|
||||||
@@ -159,21 +151,29 @@ static int brcm_nvram_probe(struct platf
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
priv->dev = dev;
|
priv->dev = dev;
|
||||||
|
|
||||||
- priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
- priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
||||||
- if (IS_ERR(priv->base))
|
- if (IS_ERR(priv->base))
|
||||||
- return PTR_ERR(priv->base);
|
- return PTR_ERR(priv->base);
|
||||||
+ base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
+ err = brcm_nvram_copy_data(priv, pdev);
|
||||||
+ if (IS_ERR(base))
|
+ if (err)
|
||||||
+ return PTR_ERR(base);
|
+ return err;
|
||||||
+
|
|
||||||
+ size = resource_size(res);
|
|
||||||
+
|
|
||||||
+ priv->data = kzalloc(size, GFP_KERNEL);
|
|
||||||
+ if (!priv->data)
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+
|
|
||||||
+ memcpy_fromio(priv->data, base, size);
|
|
||||||
|
|
||||||
err = brcm_nvram_parse(priv);
|
err = brcm_nvram_parse(priv);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
- bcm47xx_nvram_init_from_iomem(priv->base, resource_size(res));
|
- bcm47xx_nvram_init_from_iomem(priv->base, resource_size(res));
|
||||||
+ bcm47xx_nvram_init_from_iomem(base, size);
|
-
|
||||||
|
|
||||||
config.dev = dev;
|
config.dev = dev;
|
||||||
config.cells = priv->cells;
|
config.cells = priv->cells;
|
||||||
config.ncells = priv->ncells;
|
config.ncells = priv->ncells;
|
||||||
config.priv = priv;
|
config.priv = priv;
|
||||||
- config.size = resource_size(res);
|
- config.size = resource_size(res);
|
||||||
+ config.size = size;
|
+ config.size = priv->nvmem_size;
|
||||||
|
|
||||||
return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &config));
|
return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &config));
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
|||||||
|
|
||||||
--- a/drivers/net/dsa/qca/qca8k-8xxx.c
|
--- a/drivers/net/dsa/qca/qca8k-8xxx.c
|
||||||
+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
|
+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
|
||||||
@@ -743,9 +743,9 @@ qca8k_mdio_busy_wait(struct mii_bus *bus
|
@@ -754,9 +754,9 @@ qca8k_mdio_busy_wait(struct mii_bus *bus
|
||||||
|
|
||||||
qca8k_split_addr(reg, &r1, &r2, &page);
|
qca8k_split_addr(reg, &r1, &r2, &page);
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
|||||||
|
|
||||||
/* Check if qca8k_read has failed for a different reason
|
/* Check if qca8k_read has failed for a different reason
|
||||||
* before returnting -ETIMEDOUT
|
* before returnting -ETIMEDOUT
|
||||||
@@ -787,7 +787,7 @@ qca8k_mdio_write(struct qca8k_priv *priv
|
@@ -798,7 +798,7 @@ qca8k_mdio_write(struct qca8k_priv *priv
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
/* even if the busy_wait timeouts try to clear the MASTER_EN */
|
/* even if the busy_wait timeouts try to clear the MASTER_EN */
|
||||||
@ -49,7 +49,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
|||||||
|
|
||||||
mutex_unlock(&bus->mdio_lock);
|
mutex_unlock(&bus->mdio_lock);
|
||||||
|
|
||||||
@@ -817,18 +817,18 @@ qca8k_mdio_read(struct qca8k_priv *priv,
|
@@ -828,18 +828,18 @@ qca8k_mdio_read(struct qca8k_priv *priv,
|
||||||
if (ret)
|
if (ret)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
|
@ -168,7 +168,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
|||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -2091,8 +2147,6 @@ static SIMPLE_DEV_PM_OPS(qca8k_pm_ops,
|
@@ -2102,8 +2158,6 @@ static SIMPLE_DEV_PM_OPS(qca8k_pm_ops,
|
||||||
|
|
||||||
static const struct qca8k_info_ops qca8xxx_ops = {
|
static const struct qca8k_info_ops qca8xxx_ops = {
|
||||||
.autocast_mib = qca8k_get_ethtool_stats_eth,
|
.autocast_mib = qca8k_get_ethtool_stats_eth,
|
||||||
|
@ -32,7 +32,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|||||||
|
|
||||||
--- a/drivers/net/dsa/qca/qca8k-8xxx.c
|
--- a/drivers/net/dsa/qca/qca8k-8xxx.c
|
||||||
+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
|
+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
|
||||||
@@ -1883,9 +1883,8 @@ qca8k_setup(struct dsa_switch *ds)
|
@@ -1894,9 +1894,8 @@ qca8k_setup(struct dsa_switch *ds)
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@@ -1991,6 +1990,8 @@ static const struct dsa_switch_ops qca8k
|
@@ -2002,6 +2001,8 @@ static const struct dsa_switch_ops qca8k
|
||||||
.port_change_mtu = qca8k_port_change_mtu,
|
.port_change_mtu = qca8k_port_change_mtu,
|
||||||
.port_max_mtu = qca8k_port_max_mtu,
|
.port_max_mtu = qca8k_port_max_mtu,
|
||||||
.port_stp_state_set = qca8k_port_stp_state_set,
|
.port_stp_state_set = qca8k_port_stp_state_set,
|
||||||
|
@ -26,7 +26,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|||||||
|
|
||||||
--- a/drivers/net/dsa/qca/qca8k-8xxx.c
|
--- a/drivers/net/dsa/qca/qca8k-8xxx.c
|
||||||
+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
|
+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
|
||||||
@@ -1863,18 +1863,16 @@ qca8k_setup(struct dsa_switch *ds)
|
@@ -1874,18 +1874,16 @@ qca8k_setup(struct dsa_switch *ds)
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|||||||
|
|
||||||
--- a/drivers/net/dsa/qca/qca8k-8xxx.c
|
--- a/drivers/net/dsa/qca/qca8k-8xxx.c
|
||||||
+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
|
+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
|
||||||
@@ -1773,6 +1773,46 @@ static int qca8k_connect_tag_protocol(st
|
@@ -1784,6 +1784,46 @@ static int qca8k_connect_tag_protocol(st
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|||||||
static int
|
static int
|
||||||
qca8k_setup(struct dsa_switch *ds)
|
qca8k_setup(struct dsa_switch *ds)
|
||||||
{
|
{
|
||||||
@@ -1908,42 +1948,8 @@ qca8k_setup(struct dsa_switch *ds)
|
@@ -1919,42 +1959,8 @@ qca8k_setup(struct dsa_switch *ds)
|
||||||
* missing settings to improve switch stability under load condition.
|
* missing settings to improve switch stability under load condition.
|
||||||
* This problem is limited to qca8337 and other qca8k switch are not affected.
|
* This problem is limited to qca8337 and other qca8k switch are not affected.
|
||||||
*/
|
*/
|
||||||
|
@ -17,7 +17,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|||||||
|
|
||||||
--- a/drivers/net/dsa/qca/qca8k-8xxx.c
|
--- a/drivers/net/dsa/qca/qca8k-8xxx.c
|
||||||
+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
|
+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
|
||||||
@@ -1817,7 +1817,8 @@ static int
|
@@ -1828,7 +1828,8 @@ static int
|
||||||
qca8k_setup(struct dsa_switch *ds)
|
qca8k_setup(struct dsa_switch *ds)
|
||||||
{
|
{
|
||||||
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
|
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
|
||||||
@ -27,7 +27,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|||||||
u32 mask;
|
u32 mask;
|
||||||
|
|
||||||
cpu_port = qca8k_find_cpu_port(ds);
|
cpu_port = qca8k_find_cpu_port(ds);
|
||||||
@@ -1868,27 +1869,27 @@ qca8k_setup(struct dsa_switch *ds)
|
@@ -1879,27 +1880,27 @@ qca8k_setup(struct dsa_switch *ds)
|
||||||
dev_warn(priv->dev, "mib init failed");
|
dev_warn(priv->dev, "mib init failed");
|
||||||
|
|
||||||
/* Initial setup of all ports */
|
/* Initial setup of all ports */
|
||||||
@ -70,7 +70,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Forward all unknown frames to CPU port for Linux processing
|
/* Forward all unknown frames to CPU port for Linux processing
|
||||||
@@ -1910,48 +1911,48 @@ qca8k_setup(struct dsa_switch *ds)
|
@@ -1921,48 +1922,48 @@ qca8k_setup(struct dsa_switch *ds)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* Setup connection between CPU port & user ports
|
/* Setup connection between CPU port & user ports
|
||||||
|
@ -1,106 +0,0 @@
|
|||||||
From 526c8ee04bdbd4d8d19a583b1f3b06700229a815 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
|
|
||||||
Date: Wed, 4 Oct 2023 11:19:04 +0200
|
|
||||||
Subject: [PATCH 2/2] net: dsa: qca8k: fix potential MDIO bus conflict when
|
|
||||||
accessing internal PHYs via management frames
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
Besides the QCA8337 switch the Turris 1.x device has on it's MDIO bus
|
|
||||||
also Micron ethernet PHY (dedicated to the WAN port).
|
|
||||||
|
|
||||||
We've been experiencing a strange behavior of the WAN ethernet
|
|
||||||
interface, wherein the WAN PHY started timing out the MDIO accesses, for
|
|
||||||
example when the interface was brought down and then back up.
|
|
||||||
|
|
||||||
Bisecting led to commit 2cd548566384 ("net: dsa: qca8k: add support for
|
|
||||||
phy read/write with mgmt Ethernet"), which added support to access the
|
|
||||||
QCA8337 switch's internal PHYs via management ethernet frames.
|
|
||||||
|
|
||||||
Connecting the MDIO bus pins onto an oscilloscope, I was able to see
|
|
||||||
that the MDIO bus was active whenever a request to read/write an
|
|
||||||
internal PHY register was done via an management ethernet frame.
|
|
||||||
|
|
||||||
My theory is that when the switch core always communicates with the
|
|
||||||
internal PHYs via the MDIO bus, even when externally we request the
|
|
||||||
access via ethernet. This MDIO bus is the same one via which the switch
|
|
||||||
and internal PHYs are accessible to the board, and the board may have
|
|
||||||
other devices connected on this bus. An ASCII illustration may give more
|
|
||||||
insight:
|
|
||||||
|
|
||||||
+---------+
|
|
||||||
+----| |
|
|
||||||
| | WAN PHY |
|
|
||||||
| +--| |
|
|
||||||
| | +---------+
|
|
||||||
| |
|
|
||||||
| | +----------------------------------+
|
|
||||||
| | | QCA8337 |
|
|
||||||
MDC | | | +-------+ |
|
|
||||||
------o-+--|--------o------------o--| | |
|
|
||||||
MDIO | | | | | PHY 1 |-|--to RJ45
|
|
||||||
--------o--|---o----+---------o--+--| | |
|
|
||||||
| | | | | +-------+ |
|
|
||||||
| +-------------+ | o--| | |
|
|
||||||
| | MDIO MDC | | | | PHY 2 |-|--to RJ45
|
|
||||||
eth1 | | | o--+--| | |
|
|
||||||
-----------|-|port0 | | | +-------+ |
|
|
||||||
| | | | o--| | |
|
|
||||||
| | switch core | | | | PHY 3 |-|--to RJ45
|
|
||||||
| +-------------+ o--+--| | |
|
|
||||||
| | | +-------+ |
|
|
||||||
| | o--| ... | |
|
|
||||||
+----------------------------------+
|
|
||||||
|
|
||||||
When we send a request to read an internal PHY register via an ethernet
|
|
||||||
management frame via eth1, the switch core receives the ethernet frame
|
|
||||||
on port 0 and then communicates with the internal PHY via MDIO. At this
|
|
||||||
time, other potential devices, such as the WAN PHY on Turris 1.x, cannot
|
|
||||||
use the MDIO bus, since it may cause a bus conflict.
|
|
||||||
|
|
||||||
Fix this issue by locking the MDIO bus even when we are accessing the
|
|
||||||
PHY registers via ethernet management frames.
|
|
||||||
|
|
||||||
Fixes: 2cd548566384 ("net: dsa: qca8k: add support for phy read/write with mgmt Ethernet")
|
|
||||||
Signed-off-by: Marek Behún <kabel@kernel.org>
|
|
||||||
Reviewed-by: Christian Marangi <ansuelsmth@gmail.com>
|
|
||||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
||||||
---
|
|
||||||
drivers/net/dsa/qca/qca8k-8xxx.c | 11 +++++++++++
|
|
||||||
1 file changed, 11 insertions(+)
|
|
||||||
|
|
||||||
--- a/drivers/net/dsa/qca/qca8k-8xxx.c
|
|
||||||
+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
|
|
||||||
@@ -665,6 +665,15 @@ qca8k_phy_eth_command(struct qca8k_priv
|
|
||||||
goto err_read_skb;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ /* It seems that accessing the switch's internal PHYs via management
|
|
||||||
+ * packets still uses the MDIO bus within the switch internally, and
|
|
||||||
+ * these accesses can conflict with external MDIO accesses to other
|
|
||||||
+ * devices on the MDIO bus.
|
|
||||||
+ * We therefore need to lock the MDIO bus onto which the switch is
|
|
||||||
+ * connected.
|
|
||||||
+ */
|
|
||||||
+ mutex_lock(&priv->bus->mdio_lock);
|
|
||||||
+
|
|
||||||
/* Actually start the request:
|
|
||||||
* 1. Send mdio master packet
|
|
||||||
* 2. Busy Wait for mdio master command
|
|
||||||
@@ -677,6 +686,7 @@ qca8k_phy_eth_command(struct qca8k_priv
|
|
||||||
mgmt_master = priv->mgmt_master;
|
|
||||||
if (!mgmt_master) {
|
|
||||||
mutex_unlock(&mgmt_eth_data->mutex);
|
|
||||||
+ mutex_unlock(&priv->bus->mdio_lock);
|
|
||||||
ret = -EINVAL;
|
|
||||||
goto err_mgmt_master;
|
|
||||||
}
|
|
||||||
@@ -764,6 +774,7 @@ exit:
|
|
||||||
QCA8K_ETHERNET_TIMEOUT);
|
|
||||||
|
|
||||||
mutex_unlock(&mgmt_eth_data->mutex);
|
|
||||||
+ mutex_unlock(&priv->bus->mdio_lock);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
|||||||
|
From a75b58a46423cfd9b1f73581f4bd2ac2ae743996 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
|
||||||
|
Date: Wed, 2 Aug 2023 18:07:45 +0200
|
||||||
|
Subject: [PATCH 1/6] leds: turris-omnia: Use sysfs_emit() instead of sprintf()
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Use the dedicated sysfs_emit() function instead of sprintf() in sysfs
|
||||||
|
attribute accessor brightness_show().
|
||||||
|
|
||||||
|
Signed-off-by: Marek Behún <kabel@kernel.org>
|
||||||
|
Link: https://lore.kernel.org/r/20230802160748.11208-4-kabel@kernel.org
|
||||||
|
Signed-off-by: Lee Jones <lee@kernel.org>
|
||||||
|
---
|
||||||
|
drivers/leds/leds-turris-omnia.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/drivers/leds/leds-turris-omnia.c
|
||||||
|
+++ b/drivers/leds/leds-turris-omnia.c
|
||||||
|
@@ -166,7 +166,7 @@ static ssize_t brightness_show(struct de
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
- return sprintf(buf, "%d\n", ret);
|
||||||
|
+ return sysfs_emit(buf, "%d\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t brightness_store(struct device *dev, struct device_attribute *a,
|
@ -0,0 +1,64 @@
|
|||||||
|
From 8f3d612a5c949489b2860b74ff34c5914a9216dd Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
|
||||||
|
Date: Wed, 2 Aug 2023 18:07:43 +0200
|
||||||
|
Subject: [PATCH 2/6] leds: turris-omnia: Drop unnecessary mutex locking
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Do not lock driver mutex in the global LED panel brightness sysfs
|
||||||
|
accessors brightness_show() and brightness_store().
|
||||||
|
|
||||||
|
The mutex locking is unnecessary here. The I2C transfers are guarded by
|
||||||
|
I2C core locking mechanism, and the LED commands itself do not interfere
|
||||||
|
with other commands.
|
||||||
|
|
||||||
|
Fixes: 089381b27abe ("leds: initial support for Turris Omnia LEDs")
|
||||||
|
Signed-off-by: Marek Behún <kabel@kernel.org>
|
||||||
|
Reviewed-by: Lee Jones <lee@kernel.org>
|
||||||
|
Link: https://lore.kernel.org/r/20230802160748.11208-2-kabel@kernel.org
|
||||||
|
Signed-off-by: Lee Jones <lee@kernel.org>
|
||||||
|
---
|
||||||
|
drivers/leds/leds-turris-omnia.c | 11 +----------
|
||||||
|
1 file changed, 1 insertion(+), 10 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/leds/leds-turris-omnia.c
|
||||||
|
+++ b/drivers/leds/leds-turris-omnia.c
|
||||||
|
@@ -156,12 +156,9 @@ static ssize_t brightness_show(struct de
|
||||||
|
char *buf)
|
||||||
|
{
|
||||||
|
struct i2c_client *client = to_i2c_client(dev);
|
||||||
|
- struct omnia_leds *leds = i2c_get_clientdata(client);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
- mutex_lock(&leds->lock);
|
||||||
|
ret = i2c_smbus_read_byte_data(client, CMD_LED_GET_BRIGHTNESS);
|
||||||
|
- mutex_unlock(&leds->lock);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
@@ -173,7 +170,6 @@ static ssize_t brightness_store(struct d
|
||||||
|
const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
struct i2c_client *client = to_i2c_client(dev);
|
||||||
|
- struct omnia_leds *leds = i2c_get_clientdata(client);
|
||||||
|
unsigned long brightness;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
@@ -183,15 +179,10 @@ static ssize_t brightness_store(struct d
|
||||||
|
if (brightness > 100)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
- mutex_lock(&leds->lock);
|
||||||
|
ret = i2c_smbus_write_byte_data(client, CMD_LED_SET_BRIGHTNESS,
|
||||||
|
(u8)brightness);
|
||||||
|
- mutex_unlock(&leds->lock);
|
||||||
|
|
||||||
|
- if (ret < 0)
|
||||||
|
- return ret;
|
||||||
|
-
|
||||||
|
- return count;
|
||||||
|
+ return ret < 0 ? ret : count;
|
||||||
|
}
|
||||||
|
static DEVICE_ATTR_RW(brightness);
|
||||||
|
|
@ -0,0 +1,145 @@
|
|||||||
|
From 1848bb28f0579582f653ae95355b544fd8a51d1e Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
|
||||||
|
Date: Mon, 18 Sep 2023 18:11:01 +0200
|
||||||
|
Subject: [PATCH 3/6] leds: turris-omnia: Do not use SMBUS calls
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
The leds-turris-omnia driver uses three function for I2C access:
|
||||||
|
- i2c_smbus_write_byte_data() and i2c_smbus_read_byte_data(), which
|
||||||
|
cause an emulated SMBUS transfer,
|
||||||
|
- i2c_master_send(), which causes an ordinary I2C transfer.
|
||||||
|
|
||||||
|
The Turris Omnia MCU LED controller is not semantically SMBUS, it
|
||||||
|
operates as a simple I2C bus. It does not implement any of the SMBUS
|
||||||
|
specific features, like PEC, or procedure calls, or anything. Moreover
|
||||||
|
the I2C controller driver also does not implement SMBUS, and so the
|
||||||
|
emulated SMBUS procedure from drivers/i2c/i2c-core-smbus.c is used for
|
||||||
|
the SMBUS calls, which gives an unnecessary overhead.
|
||||||
|
|
||||||
|
When I first wrote the driver, I was unaware of these facts, and I
|
||||||
|
simply used the first function that worked.
|
||||||
|
|
||||||
|
Drop the I2C SMBUS calls and instead use simple I2C transfers.
|
||||||
|
|
||||||
|
Fixes: 089381b27abe ("leds: initial support for Turris Omnia LEDs")
|
||||||
|
Signed-off-by: Marek Behún <kabel@kernel.org>
|
||||||
|
Link: https://lore.kernel.org/r/20230918161104.20860-2-kabel@kernel.org
|
||||||
|
Signed-off-by: Lee Jones <lee@kernel.org>
|
||||||
|
---
|
||||||
|
drivers/leds/leds-turris-omnia.c | 54 +++++++++++++++++++++++++-------
|
||||||
|
1 file changed, 42 insertions(+), 12 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/leds/leds-turris-omnia.c
|
||||||
|
+++ b/drivers/leds/leds-turris-omnia.c
|
||||||
|
@@ -2,7 +2,7 @@
|
||||||
|
/*
|
||||||
|
* CZ.NIC's Turris Omnia LEDs driver
|
||||||
|
*
|
||||||
|
- * 2020 by Marek Behún <kabel@kernel.org>
|
||||||
|
+ * 2020, 2023 by Marek Behún <kabel@kernel.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/i2c.h>
|
||||||
|
@@ -41,6 +41,37 @@ struct omnia_leds {
|
||||||
|
struct omnia_led leds[];
|
||||||
|
};
|
||||||
|
|
||||||
|
+static int omnia_cmd_write_u8(const struct i2c_client *client, u8 cmd, u8 val)
|
||||||
|
+{
|
||||||
|
+ u8 buf[2] = { cmd, val };
|
||||||
|
+
|
||||||
|
+ return i2c_master_send(client, buf, sizeof(buf));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int omnia_cmd_read_u8(const struct i2c_client *client, u8 cmd)
|
||||||
|
+{
|
||||||
|
+ struct i2c_msg msgs[2];
|
||||||
|
+ u8 reply;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ msgs[0].addr = client->addr;
|
||||||
|
+ msgs[0].flags = 0;
|
||||||
|
+ msgs[0].len = 1;
|
||||||
|
+ msgs[0].buf = &cmd;
|
||||||
|
+ msgs[1].addr = client->addr;
|
||||||
|
+ msgs[1].flags = I2C_M_RD;
|
||||||
|
+ msgs[1].len = 1;
|
||||||
|
+ msgs[1].buf = &reply;
|
||||||
|
+
|
||||||
|
+ ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
|
||||||
|
+ if (likely(ret == ARRAY_SIZE(msgs)))
|
||||||
|
+ return reply;
|
||||||
|
+ else if (ret < 0)
|
||||||
|
+ return ret;
|
||||||
|
+ else
|
||||||
|
+ return -EIO;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int omnia_led_brightness_set_blocking(struct led_classdev *cdev,
|
||||||
|
enum led_brightness brightness)
|
||||||
|
{
|
||||||
|
@@ -64,7 +95,7 @@ static int omnia_led_brightness_set_bloc
|
||||||
|
if (buf[2] || buf[3] || buf[4])
|
||||||
|
state |= CMD_LED_STATE_ON;
|
||||||
|
|
||||||
|
- ret = i2c_smbus_write_byte_data(leds->client, CMD_LED_STATE, state);
|
||||||
|
+ ret = omnia_cmd_write_u8(leds->client, CMD_LED_STATE, state);
|
||||||
|
if (ret >= 0 && (state & CMD_LED_STATE_ON))
|
||||||
|
ret = i2c_master_send(leds->client, buf, 5);
|
||||||
|
|
||||||
|
@@ -114,9 +145,9 @@ static int omnia_led_register(struct i2c
|
||||||
|
cdev->brightness_set_blocking = omnia_led_brightness_set_blocking;
|
||||||
|
|
||||||
|
/* put the LED into software mode */
|
||||||
|
- ret = i2c_smbus_write_byte_data(client, CMD_LED_MODE,
|
||||||
|
- CMD_LED_MODE_LED(led->reg) |
|
||||||
|
- CMD_LED_MODE_USER);
|
||||||
|
+ ret = omnia_cmd_write_u8(client, CMD_LED_MODE,
|
||||||
|
+ CMD_LED_MODE_LED(led->reg) |
|
||||||
|
+ CMD_LED_MODE_USER);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(dev, "Cannot set LED %pOF to software mode: %i\n", np,
|
||||||
|
ret);
|
||||||
|
@@ -124,8 +155,8 @@ static int omnia_led_register(struct i2c
|
||||||
|
}
|
||||||
|
|
||||||
|
/* disable the LED */
|
||||||
|
- ret = i2c_smbus_write_byte_data(client, CMD_LED_STATE,
|
||||||
|
- CMD_LED_STATE_LED(led->reg));
|
||||||
|
+ ret = omnia_cmd_write_u8(client, CMD_LED_STATE,
|
||||||
|
+ CMD_LED_STATE_LED(led->reg));
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(dev, "Cannot set LED %pOF brightness: %i\n", np, ret);
|
||||||
|
return ret;
|
||||||
|
@@ -158,7 +189,7 @@ static ssize_t brightness_show(struct de
|
||||||
|
struct i2c_client *client = to_i2c_client(dev);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
- ret = i2c_smbus_read_byte_data(client, CMD_LED_GET_BRIGHTNESS);
|
||||||
|
+ ret = omnia_cmd_read_u8(client, CMD_LED_GET_BRIGHTNESS);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
@@ -179,8 +210,7 @@ static ssize_t brightness_store(struct d
|
||||||
|
if (brightness > 100)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
- ret = i2c_smbus_write_byte_data(client, CMD_LED_SET_BRIGHTNESS,
|
||||||
|
- (u8)brightness);
|
||||||
|
+ ret = omnia_cmd_write_u8(client, CMD_LED_SET_BRIGHTNESS, brightness);
|
||||||
|
|
||||||
|
return ret < 0 ? ret : count;
|
||||||
|
}
|
||||||
|
@@ -238,8 +268,8 @@ static void omnia_leds_remove(struct i2c
|
||||||
|
u8 buf[5];
|
||||||
|
|
||||||
|
/* put all LEDs into default (HW triggered) mode */
|
||||||
|
- i2c_smbus_write_byte_data(client, CMD_LED_MODE,
|
||||||
|
- CMD_LED_MODE_LED(OMNIA_BOARD_LEDS));
|
||||||
|
+ omnia_cmd_write_u8(client, CMD_LED_MODE,
|
||||||
|
+ CMD_LED_MODE_LED(OMNIA_BOARD_LEDS));
|
||||||
|
|
||||||
|
/* set all LEDs color to [255, 255, 255] */
|
||||||
|
buf[0] = CMD_LED_COLOR;
|
@ -0,0 +1,207 @@
|
|||||||
|
From a64c3c1357275b1fd61bc9734f638cdb5d8a8bbb Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
|
||||||
|
Date: Mon, 18 Sep 2023 18:11:02 +0200
|
||||||
|
Subject: [PATCH 4/6] leds: turris-omnia: Make set_brightness() more efficient
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Implement caching of the LED color and state values that are sent to MCU
|
||||||
|
in order to make the set_brightness() operation more efficient by
|
||||||
|
avoiding I2C transactions which are not needed.
|
||||||
|
|
||||||
|
On Turris Omnia's MCU, which acts as the RGB LED controller, each LED
|
||||||
|
has a RGB color, and a ON/OFF state, which are configurable via I2C
|
||||||
|
commands CMD_LED_COLOR and CMD_LED_STATE.
|
||||||
|
|
||||||
|
The CMD_LED_COLOR command sends 5 bytes and the CMD_LED_STATE command 2
|
||||||
|
bytes over the I2C bus, which operates at 100 kHz. With I2C overhead
|
||||||
|
this allows ~1670 color changing commands and ~3200 state changing
|
||||||
|
commands per second (or around 1000 color + state changes per second).
|
||||||
|
This may seem more than enough, but the issue is that the I2C bus is
|
||||||
|
shared with another peripheral, the MCU. The MCU exposes an interrupt
|
||||||
|
interface, and it can trigger hundreds of interrupts per second. Each
|
||||||
|
time, we need to read the interrupt state register over this I2C bus.
|
||||||
|
Whenever we are sending a LED color/state changing command, the
|
||||||
|
interrupt reading is waiting.
|
||||||
|
|
||||||
|
Currently, every time LED brightness or LED multi intensity is changed,
|
||||||
|
we send a CMD_LED_STATE command, and if the computed color (brightness
|
||||||
|
adjusted multi_intensity) is non-zero, we also send a CMD_LED_COLOR
|
||||||
|
command.
|
||||||
|
|
||||||
|
Consider for example the situation when we have a netdev trigger enabled
|
||||||
|
for a LED. The netdev trigger does not change the LED color, only the
|
||||||
|
brightness (either to 0 or to currently configured brightness), and so
|
||||||
|
there is no need to send the CMD_LED_COLOR command. But each change of
|
||||||
|
brightness to 0 sends one CMD_LED_STATE command, and each change of
|
||||||
|
brightness to max_brightness sends one CMD_LED_STATE command and one
|
||||||
|
CMD_LED_COLOR command:
|
||||||
|
set_brightness(0) -> CMD_LED_STATE
|
||||||
|
set_brightness(255) -> CMD_LED_STATE + CMD_LED_COLOR
|
||||||
|
(unnecessary)
|
||||||
|
|
||||||
|
We can avoid the unnecessary I2C transactions if we cache the values of
|
||||||
|
state and color that are sent to the controller. If the color does not
|
||||||
|
change from the one previously sent, there is no need to do the
|
||||||
|
CMD_LED_COLOR I2C transaction, and if the state does not change, there
|
||||||
|
is no need to do the CMD_LED_STATE transaction.
|
||||||
|
|
||||||
|
Because we need to make sure that our cached values are consistent with
|
||||||
|
the controller state, add explicit setting of the LED color to white at
|
||||||
|
probe time (this is the default setting when MCU resets, but does not
|
||||||
|
necessarily need to be the case, for example if U-Boot played with the
|
||||||
|
LED colors).
|
||||||
|
|
||||||
|
Signed-off-by: Marek Behún <kabel@kernel.org>
|
||||||
|
Link: https://lore.kernel.org/r/20230918161104.20860-3-kabel@kernel.org
|
||||||
|
Signed-off-by: Lee Jones <lee@kernel.org>
|
||||||
|
---
|
||||||
|
drivers/leds/leds-turris-omnia.c | 96 ++++++++++++++++++++++++++------
|
||||||
|
1 file changed, 78 insertions(+), 18 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/leds/leds-turris-omnia.c
|
||||||
|
+++ b/drivers/leds/leds-turris-omnia.c
|
||||||
|
@@ -30,6 +30,8 @@
|
||||||
|
struct omnia_led {
|
||||||
|
struct led_classdev_mc mc_cdev;
|
||||||
|
struct mc_subled subled_info[OMNIA_LED_NUM_CHANNELS];
|
||||||
|
+ u8 cached_channels[OMNIA_LED_NUM_CHANNELS];
|
||||||
|
+ bool on;
|
||||||
|
int reg;
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -72,36 +74,82 @@ static int omnia_cmd_read_u8(const struc
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int omnia_led_send_color_cmd(const struct i2c_client *client,
|
||||||
|
+ struct omnia_led *led)
|
||||||
|
+{
|
||||||
|
+ char cmd[5];
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ cmd[0] = CMD_LED_COLOR;
|
||||||
|
+ cmd[1] = led->reg;
|
||||||
|
+ cmd[2] = led->subled_info[0].brightness;
|
||||||
|
+ cmd[3] = led->subled_info[1].brightness;
|
||||||
|
+ cmd[4] = led->subled_info[2].brightness;
|
||||||
|
+
|
||||||
|
+ /* Send the color change command */
|
||||||
|
+ ret = i2c_master_send(client, cmd, 5);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ /* Cache the RGB channel brightnesses */
|
||||||
|
+ for (int i = 0; i < OMNIA_LED_NUM_CHANNELS; ++i)
|
||||||
|
+ led->cached_channels[i] = led->subled_info[i].brightness;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Determine if the computed RGB channels are different from the cached ones */
|
||||||
|
+static bool omnia_led_channels_changed(struct omnia_led *led)
|
||||||
|
+{
|
||||||
|
+ for (int i = 0; i < OMNIA_LED_NUM_CHANNELS; ++i)
|
||||||
|
+ if (led->subled_info[i].brightness != led->cached_channels[i])
|
||||||
|
+ return true;
|
||||||
|
+
|
||||||
|
+ return false;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int omnia_led_brightness_set_blocking(struct led_classdev *cdev,
|
||||||
|
enum led_brightness brightness)
|
||||||
|
{
|
||||||
|
struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(cdev);
|
||||||
|
struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent);
|
||||||
|
struct omnia_led *led = to_omnia_led(mc_cdev);
|
||||||
|
- u8 buf[5], state;
|
||||||
|
- int ret;
|
||||||
|
+ int err = 0;
|
||||||
|
|
||||||
|
mutex_lock(&leds->lock);
|
||||||
|
|
||||||
|
- led_mc_calc_color_components(&led->mc_cdev, brightness);
|
||||||
|
+ /*
|
||||||
|
+ * Only recalculate RGB brightnesses from intensities if brightness is
|
||||||
|
+ * non-zero. Otherwise we won't be using them and we can save ourselves
|
||||||
|
+ * some software divisions (Omnia's CPU does not implement the division
|
||||||
|
+ * instruction).
|
||||||
|
+ */
|
||||||
|
+ if (brightness) {
|
||||||
|
+ led_mc_calc_color_components(mc_cdev, brightness);
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Send color command only if brightness is non-zero and the RGB
|
||||||
|
+ * channel brightnesses changed.
|
||||||
|
+ */
|
||||||
|
+ if (omnia_led_channels_changed(led))
|
||||||
|
+ err = omnia_led_send_color_cmd(leds->client, led);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- buf[0] = CMD_LED_COLOR;
|
||||||
|
- buf[1] = led->reg;
|
||||||
|
- buf[2] = mc_cdev->subled_info[0].brightness;
|
||||||
|
- buf[3] = mc_cdev->subled_info[1].brightness;
|
||||||
|
- buf[4] = mc_cdev->subled_info[2].brightness;
|
||||||
|
-
|
||||||
|
- state = CMD_LED_STATE_LED(led->reg);
|
||||||
|
- if (buf[2] || buf[3] || buf[4])
|
||||||
|
- state |= CMD_LED_STATE_ON;
|
||||||
|
-
|
||||||
|
- ret = omnia_cmd_write_u8(leds->client, CMD_LED_STATE, state);
|
||||||
|
- if (ret >= 0 && (state & CMD_LED_STATE_ON))
|
||||||
|
- ret = i2c_master_send(leds->client, buf, 5);
|
||||||
|
+ /* Send on/off state change only if (bool)brightness changed */
|
||||||
|
+ if (!err && !brightness != !led->on) {
|
||||||
|
+ u8 state = CMD_LED_STATE_LED(led->reg);
|
||||||
|
+
|
||||||
|
+ if (brightness)
|
||||||
|
+ state |= CMD_LED_STATE_ON;
|
||||||
|
+
|
||||||
|
+ err = omnia_cmd_write_u8(leds->client, CMD_LED_STATE, state);
|
||||||
|
+ if (!err)
|
||||||
|
+ led->on = !!brightness;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
mutex_unlock(&leds->lock);
|
||||||
|
|
||||||
|
- return ret;
|
||||||
|
+ return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int omnia_led_register(struct i2c_client *client, struct omnia_led *led,
|
||||||
|
@@ -129,11 +177,15 @@ static int omnia_led_register(struct i2c
|
||||||
|
}
|
||||||
|
|
||||||
|
led->subled_info[0].color_index = LED_COLOR_ID_RED;
|
||||||
|
- led->subled_info[0].channel = 0;
|
||||||
|
led->subled_info[1].color_index = LED_COLOR_ID_GREEN;
|
||||||
|
- led->subled_info[1].channel = 1;
|
||||||
|
led->subled_info[2].color_index = LED_COLOR_ID_BLUE;
|
||||||
|
- led->subled_info[2].channel = 2;
|
||||||
|
+
|
||||||
|
+ /* Initial color is white */
|
||||||
|
+ for (int i = 0; i < OMNIA_LED_NUM_CHANNELS; ++i) {
|
||||||
|
+ led->subled_info[i].intensity = 255;
|
||||||
|
+ led->subled_info[i].brightness = 255;
|
||||||
|
+ led->subled_info[i].channel = i;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
led->mc_cdev.subled_info = led->subled_info;
|
||||||
|
led->mc_cdev.num_colors = OMNIA_LED_NUM_CHANNELS;
|
||||||
|
@@ -162,6 +214,14 @@ static int omnia_led_register(struct i2c
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /* Set initial color and cache it */
|
||||||
|
+ ret = omnia_led_send_color_cmd(client, led);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ dev_err(dev, "Cannot set LED %pOF initial color: %i\n", np,
|
||||||
|
+ ret);
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
ret = devm_led_classdev_multicolor_register_ext(dev, &led->mc_cdev,
|
||||||
|
&init_data);
|
||||||
|
if (ret < 0) {
|
@ -0,0 +1,202 @@
|
|||||||
|
From e965e0f6de60874fc0a0caed9a9e0122999e0c7b Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
|
||||||
|
Date: Mon, 18 Sep 2023 18:11:03 +0200
|
||||||
|
Subject: [PATCH 5/6] leds: turris-omnia: Support HW controlled mode via
|
||||||
|
private trigger
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Add support for enabling MCU controlled mode of the Turris Omnia LEDs
|
||||||
|
via a LED private trigger called "omnia-mcu". Recall that private LED
|
||||||
|
triggers will only be listed in the sysfs trigger file for LEDs that
|
||||||
|
support them (currently there is no user of this mechanism).
|
||||||
|
|
||||||
|
When in MCU controlled mode, the user can still set LED color, but the
|
||||||
|
blinking is done by MCU, which does different things for different LEDs:
|
||||||
|
- WAN LED is blinked according to the LED[0] pin of the WAN PHY
|
||||||
|
- LAN LEDs are blinked according to the LED[0] output of the
|
||||||
|
corresponding port of the LAN switch
|
||||||
|
- PCIe LEDs are blinked according to the logical OR of the MiniPCIe port
|
||||||
|
LED pins
|
||||||
|
|
||||||
|
In the future I want to make the netdev trigger to transparently offload
|
||||||
|
the blinking to the HW if user sets compatible settings for the netdev
|
||||||
|
trigger (for LEDs associated with network devices).
|
||||||
|
There was some work on this already, and hopefully we will be able to
|
||||||
|
complete it sometime, but for now there are still multiple blockers for
|
||||||
|
this, and even if there weren't, we still would not be able to configure
|
||||||
|
HW controlled mode for the LEDs associated with MiniPCIe ports.
|
||||||
|
|
||||||
|
In the meantime let's support HW controlled mode via the private LED
|
||||||
|
trigger mechanism. If, in the future, we manage to complete the netdev
|
||||||
|
trigger offloading, we can still keep this private trigger for backwards
|
||||||
|
compatibility, if needed.
|
||||||
|
|
||||||
|
We also set "omnia-mcu" to cdev->default_trigger, so that the MCU keeps
|
||||||
|
control until the user first wants to take over it. If a different
|
||||||
|
default trigger is specified in device-tree via the
|
||||||
|
'linux,default-trigger' property, LED class will overwrite
|
||||||
|
cdev->default_trigger, and so the DT property will be respected.
|
||||||
|
|
||||||
|
Signed-off-by: Marek Behún <kabel@kernel.org>
|
||||||
|
Link: https://lore.kernel.org/r/20230918161104.20860-4-kabel@kernel.org
|
||||||
|
Signed-off-by: Lee Jones <lee@kernel.org>
|
||||||
|
---
|
||||||
|
drivers/leds/Kconfig | 1 +
|
||||||
|
drivers/leds/leds-turris-omnia.c | 98 +++++++++++++++++++++++++++++---
|
||||||
|
2 files changed, 91 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/leds/Kconfig
|
||||||
|
+++ b/drivers/leds/Kconfig
|
||||||
|
@@ -163,6 +163,7 @@ config LEDS_TURRIS_OMNIA
|
||||||
|
depends on I2C
|
||||||
|
depends on MACH_ARMADA_38X || COMPILE_TEST
|
||||||
|
depends on OF
|
||||||
|
+ select LEDS_TRIGGERS
|
||||||
|
help
|
||||||
|
This option enables basic support for the LEDs found on the front
|
||||||
|
side of CZ.NIC's Turris Omnia router. There are 12 RGB LEDs on the
|
||||||
|
--- a/drivers/leds/leds-turris-omnia.c
|
||||||
|
+++ b/drivers/leds/leds-turris-omnia.c
|
||||||
|
@@ -31,7 +31,7 @@ struct omnia_led {
|
||||||
|
struct led_classdev_mc mc_cdev;
|
||||||
|
struct mc_subled subled_info[OMNIA_LED_NUM_CHANNELS];
|
||||||
|
u8 cached_channels[OMNIA_LED_NUM_CHANNELS];
|
||||||
|
- bool on;
|
||||||
|
+ bool on, hwtrig;
|
||||||
|
int reg;
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -120,12 +120,14 @@ static int omnia_led_brightness_set_bloc
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Only recalculate RGB brightnesses from intensities if brightness is
|
||||||
|
- * non-zero. Otherwise we won't be using them and we can save ourselves
|
||||||
|
- * some software divisions (Omnia's CPU does not implement the division
|
||||||
|
- * instruction).
|
||||||
|
+ * non-zero (if it is zero and the LED is in HW blinking mode, we use
|
||||||
|
+ * max_brightness as brightness). Otherwise we won't be using them and
|
||||||
|
+ * we can save ourselves some software divisions (Omnia's CPU does not
|
||||||
|
+ * implement the division instruction).
|
||||||
|
*/
|
||||||
|
- if (brightness) {
|
||||||
|
- led_mc_calc_color_components(mc_cdev, brightness);
|
||||||
|
+ if (brightness || led->hwtrig) {
|
||||||
|
+ led_mc_calc_color_components(mc_cdev, brightness ?:
|
||||||
|
+ cdev->max_brightness);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send color command only if brightness is non-zero and the RGB
|
||||||
|
@@ -135,8 +137,11 @@ static int omnia_led_brightness_set_bloc
|
||||||
|
err = omnia_led_send_color_cmd(leds->client, led);
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* Send on/off state change only if (bool)brightness changed */
|
||||||
|
- if (!err && !brightness != !led->on) {
|
||||||
|
+ /*
|
||||||
|
+ * Send on/off state change only if (bool)brightness changed and the LED
|
||||||
|
+ * is not being blinked by HW.
|
||||||
|
+ */
|
||||||
|
+ if (!err && !led->hwtrig && !brightness != !led->on) {
|
||||||
|
u8 state = CMD_LED_STATE_LED(led->reg);
|
||||||
|
|
||||||
|
if (brightness)
|
||||||
|
@@ -152,6 +157,71 @@ static int omnia_led_brightness_set_bloc
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static struct led_hw_trigger_type omnia_hw_trigger_type;
|
||||||
|
+
|
||||||
|
+static int omnia_hwtrig_activate(struct led_classdev *cdev)
|
||||||
|
+{
|
||||||
|
+ struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(cdev);
|
||||||
|
+ struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent);
|
||||||
|
+ struct omnia_led *led = to_omnia_led(mc_cdev);
|
||||||
|
+ int err = 0;
|
||||||
|
+
|
||||||
|
+ mutex_lock(&leds->lock);
|
||||||
|
+
|
||||||
|
+ if (!led->on) {
|
||||||
|
+ /*
|
||||||
|
+ * If the LED is off (brightness was set to 0), the last
|
||||||
|
+ * configured color was not necessarily sent to the MCU.
|
||||||
|
+ * Recompute with max_brightness and send if needed.
|
||||||
|
+ */
|
||||||
|
+ led_mc_calc_color_components(mc_cdev, cdev->max_brightness);
|
||||||
|
+
|
||||||
|
+ if (omnia_led_channels_changed(led))
|
||||||
|
+ err = omnia_led_send_color_cmd(leds->client, led);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!err) {
|
||||||
|
+ /* Put the LED into MCU controlled mode */
|
||||||
|
+ err = omnia_cmd_write_u8(leds->client, CMD_LED_MODE,
|
||||||
|
+ CMD_LED_MODE_LED(led->reg));
|
||||||
|
+ if (!err)
|
||||||
|
+ led->hwtrig = true;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ mutex_unlock(&leds->lock);
|
||||||
|
+
|
||||||
|
+ return err;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void omnia_hwtrig_deactivate(struct led_classdev *cdev)
|
||||||
|
+{
|
||||||
|
+ struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent);
|
||||||
|
+ struct omnia_led *led = to_omnia_led(lcdev_to_mccdev(cdev));
|
||||||
|
+ int err;
|
||||||
|
+
|
||||||
|
+ mutex_lock(&leds->lock);
|
||||||
|
+
|
||||||
|
+ led->hwtrig = false;
|
||||||
|
+
|
||||||
|
+ /* Put the LED into software mode */
|
||||||
|
+ err = omnia_cmd_write_u8(leds->client, CMD_LED_MODE,
|
||||||
|
+ CMD_LED_MODE_LED(led->reg) |
|
||||||
|
+ CMD_LED_MODE_USER);
|
||||||
|
+
|
||||||
|
+ mutex_unlock(&leds->lock);
|
||||||
|
+
|
||||||
|
+ if (err < 0)
|
||||||
|
+ dev_err(cdev->dev, "Cannot put LED to software mode: %i\n",
|
||||||
|
+ err);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct led_trigger omnia_hw_trigger = {
|
||||||
|
+ .name = "omnia-mcu",
|
||||||
|
+ .activate = omnia_hwtrig_activate,
|
||||||
|
+ .deactivate = omnia_hwtrig_deactivate,
|
||||||
|
+ .trigger_type = &omnia_hw_trigger_type,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
static int omnia_led_register(struct i2c_client *client, struct omnia_led *led,
|
||||||
|
struct device_node *np)
|
||||||
|
{
|
||||||
|
@@ -195,6 +265,12 @@ static int omnia_led_register(struct i2c
|
||||||
|
cdev = &led->mc_cdev.led_cdev;
|
||||||
|
cdev->max_brightness = 255;
|
||||||
|
cdev->brightness_set_blocking = omnia_led_brightness_set_blocking;
|
||||||
|
+ cdev->trigger_type = &omnia_hw_trigger_type;
|
||||||
|
+ /*
|
||||||
|
+ * Use the omnia-mcu trigger as the default trigger. It may be rewritten
|
||||||
|
+ * by LED class from the linux,default-trigger property.
|
||||||
|
+ */
|
||||||
|
+ cdev->default_trigger = omnia_hw_trigger.name;
|
||||||
|
|
||||||
|
/* put the LED into software mode */
|
||||||
|
ret = omnia_cmd_write_u8(client, CMD_LED_MODE,
|
||||||
|
@@ -309,6 +385,12 @@ static int omnia_leds_probe(struct i2c_c
|
||||||
|
|
||||||
|
mutex_init(&leds->lock);
|
||||||
|
|
||||||
|
+ ret = devm_led_trigger_register(dev, &omnia_hw_trigger);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ dev_err(dev, "Cannot register private LED trigger: %d\n", ret);
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
led = &leds->leds[0];
|
||||||
|
for_each_available_child_of_node(np, child) {
|
||||||
|
ret = omnia_led_register(client, led, child);
|
@ -0,0 +1,244 @@
|
|||||||
|
From 0efb3f9609d3de5a7d8c31e3835d7eb3e6adce79 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
|
||||||
|
Date: Mon, 18 Sep 2023 18:11:04 +0200
|
||||||
|
Subject: [PATCH 6/6] leds: turris-omnia: Add support for enabling/disabling HW
|
||||||
|
gamma correction
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
If the MCU on Turris Omnia is running newer firmware versions, the LED
|
||||||
|
controller supports RGB gamma correction (and enables it by default for
|
||||||
|
newer boards).
|
||||||
|
|
||||||
|
Determine whether the gamma correction setting feature is supported and
|
||||||
|
add the ability to set it via sysfs attribute file.
|
||||||
|
|
||||||
|
Signed-off-by: Marek Behún <kabel@kernel.org>
|
||||||
|
Link: https://lore.kernel.org/r/20230918161104.20860-5-kabel@kernel.org
|
||||||
|
Signed-off-by: Lee Jones <lee@kernel.org>
|
||||||
|
---
|
||||||
|
.../sysfs-class-led-driver-turris-omnia | 14 ++
|
||||||
|
drivers/leds/leds-turris-omnia.c | 137 +++++++++++++++---
|
||||||
|
2 files changed, 134 insertions(+), 17 deletions(-)
|
||||||
|
|
||||||
|
--- a/Documentation/ABI/testing/sysfs-class-led-driver-turris-omnia
|
||||||
|
+++ b/Documentation/ABI/testing/sysfs-class-led-driver-turris-omnia
|
||||||
|
@@ -12,3 +12,17 @@ Description: (RW) On the front panel of
|
||||||
|
able to change this setting from software.
|
||||||
|
|
||||||
|
Format: %i
|
||||||
|
+
|
||||||
|
+What: /sys/class/leds/<led>/device/gamma_correction
|
||||||
|
+Date: August 2023
|
||||||
|
+KernelVersion: 6.6
|
||||||
|
+Contact: Marek Behún <kabel@kernel.org>
|
||||||
|
+Description: (RW) Newer versions of the microcontroller firmware of the
|
||||||
|
+ Turris Omnia router support gamma correction for the RGB LEDs.
|
||||||
|
+ This feature can be enabled/disabled by writing to this file.
|
||||||
|
+
|
||||||
|
+ If the feature is not supported because the MCU firmware is too
|
||||||
|
+ old, the file always reads as 0, and writing to the file results
|
||||||
|
+ in the EOPNOTSUPP error.
|
||||||
|
+
|
||||||
|
+ Format: %i
|
||||||
|
--- a/drivers/leds/leds-turris-omnia.c
|
||||||
|
+++ b/drivers/leds/leds-turris-omnia.c
|
||||||
|
@@ -15,17 +15,30 @@
|
||||||
|
#define OMNIA_BOARD_LEDS 12
|
||||||
|
#define OMNIA_LED_NUM_CHANNELS 3
|
||||||
|
|
||||||
|
-#define CMD_LED_MODE 3
|
||||||
|
-#define CMD_LED_MODE_LED(l) ((l) & 0x0f)
|
||||||
|
-#define CMD_LED_MODE_USER 0x10
|
||||||
|
-
|
||||||
|
-#define CMD_LED_STATE 4
|
||||||
|
-#define CMD_LED_STATE_LED(l) ((l) & 0x0f)
|
||||||
|
-#define CMD_LED_STATE_ON 0x10
|
||||||
|
-
|
||||||
|
-#define CMD_LED_COLOR 5
|
||||||
|
-#define CMD_LED_SET_BRIGHTNESS 7
|
||||||
|
-#define CMD_LED_GET_BRIGHTNESS 8
|
||||||
|
+/* MCU controller commands at I2C address 0x2a */
|
||||||
|
+#define OMNIA_MCU_I2C_ADDR 0x2a
|
||||||
|
+
|
||||||
|
+#define CMD_GET_STATUS_WORD 0x01
|
||||||
|
+#define STS_FEATURES_SUPPORTED BIT(2)
|
||||||
|
+
|
||||||
|
+#define CMD_GET_FEATURES 0x10
|
||||||
|
+#define FEAT_LED_GAMMA_CORRECTION BIT(5)
|
||||||
|
+
|
||||||
|
+/* LED controller commands at I2C address 0x2b */
|
||||||
|
+#define CMD_LED_MODE 0x03
|
||||||
|
+#define CMD_LED_MODE_LED(l) ((l) & 0x0f)
|
||||||
|
+#define CMD_LED_MODE_USER 0x10
|
||||||
|
+
|
||||||
|
+#define CMD_LED_STATE 0x04
|
||||||
|
+#define CMD_LED_STATE_LED(l) ((l) & 0x0f)
|
||||||
|
+#define CMD_LED_STATE_ON 0x10
|
||||||
|
+
|
||||||
|
+#define CMD_LED_COLOR 0x05
|
||||||
|
+#define CMD_LED_SET_BRIGHTNESS 0x07
|
||||||
|
+#define CMD_LED_GET_BRIGHTNESS 0x08
|
||||||
|
+
|
||||||
|
+#define CMD_SET_GAMMA_CORRECTION 0x30
|
||||||
|
+#define CMD_GET_GAMMA_CORRECTION 0x31
|
||||||
|
|
||||||
|
struct omnia_led {
|
||||||
|
struct led_classdev_mc mc_cdev;
|
||||||
|
@@ -40,6 +53,7 @@ struct omnia_led {
|
||||||
|
struct omnia_leds {
|
||||||
|
struct i2c_client *client;
|
||||||
|
struct mutex lock;
|
||||||
|
+ bool has_gamma_correction;
|
||||||
|
struct omnia_led leds[];
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -50,30 +64,42 @@ static int omnia_cmd_write_u8(const stru
|
||||||
|
return i2c_master_send(client, buf, sizeof(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int omnia_cmd_read_u8(const struct i2c_client *client, u8 cmd)
|
||||||
|
+static int omnia_cmd_read_raw(struct i2c_adapter *adapter, u8 addr, u8 cmd,
|
||||||
|
+ void *reply, size_t len)
|
||||||
|
{
|
||||||
|
struct i2c_msg msgs[2];
|
||||||
|
- u8 reply;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
- msgs[0].addr = client->addr;
|
||||||
|
+ msgs[0].addr = addr;
|
||||||
|
msgs[0].flags = 0;
|
||||||
|
msgs[0].len = 1;
|
||||||
|
msgs[0].buf = &cmd;
|
||||||
|
- msgs[1].addr = client->addr;
|
||||||
|
+ msgs[1].addr = addr;
|
||||||
|
msgs[1].flags = I2C_M_RD;
|
||||||
|
- msgs[1].len = 1;
|
||||||
|
- msgs[1].buf = &reply;
|
||||||
|
+ msgs[1].len = len;
|
||||||
|
+ msgs[1].buf = reply;
|
||||||
|
|
||||||
|
- ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
|
||||||
|
+ ret = i2c_transfer(adapter, msgs, ARRAY_SIZE(msgs));
|
||||||
|
if (likely(ret == ARRAY_SIZE(msgs)))
|
||||||
|
- return reply;
|
||||||
|
+ return len;
|
||||||
|
else if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
else
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int omnia_cmd_read_u8(const struct i2c_client *client, u8 cmd)
|
||||||
|
+{
|
||||||
|
+ u8 reply;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ ret = omnia_cmd_read_raw(client->adapter, client->addr, cmd, &reply, 1);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ return reply;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int omnia_led_send_color_cmd(const struct i2c_client *client,
|
||||||
|
struct omnia_led *led)
|
||||||
|
{
|
||||||
|
@@ -352,12 +378,74 @@ static ssize_t brightness_store(struct d
|
||||||
|
}
|
||||||
|
static DEVICE_ATTR_RW(brightness);
|
||||||
|
|
||||||
|
+static ssize_t gamma_correction_show(struct device *dev,
|
||||||
|
+ struct device_attribute *a, char *buf)
|
||||||
|
+{
|
||||||
|
+ struct i2c_client *client = to_i2c_client(dev);
|
||||||
|
+ struct omnia_leds *leds = i2c_get_clientdata(client);
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ if (leds->has_gamma_correction) {
|
||||||
|
+ ret = omnia_cmd_read_u8(client, CMD_GET_GAMMA_CORRECTION);
|
||||||
|
+ if (ret < 0)
|
||||||
|
+ return ret;
|
||||||
|
+ } else {
|
||||||
|
+ ret = 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return sysfs_emit(buf, "%d\n", !!ret);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static ssize_t gamma_correction_store(struct device *dev,
|
||||||
|
+ struct device_attribute *a,
|
||||||
|
+ const char *buf, size_t count)
|
||||||
|
+{
|
||||||
|
+ struct i2c_client *client = to_i2c_client(dev);
|
||||||
|
+ struct omnia_leds *leds = i2c_get_clientdata(client);
|
||||||
|
+ bool val;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ if (!leds->has_gamma_correction)
|
||||||
|
+ return -EOPNOTSUPP;
|
||||||
|
+
|
||||||
|
+ if (kstrtobool(buf, &val) < 0)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ ret = omnia_cmd_write_u8(client, CMD_SET_GAMMA_CORRECTION, val);
|
||||||
|
+
|
||||||
|
+ return ret < 0 ? ret : count;
|
||||||
|
+}
|
||||||
|
+static DEVICE_ATTR_RW(gamma_correction);
|
||||||
|
+
|
||||||
|
static struct attribute *omnia_led_controller_attrs[] = {
|
||||||
|
&dev_attr_brightness.attr,
|
||||||
|
+ &dev_attr_gamma_correction.attr,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
ATTRIBUTE_GROUPS(omnia_led_controller);
|
||||||
|
|
||||||
|
+static int omnia_mcu_get_features(const struct i2c_client *client)
|
||||||
|
+{
|
||||||
|
+ u16 reply;
|
||||||
|
+ int err;
|
||||||
|
+
|
||||||
|
+ err = omnia_cmd_read_raw(client->adapter, OMNIA_MCU_I2C_ADDR,
|
||||||
|
+ CMD_GET_STATUS_WORD, &reply, sizeof(reply));
|
||||||
|
+ if (err < 0)
|
||||||
|
+ return err;
|
||||||
|
+
|
||||||
|
+ /* Check whether MCU firmware supports the CMD_GET_FEAUTRES command */
|
||||||
|
+ if (!(le16_to_cpu(reply) & STS_FEATURES_SUPPORTED))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ err = omnia_cmd_read_raw(client->adapter, OMNIA_MCU_I2C_ADDR,
|
||||||
|
+ CMD_GET_FEATURES, &reply, sizeof(reply));
|
||||||
|
+ if (err < 0)
|
||||||
|
+ return err;
|
||||||
|
+
|
||||||
|
+ return le16_to_cpu(reply);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int omnia_leds_probe(struct i2c_client *client,
|
||||||
|
const struct i2c_device_id *id)
|
||||||
|
{
|
||||||
|
@@ -383,6 +471,21 @@ static int omnia_leds_probe(struct i2c_c
|
||||||
|
leds->client = client;
|
||||||
|
i2c_set_clientdata(client, leds);
|
||||||
|
|
||||||
|
+ ret = omnia_mcu_get_features(client);
|
||||||
|
+ if (ret < 0) {
|
||||||
|
+ dev_err(dev, "Cannot determine MCU supported features: %d\n",
|
||||||
|
+ ret);
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ leds->has_gamma_correction = ret & FEAT_LED_GAMMA_CORRECTION;
|
||||||
|
+ if (!leds->has_gamma_correction) {
|
||||||
|
+ dev_info(dev,
|
||||||
|
+ "Your board's MCU firmware does not support the LED gamma correction feature.\n");
|
||||||
|
+ dev_info(dev,
|
||||||
|
+ "Consider upgrading MCU firmware with the omnia-mcutool utility.\n");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
mutex_init(&leds->lock);
|
||||||
|
|
||||||
|
ret = devm_led_trigger_register(dev, &omnia_hw_trigger);
|
@ -0,0 +1,167 @@
|
|||||||
|
From ffec49d391c5f0195360912b216aa24dbc9b53c8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
|
||||||
|
Date: Mon, 16 Oct 2023 16:15:38 +0200
|
||||||
|
Subject: [PATCH] leds: turris-omnia: Fix brightness setting and trigger
|
||||||
|
activating
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
I have improperly refactored commits
|
||||||
|
4d5ed2621c24 ("leds: turris-omnia: Make set_brightness() more efficient")
|
||||||
|
and
|
||||||
|
aaf38273cf76 ("leds: turris-omnia: Support HW controlled mode via private trigger")
|
||||||
|
after Lee requested a change in API semantics of the new functions I
|
||||||
|
introduced in commit
|
||||||
|
28350bc0ac77 ("leds: turris-omnia: Do not use SMBUS calls").
|
||||||
|
|
||||||
|
Before the change, the function omnia_cmd_write_u8() returned 0 on
|
||||||
|
success, and afterwards it returned a positive value (number of bytes
|
||||||
|
written). The latter version was applied, but the following commits did
|
||||||
|
not properly account for this change.
|
||||||
|
|
||||||
|
This results in non-functional LED's .brightness_set_blocking() and
|
||||||
|
trigger's .activate() methods.
|
||||||
|
|
||||||
|
The main reasoning behind the semantics change was that read/write
|
||||||
|
methods should return the number of read/written bytes on success.
|
||||||
|
It was pointed to me [1] that this is not always true (for example the
|
||||||
|
regmap API does not do so), and since the driver never uses this number
|
||||||
|
of read/written bytes information, I decided to fix this issue by
|
||||||
|
changing the functions to the original semantics (return 0 on success).
|
||||||
|
|
||||||
|
[1] https://lore.kernel.org/linux-gpio/ZQnn+Gi0xVlsGCYA@smile.fi.intel.com/
|
||||||
|
|
||||||
|
Fixes: 28350bc0ac77 ("leds: turris-omnia: Do not use SMBUS calls")
|
||||||
|
Signed-off-by: Marek Behún <kabel@kernel.org>
|
||||||
|
---
|
||||||
|
drivers/leds/leds-turris-omnia.c | 37 +++++++++++++++++---------------
|
||||||
|
1 file changed, 20 insertions(+), 17 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/leds/leds-turris-omnia.c
|
||||||
|
+++ b/drivers/leds/leds-turris-omnia.c
|
||||||
|
@@ -60,8 +60,11 @@ struct omnia_leds {
|
||||||
|
static int omnia_cmd_write_u8(const struct i2c_client *client, u8 cmd, u8 val)
|
||||||
|
{
|
||||||
|
u8 buf[2] = { cmd, val };
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ ret = i2c_master_send(client, buf, sizeof(buf));
|
||||||
|
|
||||||
|
- return i2c_master_send(client, buf, sizeof(buf));
|
||||||
|
+ return ret < 0 ? ret : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int omnia_cmd_read_raw(struct i2c_adapter *adapter, u8 addr, u8 cmd,
|
||||||
|
@@ -81,7 +84,7 @@ static int omnia_cmd_read_raw(struct i2c
|
||||||
|
|
||||||
|
ret = i2c_transfer(adapter, msgs, ARRAY_SIZE(msgs));
|
||||||
|
if (likely(ret == ARRAY_SIZE(msgs)))
|
||||||
|
- return len;
|
||||||
|
+ return 0;
|
||||||
|
else if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
else
|
||||||
|
@@ -91,11 +94,11 @@ static int omnia_cmd_read_raw(struct i2c
|
||||||
|
static int omnia_cmd_read_u8(const struct i2c_client *client, u8 cmd)
|
||||||
|
{
|
||||||
|
u8 reply;
|
||||||
|
- int ret;
|
||||||
|
+ int err;
|
||||||
|
|
||||||
|
- ret = omnia_cmd_read_raw(client->adapter, client->addr, cmd, &reply, 1);
|
||||||
|
- if (ret < 0)
|
||||||
|
- return ret;
|
||||||
|
+ err = omnia_cmd_read_raw(client->adapter, client->addr, cmd, &reply, 1);
|
||||||
|
+ if (err)
|
||||||
|
+ return err;
|
||||||
|
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
@@ -236,7 +239,7 @@ static void omnia_hwtrig_deactivate(stru
|
||||||
|
|
||||||
|
mutex_unlock(&leds->lock);
|
||||||
|
|
||||||
|
- if (err < 0)
|
||||||
|
+ if (err)
|
||||||
|
dev_err(cdev->dev, "Cannot put LED to software mode: %i\n",
|
||||||
|
err);
|
||||||
|
}
|
||||||
|
@@ -302,7 +305,7 @@ static int omnia_led_register(struct i2c
|
||||||
|
ret = omnia_cmd_write_u8(client, CMD_LED_MODE,
|
||||||
|
CMD_LED_MODE_LED(led->reg) |
|
||||||
|
CMD_LED_MODE_USER);
|
||||||
|
- if (ret < 0) {
|
||||||
|
+ if (ret) {
|
||||||
|
dev_err(dev, "Cannot set LED %pOF to software mode: %i\n", np,
|
||||||
|
ret);
|
||||||
|
return ret;
|
||||||
|
@@ -311,7 +314,7 @@ static int omnia_led_register(struct i2c
|
||||||
|
/* disable the LED */
|
||||||
|
ret = omnia_cmd_write_u8(client, CMD_LED_STATE,
|
||||||
|
CMD_LED_STATE_LED(led->reg));
|
||||||
|
- if (ret < 0) {
|
||||||
|
+ if (ret) {
|
||||||
|
dev_err(dev, "Cannot set LED %pOF brightness: %i\n", np, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@@ -364,7 +367,7 @@ static ssize_t brightness_store(struct d
|
||||||
|
{
|
||||||
|
struct i2c_client *client = to_i2c_client(dev);
|
||||||
|
unsigned long brightness;
|
||||||
|
- int ret;
|
||||||
|
+ int err;
|
||||||
|
|
||||||
|
if (kstrtoul(buf, 10, &brightness))
|
||||||
|
return -EINVAL;
|
||||||
|
@@ -372,9 +375,9 @@ static ssize_t brightness_store(struct d
|
||||||
|
if (brightness > 100)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
- ret = omnia_cmd_write_u8(client, CMD_LED_SET_BRIGHTNESS, brightness);
|
||||||
|
+ err = omnia_cmd_write_u8(client, CMD_LED_SET_BRIGHTNESS, brightness);
|
||||||
|
|
||||||
|
- return ret < 0 ? ret : count;
|
||||||
|
+ return err ?: count;
|
||||||
|
}
|
||||||
|
static DEVICE_ATTR_RW(brightness);
|
||||||
|
|
||||||
|
@@ -403,7 +406,7 @@ static ssize_t gamma_correction_store(st
|
||||||
|
struct i2c_client *client = to_i2c_client(dev);
|
||||||
|
struct omnia_leds *leds = i2c_get_clientdata(client);
|
||||||
|
bool val;
|
||||||
|
- int ret;
|
||||||
|
+ int err;
|
||||||
|
|
||||||
|
if (!leds->has_gamma_correction)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
@@ -411,9 +414,9 @@ static ssize_t gamma_correction_store(st
|
||||||
|
if (kstrtobool(buf, &val) < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
- ret = omnia_cmd_write_u8(client, CMD_SET_GAMMA_CORRECTION, val);
|
||||||
|
+ err = omnia_cmd_write_u8(client, CMD_SET_GAMMA_CORRECTION, val);
|
||||||
|
|
||||||
|
- return ret < 0 ? ret : count;
|
||||||
|
+ return err ?: count;
|
||||||
|
}
|
||||||
|
static DEVICE_ATTR_RW(gamma_correction);
|
||||||
|
|
||||||
|
@@ -431,7 +434,7 @@ static int omnia_mcu_get_features(const
|
||||||
|
|
||||||
|
err = omnia_cmd_read_raw(client->adapter, OMNIA_MCU_I2C_ADDR,
|
||||||
|
CMD_GET_STATUS_WORD, &reply, sizeof(reply));
|
||||||
|
- if (err < 0)
|
||||||
|
+ if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
/* Check whether MCU firmware supports the CMD_GET_FEAUTRES command */
|
||||||
|
@@ -440,7 +443,7 @@ static int omnia_mcu_get_features(const
|
||||||
|
|
||||||
|
err = omnia_cmd_read_raw(client->adapter, OMNIA_MCU_I2C_ADDR,
|
||||||
|
CMD_GET_FEATURES, &reply, sizeof(reply));
|
||||||
|
- if (err < 0)
|
||||||
|
+ if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
return le16_to_cpu(reply);
|
@ -105,7 +105,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
help
|
help
|
||||||
--- a/net/core/dev.c
|
--- a/net/core/dev.c
|
||||||
+++ b/net/core/dev.c
|
+++ b/net/core/dev.c
|
||||||
@@ -3575,6 +3575,11 @@ static int xmit_one(struct sk_buff *skb,
|
@@ -3579,6 +3579,11 @@ static int xmit_one(struct sk_buff *skb,
|
||||||
if (dev_nit_active(dev))
|
if (dev_nit_active(dev))
|
||||||
dev_queue_xmit_nit(skb, dev);
|
dev_queue_xmit_nit(skb, dev);
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
|
|
||||||
--- a/net/core/dev.c
|
--- a/net/core/dev.c
|
||||||
+++ b/net/core/dev.c
|
+++ b/net/core/dev.c
|
||||||
@@ -7593,6 +7593,48 @@ static void __netdev_adjacent_dev_unlink
|
@@ -7597,6 +7597,48 @@ static void __netdev_adjacent_dev_unlink
|
||||||
&upper_dev->adj_list.lower);
|
&upper_dev->adj_list.lower);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,7 +93,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
static int __netdev_upper_dev_link(struct net_device *dev,
|
static int __netdev_upper_dev_link(struct net_device *dev,
|
||||||
struct net_device *upper_dev, bool master,
|
struct net_device *upper_dev, bool master,
|
||||||
void *upper_priv, void *upper_info,
|
void *upper_priv, void *upper_info,
|
||||||
@@ -7644,6 +7686,7 @@ static int __netdev_upper_dev_link(struc
|
@@ -7648,6 +7690,7 @@ static int __netdev_upper_dev_link(struc
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -101,7 +101,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
ret = call_netdevice_notifiers_info(NETDEV_CHANGEUPPER,
|
ret = call_netdevice_notifiers_info(NETDEV_CHANGEUPPER,
|
||||||
&changeupper_info.info);
|
&changeupper_info.info);
|
||||||
ret = notifier_to_errno(ret);
|
ret = notifier_to_errno(ret);
|
||||||
@@ -7740,6 +7783,7 @@ static void __netdev_upper_dev_unlink(st
|
@@ -7744,6 +7787,7 @@ static void __netdev_upper_dev_unlink(st
|
||||||
|
|
||||||
__netdev_adjacent_dev_unlink_neighbour(dev, upper_dev);
|
__netdev_adjacent_dev_unlink_neighbour(dev, upper_dev);
|
||||||
|
|
||||||
@ -109,7 +109,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
call_netdevice_notifiers_info(NETDEV_CHANGEUPPER,
|
call_netdevice_notifiers_info(NETDEV_CHANGEUPPER,
|
||||||
&changeupper_info.info);
|
&changeupper_info.info);
|
||||||
|
|
||||||
@@ -8792,6 +8836,7 @@ int dev_set_mac_address(struct net_devic
|
@@ -8796,6 +8840,7 @@ int dev_set_mac_address(struct net_devic
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
dev->addr_assign_type = NET_ADDR_SET;
|
dev->addr_assign_type = NET_ADDR_SET;
|
||||||
|
@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
#endif
|
#endif
|
||||||
--- a/net/core/dev.c
|
--- a/net/core/dev.c
|
||||||
+++ b/net/core/dev.c
|
+++ b/net/core/dev.c
|
||||||
@@ -4593,7 +4593,7 @@ static int napi_schedule_rps(struct soft
|
@@ -4597,7 +4597,7 @@ static int napi_schedule_rps(struct soft
|
||||||
struct softnet_data *mysd = this_cpu_ptr(&softnet_data);
|
struct softnet_data *mysd = this_cpu_ptr(&softnet_data);
|
||||||
|
|
||||||
#ifdef CONFIG_RPS
|
#ifdef CONFIG_RPS
|
||||||
@ -39,7 +39,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
sd->rps_ipi_next = mysd->rps_ipi_list;
|
sd->rps_ipi_next = mysd->rps_ipi_list;
|
||||||
mysd->rps_ipi_list = sd;
|
mysd->rps_ipi_list = sd;
|
||||||
|
|
||||||
@@ -5774,6 +5774,8 @@ static DEFINE_PER_CPU(struct work_struct
|
@@ -5778,6 +5778,8 @@ static DEFINE_PER_CPU(struct work_struct
|
||||||
/* Network device is going away, flush any packets still pending */
|
/* Network device is going away, flush any packets still pending */
|
||||||
static void flush_backlog(struct work_struct *work)
|
static void flush_backlog(struct work_struct *work)
|
||||||
{
|
{
|
||||||
@ -48,7 +48,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
struct sk_buff *skb, *tmp;
|
struct sk_buff *skb, *tmp;
|
||||||
struct softnet_data *sd;
|
struct softnet_data *sd;
|
||||||
|
|
||||||
@@ -5788,8 +5790,17 @@ static void flush_backlog(struct work_st
|
@@ -5792,8 +5794,17 @@ static void flush_backlog(struct work_st
|
||||||
input_queue_head_incr(sd);
|
input_queue_head_incr(sd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -66,7 +66,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
skb_queue_walk_safe(&sd->process_queue, skb, tmp) {
|
skb_queue_walk_safe(&sd->process_queue, skb, tmp) {
|
||||||
if (skb->dev->reg_state == NETREG_UNREGISTERING) {
|
if (skb->dev->reg_state == NETREG_UNREGISTERING) {
|
||||||
__skb_unlink(skb, &sd->process_queue);
|
__skb_unlink(skb, &sd->process_queue);
|
||||||
@@ -5797,7 +5808,16 @@ static void flush_backlog(struct work_st
|
@@ -5801,7 +5812,16 @@ static void flush_backlog(struct work_st
|
||||||
input_queue_head_incr(sd);
|
input_queue_head_incr(sd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,7 +83,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool flush_required(int cpu)
|
static bool flush_required(int cpu)
|
||||||
@@ -5929,6 +5949,7 @@ static int process_backlog(struct napi_s
|
@@ -5933,6 +5953,7 @@ static int process_backlog(struct napi_s
|
||||||
}
|
}
|
||||||
|
|
||||||
rps_lock_irq_disable(sd);
|
rps_lock_irq_disable(sd);
|
||||||
@ -91,7 +91,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
if (skb_queue_empty(&sd->input_pkt_queue)) {
|
if (skb_queue_empty(&sd->input_pkt_queue)) {
|
||||||
/*
|
/*
|
||||||
* Inline a custom version of __napi_complete().
|
* Inline a custom version of __napi_complete().
|
||||||
@@ -5938,7 +5959,8 @@ static int process_backlog(struct napi_s
|
@@ -5942,7 +5963,8 @@ static int process_backlog(struct napi_s
|
||||||
* We can use a plain write instead of clear_bit(),
|
* We can use a plain write instead of clear_bit(),
|
||||||
* and we dont need an smp_mb() memory barrier.
|
* and we dont need an smp_mb() memory barrier.
|
||||||
*/
|
*/
|
||||||
@ -101,7 +101,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
again = false;
|
again = false;
|
||||||
} else {
|
} else {
|
||||||
skb_queue_splice_tail_init(&sd->input_pkt_queue,
|
skb_queue_splice_tail_init(&sd->input_pkt_queue,
|
||||||
@@ -6354,6 +6376,55 @@ int dev_set_threaded(struct net_device *
|
@@ -6358,6 +6380,55 @@ int dev_set_threaded(struct net_device *
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dev_set_threaded);
|
EXPORT_SYMBOL(dev_set_threaded);
|
||||||
|
|
||||||
@ -157,7 +157,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
void netif_napi_add_weight(struct net_device *dev, struct napi_struct *napi,
|
void netif_napi_add_weight(struct net_device *dev, struct napi_struct *napi,
|
||||||
int (*poll)(struct napi_struct *, int), int weight)
|
int (*poll)(struct napi_struct *, int), int weight)
|
||||||
{
|
{
|
||||||
@@ -11126,6 +11197,9 @@ static int dev_cpu_dead(unsigned int old
|
@@ -11130,6 +11201,9 @@ static int dev_cpu_dead(unsigned int old
|
||||||
raise_softirq_irqoff(NET_TX_SOFTIRQ);
|
raise_softirq_irqoff(NET_TX_SOFTIRQ);
|
||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
|
|
||||||
@ -167,7 +167,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||||||
#ifdef CONFIG_RPS
|
#ifdef CONFIG_RPS
|
||||||
remsd = oldsd->rps_ipi_list;
|
remsd = oldsd->rps_ipi_list;
|
||||||
oldsd->rps_ipi_list = NULL;
|
oldsd->rps_ipi_list = NULL;
|
||||||
@@ -11429,6 +11503,7 @@ static int __init net_dev_init(void)
|
@@ -11433,6 +11507,7 @@ static int __init net_dev_init(void)
|
||||||
INIT_CSD(&sd->defer_csd, trigger_rx_softirq, sd);
|
INIT_CSD(&sd->defer_csd, trigger_rx_softirq, sd);
|
||||||
spin_lock_init(&sd->defer_lock);
|
spin_lock_init(&sd->defer_lock);
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|||||||
/**
|
/**
|
||||||
* ata_build_rw_tf - Build ATA taskfile for given read/write request
|
* ata_build_rw_tf - Build ATA taskfile for given read/write request
|
||||||
* @qc: Metadata associated with the taskfile to build
|
* @qc: Metadata associated with the taskfile to build
|
||||||
@@ -4622,6 +4635,9 @@ void __ata_qc_complete(struct ata_queued
|
@@ -4712,6 +4725,9 @@ void __ata_qc_complete(struct ata_queued
|
||||||
link->active_tag = ATA_TAG_POISON;
|
link->active_tag = ATA_TAG_POISON;
|
||||||
ap->nr_active_links--;
|
ap->nr_active_links--;
|
||||||
}
|
}
|
||||||
@ -75,7 +75,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|||||||
|
|
||||||
/* clear exclusive status */
|
/* clear exclusive status */
|
||||||
if (unlikely(qc->flags & ATA_QCFLAG_CLEAR_EXCL &&
|
if (unlikely(qc->flags & ATA_QCFLAG_CLEAR_EXCL &&
|
||||||
@@ -5344,6 +5360,9 @@ struct ata_port *ata_port_alloc(struct a
|
@@ -5434,6 +5450,9 @@ struct ata_port *ata_port_alloc(struct a
|
||||||
ap->stats.unhandled_irq = 1;
|
ap->stats.unhandled_irq = 1;
|
||||||
ap->stats.idle_irq = 1;
|
ap->stats.idle_irq = 1;
|
||||||
#endif
|
#endif
|
||||||
@ -85,7 +85,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|||||||
ata_sff_port_init(ap);
|
ata_sff_port_init(ap);
|
||||||
|
|
||||||
return ap;
|
return ap;
|
||||||
@@ -5379,6 +5398,12 @@ static void ata_host_release(struct kref
|
@@ -5469,6 +5488,12 @@ static void ata_host_release(struct kref
|
||||||
|
|
||||||
kfree(ap->pmp_link);
|
kfree(ap->pmp_link);
|
||||||
kfree(ap->slave_link);
|
kfree(ap->slave_link);
|
||||||
@ -98,7 +98,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|||||||
kfree(ap);
|
kfree(ap);
|
||||||
host->ports[i] = NULL;
|
host->ports[i] = NULL;
|
||||||
}
|
}
|
||||||
@@ -5781,7 +5806,23 @@ int ata_host_register(struct ata_host *h
|
@@ -5871,7 +5896,23 @@ int ata_host_register(struct ata_host *h
|
||||||
host->ports[i]->print_id = atomic_inc_return(&ata_print_id);
|
host->ports[i]->print_id = atomic_inc_return(&ata_print_id);
|
||||||
host->ports[i]->local_port_no = i + 1;
|
host->ports[i]->local_port_no = i + 1;
|
||||||
}
|
}
|
||||||
@ -134,7 +134,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Define if arch has non-standard setup. This is a _PCI_ standard
|
* Define if arch has non-standard setup. This is a _PCI_ standard
|
||||||
@@ -861,6 +864,12 @@ struct ata_port {
|
@@ -864,6 +867,12 @@ struct ata_port {
|
||||||
#ifdef CONFIG_ATA_ACPI
|
#ifdef CONFIG_ATA_ACPI
|
||||||
struct ata_acpi_gtm __acpi_init_gtm; /* use ata_acpi_init_gtm() */
|
struct ata_acpi_gtm __acpi_init_gtm; /* use ata_acpi_init_gtm() */
|
||||||
#endif
|
#endif
|
||||||
|
@ -74,8 +74,8 @@ CONFIG_CPU_COPY_V6=y
|
|||||||
CONFIG_CPU_CP15=y
|
CONFIG_CPU_CP15=y
|
||||||
CONFIG_CPU_CP15_MMU=y
|
CONFIG_CPU_CP15_MMU=y
|
||||||
CONFIG_CPU_FREQ=y
|
CONFIG_CPU_FREQ=y
|
||||||
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
|
# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
|
||||||
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
|
CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
|
||||||
CONFIG_CPU_FREQ_GOV_ATTR_SET=y
|
CONFIG_CPU_FREQ_GOV_ATTR_SET=y
|
||||||
CONFIG_CPU_FREQ_GOV_COMMON=y
|
CONFIG_CPU_FREQ_GOV_COMMON=y
|
||||||
# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
|
# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
|
||||||
|
@ -354,7 +354,7 @@ endef
|
|||||||
#TARGET_DEVICES += compex_wpj419
|
#TARGET_DEVICES += compex_wpj419
|
||||||
|
|
||||||
define Device/compex_wpj428
|
define Device/compex_wpj428
|
||||||
$(call Device/FitImage)
|
$(call Device/FitzImage)
|
||||||
DEVICE_VENDOR := Compex
|
DEVICE_VENDOR := Compex
|
||||||
DEVICE_MODEL := WPJ428
|
DEVICE_MODEL := WPJ428
|
||||||
SOC := qcom-ipq4028
|
SOC := qcom-ipq4028
|
||||||
|
@ -66,7 +66,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
|||||||
/**
|
/**
|
||||||
--- a/net/core/dev.c
|
--- a/net/core/dev.c
|
||||||
+++ b/net/core/dev.c
|
+++ b/net/core/dev.c
|
||||||
@@ -6562,7 +6562,7 @@ static int __napi_poll(struct napi_struc
|
@@ -6566,7 +6566,7 @@ static int __napi_poll(struct napi_struc
|
||||||
* accidentally calling ->poll() when NAPI is not scheduled.
|
* accidentally calling ->poll() when NAPI is not scheduled.
|
||||||
*/
|
*/
|
||||||
work = 0;
|
work = 0;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
ARCH:=mips
|
ARCH:=mips
|
||||||
SUBTARGET:=xrx200
|
SUBTARGET:=xrx200
|
||||||
BOARDNAME:=XRX200
|
BOARDNAME:=XRX200
|
||||||
FEATURES+=atm nand ramdisk source-only
|
FEATURES+=atm nand ramdisk
|
||||||
CPU_TYPE:=24kc
|
CPU_TYPE:=24kc
|
||||||
|
|
||||||
DEFAULT_PACKAGES+=kmod-leds-gpio \
|
DEFAULT_PACKAGES+=kmod-leds-gpio \
|
||||||
|
@ -149,11 +149,9 @@ Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com>
|
|||||||
drivers/staging/fsl_ppfe/pfe_sysfs.c | 2 +-
|
drivers/staging/fsl_ppfe/pfe_sysfs.c | 2 +-
|
||||||
3 files changed, 11 insertions(+), 11 deletions(-)
|
3 files changed, 11 insertions(+), 11 deletions(-)
|
||||||
|
|
||||||
diff --git a/drivers/staging/fsl_ppfe/pfe_cdev.c b/drivers/staging/fsl_ppfe/pfe_cdev.c
|
|
||||||
index f19a1821af42..e0b3af0892ac 100644
|
|
||||||
--- a/drivers/staging/fsl_ppfe/pfe_cdev.c
|
--- a/drivers/staging/fsl_ppfe/pfe_cdev.c
|
||||||
+++ b/drivers/staging/fsl_ppfe/pfe_cdev.c
|
+++ b/drivers/staging/fsl_ppfe/pfe_cdev.c
|
||||||
@@ -34,7 +34,7 @@ static ssize_t pfe_cdev_read(struct file *fp, char *buf,
|
@@ -34,7 +34,7 @@ static ssize_t pfe_cdev_read(struct file
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@ -162,7 +160,7 @@ index f19a1821af42..e0b3af0892ac 100644
|
|||||||
sizeof(link_states));
|
sizeof(link_states));
|
||||||
|
|
||||||
pr_debug("Dump link_state on screen before copy_to_user\n");
|
pr_debug("Dump link_state on screen before copy_to_user\n");
|
||||||
@@ -47,14 +47,14 @@ static ssize_t pfe_cdev_read(struct file *fp, char *buf,
|
@@ -47,14 +47,14 @@ static ssize_t pfe_cdev_read(struct file
|
||||||
/* Copy to user the value in buffer sized len */
|
/* Copy to user the value in buffer sized len */
|
||||||
ret = copy_to_user(buf, &link_states, sizeof(link_states));
|
ret = copy_to_user(buf, &link_states, sizeof(link_states));
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
@ -179,8 +177,6 @@ index f19a1821af42..e0b3af0892ac 100644
|
|||||||
|
|
||||||
return sizeof(link_states);
|
return sizeof(link_states);
|
||||||
}
|
}
|
||||||
diff --git a/drivers/staging/fsl_ppfe/pfe_hif.c b/drivers/staging/fsl_ppfe/pfe_hif.c
|
|
||||||
index dcc3f7f1e9ef..5347401f92c0 100644
|
|
||||||
--- a/drivers/staging/fsl_ppfe/pfe_hif.c
|
--- a/drivers/staging/fsl_ppfe/pfe_hif.c
|
||||||
+++ b/drivers/staging/fsl_ppfe/pfe_hif.c
|
+++ b/drivers/staging/fsl_ppfe/pfe_hif.c
|
||||||
@@ -115,11 +115,11 @@ static void send_dummy_pkt_to_hif(void)
|
@@ -115,11 +115,11 @@ static void send_dummy_pkt_to_hif(void)
|
||||||
@ -197,7 +193,7 @@ index dcc3f7f1e9ef..5347401f92c0 100644
|
|||||||
if (!lmem_ptr)
|
if (!lmem_ptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -186,16 +186,16 @@ static void pfe_hif_free_descr(struct pfe_hif *hif)
|
@@ -186,16 +186,16 @@ static void pfe_hif_free_descr(struct pf
|
||||||
void pfe_hif_desc_dump(struct pfe_hif *hif)
|
void pfe_hif_desc_dump(struct pfe_hif *hif)
|
||||||
{
|
{
|
||||||
struct hif_desc *desc;
|
struct hif_desc *desc;
|
||||||
@ -217,7 +213,7 @@ index dcc3f7f1e9ef..5347401f92c0 100644
|
|||||||
for (ii = 0; ii < hif->rx_ring_size; ii++) {
|
for (ii = 0; ii < hif->rx_ring_size; ii++) {
|
||||||
pr_info("status: %08x, ctrl: %08x, data: %08x, next: %x\n",
|
pr_info("status: %08x, ctrl: %08x, data: %08x, next: %x\n",
|
||||||
readl(&desc->status), readl(&desc->ctrl),
|
readl(&desc->status), readl(&desc->ctrl),
|
||||||
@@ -204,10 +204,10 @@ void pfe_hif_desc_dump(struct pfe_hif *hif)
|
@@ -204,10 +204,10 @@ void pfe_hif_desc_dump(struct pfe_hif *h
|
||||||
}
|
}
|
||||||
|
|
||||||
desc = hif->tx_base;
|
desc = hif->tx_base;
|
||||||
@ -230,11 +226,9 @@ index dcc3f7f1e9ef..5347401f92c0 100644
|
|||||||
for (ii = 0; ii < hif->tx_ring_size; ii++) {
|
for (ii = 0; ii < hif->tx_ring_size; ii++) {
|
||||||
pr_info("status: %08x, ctrl: %08x, data: %08x, next: %x\n",
|
pr_info("status: %08x, ctrl: %08x, data: %08x, next: %x\n",
|
||||||
readl(&desc->status), readl(&desc->ctrl),
|
readl(&desc->status), readl(&desc->ctrl),
|
||||||
diff --git a/drivers/staging/fsl_ppfe/pfe_sysfs.c b/drivers/staging/fsl_ppfe/pfe_sysfs.c
|
|
||||||
index 1792e88140d1..ede651be51bf 100644
|
|
||||||
--- a/drivers/staging/fsl_ppfe/pfe_sysfs.c
|
--- a/drivers/staging/fsl_ppfe/pfe_sysfs.c
|
||||||
+++ b/drivers/staging/fsl_ppfe/pfe_sysfs.c
|
+++ b/drivers/staging/fsl_ppfe/pfe_sysfs.c
|
||||||
@@ -535,7 +535,7 @@ static ssize_t pfe_show_tmu3_queues(struct device *dev, struct device_attribute
|
@@ -535,7 +535,7 @@ static ssize_t pfe_show_tmu3_queues(stru
|
||||||
static ssize_t pfe_set_util(struct device *dev, struct device_attribute *attr,
|
static ssize_t pfe_set_util(struct device *dev, struct device_attribute *attr,
|
||||||
const char *buf, size_t count)
|
const char *buf, size_t count)
|
||||||
{
|
{
|
||||||
@ -243,6 +237,3 @@ index 1792e88140d1..ede651be51bf 100644
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
--
|
|
||||||
2.25.1
|
|
||||||
|
|
||||||
|
@ -30,11 +30,9 @@ Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
|
|||||||
drivers/net/phy/phylink.c | 1 +
|
drivers/net/phy/phylink.c | 1 +
|
||||||
1 file changed, 1 insertion(+)
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
|
|
||||||
index 2805b04d6402..a1e34b127401 100644
|
|
||||||
--- a/drivers/net/phy/phylink.c
|
--- a/drivers/net/phy/phylink.c
|
||||||
+++ b/drivers/net/phy/phylink.c
|
+++ b/drivers/net/phy/phylink.c
|
||||||
@@ -485,6 +485,7 @@ unsigned long phylink_get_capabilities(phy_interface_t interface,
|
@@ -485,6 +485,7 @@ unsigned long phylink_get_capabilities(p
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PHY_INTERFACE_MODE_2500BASEX:
|
case PHY_INTERFACE_MODE_2500BASEX:
|
||||||
@ -42,6 +40,3 @@ index 2805b04d6402..a1e34b127401 100644
|
|||||||
caps |= MAC_2500FD;
|
caps |= MAC_2500FD;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
--
|
|
||||||
2.25.1
|
|
||||||
|
|
||||||
|
@ -1,118 +0,0 @@
|
|||||||
From 80e643510cb14f116f687e992210c0008a09d869 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
|
|
||||||
Date: Mon, 4 Jul 2022 12:59:53 +0200
|
|
||||||
Subject: [PATCH] leds: turris-omnia: support HW controlled mode via
|
|
||||||
private trigger
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
Add support for enabling MCU controlled mode of the Turris Omnia LEDs
|
|
||||||
via a LED private trigger called "omnia-mcu".
|
|
||||||
|
|
||||||
When in MCU controlled mode, the user can still set LED color, but the
|
|
||||||
blinking is done by MCU, which does different things for various LEDs:
|
|
||||||
- WAN LED is blinked according to the LED[0] pin of the WAN PHY
|
|
||||||
- LAN LEDs are blinked according to the LED[0] output of corresponding
|
|
||||||
port of the LAN switch
|
|
||||||
- PCIe LEDs are blinked according to the logical OR of the MiniPCIe port
|
|
||||||
LED pins
|
|
||||||
|
|
||||||
For a long time I wanted to actually do this differently: I wanted to
|
|
||||||
make the netdev trigger to transparently offload the blinking to the HW
|
|
||||||
if user set compatible settings for the netdev trigger.
|
|
||||||
There was some work on this, and hopefully we will be able to complete
|
|
||||||
it sometime, but since there are various complications, it will probably
|
|
||||||
not be soon.
|
|
||||||
|
|
||||||
In the meantime let's support HW controlled mode via this private LED
|
|
||||||
trigger. If, in the future, we manage to complete the netdev trigger
|
|
||||||
offloading, we can still keep this private trigger for backwards
|
|
||||||
compatiblity, if needed.
|
|
||||||
|
|
||||||
We also set "omnia-mcu" to cdev->default_trigger, so that the MCU keeps
|
|
||||||
control until the user first wants to take over it. If a different
|
|
||||||
default trigger is specified in device-tree via the
|
|
||||||
`linux,default-trigger` property, LED class will overwrite
|
|
||||||
cdev->default_trigger, and so the DT property will be respected.
|
|
||||||
|
|
||||||
Signed-off-by: Marek Behún <kabel@kernel.org>
|
|
||||||
---
|
|
||||||
drivers/leds/Kconfig | 1 +
|
|
||||||
drivers/leds/leds-turris-omnia.c | 41 ++++++++++++++++++++++++++++++++
|
|
||||||
2 files changed, 42 insertions(+)
|
|
||||||
|
|
||||||
--- a/drivers/leds/Kconfig
|
|
||||||
+++ b/drivers/leds/Kconfig
|
|
||||||
@@ -163,6 +163,7 @@ config LEDS_TURRIS_OMNIA
|
|
||||||
depends on I2C
|
|
||||||
depends on MACH_ARMADA_38X || COMPILE_TEST
|
|
||||||
depends on OF
|
|
||||||
+ select LEDS_TRIGGERS
|
|
||||||
help
|
|
||||||
This option enables basic support for the LEDs found on the front
|
|
||||||
side of CZ.NIC's Turris Omnia router. There are 12 RGB LEDs on the
|
|
||||||
--- a/drivers/leds/leds-turris-omnia.c
|
|
||||||
+++ b/drivers/leds/leds-turris-omnia.c
|
|
||||||
@@ -41,6 +41,39 @@ struct omnia_leds {
|
|
||||||
struct omnia_led leds[];
|
|
||||||
};
|
|
||||||
|
|
||||||
+static struct led_hw_trigger_type omnia_hw_trigger_type;
|
|
||||||
+
|
|
||||||
+static int omnia_hwtrig_activate(struct led_classdev *cdev)
|
|
||||||
+{
|
|
||||||
+ struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent);
|
|
||||||
+ struct omnia_led *led = to_omnia_led(lcdev_to_mccdev(cdev));
|
|
||||||
+
|
|
||||||
+ /* put the LED into MCU controlled mode */
|
|
||||||
+ return i2c_smbus_write_byte_data(leds->client, CMD_LED_MODE,
|
|
||||||
+ CMD_LED_MODE_LED(led->reg));
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void omnia_hwtrig_deactivate(struct led_classdev *cdev)
|
|
||||||
+{
|
|
||||||
+ struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent);
|
|
||||||
+ struct omnia_led *led = to_omnia_led(lcdev_to_mccdev(cdev));
|
|
||||||
+ int ret;
|
|
||||||
+
|
|
||||||
+ /* put the LED into software mode */
|
|
||||||
+ ret = i2c_smbus_write_byte_data(leds->client, CMD_LED_MODE,
|
|
||||||
+ CMD_LED_MODE_LED(led->reg) |
|
|
||||||
+ CMD_LED_MODE_USER);
|
|
||||||
+ if (ret < 0)
|
|
||||||
+ dev_err(cdev->dev, "Cannot put to software mode: %i\n", ret);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct led_trigger omnia_hw_trigger = {
|
|
||||||
+ .name = "omnia-mcu",
|
|
||||||
+ .activate = omnia_hwtrig_activate,
|
|
||||||
+ .deactivate = omnia_hwtrig_deactivate,
|
|
||||||
+ .trigger_type = &omnia_hw_trigger_type,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static int omnia_led_brightness_set_blocking(struct led_classdev *cdev,
|
|
||||||
enum led_brightness brightness)
|
|
||||||
{
|
|
||||||
@@ -112,6 +145,8 @@ static int omnia_led_register(struct i2c
|
|
||||||
cdev = &led->mc_cdev.led_cdev;
|
|
||||||
cdev->max_brightness = 255;
|
|
||||||
cdev->brightness_set_blocking = omnia_led_brightness_set_blocking;
|
|
||||||
+ cdev->trigger_type = &omnia_hw_trigger_type;
|
|
||||||
+ cdev->default_trigger = omnia_hw_trigger.name;
|
|
||||||
|
|
||||||
/* put the LED into software mode */
|
|
||||||
ret = i2c_smbus_write_byte_data(client, CMD_LED_MODE,
|
|
||||||
@@ -228,6 +263,12 @@ static int omnia_leds_probe(struct i2c_c
|
|
||||||
|
|
||||||
mutex_init(&leds->lock);
|
|
||||||
|
|
||||||
+ ret = devm_led_trigger_register(dev, &omnia_hw_trigger);
|
|
||||||
+ if (ret < 0) {
|
|
||||||
+ dev_err(dev, "Cannot register private LED trigger: %d\n", ret);
|
|
||||||
+ return ret;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
led = &leds->leds[0];
|
|
||||||
for_each_available_child_of_node(np, child) {
|
|
||||||
ret = omnia_led_register(client, led, child);
|
|
@ -1,33 +0,0 @@
|
|||||||
From bda176cceb735b9b46c1900658b6486c34e13ae6 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
|
|
||||||
Date: Mon, 4 Jul 2022 12:59:54 +0200
|
|
||||||
Subject: [PATCH] leds: turris-omnia: initialize multi-intensity to full
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
The default color of each LED before driver probe (255, 255, 255).
|
|
||||||
Initialize multi_intensity to this value, so that it corresponds to the
|
|
||||||
reality.
|
|
||||||
|
|
||||||
Signed-off-by: Marek Behún <kabel@kernel.org>
|
|
||||||
---
|
|
||||||
drivers/leds/leds-turris-omnia.c | 3 +++
|
|
||||||
1 file changed, 3 insertions(+)
|
|
||||||
|
|
||||||
--- a/drivers/leds/leds-turris-omnia.c
|
|
||||||
+++ b/drivers/leds/leds-turris-omnia.c
|
|
||||||
@@ -131,10 +131,13 @@ static int omnia_led_register(struct i2c
|
|
||||||
}
|
|
||||||
|
|
||||||
led->subled_info[0].color_index = LED_COLOR_ID_RED;
|
|
||||||
+ led->subled_info[0].intensity = 255;
|
|
||||||
led->subled_info[0].channel = 0;
|
|
||||||
led->subled_info[1].color_index = LED_COLOR_ID_GREEN;
|
|
||||||
+ led->subled_info[1].intensity = 255;
|
|
||||||
led->subled_info[1].channel = 1;
|
|
||||||
led->subled_info[2].color_index = LED_COLOR_ID_BLUE;
|
|
||||||
+ led->subled_info[2].intensity = 255;
|
|
||||||
led->subled_info[2].channel = 2;
|
|
||||||
|
|
||||||
led->mc_cdev.subled_info = led->subled_info;
|
|
@ -1,31 +0,0 @@
|
|||||||
From 349cbe949b9622cc05b148ecfa6268cbbae35b45 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
|
|
||||||
Date: Mon, 4 Jul 2022 12:59:55 +0200
|
|
||||||
Subject: [PATCH] leds: turris-omnia: change max brightness from 255 to 1
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
Using binary brightness makes more sense for this controller, because
|
|
||||||
internally in the MCU it works that way: the LED has a color, and a
|
|
||||||
state whether it is ON or OFF.
|
|
||||||
|
|
||||||
The resulting brightness computation with led_mc_calc_color_components()
|
|
||||||
will now always result in either (0, 0, 0) or the multi_intensity value.
|
|
||||||
|
|
||||||
Signed-off-by: Marek Behún <kabel@kernel.org>
|
|
||||||
---
|
|
||||||
drivers/leds/leds-turris-omnia.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
--- a/drivers/leds/leds-turris-omnia.c
|
|
||||||
+++ b/drivers/leds/leds-turris-omnia.c
|
|
||||||
@@ -146,7 +146,7 @@ static int omnia_led_register(struct i2c
|
|
||||||
init_data.fwnode = &np->fwnode;
|
|
||||||
|
|
||||||
cdev = &led->mc_cdev.led_cdev;
|
|
||||||
- cdev->max_brightness = 255;
|
|
||||||
+ cdev->max_brightness = 1;
|
|
||||||
cdev->brightness_set_blocking = omnia_led_brightness_set_blocking;
|
|
||||||
cdev->trigger_type = &omnia_hw_trigger_type;
|
|
||||||
cdev->default_trigger = omnia_hw_trigger.name;
|
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include <dt-bindings/gpio/gpio.h>
|
#include <dt-bindings/gpio/gpio.h>
|
||||||
#include <dt-bindings/input/input.h>
|
#include <dt-bindings/input/input.h>
|
||||||
|
#include <dt-bindings/leds/common.h>
|
||||||
|
|
||||||
/ {
|
/ {
|
||||||
aliases {
|
aliases {
|
||||||
@ -21,14 +22,14 @@
|
|||||||
keys {
|
keys {
|
||||||
compatible = "gpio-keys";
|
compatible = "gpio-keys";
|
||||||
|
|
||||||
wps {
|
button-wps {
|
||||||
label = "wps";
|
label = "wps";
|
||||||
gpios = <&gpio 28 GPIO_ACTIVE_LOW>;
|
gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
|
||||||
debounce-interval = <60>;
|
debounce-interval = <60>;
|
||||||
linux,code = <KEY_WPS_BUTTON>;
|
linux,code = <KEY_WPS_BUTTON>;
|
||||||
};
|
};
|
||||||
|
|
||||||
reset {
|
button-reset {
|
||||||
label = "reset";
|
label = "reset";
|
||||||
gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
|
gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
|
||||||
debounce-interval = <60>;
|
debounce-interval = <60>;
|
||||||
@ -39,35 +40,44 @@
|
|||||||
leds {
|
leds {
|
||||||
compatible = "gpio-leds";
|
compatible = "gpio-leds";
|
||||||
|
|
||||||
led_power: power {
|
led_power: led-power {
|
||||||
label = "green:power";
|
label = "green:power";
|
||||||
|
color = <LED_COLOR_ID_GREEN>;
|
||||||
|
function = LED_FUNCTION_POWER;
|
||||||
gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
|
gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
|
||||||
};
|
};
|
||||||
|
|
||||||
wan_orange {
|
led-wan-amber {
|
||||||
label = "orange:wan";
|
color = <LED_COLOR_ID_AMBER>;
|
||||||
|
function = LED_FUNCTION_WAN;
|
||||||
gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
|
gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
|
||||||
};
|
};
|
||||||
|
|
||||||
lan {
|
led-lan {
|
||||||
label = "green:lan";
|
color = <LED_COLOR_ID_GREEN>;
|
||||||
|
function = LED_FUNCTION_LAN;
|
||||||
gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
|
gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
|
||||||
};
|
};
|
||||||
|
|
||||||
wifi5g {
|
led-wifi5g {
|
||||||
label = "green:wifi5g";
|
color = <LED_COLOR_ID_GREEN>;
|
||||||
|
function = LED_FUNCTION_WLAN;
|
||||||
|
function-enumerator = <5>;
|
||||||
gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
|
gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
|
||||||
linux,default-trigger = "phy1tpt";
|
linux,default-trigger = "phy1tpt";
|
||||||
};
|
};
|
||||||
|
|
||||||
wifi2g {
|
led-wifi2g {
|
||||||
label = "green:wifi2g";
|
color = <LED_COLOR_ID_GREEN>;
|
||||||
|
function = LED_FUNCTION_WLAN;
|
||||||
|
function-enumerator = <2>;
|
||||||
gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
|
gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
|
||||||
linux,default-trigger = "phy0tpt";
|
linux,default-trigger = "phy0tpt";
|
||||||
};
|
};
|
||||||
|
|
||||||
wan_green {
|
led-wan-green {
|
||||||
label = "green:wan";
|
color = <LED_COLOR_ID_GREEN>;
|
||||||
|
function = LED_FUNCTION_WAN;
|
||||||
gpios = <&gpio 45 GPIO_ACTIVE_LOW>;
|
gpios = <&gpio 45 GPIO_ACTIVE_LOW>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
. /lib/functions.sh
|
||||||
|
. /lib/functions/migrations.sh
|
||||||
|
|
||||||
|
board=$(board_name)
|
||||||
|
|
||||||
|
case "$board" in
|
||||||
|
tplink,archer-a6-v3|\
|
||||||
|
tplink,archer-c6-v3)
|
||||||
|
migrate_leds ':wifi2g$=:wlan-2' ':wifi5g$=:wlan-5'
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
remove_devicename_leds
|
||||||
|
|
||||||
|
migrations_apply system
|
||||||
|
|
||||||
|
exit 0
|
@ -44,7 +44,8 @@ hpe,1920-24g)
|
|||||||
;;
|
;;
|
||||||
tplink,sg2008p-v1|\
|
tplink,sg2008p-v1|\
|
||||||
tplink,sg2210p-v3|\
|
tplink,sg2210p-v3|\
|
||||||
tplink,sg2452p-v4)
|
tplink,sg2452p-v4|\
|
||||||
|
tplink,t1600g-28ts-v3)
|
||||||
label_mac=$(get_mac_label)
|
label_mac=$(get_mac_label)
|
||||||
lan_mac="$label_mac"
|
lan_mac="$label_mac"
|
||||||
;;
|
;;
|
||||||
|
172
target/linux/realtek/dts-5.15/rtl8382_tplink_t1600g-28ts-v3.dts
Normal file
172
target/linux/realtek/dts-5.15/rtl8382_tplink_t1600g-28ts-v3.dts
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
|
||||||
|
|
||||||
|
#include "rtl838x.dtsi"
|
||||||
|
|
||||||
|
#include <dt-bindings/input/input.h>
|
||||||
|
#include <dt-bindings/gpio/gpio.h>
|
||||||
|
#include <dt-bindings/leds/common.h>
|
||||||
|
|
||||||
|
/ {
|
||||||
|
compatible = "tplink,t1600g-28ts-v3", "realtek,rtl838x-soc";
|
||||||
|
model = "TP-Link T1600G-28TS v3";
|
||||||
|
|
||||||
|
aliases {
|
||||||
|
led-boot = &led_sys;
|
||||||
|
led-failsafe = &led_sys;
|
||||||
|
led-running = &led_sys;
|
||||||
|
led-upgrade = &led_sys;
|
||||||
|
label-mac-device = ðernet0;
|
||||||
|
};
|
||||||
|
|
||||||
|
chosen {
|
||||||
|
stdout-path = "serial0:38400n8";
|
||||||
|
};
|
||||||
|
|
||||||
|
leds {
|
||||||
|
pinctrl-names = "default";
|
||||||
|
compatible = "gpio-leds";
|
||||||
|
|
||||||
|
led_sys: led-0 {
|
||||||
|
label = "green:sys";
|
||||||
|
gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>;
|
||||||
|
color = <LED_COLOR_ID_GREEN>;
|
||||||
|
function = LED_FUNCTION_STATUS;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
memory@0 {
|
||||||
|
device_type = "memory";
|
||||||
|
reg = <0x0 0x10000000>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&spi0 {
|
||||||
|
status = "okay";
|
||||||
|
|
||||||
|
flash@0 {
|
||||||
|
compatible = "jedec,spi-nor";
|
||||||
|
reg = <0>;
|
||||||
|
spi-max-frequency = <10000000>;
|
||||||
|
|
||||||
|
partitions {
|
||||||
|
compatible = "fixed-partitions";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
|
||||||
|
partition@0 {
|
||||||
|
label = "u-boot";
|
||||||
|
reg = <0x0 0xe0000>;
|
||||||
|
read-only;
|
||||||
|
};
|
||||||
|
partition@e0000 {
|
||||||
|
label = "u-boot-env";
|
||||||
|
reg = <0xe0000 0x20000>;
|
||||||
|
};
|
||||||
|
partition@100000 {
|
||||||
|
compatible = "denx,uimage";
|
||||||
|
label = "firmware";
|
||||||
|
reg = <0x100000 0x1a00000>;
|
||||||
|
};
|
||||||
|
partition@1b00000 {
|
||||||
|
label = "usrappfs";
|
||||||
|
reg = <0x1b00000 0x400000>;
|
||||||
|
};
|
||||||
|
partition@1f00000 {
|
||||||
|
compatible = "nvmem-cells";
|
||||||
|
label = "para";
|
||||||
|
reg = <0x1f00000 0x100000>;
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
read-only;
|
||||||
|
|
||||||
|
factory_macaddr: macaddr@fdff4 {
|
||||||
|
reg = <0xfdff4 0x6>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
ðernet0 {
|
||||||
|
nvmem-cells = <&factory_macaddr>;
|
||||||
|
nvmem-cell-names = "mac-address";
|
||||||
|
|
||||||
|
mdio-bus {
|
||||||
|
compatible = "realtek,rtl838x-mdio";
|
||||||
|
regmap = <ðernet0>;
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
EXTERNAL_PHY(0)
|
||||||
|
EXTERNAL_PHY(1)
|
||||||
|
EXTERNAL_PHY(2)
|
||||||
|
EXTERNAL_PHY(3)
|
||||||
|
EXTERNAL_PHY(4)
|
||||||
|
EXTERNAL_PHY(5)
|
||||||
|
EXTERNAL_PHY(6)
|
||||||
|
EXTERNAL_PHY(7)
|
||||||
|
|
||||||
|
INTERNAL_PHY(8)
|
||||||
|
INTERNAL_PHY(9)
|
||||||
|
INTERNAL_PHY(10)
|
||||||
|
INTERNAL_PHY(11)
|
||||||
|
INTERNAL_PHY(12)
|
||||||
|
INTERNAL_PHY(13)
|
||||||
|
INTERNAL_PHY(14)
|
||||||
|
INTERNAL_PHY(15)
|
||||||
|
|
||||||
|
EXTERNAL_PHY(16)
|
||||||
|
EXTERNAL_PHY(17)
|
||||||
|
EXTERNAL_PHY(18)
|
||||||
|
EXTERNAL_PHY(19)
|
||||||
|
EXTERNAL_PHY(20)
|
||||||
|
EXTERNAL_PHY(21)
|
||||||
|
EXTERNAL_PHY(22)
|
||||||
|
EXTERNAL_PHY(23)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&switch0 {
|
||||||
|
ports {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
SWITCH_PORT(0, 1, qsgmii)
|
||||||
|
SWITCH_PORT(1, 2, qsgmii)
|
||||||
|
SWITCH_PORT(2, 3, qsgmii)
|
||||||
|
SWITCH_PORT(3, 4, qsgmii)
|
||||||
|
SWITCH_PORT(4, 5, qsgmii)
|
||||||
|
SWITCH_PORT(5, 6, qsgmii)
|
||||||
|
SWITCH_PORT(6, 7, qsgmii)
|
||||||
|
SWITCH_PORT(7, 8, qsgmii)
|
||||||
|
|
||||||
|
SWITCH_PORT(8, 9, internal)
|
||||||
|
SWITCH_PORT(9, 10, internal)
|
||||||
|
SWITCH_PORT(10, 11, internal)
|
||||||
|
SWITCH_PORT(11, 12, internal)
|
||||||
|
SWITCH_PORT(12, 13, internal)
|
||||||
|
SWITCH_PORT(13, 14, internal)
|
||||||
|
SWITCH_PORT(14, 15, internal)
|
||||||
|
SWITCH_PORT(15, 16, internal)
|
||||||
|
|
||||||
|
SWITCH_PORT(16, 17, qsgmii)
|
||||||
|
SWITCH_PORT(17, 18, qsgmii)
|
||||||
|
SWITCH_PORT(18, 19, qsgmii)
|
||||||
|
SWITCH_PORT(19, 20, qsgmii)
|
||||||
|
SWITCH_PORT(20, 21, qsgmii)
|
||||||
|
SWITCH_PORT(21, 22, qsgmii)
|
||||||
|
SWITCH_PORT(22, 23, qsgmii)
|
||||||
|
SWITCH_PORT(23, 24, qsgmii)
|
||||||
|
|
||||||
|
port@28 {
|
||||||
|
ethernet = <ðernet0>;
|
||||||
|
reg = <28>;
|
||||||
|
phy-mode = "internal";
|
||||||
|
|
||||||
|
fixed-link {
|
||||||
|
speed = <1000>;
|
||||||
|
full-duplex;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
@ -252,6 +252,16 @@ define Device/tplink_sg2210p-v3
|
|||||||
endef
|
endef
|
||||||
TARGET_DEVICES += tplink_sg2210p-v3
|
TARGET_DEVICES += tplink_sg2210p-v3
|
||||||
|
|
||||||
|
define Device/tplink_t1600g-28ts-v3
|
||||||
|
SOC := rtl8382
|
||||||
|
KERNEL_SIZE := 6m
|
||||||
|
IMAGE_SIZE := 26m
|
||||||
|
DEVICE_VENDOR := TP-Link
|
||||||
|
DEVICE_MODEL := T1600G-28TS
|
||||||
|
DEVICE_VARIANT := v3
|
||||||
|
endef
|
||||||
|
TARGET_DEVICES += tplink_t1600g-28ts-v3
|
||||||
|
|
||||||
define Device/zyxel_gs1900-10hp
|
define Device/zyxel_gs1900-10hp
|
||||||
$(Device/zyxel_gs1900)
|
$(Device/zyxel_gs1900)
|
||||||
SOC := rtl8380
|
SOC := rtl8380
|
||||||
|
@ -150,6 +150,14 @@ menuconfig EXTERNAL_TOOLCHAIN
|
|||||||
|
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
|
config EXTERNAL_GCC_VERSION
|
||||||
|
string
|
||||||
|
prompt "External Toolchain GCC Version" if DEVEL
|
||||||
|
depends on EXTERNAL_TOOLCHAIN && !NATIVE_TOOLCHAIN
|
||||||
|
help
|
||||||
|
Manually specify the GCC version used by the selected
|
||||||
|
external toolchain.
|
||||||
|
|
||||||
config TOOLCHAIN_LIBC
|
config TOOLCHAIN_LIBC
|
||||||
string
|
string
|
||||||
depends on EXTERNAL_TOOLCHAIN && !NATIVE_TOOLCHAIN
|
depends on EXTERNAL_TOOLCHAIN && !NATIVE_TOOLCHAIN
|
||||||
|
@ -8,6 +8,7 @@ config GCC_VERSION_13
|
|||||||
|
|
||||||
config GCC_VERSION
|
config GCC_VERSION
|
||||||
string
|
string
|
||||||
|
default EXTERNAL_GCC_VERSION if EXTERNAL_TOOLCHAIN && !NATIVE_TOOLCHAIN
|
||||||
default "11.3.0" if GCC_VERSION_11
|
default "11.3.0" if GCC_VERSION_11
|
||||||
default "13.2.0" if GCC_VERSION_13
|
default "13.2.0" if GCC_VERSION_13
|
||||||
default "12.3.0"
|
default "12.3.0"
|
||||||
|
@ -3,12 +3,12 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=mold
|
PKG_NAME:=mold
|
||||||
PKG_VERSION:=2.2.0
|
PKG_VERSION:=2.3.1
|
||||||
|
|
||||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||||
PKG_SOURCE_URL_FILE:=v$(PKG_VERSION).tar.gz
|
PKG_SOURCE_URL_FILE:=v$(PKG_VERSION).tar.gz
|
||||||
PKG_SOURCE_URL:=https://github.com/rui314/mold/archive/refs/tags
|
PKG_SOURCE_URL:=https://github.com/rui314/mold/archive/refs/tags
|
||||||
PKG_HASH:=78ddddaaa004e50f8d92a13d8e792a46a1b37745fab48d39ad16aeb5a776e7c6
|
PKG_HASH:=380f540114408c37bcdb7f3bda91a056448a93124ca6992a373ae2bda35e9af7
|
||||||
|
|
||||||
include $(INCLUDE_DIR)/host-build.mk
|
include $(INCLUDE_DIR)/host-build.mk
|
||||||
include $(INCLUDE_DIR)/cmake.mk
|
include $(INCLUDE_DIR)/cmake.mk
|
||||||
|
Loading…
x
Reference in New Issue
Block a user