aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-12-20 18:19:55 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-12-20 18:19:55 -0500
commit74f65bbf46da4f32ddeab221e2de6d6e15f806bd (patch)
treeee947376544b630d2ab6a23494abb754906ffd5c
parent1351522b5f627f06e44e781805b5bd5c01566cf3 (diff)
parent649ac63a9ae5e08b7123f2fa98c2bf42f033bdb9 (diff)
Merge branch 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c fixes from Wolfram Sang. * 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: i2c: mux: mlxcpld: fix i2c mux selection caching i2c: designware: fix wrong Tx/Rx FIFO for ACPI i2c: xgene: Fix missing code of DTB support i2c: mux: pca954x: fix i2c mux selection caching i2c: octeon: thunderx: Limit register access retries
-rw-r--r--drivers/i2c/busses/i2c-designware-platdrv.c31
-rw-r--r--drivers/i2c/busses/i2c-octeon-core.c4
-rw-r--r--drivers/i2c/busses/i2c-octeon-core.h21
-rw-r--r--drivers/i2c/busses/i2c-xgene-slimpro.c1
-rw-r--r--drivers/i2c/muxes/i2c-mux-mlxcpld.c24
-rw-r--r--drivers/i2c/muxes/i2c-mux-pca954x.c5
6 files changed, 61 insertions, 25 deletions
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
index 08153ea4d848..6ce431323125 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -150,6 +150,29 @@ static int i2c_dw_plat_prepare_clk(struct dw_i2c_dev *i_dev, bool prepare)
150 return 0; 150 return 0;
151} 151}
152 152
153static void dw_i2c_set_fifo_size(struct dw_i2c_dev *dev, int id)
154{
155 u32 param, tx_fifo_depth, rx_fifo_depth;
156
157 /*
158 * Try to detect the FIFO depth if not set by interface driver,
159 * the depth could be from 2 to 256 from HW spec.
160 */
161 param = i2c_dw_read_comp_param(dev);
162 tx_fifo_depth = ((param >> 16) & 0xff) + 1;
163 rx_fifo_depth = ((param >> 8) & 0xff) + 1;
164 if (!dev->tx_fifo_depth) {
165 dev->tx_fifo_depth = tx_fifo_depth;
166 dev->rx_fifo_depth = rx_fifo_depth;
167 dev->adapter.nr = id;
168 } else if (tx_fifo_depth >= 2) {
169 dev->tx_fifo_depth = min_t(u32, dev->tx_fifo_depth,
170 tx_fifo_depth);
171 dev->rx_fifo_depth = min_t(u32, dev->rx_fifo_depth,
172 rx_fifo_depth);
173 }
174}
175
153static int dw_i2c_plat_probe(struct platform_device *pdev) 176static int dw_i2c_plat_probe(struct platform_device *pdev)
154{ 177{
155 struct dw_i2c_platform_data *pdata = dev_get_platdata(&pdev->dev); 178 struct dw_i2c_platform_data *pdata = dev_get_platdata(&pdev->dev);
@@ -245,13 +268,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
245 1000000); 268 1000000);
246 } 269 }
247 270
248 if (!dev->tx_fifo_depth) { 271 dw_i2c_set_fifo_size(dev, pdev->id);
249 u32 param1 = i2c_dw_read_comp_param(dev);
250
251 dev->tx_fifo_depth = ((param1 >> 16) & 0xff) + 1;
252 dev->rx_fifo_depth = ((param1 >> 8) & 0xff) + 1;
253 dev->adapter.nr = pdev->id;
254 }
255 272
256 adap = &dev->adapter; 273 adap = &dev->adapter;
257 adap->owner = THIS_MODULE; 274 adap->owner = THIS_MODULE;
diff --git a/drivers/i2c/busses/i2c-octeon-core.c b/drivers/i2c/busses/i2c-octeon-core.c
index 3d10f1a802be..1d8775799056 100644
--- a/drivers/i2c/busses/i2c-octeon-core.c
+++ b/drivers/i2c/busses/i2c-octeon-core.c
@@ -342,7 +342,9 @@ static int octeon_i2c_read(struct octeon_i2c *i2c, int target,
342 if (result) 342 if (result)
343 return result; 343 return result;
344 344
345 data[i] = octeon_i2c_data_read(i2c); 345 data[i] = octeon_i2c_data_read(i2c, &result);
346 if (result)
347 return result;
346 if (recv_len && i == 0) { 348 if (recv_len && i == 0) {
347 if (data[i] > I2C_SMBUS_BLOCK_MAX + 1) 349 if (data[i] > I2C_SMBUS_BLOCK_MAX + 1)
348 return -EPROTO; 350 return -EPROTO;
diff --git a/drivers/i2c/busses/i2c-octeon-core.h b/drivers/i2c/busses/i2c-octeon-core.h
index 87151ea74acd..e160f838c254 100644
--- a/drivers/i2c/busses/i2c-octeon-core.h
+++ b/drivers/i2c/busses/i2c-octeon-core.h
@@ -141,11 +141,14 @@ static inline void octeon_i2c_writeq_flush(u64 val, void __iomem *addr)
141 */ 141 */
142static inline void octeon_i2c_reg_write(struct octeon_i2c *i2c, u64 eop_reg, u8 data) 142static inline void octeon_i2c_reg_write(struct octeon_i2c *i2c, u64 eop_reg, u8 data)
143{ 143{
144 int tries = 1000;
144 u64 tmp; 145 u64 tmp;
145 146
146 __raw_writeq(SW_TWSI_V | eop_reg | data, i2c->twsi_base + SW_TWSI(i2c)); 147 __raw_writeq(SW_TWSI_V | eop_reg | data, i2c->twsi_base + SW_TWSI(i2c));
147 do { 148 do {
148 tmp = __raw_readq(i2c->twsi_base + SW_TWSI(i2c)); 149 tmp = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
150 if (--tries < 0)
151 return;
149 } while ((tmp & SW_TWSI_V) != 0); 152 } while ((tmp & SW_TWSI_V) != 0);
150} 153}
151 154
@@ -163,24 +166,32 @@ static inline void octeon_i2c_reg_write(struct octeon_i2c *i2c, u64 eop_reg, u8
163 * 166 *
164 * The I2C core registers are accessed indirectly via the SW_TWSI CSR. 167 * The I2C core registers are accessed indirectly via the SW_TWSI CSR.
165 */ 168 */
166static inline u8 octeon_i2c_reg_read(struct octeon_i2c *i2c, u64 eop_reg) 169static inline int octeon_i2c_reg_read(struct octeon_i2c *i2c, u64 eop_reg,
170 int *error)
167{ 171{
172 int tries = 1000;
168 u64 tmp; 173 u64 tmp;
169 174
170 __raw_writeq(SW_TWSI_V | eop_reg | SW_TWSI_R, i2c->twsi_base + SW_TWSI(i2c)); 175 __raw_writeq(SW_TWSI_V | eop_reg | SW_TWSI_R, i2c->twsi_base + SW_TWSI(i2c));
171 do { 176 do {
172 tmp = __raw_readq(i2c->twsi_base + SW_TWSI(i2c)); 177 tmp = __raw_readq(i2c->twsi_base + SW_TWSI(i2c));
178 if (--tries < 0) {
179 /* signal that the returned data is invalid */
180 if (error)
181 *error = -EIO;
182 return 0;
183 }
173 } while ((tmp & SW_TWSI_V) != 0); 184 } while ((tmp & SW_TWSI_V) != 0);
174 185
175 return tmp & 0xFF; 186 return tmp & 0xFF;
176} 187}
177 188
178#define octeon_i2c_ctl_read(i2c) \ 189#define octeon_i2c_ctl_read(i2c) \
179 octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_CTL) 190 octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_CTL, NULL)
180#define octeon_i2c_data_read(i2c) \ 191#define octeon_i2c_data_read(i2c, error) \
181 octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_DATA) 192 octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_DATA, error)
182#define octeon_i2c_stat_read(i2c) \ 193#define octeon_i2c_stat_read(i2c) \
183 octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_STAT) 194 octeon_i2c_reg_read(i2c, SW_TWSI_EOP_TWSI_STAT, NULL)
184 195
185/** 196/**
186 * octeon_i2c_read_int - read the TWSI_INT register 197 * octeon_i2c_read_int - read the TWSI_INT register
diff --git a/drivers/i2c/busses/i2c-xgene-slimpro.c b/drivers/i2c/busses/i2c-xgene-slimpro.c
index 05cf192ef1ac..0ab1e55558bc 100644
--- a/drivers/i2c/busses/i2c-xgene-slimpro.c
+++ b/drivers/i2c/busses/i2c-xgene-slimpro.c
@@ -415,6 +415,7 @@ static int xgene_slimpro_i2c_probe(struct platform_device *pdev)
415 adapter->algo = &xgene_slimpro_i2c_algorithm; 415 adapter->algo = &xgene_slimpro_i2c_algorithm;
416 adapter->class = I2C_CLASS_HWMON; 416 adapter->class = I2C_CLASS_HWMON;
417 adapter->dev.parent = &pdev->dev; 417 adapter->dev.parent = &pdev->dev;
418 adapter->dev.of_node = pdev->dev.of_node;
418 i2c_set_adapdata(adapter, ctx); 419 i2c_set_adapdata(adapter, ctx);
419 rc = i2c_add_adapter(adapter); 420 rc = i2c_add_adapter(adapter);
420 if (rc) { 421 if (rc) {
diff --git a/drivers/i2c/muxes/i2c-mux-mlxcpld.c b/drivers/i2c/muxes/i2c-mux-mlxcpld.c
index 3ab654bbfab5..b7ca249ec9c3 100644
--- a/drivers/i2c/muxes/i2c-mux-mlxcpld.c
+++ b/drivers/i2c/muxes/i2c-mux-mlxcpld.c
@@ -95,6 +95,7 @@ static int mlxcpld_mux_reg_write(struct i2c_adapter *adap,
95 struct i2c_client *client, u8 val) 95 struct i2c_client *client, u8 val)
96{ 96{
97 struct mlxcpld_mux_plat_data *pdata = dev_get_platdata(&client->dev); 97 struct mlxcpld_mux_plat_data *pdata = dev_get_platdata(&client->dev);
98 int ret = -ENODEV;
98 99
99 if (adap->algo->master_xfer) { 100 if (adap->algo->master_xfer) {
100 struct i2c_msg msg; 101 struct i2c_msg msg;
@@ -104,17 +105,21 @@ static int mlxcpld_mux_reg_write(struct i2c_adapter *adap,
104 msg.flags = 0; 105 msg.flags = 0;
105 msg.len = 2; 106 msg.len = 2;
106 msg.buf = msgbuf; 107 msg.buf = msgbuf;
107 return __i2c_transfer(adap, &msg, 1); 108 ret = __i2c_transfer(adap, &msg, 1);
109
110 if (ret >= 0 && ret != 1)
111 ret = -EREMOTEIO;
108 } else if (adap->algo->smbus_xfer) { 112 } else if (adap->algo->smbus_xfer) {
109 union i2c_smbus_data data; 113 union i2c_smbus_data data;
110 114
111 data.byte = val; 115 data.byte = val;
112 return adap->algo->smbus_xfer(adap, client->addr, 116 ret = adap->algo->smbus_xfer(adap, client->addr,
113 client->flags, I2C_SMBUS_WRITE, 117 client->flags, I2C_SMBUS_WRITE,
114 pdata->sel_reg_addr, 118 pdata->sel_reg_addr,
115 I2C_SMBUS_BYTE_DATA, &data); 119 I2C_SMBUS_BYTE_DATA, &data);
116 } else 120 }
117 return -ENODEV; 121
122 return ret;
118} 123}
119 124
120static int mlxcpld_mux_select_chan(struct i2c_mux_core *muxc, u32 chan) 125static int mlxcpld_mux_select_chan(struct i2c_mux_core *muxc, u32 chan)
@@ -127,10 +132,7 @@ static int mlxcpld_mux_select_chan(struct i2c_mux_core *muxc, u32 chan)
127 /* Only select the channel if its different from the last channel */ 132 /* Only select the channel if its different from the last channel */
128 if (data->last_chan != regval) { 133 if (data->last_chan != regval) {
129 err = mlxcpld_mux_reg_write(muxc->parent, client, regval); 134 err = mlxcpld_mux_reg_write(muxc->parent, client, regval);
130 if (err) 135 data->last_chan = err < 0 ? 0 : regval;
131 data->last_chan = 0;
132 else
133 data->last_chan = regval;
134 } 136 }
135 137
136 return err; 138 return err;
diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
index 9a348ee4dc14..dd18b9ccb1f4 100644
--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
+++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
@@ -167,6 +167,9 @@ static int pca954x_reg_write(struct i2c_adapter *adap,
167 buf[0] = val; 167 buf[0] = val;
168 msg.buf = buf; 168 msg.buf = buf;
169 ret = __i2c_transfer(adap, &msg, 1); 169 ret = __i2c_transfer(adap, &msg, 1);
170
171 if (ret >= 0 && ret != 1)
172 ret = -EREMOTEIO;
170 } else { 173 } else {
171 union i2c_smbus_data data; 174 union i2c_smbus_data data;
172 ret = adap->algo->smbus_xfer(adap, client->addr, 175 ret = adap->algo->smbus_xfer(adap, client->addr,
@@ -195,7 +198,7 @@ static int pca954x_select_chan(struct i2c_mux_core *muxc, u32 chan)
195 /* Only select the channel if its different from the last channel */ 198 /* Only select the channel if its different from the last channel */
196 if (data->last_chan != regval) { 199 if (data->last_chan != regval) {
197 ret = pca954x_reg_write(muxc->parent, client, regval); 200 ret = pca954x_reg_write(muxc->parent, client, regval);
198 data->last_chan = ret ? 0 : regval; 201 data->last_chan = ret < 0 ? 0 : regval;
199 } 202 }
200 203
201 return ret; 204 return ret;