Commit 8aacd901 authored by Peter Rosin's avatar Peter Rosin Committed by Wolfram Sang

i2c: i2c-arb-gpio-challenge: convert to use an explicit i2c mux core

Allocate an explicit i2c mux core to handle parent and child adapters
etc. Update the select/deselect ops to be in terms of the i2c mux core
instead of the child adapter.
Signed-off-by: default avatarPeter Rosin <peda@axentia.se>
Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
parent 4bbe7fb0
...@@ -28,8 +28,6 @@ ...@@ -28,8 +28,6 @@
/** /**
* struct i2c_arbitrator_data - Driver data for I2C arbitrator * struct i2c_arbitrator_data - Driver data for I2C arbitrator
* *
* @parent: Parent adapter
* @child: Child bus
* @our_gpio: GPIO we'll use to claim. * @our_gpio: GPIO we'll use to claim.
* @our_gpio_release: 0 if active high; 1 if active low; AKA if the GPIO == * @our_gpio_release: 0 if active high; 1 if active low; AKA if the GPIO ==
* this then consider it released. * this then consider it released.
...@@ -42,8 +40,6 @@ ...@@ -42,8 +40,6 @@
*/ */
struct i2c_arbitrator_data { struct i2c_arbitrator_data {
struct i2c_adapter *parent;
struct i2c_adapter *child;
int our_gpio; int our_gpio;
int our_gpio_release; int our_gpio_release;
int their_gpio; int their_gpio;
...@@ -59,9 +55,9 @@ struct i2c_arbitrator_data { ...@@ -59,9 +55,9 @@ struct i2c_arbitrator_data {
* *
* Use the GPIO-based signalling protocol; return -EBUSY if we fail. * Use the GPIO-based signalling protocol; return -EBUSY if we fail.
*/ */
static int i2c_arbitrator_select(struct i2c_adapter *adap, void *data, u32 chan) static int i2c_arbitrator_select(struct i2c_mux_core *muxc, u32 chan)
{ {
const struct i2c_arbitrator_data *arb = data; const struct i2c_arbitrator_data *arb = i2c_mux_priv(muxc);
unsigned long stop_retry, stop_time; unsigned long stop_retry, stop_time;
/* Start a round of trying to claim the bus */ /* Start a round of trying to claim the bus */
...@@ -93,7 +89,7 @@ static int i2c_arbitrator_select(struct i2c_adapter *adap, void *data, u32 chan) ...@@ -93,7 +89,7 @@ static int i2c_arbitrator_select(struct i2c_adapter *adap, void *data, u32 chan)
/* Give up, release our claim */ /* Give up, release our claim */
gpio_set_value(arb->our_gpio, arb->our_gpio_release); gpio_set_value(arb->our_gpio, arb->our_gpio_release);
udelay(arb->slew_delay_us); udelay(arb->slew_delay_us);
dev_err(&adap->dev, "Could not claim bus, timeout\n"); dev_err(muxc->dev, "Could not claim bus, timeout\n");
return -EBUSY; return -EBUSY;
} }
...@@ -102,10 +98,9 @@ static int i2c_arbitrator_select(struct i2c_adapter *adap, void *data, u32 chan) ...@@ -102,10 +98,9 @@ static int i2c_arbitrator_select(struct i2c_adapter *adap, void *data, u32 chan)
* *
* Release the I2C bus using the GPIO-based signalling protocol. * Release the I2C bus using the GPIO-based signalling protocol.
*/ */
static int i2c_arbitrator_deselect(struct i2c_adapter *adap, void *data, static int i2c_arbitrator_deselect(struct i2c_mux_core *muxc, u32 chan)
u32 chan)
{ {
const struct i2c_arbitrator_data *arb = data; const struct i2c_arbitrator_data *arb = i2c_mux_priv(muxc);
/* Release the bus and wait for the other master to notice */ /* Release the bus and wait for the other master to notice */
gpio_set_value(arb->our_gpio, arb->our_gpio_release); gpio_set_value(arb->our_gpio, arb->our_gpio_release);
...@@ -119,6 +114,7 @@ static int i2c_arbitrator_probe(struct platform_device *pdev) ...@@ -119,6 +114,7 @@ static int i2c_arbitrator_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node; struct device_node *np = dev->of_node;
struct device_node *parent_np; struct device_node *parent_np;
struct i2c_mux_core *muxc;
struct i2c_arbitrator_data *arb; struct i2c_arbitrator_data *arb;
enum of_gpio_flags gpio_flags; enum of_gpio_flags gpio_flags;
unsigned long out_init; unsigned long out_init;
...@@ -134,12 +130,13 @@ static int i2c_arbitrator_probe(struct platform_device *pdev) ...@@ -134,12 +130,13 @@ static int i2c_arbitrator_probe(struct platform_device *pdev)
return -EINVAL; return -EINVAL;
} }
arb = devm_kzalloc(dev, sizeof(*arb), GFP_KERNEL); muxc = i2c_mux_alloc(NULL, dev, 1, sizeof(*arb), 0,
if (!arb) { i2c_arbitrator_select, i2c_arbitrator_deselect);
dev_err(dev, "Cannot allocate i2c_arbitrator_data\n"); if (!muxc)
return -ENOMEM; return -ENOMEM;
} arb = i2c_mux_priv(muxc);
platform_set_drvdata(pdev, arb);
platform_set_drvdata(pdev, muxc);
/* Request GPIOs */ /* Request GPIOs */
ret = of_get_named_gpio_flags(np, "our-claim-gpio", 0, &gpio_flags); ret = of_get_named_gpio_flags(np, "our-claim-gpio", 0, &gpio_flags);
...@@ -196,21 +193,18 @@ static int i2c_arbitrator_probe(struct platform_device *pdev) ...@@ -196,21 +193,18 @@ static int i2c_arbitrator_probe(struct platform_device *pdev)
dev_err(dev, "Cannot parse i2c-parent\n"); dev_err(dev, "Cannot parse i2c-parent\n");
return -EINVAL; return -EINVAL;
} }
arb->parent = of_get_i2c_adapter_by_node(parent_np); muxc->parent = of_get_i2c_adapter_by_node(parent_np);
of_node_put(parent_np); of_node_put(parent_np);
if (!arb->parent) { if (!muxc->parent) {
dev_err(dev, "Cannot find parent bus\n"); dev_err(dev, "Cannot find parent bus\n");
return -EPROBE_DEFER; return -EPROBE_DEFER;
} }
/* Actually add the mux adapter */ /* Actually add the mux adapter */
arb->child = i2c_add_mux_adapter(arb->parent, dev, arb, 0, 0, 0, ret = i2c_mux_add_adapter(muxc, 0, 0, 0);
i2c_arbitrator_select, if (ret) {
i2c_arbitrator_deselect);
if (!arb->child) {
dev_err(dev, "Failed to add adapter\n"); dev_err(dev, "Failed to add adapter\n");
ret = -ENODEV; i2c_put_adapter(muxc->parent);
i2c_put_adapter(arb->parent);
} }
return ret; return ret;
...@@ -218,11 +212,10 @@ static int i2c_arbitrator_probe(struct platform_device *pdev) ...@@ -218,11 +212,10 @@ static int i2c_arbitrator_probe(struct platform_device *pdev)
static int i2c_arbitrator_remove(struct platform_device *pdev) static int i2c_arbitrator_remove(struct platform_device *pdev)
{ {
struct i2c_arbitrator_data *arb = platform_get_drvdata(pdev); struct i2c_mux_core *muxc = platform_get_drvdata(pdev);
i2c_del_mux_adapter(arb->child);
i2c_put_adapter(arb->parent);
i2c_mux_del_adapters(muxc);
i2c_put_adapter(muxc->parent);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment