lkml.org 
[lkml]   [2020]   [Sep]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v8 1/6] i2c: Allow an ACPI driver to manage the device's power state during probe
    Date
    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_FL_ALLOW_LOW_POWER_PROBE to tell a driver supports probe in
    low power state.

    Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
    ---
    drivers/i2c/i2c-core-base.c | 19 ++++++++++++++++---
    include/linux/i2c.h | 14 ++++++++++++++
    2 files changed, 30 insertions(+), 3 deletions(-)

    diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
    index 5ec082e2039d9..cfb1e777c6196 100644
    --- a/drivers/i2c/i2c-core-base.c
    +++ b/drivers/i2c/i2c-core-base.c
    @@ -436,6 +436,16 @@ static int i2c_smbus_host_notify_to_irq(const struct i2c_client *client)
    return irq > 0 ? irq : -ENXIO;
    }

    +static bool allow_low_power_probe(struct device *dev)
    +{
    + struct i2c_driver *driver = to_i2c_driver(dev->driver);
    +
    + return driver->flags & I2C_DRV_FL_ALLOW_LOW_POWER_PROBE &&
    + !acpi_dev_get_property(ACPI_COMPANION(dev),
    + "i2c-allow-low-power-probe",
    + ACPI_TYPE_ANY, NULL);
    +}
    +
    static int i2c_device_probe(struct device *dev)
    {
    struct i2c_client *client = i2c_verify_client(dev);
    @@ -514,7 +524,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,
    + !allow_low_power_probe(&client->dev));
    if (status)
    goto err_clear_wakeup_irq;

    @@ -536,7 +547,8 @@ static int i2c_device_probe(struct device *dev)
    return 0;

    err_detach_pm_domain:
    - dev_pm_domain_detach(&client->dev, true);
    + dev_pm_domain_detach(&client->dev,
    + !allow_low_power_probe(&client->dev));
    err_clear_wakeup_irq:
    dev_pm_clear_wake_irq(&client->dev);
    device_init_wakeup(&client->dev, false);
    @@ -562,7 +574,8 @@ static int i2c_device_remove(struct device *dev)
    status = driver->remove(client);
    }

    - dev_pm_domain_detach(&client->dev, true);
    + dev_pm_domain_detach(&client->dev,
    + !allow_low_power_probe(&client->dev));

    dev_pm_clear_wake_irq(&client->dev);
    device_init_wakeup(&client->dev, false);
    diff --git a/include/linux/i2c.h b/include/linux/i2c.h
    index fc55ea41d3237..f8c3257a8bb25 100644
    --- a/include/linux/i2c.h
    +++ b/include/linux/i2c.h
    @@ -11,6 +11,7 @@
    #define _LINUX_I2C_H

    #include <linux/acpi.h> /* for acpi_handle */
    +#include <linux/bits.h>
    #include <linux/mod_devicetable.h>
    #include <linux/device.h> /* for struct device */
    #include <linux/sched.h> /* for completion */
    @@ -217,6 +218,16 @@ enum i2c_alert_protocol {
    I2C_PROTOCOL_SMBUS_HOST_NOTIFY,
    };

    +/**
    + * enum i2c_driver_flags - Flags for an I2C device driver
    + *
    + * @I2C_DRV_FL_ALLOW_LOW_POWER_PROBE: Let the ACPI driver manage the device's
    + * power state during probe and remove
    + */
    +enum i2c_driver_flags {
    + I2C_DRV_FL_ALLOW_LOW_POWER_PROBE = BIT(0),
    +};
    +
    /**
    * struct i2c_driver - represent an I2C device driver
    * @class: What kind of i2c device we instantiate (for detect)
    @@ -231,6 +242,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.
    @@ -289,6 +301,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)

    --
    2.20.1
    \
     
     \ /
      Last update: 2020-09-03 10:16    [W:2.921 / U:0.076 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site