1 // SPDX-License-Identifier: GPL-2.0
3 * ACPI Time and Alarm (TAD) Device Driver
5 * Copyright (C) 2018 Intel Corporation
6 * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
8 * This driver is based on Section 9.18 of the ACPI 6.2 specification revision.
10 * It only supports the system wakeup capabilities of the TAD.
12 * Provided are sysfs attributes, available under the TAD platform device,
13 * allowing user space to manage the AC and DC wakeup timers of the TAD:
14 * set and read their values, set and check their expire timer wake policies,
15 * check and clear their status and check the capabilities of the TAD reported
16 * by AML. The DC timer attributes are only present if the TAD supports a
17 * separate DC alarm timer.
19 * The wakeup events handling and power management of the TAD is expected to
20 * be taken care of by the ACPI PM domain attached to its platform device.
23 #include <linux/acpi.h>
24 #include <linux/kernel.h>
25 #include <linux/module.h>
26 #include <linux/platform_device.h>
27 #include <linux/pm_runtime.h>
28 #include <linux/suspend.h>
30 MODULE_LICENSE("GPL v2");
31 MODULE_AUTHOR("Rafael J. Wysocki");
33 /* ACPI TAD capability flags (ACPI 6.2, Section 9.18.2) */
34 #define ACPI_TAD_AC_WAKE BIT(0)
35 #define ACPI_TAD_DC_WAKE BIT(1)
36 #define ACPI_TAD_RT BIT(2)
37 #define ACPI_TAD_RT_IN_MS BIT(3)
38 #define ACPI_TAD_S4_S5__GWS BIT(4)
39 #define ACPI_TAD_AC_S4_WAKE BIT(5)
40 #define ACPI_TAD_AC_S5_WAKE BIT(6)
41 #define ACPI_TAD_DC_S4_WAKE BIT(7)
42 #define ACPI_TAD_DC_S5_WAKE BIT(8)
44 /* ACPI TAD alarm timer selection */
45 #define ACPI_TAD_AC_TIMER (u32)0
46 #define ACPI_TAD_DC_TIMER (u32)1
48 /* Special value for disabled timer or expired timer wake policy. */
49 #define ACPI_TAD_WAKE_DISABLED (~(u32)0)
51 struct acpi_tad_driver_data
{
55 static int acpi_tad_wake_set(struct device
*dev
, char *method
, u32 timer_id
,
58 acpi_handle handle
= ACPI_HANDLE(dev
);
59 union acpi_object args
[] = {
60 { .type
= ACPI_TYPE_INTEGER
, },
61 { .type
= ACPI_TYPE_INTEGER
, },
63 struct acpi_object_list arg_list
= {
65 .count
= ARRAY_SIZE(args
),
67 unsigned long long retval
;
70 args
[0].integer
.value
= timer_id
;
71 args
[1].integer
.value
= value
;
73 pm_runtime_get_sync(dev
);
75 status
= acpi_evaluate_integer(handle
, method
, &arg_list
, &retval
);
77 pm_runtime_put_sync(dev
);
79 if (ACPI_FAILURE(status
) || retval
)
85 static int acpi_tad_wake_write(struct device
*dev
, const char *buf
, char *method
,
86 u32 timer_id
, const char *specval
)
90 if (sysfs_streq(buf
, specval
)) {
91 value
= ACPI_TAD_WAKE_DISABLED
;
93 int ret
= kstrtou32(buf
, 0, &value
);
98 if (value
== ACPI_TAD_WAKE_DISABLED
)
102 return acpi_tad_wake_set(dev
, method
, timer_id
, value
);
105 static ssize_t
acpi_tad_wake_read(struct device
*dev
, char *buf
, char *method
,
106 u32 timer_id
, const char *specval
)
108 acpi_handle handle
= ACPI_HANDLE(dev
);
109 union acpi_object args
[] = {
110 { .type
= ACPI_TYPE_INTEGER
, },
112 struct acpi_object_list arg_list
= {
114 .count
= ARRAY_SIZE(args
),
116 unsigned long long retval
;
119 args
[0].integer
.value
= timer_id
;
121 pm_runtime_get_sync(dev
);
123 status
= acpi_evaluate_integer(handle
, method
, &arg_list
, &retval
);
125 pm_runtime_put_sync(dev
);
127 if (ACPI_FAILURE(status
))
130 if ((u32
)retval
== ACPI_TAD_WAKE_DISABLED
)
131 return sprintf(buf
, "%s\n", specval
);
133 return sprintf(buf
, "%u\n", (u32
)retval
);
136 static const char *alarm_specval
= "disabled";
138 static int acpi_tad_alarm_write(struct device
*dev
, const char *buf
,
141 return acpi_tad_wake_write(dev
, buf
, "_STV", timer_id
, alarm_specval
);
144 static ssize_t
acpi_tad_alarm_read(struct device
*dev
, char *buf
, u32 timer_id
)
146 return acpi_tad_wake_read(dev
, buf
, "_TIV", timer_id
, alarm_specval
);
149 static const char *policy_specval
= "never";
151 static int acpi_tad_policy_write(struct device
*dev
, const char *buf
,
154 return acpi_tad_wake_write(dev
, buf
, "_STP", timer_id
, policy_specval
);
157 static ssize_t
acpi_tad_policy_read(struct device
*dev
, char *buf
, u32 timer_id
)
159 return acpi_tad_wake_read(dev
, buf
, "_TIP", timer_id
, policy_specval
);
162 static int acpi_tad_clear_status(struct device
*dev
, u32 timer_id
)
164 acpi_handle handle
= ACPI_HANDLE(dev
);
165 union acpi_object args
[] = {
166 { .type
= ACPI_TYPE_INTEGER
, },
168 struct acpi_object_list arg_list
= {
170 .count
= ARRAY_SIZE(args
),
172 unsigned long long retval
;
175 args
[0].integer
.value
= timer_id
;
177 pm_runtime_get_sync(dev
);
179 status
= acpi_evaluate_integer(handle
, "_CWS", &arg_list
, &retval
);
181 pm_runtime_put_sync(dev
);
183 if (ACPI_FAILURE(status
) || retval
)
189 static int acpi_tad_status_write(struct device
*dev
, const char *buf
, u32 timer_id
)
193 ret
= kstrtoint(buf
, 0, &value
);
200 return acpi_tad_clear_status(dev
, timer_id
);
203 static ssize_t
acpi_tad_status_read(struct device
*dev
, char *buf
, u32 timer_id
)
205 acpi_handle handle
= ACPI_HANDLE(dev
);
206 union acpi_object args
[] = {
207 { .type
= ACPI_TYPE_INTEGER
, },
209 struct acpi_object_list arg_list
= {
211 .count
= ARRAY_SIZE(args
),
213 unsigned long long retval
;
216 args
[0].integer
.value
= timer_id
;
218 pm_runtime_get_sync(dev
);
220 status
= acpi_evaluate_integer(handle
, "_GWS", &arg_list
, &retval
);
222 pm_runtime_put_sync(dev
);
224 if (ACPI_FAILURE(status
))
227 return sprintf(buf
, "0x%02X\n", (u32
)retval
);
230 static ssize_t
caps_show(struct device
*dev
, struct device_attribute
*attr
,
233 struct acpi_tad_driver_data
*dd
= dev_get_drvdata(dev
);
235 return sprintf(buf
, "0x%02X\n", dd
->capabilities
);
238 static DEVICE_ATTR_RO(caps
);
240 static ssize_t
ac_alarm_store(struct device
*dev
, struct device_attribute
*attr
,
241 const char *buf
, size_t count
)
243 int ret
= acpi_tad_alarm_write(dev
, buf
, ACPI_TAD_AC_TIMER
);
245 return ret
? ret
: count
;
248 static ssize_t
ac_alarm_show(struct device
*dev
, struct device_attribute
*attr
,
251 return acpi_tad_alarm_read(dev
, buf
, ACPI_TAD_AC_TIMER
);
254 static DEVICE_ATTR(ac_alarm
, S_IRUSR
| S_IWUSR
, ac_alarm_show
, ac_alarm_store
);
256 static ssize_t
ac_policy_store(struct device
*dev
, struct device_attribute
*attr
,
257 const char *buf
, size_t count
)
259 int ret
= acpi_tad_policy_write(dev
, buf
, ACPI_TAD_AC_TIMER
);
261 return ret
? ret
: count
;
264 static ssize_t
ac_policy_show(struct device
*dev
, struct device_attribute
*attr
,
267 return acpi_tad_policy_read(dev
, buf
, ACPI_TAD_AC_TIMER
);
270 static DEVICE_ATTR(ac_policy
, S_IRUSR
| S_IWUSR
, ac_policy_show
, ac_policy_store
);
272 static ssize_t
ac_status_store(struct device
*dev
, struct device_attribute
*attr
,
273 const char *buf
, size_t count
)
275 int ret
= acpi_tad_status_write(dev
, buf
, ACPI_TAD_AC_TIMER
);
277 return ret
? ret
: count
;
280 static ssize_t
ac_status_show(struct device
*dev
, struct device_attribute
*attr
,
283 return acpi_tad_status_read(dev
, buf
, ACPI_TAD_AC_TIMER
);
286 static DEVICE_ATTR(ac_status
, S_IRUSR
| S_IWUSR
, ac_status_show
, ac_status_store
);
288 static struct attribute
*acpi_tad_attrs
[] = {
290 &dev_attr_ac_alarm
.attr
,
291 &dev_attr_ac_policy
.attr
,
292 &dev_attr_ac_status
.attr
,
295 static const struct attribute_group acpi_tad_attr_group
= {
296 .attrs
= acpi_tad_attrs
,
299 static ssize_t
dc_alarm_store(struct device
*dev
, struct device_attribute
*attr
,
300 const char *buf
, size_t count
)
302 int ret
= acpi_tad_alarm_write(dev
, buf
, ACPI_TAD_DC_TIMER
);
304 return ret
? ret
: count
;
307 static ssize_t
dc_alarm_show(struct device
*dev
, struct device_attribute
*attr
,
310 return acpi_tad_alarm_read(dev
, buf
, ACPI_TAD_DC_TIMER
);
313 static DEVICE_ATTR(dc_alarm
, S_IRUSR
| S_IWUSR
, dc_alarm_show
, dc_alarm_store
);
315 static ssize_t
dc_policy_store(struct device
*dev
, struct device_attribute
*attr
,
316 const char *buf
, size_t count
)
318 int ret
= acpi_tad_policy_write(dev
, buf
, ACPI_TAD_DC_TIMER
);
320 return ret
? ret
: count
;
323 static ssize_t
dc_policy_show(struct device
*dev
, struct device_attribute
*attr
,
326 return acpi_tad_policy_read(dev
, buf
, ACPI_TAD_DC_TIMER
);
329 static DEVICE_ATTR(dc_policy
, S_IRUSR
| S_IWUSR
, dc_policy_show
, dc_policy_store
);
331 static ssize_t
dc_status_store(struct device
*dev
, struct device_attribute
*attr
,
332 const char *buf
, size_t count
)
334 int ret
= acpi_tad_status_write(dev
, buf
, ACPI_TAD_DC_TIMER
);
336 return ret
? ret
: count
;
339 static ssize_t
dc_status_show(struct device
*dev
, struct device_attribute
*attr
,
342 return acpi_tad_status_read(dev
, buf
, ACPI_TAD_DC_TIMER
);
345 static DEVICE_ATTR(dc_status
, S_IRUSR
| S_IWUSR
, dc_status_show
, dc_status_store
);
347 static struct attribute
*acpi_tad_dc_attrs
[] = {
348 &dev_attr_dc_alarm
.attr
,
349 &dev_attr_dc_policy
.attr
,
350 &dev_attr_dc_status
.attr
,
353 static const struct attribute_group acpi_tad_dc_attr_group
= {
354 .attrs
= acpi_tad_dc_attrs
,
357 static int acpi_tad_disable_timer(struct device
*dev
, u32 timer_id
)
359 return acpi_tad_wake_set(dev
, "_STV", timer_id
, ACPI_TAD_WAKE_DISABLED
);
362 static int acpi_tad_remove(struct platform_device
*pdev
)
364 struct device
*dev
= &pdev
->dev
;
365 struct acpi_tad_driver_data
*dd
= dev_get_drvdata(dev
);
367 device_init_wakeup(dev
, false);
369 pm_runtime_get_sync(dev
);
371 if (dd
->capabilities
& ACPI_TAD_DC_WAKE
)
372 sysfs_remove_group(&dev
->kobj
, &acpi_tad_dc_attr_group
);
374 sysfs_remove_group(&dev
->kobj
, &acpi_tad_attr_group
);
376 acpi_tad_disable_timer(dev
, ACPI_TAD_AC_TIMER
);
377 acpi_tad_clear_status(dev
, ACPI_TAD_AC_TIMER
);
378 if (dd
->capabilities
& ACPI_TAD_DC_WAKE
) {
379 acpi_tad_disable_timer(dev
, ACPI_TAD_DC_TIMER
);
380 acpi_tad_clear_status(dev
, ACPI_TAD_DC_TIMER
);
383 pm_runtime_put_sync(dev
);
384 pm_runtime_disable(dev
);
388 static int acpi_tad_probe(struct platform_device
*pdev
)
390 struct device
*dev
= &pdev
->dev
;
391 acpi_handle handle
= ACPI_HANDLE(dev
);
392 struct acpi_tad_driver_data
*dd
;
394 unsigned long long caps
;
398 * Initialization failure messages are mostly about firmware issues, so
399 * print them at the "info" level.
401 status
= acpi_evaluate_integer(handle
, "_GCP", NULL
, &caps
);
402 if (ACPI_FAILURE(status
)) {
403 dev_info(dev
, "Unable to get capabilities\n");
407 if (!(caps
& ACPI_TAD_AC_WAKE
)) {
408 dev_info(dev
, "Unsupported capabilities\n");
412 if (!acpi_has_method(handle
, "_PRW")) {
413 dev_info(dev
, "Missing _PRW\n");
417 dd
= devm_kzalloc(dev
, sizeof(*dd
), GFP_KERNEL
);
421 dd
->capabilities
= caps
;
422 dev_set_drvdata(dev
, dd
);
425 * Assume that the ACPI PM domain has been attached to the device and
426 * simply enable system wakeup and runtime PM and put the device into
427 * runtime suspend. Everything else should be taken care of by the ACPI
428 * PM domain callbacks.
430 device_init_wakeup(dev
, true);
431 dev_pm_set_driver_flags(dev
, DPM_FLAG_SMART_SUSPEND
|
432 DPM_FLAG_LEAVE_SUSPENDED
);
434 * The platform bus type layer tells the ACPI PM domain powers up the
435 * device, so set the runtime PM status of it to "active".
437 pm_runtime_set_active(dev
);
438 pm_runtime_enable(dev
);
439 pm_runtime_suspend(dev
);
441 ret
= sysfs_create_group(&dev
->kobj
, &acpi_tad_attr_group
);
445 if (caps
& ACPI_TAD_DC_WAKE
) {
446 ret
= sysfs_create_group(&dev
->kobj
, &acpi_tad_dc_attr_group
);
454 acpi_tad_remove(pdev
);
458 static const struct acpi_device_id acpi_tad_ids
[] = {
463 static struct platform_driver acpi_tad_driver
= {
466 .acpi_match_table
= acpi_tad_ids
,
468 .probe
= acpi_tad_probe
,
469 .remove
= acpi_tad_remove
,
471 MODULE_DEVICE_TABLE(acpi
, acpi_tad_ids
);
473 module_platform_driver(acpi_tad_driver
);