From e00fed40f48e43bdb5e018156d077c65b61f93bf Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Wed, 20 Apr 2016 08:41:02 +0200 Subject: [media] m88ds3103: convert to use an explicit i2c mux core Allocate an explicit i2c mux core to handle parent and child adapters etc. Update the select op to be in terms of the i2c mux core instead of the child adapter. Tested-by: Antti Palosaari Reviewed-by: Antti Palosaari Signed-off-by: Peter Rosin Signed-off-by: Wolfram Sang --- drivers/media/dvb-frontends/m88ds3103.c | 19 +++++++++++-------- drivers/media/dvb-frontends/m88ds3103_priv.h | 2 +- 2 files changed, 12 insertions(+), 9 deletions(-) (limited to 'drivers/media/dvb-frontends') diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index 76883600ec6f..5557ef8fc704 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -1251,9 +1251,9 @@ static void m88ds3103_release(struct dvb_frontend *fe) i2c_unregister_device(client); } -static int m88ds3103_select(struct i2c_adapter *adap, void *mux_priv, u32 chan) +static int m88ds3103_select(struct i2c_mux_core *muxc, u32 chan) { - struct m88ds3103_dev *dev = mux_priv; + struct m88ds3103_dev *dev = i2c_mux_priv(muxc); struct i2c_client *client = dev->client; int ret; struct i2c_msg msg = { @@ -1374,7 +1374,7 @@ static struct i2c_adapter *m88ds3103_get_i2c_adapter(struct i2c_client *client) dev_dbg(&client->dev, "\n"); - return dev->i2c_adapter; + return dev->muxc->adapter[0]; } static int m88ds3103_probe(struct i2c_client *client, @@ -1467,13 +1467,16 @@ static int m88ds3103_probe(struct i2c_client *client, goto err_kfree; /* create mux i2c adapter for tuner */ - dev->i2c_adapter = i2c_add_mux_adapter(client->adapter, &client->dev, - dev, 0, 0, 0, m88ds3103_select, - NULL); - if (dev->i2c_adapter == NULL) { + dev->muxc = i2c_mux_alloc(client->adapter, &client->dev, 1, 0, 0, + m88ds3103_select, NULL); + if (!dev->muxc) { ret = -ENOMEM; goto err_kfree; } + dev->muxc->priv = dev; + ret = i2c_mux_add_adapter(dev->muxc, 0, 0, 0); + if (ret) + goto err_kfree; /* create dvb_frontend */ memcpy(&dev->fe.ops, &m88ds3103_ops, sizeof(struct dvb_frontend_ops)); @@ -1502,7 +1505,7 @@ static int m88ds3103_remove(struct i2c_client *client) dev_dbg(&client->dev, "\n"); - i2c_del_mux_adapter(dev->i2c_adapter); + i2c_mux_del_adapters(dev->muxc); kfree(dev); return 0; diff --git a/drivers/media/dvb-frontends/m88ds3103_priv.h b/drivers/media/dvb-frontends/m88ds3103_priv.h index eee8c22c51ec..c5b4e177c6ea 100644 --- a/drivers/media/dvb-frontends/m88ds3103_priv.h +++ b/drivers/media/dvb-frontends/m88ds3103_priv.h @@ -42,7 +42,7 @@ struct m88ds3103_dev { enum fe_status fe_status; u32 dvbv3_ber; /* for old DVBv3 API read_ber */ bool warm; /* FW running */ - struct i2c_adapter *i2c_adapter; + struct i2c_mux_core *muxc; /* auto detect chip id to do different config */ u8 chip_id; /* main mclk is calculated for M88RS6000 dynamically */ -- cgit v1.2.3 From a0119159e66e2e67154384d7e20a0ebf46cfa32b Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Wed, 20 Apr 2016 08:41:13 +0200 Subject: [media] rtl2830: convert to use an explicit i2c mux core Allocate an explicit i2c mux core to handle parent and child adapters etc. Update the select op to be in terms of the i2c mux core instead of the child adapter. Tested-by: Antti Palosaari Reviewed-by: Antti Palosaari Signed-off-by: Peter Rosin Signed-off-by: Wolfram Sang --- drivers/media/dvb-frontends/rtl2830.c | 20 ++++++++++++-------- drivers/media/dvb-frontends/rtl2830_priv.h | 2 +- 2 files changed, 13 insertions(+), 9 deletions(-) (limited to 'drivers/media/dvb-frontends') diff --git a/drivers/media/dvb-frontends/rtl2830.c b/drivers/media/dvb-frontends/rtl2830.c index 3f96429af0e5..d25d1e0cd4ca 100644 --- a/drivers/media/dvb-frontends/rtl2830.c +++ b/drivers/media/dvb-frontends/rtl2830.c @@ -677,9 +677,9 @@ err: * adapter lock is already taken by tuner driver. * Gate is closed automatically after single I2C transfer. */ -static int rtl2830_select(struct i2c_adapter *adap, void *mux_priv, u32 chan_id) +static int rtl2830_select(struct i2c_mux_core *muxc, u32 chan_id) { - struct i2c_client *client = mux_priv; + struct i2c_client *client = i2c_mux_priv(muxc); struct rtl2830_dev *dev = i2c_get_clientdata(client); int ret; @@ -712,7 +712,7 @@ static struct i2c_adapter *rtl2830_get_i2c_adapter(struct i2c_client *client) dev_dbg(&client->dev, "\n"); - return dev->adapter; + return dev->muxc->adapter[0]; } /* @@ -865,12 +865,16 @@ static int rtl2830_probe(struct i2c_client *client, goto err_regmap_exit; /* create muxed i2c adapter for tuner */ - dev->adapter = i2c_add_mux_adapter(client->adapter, &client->dev, - client, 0, 0, 0, rtl2830_select, NULL); - if (dev->adapter == NULL) { - ret = -ENODEV; + dev->muxc = i2c_mux_alloc(client->adapter, &client->dev, 1, 0, 0, + rtl2830_select, NULL); + if (!dev->muxc) { + ret = -ENOMEM; goto err_regmap_exit; } + dev->muxc->priv = client; + ret = i2c_mux_add_adapter(dev->muxc, 0, 0, 0); + if (ret) + goto err_regmap_exit; /* create dvb frontend */ memcpy(&dev->fe.ops, &rtl2830_ops, sizeof(dev->fe.ops)); @@ -903,7 +907,7 @@ static int rtl2830_remove(struct i2c_client *client) /* stop statistics polling */ cancel_delayed_work_sync(&dev->stat_work); - i2c_del_mux_adapter(dev->adapter); + i2c_mux_del_adapters(dev->muxc); regmap_exit(dev->regmap); kfree(dev); diff --git a/drivers/media/dvb-frontends/rtl2830_priv.h b/drivers/media/dvb-frontends/rtl2830_priv.h index cf793f39a09b..da4909543da2 100644 --- a/drivers/media/dvb-frontends/rtl2830_priv.h +++ b/drivers/media/dvb-frontends/rtl2830_priv.h @@ -29,7 +29,7 @@ struct rtl2830_dev { struct rtl2830_platform_data *pdata; struct i2c_client *client; struct regmap *regmap; - struct i2c_adapter *adapter; + struct i2c_mux_core *muxc; struct dvb_frontend fe; bool sleeping; unsigned long filters; -- cgit v1.2.3 From cddcc40b1b1553010acb89add84c64b5d123ec94 Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Wed, 20 Apr 2016 08:41:25 +0200 Subject: [media] rtl2832: 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. Tested-by: Antti Palosaari Reviewed-by: Antti Palosaari Signed-off-by: Peter Rosin Signed-off-by: Wolfram Sang --- drivers/media/dvb-frontends/rtl2832.c | 25 ++++++++++++++----------- drivers/media/dvb-frontends/rtl2832_priv.h | 2 +- 2 files changed, 15 insertions(+), 12 deletions(-) (limited to 'drivers/media/dvb-frontends') diff --git a/drivers/media/dvb-frontends/rtl2832.c b/drivers/media/dvb-frontends/rtl2832.c index 7c96f7679669..1b23788797b5 100644 --- a/drivers/media/dvb-frontends/rtl2832.c +++ b/drivers/media/dvb-frontends/rtl2832.c @@ -847,9 +847,9 @@ err: dev_dbg(&client->dev, "failed=%d\n", ret); } -static int rtl2832_select(struct i2c_adapter *adap, void *mux_priv, u32 chan_id) +static int rtl2832_select(struct i2c_mux_core *muxc, u32 chan_id) { - struct rtl2832_dev *dev = mux_priv; + struct rtl2832_dev *dev = i2c_mux_priv(muxc); struct i2c_client *client = dev->client; int ret; @@ -870,10 +870,9 @@ err: return ret; } -static int rtl2832_deselect(struct i2c_adapter *adap, void *mux_priv, - u32 chan_id) +static int rtl2832_deselect(struct i2c_mux_core *muxc, u32 chan_id) { - struct rtl2832_dev *dev = mux_priv; + struct rtl2832_dev *dev = i2c_mux_priv(muxc); schedule_delayed_work(&dev->i2c_gate_work, usecs_to_jiffies(100)); return 0; @@ -1059,7 +1058,7 @@ static struct i2c_adapter *rtl2832_get_i2c_adapter(struct i2c_client *client) struct rtl2832_dev *dev = i2c_get_clientdata(client); dev_dbg(&client->dev, "\n"); - return dev->i2c_adapter_tuner; + return dev->muxc->adapter[0]; } static int rtl2832_slave_ts_ctrl(struct i2c_client *client, bool enable) @@ -1242,12 +1241,16 @@ static int rtl2832_probe(struct i2c_client *client, goto err_regmap_exit; /* create muxed i2c adapter for demod tuner bus */ - dev->i2c_adapter_tuner = i2c_add_mux_adapter(i2c, &i2c->dev, dev, - 0, 0, 0, rtl2832_select, rtl2832_deselect); - if (dev->i2c_adapter_tuner == NULL) { - ret = -ENODEV; + dev->muxc = i2c_mux_alloc(i2c, &i2c->dev, 1, 0, 0, + rtl2832_select, rtl2832_deselect); + if (!dev->muxc) { + ret = -ENOMEM; goto err_regmap_exit; } + dev->muxc->priv = dev; + ret = i2c_mux_add_adapter(dev->muxc, 0, 0, 0); + if (ret) + goto err_regmap_exit; /* create dvb_frontend */ memcpy(&dev->fe.ops, &rtl2832_ops, sizeof(struct dvb_frontend_ops)); @@ -1282,7 +1285,7 @@ static int rtl2832_remove(struct i2c_client *client) cancel_delayed_work_sync(&dev->i2c_gate_work); - i2c_del_mux_adapter(dev->i2c_adapter_tuner); + i2c_mux_del_adapters(dev->muxc); regmap_exit(dev->regmap); diff --git a/drivers/media/dvb-frontends/rtl2832_priv.h b/drivers/media/dvb-frontends/rtl2832_priv.h index 6b875f462f8b..d8f97d14f6fd 100644 --- a/drivers/media/dvb-frontends/rtl2832_priv.h +++ b/drivers/media/dvb-frontends/rtl2832_priv.h @@ -36,7 +36,7 @@ struct rtl2832_dev { struct mutex regmap_mutex; struct regmap_config regmap_config; struct regmap *regmap; - struct i2c_adapter *i2c_adapter_tuner; + struct i2c_mux_core *muxc; struct dvb_frontend fe; enum fe_status fe_status; u64 post_bit_error_prev; /* for old DVBv3 read_ber() calculation */ -- cgit v1.2.3 From 58d7b541dd96535b03cc9dd13fe9efff2a5402e0 Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Wed, 20 Apr 2016 08:41:36 +0200 Subject: [media] si2168: 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. Tested-by: Antti Palosaari Reviewed-by: Antti Palosaari Signed-off-by: Peter Rosin Signed-off-by: Wolfram Sang --- drivers/media/dvb-frontends/si2168.c | 25 +++++++++++++++---------- drivers/media/dvb-frontends/si2168_priv.h | 2 +- 2 files changed, 16 insertions(+), 11 deletions(-) (limited to 'drivers/media/dvb-frontends') diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c index 821a8f481507..5583827c386e 100644 --- a/drivers/media/dvb-frontends/si2168.c +++ b/drivers/media/dvb-frontends/si2168.c @@ -615,9 +615,9 @@ static int si2168_get_tune_settings(struct dvb_frontend *fe, * We must use unlocked I2C I/O because I2C adapter lock is already taken * by the caller (usually tuner driver). */ -static int si2168_select(struct i2c_adapter *adap, void *mux_priv, u32 chan) +static int si2168_select(struct i2c_mux_core *muxc, u32 chan) { - struct i2c_client *client = mux_priv; + struct i2c_client *client = i2c_mux_priv(muxc); int ret; struct si2168_cmd cmd; @@ -635,9 +635,9 @@ err: return ret; } -static int si2168_deselect(struct i2c_adapter *adap, void *mux_priv, u32 chan) +static int si2168_deselect(struct i2c_mux_core *muxc, u32 chan) { - struct i2c_client *client = mux_priv; + struct i2c_client *client = i2c_mux_priv(muxc); int ret; struct si2168_cmd cmd; @@ -709,17 +709,22 @@ static int si2168_probe(struct i2c_client *client, } /* create mux i2c adapter for tuner */ - dev->adapter = i2c_add_mux_adapter(client->adapter, &client->dev, - client, 0, 0, 0, si2168_select, si2168_deselect); - if (dev->adapter == NULL) { - ret = -ENODEV; + dev->muxc = i2c_mux_alloc(client->adapter, &client->dev, + 1, 0, 0, + si2168_select, si2168_deselect); + if (!dev->muxc) { + ret = -ENOMEM; goto err_kfree; } + dev->muxc->priv = client; + ret = i2c_mux_add_adapter(dev->muxc, 0, 0, 0); + if (ret) + goto err_kfree; /* create dvb_frontend */ memcpy(&dev->fe.ops, &si2168_ops, sizeof(struct dvb_frontend_ops)); dev->fe.demodulator_priv = client; - *config->i2c_adapter = dev->adapter; + *config->i2c_adapter = dev->muxc->adapter[0]; *config->fe = &dev->fe; dev->ts_mode = config->ts_mode; dev->ts_clock_inv = config->ts_clock_inv; @@ -743,7 +748,7 @@ static int si2168_remove(struct i2c_client *client) dev_dbg(&client->dev, "\n"); - i2c_del_mux_adapter(dev->adapter); + i2c_mux_del_adapters(dev->muxc); dev->fe.ops.release = NULL; dev->fe.demodulator_priv = NULL; diff --git a/drivers/media/dvb-frontends/si2168_priv.h b/drivers/media/dvb-frontends/si2168_priv.h index c07e6fe2cb10..165bf1412063 100644 --- a/drivers/media/dvb-frontends/si2168_priv.h +++ b/drivers/media/dvb-frontends/si2168_priv.h @@ -29,7 +29,7 @@ /* state struct */ struct si2168_dev { - struct i2c_adapter *adapter; + struct i2c_mux_core *muxc; struct dvb_frontend fe; enum fe_delivery_system delivery_system; enum fe_status fe_status; -- cgit v1.2.3 From e6d7ffcdf15f40fc1cff7a3c2fd2720ce3d53e49 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 4 May 2016 22:15:32 +0200 Subject: [media] si2168: change the i2c gate to be mux-locked The root i2c adapter lock is then no longer held by the i2c mux during accesses behind the i2c gate, and such accesses need to take that lock just like any other ordinary i2c accesses do. So, declare the i2c gate mux-locked, and zap the code that makes the i2c accesses unlocked. But add a mutex so that firmware commands are still serialized. Signed-off-by: Antti Palosaari Signed-off-by: Peter Rosin Signed-off-by: Wolfram Sang --- Documentation/i2c/i2c-topology | 2 +- drivers/media/dvb-frontends/si2168.c | 83 ++++++++----------------------- drivers/media/dvb-frontends/si2168_priv.h | 1 + 3 files changed, 22 insertions(+), 64 deletions(-) (limited to 'drivers/media/dvb-frontends') diff --git a/Documentation/i2c/i2c-topology b/Documentation/i2c/i2c-topology index 69b008518454..5e40802f0be2 100644 --- a/Documentation/i2c/i2c-topology +++ b/Documentation/i2c/i2c-topology @@ -56,7 +56,7 @@ In drivers/media/ dvb-frontends/m88ds3103 Parent-locked dvb-frontends/rtl2830 Parent-locked dvb-frontends/rtl2832 Parent-locked -dvb-frontends/si2168 Parent-locked +dvb-frontends/si2168 Mux-locked usb/cx231xx/ Parent-locked diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c index 5583827c386e..108a069fa1ae 100644 --- a/drivers/media/dvb-frontends/si2168.c +++ b/drivers/media/dvb-frontends/si2168.c @@ -18,53 +18,23 @@ static const struct dvb_frontend_ops si2168_ops; -/* Own I2C adapter locking is needed because of I2C gate logic. */ -static int si2168_i2c_master_send_unlocked(const struct i2c_client *client, - const char *buf, int count) -{ - int ret; - struct i2c_msg msg = { - .addr = client->addr, - .flags = 0, - .len = count, - .buf = (char *)buf, - }; - - ret = __i2c_transfer(client->adapter, &msg, 1); - return (ret == 1) ? count : ret; -} - -static int si2168_i2c_master_recv_unlocked(const struct i2c_client *client, - char *buf, int count) -{ - int ret; - struct i2c_msg msg = { - .addr = client->addr, - .flags = I2C_M_RD, - .len = count, - .buf = buf, - }; - - ret = __i2c_transfer(client->adapter, &msg, 1); - return (ret == 1) ? count : ret; -} - /* execute firmware command */ -static int si2168_cmd_execute_unlocked(struct i2c_client *client, - struct si2168_cmd *cmd) +static int si2168_cmd_execute(struct i2c_client *client, struct si2168_cmd *cmd) { + struct si2168_dev *dev = i2c_get_clientdata(client); int ret; unsigned long timeout; + mutex_lock(&dev->i2c_mutex); + if (cmd->wlen) { /* write cmd and args for firmware */ - ret = si2168_i2c_master_send_unlocked(client, cmd->args, - cmd->wlen); + ret = i2c_master_send(client, cmd->args, cmd->wlen); if (ret < 0) { - goto err; + goto err_mutex_unlock; } else if (ret != cmd->wlen) { ret = -EREMOTEIO; - goto err; + goto err_mutex_unlock; } } @@ -73,13 +43,12 @@ static int si2168_cmd_execute_unlocked(struct i2c_client *client, #define TIMEOUT 70 timeout = jiffies + msecs_to_jiffies(TIMEOUT); while (!time_after(jiffies, timeout)) { - ret = si2168_i2c_master_recv_unlocked(client, cmd->args, - cmd->rlen); + ret = i2c_master_recv(client, cmd->args, cmd->rlen); if (ret < 0) { - goto err; + goto err_mutex_unlock; } else if (ret != cmd->rlen) { ret = -EREMOTEIO; - goto err; + goto err_mutex_unlock; } /* firmware ready? */ @@ -94,32 +63,23 @@ static int si2168_cmd_execute_unlocked(struct i2c_client *client, /* error bit set? */ if ((cmd->args[0] >> 6) & 0x01) { ret = -EREMOTEIO; - goto err; + goto err_mutex_unlock; } if (!((cmd->args[0] >> 7) & 0x01)) { ret = -ETIMEDOUT; - goto err; + goto err_mutex_unlock; } } + mutex_unlock(&dev->i2c_mutex); return 0; -err: +err_mutex_unlock: + mutex_unlock(&dev->i2c_mutex); dev_dbg(&client->dev, "failed=%d\n", ret); return ret; } -static int si2168_cmd_execute(struct i2c_client *client, struct si2168_cmd *cmd) -{ - int ret; - - i2c_lock_adapter(client->adapter); - ret = si2168_cmd_execute_unlocked(client, cmd); - i2c_unlock_adapter(client->adapter); - - return ret; -} - static int si2168_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct i2c_client *client = fe->demodulator_priv; @@ -610,11 +570,6 @@ static int si2168_get_tune_settings(struct dvb_frontend *fe, return 0; } -/* - * I2C gate logic - * We must use unlocked I2C I/O because I2C adapter lock is already taken - * by the caller (usually tuner driver). - */ static int si2168_select(struct i2c_mux_core *muxc, u32 chan) { struct i2c_client *client = i2c_mux_priv(muxc); @@ -625,7 +580,7 @@ static int si2168_select(struct i2c_mux_core *muxc, u32 chan) memcpy(cmd.args, "\xc0\x0d\x01", 3); cmd.wlen = 3; cmd.rlen = 0; - ret = si2168_cmd_execute_unlocked(client, &cmd); + ret = si2168_cmd_execute(client, &cmd); if (ret) goto err; @@ -645,7 +600,7 @@ static int si2168_deselect(struct i2c_mux_core *muxc, u32 chan) memcpy(cmd.args, "\xc0\x0d\x00", 3); cmd.wlen = 3; cmd.rlen = 0; - ret = si2168_cmd_execute_unlocked(client, &cmd); + ret = si2168_cmd_execute(client, &cmd); if (ret) goto err; @@ -708,9 +663,11 @@ static int si2168_probe(struct i2c_client *client, goto err; } + mutex_init(&dev->i2c_mutex); + /* create mux i2c adapter for tuner */ dev->muxc = i2c_mux_alloc(client->adapter, &client->dev, - 1, 0, 0, + 1, 0, I2C_MUX_LOCKED, si2168_select, si2168_deselect); if (!dev->muxc) { ret = -ENOMEM; diff --git a/drivers/media/dvb-frontends/si2168_priv.h b/drivers/media/dvb-frontends/si2168_priv.h index 165bf1412063..8a1f36d2014d 100644 --- a/drivers/media/dvb-frontends/si2168_priv.h +++ b/drivers/media/dvb-frontends/si2168_priv.h @@ -29,6 +29,7 @@ /* state struct */ struct si2168_dev { + struct mutex i2c_mutex; struct i2c_mux_core *muxc; struct dvb_frontend fe; enum fe_delivery_system delivery_system; -- cgit v1.2.3 From 1cf79db28ef53aeaa66a825e8f788d19fdd8648f Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Wed, 4 May 2016 22:15:33 +0200 Subject: [media] rtl2832: change the i2c gate to be mux-locked The root i2c adapter lock is then no longer held by the i2c mux during accesses behind the i2c gate, and such accesses need to take that lock just like any other ordinary i2c accesses do. So, declare the i2c gate mux-locked, and zap the regmap overrides that makes the i2c accesses unlocked and use plain old regmap accesses. This also removes the need for the regmap wrappers used by rtl2832_sdr, so deconvolute the code further and provide the regmap handle directly instead of the wrapper functions. Tested-by: Antti Palosaari Signed-off-by: Peter Rosin Signed-off-by: Wolfram Sang --- Documentation/i2c/i2c-topology | 2 +- drivers/media/dvb-frontends/rtl2832.c | 190 ++++-------------------------- drivers/media/dvb-frontends/rtl2832.h | 4 +- drivers/media/dvb-frontends/rtl2832_sdr.c | 13 +- drivers/media/dvb-frontends/rtl2832_sdr.h | 5 +- drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 5 +- 6 files changed, 37 insertions(+), 182 deletions(-) (limited to 'drivers/media/dvb-frontends') diff --git a/Documentation/i2c/i2c-topology b/Documentation/i2c/i2c-topology index 5e40802f0be2..e0aefeece551 100644 --- a/Documentation/i2c/i2c-topology +++ b/Documentation/i2c/i2c-topology @@ -55,7 +55,7 @@ imu/inv_mpu6050/ Mux-locked In drivers/media/ dvb-frontends/m88ds3103 Parent-locked dvb-frontends/rtl2830 Parent-locked -dvb-frontends/rtl2832 Parent-locked +dvb-frontends/rtl2832 Mux-locked dvb-frontends/si2168 Mux-locked usb/cx231xx/ Parent-locked diff --git a/drivers/media/dvb-frontends/rtl2832.c b/drivers/media/dvb-frontends/rtl2832.c index 1b23788797b5..957523f07f61 100644 --- a/drivers/media/dvb-frontends/rtl2832.c +++ b/drivers/media/dvb-frontends/rtl2832.c @@ -153,43 +153,6 @@ static const struct rtl2832_reg_entry registers[] = { [DVBT_REG_4MSEL] = {0x013, 0, 0}, }; -/* Our regmap is bypassing I2C adapter lock, thus we do it! */ -static int rtl2832_bulk_write(struct i2c_client *client, unsigned int reg, - const void *val, size_t val_count) -{ - struct rtl2832_dev *dev = i2c_get_clientdata(client); - int ret; - - i2c_lock_adapter(client->adapter); - ret = regmap_bulk_write(dev->regmap, reg, val, val_count); - i2c_unlock_adapter(client->adapter); - return ret; -} - -static int rtl2832_update_bits(struct i2c_client *client, unsigned int reg, - unsigned int mask, unsigned int val) -{ - struct rtl2832_dev *dev = i2c_get_clientdata(client); - int ret; - - i2c_lock_adapter(client->adapter); - ret = regmap_update_bits(dev->regmap, reg, mask, val); - i2c_unlock_adapter(client->adapter); - return ret; -} - -static int rtl2832_bulk_read(struct i2c_client *client, unsigned int reg, - void *val, size_t val_count) -{ - struct rtl2832_dev *dev = i2c_get_clientdata(client); - int ret; - - i2c_lock_adapter(client->adapter); - ret = regmap_bulk_read(dev->regmap, reg, val, val_count); - i2c_unlock_adapter(client->adapter); - return ret; -} - static int rtl2832_rd_demod_reg(struct rtl2832_dev *dev, int reg, u32 *val) { struct i2c_client *client = dev->client; @@ -204,7 +167,7 @@ static int rtl2832_rd_demod_reg(struct rtl2832_dev *dev, int reg, u32 *val) len = (msb >> 3) + 1; mask = REG_MASK(msb - lsb); - ret = rtl2832_bulk_read(client, reg_start_addr, reading, len); + ret = regmap_bulk_read(dev->regmap, reg_start_addr, reading, len); if (ret) goto err; @@ -234,7 +197,7 @@ static int rtl2832_wr_demod_reg(struct rtl2832_dev *dev, int reg, u32 val) len = (msb >> 3) + 1; mask = REG_MASK(msb - lsb); - ret = rtl2832_bulk_read(client, reg_start_addr, reading, len); + ret = regmap_bulk_read(dev->regmap, reg_start_addr, reading, len); if (ret) goto err; @@ -248,7 +211,7 @@ static int rtl2832_wr_demod_reg(struct rtl2832_dev *dev, int reg, u32 val) for (i = 0; i < len; i++) writing[i] = (writing_tmp >> ((len - 1 - i) * 8)) & 0xff; - ret = rtl2832_bulk_write(client, reg_start_addr, writing, len); + ret = regmap_bulk_write(dev->regmap, reg_start_addr, writing, len); if (ret) goto err; @@ -525,7 +488,8 @@ static int rtl2832_set_frontend(struct dvb_frontend *fe) } for (j = 0; j < sizeof(bw_params[0]); j++) { - ret = rtl2832_bulk_write(client, 0x11c + j, &bw_params[i][j], 1); + ret = regmap_bulk_write(dev->regmap, + 0x11c + j, &bw_params[i][j], 1); if (ret) goto err; } @@ -581,11 +545,11 @@ static int rtl2832_get_frontend(struct dvb_frontend *fe, if (dev->sleeping) return 0; - ret = rtl2832_bulk_read(client, 0x33c, buf, 2); + ret = regmap_bulk_read(dev->regmap, 0x33c, buf, 2); if (ret) goto err; - ret = rtl2832_bulk_read(client, 0x351, &buf[2], 1); + ret = regmap_bulk_read(dev->regmap, 0x351, &buf[2], 1); if (ret) goto err; @@ -716,7 +680,7 @@ static int rtl2832_read_status(struct dvb_frontend *fe, enum fe_status *status) /* signal strength */ if (dev->fe_status & FE_HAS_SIGNAL) { /* read digital AGC */ - ret = rtl2832_bulk_read(client, 0x305, &u8tmp, 1); + ret = regmap_bulk_read(dev->regmap, 0x305, &u8tmp, 1); if (ret) goto err; @@ -742,7 +706,7 @@ static int rtl2832_read_status(struct dvb_frontend *fe, enum fe_status *status) {87659938, 87659938, 87885178, 88241743}, }; - ret = rtl2832_bulk_read(client, 0x33c, &u8tmp, 1); + ret = regmap_bulk_read(dev->regmap, 0x33c, &u8tmp, 1); if (ret) goto err; @@ -754,7 +718,7 @@ static int rtl2832_read_status(struct dvb_frontend *fe, enum fe_status *status) if (hierarchy > HIERARCHY_NUM - 1) goto err; - ret = rtl2832_bulk_read(client, 0x40c, buf, 2); + ret = regmap_bulk_read(dev->regmap, 0x40c, buf, 2); if (ret) goto err; @@ -775,7 +739,7 @@ static int rtl2832_read_status(struct dvb_frontend *fe, enum fe_status *status) /* BER */ if (dev->fe_status & FE_HAS_LOCK) { - ret = rtl2832_bulk_read(client, 0x34e, buf, 2); + ret = regmap_bulk_read(dev->regmap, 0x34e, buf, 2); if (ret) goto err; @@ -825,8 +789,6 @@ static int rtl2832_read_ber(struct dvb_frontend *fe, u32 *ber) /* * I2C gate/mux/repeater logic - * We must use unlocked __i2c_transfer() here (through regmap) because of I2C - * adapter lock is already taken by tuner driver. * There is delay mechanism to avoid unneeded I2C gate open / close. Gate close * is delayed here a little bit in order to see if there is sequence of I2C * messages sent to same I2C bus. @@ -838,7 +800,7 @@ static void rtl2832_i2c_gate_work(struct work_struct *work) int ret; /* close gate */ - ret = rtl2832_update_bits(dev->client, 0x101, 0x08, 0x00); + ret = regmap_update_bits(dev->regmap, 0x101, 0x08, 0x00); if (ret) goto err; @@ -856,10 +818,7 @@ static int rtl2832_select(struct i2c_mux_core *muxc, u32 chan_id) /* terminate possible gate closing */ cancel_delayed_work(&dev->i2c_gate_work); - /* - * I2C adapter lock is already taken and due to that we will use - * regmap_update_bits() which does not lock again I2C adapter. - */ + /* open gate */ ret = regmap_update_bits(dev->regmap, 0x101, 0x08, 0x08); if (ret) goto err; @@ -931,94 +890,6 @@ static bool rtl2832_volatile_reg(struct device *dev, unsigned int reg) return false; } -/* - * We implement own I2C access routines for regmap in order to get manual access - * to I2C adapter lock, which is needed for I2C mux adapter. - */ -static int rtl2832_regmap_read(void *context, const void *reg_buf, - size_t reg_size, void *val_buf, size_t val_size) -{ - struct i2c_client *client = context; - int ret; - struct i2c_msg msg[2] = { - { - .addr = client->addr, - .flags = 0, - .len = reg_size, - .buf = (u8 *)reg_buf, - }, { - .addr = client->addr, - .flags = I2C_M_RD, - .len = val_size, - .buf = val_buf, - } - }; - - ret = __i2c_transfer(client->adapter, msg, 2); - if (ret != 2) { - dev_warn(&client->dev, "i2c reg read failed %d reg %02x\n", - ret, *(u8 *)reg_buf); - if (ret >= 0) - ret = -EREMOTEIO; - return ret; - } - return 0; -} - -static int rtl2832_regmap_write(void *context, const void *data, size_t count) -{ - struct i2c_client *client = context; - int ret; - struct i2c_msg msg[1] = { - { - .addr = client->addr, - .flags = 0, - .len = count, - .buf = (u8 *)data, - } - }; - - ret = __i2c_transfer(client->adapter, msg, 1); - if (ret != 1) { - dev_warn(&client->dev, "i2c reg write failed %d reg %02x\n", - ret, *(u8 *)data); - if (ret >= 0) - ret = -EREMOTEIO; - return ret; - } - return 0; -} - -static int rtl2832_regmap_gather_write(void *context, const void *reg, - size_t reg_len, const void *val, - size_t val_len) -{ - struct i2c_client *client = context; - int ret; - u8 buf[256]; - struct i2c_msg msg[1] = { - { - .addr = client->addr, - .flags = 0, - .len = 1 + val_len, - .buf = buf, - } - }; - - buf[0] = *(u8 const *)reg; - memcpy(&buf[1], val, val_len); - - ret = __i2c_transfer(client->adapter, msg, 1); - if (ret != 1) { - dev_warn(&client->dev, "i2c reg write failed %d reg %02x\n", - ret, *(u8 const *)reg); - if (ret >= 0) - ret = -EREMOTEIO; - return ret; - } - return 0; -} - /* * FIXME: Hack. Implement own regmap locking in order to silence lockdep * recursive lock warning. That happens when regmap I2C client calls I2C mux @@ -1072,29 +943,29 @@ static int rtl2832_slave_ts_ctrl(struct i2c_client *client, bool enable) ret = rtl2832_wr_demod_reg(dev, DVBT_SOFT_RST, 0x0); if (ret) goto err; - ret = rtl2832_bulk_write(client, 0x10c, "\x5f\xff", 2); + ret = regmap_bulk_write(dev->regmap, 0x10c, "\x5f\xff", 2); if (ret) goto err; ret = rtl2832_wr_demod_reg(dev, DVBT_PIP_ON, 0x1); if (ret) goto err; - ret = rtl2832_bulk_write(client, 0x0bc, "\x18", 1); + ret = regmap_bulk_write(dev->regmap, 0x0bc, "\x18", 1); if (ret) goto err; - ret = rtl2832_bulk_write(client, 0x192, "\x7f\xf7\xff", 3); + ret = regmap_bulk_write(dev->regmap, 0x192, "\x7f\xf7\xff", 3); if (ret) goto err; } else { - ret = rtl2832_bulk_write(client, 0x192, "\x00\x0f\xff", 3); + ret = regmap_bulk_write(dev->regmap, 0x192, "\x00\x0f\xff", 3); if (ret) goto err; - ret = rtl2832_bulk_write(client, 0x0bc, "\x08", 1); + ret = regmap_bulk_write(dev->regmap, 0x0bc, "\x08", 1); if (ret) goto err; ret = rtl2832_wr_demod_reg(dev, DVBT_PIP_ON, 0x0); if (ret) goto err; - ret = rtl2832_bulk_write(client, 0x10c, "\x00\x00", 2); + ret = regmap_bulk_write(dev->regmap, 0x10c, "\x00\x00", 2); if (ret) goto err; ret = rtl2832_wr_demod_reg(dev, DVBT_SOFT_RST, 0x1); @@ -1123,7 +994,7 @@ static int rtl2832_pid_filter_ctrl(struct dvb_frontend *fe, int onoff) else u8tmp = 0x00; - ret = rtl2832_update_bits(client, 0x061, 0xc0, u8tmp); + ret = regmap_update_bits(dev->regmap, 0x061, 0xc0, u8tmp); if (ret) goto err; @@ -1158,14 +1029,14 @@ static int rtl2832_pid_filter(struct dvb_frontend *fe, u8 index, u16 pid, buf[1] = (dev->filters >> 8) & 0xff; buf[2] = (dev->filters >> 16) & 0xff; buf[3] = (dev->filters >> 24) & 0xff; - ret = rtl2832_bulk_write(client, 0x062, buf, 4); + ret = regmap_bulk_write(dev->regmap, 0x062, buf, 4); if (ret) goto err; /* add PID */ buf[0] = (pid >> 8) & 0xff; buf[1] = (pid >> 0) & 0xff; - ret = rtl2832_bulk_write(client, 0x066 + 2 * index, buf, 2); + ret = regmap_bulk_write(dev->regmap, 0x066 + 2 * index, buf, 2); if (ret) goto err; @@ -1183,12 +1054,6 @@ static int rtl2832_probe(struct i2c_client *client, struct rtl2832_dev *dev; int ret; u8 tmp; - static const struct regmap_bus regmap_bus = { - .read = rtl2832_regmap_read, - .write = rtl2832_regmap_write, - .gather_write = rtl2832_regmap_gather_write, - .val_format_endian_default = REGMAP_ENDIAN_NATIVE, - }; static const struct regmap_range_cfg regmap_range_cfg[] = { { .selector_reg = 0x00, @@ -1228,20 +1093,19 @@ static int rtl2832_probe(struct i2c_client *client, dev->regmap_config.ranges = regmap_range_cfg, dev->regmap_config.num_ranges = ARRAY_SIZE(regmap_range_cfg), dev->regmap_config.cache_type = REGCACHE_NONE, - dev->regmap = regmap_init(&client->dev, ®map_bus, client, - &dev->regmap_config); + dev->regmap = regmap_init_i2c(client, &dev->regmap_config); if (IS_ERR(dev->regmap)) { ret = PTR_ERR(dev->regmap); goto err_kfree; } /* check if the demod is there */ - ret = rtl2832_bulk_read(client, 0x000, &tmp, 1); + ret = regmap_bulk_read(dev->regmap, 0x000, &tmp, 1); if (ret) goto err_regmap_exit; /* create muxed i2c adapter for demod tuner bus */ - dev->muxc = i2c_mux_alloc(i2c, &i2c->dev, 1, 0, 0, + dev->muxc = i2c_mux_alloc(i2c, &i2c->dev, 1, 0, I2C_MUX_LOCKED, rtl2832_select, rtl2832_deselect); if (!dev->muxc) { ret = -ENOMEM; @@ -1262,9 +1126,7 @@ static int rtl2832_probe(struct i2c_client *client, pdata->slave_ts_ctrl = rtl2832_slave_ts_ctrl; pdata->pid_filter = rtl2832_pid_filter; pdata->pid_filter_ctrl = rtl2832_pid_filter_ctrl; - pdata->bulk_read = rtl2832_bulk_read; - pdata->bulk_write = rtl2832_bulk_write; - pdata->update_bits = rtl2832_update_bits; + pdata->regmap = dev->regmap; dev_info(&client->dev, "Realtek RTL2832 successfully attached\n"); return 0; diff --git a/drivers/media/dvb-frontends/rtl2832.h b/drivers/media/dvb-frontends/rtl2832.h index 6390af64cf45..03c0de039fa9 100644 --- a/drivers/media/dvb-frontends/rtl2832.h +++ b/drivers/media/dvb-frontends/rtl2832.h @@ -57,9 +57,7 @@ struct rtl2832_platform_data { int (*pid_filter)(struct dvb_frontend *, u8, u16, int); int (*pid_filter_ctrl)(struct dvb_frontend *, int); /* private: Register access for SDR module use only */ - int (*bulk_read)(struct i2c_client *, unsigned int, void *, size_t); - int (*bulk_write)(struct i2c_client *, unsigned int, const void *, size_t); - int (*update_bits)(struct i2c_client *, unsigned int, unsigned int, unsigned int); + struct regmap *regmap; }; #endif /* RTL2832_H */ diff --git a/drivers/media/dvb-frontends/rtl2832_sdr.c b/drivers/media/dvb-frontends/rtl2832_sdr.c index b860f02a4e55..6a6b1debe277 100644 --- a/drivers/media/dvb-frontends/rtl2832_sdr.c +++ b/drivers/media/dvb-frontends/rtl2832_sdr.c @@ -35,6 +35,7 @@ #include #include #include +#include static bool rtl2832_sdr_emulated_fmt; module_param_named(emulated_formats, rtl2832_sdr_emulated_fmt, bool, 0644); @@ -169,9 +170,9 @@ static int rtl2832_sdr_wr_regs(struct rtl2832_sdr_dev *dev, u16 reg, { struct platform_device *pdev = dev->pdev; struct rtl2832_sdr_platform_data *pdata = pdev->dev.platform_data; - struct i2c_client *client = pdata->i2c_client; + struct regmap *regmap = pdata->regmap; - return pdata->bulk_write(client, reg, val, len); + return regmap_bulk_write(regmap, reg, val, len); } #if 0 @@ -181,9 +182,9 @@ static int rtl2832_sdr_rd_regs(struct rtl2832_sdr_dev *dev, u16 reg, u8 *val, { struct platform_device *pdev = dev->pdev; struct rtl2832_sdr_platform_data *pdata = pdev->dev.platform_data; - struct i2c_client *client = pdata->i2c_client; + struct regmap *regmap = pdata->regmap; - return pdata->bulk_read(client, reg, val, len); + return regmap_bulk_read(regmap, reg, val, len); } #endif @@ -199,9 +200,9 @@ static int rtl2832_sdr_wr_reg_mask(struct rtl2832_sdr_dev *dev, u16 reg, { struct platform_device *pdev = dev->pdev; struct rtl2832_sdr_platform_data *pdata = pdev->dev.platform_data; - struct i2c_client *client = pdata->i2c_client; + struct regmap *regmap = pdata->regmap; - return pdata->update_bits(client, reg, mask, val); + return regmap_update_bits(regmap, reg, mask, val); } /* Private functions */ diff --git a/drivers/media/dvb-frontends/rtl2832_sdr.h b/drivers/media/dvb-frontends/rtl2832_sdr.h index 342ea84860df..d8fc7e7212e3 100644 --- a/drivers/media/dvb-frontends/rtl2832_sdr.h +++ b/drivers/media/dvb-frontends/rtl2832_sdr.h @@ -56,10 +56,7 @@ struct rtl2832_sdr_platform_data { #define RTL2832_SDR_TUNER_R828D 0x2b u8 tuner; - struct i2c_client *i2c_client; - int (*bulk_read)(struct i2c_client *, unsigned int, void *, size_t); - int (*bulk_write)(struct i2c_client *, unsigned int, const void *, size_t); - int (*update_bits)(struct i2c_client *, unsigned int, unsigned int, unsigned int); + struct regmap *regmap; struct dvb_frontend *dvb_frontend; struct v4l2_subdev *v4l2_subdev; struct dvb_usb_device *dvb_usb_device; diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index fa72642d41f3..eb7af8cb8aca 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -1333,10 +1333,7 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) case TUNER_RTL2832_R828D: pdata.clk = dev->rtl2832_platform_data.clk; pdata.tuner = dev->tuner; - pdata.i2c_client = dev->i2c_client_demod; - pdata.bulk_read = dev->rtl2832_platform_data.bulk_read; - pdata.bulk_write = dev->rtl2832_platform_data.bulk_write; - pdata.update_bits = dev->rtl2832_platform_data.update_bits; + pdata.regmap = dev->rtl2832_platform_data.regmap; pdata.dvb_frontend = adap->fe[0]; pdata.dvb_usb_device = d; pdata.v4l2_subdev = subdev; -- cgit v1.2.3 From e01fc42d78ab953f6de4ff9273cb9d6d9ed3dd37 Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Wed, 4 May 2016 22:15:34 +0200 Subject: [media] rtl2832_sdr: get rid of empty regmap wrappers Tested-by: Antti Palosaari Reviewed-by: Antti Palosaari Signed-off-by: Peter Rosin Signed-off-by: Wolfram Sang --- drivers/media/dvb-frontends/rtl2832_sdr.c | 302 +++++++++++++----------------- 1 file changed, 132 insertions(+), 170 deletions(-) (limited to 'drivers/media/dvb-frontends') diff --git a/drivers/media/dvb-frontends/rtl2832_sdr.c b/drivers/media/dvb-frontends/rtl2832_sdr.c index 6a6b1debe277..47a480a7d46c 100644 --- a/drivers/media/dvb-frontends/rtl2832_sdr.c +++ b/drivers/media/dvb-frontends/rtl2832_sdr.c @@ -120,6 +120,7 @@ struct rtl2832_sdr_dev { unsigned long flags; struct platform_device *pdev; + struct regmap *regmap; struct video_device vdev; struct v4l2_device v4l2_dev; @@ -164,47 +165,6 @@ struct rtl2832_sdr_dev { unsigned long jiffies_next; }; -/* write multiple registers */ -static int rtl2832_sdr_wr_regs(struct rtl2832_sdr_dev *dev, u16 reg, - const u8 *val, int len) -{ - struct platform_device *pdev = dev->pdev; - struct rtl2832_sdr_platform_data *pdata = pdev->dev.platform_data; - struct regmap *regmap = pdata->regmap; - - return regmap_bulk_write(regmap, reg, val, len); -} - -#if 0 -/* read multiple registers */ -static int rtl2832_sdr_rd_regs(struct rtl2832_sdr_dev *dev, u16 reg, u8 *val, - int len) -{ - struct platform_device *pdev = dev->pdev; - struct rtl2832_sdr_platform_data *pdata = pdev->dev.platform_data; - struct regmap *regmap = pdata->regmap; - - return regmap_bulk_read(regmap, reg, val, len); -} -#endif - -/* write single register */ -static int rtl2832_sdr_wr_reg(struct rtl2832_sdr_dev *dev, u16 reg, u8 val) -{ - return rtl2832_sdr_wr_regs(dev, reg, &val, 1); -} - -/* write single register with mask */ -static int rtl2832_sdr_wr_reg_mask(struct rtl2832_sdr_dev *dev, u16 reg, - u8 val, u8 mask) -{ - struct platform_device *pdev = dev->pdev; - struct rtl2832_sdr_platform_data *pdata = pdev->dev.platform_data; - struct regmap *regmap = pdata->regmap; - - return regmap_update_bits(regmap, reg, mask, val); -} - /* Private functions */ static struct rtl2832_sdr_frame_buf *rtl2832_sdr_get_next_fill_buf( struct rtl2832_sdr_dev *dev) @@ -559,11 +519,11 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_dev *dev) f_sr = dev->f_adc; - ret = rtl2832_sdr_wr_regs(dev, 0x13e, "\x00\x00", 2); + ret = regmap_bulk_write(dev->regmap, 0x13e, "\x00\x00", 2); if (ret) goto err; - ret = rtl2832_sdr_wr_regs(dev, 0x115, "\x00\x00\x00\x00", 4); + ret = regmap_bulk_write(dev->regmap, 0x115, "\x00\x00\x00\x00", 4); if (ret) goto err; @@ -589,7 +549,7 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_dev *dev) buf[1] = (u32tmp >> 8) & 0xff; buf[2] = (u32tmp >> 0) & 0xff; - ret = rtl2832_sdr_wr_regs(dev, 0x119, buf, 3); + ret = regmap_bulk_write(dev->regmap, 0x119, buf, 3); if (ret) goto err; @@ -603,15 +563,15 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_dev *dev) u8tmp2 = 0xcd; /* enable ADC I, ADC Q */ } - ret = rtl2832_sdr_wr_reg(dev, 0x1b1, u8tmp1); + ret = regmap_write(dev->regmap, 0x1b1, u8tmp1); if (ret) goto err; - ret = rtl2832_sdr_wr_reg(dev, 0x008, u8tmp2); + ret = regmap_write(dev->regmap, 0x008, u8tmp2); if (ret) goto err; - ret = rtl2832_sdr_wr_reg(dev, 0x006, 0x80); + ret = regmap_write(dev->regmap, 0x006, 0x80); if (ret) goto err; @@ -622,168 +582,169 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_dev *dev) buf[1] = (u32tmp >> 16) & 0xff; buf[2] = (u32tmp >> 8) & 0xff; buf[3] = (u32tmp >> 0) & 0xff; - ret = rtl2832_sdr_wr_regs(dev, 0x19f, buf, 4); + ret = regmap_bulk_write(dev->regmap, 0x19f, buf, 4); if (ret) goto err; /* low-pass filter */ - ret = rtl2832_sdr_wr_regs(dev, 0x11c, - "\xca\xdc\xd7\xd8\xe0\xf2\x0e\x35\x06\x50\x9c\x0d\x71\x11\x14\x71\x74\x19\x41\xa5", - 20); + ret = regmap_bulk_write(dev->regmap, 0x11c, + "\xca\xdc\xd7\xd8\xe0\xf2\x0e\x35\x06\x50\x9c\x0d\x71\x11\x14\x71\x74\x19\x41\xa5", + 20); if (ret) goto err; - ret = rtl2832_sdr_wr_regs(dev, 0x017, "\x11\x10", 2); + ret = regmap_bulk_write(dev->regmap, 0x017, "\x11\x10", 2); if (ret) goto err; /* mode */ - ret = rtl2832_sdr_wr_regs(dev, 0x019, "\x05", 1); + ret = regmap_write(dev->regmap, 0x019, 0x05); if (ret) goto err; - ret = rtl2832_sdr_wr_regs(dev, 0x01a, "\x1b\x16\x0d\x06\x01\xff", 6); + ret = regmap_bulk_write(dev->regmap, 0x01a, + "\x1b\x16\x0d\x06\x01\xff", 6); if (ret) goto err; /* FSM */ - ret = rtl2832_sdr_wr_regs(dev, 0x192, "\x00\xf0\x0f", 3); + ret = regmap_bulk_write(dev->regmap, 0x192, "\x00\xf0\x0f", 3); if (ret) goto err; /* PID filter */ - ret = rtl2832_sdr_wr_regs(dev, 0x061, "\x60", 1); + ret = regmap_write(dev->regmap, 0x061, 0x60); if (ret) goto err; /* used RF tuner based settings */ switch (pdata->tuner) { case RTL2832_SDR_TUNER_E4000: - ret = rtl2832_sdr_wr_regs(dev, 0x112, "\x5a", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x102, "\x40", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x103, "\x5a", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1c7, "\x30", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x104, "\xd0", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x105, "\xbe", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1c8, "\x18", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x106, "\x35", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1c9, "\x21", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1ca, "\x21", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1cb, "\x00", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x107, "\x40", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1cd, "\x10", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1ce, "\x10", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x108, "\x80", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x109, "\x7f", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x10a, "\x80", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x10b, "\x7f", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x00e, "\xfc", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x00e, "\xfc", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x011, "\xd4", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1e5, "\xf0", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1d9, "\x00", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1db, "\x00", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1dd, "\x14", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1de, "\xec", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1d8, "\x0c", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1e6, "\x02", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1d7, "\x09", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x00d, "\x83", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x010, "\x49", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x00d, "\x87", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x00d, "\x85", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x013, "\x02", 1); + ret = regmap_write(dev->regmap, 0x112, 0x5a); + ret = regmap_write(dev->regmap, 0x102, 0x40); + ret = regmap_write(dev->regmap, 0x103, 0x5a); + ret = regmap_write(dev->regmap, 0x1c7, 0x30); + ret = regmap_write(dev->regmap, 0x104, 0xd0); + ret = regmap_write(dev->regmap, 0x105, 0xbe); + ret = regmap_write(dev->regmap, 0x1c8, 0x18); + ret = regmap_write(dev->regmap, 0x106, 0x35); + ret = regmap_write(dev->regmap, 0x1c9, 0x21); + ret = regmap_write(dev->regmap, 0x1ca, 0x21); + ret = regmap_write(dev->regmap, 0x1cb, 0x00); + ret = regmap_write(dev->regmap, 0x107, 0x40); + ret = regmap_write(dev->regmap, 0x1cd, 0x10); + ret = regmap_write(dev->regmap, 0x1ce, 0x10); + ret = regmap_write(dev->regmap, 0x108, 0x80); + ret = regmap_write(dev->regmap, 0x109, 0x7f); + ret = regmap_write(dev->regmap, 0x10a, 0x80); + ret = regmap_write(dev->regmap, 0x10b, 0x7f); + ret = regmap_write(dev->regmap, 0x00e, 0xfc); + ret = regmap_write(dev->regmap, 0x00e, 0xfc); + ret = regmap_write(dev->regmap, 0x011, 0xd4); + ret = regmap_write(dev->regmap, 0x1e5, 0xf0); + ret = regmap_write(dev->regmap, 0x1d9, 0x00); + ret = regmap_write(dev->regmap, 0x1db, 0x00); + ret = regmap_write(dev->regmap, 0x1dd, 0x14); + ret = regmap_write(dev->regmap, 0x1de, 0xec); + ret = regmap_write(dev->regmap, 0x1d8, 0x0c); + ret = regmap_write(dev->regmap, 0x1e6, 0x02); + ret = regmap_write(dev->regmap, 0x1d7, 0x09); + ret = regmap_write(dev->regmap, 0x00d, 0x83); + ret = regmap_write(dev->regmap, 0x010, 0x49); + ret = regmap_write(dev->regmap, 0x00d, 0x87); + ret = regmap_write(dev->regmap, 0x00d, 0x85); + ret = regmap_write(dev->regmap, 0x013, 0x02); break; case RTL2832_SDR_TUNER_FC0012: case RTL2832_SDR_TUNER_FC0013: - ret = rtl2832_sdr_wr_regs(dev, 0x112, "\x5a", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x102, "\x40", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x103, "\x5a", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1c7, "\x2c", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x104, "\xcc", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x105, "\xbe", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1c8, "\x16", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x106, "\x35", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1c9, "\x21", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1ca, "\x21", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1cb, "\x00", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x107, "\x40", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1cd, "\x10", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1ce, "\x10", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x108, "\x80", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x109, "\x7f", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x10a, "\x80", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x10b, "\x7f", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x00e, "\xfc", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x00e, "\xfc", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x011, "\xe9\xbf", 2); - ret = rtl2832_sdr_wr_regs(dev, 0x1e5, "\xf0", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1d9, "\x00", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1db, "\x00", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1dd, "\x11", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1de, "\xef", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1d8, "\x0c", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1e6, "\x02", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1d7, "\x09", 1); + ret = regmap_write(dev->regmap, 0x112, 0x5a); + ret = regmap_write(dev->regmap, 0x102, 0x40); + ret = regmap_write(dev->regmap, 0x103, 0x5a); + ret = regmap_write(dev->regmap, 0x1c7, 0x2c); + ret = regmap_write(dev->regmap, 0x104, 0xcc); + ret = regmap_write(dev->regmap, 0x105, 0xbe); + ret = regmap_write(dev->regmap, 0x1c8, 0x16); + ret = regmap_write(dev->regmap, 0x106, 0x35); + ret = regmap_write(dev->regmap, 0x1c9, 0x21); + ret = regmap_write(dev->regmap, 0x1ca, 0x21); + ret = regmap_write(dev->regmap, 0x1cb, 0x00); + ret = regmap_write(dev->regmap, 0x107, 0x40); + ret = regmap_write(dev->regmap, 0x1cd, 0x10); + ret = regmap_write(dev->regmap, 0x1ce, 0x10); + ret = regmap_write(dev->regmap, 0x108, 0x80); + ret = regmap_write(dev->regmap, 0x109, 0x7f); + ret = regmap_write(dev->regmap, 0x10a, 0x80); + ret = regmap_write(dev->regmap, 0x10b, 0x7f); + ret = regmap_write(dev->regmap, 0x00e, 0xfc); + ret = regmap_write(dev->regmap, 0x00e, 0xfc); + ret = regmap_bulk_write(dev->regmap, 0x011, "\xe9\xbf", 2); + ret = regmap_write(dev->regmap, 0x1e5, 0xf0); + ret = regmap_write(dev->regmap, 0x1d9, 0x00); + ret = regmap_write(dev->regmap, 0x1db, 0x00); + ret = regmap_write(dev->regmap, 0x1dd, 0x11); + ret = regmap_write(dev->regmap, 0x1de, 0xef); + ret = regmap_write(dev->regmap, 0x1d8, 0x0c); + ret = regmap_write(dev->regmap, 0x1e6, 0x02); + ret = regmap_write(dev->regmap, 0x1d7, 0x09); break; case RTL2832_SDR_TUNER_R820T: case RTL2832_SDR_TUNER_R828D: - ret = rtl2832_sdr_wr_regs(dev, 0x112, "\x5a", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x102, "\x40", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x115, "\x01", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x103, "\x80", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1c7, "\x24", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x104, "\xcc", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x105, "\xbe", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1c8, "\x14", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x106, "\x35", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1c9, "\x21", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1ca, "\x21", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1cb, "\x00", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x107, "\x40", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1cd, "\x10", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1ce, "\x10", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x108, "\x80", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x109, "\x7f", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x10a, "\x80", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x10b, "\x7f", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x00e, "\xfc", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x00e, "\xfc", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x011, "\xf4", 1); + ret = regmap_write(dev->regmap, 0x112, 0x5a); + ret = regmap_write(dev->regmap, 0x102, 0x40); + ret = regmap_write(dev->regmap, 0x115, 0x01); + ret = regmap_write(dev->regmap, 0x103, 0x80); + ret = regmap_write(dev->regmap, 0x1c7, 0x24); + ret = regmap_write(dev->regmap, 0x104, 0xcc); + ret = regmap_write(dev->regmap, 0x105, 0xbe); + ret = regmap_write(dev->regmap, 0x1c8, 0x14); + ret = regmap_write(dev->regmap, 0x106, 0x35); + ret = regmap_write(dev->regmap, 0x1c9, 0x21); + ret = regmap_write(dev->regmap, 0x1ca, 0x21); + ret = regmap_write(dev->regmap, 0x1cb, 0x00); + ret = regmap_write(dev->regmap, 0x107, 0x40); + ret = regmap_write(dev->regmap, 0x1cd, 0x10); + ret = regmap_write(dev->regmap, 0x1ce, 0x10); + ret = regmap_write(dev->regmap, 0x108, 0x80); + ret = regmap_write(dev->regmap, 0x109, 0x7f); + ret = regmap_write(dev->regmap, 0x10a, 0x80); + ret = regmap_write(dev->regmap, 0x10b, 0x7f); + ret = regmap_write(dev->regmap, 0x00e, 0xfc); + ret = regmap_write(dev->regmap, 0x00e, 0xfc); + ret = regmap_write(dev->regmap, 0x011, 0xf4); break; case RTL2832_SDR_TUNER_FC2580: - ret = rtl2832_sdr_wr_regs(dev, 0x112, "\x39", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x102, "\x40", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x103, "\x5a", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1c7, "\x2c", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x104, "\xcc", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x105, "\xbe", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1c8, "\x16", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x106, "\x35", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1c9, "\x21", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1ca, "\x21", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1cb, "\x00", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x107, "\x40", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1cd, "\x10", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x1ce, "\x10", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x108, "\x80", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x109, "\x7f", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x10a, "\x9c", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x10b, "\x7f", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x00e, "\xfc", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x00e, "\xfc", 1); - ret = rtl2832_sdr_wr_regs(dev, 0x011, "\xe9\xf4", 2); + ret = regmap_write(dev->regmap, 0x112, 0x39); + ret = regmap_write(dev->regmap, 0x102, 0x40); + ret = regmap_write(dev->regmap, 0x103, 0x5a); + ret = regmap_write(dev->regmap, 0x1c7, 0x2c); + ret = regmap_write(dev->regmap, 0x104, 0xcc); + ret = regmap_write(dev->regmap, 0x105, 0xbe); + ret = regmap_write(dev->regmap, 0x1c8, 0x16); + ret = regmap_write(dev->regmap, 0x106, 0x35); + ret = regmap_write(dev->regmap, 0x1c9, 0x21); + ret = regmap_write(dev->regmap, 0x1ca, 0x21); + ret = regmap_write(dev->regmap, 0x1cb, 0x00); + ret = regmap_write(dev->regmap, 0x107, 0x40); + ret = regmap_write(dev->regmap, 0x1cd, 0x10); + ret = regmap_write(dev->regmap, 0x1ce, 0x10); + ret = regmap_write(dev->regmap, 0x108, 0x80); + ret = regmap_write(dev->regmap, 0x109, 0x7f); + ret = regmap_write(dev->regmap, 0x10a, 0x9c); + ret = regmap_write(dev->regmap, 0x10b, 0x7f); + ret = regmap_write(dev->regmap, 0x00e, 0xfc); + ret = regmap_write(dev->regmap, 0x00e, 0xfc); + ret = regmap_bulk_write(dev->regmap, 0x011, "\xe9\xf4", 2); break; default: dev_notice(&pdev->dev, "Unsupported tuner\n"); } /* software reset */ - ret = rtl2832_sdr_wr_reg_mask(dev, 0x101, 0x04, 0x04); + ret = regmap_update_bits(dev->regmap, 0x101, 0x04, 0x04); if (ret) goto err; - ret = rtl2832_sdr_wr_reg_mask(dev, 0x101, 0x00, 0x04); + ret = regmap_update_bits(dev->regmap, 0x101, 0x04, 0x00); if (ret) goto err; err: @@ -798,29 +759,29 @@ static void rtl2832_sdr_unset_adc(struct rtl2832_sdr_dev *dev) dev_dbg(&pdev->dev, "\n"); /* PID filter */ - ret = rtl2832_sdr_wr_regs(dev, 0x061, "\xe0", 1); + ret = regmap_write(dev->regmap, 0x061, 0xe0); if (ret) goto err; /* mode */ - ret = rtl2832_sdr_wr_regs(dev, 0x019, "\x20", 1); + ret = regmap_write(dev->regmap, 0x019, 0x20); if (ret) goto err; - ret = rtl2832_sdr_wr_regs(dev, 0x017, "\x11\x10", 2); + ret = regmap_bulk_write(dev->regmap, 0x017, "\x11\x10", 2); if (ret) goto err; /* FSM */ - ret = rtl2832_sdr_wr_regs(dev, 0x192, "\x00\x0f\xff", 3); + ret = regmap_bulk_write(dev->regmap, 0x192, "\x00\x0f\xff", 3); if (ret) goto err; - ret = rtl2832_sdr_wr_regs(dev, 0x13e, "\x40\x00", 2); + ret = regmap_bulk_write(dev->regmap, 0x13e, "\x40\x00", 2); if (ret) goto err; - ret = rtl2832_sdr_wr_regs(dev, 0x115, "\x06\x3f\xce\xcc", 4); + ret = regmap_bulk_write(dev->regmap, 0x115, "\x06\x3f\xce\xcc", 4); if (ret) goto err; err: @@ -1400,6 +1361,7 @@ static int rtl2832_sdr_probe(struct platform_device *pdev) subdev = pdata->v4l2_subdev; dev->v4l2_subdev = pdata->v4l2_subdev; dev->pdev = pdev; + dev->regmap = pdata->regmap; dev->udev = pdata->dvb_usb_device->udev; dev->f_adc = bands_adc[0].rangelow; dev->f_tuner = bands_fm[0].rangelow; -- cgit v1.2.3 From 3f30e40b96b085ff25babaa8d6bc0b75c8fb32b2 Mon Sep 17 00:00:00 2001 From: Peter Rosin Date: Wed, 4 May 2016 22:15:35 +0200 Subject: [media] rtl2832: regmap is aware of lockdep, drop local locking hack Tested-by: Antti Palosaari Reviewed-by: Antti Palosaari Signed-off-by: Peter Rosin Signed-off-by: Wolfram Sang --- drivers/media/dvb-frontends/rtl2832.c | 30 ------------------------------ drivers/media/dvb-frontends/rtl2832_priv.h | 1 - 2 files changed, 31 deletions(-) (limited to 'drivers/media/dvb-frontends') diff --git a/drivers/media/dvb-frontends/rtl2832.c b/drivers/media/dvb-frontends/rtl2832.c index 957523f07f61..bfb6beedd40b 100644 --- a/drivers/media/dvb-frontends/rtl2832.c +++ b/drivers/media/dvb-frontends/rtl2832.c @@ -890,32 +890,6 @@ static bool rtl2832_volatile_reg(struct device *dev, unsigned int reg) return false; } -/* - * FIXME: Hack. Implement own regmap locking in order to silence lockdep - * recursive lock warning. That happens when regmap I2C client calls I2C mux - * adapter, which leads demod I2C repeater enable via demod regmap. Operation - * takes two regmap locks recursively - but those are different regmap instances - * in a two different I2C drivers, so it is not deadlock. Proper fix is to make - * regmap aware of lockdep. - */ -static void rtl2832_regmap_lock(void *__dev) -{ - struct rtl2832_dev *dev = __dev; - struct i2c_client *client = dev->client; - - dev_dbg(&client->dev, "\n"); - mutex_lock(&dev->regmap_mutex); -} - -static void rtl2832_regmap_unlock(void *__dev) -{ - struct rtl2832_dev *dev = __dev; - struct i2c_client *client = dev->client; - - dev_dbg(&client->dev, "\n"); - mutex_unlock(&dev->regmap_mutex); -} - static struct dvb_frontend *rtl2832_get_dvb_frontend(struct i2c_client *client) { struct rtl2832_dev *dev = i2c_get_clientdata(client); @@ -1082,12 +1056,8 @@ static int rtl2832_probe(struct i2c_client *client, dev->sleeping = true; INIT_DELAYED_WORK(&dev->i2c_gate_work, rtl2832_i2c_gate_work); /* create regmap */ - mutex_init(&dev->regmap_mutex); dev->regmap_config.reg_bits = 8, dev->regmap_config.val_bits = 8, - dev->regmap_config.lock = rtl2832_regmap_lock, - dev->regmap_config.unlock = rtl2832_regmap_unlock, - dev->regmap_config.lock_arg = dev, dev->regmap_config.volatile_reg = rtl2832_volatile_reg, dev->regmap_config.max_register = 5 * 0x100, dev->regmap_config.ranges = regmap_range_cfg, diff --git a/drivers/media/dvb-frontends/rtl2832_priv.h b/drivers/media/dvb-frontends/rtl2832_priv.h index d8f97d14f6fd..c1a8a69e9015 100644 --- a/drivers/media/dvb-frontends/rtl2832_priv.h +++ b/drivers/media/dvb-frontends/rtl2832_priv.h @@ -33,7 +33,6 @@ struct rtl2832_dev { struct rtl2832_platform_data *pdata; struct i2c_client *client; - struct mutex regmap_mutex; struct regmap_config regmap_config; struct regmap *regmap; struct i2c_mux_core *muxc; -- cgit v1.2.3