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_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/asm/mach-generic \
|
||||
-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) .)
|
||||
|
||||
ifeq ($(CONFIG_EXTERNAL_TOOLCHAIN),)
|
||||
cmake_tool=$(TOOLCHAIN_DIR)/bin/$(1)
|
||||
cmake_tool=$(firstword $(TOOLCHAIN_BIN_DIRS))/$(1)
|
||||
else
|
||||
cmake_tool=$(shell command -v $(1))
|
||||
endif
|
||||
@ -49,7 +49,7 @@ CMAKE_AR:=$(call cmake_tool,$(TARGET_AR))
|
||||
CMAKE_NM:=$(call cmake_tool,$(TARGET_NM))
|
||||
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_SHARED_LDFLAGS:=-Wl,-Bsymbolic-functions
|
||||
CMAKE_HOST_INSTALL_PREFIX = $(HOST_BUILD_PREFIX)
|
||||
|
@ -1,2 +1,2 @@
|
||||
LINUX_VERSION-6.1 = .57
|
||||
LINUX_KERNEL_HASH-6.1.57 = f9ebfe3ddc5152d87b37e33be30e31875d137433be10a57ce29d2eae7b6e91b1
|
||||
LINUX_VERSION-6.1 = .59
|
||||
LINUX_KERNEL_HASH-6.1.59 = 627f7724c675036639290fb5c39e3fdeb3d566b80b192c45f4a808ab54c8c0a0
|
||||
|
@ -108,6 +108,9 @@ define Build/Prepare
|
||||
mkdir -p $(PKG_BUILD_DIR)
|
||||
endef
|
||||
|
||||
define Build/Quilt
|
||||
endef
|
||||
|
||||
define Build/Compile/Default
|
||||
|
||||
endef
|
||||
|
@ -107,7 +107,7 @@ ucidef_set_bridge_mac() {
|
||||
}
|
||||
|
||||
ucidef_set_network_device_mac() {
|
||||
json_select_object "network-device"
|
||||
json_select_object "network_device"
|
||||
json_select_object "${1}"
|
||||
json_add_string macaddr "${2}"
|
||||
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_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_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_5=Reset all settings to factory defaults.=run reset_factory ; reset
|
||||
+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)" \
|
||||
SAN_CFLAGS="$(TARGET_CFLAGS) $(TARGET_CPPFLAGS)" \
|
||||
LDLIBS="$(TARGET_LDFLAGS)" \
|
||||
TOOLCHAIN_INCLUDE="$(TOOLCHAIN_DIR)/include" \
|
||||
TOOLCHAIN_INCLUDE="$(TOOLCHAIN_INC_DIRS)" \
|
||||
VMLINUX_BTF="$(LINUX_DIR)/vmlinux"
|
||||
|
||||
MAKE_FLAGS = \
|
||||
|
@ -37,6 +37,9 @@ endef
|
||||
define Build/Configure
|
||||
endef
|
||||
|
||||
define Build/Quilt
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
|
@ -523,6 +523,8 @@ define KernelPackage/crypto-lib-chacha20/arm
|
||||
FILES:=$(LINUX_DIR)/arch/arm/crypto/chacha-neon.ko
|
||||
endef
|
||||
|
||||
KernelPackage/crypto-lib-chacha20/armeb=$(KernelPackage/crypto-lib-chacha20/arm)
|
||||
|
||||
define KernelPackage/crypto-lib-chacha20/aarch64
|
||||
KCONFIG+=CONFIG_CRYPTO_CHACHA20_NEON
|
||||
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
|
||||
endef
|
||||
|
||||
KernelPackage/crypto-lib-poly1305/armeb=$(KernelPackage/crypto-lib-poly1305/arm)
|
||||
|
||||
define KernelPackage/crypto-lib-poly1305/aarch64
|
||||
KCONFIG+=CONFIG_CRYPTO_POLY1305_NEON
|
||||
FILES:=$(LINUX_DIR)/arch/arm64/crypto/poly1305-neon.ko
|
||||
|
@ -728,6 +728,22 @@ endef
|
||||
|
||||
$(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
|
||||
SUBMENU:=$(OTHER_MENU)
|
||||
@ -780,6 +796,22 @@ endef
|
||||
|
||||
$(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
|
||||
SUBMENU:=$(OTHER_MENU)
|
||||
|
@ -31,17 +31,11 @@ endef
|
||||
|
||||
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
|
||||
|
||||
MAKE_FLAGS+= \
|
||||
TARGET_NAME=$(CONFIG_TARGET_NAME) \
|
||||
TOOL_PATH=$(TOOLCHAIN_BIN_PATH) \
|
||||
TOOL_PATH=$(firstword $(TOOLCHAIN_BIN_DIRS)) \
|
||||
SYS_PATH=$(LINUX_DIR) \
|
||||
TOOLPREFIX=$(TARGET_CROSS) \
|
||||
KVER=$(LINUX_VERSION) \
|
||||
|
@ -55,10 +55,16 @@ $(call Package/libnl/default)
|
||||
DEPENDS:=+libnl-route
|
||||
endef
|
||||
|
||||
define Package/libnl-cli
|
||||
$(call Package/libnl/default)
|
||||
TITLE:=CLI Netlink Library
|
||||
DEPENDS:=+libnl-genl +libnl-nf
|
||||
endef
|
||||
|
||||
define Package/libnl
|
||||
$(call Package/libnl/default)
|
||||
TITLE:=Full Netlink Library
|
||||
DEPENDS:=+libnl-genl +libnl-route +libnl-nf
|
||||
DEPENDS:=+libnl-genl +libnl-route +libnl-nf +libnl-cli
|
||||
endef
|
||||
|
||||
define Package/libnl-core/description
|
||||
@ -77,6 +83,10 @@ define Package/libnl-nf/description
|
||||
Netfilter Netlink Library Functions
|
||||
endef
|
||||
|
||||
define Package/libnl-cli/description
|
||||
CLI Netlink Library Functions
|
||||
endef
|
||||
|
||||
define Package/libnl/description
|
||||
Socket handling, connection management, sending and receiving of data,
|
||||
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-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-cli-3.so $(1)/usr/lib/libnl-cli.so
|
||||
endef
|
||||
|
||||
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/
|
||||
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
|
||||
:
|
||||
endef
|
||||
@ -128,4 +144,5 @@ $(eval $(call BuildPackage,libnl-core))
|
||||
$(eval $(call BuildPackage,libnl-genl))
|
||||
$(eval $(call BuildPackage,libnl-route))
|
||||
$(eval $(call BuildPackage,libnl-nf))
|
||||
$(eval $(call BuildPackage,libnl-cli))
|
||||
$(eval $(call BuildPackage,libnl))
|
||||
|
@ -454,6 +454,9 @@ define Build/Prepare
|
||||
mkdir -p $(PKG_BUILD_DIR)
|
||||
endef
|
||||
|
||||
define Build/Quilt
|
||||
endef
|
||||
|
||||
LIBGCC_A=$(lastword $(wildcard $(TOOLCHAIN_DIR)/lib/gcc/*/*/libgcc_pic.a))
|
||||
LIBGCC_MAP=$(lastword $(wildcard $(TOOLCHAIN_DIR)/lib/gcc/*/*/libgcc.map))
|
||||
LIBGCC_SO=$(lastword $(wildcard $(TOOLCHAIN_DIR)/lib/libgcc_s.so.*))
|
||||
@ -652,12 +655,23 @@ else
|
||||
exit 0
|
||||
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
|
||||
for file in $(call qstrip,$(CONFIG_LIBC_FILE_SPEC)); do \
|
||||
$(INSTALL_DIR) $(1)/lib ; \
|
||||
$(CP) $(call qstrip,$(CONFIG_LIBC_ROOT_DIR))/$$$$file $(1)/lib/ ; \
|
||||
done ; \
|
||||
exit 0
|
||||
$(call Package/$(LIBC)/install,$1)
|
||||
endef
|
||||
|
||||
define Package/libpthread/install
|
||||
|
@ -5,9 +5,9 @@ PKG_RELEASE:=2
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/netifd.git
|
||||
PKG_SOURCE_DATE:=2023-09-19
|
||||
PKG_SOURCE_VERSION:=7a58b995fdbecd9beed57e4d66d42cb3cf66aee2
|
||||
PKG_MIRROR_HASH:=a460a3b912047f8802eb24bb737084a08dad65b2dd520e5f5e7459379d1fcf8c
|
||||
PKG_SOURCE_DATE:=2023-10-20
|
||||
PKG_SOURCE_VERSION:=5590a80e2566d378be955f61c287a63fb3bdf329
|
||||
PKG_MIRROR_HASH:=eef792b4e9fa7a5227cf8c2ec4ed5e6558dd04c119cd9f97561923821fd1aa92
|
||||
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
@ -568,6 +568,7 @@ dhcp_add() {
|
||||
config_get ra_management "$cfg" ra_management
|
||||
config_get ra_preference "$cfg" ra_preference
|
||||
config_get dns "$cfg" dns
|
||||
config_get dns_sl "$cfg" domain
|
||||
|
||||
config_list_foreach "$cfg" "interface_name" append_interface_name "$ifname"
|
||||
|
||||
@ -647,6 +648,13 @@ dhcp_add() {
|
||||
fi
|
||||
|
||||
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
|
||||
|
||||
dhcp_option_add "$cfg" "$networkid" 0
|
||||
|
@ -12,9 +12,9 @@ PKG_RELEASE:=5
|
||||
|
||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/mdnsd.git
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_DATE:=2023-01-16
|
||||
PKG_SOURCE_VERSION:=65b3308d13de7d7975444d34389651612e2a4d38
|
||||
PKG_MIRROR_HASH:=945fdf51a299b68982aab74e8fba5614f2553a7b4c49a3a53b3093ea8aac0279
|
||||
PKG_SOURCE_DATE:=2023-10-19
|
||||
PKG_SOURCE_VERSION:=d45c443aa1e6514aab58bbbf9311913e484d31a6
|
||||
PKG_MIRROR_HASH:=20d91d867f4f34a37c7b2a600327884375f9f16c1ea9bbb3199347d8b617d856
|
||||
|
||||
PKG_MAINTAINER:=John Crispin <john@phrozen.org>
|
||||
PKG_LICENSE:=LGPL-2.1
|
||||
|
@ -6,12 +6,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=nftables
|
||||
PKG_VERSION:=1.0.8
|
||||
PKG_VERSION:=1.0.9
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
|
||||
PKG_SOURCE_URL:=https://netfilter.org/projects/$(PKG_NAME)/files
|
||||
PKG_HASH:=9373740de41a82dbc98818e0a46a073faeb8a8d0689fa4fa1a74399c32bf3d50
|
||||
PKG_HASH:=a3c304cd9ba061239ee0474f9afb938a9bb99d89b960246f66f0c3a0a85e14cd
|
||||
|
||||
PKG_MAINTAINER:=
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
@ -18,6 +18,9 @@ define Build/Prepare
|
||||
mkdir -p $(PKG_BUILD_DIR)
|
||||
endef
|
||||
|
||||
define Build/Quilt
|
||||
endef
|
||||
|
||||
define Build/Compile/Default
|
||||
endef
|
||||
Build/Compile = $(Build/Compile/Default)
|
||||
|
@ -9,6 +9,7 @@ clear_partialboots() {
|
||||
# clear partialboots
|
||||
|
||||
case $(board_name) in
|
||||
linksys,ea9200|\
|
||||
linksys,panamera)
|
||||
COMMIT=1
|
||||
nvram set partialboots=0
|
||||
|
28
rules.mk
28
rules.mk
@ -184,14 +184,14 @@ ifndef DUMP
|
||||
-include $(TOOLCHAIN_DIR)/info.mk
|
||||
export GCC_HONOUR_COPTS:=0
|
||||
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_CPPFLAGS+= -I$(TOOLCHAIN_DIR)/usr/include
|
||||
ifeq ($(CONFIG_USE_MUSL),y)
|
||||
TARGET_CPPFLAGS+= -I$(TOOLCHAIN_DIR)/include/fortify
|
||||
TOOLCHAIN_INC_DIRS+= $(TOOLCHAIN_DIR)/include/fortify
|
||||
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
|
||||
ifeq ($(CONFIG_NATIVE_TOOLCHAIN),)
|
||||
TARGET_CROSS:=$(call qstrip,$(CONFIG_TOOLCHAIN_PREFIX))
|
||||
@ -199,17 +199,17 @@ ifndef DUMP
|
||||
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_LIB_DIRS:=$(patsubst ./%,$(TOOLCHAIN_ROOT_DIR)/%,$(call qstrip,$(CONFIG_TOOLCHAIN_LIB_PATH)))
|
||||
ifneq ($(TOOLCHAIN_BIN_DIRS),)
|
||||
TARGET_PATH:=$(subst $(space),:,$(TOOLCHAIN_BIN_DIRS)):$(TARGET_PATH)
|
||||
endif
|
||||
ifneq ($(TOOLCHAIN_INC_DIRS),)
|
||||
TARGET_CPPFLAGS+= $(patsubst %,-I%,$(TOOLCHAIN_INC_DIRS))
|
||||
endif
|
||||
ifneq ($(TOOLCHAIN_LIB_DIRS),)
|
||||
TARGET_LDFLAGS+= $(patsubst %,-L%,$(TOOLCHAIN_LIB_DIRS))
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifneq ($(TOOLCHAIN_BIN_DIRS),)
|
||||
TARGET_PATH:=$(subst $(space),:,$(TOOLCHAIN_BIN_DIRS)):$(TARGET_PATH)
|
||||
endif
|
||||
ifneq ($(TOOLCHAIN_INC_DIRS),)
|
||||
TARGET_CPPFLAGS+= $(patsubst %,-I%,$(TOOLCHAIN_INC_DIRS))
|
||||
endif
|
||||
ifneq ($(TOOLCHAIN_LIB_DIRS),)
|
||||
TARGET_LDFLAGS+= $(patsubst %,-L%,$(TOOLCHAIN_LIB_DIRS))
|
||||
endif
|
||||
endif
|
||||
|
||||
TARGET_LINKER?=bfd
|
||||
|
@ -27,6 +27,7 @@ CFLAGS=""
|
||||
TOOLCHAIN="."
|
||||
|
||||
LIBC_TYPE=""
|
||||
GCC_VERSION=""
|
||||
|
||||
|
||||
# Library specs
|
||||
@ -199,6 +200,19 @@ find_bins() {
|
||||
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() {
|
||||
local out="$1"
|
||||
@ -383,6 +397,13 @@ print_config() {
|
||||
return 1
|
||||
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
|
||||
for lib in C RT PTHREAD GCC STDCPP SSP GFORTRAN GOMP; do
|
||||
local file
|
||||
@ -564,6 +585,7 @@ while [ -n "$1" ]; do
|
||||
--config)
|
||||
if probe_cc; then
|
||||
probe_libc
|
||||
find_gcc_version
|
||||
print_config "$1"
|
||||
exit $?
|
||||
fi
|
||||
|
@ -3,7 +3,12 @@ define Build/create-uImage-dtb
|
||||
-$(STAGING_DIR_HOST)/bin/mkimage -A $(LINUX_KARCH) \
|
||||
-O linux -T kernel -C none \
|
||||
-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
|
||||
|
||||
define Build/meraki-header
|
||||
@ -104,7 +109,7 @@ define Device/netgear_wndr4700
|
||||
# append a fake/empty rootfs to fool netgear's uboot
|
||||
# CHECK_DNI_FIRMWARE_ROOTFS_INTEGRITY in do_chk_dniimg()
|
||||
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
|
||||
IMAGE/factory.img := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-ubi | \
|
||||
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() {
|
||||
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
|
||||
cp -af "$UPGRADE_BACKUP" "/mnt/$BACKUP_FILE"
|
||||
umount /mnt
|
||||
|
@ -96,9 +96,8 @@
|
||||
|
||||
ath9k0: wifi@0,11 { /* 2.4 GHz */
|
||||
compatible = "pci168c,0029";
|
||||
nvmem-cells = <&macaddr_hwinfo_1c>;
|
||||
nvmem-cells = <&macaddr_hwinfo_1c 1>;
|
||||
nvmem-cell-names = "mac-address";
|
||||
mac-address-increment = <1>;
|
||||
reg = <0x8800 0 0 0 0>;
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
@ -106,9 +105,8 @@
|
||||
|
||||
ath9k1: wifi@0,12 { /* 5 GHz */
|
||||
compatible = "pci168c,0029";
|
||||
nvmem-cells = <&macaddr_hwinfo_1c>;
|
||||
nvmem-cells = <&macaddr_hwinfo_1c 2>;
|
||||
nvmem-cell-names = "mac-address";
|
||||
mac-address-increment = <2>;
|
||||
reg = <0x9000 0 0 0 0>;
|
||||
#gpio-cells = <2>;
|
||||
gpio-controller;
|
||||
@ -125,7 +123,7 @@
|
||||
|
||||
ð0 {
|
||||
status = "okay";
|
||||
nvmem-cells = <&macaddr_hwinfo_1c>;
|
||||
nvmem-cells = <&macaddr_hwinfo_1c 0>;
|
||||
nvmem-cell-names = "mac-address";
|
||||
|
||||
pll-data = <0x00110000 0x00001099 0x00991099>;
|
||||
@ -160,9 +158,22 @@
|
||||
};
|
||||
|
||||
hwinfo: partition@fe0000 {
|
||||
label = "hwinfo";
|
||||
reg = <0xfe0000 0x10000>;
|
||||
compatible = "nvmem-cells";
|
||||
label = "hwinfo";
|
||||
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 {
|
||||
@ -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) {
|
||||
--- a/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 */
|
||||
|
||||
if (unlikely(OPTION_MD5 & options)) {
|
||||
@ -426,7 +426,7 @@ SVN-Revision: 35130
|
||||
}
|
||||
|
||||
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;
|
||||
int this_sack;
|
||||
|
||||
@ -450,7 +450,7 @@ SVN-Revision: 35130
|
||||
}
|
||||
|
||||
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) {
|
||||
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
|
||||
+++ 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 =
|
||||
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
|
||||
+++ 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;
|
||||
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) {
|
||||
if (!new_crtc_state->active)
|
||||
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);
|
||||
continue;
|
||||
}
|
||||
|
@ -1185,7 +1185,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
|
||||
}
|
||||
--- a/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_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
|
||||
--- a/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),
|
||||
DEVICE_FLG(0x0ecb, 0x2069, /* JBL Quantum810 Wireless */
|
||||
QUIRK_FLAG_FIXED_RATE),
|
||||
+ DEVICE_FLG(0x09da, 0x2695, /* A4Tech FHD 1080p webcam */
|
||||
+ 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)
|
||||
@@ -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);
|
||||
|
||||
@ -108,7 +108,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
|
||||
if (ts->load_cfg_from_disk)
|
||||
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 */
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1465,7 +1523,7 @@ static int __maybe_unused goodix_resume(
|
||||
@@ -1484,7 +1542,7 @@ static int __maybe_unused goodix_resume(
|
||||
int error;
|
||||
|
||||
if (ts->irq_pin_access_method == IRQ_PIN_ACCESS_NONE) {
|
||||
|
@ -50,6 +50,7 @@ bcm53xx_setup_macs()
|
||||
offset=1
|
||||
;;
|
||||
dlink,dir-885l | \
|
||||
linksys,ea9200 | \
|
||||
linksys,panamera | \
|
||||
netgear,r7900 | \
|
||||
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>
|
||||
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
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
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>
|
||||
---
|
||||
drivers/nvmem/brcm_nvram.c | 54 +++++++++++++++++++-------------------
|
||||
1 file changed, 27 insertions(+), 27 deletions(-)
|
||||
drivers/nvmem/brcm_nvram.c | 130 +++++++++++++++++++++++++------------
|
||||
1 file changed, 90 insertions(+), 40 deletions(-)
|
||||
|
||||
--- a/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 device *dev;
|
||||
- void __iomem *base;
|
||||
+ size_t nvmem_size;
|
||||
+ uint8_t *data;
|
||||
+ size_t data_len;
|
||||
+ uint8_t padding_byte;
|
||||
struct nvmem_cell_info *cells;
|
||||
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)
|
||||
{
|
||||
struct brcm_nvram *priv = context;
|
||||
- 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--)
|
||||
- *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;
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
@ -42,7 +178,6 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
struct device *dev = priv->dev;
|
||||
- struct brcm_nvram_header header;
|
||||
- uint8_t *data;
|
||||
+ uint8_t tmp;
|
||||
size_t len;
|
||||
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);
|
||||
|
||||
-
|
||||
- data = kzalloc(len, GFP_KERNEL);
|
||||
- if (!data)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- memcpy_fromio(data, priv->base, len);
|
||||
- data[len - 1] = '\0';
|
||||
+ tmp = priv->data[len - 1];
|
||||
+ priv->data[len - 1] = '\0';
|
||||
|
||||
-
|
||||
- err = brcm_nvram_add_cells(priv, data, len);
|
||||
- if (err) {
|
||||
+ err = brcm_nvram_add_cells(priv, priv->data, len);
|
||||
+ if (err)
|
||||
dev_err(dev, "Failed to add cells: %d\n", err);
|
||||
- dev_err(dev, "Failed to add cells: %d\n", 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);
|
||||
+ 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;
|
||||
}
|
||||
@@ -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,
|
||||
};
|
||||
struct device *dev = &pdev->dev;
|
||||
- struct resource *res;
|
||||
struct brcm_nvram *priv;
|
||||
+ struct resource *res;
|
||||
+ void __iomem *base;
|
||||
+ size_t size;
|
||||
int err;
|
||||
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
@@ -159,21 +151,29 @@ static int brcm_nvram_probe(struct platf
|
||||
@@ -159,21 +211,19 @@ static int brcm_nvram_probe(struct platf
|
||||
return -ENOMEM;
|
||||
priv->dev = dev;
|
||||
|
||||
- priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
||||
- if (IS_ERR(priv->base))
|
||||
- return PTR_ERR(priv->base);
|
||||
+ base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
||||
+ if (IS_ERR(base))
|
||||
+ return PTR_ERR(base);
|
||||
+
|
||||
+ size = resource_size(res);
|
||||
+
|
||||
+ priv->data = kzalloc(size, GFP_KERNEL);
|
||||
+ if (!priv->data)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ memcpy_fromio(priv->data, base, size);
|
||||
+ err = brcm_nvram_copy_data(priv, pdev);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
|
||||
err = brcm_nvram_parse(priv);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
- bcm47xx_nvram_init_from_iomem(priv->base, resource_size(res));
|
||||
+ bcm47xx_nvram_init_from_iomem(base, size);
|
||||
|
||||
-
|
||||
config.dev = dev;
|
||||
config.cells = priv->cells;
|
||||
config.ncells = priv->ncells;
|
||||
config.priv = priv;
|
||||
- config.size = resource_size(res);
|
||||
+ config.size = size;
|
||||
+ config.size = priv->nvmem_size;
|
||||
|
||||
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>
|
||||
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
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
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>
|
||||
---
|
||||
drivers/nvmem/brcm_nvram.c | 54 +++++++++++++++++++-------------------
|
||||
1 file changed, 27 insertions(+), 27 deletions(-)
|
||||
drivers/nvmem/brcm_nvram.c | 130 +++++++++++++++++++++++++------------
|
||||
1 file changed, 90 insertions(+), 40 deletions(-)
|
||||
|
||||
--- a/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 device *dev;
|
||||
- void __iomem *base;
|
||||
+ size_t nvmem_size;
|
||||
+ uint8_t *data;
|
||||
+ size_t data_len;
|
||||
+ uint8_t padding_byte;
|
||||
struct nvmem_cell_info *cells;
|
||||
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)
|
||||
{
|
||||
struct brcm_nvram *priv = context;
|
||||
- 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--)
|
||||
- *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;
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
@ -42,7 +178,6 @@ Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
struct device *dev = priv->dev;
|
||||
- struct brcm_nvram_header header;
|
||||
- uint8_t *data;
|
||||
+ uint8_t tmp;
|
||||
size_t len;
|
||||
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);
|
||||
|
||||
-
|
||||
- data = kzalloc(len, GFP_KERNEL);
|
||||
- if (!data)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- memcpy_fromio(data, priv->base, len);
|
||||
- data[len - 1] = '\0';
|
||||
+ tmp = priv->data[len - 1];
|
||||
+ priv->data[len - 1] = '\0';
|
||||
|
||||
-
|
||||
- err = brcm_nvram_add_cells(priv, data, len);
|
||||
- if (err) {
|
||||
+ err = brcm_nvram_add_cells(priv, priv->data, len);
|
||||
+ if (err)
|
||||
dev_err(dev, "Failed to add cells: %d\n", err);
|
||||
- dev_err(dev, "Failed to add cells: %d\n", 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);
|
||||
+ 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;
|
||||
}
|
||||
@@ -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,
|
||||
};
|
||||
struct device *dev = &pdev->dev;
|
||||
- struct resource *res;
|
||||
struct brcm_nvram *priv;
|
||||
+ struct resource *res;
|
||||
+ void __iomem *base;
|
||||
+ size_t size;
|
||||
int err;
|
||||
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
@@ -159,21 +151,29 @@ static int brcm_nvram_probe(struct platf
|
||||
@@ -159,21 +211,19 @@ static int brcm_nvram_probe(struct platf
|
||||
return -ENOMEM;
|
||||
priv->dev = dev;
|
||||
|
||||
- priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
||||
- if (IS_ERR(priv->base))
|
||||
- return PTR_ERR(priv->base);
|
||||
+ base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
|
||||
+ if (IS_ERR(base))
|
||||
+ return PTR_ERR(base);
|
||||
+
|
||||
+ size = resource_size(res);
|
||||
+
|
||||
+ priv->data = kzalloc(size, GFP_KERNEL);
|
||||
+ if (!priv->data)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ memcpy_fromio(priv->data, base, size);
|
||||
+ err = brcm_nvram_copy_data(priv, pdev);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
|
||||
err = brcm_nvram_parse(priv);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
- bcm47xx_nvram_init_from_iomem(priv->base, resource_size(res));
|
||||
+ bcm47xx_nvram_init_from_iomem(base, size);
|
||||
|
||||
-
|
||||
config.dev = dev;
|
||||
config.cells = priv->cells;
|
||||
config.ncells = priv->ncells;
|
||||
config.priv = priv;
|
||||
- config.size = resource_size(res);
|
||||
+ config.size = size;
|
||||
+ config.size = priv->nvmem_size;
|
||||
|
||||
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
|
||||
+++ 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);
|
||||
|
||||
@ -40,7 +40,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
|
||||
/* Check if qca8k_read has failed for a different reason
|
||||
* 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:
|
||||
/* 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);
|
||||
|
||||
@@ -817,18 +817,18 @@ qca8k_mdio_read(struct qca8k_priv *priv,
|
||||
@@ -828,18 +828,18 @@ qca8k_mdio_read(struct qca8k_priv *priv,
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
|
@ -168,7 +168,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
};
|
||||
|
||||
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 = {
|
||||
.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
|
||||
+++ 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)
|
||||
return ret;
|
||||
|
||||
@ -44,7 +44,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
if (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_max_mtu = qca8k_port_max_mtu,
|
||||
.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
|
||||
+++ 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)
|
||||
return ret;
|
||||
|
||||
|
@ -17,7 +17,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
|
||||
--- a/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;
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
static int
|
||||
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.
|
||||
* 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
|
||||
+++ 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)
|
||||
{
|
||||
struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
|
||||
@ -27,7 +27,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
u32 mask;
|
||||
|
||||
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");
|
||||
|
||||
/* 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
|
||||
@@ -1910,48 +1911,48 @@ qca8k_setup(struct dsa_switch *ds)
|
||||
@@ -1921,48 +1922,48 @@ qca8k_setup(struct dsa_switch *ds)
|
||||
return ret;
|
||||
|
||||
/* 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
|
||||
--- a/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))
|
||||
dev_queue_xmit_nit(skb, dev);
|
||||
|
||||
|
@ -44,7 +44,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
--- a/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);
|
||||
}
|
||||
|
||||
@ -93,7 +93,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
static int __netdev_upper_dev_link(struct net_device *dev,
|
||||
struct net_device *upper_dev, bool master,
|
||||
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)
|
||||
return ret;
|
||||
|
||||
@ -101,7 +101,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
ret = call_netdevice_notifiers_info(NETDEV_CHANGEUPPER,
|
||||
&changeupper_info.info);
|
||||
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);
|
||||
|
||||
@ -109,7 +109,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
call_netdevice_notifiers_info(NETDEV_CHANGEUPPER,
|
||||
&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)
|
||||
return err;
|
||||
dev->addr_assign_type = NET_ADDR_SET;
|
||||
|
@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
#endif
|
||||
--- a/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);
|
||||
|
||||
#ifdef CONFIG_RPS
|
||||
@ -39,7 +39,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
sd->rps_ipi_next = mysd->rps_ipi_list;
|
||||
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 */
|
||||
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 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);
|
||||
}
|
||||
}
|
||||
@ -66,7 +66,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
skb_queue_walk_safe(&sd->process_queue, skb, tmp) {
|
||||
if (skb->dev->reg_state == NETREG_UNREGISTERING) {
|
||||
__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);
|
||||
}
|
||||
}
|
||||
@ -83,7 +83,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
}
|
||||
|
||||
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);
|
||||
@ -91,7 +91,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
if (skb_queue_empty(&sd->input_pkt_queue)) {
|
||||
/*
|
||||
* 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(),
|
||||
* and we dont need an smp_mb() memory barrier.
|
||||
*/
|
||||
@ -101,7 +101,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
again = false;
|
||||
} else {
|
||||
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);
|
||||
|
||||
@ -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,
|
||||
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);
|
||||
local_irq_enable();
|
||||
|
||||
@ -167,7 +167,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
#ifdef CONFIG_RPS
|
||||
remsd = oldsd->rps_ipi_list;
|
||||
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);
|
||||
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
|
||||
* @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;
|
||||
ap->nr_active_links--;
|
||||
}
|
||||
@ -75,7 +75,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
/* clear exclusive status */
|
||||
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.idle_irq = 1;
|
||||
#endif
|
||||
@ -85,7 +85,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
ata_sff_port_init(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->slave_link);
|
||||
@ -98,7 +98,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
kfree(ap);
|
||||
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]->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
|
||||
@@ -861,6 +864,12 @@ struct ata_port {
|
||||
@@ -864,6 +867,12 @@ struct ata_port {
|
||||
#ifdef CONFIG_ATA_ACPI
|
||||
struct ata_acpi_gtm __acpi_init_gtm; /* use ata_acpi_init_gtm() */
|
||||
#endif
|
||||
|
@ -74,8 +74,8 @@ CONFIG_CPU_COPY_V6=y
|
||||
CONFIG_CPU_CP15=y
|
||||
CONFIG_CPU_CP15_MMU=y
|
||||
CONFIG_CPU_FREQ=y
|
||||
CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
|
||||
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
|
||||
# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
|
||||
CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
|
||||
CONFIG_CPU_FREQ_GOV_ATTR_SET=y
|
||||
CONFIG_CPU_FREQ_GOV_COMMON=y
|
||||
# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
|
||||
|
@ -354,7 +354,7 @@ endef
|
||||
#TARGET_DEVICES += compex_wpj419
|
||||
|
||||
define Device/compex_wpj428
|
||||
$(call Device/FitImage)
|
||||
$(call Device/FitzImage)
|
||||
DEVICE_VENDOR := Compex
|
||||
DEVICE_MODEL := WPJ428
|
||||
SOC := qcom-ipq4028
|
||||
|
@ -66,7 +66,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
/**
|
||||
--- a/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.
|
||||
*/
|
||||
work = 0;
|
||||
|
@ -1,7 +1,7 @@
|
||||
ARCH:=mips
|
||||
SUBTARGET:=xrx200
|
||||
BOARDNAME:=XRX200
|
||||
FEATURES+=atm nand ramdisk source-only
|
||||
FEATURES+=atm nand ramdisk
|
||||
CPU_TYPE:=24kc
|
||||
|
||||
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 +-
|
||||
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
|
||||
+++ 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;
|
||||
|
||||
@ -162,7 +160,7 @@ index f19a1821af42..e0b3af0892ac 100644
|
||||
sizeof(link_states));
|
||||
|
||||
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 */
|
||||
ret = copy_to_user(buf, &link_states, sizeof(link_states));
|
||||
if (ret != 0) {
|
||||
@ -179,8 +177,6 @@ index f19a1821af42..e0b3af0892ac 100644
|
||||
|
||||
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
|
||||
+++ b/drivers/staging/fsl_ppfe/pfe_hif.c
|
||||
@@ -115,11 +115,11 @@ static void send_dummy_pkt_to_hif(void)
|
||||
@ -197,7 +193,7 @@ index dcc3f7f1e9ef..5347401f92c0 100644
|
||||
if (!lmem_ptr)
|
||||
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)
|
||||
{
|
||||
struct hif_desc *desc;
|
||||
@ -217,7 +213,7 @@ index dcc3f7f1e9ef..5347401f92c0 100644
|
||||
for (ii = 0; ii < hif->rx_ring_size; ii++) {
|
||||
pr_info("status: %08x, ctrl: %08x, data: %08x, next: %x\n",
|
||||
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;
|
||||
@ -230,11 +226,9 @@ index dcc3f7f1e9ef..5347401f92c0 100644
|
||||
for (ii = 0; ii < hif->tx_ring_size; ii++) {
|
||||
pr_info("status: %08x, ctrl: %08x, data: %08x, next: %x\n",
|
||||
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
|
||||
+++ 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,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
@ -243,6 +237,3 @@ index 1792e88140d1..ede651be51bf 100644
|
||||
return count;
|
||||
}
|
||||
|
||||
--
|
||||
2.25.1
|
||||
|
||||
|
@ -30,11 +30,9 @@ Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
|
||||
drivers/net/phy/phylink.c | 1 +
|
||||
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
|
||||
+++ 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;
|
||||
|
||||
case PHY_INTERFACE_MODE_2500BASEX:
|
||||
@ -42,6 +40,3 @@ index 2805b04d6402..a1e34b127401 100644
|
||||
caps |= MAC_2500FD;
|
||||
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/input/input.h>
|
||||
#include <dt-bindings/leds/common.h>
|
||||
|
||||
/ {
|
||||
aliases {
|
||||
@ -21,14 +22,14 @@
|
||||
keys {
|
||||
compatible = "gpio-keys";
|
||||
|
||||
wps {
|
||||
button-wps {
|
||||
label = "wps";
|
||||
gpios = <&gpio 28 GPIO_ACTIVE_LOW>;
|
||||
gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
|
||||
debounce-interval = <60>;
|
||||
linux,code = <KEY_WPS_BUTTON>;
|
||||
};
|
||||
|
||||
reset {
|
||||
button-reset {
|
||||
label = "reset";
|
||||
gpios = <&gpio 8 GPIO_ACTIVE_LOW>;
|
||||
debounce-interval = <60>;
|
||||
@ -39,35 +40,44 @@
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
led_power: power {
|
||||
led_power: led-power {
|
||||
label = "green:power";
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
function = LED_FUNCTION_POWER;
|
||||
gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
wan_orange {
|
||||
label = "orange:wan";
|
||||
led-wan-amber {
|
||||
color = <LED_COLOR_ID_AMBER>;
|
||||
function = LED_FUNCTION_WAN;
|
||||
gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
lan {
|
||||
label = "green:lan";
|
||||
led-lan {
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
function = LED_FUNCTION_LAN;
|
||||
gpios = <&gpio 15 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
wifi5g {
|
||||
label = "green:wifi5g";
|
||||
led-wifi5g {
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
function = LED_FUNCTION_WLAN;
|
||||
function-enumerator = <5>;
|
||||
gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
|
||||
linux,default-trigger = "phy1tpt";
|
||||
};
|
||||
|
||||
wifi2g {
|
||||
label = "green:wifi2g";
|
||||
led-wifi2g {
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
function = LED_FUNCTION_WLAN;
|
||||
function-enumerator = <2>;
|
||||
gpios = <&gpio 18 GPIO_ACTIVE_LOW>;
|
||||
linux,default-trigger = "phy0tpt";
|
||||
};
|
||||
|
||||
wan_green {
|
||||
label = "green:wan";
|
||||
led-wan-green {
|
||||
color = <LED_COLOR_ID_GREEN>;
|
||||
function = LED_FUNCTION_WAN;
|
||||
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,sg2210p-v3|\
|
||||
tplink,sg2452p-v4)
|
||||
tplink,sg2452p-v4|\
|
||||
tplink,t1600g-28ts-v3)
|
||||
label_mac=$(get_mac_label)
|
||||
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
|
||||
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
|
||||
$(Device/zyxel_gs1900)
|
||||
SOC := rtl8380
|
||||
|
@ -150,6 +150,14 @@ menuconfig EXTERNAL_TOOLCHAIN
|
||||
|
||||
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
|
||||
string
|
||||
depends on EXTERNAL_TOOLCHAIN && !NATIVE_TOOLCHAIN
|
||||
|
@ -8,6 +8,7 @@ config GCC_VERSION_13
|
||||
|
||||
config GCC_VERSION
|
||||
string
|
||||
default EXTERNAL_GCC_VERSION if EXTERNAL_TOOLCHAIN && !NATIVE_TOOLCHAIN
|
||||
default "11.3.0" if GCC_VERSION_11
|
||||
default "13.2.0" if GCC_VERSION_13
|
||||
default "12.3.0"
|
||||
|
@ -3,12 +3,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=mold
|
||||
PKG_VERSION:=2.2.0
|
||||
PKG_VERSION:=2.3.1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(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_HASH:=78ddddaaa004e50f8d92a13d8e792a46a1b37745fab48d39ad16aeb5a776e7c6
|
||||
PKG_HASH:=380f540114408c37bcdb7f3bda91a056448a93124ca6992a373ae2bda35e9af7
|
||||
|
||||
include $(INCLUDE_DIR)/host-build.mk
|
||||
include $(INCLUDE_DIR)/cmake.mk
|
||||
|
Loading…
x
Reference in New Issue
Block a user