Commit c3ad33c9 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus/i2c-2635' of git://git.fluff.org/bjdooks/linux

* 'for-linus/i2c-2635' of git://git.fluff.org/bjdooks/linux: (21 commits)
  i2c-highlander: remover superflous variable
  i2c-ibm-iic: drop NO_IRQ
  i2c-cpm: drop NO_IRQ
  i2c-mpc: drop NO_IRQ
  MAINTAINERS: add i2c tree for embedded platforms
  i2c-pxa: only define 'blue_murder'-function if DEBUG is #defined
  i2c-pxa: remove unused macro
  i2c-nomadik: fix operator precedence warning
  i2c-nomadik: release region when removed
  OMAP3: I2C: Clean up Errata 1p153 handling
  OMAP2/3: I2C: Errata ID i207: Clear wrong RDR interrupt
  omap: i2c: add a timeout to the busy waiting
  omap: i2c: make errata 1.153 workaround a separate function
  i2c-omap: add mpu wake up latency constraint in i2c
  omap: i2c: Add i2c support on omap4 platform
  i2c-bfin-twi: return completion in interrupt for smbus quick transfers
  i2c-bfin-twi: remove redundant retry
  i2c-bfin-twi: fix lost interrupts at high speeds
  i2c-bfin-twi: add debug output for error status
  i2c-bfin-twi: integrate timeout timer with completion interface
  ...
parents fb091be0 b5c80bc5
......@@ -2747,6 +2747,7 @@ M: "Ben Dooks (embedded platforms)" <ben-linux@fluff.org>
L: linux-i2c@vger.kernel.org
W: http://i2c.wiki.kernel.org/
T: quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-i2c/
T: git git://git.fluff.org/bjdooks/linux.git
S: Maintained
F: Documentation/i2c/
F: drivers/i2c/
......
......@@ -26,9 +26,12 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/i2c-omap.h>
#include <mach/irqs.h>
#include <plat/mux.h>
#include <plat/i2c.h>
#include <plat/omap-pm.h>
#define OMAP_I2C_SIZE 0x3f
#define OMAP1_I2C_BASE 0xfffb3800
......@@ -70,14 +73,14 @@ static struct resource i2c_resources[][2] = {
}, \
}
static u32 i2c_rate[ARRAY_SIZE(i2c_resources)];
static struct omap_i2c_bus_platform_data i2c_pdata[ARRAY_SIZE(i2c_resources)];
static struct platform_device omap_i2c_devices[] = {
I2C_DEV_BUILDER(1, i2c_resources[0], &i2c_rate[0]),
I2C_DEV_BUILDER(1, i2c_resources[0], &i2c_pdata[0]),
#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
I2C_DEV_BUILDER(2, i2c_resources[1], &i2c_rate[1]),
I2C_DEV_BUILDER(2, i2c_resources[1], &i2c_pdata[1]),
#endif
#if defined(CONFIG_ARCH_OMAP3)
I2C_DEV_BUILDER(3, i2c_resources[2], &i2c_rate[2]),
I2C_DEV_BUILDER(3, i2c_resources[2], &i2c_pdata[2]),
#endif
};
......@@ -100,10 +103,12 @@ static int __init omap_i2c_nr_ports(void)
static int __init omap_i2c_add_bus(int bus_id)
{
struct platform_device *pdev;
struct omap_i2c_bus_platform_data *pd;
struct resource *res;
resource_size_t base, irq;
pdev = &omap_i2c_devices[bus_id - 1];
pd = pdev->dev.platform_data;
if (bus_id == 1) {
res = pdev->resource;
if (cpu_class_is_omap1()) {
......@@ -123,6 +128,15 @@ static int __init omap_i2c_add_bus(int bus_id)
if (cpu_class_is_omap2())
omap2_i2c_mux_pins(bus_id);
/*
* When waiting for completion of a i2c transfer, we need to
* set a wake up latency constraint for the MPU. This is to
* ensure quick enough wakeup from idle, when transfer
* completes.
*/
if (cpu_is_omap34xx())
pd->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat;
return platform_device_register(pdev);
}
......@@ -146,8 +160,8 @@ static int __init omap_i2c_bus_setup(char *str)
get_options(str, 3, ints);
if (ints[0] < 2 || ints[1] < 1 || ints[1] > ports)
return 0;
i2c_rate[ints[1] - 1] = ints[2];
i2c_rate[ints[1] - 1] |= OMAP_I2C_CMDLINE_SETUP;
i2c_pdata[ints[1] - 1].clkrate = ints[2];
i2c_pdata[ints[1] - 1].clkrate |= OMAP_I2C_CMDLINE_SETUP;
return 1;
}
......@@ -161,9 +175,9 @@ static int __init omap_register_i2c_bus_cmdline(void)
{
int i, err = 0;
for (i = 0; i < ARRAY_SIZE(i2c_rate); i++)
if (i2c_rate[i] & OMAP_I2C_CMDLINE_SETUP) {
i2c_rate[i] &= ~OMAP_I2C_CMDLINE_SETUP;
for (i = 0; i < ARRAY_SIZE(i2c_pdata); i++)
if (i2c_pdata[i].clkrate & OMAP_I2C_CMDLINE_SETUP) {
i2c_pdata[i].clkrate &= ~OMAP_I2C_CMDLINE_SETUP;
err = omap_i2c_add_bus(i + 1);
if (err)
goto out;
......@@ -197,9 +211,10 @@ int __init omap_register_i2c_bus(int bus_id, u32 clkrate,
return err;
}
if (!i2c_rate[bus_id - 1])
i2c_rate[bus_id - 1] = clkrate;
i2c_rate[bus_id - 1] &= ~OMAP_I2C_CMDLINE_SETUP;
if (!i2c_pdata[bus_id - 1].clkrate)
i2c_pdata[bus_id - 1].clkrate = clkrate;
i2c_pdata[bus_id - 1].clkrate &= ~OMAP_I2C_CMDLINE_SETUP;
return omap_i2c_add_bus(bus_id);
}
......@@ -25,8 +25,6 @@
#include <asm/portmux.h>
#include <asm/irq.h>
#define POLL_TIMEOUT (2 * HZ)
/* SMBus mode*/
#define TWI_I2C_MODE_STANDARD 1
#define TWI_I2C_MODE_STANDARDSUB 2
......@@ -44,8 +42,6 @@ struct bfin_twi_iface {
int cur_mode;
int manual_stop;
int result;
int timeout_count;
struct timer_list timeout_timer;
struct i2c_adapter adap;
struct completion complete;
struct i2c_msg *pmsg;
......@@ -85,14 +81,15 @@ static const u16 pin_req[2][3] = {
{P_TWI1_SCL, P_TWI1_SDA, 0},
};
static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface)
static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface,
unsigned short twi_int_status)
{
unsigned short twi_int_status = read_INT_STAT(iface);
unsigned short mast_stat = read_MASTER_STAT(iface);
if (twi_int_status & XMTSERV) {
/* Transmit next data */
if (iface->writeNum > 0) {
SSYNC();
write_XMT_DATA8(iface, *(iface->transPtr++));
iface->writeNum--;
}
......@@ -114,10 +111,6 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface)
write_MASTER_CTL(iface,
(read_MASTER_CTL(iface) | RSTART) & ~MDIR);
}
SSYNC();
/* Clear status */
write_INT_STAT(iface, XMTSERV);
SSYNC();
}
if (twi_int_status & RCVSERV) {
if (iface->readNum > 0) {
......@@ -139,7 +132,6 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface)
} else if (iface->manual_stop) {
write_MASTER_CTL(iface,
read_MASTER_CTL(iface) | STOP);
SSYNC();
} else if (iface->cur_mode == TWI_I2C_MODE_REPEAT &&
iface->cur_msg + 1 < iface->msg_num) {
if (iface->pmsg[iface->cur_msg + 1].flags & I2C_M_RD)
......@@ -148,44 +140,37 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface)
else
write_MASTER_CTL(iface,
(read_MASTER_CTL(iface) | RSTART) & ~MDIR);
SSYNC();
}
/* Clear interrupt source */
write_INT_STAT(iface, RCVSERV);
SSYNC();
}
if (twi_int_status & MERR) {
write_INT_STAT(iface, MERR);
write_INT_MASK(iface, 0);
write_MASTER_STAT(iface, 0x3e);
write_MASTER_CTL(iface, 0);
SSYNC();
iface->result = -EIO;
/* if both err and complete int stats are set, return proper
* results.
if (mast_stat & LOSTARB)
dev_dbg(&iface->adap.dev, "Lost Arbitration\n");
if (mast_stat & ANAK)
dev_dbg(&iface->adap.dev, "Address Not Acknowledged\n");
if (mast_stat & DNAK)
dev_dbg(&iface->adap.dev, "Data Not Acknowledged\n");
if (mast_stat & BUFRDERR)
dev_dbg(&iface->adap.dev, "Buffer Read Error\n");
if (mast_stat & BUFWRERR)
dev_dbg(&iface->adap.dev, "Buffer Write Error\n");
/* If it is a quick transfer, only address without data,
* not an err, return 1.
*/
if (twi_int_status & MCOMP) {
write_INT_STAT(iface, MCOMP);
write_INT_MASK(iface, 0);
write_MASTER_CTL(iface, 0);
SSYNC();
/* If it is a quick transfer, only address bug no data,
* not an err, return 1.
*/
if (iface->writeNum == 0 && (mast_stat & BUFRDERR))
iface->result = 1;
/* If address not acknowledged return -1,
* else return 0.
*/
else if (!(mast_stat & ANAK))
iface->result = 0;
}
if (iface->cur_mode == TWI_I2C_MODE_STANDARD &&
iface->transPtr == NULL &&
(twi_int_status & MCOMP) && (mast_stat & DNAK))
iface->result = 1;
complete(&iface->complete);
return;
}
if (twi_int_status & MCOMP) {
write_INT_STAT(iface, MCOMP);
SSYNC();
if (iface->cur_mode == TWI_I2C_MODE_COMBINED) {
if (iface->readNum == 0) {
/* set the read number to 1 and ask for manual
......@@ -207,7 +192,6 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface)
/* remove restart bit and enable master receive */
write_MASTER_CTL(iface,
read_MASTER_CTL(iface) & ~RSTART);
SSYNC();
} else if (iface->cur_mode == TWI_I2C_MODE_REPEAT &&
iface->cur_msg+1 < iface->msg_num) {
iface->cur_msg++;
......@@ -226,7 +210,6 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface)
write_XMT_DATA8(iface,
*(iface->transPtr++));
iface->writeNum--;
SSYNC();
}
}
......@@ -244,15 +227,13 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface)
/* remove restart bit and enable master receive */
write_MASTER_CTL(iface,
read_MASTER_CTL(iface) & ~RSTART);
SSYNC();
} else {
iface->result = 1;
write_INT_MASK(iface, 0);
write_MASTER_CTL(iface, 0);
SSYNC();
complete(&iface->complete);
}
}
complete(&iface->complete);
}
/* Interrupt handler */
......@@ -260,38 +241,26 @@ static irqreturn_t bfin_twi_interrupt_entry(int irq, void *dev_id)
{
struct bfin_twi_iface *iface = dev_id;
unsigned long flags;
unsigned short twi_int_status;
spin_lock_irqsave(&iface->lock, flags);
del_timer(&iface->timeout_timer);
bfin_twi_handle_interrupt(iface);
spin_unlock_irqrestore(&iface->lock, flags);
return IRQ_HANDLED;
}
static void bfin_twi_timeout(unsigned long data)
{
struct bfin_twi_iface *iface = (struct bfin_twi_iface *)data;
unsigned long flags;
spin_lock_irqsave(&iface->lock, flags);
bfin_twi_handle_interrupt(iface);
if (iface->result == 0) {
iface->timeout_count--;
if (iface->timeout_count > 0) {
iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
add_timer(&iface->timeout_timer);
} else {
iface->result = -1;
complete(&iface->complete);
}
while (1) {
twi_int_status = read_INT_STAT(iface);
if (!twi_int_status)
break;
/* Clear interrupt status */
write_INT_STAT(iface, twi_int_status);
bfin_twi_handle_interrupt(iface, twi_int_status);
SSYNC();
}
spin_unlock_irqrestore(&iface->lock, flags);
return IRQ_HANDLED;
}
/*
* Generic i2c master transfer entrypoint
* One i2c master transfer
*/
static int bfin_twi_master_xfer(struct i2c_adapter *adap,
static int bfin_twi_do_master_xfer(struct i2c_adapter *adap,
struct i2c_msg *msgs, int num)
{
struct bfin_twi_iface *iface = adap->algo_data;
......@@ -319,7 +288,6 @@ static int bfin_twi_master_xfer(struct i2c_adapter *adap,
iface->transPtr = pmsg->buf;
iface->writeNum = iface->readNum = pmsg->len;
iface->result = 0;
iface->timeout_count = 10;
init_completion(&(iface->complete));
/* Set Transmit device address */
write_MASTER_ADDR(iface, pmsg->addr);
......@@ -358,30 +326,41 @@ static int bfin_twi_master_xfer(struct i2c_adapter *adap,
iface->manual_stop = 1;
}
iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
add_timer(&iface->timeout_timer);
/* Master enable */
write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN |
((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) |
((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ > 100) ? FAST : 0));
SSYNC();
wait_for_completion(&iface->complete);
rc = iface->result;
while (!iface->result) {
if (!wait_for_completion_timeout(&iface->complete,
adap->timeout)) {
iface->result = -1;
dev_err(&adap->dev, "master transfer timeout\n");
}
}
if (rc == 1)
return num;
if (iface->result == 1)
rc = iface->cur_msg + 1;
else
return rc;
rc = iface->result;
return rc;
}
/*
* SMBus type transfer entrypoint
* Generic i2c master transfer entrypoint
*/
static int bfin_twi_master_xfer(struct i2c_adapter *adap,
struct i2c_msg *msgs, int num)
{
return bfin_twi_do_master_xfer(adap, msgs, num);
}
int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
/*
* One I2C SMBus transfer
*/
int bfin_twi_do_smbus_xfer(struct i2c_adapter *adap, u16 addr,
unsigned short flags, char read_write,
u8 command, int size, union i2c_smbus_data *data)
{
......@@ -469,7 +448,6 @@ int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
iface->manual_stop = 0;
iface->read_write = read_write;
iface->command = command;
iface->timeout_count = 10;
init_completion(&(iface->complete));
/* FIFO Initiation. Data in FIFO should be discarded before
......@@ -486,9 +464,6 @@ int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
write_MASTER_ADDR(iface, addr);
SSYNC();
iface->timeout_timer.expires = jiffies + POLL_TIMEOUT;
add_timer(&iface->timeout_timer);
switch (iface->cur_mode) {
case TWI_I2C_MODE_STANDARDSUB:
write_XMT_DATA8(iface, iface->command);
......@@ -550,10 +525,8 @@ int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
else if (iface->readNum > 255) {
write_MASTER_CTL(iface, 0xff << 6);
iface->manual_stop = 1;
} else {
del_timer(&iface->timeout_timer);
} else
break;
}
}
}
write_INT_MASK(iface, MCOMP | MERR |
......@@ -569,13 +542,30 @@ int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
}
SSYNC();
wait_for_completion(&iface->complete);
while (!iface->result) {
if (!wait_for_completion_timeout(&iface->complete,
adap->timeout)) {
iface->result = -1;
dev_err(&adap->dev, "smbus transfer timeout\n");
}
}
rc = (iface->result >= 0) ? 0 : -1;
return rc;
}
/*
* Generic I2C SMBus transfer entrypoint
*/
int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
unsigned short flags, char read_write,
u8 command, int size, union i2c_smbus_data *data)
{
return bfin_twi_do_smbus_xfer(adap, addr, flags,
read_write, command, size, data);
}
/*
* Return what the adapter supports
*/
......@@ -667,10 +657,6 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev)
goto out_error_no_irq;
}
init_timer(&(iface->timeout_timer));
iface->timeout_timer.function = bfin_twi_timeout;
iface->timeout_timer.data = (unsigned long)iface;
p_adap = &iface->adap;
p_adap->nr = pdev->id;
strlcpy(p_adap->name, pdev->name, sizeof(p_adap->name));
......@@ -678,6 +664,8 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev)
p_adap->algo_data = iface;
p_adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
p_adap->dev.parent = &pdev->dev;
p_adap->timeout = 5 * HZ;
p_adap->retries = 3;
rc = peripheral_request_list(pin_req[pdev->id], "i2c-bfin-twi");
if (rc) {
......
......@@ -441,7 +441,7 @@ static int __devinit cpm_i2c_setup(struct cpm_i2c *cpm)
init_waitqueue_head(&cpm->i2c_wait);
cpm->irq = of_irq_to_resource(ofdev->node, 0, NULL);
if (cpm->irq == NO_IRQ)
if (!cpm->irq)
return -EINVAL;
/* Install interrupt handler. */
......
......@@ -282,7 +282,6 @@ static int highlander_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr,
union i2c_smbus_data *data)
{
struct highlander_i2c_dev *dev = i2c_get_adapdata(adap);
int read = read_write & I2C_SMBUS_READ;
u16 tmp;
init_completion(&dev->cmd_complete);
......@@ -337,11 +336,11 @@ static int highlander_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr,
highlander_i2c_done(dev);
/* Set slave address */
iowrite16((addr << 1) | read, dev->base + SMSMADR);
iowrite16((addr << 1) | read_write, dev->base + SMSMADR);
highlander_i2c_command(dev, command, dev->buf_len);
if (read)
if (read_write == I2C_SMBUS_READ)
return highlander_i2c_read(dev);
else
return highlander_i2c_write(dev);
......
......@@ -668,12 +668,12 @@ static int __devinit iic_request_irq(struct of_device *ofdev,
int irq;
if (iic_force_poll)
return NO_IRQ;
return 0;
irq = irq_of_parse_and_map(np, 0);
if (irq == NO_IRQ) {
if (!irq) {
dev_err(&ofdev->dev, "irq_of_parse_and_map failed\n");
return NO_IRQ;
return 0;
}
/* Disable interrupts until we finish initialization, assumes
......@@ -683,7 +683,7 @@ static int __devinit iic_request_irq(struct of_device *ofdev,
if (request_irq(irq, iic_handler, 0, "IBM IIC", dev)) {
dev_err(&ofdev->dev, "request_irq %d failed\n", irq);
/* Fallback to the polling mode */
return NO_IRQ;
return 0;
}
return irq;
......@@ -719,7 +719,7 @@ static int __devinit iic_probe(struct of_device *ofdev,
init_waitqueue_head(&dev->wq);
dev->irq = iic_request_irq(ofdev, dev);
if (dev->irq == NO_IRQ)
if (!dev->irq)
dev_warn(&ofdev->dev, "using polling mode\n");
/* Board specific settings */
......@@ -766,7 +766,7 @@ static int __devinit iic_probe(struct of_device *ofdev,
return 0;
error_cleanup:
if (dev->irq != NO_IRQ) {
if (dev->irq) {
iic_interrupt_mode(dev, 0);
free_irq(dev->irq, dev);
}
......@@ -790,7 +790,7 @@ static int __devexit iic_remove(struct of_device *ofdev)
i2c_del_adapter(&dev->adap);
if (dev->irq != NO_IRQ) {
if (dev->irq) {
iic_interrupt_mode(dev, 0);
free_irq(dev->irq, dev);
}
......
......@@ -118,7 +118,7 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
u32 x;
int result = 0;
if (i2c->irq == NO_IRQ) {
if (!i2c->irq) {
while (!(readb(i2c->base + MPC_I2C_SR) & CSR_MIF)) {
schedule();
if (time_after(jiffies, orig_jiffies + timeout)) {
......@@ -568,7 +568,7 @@ static int __devinit fsl_i2c_probe(struct of_device *op,
}
i2c->irq = irq_of_parse_and_map(op->node, 0);
if (i2c->irq != NO_IRQ) { /* i2c->irq = NO_IRQ implies polling */
if (i2c->irq) { /* no i2c->irq implies polling */
result = request_irq(i2c->irq, mpc_i2c_isr,
IRQF_SHARED, "i2c-mpc", i2c);
if (result < 0) {
......@@ -627,7 +627,7 @@ static int __devexit fsl_i2c_remove(struct of_device *op)
i2c_del_adapter(&i2c->adap);
dev_set_drvdata(&op->dev, NULL);
if (i2c->irq != NO_IRQ)
if (i2c->irq)
free_irq(i2c->irq, i2c);
irq_dispose_mapping(i2c->irq);
......
......@@ -704,7 +704,8 @@ static irqreturn_t i2c_irq_handler(int irq, void *arg)
case I2C_IT_MTD:
case I2C_IT_MTDWS:
if (dev->cli.operation == I2C_READ) {
while (!readl(dev->virtbase + I2C_RISR) & I2C_IT_RXFE) {
while (!(readl(dev->virtbase + I2C_RISR)
& I2C_IT_RXFE)) {
if (dev->cli.count == 0)
break;
*dev->cli.buffer =
......@@ -914,6 +915,7 @@ static int __devinit nmk_i2c_probe(struct platform_device *pdev)
static int __devexit nmk_i2c_remove(struct platform_device *pdev)
{
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
struct nmk_i2c_dev *dev = platform_get_drvdata(pdev);
i2c_del_adapter(&dev->adap);
......@@ -924,6 +926,8 @@ static int __devexit nmk_i2c_remove(struct platform_device *pdev)
i2c_clr_bit(dev->virtbase + I2C_CR, I2C_CR_PE);
free_irq(dev->irq, dev);
iounmap(dev->virtbase);
if (res)
release_mem_region(res->start, resource_size(res));
clk_disable(dev->clk);
clk_put(dev->clk);
platform_set_drvdata(pdev, NULL);
......
This diff is collapsed.
......@@ -209,18 +209,6 @@ static void i2c_pxa_show_state(struct pxa_i2c *i2c, int lno, const char *fname)
}
#define show_state(i2c) i2c_pxa_show_state(i2c, __LINE__, __func__)
#else
#define i2c_debug 0
#define show_state(i2c) do { } while (0)
#define decode_ISR(val) do { } while (0)
#define decode_ICR(val) do { } while (0)
#endif
#define eedbg(lvl, x...) do { if ((lvl) < 1) { printk(KERN_DEBUG "" x); } } while(0)
static void i2c_pxa_master_complete(struct pxa_i2c *i2c, int ret);
static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id);
static void i2c_pxa_scream_blue_murder(struct pxa_i2c *i2c, const char *why)
{
......@@ -236,6 +224,20 @@ static void i2c_pxa_scream_blue_murder(struct pxa_i2c *i2c, const char *why)
printk("\n");
}
#else /* ifdef DEBUG */
#define i2c_debug 0
#define show_state(i2c) do { } while (0)
#define decode_ISR(val) do { } while (0)
#define decode_ICR(val) do { } while (0)
#define i2c_pxa_scream_blue_murder(i2c, why) do { } while (0)
#endif /* ifdef DEBUG / else */
static void i2c_pxa_master_complete(struct pxa_i2c *i2c, int ret);
static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id);
static inline int i2c_pxa_is_slavemode(struct pxa_i2c *i2c)
{
return !(readl(_ICR(i2c)) & ICR_SCLE);
......
......@@ -482,7 +482,8 @@ static int s3c24xx_i2c_set_master(struct s3c24xx_i2c *i2c)
static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
struct i2c_msg *msgs, int num)
{
unsigned long timeout;
unsigned long iicstat, timeout;
int spins = 20;
int ret;
if (i2c->suspended)
......@@ -521,7 +522,21 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
/* ensure the stop has been through the bus */
msleep(1);
dev_dbg(i2c->dev, "waiting for bus idle\n");
/* first, try busy waiting briefly */
do {
iicstat = readl(i2c->regs + S3C2410_IICSTAT);
} while ((iicstat & S3C2410_IICSTAT_START) && --spins);
/* if that timed out sleep */
if (!spins) {
msleep(1);
iicstat = readl(i2c->regs + S3C2410_IICSTAT);
}
if (iicstat & S3C2410_IICSTAT_START)
dev_warn(i2c->dev, "timeout waiting for bus idle\n");
out:
return ret;
......
#ifndef __I2C_OMAP_H__
#define __I2C_OMAP_H__
struct omap_i2c_bus_platform_data {
u32 clkrate;
void (*set_mpu_wkup_lat)(struct device *dev, long set);
};
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment