Merge branch 'pwm-dmtimer-fixes' into omap-for-v5.0/fixes-v2
[sfrench/cifs-2.6.git] / drivers / bus / ti-sysc.c
index a3a2d39280d952e5c51d812a041f61916310c318..d299ec79e4c38bd4b5117b87bd75d639fe596ea1 100644 (file)
@@ -91,6 +91,9 @@ struct sysc {
        struct delayed_work idle_work;
 };
 
+static void sysc_parse_dts_quirks(struct sysc *ddata, struct device_node *np,
+                                 bool is_child);
+
 void sysc_write(struct sysc *ddata, int offset, u32 value)
 {
        writel_relaxed(value, ddata->module_va + offset);
@@ -214,8 +217,13 @@ static int sysc_get_clocks(struct sysc *ddata)
        if (!ddata->clocks)
                return -ENOMEM;
 
-       for (i = 0; i < ddata->nr_clocks; i++) {
-               error = sysc_get_one_clock(ddata, ddata->clock_roles[i]);
+       for (i = 0; i < SYSC_MAX_CLOCKS; i++) {
+               const char *name = ddata->clock_roles[i];
+
+               if (!name)
+                       continue;
+
+               error = sysc_get_one_clock(ddata, name);
                if (error && error != -ENOENT)
                        return error;
        }
@@ -374,6 +382,7 @@ static int sysc_check_one_child(struct sysc *ddata,
                dev_warn(ddata->dev, "really a child ti,hwmods property?");
 
        sysc_check_quirk_stdout(ddata, np);
+       sysc_parse_dts_quirks(ddata, np, true);
 
        return 0;
 }
@@ -772,12 +781,12 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
        SYSC_QUIRK("smartreflex", 0, -1, 0x38, -1, 0x00000000, 0xffffffff,
                   SYSC_QUIRK_LEGACY_IDLE),
        SYSC_QUIRK("timer", 0, 0, 0x10, 0x14, 0x00000015, 0xffffffff,
-                  SYSC_QUIRK_LEGACY_IDLE),
+                  0),
        /* Some timers on omap4 and later */
        SYSC_QUIRK("timer", 0, 0, 0x10, -1, 0x50002100, 0xffffffff,
-                  SYSC_QUIRK_LEGACY_IDLE),
+                  0),
        SYSC_QUIRK("timer", 0, 0, 0x10, -1, 0x4fff1301, 0xffff00ff,
-                  SYSC_QUIRK_LEGACY_IDLE),
+                  0),
        SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000052, 0xffffffff,
                   SYSC_QUIRK_LEGACY_IDLE),
        /* Uarts on omap4 and later */
@@ -815,6 +824,7 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
        SYSC_QUIRK("ocp2scp", 0, 0, 0x10, 0x14, 0x50060005, 0xfffffff0, 0),
        SYSC_QUIRK("ocp2scp", 0, 0, -1, -1, 0x50060007, 0xffffffff, 0),
        SYSC_QUIRK("padconf", 0, 0, 0x10, -1, 0x4fff0800, 0xffffffff, 0),
+       SYSC_QUIRK("padconf", 0, 0, -1, -1, 0x40001100, 0xffffffff, 0),
        SYSC_QUIRK("prcm", 0, 0, -1, -1, 0x40000100, 0xffffffff, 0),
        SYSC_QUIRK("prcm", 0, 0, -1, -1, 0x00004102, 0xffffffff, 0),
        SYSC_QUIRK("prcm", 0, 0, -1, -1, 0x40000400, 0xffffffff, 0),
@@ -833,7 +843,9 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
        SYSC_QUIRK("rtc", 0, 0x74, 0x78, -1, 0x4eb01908, 0xffff00f0, 0),
        SYSC_QUIRK("timer32k", 0, 0, 0x4, -1, 0x00000060, 0xffffffff, 0),
        SYSC_QUIRK("usbhstll", 0, 0, 0x10, 0x14, 0x00000004, 0xffffffff, 0),
+       SYSC_QUIRK("usbhstll", 0, 0, 0x10, 0x14, 0x00000008, 0xffffffff, 0),
        SYSC_QUIRK("usb_host_hs", 0, 0, 0x10, 0x14, 0x50700100, 0xffffffff, 0),
+       SYSC_QUIRK("usb_host_hs", 0, 0, 0x10, -1, 0x50700101, 0xffffffff, 0),
        SYSC_QUIRK("usb_otg_hs", 0, 0x400, 0x404, 0x408, 0x00000050,
                   0xffffffff, 0),
        SYSC_QUIRK("wdt", 0, 0, 0x10, 0x14, 0x502a0500, 0xfffff0f0, 0),
@@ -1271,23 +1283,37 @@ static const struct sysc_dts_quirk sysc_dts_quirks[] = {
          .mask = SYSC_QUIRK_NO_RESET_ON_INIT, },
 };
 
-static int sysc_init_dts_quirks(struct sysc *ddata)
+static void sysc_parse_dts_quirks(struct sysc *ddata, struct device_node *np,
+                                 bool is_child)
 {
-       struct device_node *np = ddata->dev->of_node;
        const struct property *prop;
-       int i, len, error;
-       u32 val;
-
-       ddata->legacy_mode = of_get_property(np, "ti,hwmods", NULL);
+       int i, len;
 
        for (i = 0; i < ARRAY_SIZE(sysc_dts_quirks); i++) {
-               prop = of_get_property(np, sysc_dts_quirks[i].name, &len);
+               const char *name = sysc_dts_quirks[i].name;
+
+               prop = of_get_property(np, name, &len);
                if (!prop)
                        continue;
 
                ddata->cfg.quirks |= sysc_dts_quirks[i].mask;
+               if (is_child) {
+                       dev_warn(ddata->dev,
+                                "dts flag should be at module level for %s\n",
+                                name);
+               }
        }
+}
+
+static int sysc_init_dts_quirks(struct sysc *ddata)
+{
+       struct device_node *np = ddata->dev->of_node;
+       int error;
+       u32 val;
 
+       ddata->legacy_mode = of_get_property(np, "ti,hwmods", NULL);
+
+       sysc_parse_dts_quirks(ddata, np, false);
        error = of_property_read_u32(np, "ti,sysc-delay-us", &val);
        if (!error) {
                if (val > 255) {
@@ -1498,6 +1524,16 @@ static const struct sysc_regbits sysc_regbits_omap4_mcasp = {
 static const struct sysc_capabilities sysc_omap4_mcasp = {
        .type = TI_SYSC_OMAP4_MCASP,
        .regbits = &sysc_regbits_omap4_mcasp,
+       .mod_quirks = SYSC_QUIRK_OPT_CLKS_NEEDED,
+};
+
+/*
+ * McASP found on dra7 and later
+ */
+static const struct sysc_capabilities sysc_dra7_mcasp = {
+       .type = TI_SYSC_OMAP4_SIMPLE,
+       .regbits = &sysc_regbits_omap4_simple,
+       .mod_quirks = SYSC_QUIRK_OPT_CLKS_NEEDED,
 };
 
 /*
@@ -1726,6 +1762,7 @@ static const struct of_device_id sysc_match[] = {
        { .compatible = "ti,sysc-omap3-sham", .data = &sysc_omap3_sham, },
        { .compatible = "ti,sysc-omap-aes", .data = &sysc_omap3_aes, },
        { .compatible = "ti,sysc-mcasp", .data = &sysc_omap4_mcasp, },
+       { .compatible = "ti,sysc-dra7-mcasp", .data = &sysc_dra7_mcasp, },
        { .compatible = "ti,sysc-usb-host-fs",
          .data = &sysc_omap4_usb_host_fs, },
        { .compatible = "ti,sysc-dra7-mcan", .data = &sysc_dra7_mcan, },