Re: [RFC PATCH 1/4] i2c: allow drivers to announce that they are IRQ safe

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Sep 3, 2018 at 8:21 PM Wolfram Sang <wsa@xxxxxxxxxxxxx> wrote:
>
>
> > Then I vote for extending the 'struct i2c_algorithm' with an extra
> > callback 'master_xfer_irqless'. The idea was already proposed here.
>
> Yes, I proposed the idea a few times and now I cooked up an RFC.
> Only build tested and merely a starter for discussion.
>

> Let me know what you think, people.

LGTM.
Though I would expect that call back optional, so, it means that I2C
core, perhaps, may put some generic one as a stub.

>
> ===
>
> From: Wolfram Sang <wsa@xxxxxxxxxxxxx>
> Subject: [RFC PATCH] i2c: introduce master_xfer_irqless callback
>
> We had the request to access devices very late when interrupts are not
> available anymore multiple times now. Mostly to prepare shutdown or
> reboot. Allow adapters to specify a specific callback for this case.
> Note that we fall back to the generic master_xfer callback if this new
> irqless one is not present. This is intentional to preserve the previous
> behaviour and avoid regressions. Because there are drivers not using
> interrupts or because it might have worked "accidently" before.
>
> Signed-off-by: Wolfram Sang <wsa@xxxxxxxxxxxxx>
> ---
>  drivers/i2c/i2c-core-base.c |  6 +++++-
>  include/linux/i2c.h         | 10 +++++++---
>  2 files changed, 12 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
> index 9ee9a15e7134..38dc7125293c 100644
> --- a/drivers/i2c/i2c-core-base.c
> +++ b/drivers/i2c/i2c-core-base.c
> @@ -1887,7 +1887,11 @@ int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
>         /* Retry automatically on arbitration loss */
>         orig_jiffies = jiffies;
>         for (ret = 0, try = 0; try <= adap->retries; try++) {
> -               ret = adap->algo->master_xfer(adap, msgs, num);
> +               if (in_atomic() || irqs_disabled())
> +                       ret = adap->algo->master_xfer_irqless(adap, msgs, num);
> +               else
> +                       ret = adap->algo->master_xfer(adap, msgs, num);
> +
>                 if (ret != -EAGAIN)
>                         break;
>                 if (time_after(jiffies, orig_jiffies + adap->timeout))
> diff --git a/include/linux/i2c.h b/include/linux/i2c.h
> index 65b4eaed1d96..11e615123bd0 100644
> --- a/include/linux/i2c.h
> +++ b/include/linux/i2c.h
> @@ -498,6 +498,8 @@ i2c_register_board_info(int busnum, struct i2c_board_info const *info,
>   * @master_xfer: Issue a set of i2c transactions to the given I2C adapter
>   *   defined by the msgs array, with num messages available to transfer via
>   *   the adapter specified by adap.
> + * @master_xfer_irqless: same as master_xfer. Yet, not using any interrupts
> + *   so e.g. PMICs can be accessed very late before shutdown
>   * @smbus_xfer: Issue smbus transactions to the given I2C adapter. If this
>   *   is not present, then the bus layer will try and convert the SMBus calls
>   *   into I2C transfers instead.
> @@ -511,9 +513,9 @@ i2c_register_board_info(int busnum, struct i2c_board_info const *info,
>   * be addressed using the same bus algorithms - i.e. bit-banging or the PCF8584
>   * to name two of the most common.
>   *
> - * The return codes from the @master_xfer field should indicate the type of
> - * error code that occurred during the transfer, as documented in the kernel
> - * Documentation file Documentation/i2c/fault-codes.
> + * The return codes from the @master_xfer{_irqless} field should indicate the
> + * type of error code that occurred during the transfer, as documented in the
> + * Kernel Documentation file Documentation/i2c/fault-codes.
>   */
>  struct i2c_algorithm {
>         /* If an adapter algorithm can't do I2C-level access, set master_xfer
> @@ -524,6 +526,8 @@ struct i2c_algorithm {
>            processed, or a negative value on error */
>         int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,
>                            int num);
> +       int (*master_xfer_irqless)(struct i2c_adapter *adap,
> +                                  struct i2c_msg *msgs, int num);
>         int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,
>                            unsigned short flags, char read_write,
>                            u8 command, int size, union i2c_smbus_data *data);
> --
> 2.18.0
>
>


-- 
With Best Regards,
Andy Shevchenko



[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux