bus: ti-sysc: Handle devices with no control registers
authorTony Lindgren <tony@atomide.com>
Wed, 1 May 2019 21:24:57 +0000 (14:24 -0700)
committerTony Lindgren <tony@atomide.com>
Thu, 2 May 2019 13:29:46 +0000 (06:29 -0700)
Some interconnect target modules have no module control registers at
all, such as d_can on am335x and am437x.

The d_can register offset at 0 is CTL register with 0x401 as the default
value. I guess I mistook the 0x401 value for a revision register as the
value happens to look similar to what the revision registers typically
have for other modules.

To handle modules with no control registers, we need to improve the
ti-sysc driver a bit to bail out with errors on no control registers,
and then we can remove the bogus revision registers for d_can.

Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Tested-by: Keerthy <j-keerthy@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
arch/arm/boot/dts/am33xx-l4.dtsi
arch/arm/boot/dts/am437x-l4.dtsi
drivers/bus/ti-sysc.c

index 203616fb85f374d8f20e1d1bf09dade6f5b45046..ced1a19d5f8982f11c12986dce5ea4d81decec3e 100644 (file)
                target-module@cc000 {                   /* 0x481cc000, ap 60 46.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
                        ti,hwmods = "d_can0";
-                       reg = <0xcc000 0x4>;
-                       reg-names = "rev";
                        /* Domains (P, C): per_pwrdm, l4ls_clkdm */
                        clocks = <&l4ls_clkctrl AM3_L4LS_D_CAN0_CLKCTRL 0>,
                                 <&dcan0_fck>;
                target-module@d0000 {                   /* 0x481d0000, ap 62 42.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
                        ti,hwmods = "d_can1";
-                       reg = <0xd0000 0x4>;
-                       reg-names = "rev";
                        /* Domains (P, C): per_pwrdm, l4ls_clkdm */
                        clocks = <&l4ls_clkctrl AM3_L4LS_D_CAN1_CLKCTRL 0>,
                                 <&dcan1_fck>;
index 85c6f4ff18242f7a26c669bd4036c7cf4cab8633..989cb60b90295868f1b983ff4129c867c33fce6b 100644 (file)
                target-module@cc000 {                   /* 0x481cc000, ap 50 46.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
                        ti,hwmods = "d_can0";
-                       reg = <0xcc000 0x4>;
-                       reg-names = "rev";
                        /* Domains (P, C): per_pwrdm, l4ls_clkdm */
                        clocks = <&l4ls_clkctrl AM4_L4LS_D_CAN0_CLKCTRL 0>;
                        clock-names = "fck";
                target-module@d0000 {                   /* 0x481d0000, ap 52 3a.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
                        ti,hwmods = "d_can1";
-                       reg = <0xd0000 0x4>;
-                       reg-names = "rev";
                        /* Domains (P, C): per_pwrdm, l4ls_clkdm */
                        clocks = <&l4ls_clkctrl AM4_L4LS_D_CAN1_CLKCTRL 0>;
                        clock-names = "fck";
index 308475ed4b32ad97033cb7e9df26817c2e3a3986..b72741668c927680493369ae2678f12805dca2d4 100644 (file)
@@ -660,12 +660,6 @@ static int sysc_check_registers(struct sysc *ddata)
                nr_regs++;
        }
 
-       if (nr_regs < 1) {
-               dev_err(ddata->dev, "missing registers\n");
-
-               return -EINVAL;
-       }
-
        if (nr_matches > nr_regs) {
                dev_err(ddata->dev, "overlapping registers: (%i/%i)",
                        nr_regs, nr_matches);
@@ -691,12 +685,18 @@ static int sysc_ioremap(struct sysc *ddata)
 {
        int size;
 
-       size = max3(ddata->offsets[SYSC_REVISION],
-                   ddata->offsets[SYSC_SYSCONFIG],
-                   ddata->offsets[SYSC_SYSSTATUS]);
+       if (ddata->offsets[SYSC_REVISION] < 0 &&
+           ddata->offsets[SYSC_SYSCONFIG] < 0 &&
+           ddata->offsets[SYSC_SYSSTATUS] < 0) {
+               size = ddata->module_size;
+       } else {
+               size = max3(ddata->offsets[SYSC_REVISION],
+                           ddata->offsets[SYSC_SYSCONFIG],
+                           ddata->offsets[SYSC_SYSSTATUS]);
 
-       if (size < 0 || (size + sizeof(u32)) > ddata->module_size)
-               return -EINVAL;
+               if ((size + sizeof(u32)) > ddata->module_size)
+                       return -EINVAL;
+       }
 
        ddata->module_va = devm_ioremap(ddata->dev,
                                        ddata->module_pa,
@@ -1128,7 +1128,6 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
        SYSC_QUIRK("cpgmac", 0, 0x1200, 0x1208, 0x1204, 0x4edb1902,
                   0xffff00f0, 0),
        SYSC_QUIRK("dcan", 0, 0, -1, -1, 0xffffffff, 0xffffffff, 0),
-       SYSC_QUIRK("dcan", 0, 0, -1, -1, 0x00001401, 0xffffffff, 0),
        SYSC_QUIRK("dmic", 0, 0, 0x10, -1, 0x50010000, 0xffffffff, 0),
        SYSC_QUIRK("dwc3", 0, 0, 0x10, -1, 0x500a0200, 0xffffffff, 0),
        SYSC_QUIRK("epwmss", 0, 0, 0x4, -1, 0x47400001, 0xffffffff, 0),