Skip to content

Commit 596ca52

Browse files
zhang-ruirafaeljw
authored andcommitted
ACPI: TAD: Install SystemCMOS address space handler for ACPI000E
Currently, the SystemCMOS address space handler is installed for the ACPI RTC devices (PNP0B00/PNP0B01/PNP0B02) only. But there are platforms with SystemCMOS Operetion Region defined under the ACPI Time and Alarm Device (ACPI000E), which is used by the ACPI pre-defined control methods like _GRT (Get the Real time) and _SRT (Set the Real time). When accessing these control methods via the acpi_tad sysfs interface, missing SystemCMOS address space handler causes errors like below [ 478.255453] ACPI Error: No handler for Region [RTCM] (00000000a8d2dd39) [SystemCMOS] (20230331/evregion-130) [ 478.255458] ACPI Error: Region SystemCMOS (ID=5) has no handler (20230331/exfldio-261) [ 478.255461] Initialized Local Variables for Method [_GRT]: [ 478.255461] Local1: 00000000f182542c <Obj> Integer 0000000000000000 [ 478.255464] No Arguments are initialized for method [_GRT] [ 478.255465] ACPI Error: Aborting method \_SB.AWAC._GRT due to previous error (AE_NOT_EXIST) (20230331/psparse-529) Export two APIs for SystemCMOS address space handler from acpi_cmos_rtc scan handler and install the handler for the ACPI Time and Alarm Device from the ACPI TAD driver. Link: https://bugzilla.kernel.org/show_bug.cgi?id=217714 Signed-off-by: Zhang Rui <rui.zhang@intel.com> [ rjw: Subject and changelog edits, whitespace adjustment ] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1 parent 2ccdd1b commit 596ca52

File tree

3 files changed

+49
-12
lines changed

3 files changed

+49
-12
lines changed

drivers/acpi/acpi_cmos_rtc.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,11 @@ acpi_cmos_rtc_space_handler(u32 function, acpi_physical_address address,
5151
return AE_OK;
5252
}
5353

54-
static int acpi_install_cmos_rtc_space_handler(struct acpi_device *adev,
55-
const struct acpi_device_id *id)
54+
int acpi_install_cmos_rtc_space_handler(acpi_handle handle)
5655
{
5756
acpi_status status;
5857

59-
status = acpi_install_address_space_handler(adev->handle,
58+
status = acpi_install_address_space_handler(handle,
6059
ACPI_ADR_SPACE_CMOS,
6160
&acpi_cmos_rtc_space_handler,
6261
NULL, NULL);
@@ -67,18 +66,30 @@ static int acpi_install_cmos_rtc_space_handler(struct acpi_device *adev,
6766

6867
return 1;
6968
}
69+
EXPORT_SYMBOL_GPL(acpi_install_cmos_rtc_space_handler);
7070

71-
static void acpi_remove_cmos_rtc_space_handler(struct acpi_device *adev)
71+
void acpi_remove_cmos_rtc_space_handler(acpi_handle handle)
7272
{
73-
if (ACPI_FAILURE(acpi_remove_address_space_handler(adev->handle,
73+
if (ACPI_FAILURE(acpi_remove_address_space_handler(handle,
7474
ACPI_ADR_SPACE_CMOS, &acpi_cmos_rtc_space_handler)))
7575
pr_err("Error removing CMOS-RTC region handler\n");
7676
}
77+
EXPORT_SYMBOL_GPL(acpi_remove_cmos_rtc_space_handler);
78+
79+
static int acpi_cmos_rtc_attach_handler(struct acpi_device *adev, const struct acpi_device_id *id)
80+
{
81+
return acpi_install_cmos_rtc_space_handler(adev->handle);
82+
}
83+
84+
static void acpi_cmos_rtc_detach_handler(struct acpi_device *adev)
85+
{
86+
acpi_remove_cmos_rtc_space_handler(adev->handle);
87+
}
7788

7889
static struct acpi_scan_handler cmos_rtc_handler = {
7990
.ids = acpi_cmos_rtc_ids,
80-
.attach = acpi_install_cmos_rtc_space_handler,
81-
.detach = acpi_remove_cmos_rtc_space_handler,
91+
.attach = acpi_cmos_rtc_attach_handler,
92+
.detach = acpi_cmos_rtc_detach_handler,
8293
};
8394

8495
void __init acpi_cmos_rtc_init(void)

drivers/acpi/acpi_tad.c

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,7 @@ static int acpi_tad_disable_timer(struct device *dev, u32 timer_id)
557557
static int acpi_tad_remove(struct platform_device *pdev)
558558
{
559559
struct device *dev = &pdev->dev;
560+
acpi_handle handle = ACPI_HANDLE(dev);
560561
struct acpi_tad_driver_data *dd = dev_get_drvdata(dev);
561562

562563
device_init_wakeup(dev, false);
@@ -577,6 +578,7 @@ static int acpi_tad_remove(struct platform_device *pdev)
577578

578579
pm_runtime_put_sync(dev);
579580
pm_runtime_disable(dev);
581+
acpi_remove_cmos_rtc_space_handler(handle);
580582
return 0;
581583
}
582584

@@ -589,29 +591,39 @@ static int acpi_tad_probe(struct platform_device *pdev)
589591
unsigned long long caps;
590592
int ret;
591593

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+
}
592599
/*
593600
* Initialization failure messages are mostly about firmware issues, so
594601
* print them at the "info" level.
595602
*/
596603
status = acpi_evaluate_integer(handle, "_GCP", NULL, &caps);
597604
if (ACPI_FAILURE(status)) {
598605
dev_info(dev, "Unable to get capabilities\n");
599-
return -ENODEV;
606+
ret = -ENODEV;
607+
goto remove_handler;
600608
}
601609

602610
if (!(caps & ACPI_TAD_AC_WAKE)) {
603611
dev_info(dev, "Unsupported capabilities\n");
604-
return -ENODEV;
612+
ret = -ENODEV;
613+
goto remove_handler;
605614
}
606615

607616
if (!acpi_has_method(handle, "_PRW")) {
608617
dev_info(dev, "Missing _PRW\n");
609-
return -ENODEV;
618+
ret = -ENODEV;
619+
goto remove_handler;
610620
}
611621

612622
dd = devm_kzalloc(dev, sizeof(*dd), GFP_KERNEL);
613-
if (!dd)
614-
return -ENOMEM;
623+
if (!dd) {
624+
ret = -ENOMEM;
625+
goto remove_handler;
626+
}
615627

616628
dd->capabilities = caps;
617629
dev_set_drvdata(dev, dd);
@@ -653,6 +665,11 @@ static int acpi_tad_probe(struct platform_device *pdev)
653665

654666
fail:
655667
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);
656673
return ret;
657674
}
658675

include/acpi/acpi_bus.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,8 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev);
645645
#ifdef CONFIG_X86
646646
bool acpi_device_override_status(struct acpi_device *adev, unsigned long long *status);
647647
bool acpi_quirk_skip_acpi_ac_and_battery(void);
648+
int acpi_install_cmos_rtc_space_handler(acpi_handle handle);
649+
void acpi_remove_cmos_rtc_space_handler(acpi_handle handle);
648650
#else
649651
static inline bool acpi_device_override_status(struct acpi_device *adev,
650652
unsigned long long *status)
@@ -655,6 +657,13 @@ static inline bool acpi_quirk_skip_acpi_ac_and_battery(void)
655657
{
656658
return false;
657659
}
660+
static inline int acpi_install_cmos_rtc_space_handler(acpi_handle handle)
661+
{
662+
return 1;
663+
}
664+
static inline void acpi_remove_cmos_rtc_space_handler(acpi_handle handle)
665+
{
666+
}
658667
#endif
659668

660669
#if IS_ENABLED(CONFIG_X86_ANDROID_TABLETS)

0 commit comments

Comments
 (0)