diff options
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/i2c/ds90ub913.c | 9 | ||||
-rw-r--r-- | drivers/media/i2c/ds90ub953.c | 9 | ||||
-rw-r--r-- | drivers/media/i2c/ds90ub960.c | 54 |
3 files changed, 46 insertions, 26 deletions
diff --git a/drivers/media/i2c/ds90ub913.c b/drivers/media/i2c/ds90ub913.c index b1e67e514c6a..6d3f8617ef13 100644 --- a/drivers/media/i2c/ds90ub913.c +++ b/drivers/media/i2c/ds90ub913.c @@ -707,6 +707,7 @@ static int ub913_i2c_master_init(struct ub913_data *priv) static int ub913_add_i2c_adapter(struct ub913_data *priv) { struct device *dev = &priv->client->dev; + struct i2c_atr_adap_desc desc = { }; struct fwnode_handle *i2c_handle; int ret; @@ -714,8 +715,12 @@ static int ub913_add_i2c_adapter(struct ub913_data *priv) if (!i2c_handle) return 0; - ret = i2c_atr_add_adapter(priv->plat_data->atr, priv->plat_data->port, - dev, i2c_handle); + desc.chan_id = priv->plat_data->port; + desc.parent = dev; + desc.bus_handle = i2c_handle; + desc.num_aliases = 0; + + ret = i2c_atr_add_adapter(priv->plat_data->atr, &desc); fwnode_handle_put(i2c_handle); diff --git a/drivers/media/i2c/ds90ub953.c b/drivers/media/i2c/ds90ub953.c index 89e3132e81c5..59bd92388845 100644 --- a/drivers/media/i2c/ds90ub953.c +++ b/drivers/media/i2c/ds90ub953.c @@ -1102,6 +1102,7 @@ static int ub953_register_clkout(struct ub953_data *priv) static int ub953_add_i2c_adapter(struct ub953_data *priv) { struct device *dev = &priv->client->dev; + struct i2c_atr_adap_desc desc = { }; struct fwnode_handle *i2c_handle; int ret; @@ -1109,8 +1110,12 @@ static int ub953_add_i2c_adapter(struct ub953_data *priv) if (!i2c_handle) return 0; - ret = i2c_atr_add_adapter(priv->plat_data->atr, priv->plat_data->port, - dev, i2c_handle); + desc.chan_id = priv->plat_data->port; + desc.parent = dev; + desc.bus_handle = i2c_handle; + desc.num_aliases = 0; + + ret = i2c_atr_add_adapter(priv->plat_data->atr, &desc); fwnode_handle_put(i2c_handle); diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c index ed9ace1a5476..082fc62b0f5b 100644 --- a/drivers/media/i2c/ds90ub960.c +++ b/drivers/media/i2c/ds90ub960.c @@ -27,6 +27,7 @@ */ #include <linux/bitops.h> +#include <linux/cleanup.h> #include <linux/clk.h> #include <linux/delay.h> #include <linux/fwnode.h> @@ -521,7 +522,9 @@ struct ub960_rxport { }; } eq; - const struct i2c_client *aliased_clients[UB960_MAX_PORT_ALIASES]; + /* lock for aliased_addrs and associated registers */ + struct mutex aliased_addrs_lock; + u16 aliased_addrs[UB960_MAX_PORT_ALIASES]; }; struct ub960_asd { @@ -1264,8 +1267,8 @@ static int ub960_reset(struct ub960_data *priv, bool reset_regs) * I2C-ATR (address translator) */ -static int ub960_atr_attach_client(struct i2c_atr *atr, u32 chan_id, - const struct i2c_client *client, u16 alias) +static int ub960_atr_attach_addr(struct i2c_atr *atr, u32 chan_id, + u16 addr, u16 alias) { struct ub960_data *priv = i2c_atr_get_driver_data(atr); struct ub960_rxport *rxport = priv->rxports[chan_id]; @@ -1273,20 +1276,22 @@ static int ub960_atr_attach_client(struct i2c_atr *atr, u32 chan_id, unsigned int reg_idx; int ret = 0; - for (reg_idx = 0; reg_idx < ARRAY_SIZE(rxport->aliased_clients); reg_idx++) { - if (!rxport->aliased_clients[reg_idx]) + guard(mutex)(&rxport->aliased_addrs_lock); + + for (reg_idx = 0; reg_idx < ARRAY_SIZE(rxport->aliased_addrs); reg_idx++) { + if (!rxport->aliased_addrs[reg_idx]) break; } - if (reg_idx == ARRAY_SIZE(rxport->aliased_clients)) { + if (reg_idx == ARRAY_SIZE(rxport->aliased_addrs)) { dev_err(dev, "rx%u: alias pool exhausted\n", rxport->nport); return -EADDRNOTAVAIL; } - rxport->aliased_clients[reg_idx] = client; + rxport->aliased_addrs[reg_idx] = addr; ub960_rxport_write(priv, chan_id, UB960_RR_SLAVE_ID(reg_idx), - client->addr << 1, &ret); + addr << 1, &ret); ub960_rxport_write(priv, chan_id, UB960_RR_SLAVE_ALIAS(reg_idx), alias << 1, &ret); @@ -1294,13 +1299,13 @@ static int ub960_atr_attach_client(struct i2c_atr *atr, u32 chan_id, return ret; dev_dbg(dev, "rx%u: client 0x%02x assigned alias 0x%02x at slot %u\n", - rxport->nport, client->addr, alias, reg_idx); + rxport->nport, addr, alias, reg_idx); return 0; } -static void ub960_atr_detach_client(struct i2c_atr *atr, u32 chan_id, - const struct i2c_client *client) +static void ub960_atr_detach_addr(struct i2c_atr *atr, u32 chan_id, + u16 addr) { struct ub960_data *priv = i2c_atr_get_driver_data(atr); struct ub960_rxport *rxport = priv->rxports[chan_id]; @@ -1308,34 +1313,36 @@ static void ub960_atr_detach_client(struct i2c_atr *atr, u32 chan_id, unsigned int reg_idx; int ret; - for (reg_idx = 0; reg_idx < ARRAY_SIZE(rxport->aliased_clients); reg_idx++) { - if (rxport->aliased_clients[reg_idx] == client) + guard(mutex)(&rxport->aliased_addrs_lock); + + for (reg_idx = 0; reg_idx < ARRAY_SIZE(rxport->aliased_addrs); reg_idx++) { + if (rxport->aliased_addrs[reg_idx] == addr) break; } - if (reg_idx == ARRAY_SIZE(rxport->aliased_clients)) { + if (reg_idx == ARRAY_SIZE(rxport->aliased_addrs)) { dev_err(dev, "rx%u: client 0x%02x is not mapped!\n", - rxport->nport, client->addr); + rxport->nport, addr); return; } - rxport->aliased_clients[reg_idx] = NULL; + rxport->aliased_addrs[reg_idx] = 0; ret = ub960_rxport_write(priv, chan_id, UB960_RR_SLAVE_ALIAS(reg_idx), 0, NULL); if (ret) { dev_err(dev, "rx%u: unable to fully unmap client 0x%02x: %d\n", - rxport->nport, client->addr, ret); + rxport->nport, addr, ret); return; } dev_dbg(dev, "rx%u: client 0x%02x released at slot %u\n", rxport->nport, - client->addr, reg_idx); + addr, reg_idx); } static const struct i2c_atr_ops ub960_atr_ops = { - .attach_client = ub960_atr_attach_client, - .detach_client = ub960_atr_detach_client, + .attach_addr = ub960_atr_attach_addr, + .detach_addr = ub960_atr_detach_addr, }; static int ub960_init_atr(struct ub960_data *priv) @@ -1344,7 +1351,7 @@ static int ub960_init_atr(struct ub960_data *priv) struct i2c_adapter *parent_adap = priv->client->adapter; priv->atr = i2c_atr_new(parent_adap, dev, &ub960_atr_ops, - priv->hw_data->num_rxports); + priv->hw_data->num_rxports, 0); if (IS_ERR(priv->atr)) return PTR_ERR(priv->atr); @@ -2173,7 +2180,6 @@ static int ub960_rxport_add_serializer(struct ub960_data *priv, u8 nport) struct device *dev = &priv->client->dev; struct ds90ub9xx_platform_data *ser_pdata = &rxport->ser.pdata; struct i2c_board_info ser_info = { - .of_node = to_of_node(rxport->ser.fwnode), .fwnode = rxport->ser.fwnode, .platform_data = ser_pdata, }; @@ -4374,6 +4380,8 @@ static void ub960_rxport_free_ports(struct ub960_data *priv) fwnode_handle_put(it.rxport->source.ep_fwnode); fwnode_handle_put(it.rxport->ser.fwnode); + mutex_destroy(&it.rxport->aliased_addrs_lock); + kfree(it.rxport); priv->rxports[it.nport] = NULL; } @@ -4602,6 +4610,8 @@ static int ub960_parse_dt_rxport(struct ub960_data *priv, unsigned int nport, if (ret) goto err_put_remote_fwnode; + mutex_init(&rxport->aliased_addrs_lock); + return 0; err_put_remote_fwnode: |