diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-designware.c')
-rw-r--r-- | drivers/i2c/busses/i2c-designware.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/drivers/i2c/busses/i2c-designware.c b/drivers/i2c/busses/i2c-designware.c index 49386951f7fd..934dfe1e6ce9 100644 --- a/drivers/i2c/busses/i2c-designware.c +++ b/drivers/i2c/busses/i2c-designware.c @@ -37,6 +37,7 @@ #include <linux/platform_device.h> #include <linux/io.h> #include <linux/slab.h> +#include <linux/swab.h> /* * Registers offset @@ -193,6 +194,7 @@ static char *abort_sources[] = { * @status: i2c master status, one of STATUS_* * @abort_source: copy of the TX_ABRT_SOURCE register * @irq: interrupt number for the i2c master + * @swab: true if the instantiated IP is of different endianess * @adapter: i2c subsystem adapter node * @tx_fifo_depth: depth of the hardware tx fifo * @rx_fifo_depth: depth of the hardware rx fifo @@ -216,6 +218,7 @@ struct dw_i2c_dev { unsigned int status; u32 abort_source; int irq; + int swab; struct i2c_adapter adapter; unsigned int tx_fifo_depth; unsigned int rx_fifo_depth; @@ -223,11 +226,19 @@ struct dw_i2c_dev { static u32 dw_readl(struct dw_i2c_dev *dev, int offset) { - return readl(dev->base + offset); + u32 value = readl(dev->base + offset); + + if (dev->swab) + return swab32(value); + else + return value; } static void dw_writel(struct dw_i2c_dev *dev, u32 b, int offset) { + if (dev->swab) + b = swab32(b); + writel(b, dev->base + offset); } @@ -760,7 +771,9 @@ static int __devinit dw_i2c_probe(struct platform_device *pdev) } reg = dw_readl(dev, DW_IC_COMP_TYPE); - if (reg != 0x44570140) { + if (reg == ___constant_swab32(0x44570140)) + dev->swab = 1; + else if (reg != 0x44570140) { dev_err(&pdev->dev, "Unknown Synopsys component type: " "0x%08x\n", reg); r = -ENODEV; |