From b340c7d6f619ad63d1896a6debceea1de3a78f29 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 18 Oct 2021 15:17:24 +0300 Subject: ACPI: scan: Obtain device's desired enumeration power state Store a device's desired enumeration power state in struct acpi_device_power during acpi_device object's initialisation. Signed-off-by: Sakari Ailus Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index dce2c291b982..a50f1967c73d 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1017,6 +1017,7 @@ static void acpi_bus_init_power_state(struct acpi_device *device, int state) static void acpi_bus_get_power_flags(struct acpi_device *device) { + unsigned long long dsc = ACPI_STATE_D0; u32 i; /* Presence of _PS0|_PR0 indicates 'power manageable' */ @@ -1038,6 +1039,9 @@ static void acpi_bus_get_power_flags(struct acpi_device *device) if (acpi_has_method(device->handle, "_DSW")) device->power.flags.dsw_present = 1; + acpi_evaluate_integer(device->handle, "_DSC", NULL, &dsc); + device->power.state_for_enumeration = dsc; + /* * Enumerate supported power management states */ -- cgit v1.2.3 From b18c1ad685d9a6af5189d4cc037a653270a07b4c Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 18 Oct 2021 15:17:25 +0300 Subject: i2c: Allow an ACPI driver to manage the device's power state during probe Enable drivers to tell ACPI that there's no need to power on a device for probe. Drivers should still perform this by themselves if there's a need to. In some cases powering on the device during probe is undesirable, and this change enables a driver to choose what fits best for it. Add a field called "flags" into struct i2c_driver for driver flags, and a flag I2C_DRV_ACPI_WAIVE_D0_PROBE to tell a driver supports probe in ACPI D states other than 0. Signed-off-by: Sakari Ailus Reviewed-by: Tomasz Figa Acked-by: Wolfram Sang Signed-off-by: Rafael J. Wysocki --- drivers/i2c/i2c-core-acpi.c | 10 ++++++++++ drivers/i2c/i2c-core-base.c | 7 ++++--- include/linux/i2c.h | 18 ++++++++++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c index 546cc935e035..c025919cdaae 100644 --- a/drivers/i2c/i2c-core-acpi.c +++ b/drivers/i2c/i2c-core-acpi.c @@ -526,6 +526,16 @@ struct i2c_client *i2c_acpi_new_device(struct device *dev, int index, } EXPORT_SYMBOL_GPL(i2c_acpi_new_device); +bool i2c_acpi_waive_d0_probe(struct device *dev) +{ + struct i2c_driver *driver = to_i2c_driver(dev->driver); + struct acpi_device *adev = ACPI_COMPANION(dev); + + return driver->flags & I2C_DRV_ACPI_WAIVE_D0_PROBE && + adev && adev->power.state_for_enumeration >= adev->power.state; +} +EXPORT_SYMBOL_GPL(i2c_acpi_waive_d0_probe); + #ifdef CONFIG_ACPI_I2C_OPREGION static int acpi_gsb_i2c_read_bytes(struct i2c_client *client, u8 cmd, u8 *data, u8 data_len) diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index 54964fbe3f03..f193f9058584 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -551,7 +551,8 @@ static int i2c_device_probe(struct device *dev) if (status < 0) goto err_clear_wakeup_irq; - status = dev_pm_domain_attach(&client->dev, true); + status = dev_pm_domain_attach(&client->dev, + !i2c_acpi_waive_d0_probe(dev)); if (status) goto err_clear_wakeup_irq; @@ -590,7 +591,7 @@ static int i2c_device_probe(struct device *dev) err_release_driver_resources: devres_release_group(&client->dev, client->devres_group_id); err_detach_pm_domain: - dev_pm_domain_detach(&client->dev, true); + dev_pm_domain_detach(&client->dev, !i2c_acpi_waive_d0_probe(dev)); err_clear_wakeup_irq: dev_pm_clear_wake_irq(&client->dev); device_init_wakeup(&client->dev, false); @@ -621,7 +622,7 @@ static void i2c_device_remove(struct device *dev) devres_release_group(&client->dev, client->devres_group_id); - dev_pm_domain_detach(&client->dev, true); + dev_pm_domain_detach(&client->dev, !i2c_acpi_waive_d0_probe(dev)); if (!pm_runtime_status_suspended(&client->dev) && adap->bus_regulator) regulator_disable(adap->bus_regulator); diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 2ce3efbe9198..16119ac1aa97 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -11,6 +11,7 @@ #define _LINUX_I2C_H #include /* for acpi_handle */ +#include #include #include /* for struct device */ #include /* for completion */ @@ -222,6 +223,15 @@ enum i2c_alert_protocol { I2C_PROTOCOL_SMBUS_HOST_NOTIFY, }; +/** + * enum i2c_driver_flags - Flags for an I2C device driver + * + * @I2C_DRV_ACPI_WAIVE_D0_PROBE: Don't put the device in D0 state for probe + */ +enum i2c_driver_flags { + I2C_DRV_ACPI_WAIVE_D0_PROBE = BIT(0), +}; + /** * struct i2c_driver - represent an I2C device driver * @class: What kind of i2c device we instantiate (for detect) @@ -236,6 +246,7 @@ enum i2c_alert_protocol { * @detect: Callback for device detection * @address_list: The I2C addresses to probe (for detect) * @clients: List of detected clients we created (for i2c-core use only) + * @flags: A bitmask of flags defined in &enum i2c_driver_flags * * The driver.owner field should be set to the module owner of this driver. * The driver.name field should be set to the name of this driver. @@ -294,6 +305,8 @@ struct i2c_driver { int (*detect)(struct i2c_client *client, struct i2c_board_info *info); const unsigned short *address_list; struct list_head clients; + + u32 flags; }; #define to_i2c_driver(d) container_of(d, struct i2c_driver, driver) @@ -1015,6 +1028,7 @@ u32 i2c_acpi_find_bus_speed(struct device *dev); struct i2c_client *i2c_acpi_new_device(struct device *dev, int index, struct i2c_board_info *info); struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle handle); +bool i2c_acpi_waive_d0_probe(struct device *dev); #else static inline bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares, struct acpi_resource_i2c_serialbus **i2c) @@ -1038,6 +1052,10 @@ static inline struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle ha { return NULL; } +static inline bool i2c_acpi_waive_d0_probe(struct device *dev) +{ + return false; +} #endif /* CONFIG_ACPI */ #endif /* _LINUX_I2C_H */ -- cgit v1.2.3 From b82a7df4a7f3841896aaec1ad81e654bc87b5989 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 18 Oct 2021 15:17:27 +0300 Subject: ACPI: Add a convenience function to tell a device is in D0 state Add a convenience function to tell whether a device is in D0 state, primarily for use in drivers' probe or remove functions on busses where the custom is to power on the device for the duration of both. Returns false on non-ACPI systems. Suggested-by: Mika Westerberg Signed-off-by: Sakari Ailus Reviewed-by: Tomasz Figa Signed-off-by: Rafael J. Wysocki --- drivers/acpi/device_pm.c | 26 ++++++++++++++++++++++++++ include/linux/acpi.h | 5 +++++ 2 files changed, 31 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 0028b6b51c87..19b33c028f35 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -1400,4 +1400,30 @@ bool acpi_storage_d3(struct device *dev) } EXPORT_SYMBOL_GPL(acpi_storage_d3); +/** + * acpi_dev_state_d0 - Tell if the device is in D0 power state + * @dev: Physical device the ACPI power state of which to check + * + * On a system without ACPI, return true. On a system with ACPI, return true if + * the current ACPI power state of the device is D0, or false otherwise. + * + * Note that the power state of a device is not well-defined after it has been + * passed to acpi_device_set_power() and before that function returns, so it is + * not valid to ask for the ACPI power state of the device in that time frame. + * + * This function is intended to be used in a driver's probe or remove + * function. See Documentation/firmware-guide/acpi/low-power-probe.rst for + * more information. + */ +bool acpi_dev_state_d0(struct device *dev) +{ + struct acpi_device *adev = ACPI_COMPANION(dev); + + if (!adev) + return true; + + return adev->power.state == ACPI_STATE_D0; +} +EXPORT_SYMBOL_GPL(acpi_dev_state_d0); + #endif /* CONFIG_PM */ diff --git a/include/linux/acpi.h b/include/linux/acpi.h index fbc2146050a4..df70fc27afd7 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -1016,6 +1016,7 @@ int acpi_subsys_runtime_suspend(struct device *dev); int acpi_subsys_runtime_resume(struct device *dev); int acpi_dev_pm_attach(struct device *dev, bool power_on); bool acpi_storage_d3(struct device *dev); +bool acpi_dev_state_d0(struct device *dev); #else static inline int acpi_subsys_runtime_suspend(struct device *dev) { return 0; } static inline int acpi_subsys_runtime_resume(struct device *dev) { return 0; } @@ -1027,6 +1028,10 @@ static inline bool acpi_storage_d3(struct device *dev) { return false; } +static inline bool acpi_dev_state_d0(struct device *dev) +{ + return true; +} #endif #if defined(CONFIG_ACPI) && defined(CONFIG_PM_SLEEP) -- cgit v1.2.3 From 434aa74bd770bc1a712c8431919eabe490dbe707 Mon Sep 17 00:00:00 2001 From: Rajmohan Mani Date: Mon, 18 Oct 2021 15:17:28 +0300 Subject: media: i2c: imx319: Support device probe in non-zero ACPI D state Tell ACPI device PM code that the driver supports the device being in non-zero ACPI D state when the driver's probe function is entered. Signed-off-by: Rajmohan Mani Signed-off-by: Sakari Ailus Reviewed-by: Tomasz Figa Reviewed-by: Bingbu Cao Signed-off-by: Rafael J. Wysocki --- drivers/media/i2c/imx319.c | 74 +++++++++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/media/i2c/imx319.c b/drivers/media/i2c/imx319.c index dba0854ab5aa..daa976858e29 100644 --- a/drivers/media/i2c/imx319.c +++ b/drivers/media/i2c/imx319.c @@ -140,6 +140,8 @@ struct imx319 { /* Streaming on/off */ bool streaming; + /* True if the device has been identified */ + bool identified; }; static const struct imx319_reg imx319_global_regs[] = { @@ -2084,6 +2086,31 @@ imx319_set_pad_format(struct v4l2_subdev *sd, return 0; } +/* Verify chip ID */ +static int imx319_identify_module(struct imx319 *imx319) +{ + struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd); + int ret; + u32 val; + + if (imx319->identified) + return 0; + + ret = imx319_read_reg(imx319, IMX319_REG_CHIP_ID, 2, &val); + if (ret) + return ret; + + if (val != IMX319_CHIP_ID) { + dev_err(&client->dev, "chip id mismatch: %x!=%x", + IMX319_CHIP_ID, val); + return -EIO; + } + + imx319->identified = true; + + return 0; +} + /* Start streaming */ static int imx319_start_streaming(struct imx319 *imx319) { @@ -2091,6 +2118,10 @@ static int imx319_start_streaming(struct imx319 *imx319) const struct imx319_reg_list *reg_list; int ret; + ret = imx319_identify_module(imx319); + if (ret) + return ret; + /* Global Setting */ reg_list = &imx319_global_setting; ret = imx319_write_regs(imx319, reg_list->regs, reg_list->num_of_regs); @@ -2206,26 +2237,6 @@ error: return ret; } -/* Verify chip ID */ -static int imx319_identify_module(struct imx319 *imx319) -{ - struct i2c_client *client = v4l2_get_subdevdata(&imx319->sd); - int ret; - u32 val; - - ret = imx319_read_reg(imx319, IMX319_REG_CHIP_ID, 2, &val); - if (ret) - return ret; - - if (val != IMX319_CHIP_ID) { - dev_err(&client->dev, "chip id mismatch: %x!=%x", - IMX319_CHIP_ID, val); - return -EIO; - } - - return 0; -} - static const struct v4l2_subdev_core_ops imx319_subdev_core_ops = { .subscribe_event = v4l2_ctrl_subdev_subscribe_event, .unsubscribe_event = v4l2_event_subdev_unsubscribe, @@ -2420,6 +2431,7 @@ out_err: static int imx319_probe(struct i2c_client *client) { struct imx319 *imx319; + bool full_power; int ret; u32 i; @@ -2432,11 +2444,14 @@ static int imx319_probe(struct i2c_client *client) /* Initialize subdev */ v4l2_i2c_subdev_init(&imx319->sd, client, &imx319_subdev_ops); - /* Check module identity */ - ret = imx319_identify_module(imx319); - if (ret) { - dev_err(&client->dev, "failed to find sensor: %d", ret); - goto error_probe; + full_power = acpi_dev_state_d0(&client->dev); + if (full_power) { + /* Check module identity */ + ret = imx319_identify_module(imx319); + if (ret) { + dev_err(&client->dev, "failed to find sensor: %d", ret); + goto error_probe; + } } imx319->hwcfg = imx319_get_hwcfg(&client->dev); @@ -2488,11 +2503,9 @@ static int imx319_probe(struct i2c_client *client) if (ret < 0) goto error_media_entity; - /* - * Device is already turned on by i2c-core with ACPI domain PM. - * Enable runtime PM and turn off the device. - */ - pm_runtime_set_active(&client->dev); + /* Set the device's state to active if it's in D0 state. */ + if (full_power) + pm_runtime_set_active(&client->dev); pm_runtime_enable(&client->dev); pm_runtime_idle(&client->dev); @@ -2545,6 +2558,7 @@ static struct i2c_driver imx319_i2c_driver = { }, .probe_new = imx319_probe, .remove = imx319_remove, + .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE, }; module_i2c_driver(imx319_i2c_driver); -- cgit v1.2.3 From 1e96078e0ae456cda0e02afd42b9a2b3734f45ba Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 18 Oct 2021 15:17:29 +0300 Subject: at24: Support probing while in non-zero ACPI D state In certain use cases (where the chip is part of a camera module, and the camera module is wired together with a camera privacy LED), powering on the device during probe is undesirable. Add support for the at24 to execute probe while being in ACPI D state other than 0 (which means fully powered on). Signed-off-by: Sakari Ailus Reviewed-by: Tomasz Figa Acked-by: Bartosz Golaszewski Signed-off-by: Rafael J. Wysocki --- drivers/misc/eeprom/at24.c | 45 +++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index 305ffad131a2..49ab656e8a96 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c @@ -595,6 +595,7 @@ static int at24_probe(struct i2c_client *client) bool i2c_fn_i2c, i2c_fn_block; unsigned int i, num_addresses; struct at24_data *at24; + bool full_power; struct regmap *regmap; bool writable; u8 test_byte; @@ -747,14 +748,16 @@ static int at24_probe(struct i2c_client *client) i2c_set_clientdata(client, at24); - err = regulator_enable(at24->vcc_reg); - if (err) { - dev_err(dev, "Failed to enable vcc regulator\n"); - return err; - } + full_power = acpi_dev_state_d0(&client->dev); + if (full_power) { + err = regulator_enable(at24->vcc_reg); + if (err) { + dev_err(dev, "Failed to enable vcc regulator\n"); + return err; + } - /* enable runtime pm */ - pm_runtime_set_active(dev); + pm_runtime_set_active(dev); + } pm_runtime_enable(dev); at24->nvmem = devm_nvmem_register(dev, &nvmem_config); @@ -766,15 +769,18 @@ static int at24_probe(struct i2c_client *client) } /* - * Perform a one-byte test read to verify that the - * chip is functional. + * Perform a one-byte test read to verify that the chip is functional, + * unless powering on the device is to be avoided during probe (i.e. + * it's powered off right now). */ - err = at24_read(at24, 0, &test_byte, 1); - if (err) { - pm_runtime_disable(dev); - if (!pm_runtime_status_suspended(dev)) - regulator_disable(at24->vcc_reg); - return -ENODEV; + if (full_power) { + err = at24_read(at24, 0, &test_byte, 1); + if (err) { + pm_runtime_disable(dev); + if (!pm_runtime_status_suspended(dev)) + regulator_disable(at24->vcc_reg); + return -ENODEV; + } } pm_runtime_idle(dev); @@ -794,9 +800,11 @@ static int at24_remove(struct i2c_client *client) struct at24_data *at24 = i2c_get_clientdata(client); pm_runtime_disable(&client->dev); - if (!pm_runtime_status_suspended(&client->dev)) - regulator_disable(at24->vcc_reg); - pm_runtime_set_suspended(&client->dev); + if (acpi_dev_state_d0(&client->dev)) { + if (!pm_runtime_status_suspended(&client->dev)) + regulator_disable(at24->vcc_reg); + pm_runtime_set_suspended(&client->dev); + } return 0; } @@ -833,6 +841,7 @@ static struct i2c_driver at24_driver = { .probe_new = at24_probe, .remove = at24_remove, .id_table = at24_ids, + .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE, }; static int __init at24_init(void) -- cgit v1.2.3 From eb794e3c6bf0890bc1039baa6bbf06e922cfa9a3 Mon Sep 17 00:00:00 2001 From: Binbin Zhou Date: Thu, 28 Oct 2021 21:44:32 +0800 Subject: ACPI: EC: Use ec_no_wakeup on HP ZHAN 66 Pro EC interrupts constantly wake up system from s2idle, so set ec_no_wakeup by default to keep the system in s2idle and reduce energy consumption. Signed-off-by: Binbin Zhou [ rjw: Changelog and subject edits ] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ec.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index e629e891d1bb..7c32da8f51ed 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -2152,6 +2152,13 @@ static const struct dmi_system_id acpi_ec_no_wakeup[] = { DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Yoga 3rd"), }, }, + { + .ident = "HP ZHAN 66 Pro", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_FAMILY, "103C_5336AN HP ZHAN 66 Pro"), + }, + }, { }, }; -- cgit v1.2.3 From 69cace6e187c44d8d51d35dcce7c399a34e0f8d6 Mon Sep 17 00:00:00 2001 From: wangzhitong Date: Wed, 3 Nov 2021 13:51:19 +0800 Subject: ACPI: EC: Remove initialization of static variables to false Remove the initialization of two static variables to false which is pointless. Signed-off-by: wangzhitong [ rjw: Subject and changelog ] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 7c32da8f51ed..a6366d3f0c78 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -133,7 +133,7 @@ static unsigned int ec_storm_threshold __read_mostly = 8; module_param(ec_storm_threshold, uint, 0644); MODULE_PARM_DESC(ec_storm_threshold, "Maxim false GPE numbers not considered as GPE storm"); -static bool ec_freeze_events __read_mostly = false; +static bool ec_freeze_events __read_mostly; module_param(ec_freeze_events, bool, 0644); MODULE_PARM_DESC(ec_freeze_events, "Disabling event handling during suspend/resume"); @@ -177,7 +177,7 @@ struct acpi_ec *first_ec; EXPORT_SYMBOL(first_ec); static struct acpi_ec *boot_ec; -static bool boot_ec_is_ecdt = false; +static bool boot_ec_is_ecdt; static struct workqueue_struct *ec_wq; static struct workqueue_struct *ec_query_wq; -- cgit v1.2.3 From 009a789443fe4c8e6b1ecb7c16b4865c026184cd Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 31 Oct 2021 16:31:35 +0100 Subject: ACPI: PMIC: Fix intel_pmic_regs_handler() read accesses The handling of PMIC register reads through writing 0 to address 4 of the OpRegion is wrong. Instead of returning the read value through the value64, which is a no-op for function == ACPI_WRITE calls, store the value and then on a subsequent function == ACPI_READ with address == 3 (the address for the value field of the OpRegion) return the stored value. This has been tested on a Xiaomi Mi Pad 2 and makes the ACPI battery dev there mostly functional (unfortunately there are still other issues). Here are the SET() / GET() functions of the PMIC ACPI device, which use this OpRegion, which clearly show the new behavior to be correct: OperationRegion (REGS, 0x8F, Zero, 0x50) Field (REGS, ByteAcc, NoLock, Preserve) { CLNT, 8, SA, 8, OFF, 8, VAL, 8, RWM, 8 } Method (GET, 3, Serialized) { If ((AVBE == One)) { CLNT = Arg0 SA = Arg1 OFF = Arg2 RWM = Zero If ((AVBG == One)) { GPRW = Zero } } Return (VAL) /* \_SB_.PCI0.I2C7.PMI5.VAL_ */ } Method (SET, 4, Serialized) { If ((AVBE == One)) { CLNT = Arg0 SA = Arg1 OFF = Arg2 VAL = Arg3 RWM = One If ((AVBG == One)) { GPRW = One } } } Fixes: 0afa877a5650 ("ACPI / PMIC: intel: add REGS operation region support") Signed-off-by: Hans de Goede Signed-off-by: Rafael J. Wysocki --- drivers/acpi/pmic/intel_pmic.c | 51 +++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/pmic/intel_pmic.c b/drivers/acpi/pmic/intel_pmic.c index a371f273f99d..9cde299eba88 100644 --- a/drivers/acpi/pmic/intel_pmic.c +++ b/drivers/acpi/pmic/intel_pmic.c @@ -211,31 +211,36 @@ static acpi_status intel_pmic_regs_handler(u32 function, void *handler_context, void *region_context) { struct intel_pmic_opregion *opregion = region_context; - int result = 0; + int result = -EINVAL; + + if (function == ACPI_WRITE) { + switch (address) { + case 0: + return AE_OK; + case 1: + opregion->ctx.addr |= (*value64 & 0xff) << 8; + return AE_OK; + case 2: + opregion->ctx.addr |= *value64 & 0xff; + return AE_OK; + case 3: + opregion->ctx.val = *value64 & 0xff; + return AE_OK; + case 4: + if (*value64) { + result = regmap_write(opregion->regmap, opregion->ctx.addr, + opregion->ctx.val); + } else { + result = regmap_read(opregion->regmap, opregion->ctx.addr, + &opregion->ctx.val); + } + opregion->ctx.addr = 0; + } + } - switch (address) { - case 0: - return AE_OK; - case 1: - opregion->ctx.addr |= (*value64 & 0xff) << 8; - return AE_OK; - case 2: - opregion->ctx.addr |= *value64 & 0xff; + if (function == ACPI_READ && address == 3) { + *value64 = opregion->ctx.val; return AE_OK; - case 3: - opregion->ctx.val = *value64 & 0xff; - return AE_OK; - case 4: - if (*value64) { - result = regmap_write(opregion->regmap, opregion->ctx.addr, - opregion->ctx.val); - } else { - result = regmap_read(opregion->regmap, opregion->ctx.addr, - &opregion->ctx.val); - if (result == 0) - *value64 = opregion->ctx.val; - } - memset(&opregion->ctx, 0x00, sizeof(opregion->ctx)); } if (result < 0) { -- cgit v1.2.3 From 3b6740bdd53cb3713642942c5476fcb6969d57d8 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 3 Nov 2021 15:26:19 +0100 Subject: ACPI: video: Drop dmi_system_id.ident settings from video_detect_dmi_table[] The .ident field of the dmi_system_id structs in the video_detect_dmi_table[] is not used by the code. Change all .ident = "..." assignments to comments, this reduces the size of video_detect.o / video.ko by about 1500 bytes. Signed-off-by: Hans de Goede Signed-off-by: Rafael J. Wysocki --- drivers/acpi/video_detect.c | 70 ++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 33474fd96991..7a1f8e823208 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -115,7 +115,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { */ { .callback = video_detect_force_vendor, - .ident = "X360", + /* X360 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), DMI_MATCH(DMI_PRODUCT_NAME, "X360"), @@ -124,7 +124,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_vendor, - .ident = "Asus UL30VT", + /* Asus UL30VT */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "UL30VT"), @@ -132,7 +132,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_vendor, - .ident = "Asus UL30A", + /* Asus UL30A */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"), @@ -140,7 +140,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_vendor, - .ident = "GIGABYTE GB-BXBT-2807", + /* GIGABYTE GB-BXBT-2807 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), DMI_MATCH(DMI_PRODUCT_NAME, "GB-BXBT-2807"), @@ -148,7 +148,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_vendor, - .ident = "Sony VPCEH3U1E", + /* Sony VPCEH3U1E */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), DMI_MATCH(DMI_PRODUCT_NAME, "VPCEH3U1E"), @@ -164,7 +164,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { */ { .callback = video_detect_force_video, - .ident = "ThinkPad T420", + /* ThinkPad T420 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T420"), @@ -172,7 +172,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_video, - .ident = "ThinkPad T520", + /* ThinkPad T520 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T520"), @@ -180,7 +180,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_video, - .ident = "ThinkPad X201s", + /* ThinkPad X201s */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X201s"), @@ -188,7 +188,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_video, - .ident = "ThinkPad X201T", + /* ThinkPad X201T */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X201T"), @@ -199,7 +199,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { { /* https://bugs.freedesktop.org/show_bug.cgi?id=81515 */ .callback = video_detect_force_video, - .ident = "HP ENVY 15 Notebook", + /* HP ENVY 15 Notebook */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), DMI_MATCH(DMI_PRODUCT_NAME, "HP ENVY 15 Notebook PC"), @@ -207,7 +207,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_video, - .ident = "SAMSUNG 870Z5E/880Z5E/680Z5E", + /* SAMSUNG 870Z5E/880Z5E/680Z5E */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), DMI_MATCH(DMI_PRODUCT_NAME, "870Z5E/880Z5E/680Z5E"), @@ -215,7 +215,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_video, - .ident = "SAMSUNG 370R4E/370R4V/370R5E/3570RE/370R5V", + /* SAMSUNG 370R4E/370R4V/370R5E/3570RE/370R5V */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), DMI_MATCH(DMI_PRODUCT_NAME, @@ -225,7 +225,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { { /* https://bugzilla.redhat.com/show_bug.cgi?id=1186097 */ .callback = video_detect_force_video, - .ident = "SAMSUNG 3570R/370R/470R/450R/510R/4450RV", + /* SAMSUNG 3570R/370R/470R/450R/510R/4450RV */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), DMI_MATCH(DMI_PRODUCT_NAME, @@ -235,7 +235,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { { /* https://bugzilla.redhat.com/show_bug.cgi?id=1557060 */ .callback = video_detect_force_video, - .ident = "SAMSUNG 670Z5E", + /* SAMSUNG 670Z5E */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), DMI_MATCH(DMI_PRODUCT_NAME, "670Z5E"), @@ -244,7 +244,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { { /* https://bugzilla.redhat.com/show_bug.cgi?id=1094948 */ .callback = video_detect_force_video, - .ident = "SAMSUNG 730U3E/740U3E", + /* SAMSUNG 730U3E/740U3E */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), DMI_MATCH(DMI_PRODUCT_NAME, "730U3E/740U3E"), @@ -253,7 +253,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { { /* https://bugs.freedesktop.org/show_bug.cgi?id=87286 */ .callback = video_detect_force_video, - .ident = "SAMSUNG 900X3C/900X3D/900X3E/900X4C/900X4D", + /* SAMSUNG 900X3C/900X3D/900X3E/900X4C/900X4D */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), DMI_MATCH(DMI_PRODUCT_NAME, @@ -263,7 +263,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { { /* https://bugzilla.redhat.com/show_bug.cgi?id=1272633 */ .callback = video_detect_force_video, - .ident = "Dell XPS14 L421X", + /* Dell XPS14 L421X */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "XPS L421X"), @@ -272,7 +272,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { { /* https://bugzilla.redhat.com/show_bug.cgi?id=1163574 */ .callback = video_detect_force_video, - .ident = "Dell XPS15 L521X", + /* Dell XPS15 L521X */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "XPS L521X"), @@ -281,7 +281,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { { /* https://bugzilla.kernel.org/show_bug.cgi?id=108971 */ .callback = video_detect_force_video, - .ident = "SAMSUNG 530U4E/540U4E", + /* SAMSUNG 530U4E/540U4E */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), DMI_MATCH(DMI_PRODUCT_NAME, "530U4E/540U4E"), @@ -290,7 +290,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { /* https://bugs.launchpad.net/bugs/1894667 */ { .callback = video_detect_force_video, - .ident = "HP 635 Notebook", + /* HP 635 Notebook */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), DMI_MATCH(DMI_PRODUCT_NAME, "HP 635 Notebook PC"), @@ -301,7 +301,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { { /* https://bugzilla.redhat.com/show_bug.cgi?id=1201530 */ .callback = video_detect_force_native, - .ident = "Lenovo Ideapad S405", + /* Lenovo Ideapad S405 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), DMI_MATCH(DMI_BOARD_NAME, "Lenovo IdeaPad S405"), @@ -310,7 +310,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { { /* https://bugzilla.redhat.com/show_bug.cgi?id=1187004 */ .callback = video_detect_force_native, - .ident = "Lenovo Ideapad Z570", + /* Lenovo Ideapad Z570 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_NAME, "102434U"), @@ -318,7 +318,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_native, - .ident = "Lenovo E41-25", + /* Lenovo E41-25 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_NAME, "81FS"), @@ -326,7 +326,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_native, - .ident = "Lenovo E41-45", + /* Lenovo E41-45 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_NAME, "82BK"), @@ -335,7 +335,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { { /* https://bugzilla.redhat.com/show_bug.cgi?id=1217249 */ .callback = video_detect_force_native, - .ident = "Apple MacBook Pro 12,1", + /* Apple MacBook Pro 12,1 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro12,1"), @@ -343,7 +343,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_native, - .ident = "Dell Vostro V131", + /* Dell Vostro V131 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V131"), @@ -352,7 +352,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { { /* https://bugzilla.redhat.com/show_bug.cgi?id=1123661 */ .callback = video_detect_force_native, - .ident = "Dell XPS 17 L702X", + /* Dell XPS 17 L702X */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "Dell System XPS L702X"), @@ -360,7 +360,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_native, - .ident = "Dell Precision 7510", + /* Dell Precision 7510 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "Precision 7510"), @@ -368,7 +368,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_native, - .ident = "Acer Aspire 5738z", + /* Acer Aspire 5738z */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Acer"), DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5738"), @@ -378,7 +378,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { { /* https://bugzilla.kernel.org/show_bug.cgi?id=207835 */ .callback = video_detect_force_native, - .ident = "Acer TravelMate 5735Z", + /* Acer TravelMate 5735Z */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Acer"), DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 5735Z"), @@ -387,7 +387,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_native, - .ident = "ASUSTeK COMPUTER INC. GA401", + /* ASUSTeK COMPUTER INC. GA401 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_MATCH(DMI_PRODUCT_NAME, "GA401"), @@ -395,7 +395,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_native, - .ident = "ASUSTeK COMPUTER INC. GA502", + /* ASUSTeK COMPUTER INC. GA502 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_MATCH(DMI_PRODUCT_NAME, "GA502"), @@ -403,7 +403,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_native, - .ident = "ASUSTeK COMPUTER INC. GA503", + /* ASUSTeK COMPUTER INC. GA503 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_MATCH(DMI_PRODUCT_NAME, "GA503"), @@ -416,7 +416,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { */ { .callback = video_detect_force_none, - .ident = "Dell OptiPlex 9020M", + /* Dell OptiPlex 9020M */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 9020M"), @@ -424,7 +424,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_none, - .ident = "MSI MS-7721", + /* MSI MS-7721 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "MSI"), DMI_MATCH(DMI_PRODUCT_NAME, "MS-7721"), -- cgit v1.2.3 From 60e6655f0a6c6e4604e4b89444e5fb8e3d43a67b Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 3 Nov 2021 15:26:20 +0100 Subject: ACPI: video: use platform backlight driver on Xiaomi Mi Pad 2 The Xiaomi Mi Pad 2 is a Cherry Trail based x86 tablet which does not use the i915's driver backlight control support: i915 0000:00:02.0: [drm:intel_panel_setup_backlight [i915]] no backlight present per VBT Like all Cherry Trail devices the ACPI tables on the Xiaomi Mi Pad 2 contain a broken ACPI-video implementation which causes 6 different acpi_video backlights to get registered when used. The lack of the i915 driver registering a BACKLIGHT_RAW (aka native) type backlight causes acpi_video_get_backlight_type() to pick the broken acpi_video backlight code as the backlight driver to use. There actually is a separate lp8556 backlight controller connected over I2C which gets registered as a BACKLIGHT_PLATFORM (aka vendor). Add a quirk to force acpi_video_get_backlight_type() to return acpi_backlight_vendor, so that the broken acpi_video backlight interfaces do not get registered. Signed-off-by: Hans de Goede Signed-off-by: Rafael J. Wysocki --- drivers/acpi/video_detect.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 7a1f8e823208..068e393ea0c6 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -154,6 +154,14 @@ static const struct dmi_system_id video_detect_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "VPCEH3U1E"), }, }, + { + .callback = video_detect_force_vendor, + /* Xiaomi Mi Pad 2 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Xiaomi Inc"), + DMI_MATCH(DMI_PRODUCT_NAME, "Mipad2"), + }, + }, /* * These models have a working acpi_video backlight control, and using -- cgit v1.2.3 From 452a3e723f75880757acf87b053935c43aa89f89 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 4 Nov 2021 22:54:17 +0100 Subject: ACPI: PM: Fix device wakeup power reference counting error Fix a device wakeup power reference counting error introduced by commit a2d7b2e004af ("ACPI: PM: Fix sharing of wakeup power resources") because of a coding mistake. Fixes: a2d7b2e004af ("ACPI: PM: Fix sharing of wakeup power resources") Signed-off-by: Rafael J. Wysocki --- drivers/acpi/power.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 112256154880..5dcb02ededbc 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -757,13 +757,11 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev) mutex_lock(&acpi_device_lock); - if (dev->wakeup.prepare_count > 1) { - dev->wakeup.prepare_count--; + /* Do nothing if wakeup power has not been enabled for this device. */ + if (dev->wakeup.prepare_count <= 0) goto out; - } - /* Do nothing if wakeup power has not been enabled for this device. */ - if (!dev->wakeup.prepare_count) + if (--dev->wakeup.prepare_count > 0) goto out; err = acpi_device_sleep_wake(dev, 0, 0, 0); -- cgit v1.2.3