lkml.org 
[lkml]   [2019]   [Apr]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v2 2/3] i2c-mux-gpio: Unpin the platform-specific GPIOs request code
    Date
    The GPIOs request loop can be safely moved to a separate function.
    First of all it shall improve the code readability. Secondly the
    initialization loop at this point is used for both of- and
    platform_data-based initialization paths, but it will be changed in
    the next patch, so by isolating the code we'll simplify the future
    work.

    Signed-off-by: Serge Semin <fancer.lancer@gmail.com>

    ---
    Changelog v2
    - Create a dedicated initial_state field in the "gpiomux" structure to
    keep an initial channel selector state.
    ---
    drivers/i2c/muxes/i2c-mux-gpio.c | 113 +++++++++++++++++++------------
    1 file changed, 68 insertions(+), 45 deletions(-)

    diff --git a/drivers/i2c/muxes/i2c-mux-gpio.c b/drivers/i2c/muxes/i2c-mux-gpio.c
    index 54158b825acd..e10f72706b99 100644
    --- a/drivers/i2c/muxes/i2c-mux-gpio.c
    +++ b/drivers/i2c/muxes/i2c-mux-gpio.c
    @@ -20,7 +20,8 @@

    struct gpiomux {
    struct i2c_mux_gpio_platform_data data;
    - unsigned gpio_base;
    + unsigned int gpio_base;
    + unsigned int initial_state;
    struct gpio_desc **gpios;
    };

    @@ -162,13 +163,68 @@ static int i2c_mux_gpio_probe_plat(struct gpiomux *mux,
    return 0;
    }

    +static int i2c_mux_gpio_request_plat(struct gpiomux *mux,
    + struct platform_device *pdev)
    +{
    + struct i2c_mux_core *muxc = platform_get_drvdata(pdev);
    + struct gpio_desc *gpio_desc;
    + struct i2c_adapter *root;
    + struct device *gpio_dev;
    + int i, ret;
    +
    + root = i2c_root_adapter(&muxc->parent->dev);
    +
    + for (i = 0; i < mux->data.n_gpios; i++) {
    + ret = gpio_request(mux->gpio_base + mux->data.gpios[i],
    + "i2c-mux-gpio");
    + if (ret) {
    + dev_err(&pdev->dev, "Failed to request GPIO %d\n",
    + mux->data.gpios[i]);
    + goto err_request_gpio;
    + }
    +
    + ret = gpio_direction_output(mux->gpio_base + mux->data.gpios[i],
    + mux->initial_state & (1 << i));
    + if (ret) {
    + dev_err(&pdev->dev,
    + "Failed to set direction of GPIO %d to output\n",
    + mux->data.gpios[i]);
    + i++; /* gpio_request above succeeded, so must free */
    + goto err_request_gpio;
    + }
    +
    + gpio_desc = gpio_to_desc(mux->gpio_base + mux->data.gpios[i]);
    + mux->gpios[i] = gpio_desc;
    +
    + if (!muxc->mux_locked)
    + continue;
    +
    + gpio_dev = &gpio_desc->gdev->dev;
    + muxc->mux_locked = i2c_root_adapter(gpio_dev) == root;
    + }
    +
    + return 0;
    +
    +err_request_gpio:
    + for (; i > 0; i--)
    + gpio_free(mux->gpio_base + mux->data.gpios[i - 1]);
    +
    + return ret;
    +}
    +
    +static void i2c_mux_gpio_free(struct gpiomux *mux)
    +{
    + int i;
    +
    + for (i = 0; i < mux->data.n_gpios; i++)
    + gpiod_free(mux->gpios[i]);
    +}
    +
    static int i2c_mux_gpio_probe(struct platform_device *pdev)
    {
    struct i2c_mux_core *muxc;
    struct gpiomux *mux;
    struct i2c_adapter *parent;
    - struct i2c_adapter *root;
    - unsigned initial_state;
    int i, ret;

    mux = devm_kzalloc(&pdev->dev, sizeof(*mux), GFP_KERNEL);
    @@ -198,48 +254,18 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)

    platform_set_drvdata(pdev, muxc);

    - root = i2c_root_adapter(&parent->dev);
    -
    muxc->mux_locked = true;

    if (mux->data.idle != I2C_MUX_GPIO_NO_IDLE) {
    - initial_state = mux->data.idle;
    + mux->initial_state = mux->data.idle;
    muxc->deselect = i2c_mux_gpio_deselect;
    } else {
    - initial_state = mux->data.values[0];
    + mux->initial_state = mux->data.values[0];
    }

    - for (i = 0; i < mux->data.n_gpios; i++) {
    - struct device *gpio_dev;
    - struct gpio_desc *gpio_desc;
    -
    - ret = gpio_request(mux->gpio_base + mux->data.gpios[i],
    - "i2c-mux-gpio");
    - if (ret) {
    - dev_err(&pdev->dev, "Failed to request GPIO %d\n",
    - mux->data.gpios[i]);
    - goto err_request_gpio;
    - }
    -
    - ret = gpio_direction_output(mux->gpio_base + mux->data.gpios[i],
    - initial_state & (1 << i));
    - if (ret) {
    - dev_err(&pdev->dev,
    - "Failed to set direction of GPIO %d to output\n",
    - mux->data.gpios[i]);
    - i++; /* gpio_request above succeeded, so must free */
    - goto err_request_gpio;
    - }
    -
    - gpio_desc = gpio_to_desc(mux->gpio_base + mux->data.gpios[i]);
    - mux->gpios[i] = gpio_desc;
    -
    - if (!muxc->mux_locked)
    - continue;
    -
    - gpio_dev = &gpio_desc->gdev->dev;
    - muxc->mux_locked = i2c_root_adapter(gpio_dev) == root;
    - }
    + ret = i2c_mux_gpio_request_plat(mux, pdev);
    + if (ret)
    + goto alloc_failed;

    if (muxc->mux_locked)
    dev_info(&pdev->dev, "mux-locked i2c mux\n");
    @@ -260,10 +286,9 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)

    add_adapter_failed:
    i2c_mux_del_adapters(muxc);
    - i = mux->data.n_gpios;
    -err_request_gpio:
    - for (; i > 0; i--)
    - gpio_free(mux->gpio_base + mux->data.gpios[i - 1]);
    +
    + i2c_mux_gpio_free(mux);
    +
    alloc_failed:
    i2c_put_adapter(parent);

    @@ -274,12 +299,10 @@ static int i2c_mux_gpio_remove(struct platform_device *pdev)
    {
    struct i2c_mux_core *muxc = platform_get_drvdata(pdev);
    struct gpiomux *mux = i2c_mux_priv(muxc);
    - int i;

    i2c_mux_del_adapters(muxc);

    - for (i = 0; i < mux->data.n_gpios; i++)
    - gpio_free(mux->gpio_base + mux->data.gpios[i]);
    + i2c_mux_gpio_free(mux);

    i2c_put_adapter(muxc->parent);

    --
    2.21.0
    \
     
     \ /
      Last update: 2019-04-26 01:22    [W:2.378 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site