Skip to content

Commit 33f1459

Browse files
committed
Merge branch 'i2c-embedded/for-current' of git://git.pengutronix.de/git/wsa/linux
Pull i2c fixes from Wolfram Sang: "Bugfixes for the i2c subsystem. Except for a few one-liners, there is mainly one revert because of an overlooked dependency. Since there is no linux-next at the moment, I did some extra testing, and all was fine for me." * 'i2c-embedded/for-current' of git://git.pengutronix.de/git/wsa/linux: i2c: mxs: Handle i2c DMA failure properly i2c: s3c2410: Fix code to free gpios i2c: omap: ensure writes to dev->buf_len are ordered Revert "ARM: OMAP: convert I2C driver to PM QoS for MPU latency constraints" i2c: at91: fix SMBus quick command
2 parents f470b8c + 958f988 commit 33f1459

6 files changed

Lines changed: 48 additions & 20 deletions

File tree

arch/arm/plat-omap/i2c.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,14 @@
2626
#include <linux/kernel.h>
2727
#include <linux/platform_device.h>
2828
#include <linux/i2c.h>
29+
#include <linux/i2c-omap.h>
2930
#include <linux/slab.h>
3031
#include <linux/err.h>
3132
#include <linux/clk.h>
3233

3334
#include <mach/irqs.h>
3435
#include <plat/i2c.h>
36+
#include <plat/omap-pm.h>
3537
#include <plat/omap_device.h>
3638

3739
#define OMAP_I2C_SIZE 0x3f
@@ -127,6 +129,16 @@ static inline int omap1_i2c_add_bus(int bus_id)
127129

128130

129131
#ifdef CONFIG_ARCH_OMAP2PLUS
132+
/*
133+
* XXX This function is a temporary compatibility wrapper - only
134+
* needed until the I2C driver can be converted to call
135+
* omap_pm_set_max_dev_wakeup_lat() and handle a return code.
136+
*/
137+
static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t)
138+
{
139+
omap_pm_set_max_mpu_wakeup_lat(dev, t);
140+
}
141+
130142
static inline int omap2_i2c_add_bus(int bus_id)
131143
{
132144
int l;
@@ -158,6 +170,15 @@ static inline int omap2_i2c_add_bus(int bus_id)
158170
dev_attr = (struct omap_i2c_dev_attr *)oh->dev_attr;
159171
pdata->flags = dev_attr->flags;
160172

173+
/*
174+
* When waiting for completion of a i2c transfer, we need to
175+
* set a wake up latency constraint for the MPU. This is to
176+
* ensure quick enough wakeup from idle, when transfer
177+
* completes.
178+
* Only omap3 has support for constraints
179+
*/
180+
if (cpu_is_omap34xx())
181+
pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
161182
pdev = omap_device_build(name, bus_id, oh, pdata,
162183
sizeof(struct omap_i2c_bus_platform_data),
163184
NULL, 0, 0);

drivers/i2c/busses/i2c-at91.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#define AT91_TWI_STOP 0x0002 /* Send a Stop Condition */
4040
#define AT91_TWI_MSEN 0x0004 /* Master Transfer Enable */
4141
#define AT91_TWI_SVDIS 0x0020 /* Slave Transfer Disable */
42+
#define AT91_TWI_QUICK 0x0040 /* SMBus quick command */
4243
#define AT91_TWI_SWRST 0x0080 /* Software Reset */
4344

4445
#define AT91_TWI_MMR 0x0004 /* Master Mode Register */
@@ -212,7 +213,11 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)
212213

213214
INIT_COMPLETION(dev->cmd_complete);
214215
dev->transfer_status = 0;
215-
if (dev->msg->flags & I2C_M_RD) {
216+
217+
if (!dev->buf_len) {
218+
at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_QUICK);
219+
at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_TXCOMP);
220+
} else if (dev->msg->flags & I2C_M_RD) {
216221
unsigned start_flags = AT91_TWI_START;
217222

218223
if (at91_twi_read(dev, AT91_TWI_SR) & AT91_TWI_RXRDY) {

drivers/i2c/busses/i2c-mxs.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,12 +287,14 @@ static int mxs_i2c_dma_setup_xfer(struct i2c_adapter *adap,
287287
select_init_dma_fail:
288288
dma_unmap_sg(i2c->dev, &i2c->sg_io[0], 1, DMA_TO_DEVICE);
289289
select_init_pio_fail:
290+
dmaengine_terminate_all(i2c->dmach);
290291
return -EINVAL;
291292

292293
/* Write failpath. */
293294
write_init_dma_fail:
294295
dma_unmap_sg(i2c->dev, i2c->sg_io, 2, DMA_TO_DEVICE);
295296
write_init_pio_fail:
297+
dmaengine_terminate_all(i2c->dmach);
296298
return -EINVAL;
297299
}
298300

drivers/i2c/busses/i2c-omap.c

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
#include <linux/slab.h>
4444
#include <linux/i2c-omap.h>
4545
#include <linux/pm_runtime.h>
46-
#include <linux/pm_qos.h>
4746

4847
/* I2C controller revisions */
4948
#define OMAP_I2C_OMAP1_REV_2 0x20
@@ -187,8 +186,9 @@ struct omap_i2c_dev {
187186
int reg_shift; /* bit shift for I2C register addresses */
188187
struct completion cmd_complete;
189188
struct resource *ioarea;
190-
u32 latency; /* maximum MPU wkup latency */
191-
struct pm_qos_request pm_qos_request;
189+
u32 latency; /* maximum mpu wkup latency */
190+
void (*set_mpu_wkup_lat)(struct device *dev,
191+
long latency);
192192
u32 speed; /* Speed of bus in kHz */
193193
u32 dtrev; /* extra revision from DT */
194194
u32 flags;
@@ -494,7 +494,9 @@ static void omap_i2c_resize_fifo(struct omap_i2c_dev *dev, u8 size, bool is_rx)
494494
dev->b_hw = 1; /* Enable hardware fixes */
495495

496496
/* calculate wakeup latency constraint for MPU */
497-
dev->latency = (1000000 * dev->threshold) / (1000 * dev->speed / 8);
497+
if (dev->set_mpu_wkup_lat != NULL)
498+
dev->latency = (1000000 * dev->threshold) /
499+
(1000 * dev->speed / 8);
498500
}
499501

500502
/*
@@ -522,6 +524,9 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
522524
dev->buf = msg->buf;
523525
dev->buf_len = msg->len;
524526

527+
/* make sure writes to dev->buf_len are ordered */
528+
barrier();
529+
525530
omap_i2c_write_reg(dev, OMAP_I2C_CNT_REG, dev->buf_len);
526531

527532
/* Clear the FIFO Buffers */
@@ -579,7 +584,6 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
579584
*/
580585
timeout = wait_for_completion_timeout(&dev->cmd_complete,
581586
OMAP_I2C_TIMEOUT);
582-
dev->buf_len = 0;
583587
if (timeout == 0) {
584588
dev_err(dev->dev, "controller timed out\n");
585589
omap_i2c_init(dev);
@@ -629,25 +633,17 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
629633
if (r < 0)
630634
goto out;
631635

632-
/*
633-
* When waiting for completion of a i2c transfer, we need to
634-
* set a wake up latency constraint for the MPU. This is to
635-
* ensure quick enough wakeup from idle, when transfer
636-
* completes.
637-
*/
638-
if (dev->latency)
639-
pm_qos_add_request(&dev->pm_qos_request,
640-
PM_QOS_CPU_DMA_LATENCY,
641-
dev->latency);
636+
if (dev->set_mpu_wkup_lat != NULL)
637+
dev->set_mpu_wkup_lat(dev->dev, dev->latency);
642638

643639
for (i = 0; i < num; i++) {
644640
r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1)));
645641
if (r != 0)
646642
break;
647643
}
648644

649-
if (dev->latency)
650-
pm_qos_remove_request(&dev->pm_qos_request);
645+
if (dev->set_mpu_wkup_lat != NULL)
646+
dev->set_mpu_wkup_lat(dev->dev, -1);
651647

652648
if (r == 0)
653649
r = num;
@@ -1104,6 +1100,7 @@ omap_i2c_probe(struct platform_device *pdev)
11041100
} else if (pdata != NULL) {
11051101
dev->speed = pdata->clkrate;
11061102
dev->flags = pdata->flags;
1103+
dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
11071104
dev->dtrev = pdata->rev;
11081105
}
11091106

@@ -1159,8 +1156,9 @@ omap_i2c_probe(struct platform_device *pdev)
11591156
dev->b_hw = 1; /* Enable hardware fixes */
11601157

11611158
/* calculate wakeup latency constraint for MPU */
1162-
dev->latency = (1000000 * dev->fifo_size) /
1163-
(1000 * dev->speed / 8);
1159+
if (dev->set_mpu_wkup_lat != NULL)
1160+
dev->latency = (1000000 * dev->fifo_size) /
1161+
(1000 * dev->speed / 8);
11641162
}
11651163

11661164
/* reset ASAP, clearing any IRQs */

drivers/i2c/busses/i2c-s3c2410.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,7 @@ static int s3c24xx_i2c_parse_dt_gpio(struct s3c24xx_i2c *i2c)
806806
dev_err(i2c->dev, "invalid gpio[%d]: %d\n", idx, gpio);
807807
goto free_gpio;
808808
}
809+
i2c->gpios[idx] = gpio;
809810

810811
ret = gpio_request(gpio, "i2c-bus");
811812
if (ret) {

include/linux/i2c-omap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ struct omap_i2c_bus_platform_data {
3434
u32 clkrate;
3535
u32 rev;
3636
u32 flags;
37+
void (*set_mpu_wkup_lat)(struct device *dev, long set);
3738
};
3839

3940
#endif

0 commit comments

Comments
 (0)