2 * ACPI Hardware Watchdog (WDAT) driver.
4 * Copyright (C) 2016, Intel Corporation
5 * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
12 #include <linux/acpi.h>
13 #include <linux/ioport.h>
14 #include <linux/module.h>
15 #include <linux/platform_device.h>
17 #include <linux/watchdog.h>
19 #define MAX_WDAT_ACTIONS ACPI_WDAT_ACTION_RESERVED
22 * struct wdat_instruction - Single ACPI WDAT instruction
23 * @entry: Copy of the ACPI table instruction
24 * @reg: Register the instruction is accessing
25 * @node: Next instruction in action sequence
27 struct wdat_instruction
{
28 struct acpi_wdat_entry entry
;
30 struct list_head node
;
34 * struct wdat_wdt - ACPI WDAT watchdog device
35 * @pdev: Parent platform device
36 * @wdd: Watchdog core device
37 * @period: How long is one watchdog period in ms
38 * @stopped_in_sleep: Is this watchdog stopped by the firmware in S1-S5
39 * @stopped: Was the watchdog stopped by the driver in suspend
40 * @actions: An array of instruction lists indexed by an action number from
41 * the WDAT table. There can be %NULL entries for not implemented
45 struct platform_device
*pdev
;
46 struct watchdog_device wdd
;
48 bool stopped_in_sleep
;
50 struct list_head
*instructions
[MAX_WDAT_ACTIONS
];
53 #define to_wdat_wdt(wdd) container_of(wdd, struct wdat_wdt, wdd)
55 static bool nowayout
= WATCHDOG_NOWAYOUT
;
56 module_param(nowayout
, bool, 0);
57 MODULE_PARM_DESC(nowayout
, "Watchdog cannot be stopped once started (default="
58 __MODULE_STRING(WATCHDOG_NOWAYOUT
) ")");
60 static int wdat_wdt_read(struct wdat_wdt
*wdat
,
61 const struct wdat_instruction
*instr
, u32
*value
)
63 const struct acpi_generic_address
*gas
= &instr
->entry
.register_region
;
65 switch (gas
->access_width
) {
67 *value
= ioread8(instr
->reg
);
70 *value
= ioread16(instr
->reg
);
73 *value
= ioread32(instr
->reg
);
79 dev_dbg(&wdat
->pdev
->dev
, "Read %#x from 0x%08llx\n", *value
,
85 static int wdat_wdt_write(struct wdat_wdt
*wdat
,
86 const struct wdat_instruction
*instr
, u32 value
)
88 const struct acpi_generic_address
*gas
= &instr
->entry
.register_region
;
90 switch (gas
->access_width
) {
92 iowrite8((u8
)value
, instr
->reg
);
95 iowrite16((u16
)value
, instr
->reg
);
98 iowrite32(value
, instr
->reg
);
104 dev_dbg(&wdat
->pdev
->dev
, "Wrote %#x to 0x%08llx\n", value
,
110 static int wdat_wdt_run_action(struct wdat_wdt
*wdat
, unsigned int action
,
111 u32 param
, u32
*retval
)
113 struct wdat_instruction
*instr
;
115 if (action
>= ARRAY_SIZE(wdat
->instructions
))
118 if (!wdat
->instructions
[action
])
121 dev_dbg(&wdat
->pdev
->dev
, "Running action %#x\n", action
);
123 /* Run each instruction sequentially */
124 list_for_each_entry(instr
, wdat
->instructions
[action
], node
) {
125 const struct acpi_wdat_entry
*entry
= &instr
->entry
;
126 const struct acpi_generic_address
*gas
;
127 u32 flags
, value
, mask
, x
, y
;
131 gas
= &entry
->register_region
;
133 preserve
= entry
->instruction
& ACPI_WDAT_PRESERVE_REGISTER
;
134 flags
= entry
->instruction
& ~ACPI_WDAT_PRESERVE_REGISTER
;
135 value
= entry
->value
;
139 case ACPI_WDAT_READ_VALUE
:
140 ret
= wdat_wdt_read(wdat
, instr
, &x
);
143 x
>>= gas
->bit_offset
;
146 *retval
= x
== value
;
149 case ACPI_WDAT_READ_COUNTDOWN
:
150 ret
= wdat_wdt_read(wdat
, instr
, &x
);
153 x
>>= gas
->bit_offset
;
159 case ACPI_WDAT_WRITE_VALUE
:
161 x
<<= gas
->bit_offset
;
163 ret
= wdat_wdt_read(wdat
, instr
, &y
);
166 y
= y
& ~(mask
<< gas
->bit_offset
);
169 ret
= wdat_wdt_write(wdat
, instr
, x
);
174 case ACPI_WDAT_WRITE_COUNTDOWN
:
177 x
<<= gas
->bit_offset
;
179 ret
= wdat_wdt_read(wdat
, instr
, &y
);
182 y
= y
& ~(mask
<< gas
->bit_offset
);
185 ret
= wdat_wdt_write(wdat
, instr
, x
);
191 dev_err(&wdat
->pdev
->dev
, "Unknown instruction: %u\n",
200 static int wdat_wdt_enable_reboot(struct wdat_wdt
*wdat
)
205 * WDAT specification says that the watchdog is required to reboot
206 * the system when it fires. However, it also states that it is
207 * recommeded to make it configurable through hardware register. We
208 * enable reboot now if it is configrable, just in case.
210 ret
= wdat_wdt_run_action(wdat
, ACPI_WDAT_SET_REBOOT
, 0, NULL
);
211 if (ret
&& ret
!= -EOPNOTSUPP
) {
212 dev_err(&wdat
->pdev
->dev
,
213 "Failed to enable reboot when watchdog triggers\n");
220 static void wdat_wdt_boot_status(struct wdat_wdt
*wdat
)
225 ret
= wdat_wdt_run_action(wdat
, ACPI_WDAT_GET_STATUS
, 0, &boot_status
);
226 if (ret
&& ret
!= -EOPNOTSUPP
) {
227 dev_err(&wdat
->pdev
->dev
, "Failed to read boot status\n");
232 wdat
->wdd
.bootstatus
= WDIOF_CARDRESET
;
234 /* Clear the boot status in case BIOS did not do it */
235 ret
= wdat_wdt_run_action(wdat
, ACPI_WDAT_SET_STATUS
, 0, NULL
);
236 if (ret
&& ret
!= -EOPNOTSUPP
)
237 dev_err(&wdat
->pdev
->dev
, "Failed to clear boot status\n");
240 static void wdat_wdt_set_running(struct wdat_wdt
*wdat
)
245 ret
= wdat_wdt_run_action(wdat
, ACPI_WDAT_GET_RUNNING_STATE
, 0,
247 if (ret
&& ret
!= -EOPNOTSUPP
)
248 dev_err(&wdat
->pdev
->dev
, "Failed to read running state\n");
251 set_bit(WDOG_HW_RUNNING
, &wdat
->wdd
.status
);
254 static int wdat_wdt_start(struct watchdog_device
*wdd
)
256 return wdat_wdt_run_action(to_wdat_wdt(wdd
),
257 ACPI_WDAT_SET_RUNNING_STATE
, 0, NULL
);
260 static int wdat_wdt_stop(struct watchdog_device
*wdd
)
262 return wdat_wdt_run_action(to_wdat_wdt(wdd
),
263 ACPI_WDAT_SET_STOPPED_STATE
, 0, NULL
);
266 static int wdat_wdt_ping(struct watchdog_device
*wdd
)
268 return wdat_wdt_run_action(to_wdat_wdt(wdd
), ACPI_WDAT_RESET
, 0, NULL
);
271 static int wdat_wdt_set_timeout(struct watchdog_device
*wdd
,
272 unsigned int timeout
)
274 struct wdat_wdt
*wdat
= to_wdat_wdt(wdd
);
275 unsigned int periods
;
278 periods
= timeout
* 1000 / wdat
->period
;
279 ret
= wdat_wdt_run_action(wdat
, ACPI_WDAT_SET_COUNTDOWN
, periods
, NULL
);
281 wdd
->timeout
= timeout
;
285 static unsigned int wdat_wdt_get_timeleft(struct watchdog_device
*wdd
)
287 struct wdat_wdt
*wdat
= to_wdat_wdt(wdd
);
290 wdat_wdt_run_action(wdat
, ACPI_WDAT_GET_COUNTDOWN
, 0, &periods
);
291 return periods
* wdat
->period
/ 1000;
294 static const struct watchdog_info wdat_wdt_info
= {
295 .options
= WDIOF_SETTIMEOUT
| WDIOF_KEEPALIVEPING
| WDIOF_MAGICCLOSE
,
296 .firmware_version
= 0,
297 .identity
= "wdat_wdt",
300 static const struct watchdog_ops wdat_wdt_ops
= {
301 .owner
= THIS_MODULE
,
302 .start
= wdat_wdt_start
,
303 .stop
= wdat_wdt_stop
,
304 .ping
= wdat_wdt_ping
,
305 .set_timeout
= wdat_wdt_set_timeout
,
306 .get_timeleft
= wdat_wdt_get_timeleft
,
309 static int wdat_wdt_probe(struct platform_device
*pdev
)
311 const struct acpi_wdat_entry
*entries
;
312 const struct acpi_table_wdat
*tbl
;
313 struct wdat_wdt
*wdat
;
314 struct resource
*res
;
319 status
= acpi_get_table(ACPI_SIG_WDAT
, 0,
320 (struct acpi_table_header
**)&tbl
);
321 if (ACPI_FAILURE(status
))
324 wdat
= devm_kzalloc(&pdev
->dev
, sizeof(*wdat
), GFP_KERNEL
);
328 regs
= devm_kcalloc(&pdev
->dev
, pdev
->num_resources
, sizeof(*regs
),
333 /* WDAT specification wants to have >= 1ms period */
334 if (tbl
->timer_period
< 1)
336 if (tbl
->min_count
> tbl
->max_count
)
339 wdat
->period
= tbl
->timer_period
;
340 wdat
->wdd
.min_hw_heartbeat_ms
= wdat
->period
* tbl
->min_count
;
341 wdat
->wdd
.max_hw_heartbeat_ms
= wdat
->period
* tbl
->max_count
;
342 wdat
->stopped_in_sleep
= tbl
->flags
& ACPI_WDAT_STOPPED
;
343 wdat
->wdd
.info
= &wdat_wdt_info
;
344 wdat
->wdd
.ops
= &wdat_wdt_ops
;
347 /* Request and map all resources */
348 for (i
= 0; i
< pdev
->num_resources
; i
++) {
351 res
= &pdev
->resource
[i
];
352 if (resource_type(res
) == IORESOURCE_MEM
) {
353 reg
= devm_ioremap_resource(&pdev
->dev
, res
);
356 } else if (resource_type(res
) == IORESOURCE_IO
) {
357 reg
= devm_ioport_map(&pdev
->dev
, res
->start
, 1);
361 dev_err(&pdev
->dev
, "Unsupported resource\n");
368 entries
= (struct acpi_wdat_entry
*)(tbl
+ 1);
369 for (i
= 0; i
< tbl
->entries
; i
++) {
370 const struct acpi_generic_address
*gas
;
371 struct wdat_instruction
*instr
;
372 struct list_head
*instructions
;
377 action
= entries
[i
].action
;
378 if (action
>= MAX_WDAT_ACTIONS
) {
379 dev_dbg(&pdev
->dev
, "Skipping unknown action: %u\n",
384 instr
= devm_kzalloc(&pdev
->dev
, sizeof(*instr
), GFP_KERNEL
);
388 INIT_LIST_HEAD(&instr
->node
);
389 instr
->entry
= entries
[i
];
391 gas
= &entries
[i
].register_region
;
393 memset(&r
, 0, sizeof(r
));
394 r
.start
= gas
->address
;
395 r
.end
= r
.start
+ gas
->access_width
;
396 if (gas
->space_id
== ACPI_ADR_SPACE_SYSTEM_MEMORY
) {
397 r
.flags
= IORESOURCE_MEM
;
398 } else if (gas
->space_id
== ACPI_ADR_SPACE_SYSTEM_IO
) {
399 r
.flags
= IORESOURCE_IO
;
401 dev_dbg(&pdev
->dev
, "Unsupported address space: %d\n",
406 /* Find the matching resource */
407 for (j
= 0; j
< pdev
->num_resources
; j
++) {
408 res
= &pdev
->resource
[j
];
409 if (resource_contains(res
, &r
)) {
410 instr
->reg
= regs
[j
] + r
.start
- res
->start
;
416 dev_err(&pdev
->dev
, "I/O resource not found\n");
420 instructions
= wdat
->instructions
[action
];
422 instructions
= devm_kzalloc(&pdev
->dev
,
423 sizeof(*instructions
), GFP_KERNEL
);
427 INIT_LIST_HEAD(instructions
);
428 wdat
->instructions
[action
] = instructions
;
431 list_add_tail(&instr
->node
, instructions
);
434 wdat_wdt_boot_status(wdat
);
435 wdat_wdt_set_running(wdat
);
437 ret
= wdat_wdt_enable_reboot(wdat
);
441 platform_set_drvdata(pdev
, wdat
);
443 watchdog_set_nowayout(&wdat
->wdd
, nowayout
);
444 return devm_watchdog_register_device(&pdev
->dev
, &wdat
->wdd
);
447 #ifdef CONFIG_PM_SLEEP
448 static int wdat_wdt_suspend_noirq(struct device
*dev
)
450 struct platform_device
*pdev
= to_platform_device(dev
);
451 struct wdat_wdt
*wdat
= platform_get_drvdata(pdev
);
454 if (!watchdog_active(&wdat
->wdd
))
458 * We need to stop the watchdog if firmare is not doing it or if we
459 * are going suspend to idle (where firmware is not involved). If
460 * firmware is stopping the watchdog we kick it here one more time
461 * to give it some time.
463 wdat
->stopped
= false;
464 if (acpi_target_system_state() == ACPI_STATE_S0
||
465 !wdat
->stopped_in_sleep
) {
466 ret
= wdat_wdt_stop(&wdat
->wdd
);
468 wdat
->stopped
= true;
470 ret
= wdat_wdt_ping(&wdat
->wdd
);
476 static int wdat_wdt_resume_noirq(struct device
*dev
)
478 struct platform_device
*pdev
= to_platform_device(dev
);
479 struct wdat_wdt
*wdat
= platform_get_drvdata(pdev
);
482 if (!watchdog_active(&wdat
->wdd
))
485 if (!wdat
->stopped
) {
487 * Looks like the boot firmware reinitializes the watchdog
488 * before it hands off to the OS on resume from sleep so we
489 * stop and reprogram the watchdog here.
491 ret
= wdat_wdt_stop(&wdat
->wdd
);
495 ret
= wdat_wdt_set_timeout(&wdat
->wdd
, wdat
->wdd
.timeout
);
499 ret
= wdat_wdt_enable_reboot(wdat
);
503 ret
= wdat_wdt_ping(&wdat
->wdd
);
508 return wdat_wdt_start(&wdat
->wdd
);
512 static const struct dev_pm_ops wdat_wdt_pm_ops
= {
513 SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(wdat_wdt_suspend_noirq
,
514 wdat_wdt_resume_noirq
)
517 static struct platform_driver wdat_wdt_driver
= {
518 .probe
= wdat_wdt_probe
,
521 .pm
= &wdat_wdt_pm_ops
,
525 module_platform_driver(wdat_wdt_driver
);
527 MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
528 MODULE_DESCRIPTION("ACPI Hardware Watchdog (WDAT) driver");
529 MODULE_LICENSE("GPL v2");
530 MODULE_ALIAS("platform:wdat_wdt");