Skip to content

Commit ebe70b3

Browse files
committed
Merge tag 'i2c-for-6.10-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c fixes from Wolfram Sang: "Two fixes for the testunit and and a fixup for the code reorganization of the previous wmt-driver" * tag 'i2c-for-6.10-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: i2c: testunit: discard write requests while old command is running i2c: testunit: don't erase registers after STOP i2c: viai2c: turn common code into a proper module
2 parents 921863f + c116dea commit ebe70b3

File tree

6 files changed

+143
-90
lines changed

6 files changed

+143
-90
lines changed

drivers/i2c/busses/Makefile

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ obj-$(CONFIG_I2C_SIS630) += i2c-sis630.o
2929
obj-$(CONFIG_I2C_SIS96X) += i2c-sis96x.o
3030
obj-$(CONFIG_I2C_VIA) += i2c-via.o
3131
obj-$(CONFIG_I2C_VIAPRO) += i2c-viapro.o
32-
i2c-zhaoxin-objs := i2c-viai2c-zhaoxin.o i2c-viai2c-common.o
33-
obj-$(CONFIG_I2C_ZHAOXIN) += i2c-zhaoxin.o
32+
obj-$(CONFIG_I2C_ZHAOXIN) += i2c-viai2c-zhaoxin.o i2c-viai2c-common.o
3433

3534
# Mac SMBus host controller drivers
3635
obj-$(CONFIG_I2C_HYDRA) += i2c-hydra.o
@@ -120,8 +119,7 @@ obj-$(CONFIG_I2C_TEGRA_BPMP) += i2c-tegra-bpmp.o
120119
obj-$(CONFIG_I2C_UNIPHIER) += i2c-uniphier.o
121120
obj-$(CONFIG_I2C_UNIPHIER_F) += i2c-uniphier-f.o
122121
obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o
123-
i2c-wmt-objs := i2c-viai2c-wmt.o i2c-viai2c-common.o
124-
obj-$(CONFIG_I2C_WMT) += i2c-wmt.o
122+
obj-$(CONFIG_I2C_WMT) += i2c-viai2c-wmt.o i2c-viai2c-common.o
125123
i2c-octeon-objs := i2c-octeon-core.o i2c-octeon-platdrv.o
126124
obj-$(CONFIG_I2C_OCTEON) += i2c-octeon.o
127125
i2c-thunderx-objs := i2c-octeon-core.o i2c-thunderx-pcidrv.o

drivers/i2c/busses/i2c-viai2c-common.c

Lines changed: 9 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ int viai2c_wait_bus_not_busy(struct viai2c *i2c)
1717

1818
return 0;
1919
}
20+
EXPORT_SYMBOL_GPL(viai2c_wait_bus_not_busy);
2021

2122
static int viai2c_write(struct viai2c *i2c, struct i2c_msg *pmsg, int last)
2223
{
@@ -121,6 +122,7 @@ int viai2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
121122

122123
return (ret < 0) ? ret : i;
123124
}
125+
EXPORT_SYMBOL_GPL(viai2c_xfer);
124126

125127
/*
126128
* Main process of the byte mode xfer
@@ -130,7 +132,7 @@ int viai2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
130132
* 0: there is still data that needs to be transferred
131133
* -EIO: error occurred
132134
*/
133-
static int viai2c_irq_xfer(struct viai2c *i2c)
135+
int viai2c_irq_xfer(struct viai2c *i2c)
134136
{
135137
u16 val;
136138
struct i2c_msg *msg = i2c->msg;
@@ -171,51 +173,11 @@ static int viai2c_irq_xfer(struct viai2c *i2c)
171173

172174
return i2c->xfered_len == msg->len;
173175
}
174-
175-
int __weak viai2c_fifo_irq_xfer(struct viai2c *i2c, bool irq)
176-
{
177-
return 0;
178-
}
179-
180-
static irqreturn_t viai2c_isr(int irq, void *data)
181-
{
182-
struct viai2c *i2c = data;
183-
u8 status;
184-
185-
/* save the status and write-clear it */
186-
status = readw(i2c->base + VIAI2C_REG_ISR);
187-
if (!status && i2c->platform == VIAI2C_PLAT_ZHAOXIN)
188-
return IRQ_NONE;
189-
190-
writew(status, i2c->base + VIAI2C_REG_ISR);
191-
192-
i2c->ret = 0;
193-
if (status & VIAI2C_ISR_NACK_ADDR)
194-
i2c->ret = -EIO;
195-
196-
if (i2c->platform == VIAI2C_PLAT_WMT && (status & VIAI2C_ISR_SCL_TIMEOUT))
197-
i2c->ret = -ETIMEDOUT;
198-
199-
if (!i2c->ret) {
200-
if (i2c->mode == VIAI2C_BYTE_MODE)
201-
i2c->ret = viai2c_irq_xfer(i2c);
202-
else
203-
i2c->ret = viai2c_fifo_irq_xfer(i2c, true);
204-
}
205-
206-
/* All the data has been successfully transferred or error occurred */
207-
if (i2c->ret)
208-
complete(&i2c->complete);
209-
210-
return IRQ_HANDLED;
211-
}
176+
EXPORT_SYMBOL_GPL(viai2c_irq_xfer);
212177

213178
int viai2c_init(struct platform_device *pdev, struct viai2c **pi2c, int plat)
214179
{
215-
int err;
216-
int irq_flags;
217180
struct viai2c *i2c;
218-
struct device_node *np = pdev->dev.of_node;
219181

220182
i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
221183
if (!i2c)
@@ -225,32 +187,17 @@ int viai2c_init(struct platform_device *pdev, struct viai2c **pi2c, int plat)
225187
if (IS_ERR(i2c->base))
226188
return PTR_ERR(i2c->base);
227189

228-
if (plat == VIAI2C_PLAT_WMT) {
229-
irq_flags = 0;
230-
i2c->irq = irq_of_parse_and_map(np, 0);
231-
if (!i2c->irq)
232-
return -EINVAL;
233-
} else if (plat == VIAI2C_PLAT_ZHAOXIN) {
234-
irq_flags = IRQF_SHARED;
235-
i2c->irq = platform_get_irq(pdev, 0);
236-
if (i2c->irq < 0)
237-
return i2c->irq;
238-
} else {
239-
return dev_err_probe(&pdev->dev, -EINVAL, "wrong platform type\n");
240-
}
241-
242190
i2c->platform = plat;
243191

244-
err = devm_request_irq(&pdev->dev, i2c->irq, viai2c_isr,
245-
irq_flags, pdev->name, i2c);
246-
if (err)
247-
return dev_err_probe(&pdev->dev, err,
248-
"failed to request irq %i\n", i2c->irq);
249-
250192
i2c->dev = &pdev->dev;
251193
init_completion(&i2c->complete);
252194
platform_set_drvdata(pdev, i2c);
253195

254196
*pi2c = i2c;
255197
return 0;
256198
}
199+
EXPORT_SYMBOL_GPL(viai2c_init);
200+
201+
MODULE_DESCRIPTION("Via/Wondermedia/Zhaoxin I2C master-mode bus adapter");
202+
MODULE_AUTHOR("Tony Prisk <[email protected]>");
203+
MODULE_LICENSE("GPL");

drivers/i2c/busses/i2c-viai2c-common.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,6 @@ struct viai2c {
8080
int viai2c_wait_bus_not_busy(struct viai2c *i2c);
8181
int viai2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num);
8282
int viai2c_init(struct platform_device *pdev, struct viai2c **pi2c, int plat);
83-
int viai2c_fifo_irq_xfer(struct viai2c *i2c, bool irq);
83+
int viai2c_irq_xfer(struct viai2c *i2c);
8484

8585
#endif

drivers/i2c/busses/i2c-viai2c-wmt.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,32 @@ static int wmt_i2c_reset_hardware(struct viai2c *i2c)
7272
return 0;
7373
}
7474

75+
static irqreturn_t wmt_i2c_isr(int irq, void *data)
76+
{
77+
struct viai2c *i2c = data;
78+
u8 status;
79+
80+
/* save the status and write-clear it */
81+
status = readw(i2c->base + VIAI2C_REG_ISR);
82+
writew(status, i2c->base + VIAI2C_REG_ISR);
83+
84+
i2c->ret = 0;
85+
if (status & VIAI2C_ISR_NACK_ADDR)
86+
i2c->ret = -EIO;
87+
88+
if (status & VIAI2C_ISR_SCL_TIMEOUT)
89+
i2c->ret = -ETIMEDOUT;
90+
91+
if (!i2c->ret)
92+
i2c->ret = viai2c_irq_xfer(i2c);
93+
94+
/* All the data has been successfully transferred or error occurred */
95+
if (i2c->ret)
96+
complete(&i2c->complete);
97+
98+
return IRQ_HANDLED;
99+
}
100+
75101
static int wmt_i2c_probe(struct platform_device *pdev)
76102
{
77103
struct device_node *np = pdev->dev.of_node;
@@ -84,6 +110,16 @@ static int wmt_i2c_probe(struct platform_device *pdev)
84110
if (err)
85111
return err;
86112

113+
i2c->irq = platform_get_irq(pdev, 0);
114+
if (i2c->irq < 0)
115+
return i2c->irq;
116+
117+
err = devm_request_irq(&pdev->dev, i2c->irq, wmt_i2c_isr,
118+
0, pdev->name, i2c);
119+
if (err)
120+
return dev_err_probe(&pdev->dev, err,
121+
"failed to request irq %i\n", i2c->irq);
122+
87123
i2c->clk = of_clk_get(np, 0);
88124
if (IS_ERR(i2c->clk)) {
89125
dev_err(&pdev->dev, "unable to request clock\n");

drivers/i2c/busses/i2c-viai2c-zhaoxin.c

Lines changed: 91 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,7 @@ struct viai2c_zhaoxin {
4949
u16 xfer_len;
5050
};
5151

52-
/* 'irq == true' means in interrupt context */
53-
int viai2c_fifo_irq_xfer(struct viai2c *i2c, bool irq)
52+
static int viai2c_fifo_xfer(struct viai2c *i2c)
5453
{
5554
u16 i;
5655
u8 tmp;
@@ -59,17 +58,6 @@ int viai2c_fifo_irq_xfer(struct viai2c *i2c, bool irq)
5958
bool read = !!(msg->flags & I2C_M_RD);
6059
struct viai2c_zhaoxin *priv = i2c->pltfm_priv;
6160

62-
if (irq) {
63-
/* get the received data */
64-
if (read)
65-
for (i = 0; i < priv->xfer_len; i++)
66-
msg->buf[i2c->xfered_len + i] = ioread8(base + ZXI2C_REG_HRDR);
67-
68-
i2c->xfered_len += priv->xfer_len;
69-
if (i2c->xfered_len == msg->len)
70-
return 1;
71-
}
72-
7361
/* reset fifo buffer */
7462
tmp = ioread8(base + ZXI2C_REG_HCR);
7563
iowrite8(tmp | ZXI2C_HCR_RST_FIFO, base + ZXI2C_REG_HCR);
@@ -92,18 +80,59 @@ int viai2c_fifo_irq_xfer(struct viai2c *i2c, bool irq)
9280
iowrite8(tmp, base + VIAI2C_REG_CR);
9381
}
9482

95-
if (irq) {
96-
/* continue transmission */
97-
tmp = ioread8(base + VIAI2C_REG_CR);
98-
iowrite8(tmp |= VIAI2C_CR_CPU_RDY, base + VIAI2C_REG_CR);
83+
u16 tcr_val = i2c->tcr;
84+
85+
/* start transmission */
86+
tcr_val |= read ? VIAI2C_TCR_READ : 0;
87+
writew(tcr_val | msg->addr, base + VIAI2C_REG_TCR);
88+
89+
return 0;
90+
}
91+
92+
static int viai2c_fifo_irq_xfer(struct viai2c *i2c)
93+
{
94+
u16 i;
95+
u8 tmp;
96+
struct i2c_msg *msg = i2c->msg;
97+
void __iomem *base = i2c->base;
98+
bool read = !!(msg->flags & I2C_M_RD);
99+
struct viai2c_zhaoxin *priv = i2c->pltfm_priv;
100+
101+
/* get the received data */
102+
if (read)
103+
for (i = 0; i < priv->xfer_len; i++)
104+
msg->buf[i2c->xfered_len + i] = ioread8(base + ZXI2C_REG_HRDR);
105+
106+
i2c->xfered_len += priv->xfer_len;
107+
if (i2c->xfered_len == msg->len)
108+
return 1;
109+
110+
/* reset fifo buffer */
111+
tmp = ioread8(base + ZXI2C_REG_HCR);
112+
iowrite8(tmp | ZXI2C_HCR_RST_FIFO, base + ZXI2C_REG_HCR);
113+
114+
/* set xfer len */
115+
priv->xfer_len = min_t(u16, msg->len - i2c->xfered_len, ZXI2C_FIFO_SIZE);
116+
if (read) {
117+
iowrite8(priv->xfer_len - 1, base + ZXI2C_REG_HRLR);
99118
} else {
100-
u16 tcr_val = i2c->tcr;
119+
iowrite8(priv->xfer_len - 1, base + ZXI2C_REG_HTLR);
120+
/* set write data */
121+
for (i = 0; i < priv->xfer_len; i++)
122+
iowrite8(msg->buf[i2c->xfered_len + i], base + ZXI2C_REG_HTDR);
123+
}
101124

102-
/* start transmission */
103-
tcr_val |= read ? VIAI2C_TCR_READ : 0;
104-
writew(tcr_val | msg->addr, base + VIAI2C_REG_TCR);
125+
/* prepare to stop transmission */
126+
if (priv->hrv && msg->len == (i2c->xfered_len + priv->xfer_len)) {
127+
tmp = ioread8(base + VIAI2C_REG_CR);
128+
tmp |= read ? VIAI2C_CR_RX_END : VIAI2C_CR_TX_END;
129+
iowrite8(tmp, base + VIAI2C_REG_CR);
105130
}
106131

132+
/* continue transmission */
133+
tmp = ioread8(base + VIAI2C_REG_CR);
134+
iowrite8(tmp |= VIAI2C_CR_CPU_RDY, base + VIAI2C_REG_CR);
135+
107136
return 0;
108137
}
109138

@@ -135,7 +164,7 @@ static int zxi2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int
135164
priv->xfer_len = 0;
136165
i2c->xfered_len = 0;
137166

138-
viai2c_fifo_irq_xfer(i2c, 0);
167+
viai2c_fifo_xfer(i2c);
139168

140169
if (!wait_for_completion_timeout(&i2c->complete, VIAI2C_TIMEOUT))
141170
return -ETIMEDOUT;
@@ -228,6 +257,36 @@ static void zxi2c_get_bus_speed(struct viai2c *i2c)
228257
dev_info(i2c->dev, "speed mode is %s\n", i2c_freq_mode_string(params[0]));
229258
}
230259

260+
static irqreturn_t zxi2c_isr(int irq, void *data)
261+
{
262+
struct viai2c *i2c = data;
263+
u8 status;
264+
265+
/* save the status and write-clear it */
266+
status = readw(i2c->base + VIAI2C_REG_ISR);
267+
if (!status)
268+
return IRQ_NONE;
269+
270+
writew(status, i2c->base + VIAI2C_REG_ISR);
271+
272+
i2c->ret = 0;
273+
if (status & VIAI2C_ISR_NACK_ADDR)
274+
i2c->ret = -EIO;
275+
276+
if (!i2c->ret) {
277+
if (i2c->mode == VIAI2C_BYTE_MODE)
278+
i2c->ret = viai2c_irq_xfer(i2c);
279+
else
280+
i2c->ret = viai2c_fifo_irq_xfer(i2c);
281+
}
282+
283+
/* All the data has been successfully transferred or error occurred */
284+
if (i2c->ret)
285+
complete(&i2c->complete);
286+
287+
return IRQ_HANDLED;
288+
}
289+
231290
static int zxi2c_probe(struct platform_device *pdev)
232291
{
233292
int error;
@@ -239,6 +298,16 @@ static int zxi2c_probe(struct platform_device *pdev)
239298
if (error)
240299
return error;
241300

301+
i2c->irq = platform_get_irq(pdev, 0);
302+
if (i2c->irq < 0)
303+
return i2c->irq;
304+
305+
error = devm_request_irq(&pdev->dev, i2c->irq, zxi2c_isr,
306+
IRQF_SHARED, pdev->name, i2c);
307+
if (error)
308+
return dev_err_probe(&pdev->dev, error,
309+
"failed to request irq %i\n", i2c->irq);
310+
242311
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
243312
if (!priv)
244313
return -ENOMEM;

drivers/i2c/i2c-slave-testunit.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,12 @@ static int i2c_slave_testunit_slave_cb(struct i2c_client *client,
118118
queue_delayed_work(system_long_wq, &tu->worker,
119119
msecs_to_jiffies(10 * tu->regs[TU_REG_DELAY]));
120120
}
121-
fallthrough;
121+
break;
122122

123123
case I2C_SLAVE_WRITE_REQUESTED:
124+
if (test_bit(TU_FLAG_IN_PROCESS, &tu->flags))
125+
return -EBUSY;
126+
124127
memset(tu->regs, 0, TU_NUM_REGS);
125128
tu->reg_idx = 0;
126129
break;

0 commit comments

Comments
 (0)