From d08a745729646f407277e904b02991458f20d261 Mon Sep 17 00:00:00 2001 From: Angela Czubak Date: Thu, 8 Apr 2021 12:37:59 +0200 Subject: resource: Prevent irqresource_disabled() from erasing flags Some Chromebooks use hard-coded interrupts in their ACPI tables. This is an excerpt as dumped on Relm: ... Name (_HID, "ELAN0001") // _HID: Hardware ID Name (_DDN, "Elan Touchscreen ") // _DDN: DOS Device Name Name (_UID, 0x05) // _UID: Unique ID Name (ISTP, Zero) Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings { Name (BUF0, ResourceTemplate () { I2cSerialBusV2 (0x0010, ControllerInitiated, 0x00061A80, AddressingMode7Bit, "\\_SB.I2C1", 0x00, ResourceConsumer, , Exclusive, ) Interrupt (ResourceConsumer, Edge, ActiveLow, Exclusive, ,, ) { 0x000000B8, } }) Return (BUF0) /* \_SB_.I2C1.ETSA._CRS.BUF0 */ } ... This interrupt is hard-coded to 0xB8 = 184 which is too high to be mapped to IO-APIC, so no triggering information is propagated as acpi_register_gsi() fails and irqresource_disabled() is issued, which leads to erasing triggering and polarity information. Do not overwrite flags as it leads to erasing triggering and polarity information which might be useful in case of hard-coded interrupts. This way the information can be read later on even though mapping to APIC domain failed. Signed-off-by: Angela Czubak [ rjw: Changelog rearrangement ] Signed-off-by: Rafael J. Wysocki --- include/linux/ioport.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 55de385c839c..647744d8514e 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -331,7 +331,7 @@ static inline void irqresource_disabled(struct resource *res, u32 irq) { res->start = irq; res->end = irq; - res->flags = IORESOURCE_IRQ | IORESOURCE_DISABLED | IORESOURCE_UNSET; + res->flags |= IORESOURCE_IRQ | IORESOURCE_DISABLED | IORESOURCE_UNSET; } extern struct address_space *iomem_get_mapping(void); -- cgit v1.2.3 From 4cbaba4e3e4a8a00ed90193ae519c52ba01ea756 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 13 Apr 2021 01:23:58 +0300 Subject: ACPI: bus: Introduce acpi_dev_get() and reuse it in ACPI code Introduce acpi_dev_get() to have a symmetrical API with acpi_dev_put() and reuse both in ACPI code in drivers/acpi/. While at it, use acpi_bus_put_acpi_device() in one place instead of the above. Signed-off-by: Andy Shevchenko Signed-off-by: Rafael J. Wysocki --- drivers/acpi/device_sysfs.c | 4 ++-- drivers/acpi/glue.c | 8 ++++---- drivers/acpi/scan.c | 9 ++++----- include/acpi/acpi_bus.h | 5 +++++ 4 files changed, 15 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/drivers/acpi/device_sysfs.c b/drivers/acpi/device_sysfs.c index da4ff2a8b06a..35757c3c1b71 100644 --- a/drivers/acpi/device_sysfs.c +++ b/drivers/acpi/device_sysfs.c @@ -376,12 +376,12 @@ eject_store(struct device *d, struct device_attribute *attr, if (ACPI_FAILURE(status) || !acpi_device->flags.ejectable) return -ENODEV; - get_device(&acpi_device->dev); + acpi_dev_get(acpi_device); status = acpi_hotplug_schedule(acpi_device, ACPI_OST_EC_OSPM_EJECT); if (ACPI_SUCCESS(status)) return count; - put_device(&acpi_device->dev); + acpi_dev_put(acpi_device); acpi_evaluate_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT, ACPI_OST_SC_NON_SPECIFIC_FAILURE, NULL); return status == AE_NO_MEMORY ? -ENOMEM : -EAGAIN; diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 36b24b0658cb..0715e3be99a0 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -190,7 +190,7 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev) if (!acpi_dev) return -EINVAL; - get_device(&acpi_dev->dev); + acpi_dev_get(acpi_dev); get_device(dev); physical_node = kzalloc(sizeof(*physical_node), GFP_KERNEL); if (!physical_node) { @@ -217,7 +217,7 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev) goto err; put_device(dev); - put_device(&acpi_dev->dev); + acpi_dev_put(acpi_dev); return 0; } if (pn->node_id == node_id) { @@ -257,7 +257,7 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev) err: ACPI_COMPANION_SET(dev, NULL); put_device(dev); - put_device(&acpi_dev->dev); + acpi_dev_put(acpi_dev); return retval; } EXPORT_SYMBOL_GPL(acpi_bind_one); @@ -285,7 +285,7 @@ int acpi_unbind_one(struct device *dev) ACPI_COMPANION_SET(dev, NULL); /* Drop references taken by acpi_bind_one(). */ put_device(dev); - put_device(&acpi_dev->dev); + acpi_dev_put(acpi_dev); kfree(entry); break; } diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 1dea11786ea9..5e0e8ec221c5 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -530,7 +530,7 @@ static void acpi_device_del_work_fn(struct work_struct *work_not_used) * used by the device. */ acpi_power_transition(adev, ACPI_STATE_D3_COLD); - put_device(&adev->dev); + acpi_dev_put(adev); } } @@ -604,8 +604,7 @@ EXPORT_SYMBOL(acpi_bus_get_device); static void get_acpi_device(void *dev) { - if (dev) - get_device(&((struct acpi_device *)dev)->dev); + acpi_dev_get(dev); } struct acpi_device *acpi_bus_get_acpi_device(acpi_handle handle) @@ -615,7 +614,7 @@ struct acpi_device *acpi_bus_get_acpi_device(acpi_handle handle) void acpi_bus_put_acpi_device(struct acpi_device *adev) { - put_device(&adev->dev); + acpi_dev_put(adev); } static struct acpi_device_bus_id *acpi_device_bus_id_match(const char *dev_id) @@ -2355,7 +2354,7 @@ int __init acpi_scan_init(void) acpi_detach_data(acpi_root->handle, acpi_scan_drop_device); acpi_device_del(acpi_root); - put_device(&acpi_root->dev); + acpi_bus_put_acpi_device(acpi_root); goto out; } } diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index f28b097c658f..c1c9adaed205 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -694,6 +694,11 @@ acpi_dev_get_first_match_dev(const char *hid, const char *uid, s64 hrv); adev; \ adev = acpi_dev_get_next_match_dev(adev, hid, uid, hrv)) +static inline struct acpi_device *acpi_dev_get(struct acpi_device *adev) +{ + return adev ? to_acpi_device(get_device(&adev->dev)) : NULL; +} + static inline void acpi_dev_put(struct acpi_device *adev) { put_device(&adev->dev); -- cgit v1.2.3