Skip to content

Commit bd66be5

Browse files
committed
Merge branch 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c fixes from Wolfram Sang: "Two more I2C driver bugfixes" * 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: i2c: mpc: Use atomic read and fix break condition i2c: virtio: fix completion handling
2 parents 2acdaf5 + a74c313 commit bd66be5

File tree

2 files changed

+13
-21
lines changed

2 files changed

+13
-21
lines changed

drivers/i2c/busses/i2c-mpc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -636,7 +636,7 @@ static irqreturn_t mpc_i2c_isr(int irq, void *dev_id)
636636
status = readb(i2c->base + MPC_I2C_SR);
637637
if (status & CSR_MIF) {
638638
/* Wait up to 100us for transfer to properly complete */
639-
readb_poll_timeout(i2c->base + MPC_I2C_SR, status, !(status & CSR_MCF), 0, 100);
639+
readb_poll_timeout_atomic(i2c->base + MPC_I2C_SR, status, status & CSR_MCF, 0, 100);
640640
writeb(0, i2c->base + MPC_I2C_SR);
641641
mpc_i2c_do_intr(i2c, status);
642642
return IRQ_HANDLED;

drivers/i2c/busses/i2c-virtio.c

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,34 +22,36 @@
2222
/**
2323
* struct virtio_i2c - virtio I2C data
2424
* @vdev: virtio device for this controller
25-
* @completion: completion of virtio I2C message
2625
* @adap: I2C adapter for this controller
2726
* @vq: the virtio virtqueue for communication
2827
*/
2928
struct virtio_i2c {
3029
struct virtio_device *vdev;
31-
struct completion completion;
3230
struct i2c_adapter adap;
3331
struct virtqueue *vq;
3432
};
3533

3634
/**
3735
* struct virtio_i2c_req - the virtio I2C request structure
36+
* @completion: completion of virtio I2C message
3837
* @out_hdr: the OUT header of the virtio I2C message
3938
* @buf: the buffer into which data is read, or from which it's written
4039
* @in_hdr: the IN header of the virtio I2C message
4140
*/
4241
struct virtio_i2c_req {
42+
struct completion completion;
4343
struct virtio_i2c_out_hdr out_hdr ____cacheline_aligned;
4444
uint8_t *buf ____cacheline_aligned;
4545
struct virtio_i2c_in_hdr in_hdr ____cacheline_aligned;
4646
};
4747

4848
static void virtio_i2c_msg_done(struct virtqueue *vq)
4949
{
50-
struct virtio_i2c *vi = vq->vdev->priv;
50+
struct virtio_i2c_req *req;
51+
unsigned int len;
5152

52-
complete(&vi->completion);
53+
while ((req = virtqueue_get_buf(vq, &len)))
54+
complete(&req->completion);
5355
}
5456

5557
static int virtio_i2c_prepare_reqs(struct virtqueue *vq,
@@ -62,6 +64,8 @@ static int virtio_i2c_prepare_reqs(struct virtqueue *vq,
6264
for (i = 0; i < num; i++) {
6365
int outcnt = 0, incnt = 0;
6466

67+
init_completion(&reqs[i].completion);
68+
6569
/*
6670
* Only 7-bit mode supported for this moment. For the address
6771
* format, Please check the Virtio I2C Specification.
@@ -106,21 +110,15 @@ static int virtio_i2c_complete_reqs(struct virtqueue *vq,
106110
struct virtio_i2c_req *reqs,
107111
struct i2c_msg *msgs, int num)
108112
{
109-
struct virtio_i2c_req *req;
110113
bool failed = false;
111-
unsigned int len;
112114
int i, j = 0;
113115

114116
for (i = 0; i < num; i++) {
115-
/* Detach the ith request from the vq */
116-
req = virtqueue_get_buf(vq, &len);
117+
struct virtio_i2c_req *req = &reqs[i];
117118

118-
/*
119-
* Condition req == &reqs[i] should always meet since we have
120-
* total num requests in the vq. reqs[i] can never be NULL here.
121-
*/
122-
if (!failed && (WARN_ON(req != &reqs[i]) ||
123-
req->in_hdr.status != VIRTIO_I2C_MSG_OK))
119+
wait_for_completion(&req->completion);
120+
121+
if (!failed && req->in_hdr.status != VIRTIO_I2C_MSG_OK)
124122
failed = true;
125123

126124
i2c_put_dma_safe_msg_buf(reqs[i].buf, &msgs[i], !failed);
@@ -156,12 +154,8 @@ static int virtio_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
156154
* remote here to clear the virtqueue, so we can try another set of
157155
* messages later on.
158156
*/
159-
160-
reinit_completion(&vi->completion);
161157
virtqueue_kick(vq);
162158

163-
wait_for_completion(&vi->completion);
164-
165159
count = virtio_i2c_complete_reqs(vq, reqs, msgs, count);
166160

167161
err_free:
@@ -210,8 +204,6 @@ static int virtio_i2c_probe(struct virtio_device *vdev)
210204
vdev->priv = vi;
211205
vi->vdev = vdev;
212206

213-
init_completion(&vi->completion);
214-
215207
ret = virtio_i2c_setup_vqs(vi);
216208
if (ret)
217209
return ret;

0 commit comments

Comments
 (0)