]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ACPI: TAD: Use devres for all driver cleanup
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Wed, 22 Apr 2026 15:25:46 +0000 (17:25 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 27 Apr 2026 19:57:09 +0000 (21:57 +0200)
The code in acpi_tad_remove() needs to run after the unregistration of
the devres-managed RTC class device so that it doesn't race with the
class callbacks of the latter.

To make that happen, pass it to devm_add_action_or_reset() before
registering the RTC class device.

Fixes: 7572dcabe38d ("ACPI: TAD: Add alarm support to the RTC class device interface")
Fixes: 8a1e7f4b1764 ("ACPI: TAD: Add RTC class device interface")
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Link: https://patch.msgid.link/14001754.uLZWGnKmhe@rafael.j.wysocki
drivers/acpi/acpi_tad.c

index 91bdbf669aafc4411900222180bb1c8fa8c80978..2aaef50a2d0fac87046c9db7168b1eb524246018 100644 (file)
@@ -792,9 +792,9 @@ static int acpi_tad_disable_timer(struct device *dev, u32 timer_id)
        return acpi_tad_wake_set(dev, "_STV", timer_id, ACPI_TAD_WAKE_DISABLED);
 }
 
-static void acpi_tad_remove(struct platform_device *pdev)
+static void acpi_tad_remove(void *data)
 {
-       struct device *dev = &pdev->dev;
+       struct device *dev = data;
        struct acpi_tad_driver_data *dd = dev_get_drvdata(dev);
 
        device_init_wakeup(dev, false);
@@ -821,6 +821,7 @@ static int acpi_tad_probe(struct platform_device *pdev)
        struct acpi_tad_driver_data *dd;
        acpi_status status;
        unsigned long long caps;
+       int ret;
 
        /*
         * Initialization failure messages are mostly about firmware issues, so
@@ -867,6 +868,14 @@ static int acpi_tad_probe(struct platform_device *pdev)
        pm_runtime_enable(dev);
        pm_runtime_suspend(dev);
 
+       /*
+        * acpi_tad_remove() needs to run after unregistering the RTC class
+        * device to avoid racing with the latter's callbacks.
+        */
+       ret = devm_add_action_or_reset(&pdev->dev, acpi_tad_remove, &pdev->dev);
+       if (ret)
+               return ret;
+
        if (caps & ACPI_TAD_RT)
                acpi_tad_register_rtc(dev, caps);
 
@@ -885,7 +894,6 @@ static struct platform_driver acpi_tad_driver = {
                .dev_groups = acpi_tad_groups,
        },
        .probe = acpi_tad_probe,
-       .remove = acpi_tad_remove,
 };
 MODULE_DEVICE_TABLE(acpi, acpi_tad_ids);