Merge Official Source

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
Tianling Shen 2025-01-08 15:17:32 +08:00
commit 8607c28361
No known key found for this signature in database
GPG Key ID: 6850B6345C862176
13 changed files with 1729 additions and 46 deletions

View File

@ -844,13 +844,19 @@ mac80211_setup_adhoc() {
mac80211_setup_mesh() {
json_get_vars ssid mesh_id mcast_rate
json_get_values iface_basic_rate_list basic_rate
mcval=
[ -n "$mcast_rate" ] && wpa_supplicant_add_rate mcval "$mcast_rate"
[ -n "$mesh_id" ] && ssid="$mesh_id"
br_list="$basic_rate_list"
if [ -n "$iface_basic_rate_list" ]; then
br_list="$iface_basic_rate_list"
fi
brstr=
for br in $basic_rate_list; do
for br in $br_list; do
wpa_supplicant_add_rate brstr "$br"
done

View File

@ -40,18 +40,35 @@
gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>;
};
};
};
&mdio_aux {
status = "okay";
// Reset GPIO is <&gpio0 1 GPIO_ACTIVE_LOW>
// Don't specify the reset info so the mdio subsystem doesn't reset the bus
//reset-gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
//reset-delay-us = <1000>;
//reset-post-delay-us = <10000>;
gpio1: expander@0 {
compatible = "realtek,rtl8231";
reg = <0x0>;
gpio1: rtl8231-gpio {
compatible = "realtek,rtl8231-gpio";
#gpio-cells = <2>;
gpio-controller;
indirect-access-bus-id = <0>;
#gpio-cells = <2>;
gpio-ranges = <&gpio1 0 0 37>;
poe_enable {
gpio-hog;
gpios = <13 GPIO_ACTIVE_HIGH>;
output-high;
};
led-controller {
compatible = "realtek,rtl8231-leds";
status = "disabled";
};
};
};

View File

@ -232,6 +232,42 @@
};
};
switchcore@1b000000 {
compatible = "syscon", "simple-mfd";
reg = <0x1b000000 0x20000>;
mdio_aux: mdio-aux {
compatible = "realtek,rtl8380-aux-mdio";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
pinctrl-names = "default";
pinctrl-0 = <&mdio_aux_mdx>, <&aux_mode_mdio>;
};
};
pinmux@1b000144 {
compatible = "pinctrl-single";
reg = <0x1b000144 0x4>;
pinctrl-single,bit-per-mux;
pinctrl-single,register-width = <32>;
pinctrl-single,function-mask = <0x1>;
#pinctrl-cells = <2>;
/* I2C mode */
aux_mode_i2c: i2c-pins {
pinctrl-single,bits = <0x0 0x0 0x1>;
};
/* MDIO mode */
aux_mode_mdio: mdx-pins {
pinctrl-single,bits = <0x0 0x1 0x1>;
};
};
pinmux: pinmux@1b001000 {
compatible = "pinctrl-single";
reg = <0x1b001000 0x4>;
@ -262,6 +298,26 @@
};
};
pinmux@1b00a0e0 {
compatible = "pinctrl-single";
reg = <0x1b00a0e0 0x4>;
pinctrl-single,bit-per-mux;
pinctrl-single,register-width = <32>;
pinctrl-single,function-mask = <0x1>;
#pinctrl-cells = <2>;
/* Use SoC GPIO 2/3 as GPIO */
mdio_aux_gpio: gpio-pins {
pinctrl-single,bits = <0x0 0x0 0x1>;
};
/* Use SoC GPIO 2/3 as MDC/MDIO */
mdio_aux_mdx: mdx-pins {
pinctrl-single,bits = <0x0 0x1 0x1>;
};
};
ethernet0: ethernet@1b00a300 {
compatible = "realtek,rtl838x-eth";
reg = <0x1b00a300 0x100>;

View File

@ -0,0 +1,193 @@
From c7ddb74c981c1a29bad82d555d08724aca93b687 Mon Sep 17 00:00:00 2001
From: Sander Vanheule <sander@svanheule.net>
Date: Fri, 27 Dec 2024 14:55:31 +0100
Subject: [PATCH] net: mdio: Add Realtek Otto auxiliary controller
SoCs in Realtek's Otto platform such as the RTL8380 and RTL8391 have a
simple auxiliary MDIO controller that is commonly used to manage RTL8231
GPIO expanders on switch devices.
Add a new MDIO controller driver supporting the RTL838x (maple) and
RTL839x (cypress) SoCs.
Signed-off-by: Sander Vanheule <sander@svanheule.net>
---
drivers/net/mdio/Kconfig | 10 ++
drivers/net/mdio/Makefile | 1 +
drivers/net/mdio/mdio-realtek-otto-aux.c | 129 +++++++++++++++++++++++
3 files changed, 140 insertions(+)
create mode 100644 drivers/net/mdio/mdio-realtek-otto-aux.c
--- a/drivers/net/mdio/Kconfig
+++ b/drivers/net/mdio/Kconfig
@@ -207,6 +207,16 @@ config MDIO_REGMAP
regmap. Users willing to use this driver must explicitly select
REGMAP.
+config MDIO_REALTEK_OTTO_AUX
+ tristate "Realtek Otto auxiliary MDIO interface support"
+ default MACH_REALTEK_RTL
+ depends on MACH_REALTEK_RTL
+ depends on MFD_SYSCON
+ select MDIO_DEVRES
+ help
+ This driver supports the auxilairy MDIO bus on RTL838x SoCs. This bus
+ is typically used to attach RTL8231 GPIO extenders.
+
config MDIO_THUNDER
tristate "ThunderX SOCs MDIO buses"
depends on 64BIT
--- a/drivers/net/mdio/Makefile
+++ b/drivers/net/mdio/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_MDIO_MSCC_MIIM) += mdio-ms
obj-$(CONFIG_MDIO_MVUSB) += mdio-mvusb.o
obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o
obj-$(CONFIG_MDIO_REGMAP) += mdio-regmap.o
+obj-$(CONFIG_MDIO_REALTEK_OTTO_AUX) += mdio-realtek-otto-aux.o
obj-$(CONFIG_MDIO_SMBUS) += mdio-smbus.o
obj-$(CONFIG_MDIO_SUN4I) += mdio-sun4i.o
obj-$(CONFIG_MDIO_THUNDER) += mdio-thunder.o
--- /dev/null
+++ b/drivers/net/mdio/mdio-realtek-otto-aux.c
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <linux/mfd/core.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_mdio.h>
+#include <linux/of_platform.h>
+#include <linux/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#define RTL8380_EXT_GPIO_INDIRECT_ACCESS 0xA09C
+#define RTL8390_EXT_GPIO_INDIRECT_ACCESS 0x0224
+
+#define RTL83XX_AUX_MDIO_DATA GENMASK(31, 16)
+#define RTL83XX_AUX_MDIO_REG GENMASK(11, 7)
+#define RTL83XX_AUX_MDIO_PHY_ADDR GENMASK(6, 2)
+#define RTL83XX_AUX_MDIO_WRITE BIT(1)
+#define RTL83XX_AUX_MDIO_READ 0
+#define RTL83XX_AUX_MDIO_EXEC BIT(0)
+
+struct realtek_aux_mdio_ctrl {
+ struct device *dev;
+ struct regmap *map;
+ unsigned int cmd_reg;
+};
+
+#define mii_bus_to_ctrl(bus) ((struct realtek_aux_mdio_ctrl *) bus->priv)
+
+static int rtl83xx_aux_mdio_cmd(struct realtek_aux_mdio_ctrl *ctrl, int addr, int regnum,
+ u32 rw_bit, u16 *data)
+{
+ unsigned int mask_volatile;
+ unsigned int cmd;
+ unsigned int run;
+ int err;
+
+ cmd = rw_bit | RTL83XX_AUX_MDIO_EXEC;
+ cmd |= FIELD_PREP(RTL83XX_AUX_MDIO_PHY_ADDR, addr);
+ cmd |= FIELD_PREP(RTL83XX_AUX_MDIO_REG, regnum);
+
+ mask_volatile = RTL83XX_AUX_MDIO_EXEC;
+
+ if (rw_bit == RTL83XX_AUX_MDIO_WRITE)
+ cmd |= FIELD_PREP(RTL83XX_AUX_MDIO_DATA, *data);
+ else
+ mask_volatile |= RTL83XX_AUX_MDIO_DATA;
+
+ err = regmap_write(ctrl->map, ctrl->cmd_reg, cmd);
+ if (err)
+ return err;
+
+ err = regmap_read_poll_timeout(ctrl->map, ctrl->cmd_reg, run, (run != cmd), 3, 100);
+
+ if ((run & ~mask_volatile) != (cmd & ~mask_volatile)) {
+ dev_err(ctrl->dev, "Command modified. Is offloading still active?");
+ return -EIO;
+ }
+
+ if (!err && (rw_bit == RTL83XX_AUX_MDIO_READ))
+ *data = FIELD_GET(RTL83XX_AUX_MDIO_DATA, run);
+
+ return err;
+}
+
+static int rtl83xx_aux_mdio_read(struct mii_bus *bus, int addr, int regnum)
+{
+ struct realtek_aux_mdio_ctrl *ctrl = mii_bus_to_ctrl(bus);
+ u16 data;
+ int err;
+
+ err = rtl83xx_aux_mdio_cmd(ctrl, addr, regnum, RTL83XX_AUX_MDIO_READ, &data);
+
+ if (err)
+ return err;
+ else
+ return data;
+}
+
+static int rtl83xx_aux_mdio_write(struct mii_bus *bus, int addr, int regnum, u16 val)
+{
+ struct realtek_aux_mdio_ctrl *ctrl = mii_bus_to_ctrl(bus);
+
+ return rtl83xx_aux_mdio_cmd(ctrl, addr, regnum, RTL83XX_AUX_MDIO_WRITE, &val);
+}
+
+static int realtek_aux_mdio_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct realtek_aux_mdio_ctrl *ctrl;
+ struct mii_bus *bus;
+
+ bus = devm_mdiobus_alloc_size(&pdev->dev, sizeof(*ctrl));
+ if (!bus)
+ return -ENOMEM;
+
+ ctrl = bus->priv;
+ ctrl->dev = &pdev->dev;
+ ctrl->cmd_reg = (unsigned int) device_get_match_data(ctrl->dev);
+ ctrl->map = syscon_node_to_regmap(np->parent);
+ if (IS_ERR(ctrl->map))
+ return PTR_ERR(ctrl->map);
+
+ bus->name = "RTL83xx auxiliary MDIO bus";
+ snprintf(bus->id, MII_BUS_ID_SIZE, "rtl83xx-aux-mdio") ;
+ bus->parent = ctrl->dev;
+ bus->read = rtl83xx_aux_mdio_read;
+ bus->write = rtl83xx_aux_mdio_write;
+ /* Don't have interrupts */
+ for (unsigned int i = 0; i < PHY_MAX_ADDR; i++)
+ bus->irq[i] = PHY_POLL;
+
+ return devm_of_mdiobus_register(ctrl->dev, bus, np);
+}
+
+static const struct of_device_id realtek_aux_mdio_of_match[] = {
+ {
+ .compatible = "realtek,rtl8380-aux-mdio",
+ .data = (void *) RTL8380_EXT_GPIO_INDIRECT_ACCESS,
+ },
+ {
+ .compatible = "realtek,rtl8390-aux-mdio",
+ .data = (void *) RTL8390_EXT_GPIO_INDIRECT_ACCESS,
+ },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, realtek_aux_mdio_of_match);
+
+static struct platform_driver realtek_aux_mdio_driver = {
+ .driver = {
+ .name = "realtek-otto-aux-mdio",
+ .of_match_table = realtek_aux_mdio_of_match
+ },
+ .probe = realtek_aux_mdio_probe,
+};
+module_platform_driver(realtek_aux_mdio_driver);
+
+MODULE_AUTHOR("Sander Vanheule <sander@svanheule.net>");
+MODULE_DESCRIPTION("Realtek RTL83xx auxiliary MDIO bus");
+MODULE_LICENSE("GPL v2");

View File

@ -0,0 +1,56 @@
From b3f79468c90d8770f007d628a1e32b2d5d44a5c2 Mon Sep 17 00:00:00 2001
From: Sander Vanheule <sander@svanheule.net>
Date: Sat, 15 May 2021 11:57:32 +0200
Subject: [PATCH] gpio: regmap: Bypass cache for shadowed outputs
Some chips have the read-only input and write-only output data registers
aliased to the same offset, but do not perform direction multiplexing on
writes. Upon writing the register, this then always updates the output
value, even when the pin is configured as input. As a result it is not
safe to perform read-modify-writes on output pins, when other pins are
still configured as input.
For example, on a bit-banged I2C bus, where the lines are switched
between out-low and in (with external pull-up)
OUT(L) IN OUT(H)
SCK ....../''''''|''''''
SDA '''''''''\..........
^ ^- SCK switches to direction to OUT, but now has a high
| value, breaking the clock.
|
\- Perform RMW to update SDA. This reads the current input
value for SCK, updates the SDA value and writes back a 1
for SCK as well.
If a register is used for both the data input and data output (and is
not marked as volatile) the driver should ensure the cache is not
updated on register reads. This ensures proper functioning of writing
the output register with regmap_update_bits(), which will then use and
update the cache only on register writes.
Signed-off-by: Sander Vanheule <sander@svanheule.net>
---
drivers/gpio/gpio-regmap.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
--- a/drivers/gpio/gpio-regmap.c
+++ b/drivers/gpio/gpio-regmap.c
@@ -74,7 +74,15 @@ static int gpio_regmap_get(struct gpio_c
if (ret)
return ret;
- ret = regmap_read(gpio->regmap, reg, &val);
+ /*
+ * Ensure we don't spoil the register cache with pin input values and
+ * perform a bypassed read. This way the cache (if any) is only used and
+ * updated on register writes.
+ */
+ if (gpio->reg_dat_base == gpio->reg_set_base)
+ ret = regmap_read_bypassed(gpio->regmap, reg, &val);
+ else
+ ret = regmap_read(gpio->regmap, reg, &val);
if (ret)
return ret;

View File

@ -0,0 +1,26 @@
From f21b15dfe254b51f80c552750eb20b1dc752507a Mon Sep 17 00:00:00 2001
From: Sander Vanheule <sander@svanheule.net>
Date: Mon, 30 Dec 2024 17:59:24 +0100
Subject: [PATCH] gpio: regmap: Use generic request/free ops
Set the gpiochip request and free ops to the generic implementations.
This way a user can provide a gpio-ranges property defined for a pinmux,
allowing pins to automatically be muxed to their GPIO function when
requested.
Signed-off-by: Sander Vanheule <sander@svanheule.net>
---
drivers/gpio/gpio-regmap.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/gpio/gpio-regmap.c
+++ b/drivers/gpio/gpio-regmap.c
@@ -270,6 +270,8 @@ struct gpio_regmap *gpio_regmap_register
chip->label = config->label ?: dev_name(config->parent);
chip->can_sleep = regmap_might_sleep(config->regmap);
+ chip->request = gpiochip_generic_request;
+ chip->free = gpiochip_generic_free;
chip->get = gpio_regmap_get;
if (gpio->reg_set_base && gpio->reg_clr_base)
chip->set = gpio_regmap_set_with_clear;

View File

@ -0,0 +1,330 @@
From 4e3455e058d40eb2a7326016494e3c81dc506c33 Mon Sep 17 00:00:00 2001
From: Sander Vanheule <sander@svanheule.net>
Date: Mon, 10 May 2021 18:33:01 +0200
Subject: [PATCH] mfd: Add RTL8231 core device
The RTL8231 is implemented as an MDIO device, and provides a regmap
interface for register access by the core and child devices.
The chip can also be a device on an SMI bus, an I2C-like bus by Realtek.
Since kernel support for SMI is limited, and no real-world SMI
implementations have been encountered for this device, this is currently
unimplemented. The use of the regmap interface should make any future
support relatively straightforward.
After reset, all pins are muxed to GPIO inputs before the pin drivers
are enabled. This is done to prevent accidental system resets, when a
pin is connected to the parent SoC's reset line.
To provide different read and write semantics for the GPIO data
registers, a secondary virtual register range is used to enable separate
caching properties of pin input and output values.
Signed-off-by: Sander Vanheule <sander@svanheule.net>
---
drivers/mfd/Kconfig | 9 ++
drivers/mfd/Makefile | 1 +
drivers/mfd/rtl8231.c | 193 ++++++++++++++++++++++++++++++++++++
include/linux/mfd/rtl8231.h | 71 +++++++++++++
4 files changed, 274 insertions(+)
create mode 100644 drivers/mfd/rtl8231.c
create mode 100644 include/linux/mfd/rtl8231.h
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1171,6 +1171,15 @@ config MFD_RDC321X
southbridge which provides access to GPIOs and Watchdog using the
southbridge PCI device configuration space.
+config MFD_RTL8231
+ tristate "Realtek RTL8231 GPIO and LED expander"
+ select MFD_CORE
+ select REGMAP_MDIO
+ help
+ Support for the Realtek RTL8231 GPIO and LED expander.
+ Provides up to 37 GPIOs, 88 LEDs, and one PWM output.
+ When built as a module, this module will be named rtl8231.
+
config MFD_RT4831
tristate "Richtek RT4831 four channel WLED and Display Bias Voltage"
depends on I2C
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -240,6 +240,7 @@ obj-$(CONFIG_MFD_HI6421_PMIC) += hi6421-
obj-$(CONFIG_MFD_HI6421_SPMI) += hi6421-spmi-pmic.o
obj-$(CONFIG_MFD_HI655X_PMIC) += hi655x-pmic.o
obj-$(CONFIG_MFD_DLN2) += dln2.o
+obj-$(CONFIG_MFD_RTL8231) += rtl8231.o
obj-$(CONFIG_MFD_RT4831) += rt4831.o
obj-$(CONFIG_MFD_RT5033) += rt5033.o
obj-$(CONFIG_MFD_RT5120) += rt5120.o
--- /dev/null
+++ b/drivers/mfd/rtl8231.c
@@ -0,0 +1,193 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/bits.h>
+#include <linux/bitfield.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/mfd/core.h>
+#include <linux/mdio.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+
+#include <linux/mfd/rtl8231.h>
+
+static bool rtl8231_volatile_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ /*
+ * Registers with self-clearing bits, strapping pin values.
+ * Don't mark the data registers as volatile, since we need
+ * caching for the output values.
+ */
+ case RTL8231_REG_FUNC0:
+ case RTL8231_REG_FUNC1:
+ case RTL8231_REG_PIN_HI_CFG:
+ case RTL8231_REG_LED_END:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static const struct reg_field RTL8231_FIELD_LED_START = REG_FIELD(RTL8231_REG_FUNC0, 1, 1);
+
+static const struct mfd_cell rtl8231_cells[] = {
+ {
+ .name = "rtl8231-pinctrl",
+ },
+ {
+ .name = "rtl8231-leds",
+ .of_compatible = "realtek,rtl8231-leds",
+ },
+};
+
+static int rtl8231_soft_reset(struct regmap *map)
+{
+ const unsigned int all_pins_mask = GENMASK(RTL8231_BITS_VAL - 1, 0);
+ unsigned int val;
+ int err;
+
+ /* SOFT_RESET bit self-clears when done */
+ regmap_write_bits(map, RTL8231_REG_PIN_HI_CFG,
+ RTL8231_PIN_HI_CFG_SOFT_RESET, RTL8231_PIN_HI_CFG_SOFT_RESET);
+ err = regmap_read_poll_timeout(map, RTL8231_REG_PIN_HI_CFG, val,
+ !(val & RTL8231_PIN_HI_CFG_SOFT_RESET), 50, 1000);
+ if (err)
+ return err;
+
+ regcache_mark_dirty(map);
+
+ /*
+ * Chip reset results in a pin configuration that is a mix of LED and GPIO outputs.
+ * Select GPI functionality for all pins before enabling pin outputs.
+ */
+ regmap_write(map, RTL8231_REG_PIN_MODE0, all_pins_mask);
+ regmap_write(map, RTL8231_REG_GPIO_DIR0, all_pins_mask);
+ regmap_write(map, RTL8231_REG_PIN_MODE1, all_pins_mask);
+ regmap_write(map, RTL8231_REG_GPIO_DIR1, all_pins_mask);
+ regmap_write(map, RTL8231_REG_PIN_HI_CFG,
+ RTL8231_PIN_HI_CFG_MODE_MASK | RTL8231_PIN_HI_CFG_DIR_MASK);
+
+ return 0;
+}
+
+static int rtl8231_init(struct device *dev, struct regmap *map)
+{
+ struct regmap_field *led_start;
+ unsigned int started;
+ unsigned int val;
+ int err;
+
+ err = regmap_read(map, RTL8231_REG_FUNC1, &val);
+ if (err) {
+ dev_err(dev, "failed to read READY_CODE\n");
+ return err;
+ }
+
+ val = FIELD_GET(RTL8231_FUNC1_READY_CODE_MASK, val);
+ if (val != RTL8231_FUNC1_READY_CODE_VALUE) {
+ dev_err(dev, "RTL8231 not present or ready 0x%x != 0x%x\n",
+ val, RTL8231_FUNC1_READY_CODE_VALUE);
+ return -ENODEV;
+ }
+
+ led_start = dev_get_drvdata(dev);
+ err = regmap_field_read(led_start, &started);
+ if (err)
+ return err;
+
+ if (!started) {
+ err = rtl8231_soft_reset(map);
+ if (err)
+ return err;
+ /* LED_START enables power to output pins, and starts the LED engine */
+ err = regmap_field_force_write(led_start, 1);
+ }
+
+ return err;
+}
+
+static const struct regmap_config rtl8231_mdio_regmap_config = {
+ .val_bits = RTL8231_BITS_VAL,
+ .reg_bits = RTL8231_BITS_REG,
+ .volatile_reg = rtl8231_volatile_reg,
+ .max_register = RTL8231_REG_COUNT - 1,
+ .use_single_read = true,
+ .use_single_write = true,
+ .reg_format_endian = REGMAP_ENDIAN_BIG,
+ .val_format_endian = REGMAP_ENDIAN_BIG,
+ /* Cannot use REGCACHE_FLAT because it's not smart enough about cache invalidation */
+ .cache_type = REGCACHE_RBTREE,
+};
+
+static int rtl8231_mdio_probe(struct mdio_device *mdiodev)
+{
+ struct device *dev = &mdiodev->dev;
+ struct regmap_field *led_start;
+ struct regmap *map;
+ int err;
+
+ map = devm_regmap_init_mdio(mdiodev, &rtl8231_mdio_regmap_config);
+ if (IS_ERR(map)) {
+ dev_err(dev, "failed to init regmap\n");
+ return PTR_ERR(map);
+ }
+
+ led_start = devm_regmap_field_alloc(dev, map, RTL8231_FIELD_LED_START);
+ if (IS_ERR(led_start))
+ return PTR_ERR(led_start);
+
+ dev_set_drvdata(dev, led_start);
+
+ mdiodev->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
+ if (IS_ERR(mdiodev->reset_gpio))
+ return PTR_ERR(mdiodev->reset_gpio);
+
+ device_property_read_u32(dev, "reset-assert-delay", &mdiodev->reset_assert_delay);
+ device_property_read_u32(dev, "reset-deassert-delay", &mdiodev->reset_deassert_delay);
+
+ err = rtl8231_init(dev, map);
+ if (err)
+ return err;
+
+ return devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, rtl8231_cells,
+ ARRAY_SIZE(rtl8231_cells), NULL, 0, NULL);
+}
+
+__maybe_unused static int rtl8231_suspend(struct device *dev)
+{
+ struct regmap_field *led_start = dev_get_drvdata(dev);
+
+ return regmap_field_force_write(led_start, 0);
+}
+
+__maybe_unused static int rtl8231_resume(struct device *dev)
+{
+ struct regmap_field *led_start = dev_get_drvdata(dev);
+
+ return regmap_field_force_write(led_start, 1);
+}
+
+static SIMPLE_DEV_PM_OPS(rtl8231_pm_ops, rtl8231_suspend, rtl8231_resume);
+
+static const struct of_device_id rtl8231_of_match[] = {
+ { .compatible = "realtek,rtl8231" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, rtl8231_of_match);
+
+static struct mdio_driver rtl8231_mdio_driver = {
+ .mdiodrv.driver = {
+ .name = "rtl8231-expander",
+ .of_match_table = rtl8231_of_match,
+ .pm = pm_ptr(&rtl8231_pm_ops),
+ },
+ .probe = rtl8231_mdio_probe,
+};
+mdio_module_driver(rtl8231_mdio_driver);
+
+MODULE_AUTHOR("Sander Vanheule <sander@svanheule.net>");
+MODULE_DESCRIPTION("Realtek RTL8231 GPIO and LED expander");
+MODULE_LICENSE("GPL");
--- /dev/null
+++ b/include/linux/mfd/rtl8231.h
@@ -0,0 +1,71 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Register definitions the RTL8231 GPIO and LED expander chip
+ */
+
+#ifndef __LINUX_MFD_RTL8231_H
+#define __LINUX_MFD_RTL8231_H
+
+#include <linux/bits.h>
+
+/*
+ * Registers addresses are 5 bit, values are 16 bit
+ * Also define a duplicated range of virtual addresses, to enable
+ * different read/write behaviour on the GPIO data registers
+ */
+#define RTL8231_BITS_VAL 16
+#define RTL8231_BITS_REG 5
+
+/* Chip control */
+#define RTL8231_REG_FUNC0 0x00
+#define RTL8231_FUNC0_SCAN_MODE BIT(0)
+#define RTL8231_FUNC0_SCAN_SINGLE 0
+#define RTL8231_FUNC0_SCAN_BICOLOR BIT(0)
+
+#define RTL8231_REG_FUNC1 0x01
+#define RTL8231_FUNC1_READY_CODE_VALUE 0x37
+#define RTL8231_FUNC1_READY_CODE_MASK GENMASK(9, 4)
+#define RTL8231_FUNC1_DEBOUNCE_MASK GENMASK(15, 10)
+
+/* Pin control */
+#define RTL8231_REG_PIN_MODE0 0x02
+#define RTL8231_REG_PIN_MODE1 0x03
+
+#define RTL8231_PIN_MODE_LED 0
+#define RTL8231_PIN_MODE_GPIO 1
+
+/* Pin high config: pin and GPIO control for pins 32-26 */
+#define RTL8231_REG_PIN_HI_CFG 0x04
+#define RTL8231_PIN_HI_CFG_MODE_MASK GENMASK(4, 0)
+#define RTL8231_PIN_HI_CFG_DIR_MASK GENMASK(9, 5)
+#define RTL8231_PIN_HI_CFG_INV_MASK GENMASK(14, 10)
+#define RTL8231_PIN_HI_CFG_SOFT_RESET BIT(15)
+
+/* GPIO control registers */
+#define RTL8231_REG_GPIO_DIR0 0x05
+#define RTL8231_REG_GPIO_DIR1 0x06
+#define RTL8231_REG_GPIO_INVERT0 0x07
+#define RTL8231_REG_GPIO_INVERT1 0x08
+
+#define RTL8231_GPIO_DIR_IN 1
+#define RTL8231_GPIO_DIR_OUT 0
+
+/*
+ * GPIO data registers
+ * Only the output data can be written to these registers, and only the input
+ * data can be read.
+ */
+#define RTL8231_REG_GPIO_DATA0 0x1c
+#define RTL8231_REG_GPIO_DATA1 0x1d
+#define RTL8231_REG_GPIO_DATA2 0x1e
+#define RTL8231_PIN_HI_DATA_MASK GENMASK(4, 0)
+
+/* LED control base registers */
+#define RTL8231_REG_LED0_BASE 0x09
+#define RTL8231_REG_LED1_BASE 0x10
+#define RTL8231_REG_LED2_BASE 0x17
+#define RTL8231_REG_LED_END 0x1b
+
+#define RTL8231_REG_COUNT 0x1f
+
+#endif /* __LINUX_MFD_RTL8231_H */

View File

@ -0,0 +1,581 @@
From 098324288a63a6dcc44e96cc381aef3d5c48d89e Mon Sep 17 00:00:00 2001
From: Sander Vanheule <sander@svanheule.net>
Date: Mon, 10 May 2021 22:15:31 +0200
Subject: [PATCH] pinctrl: Add RTL8231 pin control and GPIO support
This driver implements the GPIO and pin muxing features provided by the
RTL8231. The device should be instantiated as an MFD child, where the
parent device has already configured the regmap used for register
access.
Debouncing is only available for the six highest GPIOs, and must be
emulated when other pins are used for (button) inputs. Although
described in the bindings, drive strength selection is currently not
implemented.
Signed-off-by: Sander Vanheule <sander@svanheule.net>
---
drivers/pinctrl/Kconfig | 11 +
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/pinctrl-rtl8231.c | 521 ++++++++++++++++++++++++++++++
3 files changed, 533 insertions(+)
create mode 100644 drivers/pinctrl/pinctrl-rtl8231.c
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -417,6 +417,17 @@ config PINCTRL_ROCKCHIP
help
This support pinctrl and GPIO driver for Rockchip SoCs.
+config PINCTRL_RTL8231
+ tristate "Realtek RTL8231 GPIO expander's pin controller"
+ depends on MFD_RTL8231
+ default MFD_RTL8231
+ select GPIO_REGMAP
+ select GENERIC_PINCONF
+ select GENERIC_PINMUX_FUNCTIONS
+ help
+ Support for RTL8231 expander's GPIOs and pin controller.
+ When built as a module, the module will be called pinctrl-rtl8231.
+
config PINCTRL_SINGLE
tristate "One-register-per-pin type device tree based pinctrl driver"
depends on OF
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_PINCTRL_PIC32) += pinctrl-p
obj-$(CONFIG_PINCTRL_PISTACHIO) += pinctrl-pistachio.o
obj-$(CONFIG_PINCTRL_RK805) += pinctrl-rk805.o
obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o
+obj-$(CONFIG_PINCTRL_RTL8231) += pinctrl-rtl8231.o
obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o
obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o
obj-$(CONFIG_PINCTRL_STMFX) += pinctrl-stmfx.o
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-rtl8231.c
@@ -0,0 +1,525 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/bitfield.h>
+#include <linux/gpio/driver.h>
+#include <linux/gpio/regmap.h>
+#include <linux/module.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "core.h"
+#include "pinmux.h"
+#include <linux/mfd/rtl8231.h>
+
+#define RTL8231_NUM_GPIOS 37
+#define RTL8231_DEBOUNCE_USEC 100000
+#define RTL8231_DEBOUNCE_MIN_OFFSET 31
+
+struct rtl8231_pin_ctrl {
+ struct pinctrl_desc pctl_desc;
+ struct regmap *map;
+};
+
+/*
+ * Pin controller functionality
+ */
+static const char * const rtl8231_pin_function_names[] = {
+ "gpio",
+ "led",
+ "pwm",
+};
+
+enum rtl8231_pin_function {
+ RTL8231_PIN_FUNCTION_GPIO = BIT(0),
+ RTL8231_PIN_FUNCTION_LED = BIT(1),
+ RTL8231_PIN_FUNCTION_PWM = BIT(2),
+};
+
+struct rtl8231_pin_desc {
+ const enum rtl8231_pin_function functions;
+ const u8 reg;
+ const u8 offset;
+ const u8 gpio_function_value;
+};
+
+#define RTL8231_PIN_DESC(_num, _func, _reg, _fld, _val) \
+ [_num] = { \
+ .functions = RTL8231_PIN_FUNCTION_GPIO | _func, \
+ .reg = _reg, \
+ .offset = _fld, \
+ .gpio_function_value = _val, \
+ }
+#define RTL8231_GPIO_PIN_DESC(_num, _reg, _fld) \
+ RTL8231_PIN_DESC(_num, 0, _reg, _fld, RTL8231_PIN_MODE_GPIO)
+#define RTL8231_LED_PIN_DESC(_num, _reg, _fld) \
+ RTL8231_PIN_DESC(_num, RTL8231_PIN_FUNCTION_LED, _reg, _fld, RTL8231_PIN_MODE_GPIO)
+#define RTL8231_PWM_PIN_DESC(_num, _reg, _fld) \
+ RTL8231_PIN_DESC(_num, RTL8231_PIN_FUNCTION_PWM, _reg, _fld, 0)
+
+/*
+ * All pins have a GPIO/LED mux bit, but the bits for pins 35/36 are read-only. Use this bit
+ * for the GPIO-only pin instead of a placeholder, so the rest of the logic can stay generic.
+ */
+static struct rtl8231_pin_desc rtl8231_pin_data[RTL8231_NUM_GPIOS] = {
+ RTL8231_LED_PIN_DESC(0, RTL8231_REG_PIN_MODE0, 0),
+ RTL8231_LED_PIN_DESC(1, RTL8231_REG_PIN_MODE0, 1),
+ RTL8231_LED_PIN_DESC(2, RTL8231_REG_PIN_MODE0, 2),
+ RTL8231_LED_PIN_DESC(3, RTL8231_REG_PIN_MODE0, 3),
+ RTL8231_LED_PIN_DESC(4, RTL8231_REG_PIN_MODE0, 4),
+ RTL8231_LED_PIN_DESC(5, RTL8231_REG_PIN_MODE0, 5),
+ RTL8231_LED_PIN_DESC(6, RTL8231_REG_PIN_MODE0, 6),
+ RTL8231_LED_PIN_DESC(7, RTL8231_REG_PIN_MODE0, 7),
+ RTL8231_LED_PIN_DESC(8, RTL8231_REG_PIN_MODE0, 8),
+ RTL8231_LED_PIN_DESC(9, RTL8231_REG_PIN_MODE0, 9),
+ RTL8231_LED_PIN_DESC(10, RTL8231_REG_PIN_MODE0, 10),
+ RTL8231_LED_PIN_DESC(11, RTL8231_REG_PIN_MODE0, 11),
+ RTL8231_LED_PIN_DESC(12, RTL8231_REG_PIN_MODE0, 12),
+ RTL8231_LED_PIN_DESC(13, RTL8231_REG_PIN_MODE0, 13),
+ RTL8231_LED_PIN_DESC(14, RTL8231_REG_PIN_MODE0, 14),
+ RTL8231_LED_PIN_DESC(15, RTL8231_REG_PIN_MODE0, 15),
+ RTL8231_LED_PIN_DESC(16, RTL8231_REG_PIN_MODE1, 0),
+ RTL8231_LED_PIN_DESC(17, RTL8231_REG_PIN_MODE1, 1),
+ RTL8231_LED_PIN_DESC(18, RTL8231_REG_PIN_MODE1, 2),
+ RTL8231_LED_PIN_DESC(19, RTL8231_REG_PIN_MODE1, 3),
+ RTL8231_LED_PIN_DESC(20, RTL8231_REG_PIN_MODE1, 4),
+ RTL8231_LED_PIN_DESC(21, RTL8231_REG_PIN_MODE1, 5),
+ RTL8231_LED_PIN_DESC(22, RTL8231_REG_PIN_MODE1, 6),
+ RTL8231_LED_PIN_DESC(23, RTL8231_REG_PIN_MODE1, 7),
+ RTL8231_LED_PIN_DESC(24, RTL8231_REG_PIN_MODE1, 8),
+ RTL8231_LED_PIN_DESC(25, RTL8231_REG_PIN_MODE1, 9),
+ RTL8231_LED_PIN_DESC(26, RTL8231_REG_PIN_MODE1, 10),
+ RTL8231_LED_PIN_DESC(27, RTL8231_REG_PIN_MODE1, 11),
+ RTL8231_LED_PIN_DESC(28, RTL8231_REG_PIN_MODE1, 12),
+ RTL8231_LED_PIN_DESC(29, RTL8231_REG_PIN_MODE1, 13),
+ RTL8231_LED_PIN_DESC(30, RTL8231_REG_PIN_MODE1, 14),
+ RTL8231_LED_PIN_DESC(31, RTL8231_REG_PIN_MODE1, 15),
+ RTL8231_LED_PIN_DESC(32, RTL8231_REG_PIN_HI_CFG, 0),
+ RTL8231_LED_PIN_DESC(33, RTL8231_REG_PIN_HI_CFG, 1),
+ RTL8231_LED_PIN_DESC(34, RTL8231_REG_PIN_HI_CFG, 2),
+ RTL8231_PWM_PIN_DESC(35, RTL8231_REG_FUNC1, 3),
+ RTL8231_GPIO_PIN_DESC(36, RTL8231_REG_PIN_HI_CFG, 4),
+};
+
+#define RTL8231_PIN(_num) \
+ { \
+ .number = _num, \
+ .name = "gpio" #_num, \
+ .drv_data = &rtl8231_pin_data[_num] \
+ }
+
+static const struct pinctrl_pin_desc rtl8231_pins[RTL8231_NUM_GPIOS] = {
+ RTL8231_PIN(0),
+ RTL8231_PIN(1),
+ RTL8231_PIN(2),
+ RTL8231_PIN(3),
+ RTL8231_PIN(4),
+ RTL8231_PIN(5),
+ RTL8231_PIN(6),
+ RTL8231_PIN(7),
+ RTL8231_PIN(8),
+ RTL8231_PIN(9),
+ RTL8231_PIN(10),
+ RTL8231_PIN(11),
+ RTL8231_PIN(12),
+ RTL8231_PIN(13),
+ RTL8231_PIN(14),
+ RTL8231_PIN(15),
+ RTL8231_PIN(16),
+ RTL8231_PIN(17),
+ RTL8231_PIN(18),
+ RTL8231_PIN(19),
+ RTL8231_PIN(20),
+ RTL8231_PIN(21),
+ RTL8231_PIN(22),
+ RTL8231_PIN(23),
+ RTL8231_PIN(24),
+ RTL8231_PIN(25),
+ RTL8231_PIN(26),
+ RTL8231_PIN(27),
+ RTL8231_PIN(28),
+ RTL8231_PIN(29),
+ RTL8231_PIN(30),
+ RTL8231_PIN(31),
+ RTL8231_PIN(32),
+ RTL8231_PIN(33),
+ RTL8231_PIN(34),
+ RTL8231_PIN(35),
+ RTL8231_PIN(36),
+};
+
+static int rtl8231_get_groups_count(struct pinctrl_dev *pctldev)
+{
+ return ARRAY_SIZE(rtl8231_pins);
+}
+
+static const char *rtl8231_get_group_name(struct pinctrl_dev *pctldev, unsigned int selector)
+{
+ return rtl8231_pins[selector].name;
+}
+
+static int rtl8231_get_group_pins(struct pinctrl_dev *pctldev, unsigned int selector,
+ const unsigned int **pins, unsigned int *num_pins)
+{
+ if (selector >= ARRAY_SIZE(rtl8231_pins))
+ return -EINVAL;
+
+ *pins = &rtl8231_pins[selector].number;
+ *num_pins = 1;
+
+ return 0;
+}
+
+static const struct pinctrl_ops rtl8231_pinctrl_ops = {
+ .get_groups_count = rtl8231_get_groups_count,
+ .get_group_name = rtl8231_get_group_name,
+ .get_group_pins = rtl8231_get_group_pins,
+ .dt_node_to_map = pinconf_generic_dt_node_to_map_all,
+ .dt_free_map = pinconf_generic_dt_free_map,
+};
+
+static int rtl8231_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector,
+ unsigned int group_selector)
+{
+ const struct function_desc *func = pinmux_generic_get_function(pctldev, func_selector);
+ const struct rtl8231_pin_desc *desc = rtl8231_pins[group_selector].drv_data;
+ const struct rtl8231_pin_ctrl *ctrl = pinctrl_dev_get_drvdata(pctldev);
+ unsigned int func_flag = (uintptr_t) func->data;
+ unsigned int function_mask;
+ unsigned int gpio_function;
+
+ if (!(desc->functions & func_flag))
+ return -EINVAL;
+
+ function_mask = BIT(desc->offset);
+ gpio_function = desc->gpio_function_value << desc->offset;
+
+ if (func_flag == RTL8231_PIN_FUNCTION_GPIO)
+ return regmap_update_bits(ctrl->map, desc->reg, function_mask, gpio_function);
+ else
+ return regmap_update_bits(ctrl->map, desc->reg, function_mask, ~gpio_function);
+}
+
+static int rtl8231_gpio_request_enable(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range, unsigned int offset)
+{
+ const struct rtl8231_pin_desc *desc = rtl8231_pins[offset].drv_data;
+ struct rtl8231_pin_ctrl *ctrl = pinctrl_dev_get_drvdata(pctldev);
+ unsigned int function_mask;
+ unsigned int gpio_function;
+
+ function_mask = BIT(desc->offset);
+ gpio_function = desc->gpio_function_value << desc->offset;
+
+ return regmap_update_bits(ctrl->map, desc->reg, function_mask, gpio_function);
+}
+
+static const struct pinmux_ops rtl8231_pinmux_ops = {
+ .get_functions_count = pinmux_generic_get_function_count,
+ .get_function_name = pinmux_generic_get_function_name,
+ .get_function_groups = pinmux_generic_get_function_groups,
+ .set_mux = rtl8231_set_mux,
+ .gpio_request_enable = rtl8231_gpio_request_enable,
+ .strict = true,
+};
+
+static int rtl8231_pin_config_get(struct pinctrl_dev *pctldev, unsigned int offset,
+ unsigned long *config)
+{
+ struct rtl8231_pin_ctrl *ctrl = pinctrl_dev_get_drvdata(pctldev);
+ unsigned int param = pinconf_to_config_param(*config);
+ unsigned int arg;
+ int err;
+ int v;
+
+ switch (param) {
+ case PIN_CONFIG_INPUT_DEBOUNCE:
+ if (offset < RTL8231_DEBOUNCE_MIN_OFFSET)
+ return -EINVAL;
+
+ err = regmap_read(ctrl->map, RTL8231_REG_FUNC1, &v);
+ if (err)
+ return err;
+
+ v = FIELD_GET(RTL8231_FUNC1_DEBOUNCE_MASK, v);
+ if (v & BIT(offset - RTL8231_DEBOUNCE_MIN_OFFSET))
+ arg = RTL8231_DEBOUNCE_USEC;
+ else
+ arg = 0;
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+
+ *config = pinconf_to_config_packed(param, arg);
+
+ return 0;
+}
+
+static int rtl8231_pin_config_set(struct pinctrl_dev *pctldev, unsigned int offset,
+ unsigned long *configs, unsigned int num_configs)
+{
+ struct rtl8231_pin_ctrl *ctrl = pinctrl_dev_get_drvdata(pctldev);
+ unsigned int param, arg;
+ unsigned int pin_mask;
+ int err;
+ int i;
+
+ for (i = 0; i < num_configs; i++) {
+ param = pinconf_to_config_param(configs[i]);
+ arg = pinconf_to_config_argument(configs[i]);
+
+ switch (param) {
+ case PIN_CONFIG_INPUT_DEBOUNCE:
+ if (offset < RTL8231_DEBOUNCE_MIN_OFFSET)
+ return -EINVAL;
+
+ pin_mask = FIELD_PREP(RTL8231_FUNC1_DEBOUNCE_MASK,
+ BIT(offset - RTL8231_DEBOUNCE_MIN_OFFSET));
+
+ switch (arg) {
+ case 0:
+ err = regmap_update_bits(ctrl->map, RTL8231_REG_FUNC1,
+ pin_mask, 0);
+ break;
+ case RTL8231_DEBOUNCE_USEC:
+ err = regmap_update_bits(ctrl->map, RTL8231_REG_FUNC1,
+ pin_mask, pin_mask);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+ }
+
+ return err;
+}
+
+static const struct pinconf_ops rtl8231_pinconf_ops = {
+ .is_generic = true,
+ .pin_config_get = rtl8231_pin_config_get,
+ .pin_config_set = rtl8231_pin_config_set,
+};
+
+static int rtl8231_pinctrl_init_functions(struct pinctrl_dev *pctl, struct rtl8231_pin_ctrl *ctrl)
+{
+ const char *function_name;
+ const char **groups;
+ unsigned int f_idx;
+ unsigned int pin;
+ int num_groups;
+ int err;
+
+ for (f_idx = 0; f_idx < ARRAY_SIZE(rtl8231_pin_function_names); f_idx++) {
+ function_name = rtl8231_pin_function_names[f_idx];
+
+ for (pin = 0, num_groups = 0; pin < ctrl->pctl_desc.npins; pin++)
+ if (rtl8231_pin_data[pin].functions & BIT(f_idx))
+ num_groups++;
+
+ groups = devm_kcalloc(pctl->dev, num_groups, sizeof(*groups), GFP_KERNEL);
+ if (!groups)
+ return -ENOMEM;
+
+ for (pin = 0, num_groups = 0; pin < ctrl->pctl_desc.npins; pin++)
+ if (rtl8231_pin_data[pin].functions & BIT(f_idx))
+ groups[num_groups++] = rtl8231_pins[pin].name;
+
+ err = pinmux_generic_add_function(pctl, function_name, groups, num_groups,
+ (void *) BIT(f_idx));
+ if (err < 0)
+ return err;
+ }
+
+ return 0;
+}
+
+struct pin_field_info {
+ const struct reg_field gpio_data;
+ const struct reg_field gpio_dir;
+ const struct reg_field mode;
+};
+
+static const struct pin_field_info pin_fields[] = {
+ {
+ .gpio_data = REG_FIELD(RTL8231_REG_GPIO_DATA0, 0, 15),
+ .gpio_dir = REG_FIELD(RTL8231_REG_GPIO_DIR0, 0, 15),
+ .mode = REG_FIELD(RTL8231_REG_PIN_MODE0, 0, 15),
+ },
+ {
+ .gpio_data = REG_FIELD(RTL8231_REG_GPIO_DATA1, 0, 15),
+ .gpio_dir = REG_FIELD(RTL8231_REG_GPIO_DIR1, 0, 15),
+ .mode = REG_FIELD(RTL8231_REG_PIN_MODE1, 0, 15),
+ },
+ {
+ .gpio_data = REG_FIELD(RTL8231_REG_GPIO_DATA2, 0, 4),
+ .gpio_dir = REG_FIELD(RTL8231_REG_PIN_HI_CFG, 5, 9),
+ .mode = REG_FIELD(RTL8231_REG_PIN_HI_CFG, 0, 4),
+ },
+};
+
+static int rtl8231_configure_safe(struct device *dev, struct regmap *map)
+{
+ struct regmap_field *field_data;
+ struct regmap_field *field_mode;
+ struct regmap_field *field_dir;
+ unsigned int is_output;
+ unsigned int is_gpio;
+ unsigned int data;
+ unsigned int mode;
+ unsigned int dir;
+ int err;
+
+ for (unsigned int i = 0; i < ARRAY_SIZE(pin_fields); i++) {
+ field_data = devm_regmap_field_alloc(dev, map, pin_fields[i].gpio_data);
+ if (IS_ERR(field_data))
+ return PTR_ERR(field_data);
+
+ field_dir = devm_regmap_field_alloc(dev, map, pin_fields[i].gpio_dir);
+ if (IS_ERR(field_dir))
+ return PTR_ERR(field_dir);
+
+ field_mode = devm_regmap_field_alloc(dev, map, pin_fields[i].mode);
+ if (IS_ERR(field_mode))
+ return PTR_ERR(field_mode);
+
+ /* The register cache is invalid at start-up, so this should read from HW */
+ err = regmap_field_read(field_data, &data);
+ if (err)
+ return err;
+
+ err = regmap_field_read(field_dir, &dir);
+ if (err)
+ return err;
+
+ err = regmap_field_read(field_mode, &mode);
+ if (err)
+ return err;
+
+ /* Write back only the GPIO-out values to fix the cache */
+ data &= ~dir;
+ regmap_field_write(field_data, data);
+
+ /*
+ * Set every pin that is configured as gpio-output but muxed for the alternative
+ * (LED) function to gpio-in. That way the pin will be high impedance when it is
+ * muxed to GPIO, preventing unwanted glitches.
+ * The pin muxes are left as-is, so there are no signal changes.
+ */
+ is_gpio = mode;
+ is_output = ~dir;
+ regmap_field_write(field_dir, dir | (~is_gpio & is_output));
+
+ devm_regmap_field_free(dev, field_data);
+ devm_regmap_field_free(dev, field_dir);
+ devm_regmap_field_free(dev, field_mode);
+ }
+
+ return 0;
+}
+
+static int rtl8231_pinctrl_init(struct device *dev, struct rtl8231_pin_ctrl *ctrl)
+{
+ struct pinctrl_dev *pctldev;
+ int err;
+
+ ctrl->pctl_desc.name = "rtl8231-pinctrl";
+ ctrl->pctl_desc.owner = THIS_MODULE;
+ ctrl->pctl_desc.confops = &rtl8231_pinconf_ops;
+ ctrl->pctl_desc.pctlops = &rtl8231_pinctrl_ops;
+ ctrl->pctl_desc.pmxops = &rtl8231_pinmux_ops;
+ ctrl->pctl_desc.npins = ARRAY_SIZE(rtl8231_pins);
+ ctrl->pctl_desc.pins = rtl8231_pins;
+
+ err = devm_pinctrl_register_and_init(dev->parent, &ctrl->pctl_desc, ctrl, &pctldev);
+ if (err) {
+ dev_err(dev, "failed to register pin controller\n");
+ return err;
+ }
+
+ err = rtl8231_pinctrl_init_functions(pctldev, ctrl);
+ if (err)
+ return err;
+
+ err = pinctrl_enable(pctldev);
+ if (err)
+ dev_err(dev, "failed to enable pin controller\n");
+
+ return err;
+}
+
+/*
+ * GPIO controller functionality
+ */
+static int rtl8231_gpio_reg_mask_xlate(struct gpio_regmap *gpio, unsigned int base,
+ unsigned int offset, unsigned int *reg, unsigned int *mask)
+{
+ unsigned int pin_mask = BIT(offset % RTL8231_BITS_VAL);
+
+ if (base == RTL8231_REG_GPIO_DATA0 || offset < 32) {
+ *reg = base + offset / RTL8231_BITS_VAL;
+ *mask = pin_mask;
+ } else if (base == RTL8231_REG_GPIO_DIR0) {
+ *reg = RTL8231_REG_PIN_HI_CFG;
+ *mask = FIELD_PREP(RTL8231_PIN_HI_CFG_DIR_MASK, pin_mask);
+ } else {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int rtl8231_pinctrl_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct rtl8231_pin_ctrl *ctrl;
+ struct gpio_regmap_config gpio_cfg = {};
+ int err;
+
+ ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
+ if (!ctrl)
+ return -ENOMEM;
+
+ ctrl->map = dev_get_regmap(dev->parent, NULL);
+ if (!ctrl->map)
+ return -ENODEV;
+
+ err = rtl8231_configure_safe(dev, ctrl->map);
+ if (err)
+ return err;
+
+ err = rtl8231_pinctrl_init(dev, ctrl);
+ if (err)
+ return err;
+
+ gpio_cfg.regmap = ctrl->map;
+ gpio_cfg.parent = dev->parent;
+ gpio_cfg.ngpio = RTL8231_NUM_GPIOS;
+ gpio_cfg.ngpio_per_reg = RTL8231_BITS_VAL;
+
+ gpio_cfg.reg_dat_base = GPIO_REGMAP_ADDR(RTL8231_REG_GPIO_DATA0);
+ gpio_cfg.reg_set_base = GPIO_REGMAP_ADDR(RTL8231_REG_GPIO_DATA0);
+ gpio_cfg.reg_dir_in_base = GPIO_REGMAP_ADDR(RTL8231_REG_GPIO_DIR0);
+
+ gpio_cfg.reg_mask_xlate = rtl8231_gpio_reg_mask_xlate;
+
+ return PTR_ERR_OR_ZERO(devm_gpio_regmap_register(dev, &gpio_cfg));
+}
+
+static struct platform_driver rtl8231_pinctrl_driver = {
+ .driver = {
+ .name = "rtl8231-pinctrl",
+ },
+ .probe = rtl8231_pinctrl_probe,
+};
+module_platform_driver(rtl8231_pinctrl_driver);
+
+MODULE_AUTHOR("Sander Vanheule <sander@svanheule.net>");
+MODULE_DESCRIPTION("Realtek RTL8231 pin control and GPIO support");
+MODULE_LICENSE("GPL");

View File

@ -0,0 +1,338 @@
From 6b797a97c007e46d6081fc6f4b41ce8407078605 Mon Sep 17 00:00:00 2001
From: Sander Vanheule <sander@svanheule.net>
Date: Mon, 10 May 2021 22:16:11 +0200
Subject: [PATCH] leds: Add support for RTL8231 LED scan matrix
Both single and bi-color scanning modes are supported. The driver will
verify that the addresses are valid for the current mode, before
registering the LEDs. LEDs can be turned on, off, or toggled at one of
six predefined rates from 40ms to 1280ms.
Implements a platform device for use as a child device with RTL8231 MFD,
and uses the parent regmap to access the required registers.
Signed-off-by: Sander Vanheule <sander@svanheule.net>
---
drivers/leds/Kconfig | 10 ++
drivers/leds/Makefile | 1 +
drivers/leds/leds-rtl8231.c | 291 ++++++++++++++++++++++++++++++++++++
3 files changed, 302 insertions(+)
create mode 100644 drivers/leds/leds-rtl8231.c
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -586,6 +586,16 @@ config LEDS_REGULATOR
help
This option enables support for regulator driven LEDs.
+config LEDS_RTL8231
+ tristate "RTL8231 LED matrix support"
+ depends on LEDS_CLASS
+ depends on MFD_RTL8231
+ default MFD_RTL8231
+ help
+ This option enables support for using the LED scanning matrix output
+ of the RTL8231 GPIO and LED expander chip.
+ When built as a module, this module will be named leds-rtl8231.
+
config LEDS_BD2606MVV
tristate "LED driver for BD2606MVV"
depends on LEDS_CLASS
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -77,6 +77,7 @@ obj-$(CONFIG_LEDS_PM8058) += leds-pm805
obj-$(CONFIG_LEDS_POWERNV) += leds-powernv.o
obj-$(CONFIG_LEDS_PWM) += leds-pwm.o
obj-$(CONFIG_LEDS_REGULATOR) += leds-regulator.o
+obj-$(CONFIG_LEDS_RTL8231) += leds-rtl8231.o
obj-$(CONFIG_LEDS_SC27XX_BLTC) += leds-sc27xx-bltc.o
obj-$(CONFIG_LEDS_ST1202) += leds-st1202.o
obj-$(CONFIG_LEDS_SUNFIRE) += leds-sunfire.o
--- /dev/null
+++ b/drivers/leds/leds-rtl8231.c
@@ -0,0 +1,285 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/device.h>
+#include <linux/leds.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+
+#include <linux/mfd/rtl8231.h>
+
+/**
+ * struct led_toggle_rate - description of an LED blinking mode
+ * @interval_ms: LED toggle rate in milliseconds
+ * @mode: Register field value used to activate this mode
+ *
+ * For LED hardware accelerated blinking, with equal on and off delay.
+ * Both delays are given by @interval, so the interval at which the LED blinks
+ * (i.e. turn on and off once) is double this value.
+ */
+struct led_toggle_rate {
+ u16 interval_ms;
+ u8 mode;
+};
+
+/**
+ * struct led_modes - description of all LED modes
+ * @toggle_rates: Array of led_toggle_rate values, sorted by ascending interval
+ * @num_toggle_rates: Number of elements in @led_toggle_rate
+ * @off: Register field value to turn LED off
+ * @on: Register field value to turn LED on
+ */
+struct led_modes {
+ const struct led_toggle_rate *toggle_rates;
+ unsigned int num_toggle_rates;
+ u8 off;
+ u8 on;
+};
+
+struct rtl8231_led {
+ struct led_classdev led;
+ const struct led_modes *modes;
+ struct regmap_field *reg_field;
+};
+#define to_rtl8231_led(_cdev) container_of(_cdev, struct rtl8231_led, led)
+
+#define RTL8231_NUM_LEDS 3
+#define RTL8231_LED_PER_REG 5
+#define RTL8231_BITS_PER_LED 3
+
+static const unsigned int rtl8231_led_port_counts_single[RTL8231_NUM_LEDS] = {32, 32, 24};
+static const unsigned int rtl8231_led_port_counts_bicolor[RTL8231_NUM_LEDS] = {24, 24, 24};
+
+static const unsigned int rtl8231_led_base[RTL8231_NUM_LEDS] = {
+ RTL8231_REG_LED0_BASE,
+ RTL8231_REG_LED1_BASE,
+ RTL8231_REG_LED2_BASE,
+};
+
+#define RTL8231_DEFAULT_TOGGLE_INTERVAL_MS 500
+
+static const struct led_toggle_rate rtl8231_toggle_rates[] = {
+ { 40, 1},
+ { 80, 2},
+ { 160, 3},
+ { 320, 4},
+ { 640, 5},
+ {1280, 6},
+};
+
+static const struct led_modes rtl8231_led_modes = {
+ .off = 0,
+ .on = 7,
+ .num_toggle_rates = ARRAY_SIZE(rtl8231_toggle_rates),
+ .toggle_rates = rtl8231_toggle_rates,
+};
+
+static void rtl8231_led_brightness_set(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+{
+ struct rtl8231_led *pled = to_rtl8231_led(led_cdev);
+
+ if (brightness)
+ regmap_field_write(pled->reg_field, pled->modes->on);
+ else
+ regmap_field_write(pled->reg_field, pled->modes->off);
+}
+
+static enum led_brightness rtl8231_led_brightness_get(struct led_classdev *led_cdev)
+{
+ struct rtl8231_led *pled = to_rtl8231_led(led_cdev);
+ u32 current_mode = pled->modes->off;
+
+ regmap_field_read(pled->reg_field, &current_mode);
+
+ if (current_mode == pled->modes->off)
+ return LED_OFF;
+ else
+ return LED_ON;
+}
+
+static unsigned int rtl8231_led_current_interval(struct rtl8231_led *pled)
+{
+ unsigned int mode;
+ unsigned int i;
+
+ if (regmap_field_read(pled->reg_field, &mode))
+ return 0;
+
+ for (i = 0; i < pled->modes->num_toggle_rates; i++)
+ if (mode == pled->modes->toggle_rates[i].mode)
+ return pled->modes->toggle_rates[i].interval_ms;
+
+ return 0;
+}
+
+static int rtl8231_led_blink_set(struct led_classdev *led_cdev, unsigned long *delay_on,
+ unsigned long *delay_off)
+{
+ struct rtl8231_led *pled = to_rtl8231_led(led_cdev);
+ const struct led_toggle_rate *rates = pled->modes->toggle_rates;
+ unsigned int num_rates = pled->modes->num_toggle_rates;
+ unsigned int interval_ms;
+ unsigned int i;
+ int err;
+
+ if (*delay_on == 0 && *delay_off == 0) {
+ interval_ms = RTL8231_DEFAULT_TOGGLE_INTERVAL_MS;
+ } else {
+ /*
+ * If the current mode is blinking, choose the delay that (likely) changed.
+ * Otherwise, choose the interval that would have the same total delay.
+ */
+ interval_ms = rtl8231_led_current_interval(pled);
+ if (interval_ms > 0 && interval_ms == *delay_off)
+ interval_ms = *delay_on;
+ else if (interval_ms > 0 && interval_ms == *delay_on)
+ interval_ms = *delay_off;
+ else
+ interval_ms = (*delay_on + *delay_off) / 2;
+ }
+
+ /* Find clamped toggle interval */
+ for (i = 0; i < (num_rates - 1); i++)
+ if (interval_ms > rates[i].interval_ms)
+ break;
+
+ interval_ms = rates[i].interval_ms;
+
+ err = regmap_field_write(pled->reg_field, rates[i].mode);
+ if (err)
+ return err;
+
+ *delay_on = interval_ms;
+ *delay_off = interval_ms;
+
+ return 0;
+}
+
+static int rtl8231_led_read_address(struct fwnode_handle *fwnode, unsigned int *addr_port,
+ unsigned int *addr_led)
+{
+ u32 addr[2];
+ int err;
+
+ err = fwnode_property_count_u32(fwnode, "reg");
+ if (err < 0)
+ return err;
+ if (err != ARRAY_SIZE(addr))
+ return -EINVAL;
+
+ err = fwnode_property_read_u32_array(fwnode, "reg", addr, ARRAY_SIZE(addr));
+ if (err)
+ return err;
+
+ *addr_port = addr[0];
+ *addr_led = addr[1];
+
+ return 0;
+}
+
+static const struct regmap_field *rtl8231_led_get_field(struct device *dev, struct regmap *map,
+ unsigned int port_index, unsigned int led_index)
+{
+ unsigned int offset = port_index / RTL8231_LED_PER_REG;
+ unsigned int shift = (port_index % RTL8231_LED_PER_REG) * RTL8231_BITS_PER_LED;
+ const struct reg_field field = REG_FIELD(rtl8231_led_base[led_index] + offset, shift,
+ shift + RTL8231_BITS_PER_LED - 1);
+
+ return devm_regmap_field_alloc(dev, map, field);
+}
+
+static int rtl8231_led_probe_single(struct device *dev, struct regmap *map,
+ const unsigned int *port_counts, struct fwnode_handle *fwnode)
+{
+ struct led_init_data init_data = {};
+ struct rtl8231_led *pled;
+ unsigned int port_index;
+ unsigned int led_index;
+ int err;
+
+ pled = devm_kzalloc(dev, sizeof(*pled), GFP_KERNEL);
+ if (!pled)
+ return -ENOMEM;
+
+ err = rtl8231_led_read_address(fwnode, &port_index, &led_index);
+ if (err) {
+ dev_err(dev, "LED address invalid");
+ return err;
+ }
+
+ if (led_index >= RTL8231_NUM_LEDS || port_index >= port_counts[led_index]) {
+ dev_err(dev, "LED address (%d.%d) invalid", port_index, led_index);
+ return -EINVAL;
+ }
+
+ pled->reg_field = rtl8231_led_get_field(dev, map, port_index, led_index);
+ if (IS_ERR(pled->reg_field))
+ return PTR_ERR(pled->reg_field);
+
+ pled->modes = &rtl8231_led_modes;
+
+ pled->led.max_brightness = 1;
+ pled->led.brightness_get = rtl8231_led_brightness_get;
+ pled->led.brightness_set = rtl8231_led_brightness_set;
+ pled->led.blink_set = rtl8231_led_blink_set;
+
+ init_data.fwnode = fwnode;
+
+ return devm_led_classdev_register_ext(dev, &pled->led, &init_data);
+}
+
+static int rtl8231_led_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ const unsigned int *port_counts;
+ struct fwnode_handle *child;
+ struct regmap *map;
+ int err;
+
+ map = dev_get_regmap(dev->parent, NULL);
+ if (!map)
+ return -ENODEV;
+
+ if (device_property_match_string(dev, "realtek,led-scan-mode", "single-color") >= 0) {
+ port_counts = rtl8231_led_port_counts_single;
+ regmap_update_bits(map, RTL8231_REG_FUNC0,
+ RTL8231_FUNC0_SCAN_MODE, RTL8231_FUNC0_SCAN_SINGLE);
+ } else if (device_property_match_string(dev, "realtek,led-scan-mode", "bi-color") >= 0) {
+ port_counts = rtl8231_led_port_counts_bicolor;
+ regmap_update_bits(map, RTL8231_REG_FUNC0,
+ RTL8231_FUNC0_SCAN_MODE, RTL8231_FUNC0_SCAN_BICOLOR);
+ } else {
+ dev_err(dev, "scan mode missing or invalid");
+ return -EINVAL;
+ }
+
+ fwnode_for_each_available_child_node(dev->fwnode, child) {
+ err = rtl8231_led_probe_single(dev, map, port_counts, child);
+ if (err)
+ dev_warn(dev, "failed to register LED %pfwP", child);
+ }
+
+ return 0;
+}
+
+static const struct of_device_id of_rtl8231_led_match[] = {
+ { .compatible = "realtek,rtl8231-leds" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, of_rtl8231_led_match);
+
+static struct platform_driver rtl8231_led_driver = {
+ .driver = {
+ .name = "rtl8231-leds",
+ .of_match_table = of_rtl8231_led_match,
+ },
+ .probe = rtl8231_led_probe,
+};
+module_platform_driver(rtl8231_led_driver);
+
+MODULE_AUTHOR("Sander Vanheule <sander@svanheule.net>");
+MODULE_DESCRIPTION("Realtek RTL8231 LED support");
+MODULE_LICENSE("GPL");

View File

@ -12,6 +12,7 @@ CONFIG_CLONE_BACKWARDS=y
CONFIG_COMMON_CLK=y
CONFIG_COMMON_CLK_REALTEK=y
CONFIG_COMMON_CLK_RTL83XX=y
CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
CONFIG_COMPAT_32BIT_TIME=y
CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15
CONFIG_CPUFREQ_DT=y
@ -37,6 +38,7 @@ CONFIG_CPU_MIPS32=y
# CONFIG_CPU_MIPS32_R1 is not set
CONFIG_CPU_MIPS32_R2=y
CONFIG_CPU_MIPSR2=y
CONFIG_CPU_MITIGATIONS=y
CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
CONFIG_CPU_R4K_CACHE_TLB=y
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
@ -44,29 +46,35 @@ CONFIG_CPU_SUPPORTS_CPUFREQ=y
CONFIG_CPU_SUPPORTS_HIGHMEM=y
CONFIG_CPU_SUPPORTS_MSA=y
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
CONFIG_CRYPTO_LIB_GF128MUL=y
CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_LIB_SHA1=y
CONFIG_CRYPTO_LIB_UTILS=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_SECTION_MISMATCH=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DTC=y
CONFIG_EARLY_PRINTK=y
CONFIG_EARLY_PRINTK_8250=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_EXTRA_FIRMWARE="rtl838x_phy/rtl838x_8214fc.fw rtl838x_phy/rtl838x_8218b.fw rtl838x_phy/rtl838x_8380.fw"
CONFIG_EXTRA_FIRMWARE_DIR="firmware"
CONFIG_FIXED_PHY=y
CONFIG_FORCE_MAX_ZONEORDER=13
CONFIG_FORCE_NR_CPUS=y
CONFIG_FS_IOMAP=y
CONFIG_FUNCTION_ALIGNMENT=0
CONFIG_FWNODE_MDIO=y
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_FW_LOADER_SYSFS=y
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_GENERIC_ATOMIC64=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_GENERIC_CPU_AUTOPROBE=y
CONFIG_GENERIC_FIND_FIRST_BIT=y
CONFIG_GENERIC_GETTIMEOFDAY=y
CONFIG_GENERIC_IDLE_POLL_SETUP=y
CONFIG_GENERIC_IOMAP=y
CONFIG_GENERIC_IRQ_CHIP=y
CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_LIB_ASHLDI3=y
CONFIG_GENERIC_LIB_ASHRDI3=y
@ -87,14 +95,15 @@ CONFIG_GPIO_GENERIC=y
CONFIG_GPIO_PCA953X=y
CONFIG_GPIO_PCA953X_IRQ=y
CONFIG_GPIO_REALTEK_OTTO=y
CONFIG_GPIO_REGMAP=y
CONFIG_GPIO_RTL8231=y
CONFIG_GPIO_WATCHDOG=y
# CONFIG_GPIO_WATCHDOG_ARCH_INITCALL is not set
CONFIG_GRO_CELLS=y
CONFIG_HANDLE_DOMAIN_IRQ=y
CONFIG_HARDWARE_WATCHPOINTS=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_IOPORT_MAP=y
CONFIG_HWMON=y
CONFIG_HZ_PERIODIC=y
@ -114,6 +123,7 @@ CONFIG_IRQ_MIPS_CPU=y
CONFIG_IRQ_WORK=y
CONFIG_JFFS2_ZLIB=y
CONFIG_LEDS_GPIO=y
# CONFIG_LEDS_RTL8231 is not set
CONFIG_LIBFDT=y
CONFIG_LOCK_DEBUGGING_SUPPORT=y
CONFIG_MACH_REALTEK_RTL=y
@ -122,8 +132,10 @@ CONFIG_MDIO_BUS=y
CONFIG_MDIO_DEVICE=y
CONFIG_MDIO_DEVRES=y
CONFIG_MDIO_I2C=y
CONFIG_MDIO_REALTEK_OTTO_AUX=y
CONFIG_MDIO_SMBUS=y
CONFIG_MEMFD_CREATE=y
CONFIG_MFD_CORE=y
CONFIG_MFD_RTL8231=y
CONFIG_MFD_SYSCON=y
CONFIG_MIGRATION=y
CONFIG_MIPS=y
@ -131,13 +143,12 @@ CONFIG_MIPS_ASID_BITS=8
CONFIG_MIPS_ASID_SHIFT=0
# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
CONFIG_MIPS_CMDLINE_FROM_DTB=y
CONFIG_MIPS_EBPF_JIT=y
CONFIG_MIPS_EXTERNAL_TIMER=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
CONFIG_MIPS_LD_CAN_LINK_VDSO=y
# CONFIG_MIPS_NO_APPENDED_DTB is not set
CONFIG_MIPS_RAW_APPENDED_DTB=y
CONFIG_MIPS_SPRAM=y
CONFIG_MMU_LAZY_TLB_REFCOUNT=y
CONFIG_MODULES_USE_ELF_REL=y
CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_CFI_GEOMETRY=y
@ -157,12 +168,16 @@ CONFIG_NET_DEVLINK=y
CONFIG_NET_DSA=y
CONFIG_NET_DSA_RTL83XX=y
CONFIG_NET_DSA_TAG_TRAILER=y
CONFIG_NET_EGRESS=y
CONFIG_NET_INGRESS=y
CONFIG_NET_RTL838X=y
CONFIG_NET_SELFTESTS=y
CONFIG_NET_SWITCHDEV=y
CONFIG_NET_XGRESS=y
CONFIG_NO_EXCEPT_FILL=y
CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
CONFIG_NVMEM=y
CONFIG_NVMEM_LAYOUTS=y
CONFIG_OF=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_EARLY_FLATTREE=y
@ -171,17 +186,24 @@ CONFIG_OF_GPIO=y
CONFIG_OF_IRQ=y
CONFIG_OF_KOBJ=y
CONFIG_OF_MDIO=y
CONFIG_PAGE_POOL=y
CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
CONFIG_PCI_DRIVERS_LEGACY=y
CONFIG_PERF_USE_VMALLOC=y
CONFIG_PGTABLE_LEVELS=2
CONFIG_PHYLIB=y
CONFIG_PHYLIB_LEDS=y
CONFIG_PHYLINK=y
CONFIG_PINCTRL=y
CONFIG_PINCTRL_RTL8231=y
CONFIG_PM_OPP=y
CONFIG_POWER_RESET=y
CONFIG_POWER_RESET_GPIO_RESTART=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_PREEMPT_NONE_BUILD=y
CONFIG_PTP_1588_CLOCK_OPTIONAL=y
CONFIG_RANDSTRUCT_NONE=y
CONFIG_RATIONAL=y
CONFIG_REALTEK_OTTO_TIMER=y
CONFIG_REALTEK_OTTO_WDT=y
@ -189,6 +211,7 @@ CONFIG_REALTEK_PHY=y
CONFIG_REALTEK_SOC_PHY=y
CONFIG_REGMAP=y
CONFIG_REGMAP_I2C=y
CONFIG_REGMAP_MDIO=y
CONFIG_REGMAP_MMIO=y
CONFIG_RESET_CONTROLLER=y
CONFIG_RTL838X=y
@ -200,8 +223,8 @@ CONFIG_SFP=y
CONFIG_SPI=y
CONFIG_SPI_MASTER=y
CONFIG_SPI_MEM=y
CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
CONFIG_SRAM=y
CONFIG_SRCU=y
CONFIG_SWPHY=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y
CONFIG_SYS_HAS_CPU_MIPS32_R1=y

View File

@ -6,13 +6,15 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BMIPS_CPUFREQ is not set
CONFIG_CLKDEV_LOOKUP=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_COMMON_CLK=y
CONFIG_COMMON_CLK_REALTEK=y
CONFIG_COMMON_CLK_RTL83XX=y
CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
CONFIG_COMPAT_32BIT_TIME=y
CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15
CONFIG_CONTEXT_TRACKING=y
CONFIG_CONTEXT_TRACKING_IDLE=y
CONFIG_CPUFREQ_DT=y
CONFIG_CPUFREQ_DT_PLATDEV=y
CONFIG_CPU_BIG_ENDIAN=y
@ -38,6 +40,7 @@ CONFIG_CPU_MIPS32_R2=y
CONFIG_CPU_MIPSR2=y
CONFIG_CPU_MIPSR2_IRQ_EI=y
CONFIG_CPU_MIPSR2_IRQ_VI=y
CONFIG_CPU_MITIGATIONS=y
CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
CONFIG_CPU_R4K_CACHE_TLB=y
CONFIG_CPU_RMAP=y
@ -46,24 +49,30 @@ CONFIG_CPU_SUPPORTS_CPUFREQ=y
CONFIG_CPU_SUPPORTS_HIGHMEM=y
CONFIG_CPU_SUPPORTS_MSA=y
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
CONFIG_CRYPTO_LIB_GF128MUL=y
CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_LIB_SHA1=y
CONFIG_CRYPTO_LIB_UTILS=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_SECTION_MISMATCH=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DTC=y
CONFIG_EARLY_PRINTK=y
CONFIG_EARLY_PRINTK_8250=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_FIXED_PHY=y
CONFIG_FORCE_MAX_ZONEORDER=13
CONFIG_FS_IOMAP=y
CONFIG_FUNCTION_ALIGNMENT=0
CONFIG_FWNODE_MDIO=y
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_FW_LOADER_SYSFS=y
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_GENERIC_ATOMIC64=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_GENERIC_CPU_AUTOPROBE=y
CONFIG_GENERIC_FIND_FIRST_BIT=y
CONFIG_GENERIC_GETTIMEOFDAY=y
CONFIG_GENERIC_IDLE_POLL_SETUP=y
CONFIG_GENERIC_IOMAP=y
CONFIG_GENERIC_IRQ_CHIP=y
CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
@ -91,10 +100,10 @@ CONFIG_GPIO_RTL8231=y
CONFIG_GPIO_WATCHDOG=y
# CONFIG_GPIO_WATCHDOG_ARCH_INITCALL is not set
CONFIG_GRO_CELLS=y
CONFIG_HANDLE_DOMAIN_IRQ=y
CONFIG_HARDWARE_WATCHPOINTS=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_IOPORT_MAP=y
CONFIG_HWMON=y
CONFIG_HZ_PERIODIC=y
@ -121,21 +130,18 @@ CONFIG_MDIO_BUS=y
CONFIG_MDIO_DEVICE=y
CONFIG_MDIO_DEVRES=y
CONFIG_MDIO_I2C=y
# CONFIG_MDIO_REALTEK_OTTO_AUX is not set
CONFIG_MDIO_SMBUS=y
CONFIG_MEMFD_CREATE=y
# CONFIG_MFD_RTL8231 is not set
CONFIG_MFD_SYSCON=y
CONFIG_MIGRATION=y
CONFIG_MIPS=y
CONFIG_MIPS_ASID_BITS=8
CONFIG_MIPS_ASID_SHIFT=0
CONFIG_MIPS_CLOCK_VSYSCALL=y
# CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set
# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
CONFIG_MIPS_CMDLINE_FROM_DTB=y
CONFIG_MIPS_EBPF_JIT=y
CONFIG_MIPS_EXTERNAL_TIMER=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
CONFIG_MIPS_LD_CAN_LINK_VDSO=y
CONFIG_MIPS_MT=y
# CONFIG_MIPS_MT_FPAFF is not set
CONFIG_MIPS_MT_SMP=y
@ -144,6 +150,7 @@ CONFIG_MIPS_NR_CPU_NR_MAP=2
CONFIG_MIPS_PERF_SHARED_TC_COUNTERS=y
CONFIG_MIPS_RAW_APPENDED_DTB=y
CONFIG_MIPS_SPRAM=y
CONFIG_MMU_LAZY_TLB_REFCOUNT=y
CONFIG_MODULES_USE_ELF_REL=y
CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_CFI_GEOMETRY=y
@ -158,18 +165,23 @@ CONFIG_MTD_SPLIT_TPLINK_FW=y
CONFIG_MTD_SPLIT_UIMAGE_FW=y
CONFIG_MTD_VIRT_CONCAT=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NEED_SRCU_NMI_SAFE=y
CONFIG_NET_DEVLINK=y
CONFIG_NET_DSA=y
CONFIG_NET_DSA_RTL83XX=y
CONFIG_NET_DSA_TAG_TRAILER=y
CONFIG_NET_EGRESS=y
CONFIG_NET_FLOW_LIMIT=y
CONFIG_NET_INGRESS=y
CONFIG_NET_RTL838X=y
CONFIG_NET_SELFTESTS=y
CONFIG_NET_SWITCHDEV=y
CONFIG_NET_XGRESS=y
CONFIG_NO_EXCEPT_FILL=y
CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
CONFIG_NR_CPUS=2
CONFIG_NVMEM=y
CONFIG_NVMEM_LAYOUTS=y
CONFIG_OF=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_EARLY_FLATTREE=y
@ -179,19 +191,25 @@ CONFIG_OF_IRQ=y
CONFIG_OF_KOBJ=y
CONFIG_OF_MDIO=y
CONFIG_PADATA=y
CONFIG_PAGE_POOL=y
CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
CONFIG_PCI_DRIVERS_LEGACY=y
CONFIG_PERF_USE_VMALLOC=y
CONFIG_PGTABLE_LEVELS=2
CONFIG_PHYLIB=y
CONFIG_PHYLIB_LEDS=y
CONFIG_PHYLINK=y
CONFIG_PINCTRL=y
CONFIG_PM_OPP=y
CONFIG_POWER_RESET=y
CONFIG_POWER_RESET_GPIO_RESTART=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_PREEMPT_NONE_BUILD=y
CONFIG_PTP_1588_CLOCK_OPTIONAL=y
CONFIG_QUEUED_RWLOCKS=y
CONFIG_QUEUED_SPINLOCKS=y
CONFIG_RANDSTRUCT_NONE=y
CONFIG_RATIONAL=y
CONFIG_REALTEK_OTTO_TIMER=y
CONFIG_REALTEK_OTTO_WDT=y
@ -215,8 +233,8 @@ CONFIG_SOCK_RX_QUEUE_MAPPING=y
CONFIG_SPI=y
CONFIG_SPI_MASTER=y
CONFIG_SPI_MEM=y
CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
CONFIG_SRAM=y
CONFIG_SRCU=y
CONFIG_SWPHY=y
CONFIG_SYNC_R4K=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y
@ -235,7 +253,8 @@ CONFIG_TARGET_ISA_REV=2
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
CONFIG_TINY_SRCU=y
CONFIG_TREE_RCU=y
CONFIG_TREE_SRCU=y
CONFIG_USE_GENERIC_EARLY_PRINTK_8250=y
CONFIG_USE_OF=y
CONFIG_WATCHDOG_CORE=y

View File

@ -12,6 +12,7 @@ CONFIG_BOARD_SCACHE=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_COMMON_CLK=y
# CONFIG_COMMON_CLK_REALTEK is not set
CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
CONFIG_COMPAT_32BIT_TIME=y
CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15
CONFIG_CPU_BIG_ENDIAN=y
@ -24,32 +25,40 @@ CONFIG_CPU_MIPS32=y
# CONFIG_CPU_MIPS32_R1 is not set
CONFIG_CPU_MIPS32_R2=y
CONFIG_CPU_MIPSR2=y
CONFIG_CPU_MITIGATIONS=y
CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
CONFIG_CPU_R4K_CACHE_TLB=y
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
CONFIG_CPU_SUPPORTS_HIGHMEM=y
CONFIG_CPU_SUPPORTS_MSA=y
CONFIG_CRC_CCITT=y
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
CONFIG_CRYPTO_LIB_GF128MUL=y
CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_LIB_SHA1=y
CONFIG_CRYPTO_LIB_UTILS=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_SECTION_MISMATCH=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DTC=y
CONFIG_EARLY_PRINTK=y
CONFIG_EARLY_PRINTK_8250=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_FIXED_PHY=y
CONFIG_FORCE_MAX_ZONEORDER=13
CONFIG_FORCE_NR_CPUS=y
CONFIG_FS_IOMAP=y
CONFIG_FUNCTION_ALIGNMENT=0
CONFIG_FWNODE_MDIO=y
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_FW_LOADER_SYSFS=y
CONFIG_GENERIC_ATOMIC64=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_GENERIC_CPU_AUTOPROBE=y
CONFIG_GENERIC_FIND_FIRST_BIT=y
CONFIG_GENERIC_GETTIMEOFDAY=y
CONFIG_GENERIC_IDLE_POLL_SETUP=y
CONFIG_GENERIC_IOMAP=y
CONFIG_GENERIC_IRQ_CHIP=y
CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_LIB_ASHLDI3=y
CONFIG_GENERIC_LIB_ASHRDI3=y
@ -71,10 +80,10 @@ CONFIG_GPIO_PCA953X=y
CONFIG_GPIO_REALTEK_OTTO=y
CONFIG_GPIO_RTL8231=y
CONFIG_GRO_CELLS=y
CONFIG_HANDLE_DOMAIN_IRQ=y
CONFIG_HARDWARE_WATCHPOINTS=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_IOPORT_MAP=y
CONFIG_HWMON=y
CONFIG_HZ_PERIODIC=y
@ -103,8 +112,9 @@ CONFIG_MDIO_BUS=y
CONFIG_MDIO_DEVICE=y
CONFIG_MDIO_DEVRES=y
CONFIG_MDIO_I2C=y
# CONFIG_MDIO_REALTEK_OTTO_AUX is not set
CONFIG_MDIO_SMBUS=y
CONFIG_MEMFD_CREATE=y
# CONFIG_MFD_RTL8231 is not set
CONFIG_MFD_SYSCON=y
CONFIG_MIGRATION=y
CONFIG_MIPS=y
@ -113,14 +123,13 @@ CONFIG_MIPS_ASID_SHIFT=0
# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
CONFIG_MIPS_CMDLINE_FROM_DTB=y
CONFIG_MIPS_CPU_SCACHE=y
CONFIG_MIPS_EBPF_JIT=y
CONFIG_MIPS_EXTERNAL_TIMER=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
CONFIG_MIPS_LD_CAN_LINK_VDSO=y
# CONFIG_MIPS_MT_SMP is not set
# CONFIG_MIPS_NO_APPENDED_DTB is not set
CONFIG_MIPS_RAW_APPENDED_DTB=y
CONFIG_MIPS_SPRAM=y
CONFIG_MMU_LAZY_TLB_REFCOUNT=y
CONFIG_MODULES_USE_ELF_REL=y
CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_CFI_GEOMETRY=y
@ -138,12 +147,16 @@ CONFIG_NET_DEVLINK=y
CONFIG_NET_DSA=y
CONFIG_NET_DSA_RTL83XX=y
CONFIG_NET_DSA_TAG_TRAILER=y
CONFIG_NET_EGRESS=y
CONFIG_NET_INGRESS=y
CONFIG_NET_RTL838X=y
CONFIG_NET_SELFTESTS=y
CONFIG_NET_SWITCHDEV=y
CONFIG_NET_XGRESS=y
CONFIG_NO_EXCEPT_FILL=y
CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
CONFIG_NVMEM=y
CONFIG_NVMEM_LAYOUTS=y
CONFIG_OF=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_EARLY_FLATTREE=y
@ -152,16 +165,22 @@ CONFIG_OF_GPIO=y
CONFIG_OF_IRQ=y
CONFIG_OF_KOBJ=y
CONFIG_OF_MDIO=y
CONFIG_PAGE_POOL=y
CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
CONFIG_PCI_DRIVERS_LEGACY=y
CONFIG_PERF_USE_VMALLOC=y
CONFIG_PGTABLE_LEVELS=2
CONFIG_PHYLIB=y
CONFIG_PHYLIB_LEDS=y
CONFIG_PHYLINK=y
CONFIG_PINCTRL=y
CONFIG_POWER_RESET=y
CONFIG_POWER_RESET_GPIO_RESTART=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_PREEMPT_NONE_BUILD=y
CONFIG_PTP_1588_CLOCK_OPTIONAL=y
CONFIG_RANDSTRUCT_NONE=y
CONFIG_RATIONAL=y
CONFIG_REALTEK_OTTO_TIMER=y
CONFIG_REALTEK_OTTO_WDT=y
@ -181,7 +200,7 @@ CONFIG_SFP=y
CONFIG_SPI=y
CONFIG_SPI_MASTER=y
CONFIG_SPI_MEM=y
CONFIG_SRCU=y
CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
CONFIG_SWPHY=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y
CONFIG_SYS_HAS_CPU_MIPS32_R1=y

View File

@ -8,15 +8,17 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BOARD_SCACHE=y
CONFIG_CEVT_RTL9300=y
CONFIG_CLKSRC_MIPS_GIC=y
CONFIG_CLOCKSOURCE_WATCHDOG=y
CONFIG_CLOCKSOURCE_WATCHDOG_MAX_SKEW_US=125
CONFIG_CLONE_BACKWARDS=y
CONFIG_COMMON_CLK=y
# CONFIG_COMMON_CLK_REALTEK is not set
CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
CONFIG_COMPAT_32BIT_TIME=y
CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15
CONFIG_CONTEXT_TRACKING=y
CONFIG_CONTEXT_TRACKING_IDLE=y
CONFIG_CPU_BIG_ENDIAN=y
CONFIG_CPU_GENERIC_DUMP_TLB=y
CONFIG_CPU_HAS_DIEI=y
@ -29,6 +31,7 @@ CONFIG_CPU_MIPS32_R2=y
CONFIG_CPU_MIPSR2=y
CONFIG_CPU_MIPSR2_IRQ_EI=y
CONFIG_CPU_MIPSR2_IRQ_VI=y
CONFIG_CPU_MITIGATIONS=y
CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
CONFIG_CPU_R4K_CACHE_TLB=y
CONFIG_CPU_RMAP=y
@ -36,24 +39,29 @@ CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
CONFIG_CPU_SUPPORTS_HIGHMEM=y
CONFIG_CPU_SUPPORTS_MSA=y
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
CONFIG_CRYPTO_LIB_GF128MUL=y
CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2
CONFIG_CRYPTO_RNG2=y
CONFIG_CSRC_R4K=y
CONFIG_CRYPTO_LIB_SHA1=y
CONFIG_CRYPTO_LIB_UTILS=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_SECTION_MISMATCH=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DTC=y
CONFIG_EARLY_PRINTK=y
CONFIG_EARLY_PRINTK_8250=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_FIXED_PHY=y
CONFIG_FORCE_MAX_ZONEORDER=13
CONFIG_FS_IOMAP=y
CONFIG_FUNCTION_ALIGNMENT=0
CONFIG_FWNODE_MDIO=y
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_FW_LOADER_SYSFS=y
CONFIG_GENERIC_ATOMIC64=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_GENERIC_CPU_AUTOPROBE=y
CONFIG_GENERIC_FIND_FIRST_BIT=y
CONFIG_GENERIC_GETTIMEOFDAY=y
CONFIG_GENERIC_IDLE_POLL_SETUP=y
CONFIG_GENERIC_IOMAP=y
CONFIG_GENERIC_IRQ_CHIP=y
CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
@ -77,10 +85,10 @@ CONFIG_GPIO_GENERIC=y
CONFIG_GPIO_REALTEK_OTTO=y
CONFIG_GPIO_RTL8231=y
CONFIG_GRO_CELLS=y
CONFIG_HANDLE_DOMAIN_IRQ=y
CONFIG_HARDWARE_WATCHPOINTS=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_IOPORT_MAP=y
CONFIG_HIGHMEM=y
CONFIG_HWMON=y
@ -112,8 +120,9 @@ CONFIG_MDIO_BUS=y
CONFIG_MDIO_DEVICE=y
CONFIG_MDIO_DEVRES=y
CONFIG_MDIO_I2C=y
# CONFIG_MDIO_REALTEK_OTTO_AUX is not set
CONFIG_MDIO_SMBUS=y
CONFIG_MEMFD_CREATE=y
# CONFIG_MFD_RTL8231 is not set
CONFIG_MFD_SYSCON=y
CONFIG_MIGRATION=y
CONFIG_MIPS=y
@ -127,10 +136,9 @@ CONFIG_MIPS_CPC=y
CONFIG_MIPS_CPS=y
# CONFIG_MIPS_CPS_NS16550_BOOL is not set
CONFIG_MIPS_CPU_SCACHE=y
CONFIG_MIPS_EBPF_JIT=y
CONFIG_MIPS_EXTERNAL_TIMER=y
CONFIG_MIPS_GIC=y
CONFIG_MIPS_L1_CACHE_SHIFT=5
CONFIG_MIPS_LD_CAN_LINK_VDSO=y
CONFIG_MIPS_MT=y
CONFIG_MIPS_MT_FPAFF=y
CONFIG_MIPS_MT_SMP=y
@ -139,6 +147,7 @@ CONFIG_MIPS_NR_CPU_NR_MAP=2
CONFIG_MIPS_PERF_SHARED_TC_COUNTERS=y
CONFIG_MIPS_RAW_APPENDED_DTB=y
CONFIG_MIPS_SPRAM=y
CONFIG_MMU_LAZY_TLB_REFCOUNT=y
CONFIG_MODULES_USE_ELF_REL=y
CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_CFI_GEOMETRY=y
@ -151,18 +160,23 @@ CONFIG_MTD_SPLIT_FIRMWARE=y
CONFIG_MTD_SPLIT_TPLINK_FW=y
CONFIG_MTD_SPLIT_UIMAGE_FW=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NEED_SRCU_NMI_SAFE=y
CONFIG_NET_DEVLINK=y
CONFIG_NET_DSA=y
CONFIG_NET_DSA_RTL83XX=y
CONFIG_NET_DSA_TAG_TRAILER=y
CONFIG_NET_EGRESS=y
CONFIG_NET_FLOW_LIMIT=y
CONFIG_NET_INGRESS=y
CONFIG_NET_RTL838X=y
CONFIG_NET_SELFTESTS=y
CONFIG_NET_SWITCHDEV=y
CONFIG_NET_XGRESS=y
CONFIG_NO_EXCEPT_FILL=y
CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
CONFIG_NR_CPUS=2
CONFIG_NVMEM=y
CONFIG_NVMEM_LAYOUTS=y
CONFIG_OF=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_EARLY_FLATTREE=y
@ -172,21 +186,26 @@ CONFIG_OF_IRQ=y
CONFIG_OF_KOBJ=y
CONFIG_OF_MDIO=y
CONFIG_PADATA=y
CONFIG_PAGE_POOL=y
CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
CONFIG_PCI_DRIVERS_LEGACY=y
CONFIG_PERF_USE_VMALLOC=y
CONFIG_PGTABLE_LEVELS=2
CONFIG_PHYLIB=y
CONFIG_PHYLIB_LEDS=y
CONFIG_PHYLINK=y
CONFIG_PINCTRL=y
CONFIG_POWER_RESET=y
CONFIG_POWER_RESET_SYSCON=y
CONFIG_PREEMPT_NONE_BUILD=y
CONFIG_PTP_1588_CLOCK_OPTIONAL=y
CONFIG_QUEUED_RWLOCKS=y
CONFIG_QUEUED_SPINLOCKS=y
CONFIG_RANDSTRUCT_NONE=y
CONFIG_RATIONAL=y
# CONFIG_REALTEK_OTTO_TIMER is not set
CONFIG_REALTEK_OTTO_WDT=y
# CONFIG_REALTEK_PHY is not set
CONFIG_REALTEK_SOC_PHY=y
CONFIG_REGMAP=y
CONFIG_REGMAP_I2C=y
@ -209,7 +228,7 @@ CONFIG_SOCK_RX_QUEUE_MAPPING=y
CONFIG_SPI=y
CONFIG_SPI_MASTER=y
CONFIG_SPI_MEM=y
CONFIG_SRCU=y
CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
CONFIG_SWPHY=y
CONFIG_SYNC_R4K=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y