Commit c7d8669f46ba97f6a8e14d6e9b8d6c39e2c07727

Authored by Tony Lindgren
1 parent 54ecb8f702

bus: ti-sysc: Fix watchdog quirk handling

I noticed that when probed with ti-sysc, watchdog can trigger on am3, am4
and dra7 causing a device reset.

Turns out I made several mistakes implementing the watchdog quirk handling:

1. We must do both writes to spr register

2. We must also call the reset quirk on disable

3. On am3 and am4 we need to also set swsup quirk flag

I probably only tested this earlier with watchdog service running when the
watchdog never gets disabled.

Fixes: 4e23be473e30 ("bus: ti-sysc: Add support for module specific reset quirks")
Signed-off-by: Tony Lindgren <tony@atomide.com>

Showing 1 changed file with 14 additions and 4 deletions Side-by-side Diff

drivers/bus/ti-sysc.c
... ... @@ -74,6 +74,7 @@
74 74 * @clk_disable_quirk: module specific clock disable quirk
75 75 * @reset_done_quirk: module specific reset done quirk
76 76 * @module_enable_quirk: module specific enable quirk
  77 + * @module_disable_quirk: module specific disable quirk
77 78 */
78 79 struct sysc {
79 80 struct device *dev;
... ... @@ -100,6 +101,7 @@
100 101 void (*clk_disable_quirk)(struct sysc *sysc);
101 102 void (*reset_done_quirk)(struct sysc *sysc);
102 103 void (*module_enable_quirk)(struct sysc *sysc);
  104 + void (*module_disable_quirk)(struct sysc *sysc);
103 105 };
104 106  
105 107 static void sysc_parse_dts_quirks(struct sysc *ddata, struct device_node *np,
... ... @@ -959,6 +961,9 @@
959 961 if (ddata->offsets[SYSC_SYSCONFIG] == -ENODEV)
960 962 return 0;
961 963  
  964 + if (ddata->module_disable_quirk)
  965 + ddata->module_disable_quirk(ddata);
  966 +
962 967 regbits = ddata->cap->regbits;
963 968 reg = sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]);
964 969  
... ... @@ -1248,6 +1253,9 @@
1248 1253 SYSC_MODULE_QUIRK_SGX),
1249 1254 SYSC_QUIRK("wdt", 0, 0, 0x10, 0x14, 0x502a0500, 0xfffff0f0,
1250 1255 SYSC_MODULE_QUIRK_WDT),
  1256 + /* Watchdog on am3 and am4 */
  1257 + SYSC_QUIRK("wdt", 0x44e35000, 0, 0x10, 0x14, 0x502a0500, 0xfffff0f0,
  1258 + SYSC_MODULE_QUIRK_WDT | SYSC_QUIRK_SWSUP_SIDLE),
1251 1259  
1252 1260 #ifdef DEBUG
1253 1261 SYSC_QUIRK("adc", 0, 0, 0x10, -1, 0x47300001, 0xffffffff, 0),
1254 1262  
1255 1263  
... ... @@ -1440,14 +1448,14 @@
1440 1448 !(val & 0x10), 100,
1441 1449 MAX_MODULE_SOFTRESET_WAIT);
1442 1450 if (error)
1443   - dev_warn(ddata->dev, "wdt disable spr failed\n");
  1451 + dev_warn(ddata->dev, "wdt disable step1 failed\n");
1444 1452  
1445   - sysc_write(ddata, wps, 0x5555);
  1453 + sysc_write(ddata, spr, 0x5555);
1446 1454 error = readl_poll_timeout(ddata->module_va + wps, val,
1447 1455 !(val & 0x10), 100,
1448 1456 MAX_MODULE_SOFTRESET_WAIT);
1449 1457 if (error)
1450   - dev_warn(ddata->dev, "wdt disable wps failed\n");
  1458 + dev_warn(ddata->dev, "wdt disable step2 failed\n");
1451 1459 }
1452 1460  
1453 1461 static void sysc_init_module_quirks(struct sysc *ddata)
1454 1462  
... ... @@ -1471,8 +1479,10 @@
1471 1479 if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_SGX)
1472 1480 ddata->module_enable_quirk = sysc_module_enable_quirk_sgx;
1473 1481  
1474   - if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_WDT)
  1482 + if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_WDT) {
1475 1483 ddata->reset_done_quirk = sysc_reset_done_quirk_wdt;
  1484 + ddata->module_disable_quirk = sysc_reset_done_quirk_wdt;
  1485 + }
1476 1486 }
1477 1487  
1478 1488 static int sysc_clockdomain_init(struct sysc *ddata)