]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ACPI: x86: cmos_rtc: Improve coordination with ACPI TAD driver
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 23 Feb 2026 15:28:57 +0000 (16:28 +0100)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 23 Feb 2026 18:55:27 +0000 (19:55 +0100)
If a CMOS RTC (PNP0B00/PNP0B01/PNP0B02) device coexists with an ACPI
TAD (timer and event alarm device, ACPI000E), the ACPI TAD driver will
attempt to install the CMOS RTC address space hanlder that has been
installed already and the TAD probing will fail.

Avoid that by changing acpi_install_cmos_rtc_space_handler() to return
zero and acpi_remove_cmos_rtc_space_handler() to do nothing if the CMOS
RTC address space handler has been installed already.

Fixes: 596ca52a56da ("ACPI: TAD: Install SystemCMOS address space handler for ACPI000E")
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Link: https://patch.msgid.link/2415111.ElGaqSPkdT@rafael.j.wysocki
drivers/acpi/x86/cmos_rtc.c

index 977234da9fc1116315aeaae9dda9ee9fd0701c5c..45db7e51cbe6078a6baec9f883410ad9492cf9e2 100644 (file)
@@ -24,6 +24,8 @@ static const struct acpi_device_id acpi_cmos_rtc_ids[] = {
        {}
 };
 
+static bool cmos_rtc_space_handler_present __read_mostly;
+
 static acpi_status acpi_cmos_rtc_space_handler(u32 function,
                                               acpi_physical_address address,
                                               u32 bits, u64 *value64,
@@ -59,6 +61,9 @@ int acpi_install_cmos_rtc_space_handler(acpi_handle handle)
 {
        acpi_status status;
 
+       if (cmos_rtc_space_handler_present)
+               return 0;
+
        status = acpi_install_address_space_handler(handle,
                                                    ACPI_ADR_SPACE_CMOS,
                                                    acpi_cmos_rtc_space_handler,
@@ -68,6 +73,8 @@ int acpi_install_cmos_rtc_space_handler(acpi_handle handle)
                return -ENODEV;
        }
 
+       cmos_rtc_space_handler_present = true;
+
        return 1;
 }
 EXPORT_SYMBOL_GPL(acpi_install_cmos_rtc_space_handler);
@@ -76,6 +83,9 @@ void acpi_remove_cmos_rtc_space_handler(acpi_handle handle)
 {
        acpi_status status;
 
+       if (cmos_rtc_space_handler_present)
+               return;
+
        status = acpi_remove_address_space_handler(handle,
                                                   ACPI_ADR_SPACE_CMOS,
                                                   acpi_cmos_rtc_space_handler);
@@ -87,7 +97,13 @@ EXPORT_SYMBOL_GPL(acpi_remove_cmos_rtc_space_handler);
 static int acpi_cmos_rtc_attach(struct acpi_device *adev,
                                const struct acpi_device_id *id)
 {
-       return acpi_install_cmos_rtc_space_handler(adev->handle);
+       int ret;
+
+       ret = acpi_install_cmos_rtc_space_handler(adev->handle);
+       if (ret < 0)
+               return ret;
+
+       return 1;
 }
 
 static struct acpi_scan_handler cmos_rtc_handler = {