1 // SPDX-License-Identifier: GPL-2.0-only
3 * ACPI Hardware Watchdog (WDAT) driver.
5 * Copyright (C) 2016, Intel Corporation
6 * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
9 #include <linux/acpi.h>
10 #include <linux/ioport.h>
11 #include <linux/module.h>
12 #include <linux/platform_device.h>
14 #include <linux/watchdog.h>
16 #define MAX_WDAT_ACTIONS ACPI_WDAT_ACTION_RESERVED
19 * struct wdat_instruction - Single ACPI WDAT instruction
20 * @entry: Copy of the ACPI table instruction
21 * @reg: Register the instruction is accessing
22 * @node: Next instruction in action sequence
24 struct wdat_instruction
{
25 struct acpi_wdat_entry entry
;
27 struct list_head node
;
31 * struct wdat_wdt - ACPI WDAT watchdog device
32 * @pdev: Parent platform device
33 * @wdd: Watchdog core device
34 * @period: How long is one watchdog period in ms
35 * @stopped_in_sleep: Is this watchdog stopped by the firmware in S1-S5
36 * @stopped: Was the watchdog stopped by the driver in suspend
37 * @actions: An array of instruction lists indexed by an action number from
38 * the WDAT table. There can be %NULL entries for not implemented
42 struct platform_device
*pdev
;
43 struct watchdog_device wdd
;
45 bool stopped_in_sleep
;
47 struct list_head
*instructions
[MAX_WDAT_ACTIONS
];
50 #define to_wdat_wdt(wdd) container_of(wdd, struct wdat_wdt, wdd)
52 static bool nowayout
= WATCHDOG_NOWAYOUT
;
53 module_param(nowayout
, bool, 0);
54 MODULE_PARM_DESC(nowayout
, "Watchdog cannot be stopped once started (default="
55 __MODULE_STRING(WATCHDOG_NOWAYOUT
) ")");
57 static int wdat_wdt_read(struct wdat_wdt
*wdat
,
58 const struct wdat_instruction
*instr
, u32
*value
)
60 const struct acpi_generic_address
*gas
= &instr
->entry
.register_region
;
62 switch (gas
->access_width
) {
64 *value
= ioread8(instr
->reg
);
67 *value
= ioread16(instr
->reg
);
70 *value
= ioread32(instr
->reg
);
76 dev_dbg(&wdat
->pdev
->dev
, "Read %#x from 0x%08llx\n", *value
,
82 static int wdat_wdt_write(struct wdat_wdt
*wdat
,
83 const struct wdat_instruction
*instr
, u32 value
)
85 const struct acpi_generic_address
*gas
= &instr
->entry
.register_region
;
87 switch (gas
->access_width
) {
89 iowrite8((u8
)value
, instr
->reg
);
92 iowrite16((u16
)value
, instr
->reg
);
95 iowrite32(value
, instr
->reg
);
101 dev_dbg(&wdat
->pdev
->dev
, "Wrote %#x to 0x%08llx\n", value
,
107 static int wdat_wdt_run_action(struct wdat_wdt
*wdat
, unsigned int action
,
108 u32 param
, u32
*retval
)
110 struct wdat_instruction
*instr
;
112 if (action
>= ARRAY_SIZE(wdat
->instructions
))
115 if (!wdat
->instructions
[action
])
118 dev_dbg(&wdat
->pdev
->dev
, "Running action %#x\n", action
);
120 /* Run each instruction sequentially */
121 list_for_each_entry(instr
, wdat
->instructions
[action
], node
) {
122 const struct acpi_wdat_entry
*entry
= &instr
->entry
;
123 const struct acpi_generic_address
*gas
;
124 u32 flags
, value
, mask
, x
, y
;
128 gas
= &entry
->register_region
;
130 preserve
= entry
->instruction
& ACPI_WDAT_PRESERVE_REGISTER
;
131 flags
= entry
->instruction
& ~ACPI_WDAT_PRESERVE_REGISTER
;
132 value
= entry
->value
;
136 case ACPI_WDAT_READ_VALUE
:
137 ret
= wdat_wdt_read(wdat
, instr
, &x
);
140 x
>>= gas
->bit_offset
;
143 *retval
= x
== value
;
146 case ACPI_WDAT_READ_COUNTDOWN
:
147 ret
= wdat_wdt_read(wdat
, instr
, &x
);
150 x
>>= gas
->bit_offset
;
156 case ACPI_WDAT_WRITE_VALUE
:
158 x
<<= gas
->bit_offset
;
160 ret
= wdat_wdt_read(wdat
, instr
, &y
);
163 y
= y
& ~(mask
<< gas
->bit_offset
);
166 ret
= wdat_wdt_write(wdat
, instr
, x
);
171 case ACPI_WDAT_WRITE_COUNTDOWN
:
174 x
<<= gas
->bit_offset
;
176 ret
= wdat_wdt_read(wdat
, instr
, &y
);
179 y
= y
& ~(mask
<< gas
->bit_offset
);
182 ret
= wdat_wdt_write(wdat
, instr
, x
);
188 dev_err(&wdat
->pdev
->dev
, "Unknown instruction: %u\n",
197 static int wdat_wdt_enable_reboot(struct wdat_wdt
*wdat
)
202 * WDAT specification says that the watchdog is required to reboot
203 * the system when it fires. However, it also states that it is
204 * recommeded to make it configurable through hardware register. We
205 * enable reboot now if it is configurable, just in case.
207 ret
= wdat_wdt_run_action(wdat
, ACPI_WDAT_SET_REBOOT
, 0, NULL
);
208 if (ret
&& ret
!= -EOPNOTSUPP
) {
209 dev_err(&wdat
->pdev
->dev
,
210 "Failed to enable reboot when watchdog triggers\n");
217 static void wdat_wdt_boot_status(struct wdat_wdt
*wdat
)
222 ret
= wdat_wdt_run_action(wdat
, ACPI_WDAT_GET_STATUS
, 0, &boot_status
);
223 if (ret
&& ret
!= -EOPNOTSUPP
) {
224 dev_err(&wdat
->pdev
->dev
, "Failed to read boot status\n");
229 wdat
->wdd
.bootstatus
= WDIOF_CARDRESET
;
231 /* Clear the boot status in case BIOS did not do it */
232 ret
= wdat_wdt_run_action(wdat
, ACPI_WDAT_SET_STATUS
, 0, NULL
);
233 if (ret
&& ret
!= -EOPNOTSUPP
)
234 dev_err(&wdat
->pdev
->dev
, "Failed to clear boot status\n");
237 static void wdat_wdt_set_running(struct wdat_wdt
*wdat
)
242 ret
= wdat_wdt_run_action(wdat
, ACPI_WDAT_GET_RUNNING_STATE
, 0,
244 if (ret
&& ret
!= -EOPNOTSUPP
)
245 dev_err(&wdat
->pdev
->dev
, "Failed to read running state\n");
248 set_bit(WDOG_HW_RUNNING
, &wdat
->wdd
.status
);
251 static int wdat_wdt_start(struct watchdog_device
*wdd
)
253 return wdat_wdt_run_action(to_wdat_wdt(wdd
),
254 ACPI_WDAT_SET_RUNNING_STATE
, 0, NULL
);
257 static int wdat_wdt_stop(struct watchdog_device
*wdd
)
259 return wdat_wdt_run_action(to_wdat_wdt(wdd
),
260 ACPI_WDAT_SET_STOPPED_STATE
, 0, NULL
);
263 static int wdat_wdt_ping(struct watchdog_device
*wdd
)
265 return wdat_wdt_run_action(to_wdat_wdt(wdd
), ACPI_WDAT_RESET
, 0, NULL
);
268 static int wdat_wdt_set_timeout(struct watchdog_device
*wdd
,
269 unsigned int timeout
)
271 struct wdat_wdt
*wdat
= to_wdat_wdt(wdd
);
272 unsigned int periods
;
275 periods
= timeout
* 1000 / wdat
->period
;
276 ret
= wdat_wdt_run_action(wdat
, ACPI_WDAT_SET_COUNTDOWN
, periods
, NULL
);
278 wdd
->timeout
= timeout
;
282 static unsigned int wdat_wdt_get_timeleft(struct watchdog_device
*wdd
)
284 struct wdat_wdt
*wdat
= to_wdat_wdt(wdd
);
287 wdat_wdt_run_action(wdat
, ACPI_WDAT_GET_CURRENT_COUNTDOWN
, 0, &periods
);
288 return periods
* wdat
->period
/ 1000;
291 static const struct watchdog_info wdat_wdt_info
= {
292 .options
= WDIOF_SETTIMEOUT
| WDIOF_KEEPALIVEPING
| WDIOF_MAGICCLOSE
,
293 .firmware_version
= 0,
294 .identity
= "wdat_wdt",
297 static const struct watchdog_ops wdat_wdt_ops
= {
298 .owner
= THIS_MODULE
,
299 .start
= wdat_wdt_start
,
300 .stop
= wdat_wdt_stop
,
301 .ping
= wdat_wdt_ping
,
302 .set_timeout
= wdat_wdt_set_timeout
,
303 .get_timeleft
= wdat_wdt_get_timeleft
,
306 static int wdat_wdt_probe(struct platform_device
*pdev
)
308 struct device
*dev
= &pdev
->dev
;
309 const struct acpi_wdat_entry
*entries
;
310 const struct acpi_table_wdat
*tbl
;
311 struct wdat_wdt
*wdat
;
312 struct resource
*res
;
317 status
= acpi_get_table(ACPI_SIG_WDAT
, 0,
318 (struct acpi_table_header
**)&tbl
);
319 if (ACPI_FAILURE(status
))
322 wdat
= devm_kzalloc(dev
, sizeof(*wdat
), GFP_KERNEL
);
326 regs
= devm_kcalloc(dev
, pdev
->num_resources
, sizeof(*regs
),
331 /* WDAT specification wants to have >= 1ms period */
332 if (tbl
->timer_period
< 1)
334 if (tbl
->min_count
> tbl
->max_count
)
337 wdat
->period
= tbl
->timer_period
;
338 wdat
->wdd
.min_hw_heartbeat_ms
= wdat
->period
* tbl
->min_count
;
339 wdat
->wdd
.max_hw_heartbeat_ms
= wdat
->period
* tbl
->max_count
;
340 wdat
->stopped_in_sleep
= tbl
->flags
& ACPI_WDAT_STOPPED
;
341 wdat
->wdd
.info
= &wdat_wdt_info
;
342 wdat
->wdd
.ops
= &wdat_wdt_ops
;
345 /* Request and map all resources */
346 for (i
= 0; i
< pdev
->num_resources
; i
++) {
349 res
= &pdev
->resource
[i
];
350 if (resource_type(res
) == IORESOURCE_MEM
) {
351 reg
= devm_ioremap_resource(dev
, res
);
354 } else if (resource_type(res
) == IORESOURCE_IO
) {
355 reg
= devm_ioport_map(dev
, res
->start
, 1);
359 dev_err(dev
, "Unsupported resource\n");
366 entries
= (struct acpi_wdat_entry
*)(tbl
+ 1);
367 for (i
= 0; i
< tbl
->entries
; i
++) {
368 const struct acpi_generic_address
*gas
;
369 struct wdat_instruction
*instr
;
370 struct list_head
*instructions
;
375 action
= entries
[i
].action
;
376 if (action
>= MAX_WDAT_ACTIONS
) {
377 dev_dbg(dev
, "Skipping unknown action: %u\n", action
);
381 instr
= devm_kzalloc(dev
, sizeof(*instr
), GFP_KERNEL
);
385 INIT_LIST_HEAD(&instr
->node
);
386 instr
->entry
= entries
[i
];
388 gas
= &entries
[i
].register_region
;
390 memset(&r
, 0, sizeof(r
));
391 r
.start
= gas
->address
;
392 r
.end
= r
.start
+ gas
->access_width
- 1;
393 if (gas
->space_id
== ACPI_ADR_SPACE_SYSTEM_MEMORY
) {
394 r
.flags
= IORESOURCE_MEM
;
395 } else if (gas
->space_id
== ACPI_ADR_SPACE_SYSTEM_IO
) {
396 r
.flags
= IORESOURCE_IO
;
398 dev_dbg(dev
, "Unsupported address space: %d\n",
403 /* Find the matching resource */
404 for (j
= 0; j
< pdev
->num_resources
; j
++) {
405 res
= &pdev
->resource
[j
];
406 if (resource_contains(res
, &r
)) {
407 instr
->reg
= regs
[j
] + r
.start
- res
->start
;
413 dev_err(dev
, "I/O resource not found\n");
417 instructions
= wdat
->instructions
[action
];
419 instructions
= devm_kzalloc(dev
,
420 sizeof(*instructions
),
425 INIT_LIST_HEAD(instructions
);
426 wdat
->instructions
[action
] = instructions
;
429 list_add_tail(&instr
->node
, instructions
);
432 wdat_wdt_boot_status(wdat
);
433 wdat_wdt_set_running(wdat
);
435 ret
= wdat_wdt_enable_reboot(wdat
);
439 platform_set_drvdata(pdev
, wdat
);
441 watchdog_set_nowayout(&wdat
->wdd
, nowayout
);
442 return devm_watchdog_register_device(dev
, &wdat
->wdd
);
445 #ifdef CONFIG_PM_SLEEP
446 static int wdat_wdt_suspend_noirq(struct device
*dev
)
448 struct wdat_wdt
*wdat
= dev_get_drvdata(dev
);
451 if (!watchdog_active(&wdat
->wdd
))
455 * We need to stop the watchdog if firmare is not doing it or if we
456 * are going suspend to idle (where firmware is not involved). If
457 * firmware is stopping the watchdog we kick it here one more time
458 * to give it some time.
460 wdat
->stopped
= false;
461 if (acpi_target_system_state() == ACPI_STATE_S0
||
462 !wdat
->stopped_in_sleep
) {
463 ret
= wdat_wdt_stop(&wdat
->wdd
);
465 wdat
->stopped
= true;
467 ret
= wdat_wdt_ping(&wdat
->wdd
);
473 static int wdat_wdt_resume_noirq(struct device
*dev
)
475 struct wdat_wdt
*wdat
= dev_get_drvdata(dev
);
478 if (!watchdog_active(&wdat
->wdd
))
481 if (!wdat
->stopped
) {
483 * Looks like the boot firmware reinitializes the watchdog
484 * before it hands off to the OS on resume from sleep so we
485 * stop and reprogram the watchdog here.
487 ret
= wdat_wdt_stop(&wdat
->wdd
);
491 ret
= wdat_wdt_set_timeout(&wdat
->wdd
, wdat
->wdd
.timeout
);
495 ret
= wdat_wdt_enable_reboot(wdat
);
499 ret
= wdat_wdt_ping(&wdat
->wdd
);
504 return wdat_wdt_start(&wdat
->wdd
);
508 static const struct dev_pm_ops wdat_wdt_pm_ops
= {
509 SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(wdat_wdt_suspend_noirq
,
510 wdat_wdt_resume_noirq
)
513 static struct platform_driver wdat_wdt_driver
= {
514 .probe
= wdat_wdt_probe
,
517 .pm
= &wdat_wdt_pm_ops
,
521 module_platform_driver(wdat_wdt_driver
);
523 MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
524 MODULE_DESCRIPTION("ACPI Hardware Watchdog (WDAT) driver");
525 MODULE_LICENSE("GPL v2");
526 MODULE_ALIAS("platform:wdat_wdt");