1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * ACPI Time and Alarm (TAD) Device Driver
4 *
5 * Copyright (C) 2018 Intel Corporation
6 * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
7 *
8 * This driver is based on Section 9.18 of the ACPI 6.2 specification revision.
9 *
10 * It only supports the system wakeup capabilities of the TAD.
11 *
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.
18 *
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.
21 */
22
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>
29
30 MODULE_DESCRIPTION("ACPI Time and Alarm (TAD) Device Driver");
31 MODULE_LICENSE("GPL v2");
32 MODULE_AUTHOR("Rafael J. Wysocki");
33
34 /* ACPI TAD capability flags (ACPI 6.2, Section 9.18.2) */
35 #define ACPI_TAD_AC_WAKE BIT(0)
36 #define ACPI_TAD_DC_WAKE BIT(1)
37 #define ACPI_TAD_RT BIT(2)
38 #define ACPI_TAD_RT_IN_MS BIT(3)
39 #define ACPI_TAD_S4_S5__GWS BIT(4)
40 #define ACPI_TAD_AC_S4_WAKE BIT(5)
41 #define ACPI_TAD_AC_S5_WAKE BIT(6)
42 #define ACPI_TAD_DC_S4_WAKE BIT(7)
43 #define ACPI_TAD_DC_S5_WAKE BIT(8)
44
45 /* ACPI TAD alarm timer selection */
46 #define ACPI_TAD_AC_TIMER (u32)0
47 #define ACPI_TAD_DC_TIMER (u32)1
48
49 /* Special value for disabled timer or expired timer wake policy. */
50 #define ACPI_TAD_WAKE_DISABLED (~(u32)0)
51
52 struct acpi_tad_driver_data {
53 u32 capabilities;
54 };
55
56 struct acpi_tad_rt {
57 u16 year; /* 1900 - 9999 */
58 u8 month; /* 1 - 12 */
59 u8 day; /* 1 - 31 */
60 u8 hour; /* 0 - 23 */
61 u8 minute; /* 0 - 59 */
62 u8 second; /* 0 - 59 */
63 u8 valid; /* 0 (failed) or 1 (success) for reads, 0 for writes */
64 u16 msec; /* 1 - 1000 */
65 s16 tz; /* -1440 to 1440 or 2047 (unspecified) */
66 u8 daylight;
67 u8 padding[3]; /* must be 0 */
68 } __packed;
69
acpi_tad_set_real_time(struct device * dev,struct acpi_tad_rt * rt)70 static int acpi_tad_set_real_time(struct device *dev, struct acpi_tad_rt *rt)
71 {
72 acpi_handle handle = ACPI_HANDLE(dev);
73 union acpi_object args[] = {
74 { .type = ACPI_TYPE_BUFFER, },
75 };
76 struct acpi_object_list arg_list = {
77 .pointer = args,
78 .count = ARRAY_SIZE(args),
79 };
80 unsigned long long retval;
81 acpi_status status;
82
83 if (rt->year < 1900 || rt->year > 9999 ||
84 rt->month < 1 || rt->month > 12 ||
85 rt->hour > 23 || rt->minute > 59 || rt->second > 59 ||
86 rt->tz < -1440 || (rt->tz > 1440 && rt->tz != 2047) ||
87 rt->daylight > 3)
88 return -ERANGE;
89
90 args[0].buffer.pointer = (u8 *)rt;
91 args[0].buffer.length = sizeof(*rt);
92
93 pm_runtime_get_sync(dev);
94
95 status = acpi_evaluate_integer(handle, "_SRT", &arg_list, &retval);
96
97 pm_runtime_put_sync(dev);
98
99 if (ACPI_FAILURE(status) || retval)
100 return -EIO;
101
102 return 0;
103 }
104
acpi_tad_get_real_time(struct device * dev,struct acpi_tad_rt * rt)105 static int acpi_tad_get_real_time(struct device *dev, struct acpi_tad_rt *rt)
106 {
107 acpi_handle handle = ACPI_HANDLE(dev);
108 struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER };
109 union acpi_object *out_obj;
110 struct acpi_tad_rt *data;
111 acpi_status status;
112 int ret = -EIO;
113
114 pm_runtime_get_sync(dev);
115
116 status = acpi_evaluate_object(handle, "_GRT", NULL, &output);
117
118 pm_runtime_put_sync(dev);
119
120 if (ACPI_FAILURE(status))
121 goto out_free;
122
123 out_obj = output.pointer;
124 if (out_obj->type != ACPI_TYPE_BUFFER)
125 goto out_free;
126
127 if (out_obj->buffer.length != sizeof(*rt))
128 goto out_free;
129
130 data = (struct acpi_tad_rt *)(out_obj->buffer.pointer);
131 if (!data->valid)
132 goto out_free;
133
134 memcpy(rt, data, sizeof(*rt));
135 ret = 0;
136
137 out_free:
138 ACPI_FREE(output.pointer);
139 return ret;
140 }
141
acpi_tad_rt_next_field(char * s,int * val)142 static char *acpi_tad_rt_next_field(char *s, int *val)
143 {
144 char *p;
145
146 p = strchr(s, ':');
147 if (!p)
148 return NULL;
149
150 *p = '\0';
151 if (kstrtoint(s, 10, val))
152 return NULL;
153
154 return p + 1;
155 }
156
time_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)157 static ssize_t time_store(struct device *dev, struct device_attribute *attr,
158 const char *buf, size_t count)
159 {
160 struct acpi_tad_rt rt;
161 char *str, *s;
162 int val, ret = -ENODATA;
163
164 str = kmemdup_nul(buf, count, GFP_KERNEL);
165 if (!str)
166 return -ENOMEM;
167
168 s = acpi_tad_rt_next_field(str, &val);
169 if (!s)
170 goto out_free;
171
172 rt.year = val;
173
174 s = acpi_tad_rt_next_field(s, &val);
175 if (!s)
176 goto out_free;
177
178 rt.month = val;
179
180 s = acpi_tad_rt_next_field(s, &val);
181 if (!s)
182 goto out_free;
183
184 rt.day = val;
185
186 s = acpi_tad_rt_next_field(s, &val);
187 if (!s)
188 goto out_free;
189
190 rt.hour = val;
191
192 s = acpi_tad_rt_next_field(s, &val);
193 if (!s)
194 goto out_free;
195
196 rt.minute = val;
197
198 s = acpi_tad_rt_next_field(s, &val);
199 if (!s)
200 goto out_free;
201
202 rt.second = val;
203
204 s = acpi_tad_rt_next_field(s, &val);
205 if (!s)
206 goto out_free;
207
208 rt.tz = val;
209
210 if (kstrtoint(s, 10, &val))
211 goto out_free;
212
213 rt.daylight = val;
214
215 rt.valid = 0;
216 rt.msec = 0;
217 memset(rt.padding, 0, 3);
218
219 ret = acpi_tad_set_real_time(dev, &rt);
220
221 out_free:
222 kfree(str);
223 return ret ? ret : count;
224 }
225
time_show(struct device * dev,struct device_attribute * attr,char * buf)226 static ssize_t time_show(struct device *dev, struct device_attribute *attr,
227 char *buf)
228 {
229 struct acpi_tad_rt rt;
230 int ret;
231
232 ret = acpi_tad_get_real_time(dev, &rt);
233 if (ret)
234 return ret;
235
236 return sprintf(buf, "%u:%u:%u:%u:%u:%u:%d:%u\n",
237 rt.year, rt.month, rt.day, rt.hour, rt.minute, rt.second,
238 rt.tz, rt.daylight);
239 }
240
241 static DEVICE_ATTR_RW(time);
242
243 static struct attribute *acpi_tad_time_attrs[] = {
244 &dev_attr_time.attr,
245 NULL,
246 };
247 static const struct attribute_group acpi_tad_time_attr_group = {
248 .attrs = acpi_tad_time_attrs,
249 };
250
acpi_tad_wake_set(struct device * dev,char * method,u32 timer_id,u32 value)251 static int acpi_tad_wake_set(struct device *dev, char *method, u32 timer_id,
252 u32 value)
253 {
254 acpi_handle handle = ACPI_HANDLE(dev);
255 union acpi_object args[] = {
256 { .type = ACPI_TYPE_INTEGER, },
257 { .type = ACPI_TYPE_INTEGER, },
258 };
259 struct acpi_object_list arg_list = {
260 .pointer = args,
261 .count = ARRAY_SIZE(args),
262 };
263 unsigned long long retval;
264 acpi_status status;
265
266 args[0].integer.value = timer_id;
267 args[1].integer.value = value;
268
269 pm_runtime_get_sync(dev);
270
271 status = acpi_evaluate_integer(handle, method, &arg_list, &retval);
272
273 pm_runtime_put_sync(dev);
274
275 if (ACPI_FAILURE(status) || retval)
276 return -EIO;
277
278 return 0;
279 }
280
acpi_tad_wake_write(struct device * dev,const char * buf,char * method,u32 timer_id,const char * specval)281 static int acpi_tad_wake_write(struct device *dev, const char *buf, char *method,
282 u32 timer_id, const char *specval)
283 {
284 u32 value;
285
286 if (sysfs_streq(buf, specval)) {
287 value = ACPI_TAD_WAKE_DISABLED;
288 } else {
289 int ret = kstrtou32(buf, 0, &value);
290
291 if (ret)
292 return ret;
293
294 if (value == ACPI_TAD_WAKE_DISABLED)
295 return -EINVAL;
296 }
297
298 return acpi_tad_wake_set(dev, method, timer_id, value);
299 }
300
acpi_tad_wake_read(struct device * dev,char * buf,char * method,u32 timer_id,const char * specval)301 static ssize_t acpi_tad_wake_read(struct device *dev, char *buf, char *method,
302 u32 timer_id, const char *specval)
303 {
304 acpi_handle handle = ACPI_HANDLE(dev);
305 union acpi_object args[] = {
306 { .type = ACPI_TYPE_INTEGER, },
307 };
308 struct acpi_object_list arg_list = {
309 .pointer = args,
310 .count = ARRAY_SIZE(args),
311 };
312 unsigned long long retval;
313 acpi_status status;
314
315 args[0].integer.value = timer_id;
316
317 pm_runtime_get_sync(dev);
318
319 status = acpi_evaluate_integer(handle, method, &arg_list, &retval);
320
321 pm_runtime_put_sync(dev);
322
323 if (ACPI_FAILURE(status))
324 return -EIO;
325
326 if ((u32)retval == ACPI_TAD_WAKE_DISABLED)
327 return sprintf(buf, "%s\n", specval);
328
329 return sprintf(buf, "%u\n", (u32)retval);
330 }
331
332 static const char *alarm_specval = "disabled";
333
acpi_tad_alarm_write(struct device * dev,const char * buf,u32 timer_id)334 static int acpi_tad_alarm_write(struct device *dev, const char *buf,
335 u32 timer_id)
336 {
337 return acpi_tad_wake_write(dev, buf, "_STV", timer_id, alarm_specval);
338 }
339
acpi_tad_alarm_read(struct device * dev,char * buf,u32 timer_id)340 static ssize_t acpi_tad_alarm_read(struct device *dev, char *buf, u32 timer_id)
341 {
342 return acpi_tad_wake_read(dev, buf, "_TIV", timer_id, alarm_specval);
343 }
344
345 static const char *policy_specval = "never";
346
acpi_tad_policy_write(struct device * dev,const char * buf,u32 timer_id)347 static int acpi_tad_policy_write(struct device *dev, const char *buf,
348 u32 timer_id)
349 {
350 return acpi_tad_wake_write(dev, buf, "_STP", timer_id, policy_specval);
351 }
352
acpi_tad_policy_read(struct device * dev,char * buf,u32 timer_id)353 static ssize_t acpi_tad_policy_read(struct device *dev, char *buf, u32 timer_id)
354 {
355 return acpi_tad_wake_read(dev, buf, "_TIP", timer_id, policy_specval);
356 }
357
acpi_tad_clear_status(struct device * dev,u32 timer_id)358 static int acpi_tad_clear_status(struct device *dev, u32 timer_id)
359 {
360 acpi_handle handle = ACPI_HANDLE(dev);
361 union acpi_object args[] = {
362 { .type = ACPI_TYPE_INTEGER, },
363 };
364 struct acpi_object_list arg_list = {
365 .pointer = args,
366 .count = ARRAY_SIZE(args),
367 };
368 unsigned long long retval;
369 acpi_status status;
370
371 args[0].integer.value = timer_id;
372
373 pm_runtime_get_sync(dev);
374
375 status = acpi_evaluate_integer(handle, "_CWS", &arg_list, &retval);
376
377 pm_runtime_put_sync(dev);
378
379 if (ACPI_FAILURE(status) || retval)
380 return -EIO;
381
382 return 0;
383 }
384
acpi_tad_status_write(struct device * dev,const char * buf,u32 timer_id)385 static int acpi_tad_status_write(struct device *dev, const char *buf, u32 timer_id)
386 {
387 int ret, value;
388
389 ret = kstrtoint(buf, 0, &value);
390 if (ret)
391 return ret;
392
393 if (value)
394 return -EINVAL;
395
396 return acpi_tad_clear_status(dev, timer_id);
397 }
398
acpi_tad_status_read(struct device * dev,char * buf,u32 timer_id)399 static ssize_t acpi_tad_status_read(struct device *dev, char *buf, u32 timer_id)
400 {
401 acpi_handle handle = ACPI_HANDLE(dev);
402 union acpi_object args[] = {
403 { .type = ACPI_TYPE_INTEGER, },
404 };
405 struct acpi_object_list arg_list = {
406 .pointer = args,
407 .count = ARRAY_SIZE(args),
408 };
409 unsigned long long retval;
410 acpi_status status;
411
412 args[0].integer.value = timer_id;
413
414 pm_runtime_get_sync(dev);
415
416 status = acpi_evaluate_integer(handle, "_GWS", &arg_list, &retval);
417
418 pm_runtime_put_sync(dev);
419
420 if (ACPI_FAILURE(status))
421 return -EIO;
422
423 return sprintf(buf, "0x%02X\n", (u32)retval);
424 }
425
caps_show(struct device * dev,struct device_attribute * attr,char * buf)426 static ssize_t caps_show(struct device *dev, struct device_attribute *attr,
427 char *buf)
428 {
429 struct acpi_tad_driver_data *dd = dev_get_drvdata(dev);
430
431 return sprintf(buf, "0x%02X\n", dd->capabilities);
432 }
433
434 static DEVICE_ATTR_RO(caps);
435
ac_alarm_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)436 static ssize_t ac_alarm_store(struct device *dev, struct device_attribute *attr,
437 const char *buf, size_t count)
438 {
439 int ret = acpi_tad_alarm_write(dev, buf, ACPI_TAD_AC_TIMER);
440
441 return ret ? ret : count;
442 }
443
ac_alarm_show(struct device * dev,struct device_attribute * attr,char * buf)444 static ssize_t ac_alarm_show(struct device *dev, struct device_attribute *attr,
445 char *buf)
446 {
447 return acpi_tad_alarm_read(dev, buf, ACPI_TAD_AC_TIMER);
448 }
449
450 static DEVICE_ATTR_RW(ac_alarm);
451
ac_policy_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)452 static ssize_t ac_policy_store(struct device *dev, struct device_attribute *attr,
453 const char *buf, size_t count)
454 {
455 int ret = acpi_tad_policy_write(dev, buf, ACPI_TAD_AC_TIMER);
456
457 return ret ? ret : count;
458 }
459
ac_policy_show(struct device * dev,struct device_attribute * attr,char * buf)460 static ssize_t ac_policy_show(struct device *dev, struct device_attribute *attr,
461 char *buf)
462 {
463 return acpi_tad_policy_read(dev, buf, ACPI_TAD_AC_TIMER);
464 }
465
466 static DEVICE_ATTR_RW(ac_policy);
467
ac_status_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)468 static ssize_t ac_status_store(struct device *dev, struct device_attribute *attr,
469 const char *buf, size_t count)
470 {
471 int ret = acpi_tad_status_write(dev, buf, ACPI_TAD_AC_TIMER);
472
473 return ret ? ret : count;
474 }
475
ac_status_show(struct device * dev,struct device_attribute * attr,char * buf)476 static ssize_t ac_status_show(struct device *dev, struct device_attribute *attr,
477 char *buf)
478 {
479 return acpi_tad_status_read(dev, buf, ACPI_TAD_AC_TIMER);
480 }
481
482 static DEVICE_ATTR_RW(ac_status);
483
484 static struct attribute *acpi_tad_attrs[] = {
485 &dev_attr_caps.attr,
486 &dev_attr_ac_alarm.attr,
487 &dev_attr_ac_policy.attr,
488 &dev_attr_ac_status.attr,
489 NULL,
490 };
491 static const struct attribute_group acpi_tad_attr_group = {
492 .attrs = acpi_tad_attrs,
493 };
494
dc_alarm_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)495 static ssize_t dc_alarm_store(struct device *dev, struct device_attribute *attr,
496 const char *buf, size_t count)
497 {
498 int ret = acpi_tad_alarm_write(dev, buf, ACPI_TAD_DC_TIMER);
499
500 return ret ? ret : count;
501 }
502
dc_alarm_show(struct device * dev,struct device_attribute * attr,char * buf)503 static ssize_t dc_alarm_show(struct device *dev, struct device_attribute *attr,
504 char *buf)
505 {
506 return acpi_tad_alarm_read(dev, buf, ACPI_TAD_DC_TIMER);
507 }
508
509 static DEVICE_ATTR_RW(dc_alarm);
510
dc_policy_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)511 static ssize_t dc_policy_store(struct device *dev, struct device_attribute *attr,
512 const char *buf, size_t count)
513 {
514 int ret = acpi_tad_policy_write(dev, buf, ACPI_TAD_DC_TIMER);
515
516 return ret ? ret : count;
517 }
518
dc_policy_show(struct device * dev,struct device_attribute * attr,char * buf)519 static ssize_t dc_policy_show(struct device *dev, struct device_attribute *attr,
520 char *buf)
521 {
522 return acpi_tad_policy_read(dev, buf, ACPI_TAD_DC_TIMER);
523 }
524
525 static DEVICE_ATTR_RW(dc_policy);
526
dc_status_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)527 static ssize_t dc_status_store(struct device *dev, struct device_attribute *attr,
528 const char *buf, size_t count)
529 {
530 int ret = acpi_tad_status_write(dev, buf, ACPI_TAD_DC_TIMER);
531
532 return ret ? ret : count;
533 }
534
dc_status_show(struct device * dev,struct device_attribute * attr,char * buf)535 static ssize_t dc_status_show(struct device *dev, struct device_attribute *attr,
536 char *buf)
537 {
538 return acpi_tad_status_read(dev, buf, ACPI_TAD_DC_TIMER);
539 }
540
541 static DEVICE_ATTR_RW(dc_status);
542
543 static struct attribute *acpi_tad_dc_attrs[] = {
544 &dev_attr_dc_alarm.attr,
545 &dev_attr_dc_policy.attr,
546 &dev_attr_dc_status.attr,
547 NULL,
548 };
549 static const struct attribute_group acpi_tad_dc_attr_group = {
550 .attrs = acpi_tad_dc_attrs,
551 };
552
acpi_tad_disable_timer(struct device * dev,u32 timer_id)553 static int acpi_tad_disable_timer(struct device *dev, u32 timer_id)
554 {
555 return acpi_tad_wake_set(dev, "_STV", timer_id, ACPI_TAD_WAKE_DISABLED);
556 }
557
acpi_tad_remove(struct platform_device * pdev)558 static void acpi_tad_remove(struct platform_device *pdev)
559 {
560 struct device *dev = &pdev->dev;
561 acpi_handle handle = ACPI_HANDLE(dev);
562 struct acpi_tad_driver_data *dd = dev_get_drvdata(dev);
563
564 device_init_wakeup(dev, false);
565
566 pm_runtime_get_sync(dev);
567
568 if (dd->capabilities & ACPI_TAD_DC_WAKE)
569 sysfs_remove_group(&dev->kobj, &acpi_tad_dc_attr_group);
570
571 sysfs_remove_group(&dev->kobj, &acpi_tad_attr_group);
572
573 acpi_tad_disable_timer(dev, ACPI_TAD_AC_TIMER);
574 acpi_tad_clear_status(dev, ACPI_TAD_AC_TIMER);
575 if (dd->capabilities & ACPI_TAD_DC_WAKE) {
576 acpi_tad_disable_timer(dev, ACPI_TAD_DC_TIMER);
577 acpi_tad_clear_status(dev, ACPI_TAD_DC_TIMER);
578 }
579
580 pm_runtime_put_sync(dev);
581 pm_runtime_disable(dev);
582 acpi_remove_cmos_rtc_space_handler(handle);
583 }
584
acpi_tad_probe(struct platform_device * pdev)585 static int acpi_tad_probe(struct platform_device *pdev)
586 {
587 struct device *dev = &pdev->dev;
588 acpi_handle handle = ACPI_HANDLE(dev);
589 struct acpi_tad_driver_data *dd;
590 acpi_status status;
591 unsigned long long caps;
592 int ret;
593
594 ret = acpi_install_cmos_rtc_space_handler(handle);
595 if (ret < 0) {
596 dev_info(dev, "Unable to install space handler\n");
597 return -ENODEV;
598 }
599 /*
600 * Initialization failure messages are mostly about firmware issues, so
601 * print them at the "info" level.
602 */
603 status = acpi_evaluate_integer(handle, "_GCP", NULL, &caps);
604 if (ACPI_FAILURE(status)) {
605 dev_info(dev, "Unable to get capabilities\n");
606 ret = -ENODEV;
607 goto remove_handler;
608 }
609
610 if (!(caps & ACPI_TAD_AC_WAKE)) {
611 dev_info(dev, "Unsupported capabilities\n");
612 ret = -ENODEV;
613 goto remove_handler;
614 }
615
616 if (!acpi_has_method(handle, "_PRW")) {
617 dev_info(dev, "Missing _PRW\n");
618 ret = -ENODEV;
619 goto remove_handler;
620 }
621
622 dd = devm_kzalloc(dev, sizeof(*dd), GFP_KERNEL);
623 if (!dd) {
624 ret = -ENOMEM;
625 goto remove_handler;
626 }
627
628 dd->capabilities = caps;
629 dev_set_drvdata(dev, dd);
630
631 /*
632 * Assume that the ACPI PM domain has been attached to the device and
633 * simply enable system wakeup and runtime PM and put the device into
634 * runtime suspend. Everything else should be taken care of by the ACPI
635 * PM domain callbacks.
636 */
637 device_init_wakeup(dev, true);
638 dev_pm_set_driver_flags(dev, DPM_FLAG_SMART_SUSPEND |
639 DPM_FLAG_MAY_SKIP_RESUME);
640 /*
641 * The platform bus type layer tells the ACPI PM domain powers up the
642 * device, so set the runtime PM status of it to "active".
643 */
644 pm_runtime_set_active(dev);
645 pm_runtime_enable(dev);
646 pm_runtime_suspend(dev);
647
648 ret = sysfs_create_group(&dev->kobj, &acpi_tad_attr_group);
649 if (ret)
650 goto fail;
651
652 if (caps & ACPI_TAD_DC_WAKE) {
653 ret = sysfs_create_group(&dev->kobj, &acpi_tad_dc_attr_group);
654 if (ret)
655 goto fail;
656 }
657
658 if (caps & ACPI_TAD_RT) {
659 ret = sysfs_create_group(&dev->kobj, &acpi_tad_time_attr_group);
660 if (ret)
661 goto fail;
662 }
663
664 return 0;
665
666 fail:
667 acpi_tad_remove(pdev);
668 /* Don't fallthrough because cmos rtc space handler is removed in acpi_tad_remove() */
669 return ret;
670
671 remove_handler:
672 acpi_remove_cmos_rtc_space_handler(handle);
673 return ret;
674 }
675
676 static const struct acpi_device_id acpi_tad_ids[] = {
677 {"ACPI000E", 0},
678 {}
679 };
680
681 static struct platform_driver acpi_tad_driver = {
682 .driver = {
683 .name = "acpi-tad",
684 .acpi_match_table = acpi_tad_ids,
685 },
686 .probe = acpi_tad_probe,
687 .remove_new = acpi_tad_remove,
688 };
689 MODULE_DEVICE_TABLE(acpi, acpi_tad_ids);
690
691 module_platform_driver(acpi_tad_driver);
692