From: Dirk Brandewie <dirk.brandewie@xxxxxxxxx> Move all register manipulation into the core code. Signed-off-by: Dirk Brandewie <dirk.brandewie@xxxxxxxxx> --- drivers/i2c/busses/i2c-designware-core.c | 49 ++++++++++++++++++++++++++- drivers/i2c/busses/i2c-designware-core.h | 6 +++ drivers/i2c/busses/i2c-designware-pcidrv.c | 4 +- drivers/i2c/busses/i2c-designware-platdrv.c | 6 ++-- 4 files changed, 59 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c index 5452e3b..35960db 100644 --- a/drivers/i2c/busses/i2c-designware-core.c +++ b/drivers/i2c/busses/i2c-designware-core.c @@ -247,7 +247,7 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev) ic_con |= DW_IC_CON_10BITADDR_MASTER; else ic_con &= ~DW_IC_CON_10BITADDR_MASTER; - dw_writel(dev->base, ic_con, DW_IC_CON); + dw_writel(dev, ic_con, DW_IC_CON); /* Enable the adapter */ dw_writel(dev, 1, DW_IC_ENABLE); @@ -571,3 +571,50 @@ tx_aborted: return IRQ_HANDLED; } +void i2c_dw_enable(struct dw_i2c_dev *dev) +{ + /* Enable the adapter */ + dw_writel(dev, 1, DW_IC_ENABLE); +} + + +void i2c_dw_disable(struct dw_i2c_dev *dev) +{ + int ret; + + /* + * Disabling DW_apb_i2c + * + * The IC_ENABLE register allows software to immediately shut down + * the DW_apb_i2c hardware, preventing its further participation in + * an I2C subsystem. The I2C protocol, however, does not allow + * transfers to be abruptly stopped, it's necessary for software to + * manage the correct shutdown of DW_apb_i2c, ensuring no data loss + * or bus lockup occurs. + */ + ret = i2c_dw_wait_bus_not_busy(dev); + if (ret < 0) + BUG(); + + /* Disable controller */ + dw_writel(dev, 0, DW_IC_ENABLE); + + /* Disable all interupts */ + dw_writel(dev, 0, DW_IC_INTR_MASK); + dw_readl(dev, DW_IC_CLR_INTR); +} + +void i2c_dw_clear_int(struct dw_i2c_dev *dev) +{ + dw_readl(dev, DW_IC_CLR_INTR); +} + +void i2c_dw_disable_int(struct dw_i2c_dev *dev) +{ + dw_writel(dev, 0, DW_IC_INTR_MASK); +} + +u32 i2c_dw_read_comp_param(struct dw_i2c_dev *dev) +{ + return dw_readl(dev, DW_IC_COMP_PARAM_1); +} diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h index 8d715b9..2060a53 100644 --- a/drivers/i2c/busses/i2c-designware-core.h +++ b/drivers/i2c/busses/i2c-designware-core.h @@ -195,3 +195,9 @@ extern int i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num); extern u32 i2c_dw_func(struct i2c_adapter *adap); extern irqreturn_t i2c_dw_isr(int this_irq, void *dev_id); +extern void i2c_dw_enable(struct dw_i2c_dev *dev); +extern void i2c_dw_disable(struct dw_i2c_dev *dev); +extern void i2c_dw_clear_int(struct dw_i2c_dev *dev); +extern void i2c_dw_disable_int(struct dw_i2c_dev *dev); +extern u32 i2c_dw_read_comp_param(struct dw_i2c_dev *dev); + diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c index f548064..d943318 100644 --- a/drivers/i2c/busses/i2c-designware-pcidrv.c +++ b/drivers/i2c/busses/i2c-designware-pcidrv.c @@ -231,8 +231,8 @@ const struct pci_device_id *id) goto err_iounmap; } - dw_readl(dev, DW_IC_CLR_INTR); - dw_writel(dev, 0, DW_IC_INTR_MASK); /* disable IRQ */ + i2c_dw_disable_int(dev); + i2c_dw_clear_int(dev); r = i2c_add_numbered_adapter(adap); if (r) { dev_err(&pdev->dev, "failure adding adapter\n"); diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index 964494e..dff9b52 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -107,7 +107,7 @@ static int __devinit dw_i2c_probe(struct platform_device *pdev) goto err_unuse_clocks; } { - u32 param1 = dw_readl(dev, DW_IC_COMP_PARAM_1); + u32 param1 = i2c_dw_read_comp_param(dev); dev->tx_fifo_depth = ((param1 >> 16) & 0xff) + 1; dev->rx_fifo_depth = ((param1 >> 8) & 0xff) + 1; @@ -116,7 +116,7 @@ static int __devinit dw_i2c_probe(struct platform_device *pdev) if (r) goto err_iounmap; - dw_writel(dev, 0, DW_IC_INTR_MASK); /* disable IRQ */ + i2c_dw_disable_int(dev); r = request_irq(dev->irq, i2c_dw_isr, IRQF_DISABLED, pdev->name, dev); if (r) { dev_err(&pdev->dev, "failure requesting irq %i\n", dev->irq); @@ -172,7 +172,7 @@ static int __devexit dw_i2c_remove(struct platform_device *pdev) clk_put(dev->clk); dev->clk = NULL; - dw_writel(dev, 0, DW_IC_ENABLE); + i2c_dw_disable(dev); free_irq(dev->irq, dev); kfree(dev); -- 1.7.3.4 -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html