From fc001b36e50f4136c6b8d9fceaf17fc145ffbd0d Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Thu, 27 Jul 2023 14:33:47 +0100 Subject: ACPI: Move AMBA bus scan handling into arm64 specific directory Commit fcea0ccf4fd7 ("ACPI: bus: Consolidate all arm specific initialisation into acpi_arm_init()") moved all of the ARM-specific initialization into acpi_arm_init(). However, acpi_amba.c being outside of drivers/acpi/arm64 got ignored and hence acpi_amba_init() was not moved into acpi_arm_init(). Move the AMBA platform bus support into arm64 specific folder and make acpi_amba_init() part of acpi_arm_init(). Signed-off-by: Sudeep Holla Signed-off-by: Rafael J. Wysocki --- drivers/acpi/Makefile | 1 - drivers/acpi/acpi_amba.c | 130 -------------------------------------------- drivers/acpi/arm64/Makefile | 1 + drivers/acpi/arm64/amba.c | 130 ++++++++++++++++++++++++++++++++++++++++++++ drivers/acpi/arm64/init.c | 2 + drivers/acpi/arm64/init.h | 1 + drivers/acpi/internal.h | 5 -- drivers/acpi/scan.c | 1 - 8 files changed, 134 insertions(+), 137 deletions(-) delete mode 100644 drivers/acpi/acpi_amba.c create mode 100644 drivers/acpi/arm64/amba.c diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 3fc5a0d54f6e..eaa09bf52f17 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -50,7 +50,6 @@ acpi-$(CONFIG_PCI) += acpi_lpss.o acpi-y += acpi_apd.o acpi-y += acpi_platform.o acpi-y += acpi_pnp.o -acpi-$(CONFIG_ARM_AMBA) += acpi_amba.o acpi-y += power.o acpi-y += event.o acpi-y += evged.o diff --git a/drivers/acpi/acpi_amba.c b/drivers/acpi/acpi_amba.c deleted file mode 100644 index f5b443ab01c2..000000000000 --- a/drivers/acpi/acpi_amba.c +++ /dev/null @@ -1,130 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only - -/* - * ACPI support for platform bus type. - * - * Copyright (C) 2015, Linaro Ltd - * Author: Graeme Gregory - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "internal.h" - -static const struct acpi_device_id amba_id_list[] = { - {"ARMH0061", 0}, /* PL061 GPIO Device */ - {"ARMH0330", 0}, /* ARM DMA Controller DMA-330 */ - {"ARMHC500", 0}, /* ARM CoreSight ETM4x */ - {"ARMHC501", 0}, /* ARM CoreSight ETR */ - {"ARMHC502", 0}, /* ARM CoreSight STM */ - {"ARMHC503", 0}, /* ARM CoreSight Debug */ - {"ARMHC979", 0}, /* ARM CoreSight TPIU */ - {"ARMHC97C", 0}, /* ARM CoreSight SoC-400 TMC, SoC-600 ETF/ETB */ - {"ARMHC98D", 0}, /* ARM CoreSight Dynamic Replicator */ - {"ARMHC9CA", 0}, /* ARM CoreSight CATU */ - {"ARMHC9FF", 0}, /* ARM CoreSight Dynamic Funnel */ - {"", 0}, -}; - -static void amba_register_dummy_clk(void) -{ - static struct clk *amba_dummy_clk; - - /* If clock already registered */ - if (amba_dummy_clk) - return; - - amba_dummy_clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, 0, 0); - clk_register_clkdev(amba_dummy_clk, "apb_pclk", NULL); -} - -static int amba_handler_attach(struct acpi_device *adev, - const struct acpi_device_id *id) -{ - struct acpi_device *parent = acpi_dev_parent(adev); - struct amba_device *dev; - struct resource_entry *rentry; - struct list_head resource_list; - bool address_found = false; - int irq_no = 0; - int ret; - - /* If the ACPI node already has a physical device attached, skip it. */ - if (adev->physical_node_count) - return 0; - - dev = amba_device_alloc(dev_name(&adev->dev), 0, 0); - if (!dev) { - dev_err(&adev->dev, "%s(): amba_device_alloc() failed\n", - __func__); - return -ENOMEM; - } - - INIT_LIST_HEAD(&resource_list); - ret = acpi_dev_get_resources(adev, &resource_list, NULL, NULL); - if (ret < 0) - goto err_free; - - list_for_each_entry(rentry, &resource_list, node) { - switch (resource_type(rentry->res)) { - case IORESOURCE_MEM: - if (!address_found) { - dev->res = *rentry->res; - dev->res.name = dev_name(&dev->dev); - address_found = true; - } - break; - case IORESOURCE_IRQ: - if (irq_no < AMBA_NR_IRQS) - dev->irq[irq_no++] = rentry->res->start; - break; - default: - dev_warn(&adev->dev, "Invalid resource\n"); - break; - } - } - - acpi_dev_free_resource_list(&resource_list); - - /* - * If the ACPI node has a parent and that parent has a physical device - * attached to it, that physical device should be the parent of - * the amba device we are about to create. - */ - if (parent) - dev->dev.parent = acpi_get_first_physical_node(parent); - - ACPI_COMPANION_SET(&dev->dev, adev); - - ret = amba_device_add(dev, &iomem_resource); - if (ret) { - dev_err(&adev->dev, "%s(): amba_device_add() failed (%d)\n", - __func__, ret); - goto err_free; - } - - return 1; - -err_free: - amba_device_put(dev); - return ret; -} - -static struct acpi_scan_handler amba_handler = { - .ids = amba_id_list, - .attach = amba_handler_attach, -}; - -void __init acpi_amba_init(void) -{ - amba_register_dummy_clk(); - acpi_scan_add_handler(&amba_handler); -} diff --git a/drivers/acpi/arm64/Makefile b/drivers/acpi/arm64/Makefile index f81fe24894b2..143debc1ba4a 100644 --- a/drivers/acpi/arm64/Makefile +++ b/drivers/acpi/arm64/Makefile @@ -3,4 +3,5 @@ obj-$(CONFIG_ACPI_AGDI) += agdi.o obj-$(CONFIG_ACPI_IORT) += iort.o obj-$(CONFIG_ACPI_GTDT) += gtdt.o obj-$(CONFIG_ACPI_APMT) += apmt.o +obj-$(CONFIG_ARM_AMBA) += amba.o obj-y += dma.o init.o diff --git a/drivers/acpi/arm64/amba.c b/drivers/acpi/arm64/amba.c new file mode 100644 index 000000000000..b2a7631d7ac7 --- /dev/null +++ b/drivers/acpi/arm64/amba.c @@ -0,0 +1,130 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/* + * ACPI support for platform bus type. + * + * Copyright (C) 2015, Linaro Ltd + * Author: Graeme Gregory + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "init.h" + +static const struct acpi_device_id amba_id_list[] = { + {"ARMH0061", 0}, /* PL061 GPIO Device */ + {"ARMH0330", 0}, /* ARM DMA Controller DMA-330 */ + {"ARMHC500", 0}, /* ARM CoreSight ETM4x */ + {"ARMHC501", 0}, /* ARM CoreSight ETR */ + {"ARMHC502", 0}, /* ARM CoreSight STM */ + {"ARMHC503", 0}, /* ARM CoreSight Debug */ + {"ARMHC979", 0}, /* ARM CoreSight TPIU */ + {"ARMHC97C", 0}, /* ARM CoreSight SoC-400 TMC, SoC-600 ETF/ETB */ + {"ARMHC98D", 0}, /* ARM CoreSight Dynamic Replicator */ + {"ARMHC9CA", 0}, /* ARM CoreSight CATU */ + {"ARMHC9FF", 0}, /* ARM CoreSight Dynamic Funnel */ + {"", 0}, +}; + +static void amba_register_dummy_clk(void) +{ + static struct clk *amba_dummy_clk; + + /* If clock already registered */ + if (amba_dummy_clk) + return; + + amba_dummy_clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, 0, 0); + clk_register_clkdev(amba_dummy_clk, "apb_pclk", NULL); +} + +static int amba_handler_attach(struct acpi_device *adev, + const struct acpi_device_id *id) +{ + struct acpi_device *parent = acpi_dev_parent(adev); + struct amba_device *dev; + struct resource_entry *rentry; + struct list_head resource_list; + bool address_found = false; + int irq_no = 0; + int ret; + + /* If the ACPI node already has a physical device attached, skip it. */ + if (adev->physical_node_count) + return 0; + + dev = amba_device_alloc(dev_name(&adev->dev), 0, 0); + if (!dev) { + dev_err(&adev->dev, "%s(): amba_device_alloc() failed\n", + __func__); + return -ENOMEM; + } + + INIT_LIST_HEAD(&resource_list); + ret = acpi_dev_get_resources(adev, &resource_list, NULL, NULL); + if (ret < 0) + goto err_free; + + list_for_each_entry(rentry, &resource_list, node) { + switch (resource_type(rentry->res)) { + case IORESOURCE_MEM: + if (!address_found) { + dev->res = *rentry->res; + dev->res.name = dev_name(&dev->dev); + address_found = true; + } + break; + case IORESOURCE_IRQ: + if (irq_no < AMBA_NR_IRQS) + dev->irq[irq_no++] = rentry->res->start; + break; + default: + dev_warn(&adev->dev, "Invalid resource\n"); + break; + } + } + + acpi_dev_free_resource_list(&resource_list); + + /* + * If the ACPI node has a parent and that parent has a physical device + * attached to it, that physical device should be the parent of + * the amba device we are about to create. + */ + if (parent) + dev->dev.parent = acpi_get_first_physical_node(parent); + + ACPI_COMPANION_SET(&dev->dev, adev); + + ret = amba_device_add(dev, &iomem_resource); + if (ret) { + dev_err(&adev->dev, "%s(): amba_device_add() failed (%d)\n", + __func__, ret); + goto err_free; + } + + return 1; + +err_free: + amba_device_put(dev); + return ret; +} + +static struct acpi_scan_handler amba_handler = { + .ids = amba_id_list, + .attach = amba_handler_attach, +}; + +void __init acpi_amba_init(void) +{ + amba_register_dummy_clk(); + acpi_scan_add_handler(&amba_handler); +} diff --git a/drivers/acpi/arm64/init.c b/drivers/acpi/arm64/init.c index d3ce53dda122..d0c8aed90fd1 100644 --- a/drivers/acpi/arm64/init.c +++ b/drivers/acpi/arm64/init.c @@ -10,4 +10,6 @@ void __init acpi_arm_init(void) acpi_apmt_init(); if (IS_ENABLED(CONFIG_ACPI_IORT)) acpi_iort_init(); + if (IS_ENABLED(CONFIG_ARM_AMBA)) + acpi_amba_init(); } diff --git a/drivers/acpi/arm64/init.h b/drivers/acpi/arm64/init.h index a1715a2a34e9..dcc277977194 100644 --- a/drivers/acpi/arm64/init.h +++ b/drivers/acpi/arm64/init.h @@ -4,3 +4,4 @@ void __init acpi_agdi_init(void); void __init acpi_apmt_init(void); void __init acpi_iort_init(void); +void __init acpi_amba_init(void); diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index f4148dc50b9c..21ec31b78216 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -28,11 +28,6 @@ void acpi_processor_init(void); void acpi_platform_init(void); void acpi_pnp_init(void); void acpi_int340x_thermal_init(void); -#ifdef CONFIG_ARM_AMBA -void acpi_amba_init(void); -#else -static inline void acpi_amba_init(void) {} -#endif int acpi_sysfs_init(void); void acpi_gpe_apply_masked_gpes(void); void acpi_container_init(void); diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 5b145f1aaa1b..902763430d56 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -2615,7 +2615,6 @@ void __init acpi_scan_init(void) acpi_watchdog_init(); acpi_pnp_init(); acpi_int340x_thermal_init(); - acpi_amba_init(); acpi_init_lpit(); acpi_scan_add_handler(&generic_device_handler); -- cgit v1.2.3 From 7f6fd06d34f4a9bd62bc30e9232934cfb89ae4d8 Mon Sep 17 00:00:00 2001 From: Wentong Wu Date: Sat, 29 Jul 2023 19:52:55 +0800 Subject: ACPI: scan: Defer enumeration of devices with a _DEP pointing to IVSC device Inside IVSC, switching ownership requires an interface with two different hardware modules, ACE and CSI. The software interface to these modules is based on Intel MEI framework. Usually mei client devices are dynamically created, so the info of consumers depending on mei client devices is not present in the firmware tables. This causes problems with the probe ordering with respect to drivers for consumers of these MEI client devices. But on these camera sensor devices, the ACPI nodes describing the sensors all have a _DEP dependency on the matching MEI bus ACPI device, so adding IVSC MEI bus ACPI device to acpi_honor_dep_ids allows solving the probe-ordering problem by deferring the enumeration of ACPI-devices which have a _DEP dependency on an IVSC mei bus ACPI device. On TGL platform, the HID of IVSC MEI bus ACPI device is INTC1059, and on ADL platform, the HID is INTC1095. So add both of them to acpi_honor_dep_ids. Signed-off-by: Wentong Wu Reviewed-by: Sakari Ailus [ rjw: Subject and changelog edits ] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 87e385542576..c799b03d0369 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -795,6 +795,9 @@ static const char * const acpi_ignore_dep_ids[] = { /* List of HIDs for which we honor deps of matching ACPI devs, when checking _DEP lists. */ static const char * const acpi_honor_dep_ids[] = { "INT3472", /* Camera sensor PMIC / clk and regulator info */ + "INTC1059", /* IVSC (TGL) driver must be loaded to allow i2c access to camera sensors */ + "INTC1095", /* IVSC (ADL) driver must be loaded to allow i2c access to camera sensors */ + "INTC100A", /* IVSC (RPL) driver must be loaded to allow i2c access to camera sensors */ NULL }; -- cgit v1.2.3 From 588b51ddc7dc96c4876e71bc155bd38a6bd59a14 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Sat, 22 Jul 2023 10:55:05 +0800 Subject: ACPI: Remove unused extern declaration acpi_paddr_to_node() This is never used since commit 1e3590e2e4a3 ("[PATCH] pgdat allocation for new node add (get node id by acpi)"). Signed-off-by: YueHaibing Signed-off-by: Rafael J. Wysocki --- include/linux/acpi.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 641dc4843987..58a0fdf68ca2 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -477,8 +477,6 @@ static inline int acpi_get_node(acpi_handle handle) return 0; } #endif -extern int acpi_paddr_to_node(u64 start_addr, u64 size); - extern int pnpacpi_disabled; #define PXM_INVAL (-1) -- cgit v1.2.3 From ae769fbd143d9f9349387f27bb4f36d2ba5b45df Mon Sep 17 00:00:00 2001 From: Xiaochun Lee Date: Wed, 2 Aug 2023 21:47:46 +0800 Subject: ACPI: extlog: Fix finding the generic error data for v3 structure Fix by using acpi_hest_get_payload() to find out the correct generic error data for v3 structure. The revision v300 generic error data is different from the old one, so for compatibility with old and new version, change to a new interface to locate the right memory error section that was defined in CPER. Signed-off-by: Xiaochun Lee Reviewed-by: Tony Luck Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_extlog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c index e648158368a7..e120a96e1eae 100644 --- a/drivers/acpi/acpi_extlog.c +++ b/drivers/acpi/acpi_extlog.c @@ -172,7 +172,7 @@ static int extlog_print(struct notifier_block *nb, unsigned long val, fru_text = ""; sec_type = (guid_t *)gdata->section_type; if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) { - struct cper_sec_mem_err *mem = (void *)(gdata + 1); + struct cper_sec_mem_err *mem = acpi_hest_get_payload(gdata); if (gdata->error_data_length >= sizeof(*mem)) trace_extlog_mem_event(mem, err_seq, fru_id, fru_text, -- cgit v1.2.3 From 638f139fda4f4fcb1b244b4ac755a4c4f0a6c4a2 Mon Sep 17 00:00:00 2001 From: Yue Haibing Date: Mon, 14 Aug 2023 21:56:23 +0800 Subject: ACPI: Remove assorted unused declarations of functions acpi_create_dir()/acpi_remove_dir() are never implemented since the beginning of git history. Commit f8d31489629c ("ACPICA: Debugger: Convert some mechanisms to OSPM specific") declared but never implemented acpi_run_debugger(). Commit 781d737c7466 ("ACPI: Drop power resources driver") removed acpi_power_init() but not its declaration. Signed-off-by: Yue Haibing [ rjw: Subject edits ] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/internal.h | 1 - include/acpi/acpi_bus.h | 2 -- include/acpi/acpixf.h | 2 -- 3 files changed, 5 deletions(-) diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 21ec31b78216..956aed5afded 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -123,7 +123,6 @@ int __acpi_device_uevent_modalias(const struct acpi_device *adev, /* -------------------------------------------------------------------------- Power Resource -------------------------------------------------------------------------- */ -int acpi_power_init(void); void acpi_power_resources_list_free(struct list_head *list); int acpi_extract_power_resources(union acpi_object *package, unsigned int start, struct list_head *list); diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index c941d99162c0..449ec8a015bf 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -563,8 +563,6 @@ int acpi_match_device_ids(struct acpi_device *device, const struct acpi_device_id *ids); void acpi_set_modalias(struct acpi_device *adev, const char *default_id, char *modalias, size_t len); -int acpi_create_dir(struct acpi_device *); -void acpi_remove_dir(struct acpi_device *); static inline bool acpi_device_enumerated(struct acpi_device *adev) { diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 9ffdc0425bc2..cb64010cc5d8 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -970,8 +970,6 @@ ACPI_EXTERNAL_RETURN_STATUS(acpi_status void **data, void (*callback)(void *))) -void acpi_run_debugger(char *batch_buffer); - void acpi_set_debugger_thread_id(acpi_thread_id thread_id); #endif /* __ACXFACE_H__ */ -- cgit v1.2.3 From 596ca52a56da1b9370d358c38acf2ba5251687d9 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Sat, 29 Jul 2023 12:20:50 +0800 Subject: 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 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 [ rjw: Subject and changelog edits, whitespace adjustment ] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_cmos_rtc.c | 25 ++++++++++++++++++------- drivers/acpi/acpi_tad.c | 27 ++++++++++++++++++++++----- include/acpi/acpi_bus.h | 9 +++++++++ 3 files changed, 49 insertions(+), 12 deletions(-) diff --git a/drivers/acpi/acpi_cmos_rtc.c b/drivers/acpi/acpi_cmos_rtc.c index 4cf4aef7ce0c..9b55d1593d16 100644 --- a/drivers/acpi/acpi_cmos_rtc.c +++ b/drivers/acpi/acpi_cmos_rtc.c @@ -51,12 +51,11 @@ acpi_cmos_rtc_space_handler(u32 function, acpi_physical_address address, return AE_OK; } -static int acpi_install_cmos_rtc_space_handler(struct acpi_device *adev, - const struct acpi_device_id *id) +int acpi_install_cmos_rtc_space_handler(acpi_handle handle) { acpi_status status; - status = acpi_install_address_space_handler(adev->handle, + status = acpi_install_address_space_handler(handle, ACPI_ADR_SPACE_CMOS, &acpi_cmos_rtc_space_handler, NULL, NULL); @@ -67,18 +66,30 @@ static int acpi_install_cmos_rtc_space_handler(struct acpi_device *adev, return 1; } +EXPORT_SYMBOL_GPL(acpi_install_cmos_rtc_space_handler); -static void acpi_remove_cmos_rtc_space_handler(struct acpi_device *adev) +void acpi_remove_cmos_rtc_space_handler(acpi_handle handle) { - if (ACPI_FAILURE(acpi_remove_address_space_handler(adev->handle, + if (ACPI_FAILURE(acpi_remove_address_space_handler(handle, ACPI_ADR_SPACE_CMOS, &acpi_cmos_rtc_space_handler))) pr_err("Error removing CMOS-RTC region handler\n"); } +EXPORT_SYMBOL_GPL(acpi_remove_cmos_rtc_space_handler); + +static int acpi_cmos_rtc_attach_handler(struct acpi_device *adev, const struct acpi_device_id *id) +{ + return acpi_install_cmos_rtc_space_handler(adev->handle); +} + +static void acpi_cmos_rtc_detach_handler(struct acpi_device *adev) +{ + acpi_remove_cmos_rtc_space_handler(adev->handle); +} static struct acpi_scan_handler cmos_rtc_handler = { .ids = acpi_cmos_rtc_ids, - .attach = acpi_install_cmos_rtc_space_handler, - .detach = acpi_remove_cmos_rtc_space_handler, + .attach = acpi_cmos_rtc_attach_handler, + .detach = acpi_cmos_rtc_detach_handler, }; void __init acpi_cmos_rtc_init(void) diff --git a/drivers/acpi/acpi_tad.c b/drivers/acpi/acpi_tad.c index e9b8e8305e23..33c3b16af556 100644 --- a/drivers/acpi/acpi_tad.c +++ b/drivers/acpi/acpi_tad.c @@ -557,6 +557,7 @@ static int acpi_tad_disable_timer(struct device *dev, u32 timer_id) static int acpi_tad_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; + acpi_handle handle = ACPI_HANDLE(dev); struct acpi_tad_driver_data *dd = dev_get_drvdata(dev); device_init_wakeup(dev, false); @@ -577,6 +578,7 @@ static int acpi_tad_remove(struct platform_device *pdev) pm_runtime_put_sync(dev); pm_runtime_disable(dev); + acpi_remove_cmos_rtc_space_handler(handle); return 0; } @@ -589,6 +591,11 @@ static int acpi_tad_probe(struct platform_device *pdev) unsigned long long caps; int ret; + ret = acpi_install_cmos_rtc_space_handler(handle); + if (ret < 0) { + dev_info(dev, "Unable to install space handler\n"); + return -ENODEV; + } /* * Initialization failure messages are mostly about firmware issues, so * print them at the "info" level. @@ -596,22 +603,27 @@ static int acpi_tad_probe(struct platform_device *pdev) status = acpi_evaluate_integer(handle, "_GCP", NULL, &caps); if (ACPI_FAILURE(status)) { dev_info(dev, "Unable to get capabilities\n"); - return -ENODEV; + ret = -ENODEV; + goto remove_handler; } if (!(caps & ACPI_TAD_AC_WAKE)) { dev_info(dev, "Unsupported capabilities\n"); - return -ENODEV; + ret = -ENODEV; + goto remove_handler; } if (!acpi_has_method(handle, "_PRW")) { dev_info(dev, "Missing _PRW\n"); - return -ENODEV; + ret = -ENODEV; + goto remove_handler; } dd = devm_kzalloc(dev, sizeof(*dd), GFP_KERNEL); - if (!dd) - return -ENOMEM; + if (!dd) { + ret = -ENOMEM; + goto remove_handler; + } dd->capabilities = caps; dev_set_drvdata(dev, dd); @@ -653,6 +665,11 @@ static int acpi_tad_probe(struct platform_device *pdev) fail: acpi_tad_remove(pdev); + /* Don't fallthrough because cmos rtc space handler is removed in acpi_tad_remove() */ + return ret; + +remove_handler: + acpi_remove_cmos_rtc_space_handler(handle); return ret; } diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index c941d99162c0..fb95fff23e5b 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -645,6 +645,8 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev); #ifdef CONFIG_X86 bool acpi_device_override_status(struct acpi_device *adev, unsigned long long *status); bool acpi_quirk_skip_acpi_ac_and_battery(void); +int acpi_install_cmos_rtc_space_handler(acpi_handle handle); +void acpi_remove_cmos_rtc_space_handler(acpi_handle handle); #else static inline bool acpi_device_override_status(struct acpi_device *adev, unsigned long long *status) @@ -655,6 +657,13 @@ static inline bool acpi_quirk_skip_acpi_ac_and_battery(void) { return false; } +static inline int acpi_install_cmos_rtc_space_handler(acpi_handle handle) +{ + return 1; +} +static inline void acpi_remove_cmos_rtc_space_handler(acpi_handle handle) +{ +} #endif #if IS_ENABLED(CONFIG_X86_ANDROID_TABLETS) -- cgit v1.2.3