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 203616f..ced1a19 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 85c6f4f..989cb60 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 308475e..b727416 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),