realtek: always require SMI bus ID for RTL8231
authorSander Vanheule <sander@svanheule.net>
Sat, 20 Nov 2021 19:11:33 +0000 (20:11 +0100)
committerStijn Tintel <stijn@linux-ipv6.be>
Thu, 17 Feb 2022 17:11:37 +0000 (19:11 +0200)
The SMI bus ID for RTL8231 currently defaults to 0, and can be
overridden from the devicetree. However, there is no value check on the
DT-provided value, aside from masking which would only cause value
wrap-around.

Change the driver to always require the "indirect-access-bus-id"
property, as there is no real reason to use 0 as default, and perform a
sanity check on the value when probing. This allows the other parts of
the driver to be simplified a bit.

Signed-off-by: Sander Vanheule <sander@svanheule.net>
Tested-by: Stijn Tintel <stijn@linux-ipv6.be>
target/linux/realtek/files-5.10/drivers/gpio/gpio-rtl8231.c

index 013dc238389ba878e4688cf67fc316cb57ed7f90..d7643083da466bc2ff67fad075e11667dc414e4d 100644 (file)
 
 #define USEC_TIMEOUT 5000
 
+#define RTL8231_SMI_BUS_ID_MAX                 0x1F
+
 struct rtl8231_gpios {
        struct gpio_chip gc;
        struct device *dev;
        u32 id;
-       int smi_bus_id;
+       u32 smi_bus_id;
        u16 reg_shadow[0x20];
        u32 reg_cached;
        int ext_gpio_indrt_access;
@@ -30,13 +32,11 @@ extern struct rtl83xx_soc_info soc_info;
 static u32 rtl8231_read(struct rtl8231_gpios *gpios, u32 reg)
 {
        u32 t = 0, n = 0;
-       u8 bus_id = gpios->smi_bus_id;
 
        reg &= 0x1f;
-       bus_id &= 0x1f;
 
        /* Calculate read register address */
-       t = (bus_id << 2) | (reg << 7);
+       t = (gpios->smi_bus_id << 2) | (reg << 7);
 
        /* Set execution bit: cleared when operation completed */
        t |= 1;
@@ -52,7 +52,8 @@ static u32 rtl8231_read(struct rtl8231_gpios *gpios, u32 reg)
        if (n >= USEC_TIMEOUT)
                return 0x80000000;
        
-       pr_debug("%s: %x, %x, %x\n", __func__, bus_id, reg, (t & 0xffff0000) >> 16);
+       pr_debug("%s: %x, %x, %x\n", __func__, gpios->smi_bus_id,
+               reg, (t & 0xffff0000) >> 16);
 
        return (t & 0xffff0000) >> 16;
 }
@@ -60,13 +61,11 @@ static u32 rtl8231_read(struct rtl8231_gpios *gpios, u32 reg)
 static int rtl8231_write(struct rtl8231_gpios *gpios, u32 reg, u32 data)
 {
        u32 t = 0, n = 0;
-       u8 bus_id = gpios->smi_bus_id;
 
-       pr_debug("%s: %x, %x, %x\n", __func__, bus_id, reg, data);
+       pr_debug("%s: %x, %x, %x\n", __func__, gpios->smi_bus_id, reg, data);
        reg &= 0x1f;
-       bus_id &= 0x1f;
 
-       t = (bus_id << 2) | (reg << 7) | (data << 16);
+       t = (gpios->smi_bus_id << 2) | (reg << 7) | (data << 16);
        /* Set write bit */
        t |= 2;
 
@@ -278,7 +277,6 @@ static int rtl8231_gpio_probe(struct platform_device *pdev)
        struct device_node *np = dev->of_node;
        struct rtl8231_gpios *gpios;
        int err;
-       u32 indirect_bus_id;
 
        pr_info("Probing RTL8231 GPIOs\n");
 
@@ -300,13 +298,14 @@ static int rtl8231_gpio_probe(struct platform_device *pdev)
                gpios->ext_gpio_indrt_access = RTL839X_EXT_GPIO_INDRT_ACCESS;
        }
 
-       /*
-        * We use a default MDIO bus ID for the 8231 of 0, which can be overriden
-        * by the indirect-access-bus-id property in the dts.
-        */
-       gpios->smi_bus_id = 0;
-       of_property_read_u32(np, "indirect-access-bus-id", &indirect_bus_id);
-       gpios->smi_bus_id = indirect_bus_id;
+       err = of_property_read_u32(np, "indirect-access-bus-id", &gpios->smi_bus_id);
+       if (!err && gpios->smi_bus_id > RTL8231_SMI_BUS_ID_MAX)
+               err = -EINVAL;
+
+       if (err) {
+               dev_err(dev, "invalid or missing indirect-access-bus-id\n");
+               return err;
+       }
 
        rtl8231_init(gpios);