diff options
Diffstat (limited to 'drivers/i2c/muxes/i2c-mux-gpio.c')
-rw-r--r-- | drivers/i2c/muxes/i2c-mux-gpio.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/i2c/muxes/i2c-mux-gpio.c b/drivers/i2c/muxes/i2c-mux-gpio.c index f6270ee934f9..e5cf26eefa97 100644 --- a/drivers/i2c/muxes/i2c-mux-gpio.c +++ b/drivers/i2c/muxes/i2c-mux-gpio.c @@ -15,6 +15,7 @@ #include <linux/module.h> #include <linux/slab.h> #include <linux/gpio.h> +#include "../../gpio/gpiolib.h" #include <linux/of_gpio.h> struct gpiomux { @@ -137,6 +138,7 @@ 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, gpio_base; int i, ret; @@ -184,6 +186,9 @@ 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; mux->gpio_base = gpio_base; if (mux->data.idle != I2C_MUX_GPIO_NO_IDLE) { @@ -194,6 +199,9 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev) } for (i = 0; i < mux->data.n_gpios; i++) { + struct device *gpio_dev; + struct gpio_desc *gpio_desc; + ret = gpio_request(gpio_base + mux->data.gpios[i], "i2c-mux-gpio"); if (ret) { dev_err(&pdev->dev, "Failed to request GPIO %d\n", @@ -210,8 +218,18 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev) i++; /* gpio_request above succeeded, so must free */ goto err_request_gpio; } + + if (!muxc->mux_locked) + continue; + + gpio_desc = gpio_to_desc(gpio_base + mux->data.gpios[i]); + gpio_dev = &gpio_desc->gdev->dev; + muxc->mux_locked = i2c_root_adapter(gpio_dev) == root; } + if (muxc->mux_locked) + dev_info(&pdev->dev, "mux-locked i2c mux\n"); + for (i = 0; i < mux->data.n_values; i++) { u32 nr = mux->data.base_nr ? (mux->data.base_nr + i) : 0; unsigned int class = mux->data.classes ? mux->data.classes[i] : 0; |