From: Peter Rosin <p...@axentia.se>

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: Peter Rosin <p...@axentia.se>
---
 drivers/i2c/muxes/i2c-mux-pca9541.c | 55 ++++++++++++++++---------------------
 1 file changed, 23 insertions(+), 32 deletions(-)

diff --git a/drivers/i2c/muxes/i2c-mux-pca9541.c 
b/drivers/i2c/muxes/i2c-mux-pca9541.c
index d0ba424adebc..93bea073ed13 100644
--- a/drivers/i2c/muxes/i2c-mux-pca9541.c
+++ b/drivers/i2c/muxes/i2c-mux-pca9541.c
@@ -73,7 +73,7 @@
 #define SELECT_DELAY_LONG      1000
 
 struct pca9541 {
-       struct i2c_adapter *mux_adap;
+       struct i2c_client *client;
        unsigned long select_timeout;
        unsigned long arb_timeout;
 };
@@ -217,7 +217,8 @@ static const u8 pca9541_control[16] = {
  */
 static int pca9541_arbitrate(struct i2c_client *client)
 {
-       struct pca9541 *data = i2c_get_clientdata(client);
+       struct i2c_mux_core *muxc = i2c_get_clientdata(client);
+       struct pca9541 *data = i2c_mux_priv(muxc);
        int reg;
 
        reg = pca9541_reg_read(client, PCA9541_CONTROL);
@@ -285,9 +286,10 @@ static int pca9541_arbitrate(struct i2c_client *client)
        return 0;
 }
 
-static int pca9541_select_chan(struct i2c_adapter *adap, void *client, u32 
chan)
+static int pca9541_select_chan(struct i2c_mux_core *muxc, u32 chan)
 {
-       struct pca9541 *data = i2c_get_clientdata(client);
+       struct pca9541 *data = i2c_mux_priv(muxc);
+       struct i2c_client *client = data->client;
        int ret;
        unsigned long timeout = jiffies + ARB2_TIMEOUT;
                /* give up after this time */
@@ -309,9 +311,11 @@ static int pca9541_select_chan(struct i2c_adapter *adap, 
void *client, u32 chan)
        return -ETIMEDOUT;
 }
 
-static int pca9541_release_chan(struct i2c_adapter *adap,
-                               void *client, u32 chan)
+static int pca9541_release_chan(struct i2c_mux_core *muxc, u32 chan)
 {
+       struct pca9541 *data = i2c_mux_priv(muxc);
+       struct i2c_client *client = data->client;
+
        pca9541_release_bus(client);
        return 0;
 }
@@ -324,20 +328,12 @@ static int pca9541_probe(struct i2c_client *client,
 {
        struct i2c_adapter *adap = client->adapter;
        struct pca954x_platform_data *pdata = dev_get_platdata(&client->dev);
+       struct i2c_mux_core *muxc;
        struct pca9541 *data;
        int force;
-       int ret = -ENODEV;
 
        if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE_DATA))
-               goto err;
-
-       data = kzalloc(sizeof(struct pca9541), GFP_KERNEL);
-       if (!data) {
-               ret = -ENOMEM;
-               goto err;
-       }
-
-       i2c_set_clientdata(client, data);
+               return -ENODEV;
 
        /*
         * I2C accesses are unprotected here.
@@ -352,34 +348,29 @@ static int pca9541_probe(struct i2c_client *client,
        force = 0;
        if (pdata)
                force = pdata->modes[0].adap_id;
-       data->mux_adap = i2c_add_mux_adapter(adap, &client->dev, client,
-                                            force, 0, 0,
-                                            pca9541_select_chan,
-                                            pca9541_release_chan);
-
-       if (data->mux_adap == NULL) {
+       muxc = i2c_mux_one_adapter(adap, &client->dev, sizeof(*data), 0,
+                                  force, 0, 0,
+                                  pca9541_select_chan, pca9541_release_chan);
+       if (IS_ERR(muxc)) {
                dev_err(&client->dev, "failed to register master selector\n");
-               goto exit_free;
+               return PTR_ERR(muxc);
        }
+       data = i2c_mux_priv(muxc);
+       data->client = client;
+
+       i2c_set_clientdata(client, muxc);
 
        dev_info(&client->dev, "registered master selector for I2C %s\n",
                 client->name);
 
        return 0;
-
-exit_free:
-       kfree(data);
-err:
-       return ret;
 }
 
 static int pca9541_remove(struct i2c_client *client)
 {
-       struct pca9541 *data = i2c_get_clientdata(client);
-
-       i2c_del_mux_adapter(data->mux_adap);
+       struct i2c_mux_core *muxc = i2c_get_clientdata(client);
 
-       kfree(data);
+       i2c_mux_del_adapters(muxc);
        return 0;
 }
 
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to