diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-05-31 14:34:00 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-05-31 14:34:00 -0700 |
commit | f8a52af9d00d59fd887d8ad1fa0c2c88a5d775b9 (patch) | |
tree | 4c1db12503f4fe19a9f5b34867d32da3c4f034bf /drivers/i2c/busses | |
parent | 35b51afd23c98e2f055ac563aca36173a12588b9 (diff) | |
parent | 3cd4030da3a9b54ee1ffb8397aba857397c703e4 (diff) | |
download | linux-f8a52af9d00d59fd887d8ad1fa0c2c88a5d775b9.tar.gz linux-f8a52af9d00d59fd887d8ad1fa0c2c88a5d775b9.tar.bz2 linux-f8a52af9d00d59fd887d8ad1fa0c2c88a5d775b9.zip |
Merge tag 'i2c-for-5.19' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c updates from Wolfram Sang:
"Only driver updates for 5.19.
Bigger changes are for Meson, NPCM, and R-Car, but there are also
changes all over the place"
* tag 'i2c-for-5.19' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (34 commits)
i2c: meson: fix typo in comment
i2c: rcar: use flags instead of atomic_xfer
i2c: rcar: REP_AFTER_RD is not a persistent flag
i2c: rcar: use BIT macro consistently
i2c: qcom-geni: remove unnecessary conditions
i2c: mt7621: Use devm_platform_get_and_ioremap_resource()
i2c: rcar: refactor handling of first message
i2c: rcar: avoid race condition with SMIs
i2c: xiic: Correct the datatype for rx_watermark
i2c: rcar: fix PM ref counts in probe error paths
i2c: npcm: Handle spurious interrupts
i2c: npcm: Correct register access width
i2c: npcm: Add tx complete counter
i2c: npcm: Fix timeout calculation
i2c: npcm: Remove unused variable clk_regmap
i2c: npcm: Change the way of getting GCR regmap
i2c: xiic: Fix Tx Interrupt path for grouped messages
i2c: xiic: Fix coding style issues
i2c: xiic: return value of xiic_reinit
i2c: cadence: Increase timeout per message if necessary
...
Diffstat (limited to 'drivers/i2c/busses')
-rw-r--r-- | drivers/i2c/busses/i2c-at91-master.c | 11 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-cadence.c | 12 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-davinci.c | 12 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-designware-amdpsp.c | 4 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-designware-common.c | 2 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-meson.c | 115 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-mt65xx.c | 11 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-mt7621.c | 5 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-npcm7xx.c | 122 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-powermac.c | 2 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-qcom-geni.c | 6 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-rcar.c | 217 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-xiic.c | 84 |
13 files changed, 371 insertions, 232 deletions
diff --git a/drivers/i2c/busses/i2c-at91-master.c b/drivers/i2c/busses/i2c-at91-master.c index b0eae94909f4..c0c35785a0dc 100644 --- a/drivers/i2c/busses/i2c-at91-master.c +++ b/drivers/i2c/busses/i2c-at91-master.c @@ -656,6 +656,7 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num) unsigned int_addr_flag = 0; struct i2c_msg *m_start = msg; bool is_read; + u8 *dma_buf = NULL; dev_dbg(&adap->dev, "at91_xfer: processing %d messages:\n", num); @@ -703,7 +704,17 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num) dev->msg = m_start; dev->recv_len_abort = false; + if (dev->use_dma) { + dma_buf = i2c_get_dma_safe_msg_buf(m_start, 1); + if (!dma_buf) { + ret = -ENOMEM; + goto out; + } + dev->buf = dma_buf; + } + ret = at91_do_twi_transfer(dev); + i2c_put_dma_safe_msg_buf(dma_buf, m_start, !ret); ret = (ret < 0) ? ret : num; out: diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c index 805c77143a0f..b4c1ad19cdae 100644 --- a/drivers/i2c/busses/i2c-cadence.c +++ b/drivers/i2c/busses/i2c-cadence.c @@ -760,7 +760,7 @@ static void cdns_i2c_master_reset(struct i2c_adapter *adap) static int cdns_i2c_process_msg(struct cdns_i2c *id, struct i2c_msg *msg, struct i2c_adapter *adap) { - unsigned long time_left; + unsigned long time_left, msg_timeout; u32 reg; id->p_msg = msg; @@ -785,8 +785,16 @@ static int cdns_i2c_process_msg(struct cdns_i2c *id, struct i2c_msg *msg, else cdns_i2c_msend(id); + /* Minimal time to execute this message */ + msg_timeout = msecs_to_jiffies((1000 * msg->len * BITS_PER_BYTE) / id->i2c_clk); + /* Plus some wiggle room */ + msg_timeout += msecs_to_jiffies(500); + + if (msg_timeout < adap->timeout) + msg_timeout = adap->timeout; + /* Wait for the signal of completion */ - time_left = wait_for_completion_timeout(&id->xfer_done, adap->timeout); + time_left = wait_for_completion_timeout(&id->xfer_done, msg_timeout); if (time_left == 0) { cdns_i2c_master_reset(adap); dev_err(id->adap.dev.parent, diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index e9d07323c604..9e09db31a937 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -539,10 +539,9 @@ i2c_davinci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) dev_dbg(dev->dev, "%s: msgs: %d\n", __func__, num); - ret = pm_runtime_get_sync(dev->dev); + ret = pm_runtime_resume_and_get(dev->dev); if (ret < 0) { dev_err(dev->dev, "Failed to runtime_get device: %d\n", ret); - pm_runtime_put_noidle(dev->dev); return ret; } @@ -821,10 +820,9 @@ static int davinci_i2c_probe(struct platform_device *pdev) pm_runtime_enable(dev->dev); - r = pm_runtime_get_sync(dev->dev); + r = pm_runtime_resume_and_get(dev->dev); if (r < 0) { dev_err(dev->dev, "failed to runtime_get device: %d\n", r); - pm_runtime_put_noidle(dev->dev); return r; } @@ -898,11 +896,9 @@ static int davinci_i2c_remove(struct platform_device *pdev) i2c_del_adapter(&dev->adapter); - ret = pm_runtime_get_sync(&pdev->dev); - if (ret < 0) { - pm_runtime_put_noidle(&pdev->dev); + ret = pm_runtime_resume_and_get(&pdev->dev); + if (ret < 0) return ret; - } davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, 0); diff --git a/drivers/i2c/busses/i2c-designware-amdpsp.c b/drivers/i2c/busses/i2c-designware-amdpsp.c index 9b37f2b95abc..b624356c945f 100644 --- a/drivers/i2c/busses/i2c-designware-amdpsp.c +++ b/drivers/i2c/busses/i2c-designware-amdpsp.c @@ -16,8 +16,8 @@ #define PSP_CMD_TIMEOUT_US (500 * USEC_PER_MSEC) #define PSP_I2C_REQ_BUS_CMD 0x64 -#define PSP_I2C_REQ_RETRY_CNT 10 -#define PSP_I2C_REQ_RETRY_DELAY_US (50 * USEC_PER_MSEC) +#define PSP_I2C_REQ_RETRY_CNT 400 +#define PSP_I2C_REQ_RETRY_DELAY_US (25 * USEC_PER_MSEC) #define PSP_I2C_REQ_STS_OK 0x0 #define PSP_I2C_REQ_STS_BUS_BUSY 0x1 #define PSP_I2C_REQ_STS_INV_PARAM 0x3 diff --git a/drivers/i2c/busses/i2c-designware-common.c b/drivers/i2c/busses/i2c-designware-common.c index 9f8574320eb2..e7d316b1401a 100644 --- a/drivers/i2c/busses/i2c-designware-common.c +++ b/drivers/i2c/busses/i2c-designware-common.c @@ -266,9 +266,9 @@ int i2c_dw_acpi_configure(struct device *device) * selected speed modes. */ i2c_dw_acpi_params(device, "SSCN", &dev->ss_hcnt, &dev->ss_lcnt, &ss_ht); + i2c_dw_acpi_params(device, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt, &fs_ht); i2c_dw_acpi_params(device, "FPCN", &dev->fp_hcnt, &dev->fp_lcnt, &fp_ht); i2c_dw_acpi_params(device, "HSCN", &dev->hs_hcnt, &dev->hs_lcnt, &hs_ht); - i2c_dw_acpi_params(device, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt, &fs_ht); switch (t->bus_freq_hz) { case I2C_MAX_STANDARD_MODE_FREQ: diff --git a/drivers/i2c/busses/i2c-meson.c b/drivers/i2c/busses/i2c-meson.c index 07eb819072c4..61cc5b2462c6 100644 --- a/drivers/i2c/busses/i2c-meson.c +++ b/drivers/i2c/busses/i2c-meson.c @@ -30,18 +30,21 @@ #define REG_TOK_RDATA1 0x1c /* Control register fields */ -#define REG_CTRL_START BIT(0) -#define REG_CTRL_ACK_IGNORE BIT(1) -#define REG_CTRL_STATUS BIT(2) -#define REG_CTRL_ERROR BIT(3) -#define REG_CTRL_CLKDIV GENMASK(21, 12) -#define REG_CTRL_CLKDIVEXT GENMASK(29, 28) - -#define REG_SLV_ADDR GENMASK(7, 0) -#define REG_SLV_SDA_FILTER GENMASK(10, 8) -#define REG_SLV_SCL_FILTER GENMASK(13, 11) -#define REG_SLV_SCL_LOW GENMASK(27, 16) -#define REG_SLV_SCL_LOW_EN BIT(28) +#define REG_CTRL_START BIT(0) +#define REG_CTRL_ACK_IGNORE BIT(1) +#define REG_CTRL_STATUS BIT(2) +#define REG_CTRL_ERROR BIT(3) +#define REG_CTRL_CLKDIV_SHIFT 12 +#define REG_CTRL_CLKDIV_MASK GENMASK(21, REG_CTRL_CLKDIV_SHIFT) +#define REG_CTRL_CLKDIVEXT_SHIFT 28 +#define REG_CTRL_CLKDIVEXT_MASK GENMASK(29, REG_CTRL_CLKDIVEXT_SHIFT) + +#define REG_SLV_ADDR_MASK GENMASK(7, 0) +#define REG_SLV_SDA_FILTER_MASK GENMASK(10, 8) +#define REG_SLV_SCL_FILTER_MASK GENMASK(13, 11) +#define REG_SLV_SCL_LOW_SHIFT 16 +#define REG_SLV_SCL_LOW_MASK GENMASK(27, REG_SLV_SCL_LOW_SHIFT) +#define REG_SLV_SCL_LOW_EN BIT(28) #define I2C_TIMEOUT_MS 500 #define FILTER_DELAY 15 @@ -62,10 +65,6 @@ enum { STATE_WRITE, }; -struct meson_i2c_data { - unsigned char div_factor; -}; - /** * struct meson_i2c - Meson I2C device private data * @@ -83,7 +82,7 @@ struct meson_i2c_data { * @done: Completion used to wait for transfer termination * @tokens: Sequence of tokens to be written to the device * @num_tokens: Number of tokens - * @data: Pointer to the controlller's platform data + * @data: Pointer to the controller's platform data */ struct meson_i2c { struct i2c_adapter adap; @@ -106,6 +105,10 @@ struct meson_i2c { const struct meson_i2c_data *data; }; +struct meson_i2c_data { + void (*set_clk_div)(struct meson_i2c *i2c, unsigned int freq); +}; + static void meson_i2c_set_mask(struct meson_i2c *i2c, int reg, u32 mask, u32 val) { @@ -134,14 +137,62 @@ static void meson_i2c_add_token(struct meson_i2c *i2c, int token) i2c->num_tokens++; } -static void meson_i2c_set_clk_div(struct meson_i2c *i2c, unsigned int freq) +static void meson_gxbb_axg_i2c_set_clk_div(struct meson_i2c *i2c, unsigned int freq) +{ + unsigned long clk_rate = clk_get_rate(i2c->clk); + unsigned int div_h, div_l; + + /* According to I2C-BUS Spec 2.1, in FAST-MODE, the minimum LOW period is 1.3uS, and + * minimum HIGH is least 0.6us. + * For 400000 freq, the period is 2.5us. To keep within the specs, give 40% of period to + * HIGH and 60% to LOW. This means HIGH at 1.0us and LOW 1.5us. + * The same applies for Fast-mode plus, where LOW is 0.5us and HIGH is 0.26us. + * Duty = H/(H + L) = 2/5 + */ + if (freq <= I2C_MAX_STANDARD_MODE_FREQ) { + div_h = DIV_ROUND_UP(clk_rate, freq); + div_l = DIV_ROUND_UP(div_h, 4); + div_h = DIV_ROUND_UP(div_h, 2) - FILTER_DELAY; + } else { + div_h = DIV_ROUND_UP(clk_rate * 2, freq * 5) - FILTER_DELAY; + div_l = DIV_ROUND_UP(clk_rate * 3, freq * 5 * 2); + } + + /* clock divider has 12 bits */ + if (div_h > GENMASK(11, 0)) { + dev_err(i2c->dev, "requested bus frequency too low\n"); + div_h = GENMASK(11, 0); + } + if (div_l > GENMASK(11, 0)) { + dev_err(i2c->dev, "requested bus frequency too low\n"); + div_l = GENMASK(11, 0); + } + + meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_CLKDIV_MASK, + FIELD_PREP(REG_CTRL_CLKDIV_MASK, div_h & GENMASK(9, 0))); + + meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_CLKDIVEXT_MASK, + FIELD_PREP(REG_CTRL_CLKDIVEXT_MASK, div_h >> 10)); + + /* set SCL low delay */ + meson_i2c_set_mask(i2c, REG_SLAVE_ADDR, REG_SLV_SCL_LOW_MASK, + FIELD_PREP(REG_SLV_SCL_LOW_MASK, div_l)); + + /* Enable HIGH/LOW mode */ + meson_i2c_set_mask(i2c, REG_SLAVE_ADDR, REG_SLV_SCL_LOW_EN, REG_SLV_SCL_LOW_EN); + + dev_dbg(i2c->dev, "%s: clk %lu, freq %u, divh %u, divl %u\n", __func__, + clk_rate, freq, div_h, div_l); +} + +static void meson6_i2c_set_clk_div(struct meson_i2c *i2c, unsigned int freq) { unsigned long clk_rate = clk_get_rate(i2c->clk); unsigned int div; div = DIV_ROUND_UP(clk_rate, freq); div -= FILTER_DELAY; - div = DIV_ROUND_UP(div, i2c->data->div_factor); + div = DIV_ROUND_UP(div, 4); /* clock divider has 12 bits */ if (div > GENMASK(11, 0)) { @@ -149,11 +200,11 @@ static void meson_i2c_set_clk_div(struct meson_i2c *i2c, unsigned int freq) div = GENMASK(11, 0); } - meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_CLKDIV, - FIELD_PREP(REG_CTRL_CLKDIV, div & GENMASK(9, 0))); + meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_CLKDIV_MASK, + FIELD_PREP(REG_CTRL_CLKDIV_MASK, div & GENMASK(9, 0))); - meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_CLKDIVEXT, - FIELD_PREP(REG_CTRL_CLKDIVEXT, div >> 10)); + meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_CLKDIVEXT_MASK, + FIELD_PREP(REG_CTRL_CLKDIVEXT_MASK, div >> 10)); /* Disable HIGH/LOW mode */ meson_i2c_set_mask(i2c, REG_SLAVE_ADDR, REG_SLV_SCL_LOW_EN, 0); @@ -292,8 +343,8 @@ static void meson_i2c_do_start(struct meson_i2c *i2c, struct i2c_msg *msg) TOKEN_SLAVE_ADDR_WRITE; - meson_i2c_set_mask(i2c, REG_SLAVE_ADDR, REG_SLV_ADDR, - FIELD_PREP(REG_SLV_ADDR, msg->addr << 1)); + meson_i2c_set_mask(i2c, REG_SLAVE_ADDR, REG_SLV_ADDR_MASK, + FIELD_PREP(REG_SLV_ADDR_MASK, msg->addr << 1)); meson_i2c_add_token(i2c, TOKEN_START); meson_i2c_add_token(i2c, token); @@ -467,9 +518,13 @@ static int meson_i2c_probe(struct platform_device *pdev) /* Disable filtering */ meson_i2c_set_mask(i2c, REG_SLAVE_ADDR, - REG_SLV_SDA_FILTER | REG_SLV_SCL_FILTER, 0); + REG_SLV_SDA_FILTER_MASK | REG_SLV_SCL_FILTER_MASK, 0); - meson_i2c_set_clk_div(i2c, timings.bus_freq_hz); + if (!i2c->data->set_clk_div) { + clk_disable_unprepare(i2c->clk); + return -EINVAL; + } + i2c->data->set_clk_div(i2c, timings.bus_freq_hz); ret = i2c_add_adapter(&i2c->adap); if (ret < 0) { @@ -491,15 +546,15 @@ static int meson_i2c_remove(struct platform_device *pdev) } static const struct meson_i2c_data i2c_meson6_data = { - .div_factor = 4, + .set_clk_div = meson6_i2c_set_clk_div, }; static const struct meson_i2c_data i2c_gxbb_data = { - .div_factor = 4, + .set_clk_div = meson_gxbb_axg_i2c_set_clk_div, }; static const struct meson_i2c_data i2c_axg_data = { - .div_factor = 3, + .set_clk_div = meson_gxbb_axg_i2c_set_clk_div, }; static const struct of_device_id meson_i2c_match[] = { diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index f651d3e124d6..bdecb78bfc26 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -1177,7 +1177,7 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap, int left_num = num; struct mtk_i2c *i2c = i2c_get_adapdata(adap); - ret = clk_bulk_prepare_enable(I2C_MT65XX_CLK_MAX, i2c->clocks); + ret = clk_bulk_enable(I2C_MT65XX_CLK_MAX, i2c->clocks); if (ret) return ret; @@ -1231,7 +1231,7 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap, ret = num; err_exit: - clk_bulk_disable_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks); + clk_bulk_disable(I2C_MT65XX_CLK_MAX, i2c->clocks); return ret; } @@ -1412,7 +1412,7 @@ static int mtk_i2c_probe(struct platform_device *pdev) return ret; } mtk_i2c_init_hw(i2c); - clk_bulk_disable_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks); + clk_bulk_disable(I2C_MT65XX_CLK_MAX, i2c->clocks); ret = devm_request_irq(&pdev->dev, irq, mtk_i2c_irq, IRQF_NO_SUSPEND | IRQF_TRIGGER_NONE, @@ -1439,6 +1439,8 @@ static int mtk_i2c_remove(struct platform_device *pdev) i2c_del_adapter(&i2c->adap); + clk_bulk_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks); + return 0; } @@ -1448,6 +1450,7 @@ static int mtk_i2c_suspend_noirq(struct device *dev) struct mtk_i2c *i2c = dev_get_drvdata(dev); i2c_mark_adapter_suspended(&i2c->adap); + clk_bulk_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks); return 0; } @@ -1465,7 +1468,7 @@ static int mtk_i2c_resume_noirq(struct device *dev) mtk_i2c_init_hw(i2c); - clk_bulk_disable_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks); + clk_bulk_disable(I2C_MT65XX_CLK_MAX, i2c->clocks); i2c_mark_adapter_resumed(&i2c->adap); diff --git a/drivers/i2c/busses/i2c-mt7621.c b/drivers/i2c/busses/i2c-mt7621.c index 901f0fb04fee..cfe6de8175dd 100644 --- a/drivers/i2c/busses/i2c-mt7621.c +++ b/drivers/i2c/busses/i2c-mt7621.c @@ -270,18 +270,15 @@ static void mtk_i2c_init(struct mtk_i2c *i2c) static int mtk_i2c_probe(struct platform_device *pdev) { - struct resource *res; struct mtk_i2c *i2c; struct i2c_adapter *adap; int ret; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - i2c = devm_kzalloc(&pdev->dev, sizeof(struct mtk_i2c), GFP_KERNEL); if (!i2c) return -ENOMEM; - i2c->base = devm_ioremap_resource(&pdev->dev, res); + i2c->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); if (IS_ERR(i2c->base)) return PTR_ERR(i2c->base); diff --git a/drivers/i2c/busses/i2c-npcm7xx.c b/drivers/i2c/busses/i2c-npcm7xx.c index 71aad029425d..5960ccde6574 100644 --- a/drivers/i2c/busses/i2c-npcm7xx.c +++ b/drivers/i2c/busses/i2c-npcm7xx.c @@ -314,6 +314,7 @@ struct npcm_i2c { u64 rec_fail_cnt; u64 nack_cnt; u64 timeout_cnt; + u64 tx_complete_cnt; }; static inline void npcm_i2c_select_bank(struct npcm_i2c *bus, @@ -359,14 +360,14 @@ static int npcm_i2c_get_SCL(struct i2c_adapter *_adap) { struct npcm_i2c *bus = container_of(_adap, struct npcm_i2c, adap); - return !!(I2CCTL3_SCL_LVL & ioread32(bus->reg + NPCM_I2CCTL3)); + return !!(I2CCTL3_SCL_LVL & ioread8(bus->reg + NPCM_I2CCTL3)); } static int npcm_i2c_get_SDA(struct i2c_adapter *_adap) { struct npcm_i2c *bus = container_of(_adap, struct npcm_i2c, adap); - return !!(I2CCTL3_SDA_LVL & ioread32(bus->reg + NPCM_I2CCTL3)); + return !!(I2CCTL3_SDA_LVL & ioread8(bus->reg + NPCM_I2CCTL3)); } static inline u16 npcm_i2c_get_index(struct npcm_i2c *bus) @@ -563,6 +564,15 @@ static inline void npcm_i2c_nack(struct npcm_i2c *bus) iowrite8(val, bus->reg + NPCM_I2CCTL1); } +static inline void npcm_i2c_clear_master_status(struct npcm_i2c *bus) +{ + u8 val; + + /* Clear NEGACK, STASTR and BER bits */ + val = NPCM_I2CST_BER | NPCM_I2CST_NEGACK | NPCM_I2CST_STASTR; + iowrite8(val, bus->reg + NPCM_I2CST); +} + #if IS_ENABLED(CONFIG_I2C_SLAVE) static void npcm_i2c_slave_int_enable(struct npcm_i2c *bus, bool enable) { @@ -642,8 +652,8 @@ static void npcm_i2c_reset(struct npcm_i2c *bus) iowrite8(NPCM_I2CCST_BB, bus->reg + NPCM_I2CCST); iowrite8(0xFF, bus->reg + NPCM_I2CST); - /* Clear EOB bit */ - iowrite8(NPCM_I2CCST3_EO_BUSY, bus->reg + NPCM_I2CCST3); + /* Clear and disable EOB */ + npcm_i2c_eob_int(bus, false); /* Clear all fifo bits: */ iowrite8(NPCM_I2CFIF_CTS_CLR_FIFO, bus->reg + NPCM_I2CFIF_CTS); @@ -655,6 +665,9 @@ static void npcm_i2c_reset(struct npcm_i2c *bus) } #endif + /* clear status bits for spurious interrupts */ + npcm_i2c_clear_master_status(bus); + bus->state = I2C_IDLE; } @@ -684,6 +697,8 @@ static void npcm_i2c_callback(struct npcm_i2c *bus, switch (op_status) { case I2C_MASTER_DONE_IND: bus->cmd_err = bus->msgs_num; + if (bus->tx_complete_cnt < ULLONG_MAX) + bus->tx_complete_cnt++; fallthrough; case I2C_BLOCK_BYTES_ERR_IND: /* Master tx finished and all transmit bytes were sent */ @@ -815,15 +830,6 @@ static void npcm_i2c_read_fifo(struct npcm_i2c *bus, u8 bytes_in_fifo) } } -static inline void npcm_i2c_clear_master_status(struct npcm_i2c *bus) -{ - u8 val; - - /* Clear NEGACK, STASTR and BER bits */ - val = NPCM_I2CST_BER | NPCM_I2CST_NEGACK | NPCM_I2CST_STASTR; - iowrite8(val, bus->reg + NPCM_I2CST); -} - static void npcm_i2c_master_abort(struct npcm_i2c *bus) { /* Only current master is allowed to issue a stop condition */ @@ -1231,7 +1237,16 @@ static irqreturn_t npcm_i2c_int_slave_handler(struct npcm_i2c *bus) ret = IRQ_HANDLED; } /* SDAST */ - return ret; + /* + * if irq is not one of the above, make sure EOB is disabled and all + * status bits are cleared. + */ + if (ret == IRQ_NONE) { + npcm_i2c_eob_int(bus, false); + npcm_i2c_clear_master_status(bus); + } + + return IRQ_HANDLED; } static int npcm_i2c_reg_slave(struct i2c_client *client) @@ -1467,6 +1482,9 @@ static void npcm_i2c_irq_handle_nack(struct npcm_i2c *bus) npcm_i2c_eob_int(bus, false); npcm_i2c_master_stop(bus); + /* Clear SDA Status bit (by reading dummy byte) */ + npcm_i2c_rd_byte(bus); + /* * The bus is released from stall only after the SW clears * NEGACK bit. Then a Stop condition is sent. @@ -1474,6 +1492,8 @@ static void npcm_i2c_irq_handle_nack(struct npcm_i2c *bus) npcm_i2c_clear_master_status(bus); readx_poll_timeout_atomic(ioread8, bus->reg + NPCM_I2CCST, val, !(val & NPCM_I2CCST_BUSY), 10, 200); + /* verify no status bits are still set after bus is released */ + npcm_i2c_clear_master_status(bus); } bus->state = I2C_IDLE; @@ -1672,10 +1692,10 @@ static int npcm_i2c_recovery_tgclk(struct i2c_adapter *_adap) int iter = 27; if ((npcm_i2c_get_SDA(_adap) == 1) && (npcm_i2c_get_SCL(_adap) == 1)) { - dev_dbg(bus->dev, "bus%d recovery skipped, bus not stuck", - bus->num); + dev_dbg(bus->dev, "bus%d-0x%x recovery skipped, bus not stuck", + bus->num, bus->dest_addr); npcm_i2c_reset(bus); - return status; + return 0; } npcm_i2c_int_enable(bus, false); @@ -1909,6 +1929,7 @@ static int npcm_i2c_init_module(struct npcm_i2c *bus, enum i2c_mode mode, bus_freq_hz < I2C_FREQ_MIN_HZ || bus_freq_hz > I2C_FREQ_MAX_HZ) return -EINVAL; + npcm_i2c_int_enable(bus, false); npcm_i2c_disable(bus); /* Configure FIFO mode : */ @@ -1937,10 +1958,17 @@ static int npcm_i2c_init_module(struct npcm_i2c *bus, enum i2c_mode mode, val = (val | NPCM_I2CCTL1_NMINTE) & ~NPCM_I2CCTL1_RWS; iowrite8(val, bus->reg + NPCM_I2CCTL1); - npcm_i2c_int_enable(bus, true); - npcm_i2c_reset(bus); + /* check HW is OK: SDA and SCL should be high at this point. */ + if ((npcm_i2c_get_SDA(&bus->adap) == 0) || (npcm_i2c_get_SCL(&bus->adap) == 0)) { + dev_err(bus->dev, "I2C%d init fail: lines are low\n", bus->num); + dev_err(bus->dev, "SDA=%d SCL=%d\n", npcm_i2c_get_SDA(&bus->adap), + npcm_i2c_get_SCL(&bus->adap)); + return -ENXIO; + } + + npcm_i2c_int_enable(bus, true); return 0; } @@ -1988,10 +2016,14 @@ static irqreturn_t npcm_i2c_bus_irq(int irq, void *dev_id) #if IS_ENABLED(CONFIG_I2C_SLAVE) if (bus->slave) { bus->master_or_slave = I2C_SLAVE; - return npcm_i2c_int_slave_handler(bus); + if (npcm_i2c_int_slave_handler(bus)) + return IRQ_HANDLED; } #endif - return IRQ_NONE; + /* clear status bits for spurious interrupts */ + npcm_i2c_clear_master_status(bus); + + return IRQ_HANDLED; } static bool npcm_i2c_master_start_xmit(struct npcm_i2c *bus, @@ -2047,8 +2079,7 @@ static int npcm_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, u16 nwrite, nread; u8 *write_data, *read_data; u8 slave_addr; - int timeout; - int ret = 0; + unsigned long timeout; bool read_block = false; bool read_PEC = false; u8 bus_busy; @@ -2099,13 +2130,13 @@ static int npcm_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, * 9: bits per transaction (including the ack/nack) */ timeout_usec = (2 * 9 * USEC_PER_SEC / bus->bus_freq) * (2 + nread + nwrite); - timeout = max(msecs_to_jiffies(35), usecs_to_jiffies(timeout_usec)); + timeout = max_t(unsigned long, bus->adap.timeout, usecs_to_jiffies(timeout_usec)); if (nwrite >= 32 * 1024 || nread >= 32 * 1024) { dev_err(bus->dev, "i2c%d buffer too big\n", bus->num); return -EINVAL; } - time_left = jiffies + msecs_to_jiffies(DEFAULT_STALL_COUNT) + 1; + time_left = jiffies + timeout + 1; do { /* * we must clear slave address immediately when the bus is not @@ -2138,12 +2169,12 @@ static int npcm_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, bus->read_block_use = read_block; reinit_completion(&bus->cmd_complete); - if (!npcm_i2c_master_start_xmit(bus, slave_addr, nwrite, nread, - write_data, read_data, read_PEC, - read_block)) - ret = -EBUSY; - if (ret != -EBUSY) { + npcm_i2c_int_enable(bus, true); + + if (npcm_i2c_master_start_xmit(bus, slave_addr, nwrite, nread, + write_data, read_data, read_PEC, + read_block)) { time_left = wait_for_completion_timeout(&bus->cmd_complete, timeout); @@ -2157,26 +2188,31 @@ static int npcm_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, } } } - ret = bus->cmd_err; /* if there was BER, check if need to recover the bus: */ if (bus->cmd_err == -EAGAIN) - ret = i2c_recover_bus(adap); + bus->cmd_err = i2c_recover_bus(adap); /* * After any type of error, check if LAST bit is still set, * due to a HW issue. * It cannot be cleared without resetting the module. */ - if (bus->cmd_err && - (NPCM_I2CRXF_CTL_LAST_PEC & ioread8(bus->reg + NPCM_I2CRXF_CTL))) + else if (bus->cmd_err && + (NPCM_I2CRXF_CTL_LAST_PEC & ioread8(bus->reg + NPCM_I2CRXF_CTL))) npcm_i2c_reset(bus); + /* after any xfer, successful or not, stall and EOB must be disabled */ + npcm_i2c_stall_after_start(bus, false); + npcm_i2c_eob_int(bus, false); + #if IS_ENABLED(CONFIG_I2C_SLAVE) /* reenable slave if it was enabled */ if (bus->slave) iowrite8((bus->slave->addr & 0x7F) | NPCM_I2CADDR_SAEN, bus->reg + NPCM_I2CADDR1); +#else + npcm_i2c_int_enable(bus, false); #endif return bus->cmd_err; } @@ -2223,17 +2259,18 @@ static void npcm_i2c_init_debugfs(struct platform_device *pdev, debugfs_create_u64("rec_succ_cnt", 0444, d, &bus->rec_succ_cnt); debugfs_create_u64("rec_fail_cnt", 0444, d, &bus->rec_fail_cnt); debugfs_create_u64("timeout_cnt", 0444, d, &bus->timeout_cnt); + debugfs_create_u64("tx_complete_cnt", 0444, d, &bus->tx_complete_cnt); bus->debugfs = d; } static int npcm_i2c_probe_bus(struct platform_device *pdev) { - struct npcm_i2c *bus; + struct device_node *np = pdev->dev.of_node; + static struct regmap *gcr_regmap; struct i2c_adapter *adap; + struct npcm_i2c *bus; struct clk *i2c_clk; - static struct regmap *gcr_regmap; - static struct regmap *clk_regmap; int irq; int ret; @@ -2250,15 +2287,14 @@ static int npcm_i2c_probe_bus(struct platform_device *pdev) return PTR_ERR(i2c_clk); bus->apb_clk = clk_get_rate(i2c_clk); - gcr_regmap = syscon_regmap_lookup_by_compatible("nuvoton,npcm750-gcr"); + gcr_regmap = syscon_regmap_lookup_by_phandle(np, "nuvoton,sys-mgr"); + if (IS_ERR(gcr_regmap)) + gcr_regmap = syscon_regmap_lookup_by_compatible("nuvoton,npcm750-gcr"); + if (IS_ERR(gcr_regmap)) return PTR_ERR(gcr_regmap); regmap_write(gcr_regmap, NPCM_I2CSEGCTL, NPCM_I2CSEGCTL_INIT_VAL); - clk_regmap = syscon_regmap_lookup_by_compatible("nuvoton,npcm750-clk"); - if (IS_ERR(clk_regmap)) - return PTR_ERR(clk_regmap); - bus->reg = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(bus->reg)) return PTR_ERR(bus->reg); @@ -2269,7 +2305,7 @@ static int npcm_i2c_probe_bus(struct platform_device *pdev) adap = &bus->adap; adap->owner = THIS_MODULE; adap->retries = 3; - adap->timeout = HZ; + adap->timeout = msecs_to_jiffies(35); adap->algo = &npcm_i2c_algo; adap->quirks = &npcm_i2c_quirks; adap->algo_data = bus; diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c index 5241e6f414e9..2e74747eec9c 100644 --- a/drivers/i2c/busses/i2c-powermac.c +++ b/drivers/i2c/busses/i2c-powermac.c @@ -15,7 +15,7 @@ #include <linux/device.h> #include <linux/platform_device.h> #include <linux/of_irq.h> -#include <asm/prom.h> + #include <asm/pmac_low_i2c.h> MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>"); diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c index 5b920f0fc7dd..6ac402ea58fb 100644 --- a/drivers/i2c/busses/i2c-qcom-geni.c +++ b/drivers/i2c/busses/i2c-qcom-geni.c @@ -727,16 +727,14 @@ static int setup_gpi_dma(struct geni_i2c_dev *gi2c) if (IS_ERR(gi2c->tx_c)) { ret = dev_err_probe(gi2c->se.dev, PTR_ERR(gi2c->tx_c), "Failed to get tx DMA ch\n"); - if (ret < 0) - goto err_tx; + goto err_tx; } gi2c->rx_c = dma_request_chan(gi2c->se.dev, "rx"); if (IS_ERR(gi2c->rx_c)) { ret = dev_err_probe(gi2c->se.dev, PTR_ERR(gi2c->rx_c), "Failed to get rx DMA ch\n"); - if (ret < 0) - goto err_rx; + goto err_rx; } dev_dbg(gi2c->se.dev, "Grabbed GPI dma channels\n"); diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index 0db3d7559066..6e7be9d9f504 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c @@ -45,44 +45,44 @@ #define ICDMAER 0x3c /* DMA enable (Gen3) */ /* ICSCR */ -#define SDBS (1 << 3) /* slave data buffer select */ -#define SIE (1 << 2) /* slave interface enable */ -#define GCAE (1 << 1) /* general call address enable */ -#define FNA (1 << 0) /* forced non acknowledgment */ +#define SDBS BIT(3) /* slave data buffer select */ +#define SIE BIT(2) /* slave interface enable */ +#define GCAE BIT(1) /* general call address enable */ +#define FNA BIT(0) /* forced non acknowledgment */ /* ICMCR */ -#define MDBS (1 << 7) /* non-fifo mode switch */ -#define FSCL (1 << 6) /* override SCL pin */ -#define FSDA (1 << 5) /* override SDA pin */ -#define OBPC (1 << 4) /* override pins */ -#define MIE (1 << 3) /* master if enable */ -#define TSBE (1 << 2) -#define FSB (1 << 1) /* force stop bit */ -#define ESG (1 << 0) /* enable start bit gen */ +#define MDBS BIT(7) /* non-fifo mode switch */ +#define FSCL BIT(6) /* override SCL pin */ +#define FSDA BIT(5) /* override SDA pin */ +#define OBPC BIT(4) /* override pins */ +#define MIE BIT(3) /* master if enable */ +#define TSBE BIT(2) +#define FSB BIT(1) /* force stop bit */ +#define ESG BIT(0) /* enable start bit gen */ /* ICSSR (also for ICSIER) */ -#define GCAR (1 << 6) /* general call received */ -#define STM (1 << 5) /* slave transmit mode */ -#define SSR (1 << 4) /* stop received */ -#define SDE (1 << 3) /* slave data empty */ -#define SDT (1 << 2) /* slave data transmitted */ -#define SDR (1 << 1) /* slave data received */ -#define SAR (1 << 0) /* slave addr received */ +#define GCAR BIT(6) /* general call received */ +#define STM BIT(5) /* slave transmit mode */ +#define SSR BIT(4) /* stop received */ +#define SDE BIT(3) /* slave data empty */ +#define SDT BIT(2) /* slave data transmitted */ +#define SDR BIT(1) /* slave data received */ +#define SAR BIT(0) /* slave addr received */ /* ICMSR (also for ICMIE) */ -#define MNR (1 << 6) /* nack received */ -#define MAL (1 << 5) /* arbitration lost */ -#define MST (1 << 4) /* sent a stop */ -#define MDE (1 << 3) -#define MDT (1 << 2) -#define MDR (1 << 1) -#define MAT (1 << 0) /* slave addr xfer done */ +#define MNR BIT(6) /* nack received */ +#define MAL BIT(5) /* arbitration lost */ +#define MST BIT(4) /* sent a stop */ +#define MDE BIT(3) +#define MDT BIT(2) +#define MDR BIT(1) +#define MAT BIT(0) /* slave addr xfer done */ /* ICDMAER */ -#define RSDMAE (1 << 3) /* DMA Slave Received Enable */ -#define TSDMAE (1 << 2) /* DMA Slave Transmitted Enable */ -#define RMDMAE (1 << 1) /* DMA Master Received Enable */ -#define TMDMAE (1 << 0) /* DMA Master Transmitted Enable */ +#define RSDMAE BIT(3) /* DMA Slave Received Enable */ +#define TSDMAE BIT(2) /* DMA Slave Transmitted Enable */ +#define RMDMAE BIT(1) /* DMA Master Received Enable */ +#define TMDMAE BIT(0) /* DMA Master Transmitted Enable */ /* ICFBSCR */ #define TCYC17 0x0f /* 17*Tcyc delay 1st bit between SDA and SCL */ @@ -97,17 +97,15 @@ #define RCAR_IRQ_RECV (MNR | MAL | MST | MAT | MDR) #define RCAR_IRQ_STOP (MST) -#define RCAR_IRQ_ACK_SEND (~(MAT | MDE) & 0x7F) -#define RCAR_IRQ_ACK_RECV (~(MAT | MDR) & 0x7F) - -#define ID_LAST_MSG (1 << 0) -#define ID_FIRST_MSG (1 << 1) -#define ID_DONE (1 << 2) -#define ID_ARBLOST (1 << 3) -#define ID_NACK (1 << 4) +#define ID_LAST_MSG BIT(0) +#define ID_REP_AFTER_RD BIT(1) +#define ID_DONE BIT(2) +#define ID_ARBLOST BIT(3) +#define ID_NACK BIT(4) +#define ID_EPROTO BIT(5) /* persistent flags */ -#define ID_P_HOST_NOTIFY BIT(28) -#define ID_P_REP_AFTER_RD BIT(29) +#define ID_P_NOT_ATOMIC BIT(28) +#define ID_P_HOST_NOTIFY BIT(29) #define ID_P_NO_RXDMA BIT(30) /* HW forbids RXDMA sometimes */ #define ID_P_PM_BLOCKED BIT(31) #define ID_P_MASK GENMASK(31, 28) @@ -141,7 +139,6 @@ struct rcar_i2c_priv { enum dma_data_direction dma_direction; struct reset_control *rstc; - bool atomic_xfer; int irq; struct i2c_client *host_notify_client; @@ -160,6 +157,11 @@ static u32 rcar_i2c_read(struct rcar_i2c_priv *priv, int reg) return readl(priv->io + reg); } +static void rcar_i2c_clear_irq(struct rcar_i2c_priv *priv, u32 val) +{ + writel(~val & 0x7f, priv->io + ICMSR); +} + static int rcar_i2c_get_scl(struct i2c_adapter *adap) { struct rcar_i2c_priv *priv = i2c_get_adapdata(adap); @@ -330,41 +332,46 @@ scgd_find: return 0; } +/* + * We don't have a test case but the HW engineers say that the write order of + * ICMSR and ICMCR depends on whether we issue START or REP_START. So, ICMSR + * handling is outside of this function. First messages clear ICMSR before this + * function, interrupt handlers clear the relevant bits after this function. + */ static void rcar_i2c_prepare_msg(struct rcar_i2c_priv *priv) { int read = !!rcar_i2c_is_recv(priv); + bool rep_start = !(priv->flags & ID_REP_AFTER_RD); priv->pos = 0; + priv->flags &= ID_P_MASK; + if (priv->msgs_left == 1) priv->flags |= ID_LAST_MSG; rcar_i2c_write(priv, ICMAR, i2c_8bit_addr_from_msg(priv->msg)); - if (!priv->atomic_xfer) + if (priv->flags & ID_P_NOT_ATOMIC) rcar_i2c_write(priv, ICMIER, read ? RCAR_IRQ_RECV : RCAR_IRQ_SEND); - /* - * We don't have a test case but the HW engineers say that the write order - * of ICMSR and ICMCR depends on whether we issue START or REP_START. Since - * it didn't cause a drawback for me, let's rather be safe than sorry. - */ - if (priv->flags & ID_FIRST_MSG) { - rcar_i2c_write(priv, ICMSR, 0); + if (rep_start) rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START); - } else { - if (priv->flags & ID_P_REP_AFTER_RD) - priv->flags &= ~ID_P_REP_AFTER_RD; - else - rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START); - rcar_i2c_write(priv, ICMSR, 0); - } +} + +static void rcar_i2c_first_msg(struct rcar_i2c_priv *priv, + struct i2c_msg *msgs, int num) +{ + priv->msg = msgs; + priv->msgs_left = num; + rcar_i2c_write(priv, ICMSR, 0); /* must be before preparing msg */ + rcar_i2c_prepare_msg(priv); } static void rcar_i2c_next_msg(struct rcar_i2c_priv *priv) { priv->msg++; priv->msgs_left--; - priv->flags &= ID_P_MASK; rcar_i2c_prepare_msg(priv); + /* ICMSR handling must come afterwards in the irq handler */ } static void rcar_i2c_cleanup_dma(struct rcar_i2c_priv *priv, bool terminate) @@ -413,7 +420,7 @@ static bool rcar_i2c_dma(struct rcar_i2c_priv *priv) int len; /* Do various checks to see if DMA is feasible at all */ - if (priv->atomic_xfer || IS_ERR(chan) || msg->len < RCAR_MIN_DMA_LEN || + if (!(priv->flags & ID_P_NOT_ATOMIC) || IS_ERR(chan) || msg->len < RCAR_MIN_DMA_LEN || !(msg->flags & I2C_M_DMA_SAFE) || (read && priv->flags & ID_P_NO_RXDMA)) return false; @@ -475,11 +482,15 @@ static bool rcar_i2c_dma(struct rcar_i2c_priv *priv) static void rcar_i2c_irq_send(struct rcar_i2c_priv *priv, u32 msr) { struct i2c_msg *msg = priv->msg; + u32 irqs_to_clear = MDE; /* FIXME: sometimes, unknown interrupt happened. Do nothing */ if (!(msr & MDE)) return; + if (msr & MAT) + irqs_to_clear |= MAT; + /* Check if DMA can be enabled and take over */ if (priv->pos == 1 && rcar_i2c_dma(priv)) return; @@ -503,31 +514,32 @@ static void rcar_i2c_irq_send(struct rcar_i2c_priv *priv, u32 msr) * [ICRXTX] -> [SHIFT] -> [I2C bus] */ - if (priv->flags & ID_LAST_MSG) { + if (priv->flags & ID_LAST_MSG) /* * If current msg is the _LAST_ msg, * prepare stop condition here. * ID_DONE will be set on STOP irq. */ rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP); - } else { + else rcar_i2c_next_msg(priv); - return; - } } - rcar_i2c_write(priv, ICMSR, RCAR_IRQ_ACK_SEND); + rcar_i2c_clear_irq(priv, irqs_to_clear); } static void rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr) { struct i2c_msg *msg = priv->msg; + bool recv_len_init = priv->pos == 0 && msg->flags & I2C_M_RECV_LEN; + u32 irqs_to_clear = MDR; /* FIXME: sometimes, unknown interrupt happened. Do nothing */ if (!(msr & MDR)) return; if (msr & MAT) { + irqs_to_clear |= MAT; /* * Address transfer phase finished, but no data at this point. * Try to use DMA to receive data. @@ -535,24 +547,41 @@ static void rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr) rcar_i2c_dma(priv); } else if (priv->pos < msg->len) { /* get received data */ - msg->buf[priv->pos] = rcar_i2c_read(priv, ICRXTX); + u8 data = rcar_i2c_read(priv, ICRXTX); + + msg->buf[priv->pos] = data; + if (recv_len_init) { + if (data == 0 || data > I2C_SMBUS_BLOCK_MAX) { + priv->flags |= ID_DONE | ID_EPROTO; + return; + } + msg->len += msg->buf[0]; + /* Enough data for DMA? */ + if (rcar_i2c_dma(priv)) + return; + /* new length after RECV_LEN now properly initialized */ + recv_len_init = false; + } priv->pos++; } - /* If next received data is the _LAST_, go to new phase. */ - if (priv->pos + 1 == msg->len) { + /* + * If next received data is the _LAST_ and we are not waiting for a new + * length because of RECV_LEN, then go to a new phase. + */ + if (priv->pos + 1 == msg->len && !recv_len_init) { if (priv->flags & ID_LAST_MSG) { rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP); } else { rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START); - priv->flags |= ID_P_REP_AFTER_RD; + priv->flags |= ID_REP_AFTER_RD; } } if (priv->pos == msg->len && !(priv->flags & ID_LAST_MSG)) rcar_i2c_next_msg(priv); - else - rcar_i2c_write(priv, ICMSR, RCAR_IRQ_ACK_RECV); + + rcar_i2c_clear_irq(priv, irqs_to_clear); } static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv) @@ -641,7 +670,7 @@ static irqreturn_t rcar_i2c_irq(int irq, struct rcar_i2c_priv *priv, u32 msr) /* Nack */ if (msr & MNR) { /* HW automatically sends STOP after received NACK */ - if (!priv->atomic_xfer) + if (priv->flags & ID_P_NOT_ATOMIC) rcar_i2c_write(priv, ICMIER, RCAR_IRQ_STOP); priv->flags |= ID_NACK; goto out; @@ -663,7 +692,7 @@ out: if (priv->flags & ID_DONE) { rcar_i2c_write(priv, ICMIER, 0); rcar_i2c_write(priv, ICMSR, 0); - if (!priv->atomic_xfer) + if (priv->flags & ID_P_NOT_ATOMIC) wake_up(&priv->wait); } @@ -676,12 +705,12 @@ static irqreturn_t rcar_i2c_gen2_irq(int irq, void *ptr) u32 msr; /* Clear START or STOP immediately, except for REPSTART after read */ - if (likely(!(priv->flags & ID_P_REP_AFTER_RD))) + if (likely(!(priv->flags & ID_REP_AFTER_RD))) rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_DATA); /* Only handle interrupts that are currently enabled */ msr = rcar_i2c_read(priv, ICMSR); - if (!priv->atomic_xfer) + if (priv->flags & ID_P_NOT_ATOMIC) msr &= rcar_i2c_read(priv, ICMIER); return rcar_i2c_irq(irq, priv, msr); @@ -694,14 +723,14 @@ static irqreturn_t rcar_i2c_gen3_irq(int irq, void *ptr) /* Only handle interrupts that are currently enabled */ msr = rcar_i2c_read(priv, ICMSR); - if (!priv->atomic_xfer) + if (priv->flags & ID_P_NOT_ATOMIC) msr &= rcar_i2c_read(priv, ICMIER); /* * Clear START or STOP immediately, except for REPSTART after read or * if a spurious interrupt was detected. */ - if (likely(!(priv->flags & ID_P_REP_AFTER_RD) && msr)) + if (likely(!(priv->flags & ID_REP_AFTER_RD) && msr)) rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_DATA); return rcar_i2c_irq(irq, priv, msr); @@ -803,7 +832,7 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap, int i, ret; long time_left; - priv->atomic_xfer = false; + priv->flags |= ID_P_NOT_ATOMIC; pm_runtime_get_sync(dev); @@ -827,11 +856,7 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap, for (i = 0; i < num; i++) rcar_i2c_request_dma(priv, msgs + i); - /* init first message */ - priv->msg = msgs; - priv->msgs_left = num; - priv->flags = (priv->flags & ID_P_MASK) | ID_FIRST_MSG; - rcar_i2c_prepare_msg(priv); + rcar_i2c_first_msg(priv, msgs, num); time_left = wait_event_timeout(priv->wait, priv->flags & ID_DONE, num * adap->timeout); @@ -847,6 +872,8 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap, ret = -ENXIO; } else if (priv->flags & ID_ARBLOST) { ret = -EAGAIN; + } else if (priv->flags & ID_EPROTO) { + ret = -EPROTO; } else { ret = num - priv->msgs_left; /* The number of transfer */ } @@ -869,7 +896,7 @@ static int rcar_i2c_master_xfer_atomic(struct i2c_adapter *adap, bool time_left; int ret; - priv->atomic_xfer = true; + priv->flags &= ~ID_P_NOT_ATOMIC; pm_runtime_get_sync(dev); @@ -879,12 +906,7 @@ static int rcar_i2c_master_xfer_atomic(struct i2c_adapter *adap, goto out; rcar_i2c_init(priv); - - /* init first message */ - priv->msg = msgs; - priv->msgs_left = num; - priv->flags = (priv->flags & ID_P_MASK) | ID_FIRST_MSG; - rcar_i2c_prepare_msg(priv); + rcar_i2c_first_msg(priv, msgs, num); j = jiffies + num * adap->timeout; do { @@ -909,6 +931,8 @@ static int rcar_i2c_master_xfer_atomic(struct i2c_adapter *adap, ret = -ENXIO; } else if (priv->flags & ID_ARBLOST) { ret = -EAGAIN; + } else if (priv->flags & ID_EPROTO) { + ret = -EPROTO; } else { ret = num - priv->msgs_left; /* The number of transfer */ } @@ -975,7 +999,7 @@ static u32 rcar_i2c_func(struct i2c_adapter *adap) * I2C_M_IGNORE_NAK (automatically sends STOP after NAK) */ u32 func = I2C_FUNC_I2C | I2C_FUNC_SLAVE | - (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK); + (I2C_FUNC_SMBUS_EMUL_ALL & ~I2C_FUNC_SMBUS_QUICK); if (priv->flags & ID_P_HOST_NOTIFY) func |= I2C_FUNC_SMBUS_HOST_NOTIFY; @@ -1063,8 +1087,10 @@ static int rcar_i2c_probe(struct platform_device *pdev) pm_runtime_enable(dev); pm_runtime_get_sync(dev); ret = rcar_i2c_clock_calculate(priv); - if (ret < 0) - goto out_pm_put; + if (ret < 0) { + pm_runtime_put(dev); + goto out_pm_disable; + } rcar_i2c_write(priv, ICSAR, 0); /* Gen2: must be 0 if not using slave */ @@ -1093,19 +1119,19 @@ static int rcar_i2c_probe(struct platform_device *pdev) ret = platform_get_irq(pdev, 0); if (ret < 0) - goto out_pm_disable; + goto out_pm_put; priv->irq = ret; ret = devm_request_irq(dev, priv->irq, irqhandler, irqflags, dev_name(dev), priv); if (ret < 0) { dev_err(dev, "cannot get irq %d\n", priv->irq); - goto out_pm_disable; + goto out_pm_put; } platform_set_drvdata(pdev, priv); ret = i2c_add_numbered_adapter(adap); if (ret < 0) - goto out_pm_disable; + goto out_pm_put; if (priv->flags & ID_P_HOST_NOTIFY) { priv->host_notify_client = i2c_new_slave_host_notify_device(adap); @@ -1122,7 +1148,8 @@ static int rcar_i2c_probe(struct platform_device *pdev) out_del_device: i2c_del_adapter(&priv->adap); out_pm_put: - pm_runtime_put(dev); + if (priv->flags & ID_P_PM_BLOCKED) + pm_runtime_put(dev); out_pm_disable: pm_runtime_disable(dev); return ret; diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c index ffefe3c482e9..9a1c3f8b7048 100644 --- a/drivers/i2c/busses/i2c-xiic.c +++ b/drivers/i2c/busses/i2c-xiic.c @@ -78,24 +78,23 @@ struct xiic_i2c { bool singlemaster; }; - #define XIIC_MSB_OFFSET 0 -#define XIIC_REG_OFFSET (0x100+XIIC_MSB_OFFSET) +#define XIIC_REG_OFFSET (0x100 + XIIC_MSB_OFFSET) /* * Register offsets in bytes from RegisterBase. Three is added to the * base offset to access LSB (IBM style) of the word */ -#define XIIC_CR_REG_OFFSET (0x00+XIIC_REG_OFFSET) /* Control Register */ -#define XIIC_SR_REG_OFFSET (0x04+XIIC_REG_OFFSET) /* Status Register */ -#define XIIC_DTR_REG_OFFSET (0x08+XIIC_REG_OFFSET) /* Data Tx Register */ -#define XIIC_DRR_REG_OFFSET (0x0C+XIIC_REG_OFFSET) /* Data Rx Register */ -#define XIIC_ADR_REG_OFFSET (0x10+XIIC_REG_OFFSET) /* Address Register */ -#define XIIC_TFO_REG_OFFSET (0x14+XIIC_REG_OFFSET) /* Tx FIFO Occupancy */ -#define XIIC_RFO_REG_OFFSET (0x18+XIIC_REG_OFFSET) /* Rx FIFO Occupancy */ -#define XIIC_TBA_REG_OFFSET (0x1C+XIIC_REG_OFFSET) /* 10 Bit Address reg */ -#define XIIC_RFD_REG_OFFSET (0x20+XIIC_REG_OFFSET) /* Rx FIFO Depth reg */ -#define XIIC_GPO_REG_OFFSET (0x24+XIIC_REG_OFFSET) /* Output Register */ +#define XIIC_CR_REG_OFFSET (0x00 + XIIC_REG_OFFSET) /* Control Register */ +#define XIIC_SR_REG_OFFSET (0x04 + XIIC_REG_OFFSET) /* Status Register */ +#define XIIC_DTR_REG_OFFSET (0x08 + XIIC_REG_OFFSET) /* Data Tx Register */ +#define XIIC_DRR_REG_OFFSET (0x0C + XIIC_REG_OFFSET) /* Data Rx Register */ +#define XIIC_ADR_REG_OFFSET (0x10 + XIIC_REG_OFFSET) /* Address Register */ +#define XIIC_TFO_REG_OFFSET (0x14 + XIIC_REG_OFFSET) /* Tx FIFO Occupancy */ +#define XIIC_RFO_REG_OFFSET (0x18 + XIIC_REG_OFFSET) /* Rx FIFO Occupancy */ +#define XIIC_TBA_REG_OFFSET (0x1C + XIIC_REG_OFFSET) /* 10 Bit Address reg */ +#define XIIC_RFD_REG_OFFSET (0x20 + XIIC_REG_OFFSET) /* Rx FIFO Depth reg */ +#define XIIC_GPO_REG_OFFSET (0x24 + XIIC_REG_OFFSET) /* Output Register */ /* Control Register masks */ #define XIIC_CR_ENABLE_DEVICE_MASK 0x01 /* Device enable = 1 */ @@ -233,18 +232,21 @@ static inline int xiic_getreg32(struct xiic_i2c *i2c, int reg) static inline void xiic_irq_dis(struct xiic_i2c *i2c, u32 mask) { u32 ier = xiic_getreg32(i2c, XIIC_IIER_OFFSET); + xiic_setreg32(i2c, XIIC_IIER_OFFSET, ier & ~mask); } static inline void xiic_irq_en(struct xiic_i2c *i2c, u32 mask) { u32 ier = xiic_getreg32(i2c, XIIC_IIER_OFFSET); + xiic_setreg32(i2c, XIIC_IIER_OFFSET, ier | mask); } static inline void xiic_irq_clr(struct xiic_i2c *i2c, u32 mask) { u32 isr = xiic_getreg32(i2c, XIIC_IISR_OFFSET); + xiic_setreg32(i2c, XIIC_IISR_OFFSET, isr & mask); } @@ -355,7 +357,8 @@ static void xiic_fill_tx_fifo(struct xiic_i2c *i2c) while (len--) { u16 data = i2c->tx_msg->buf[i2c->tx_pos++]; - if ((xiic_tx_space(i2c) == 0) && (i2c->nmsgs == 1)) { + + if (!xiic_tx_space(i2c) && i2c->nmsgs == 1) { /* last message in transfer -> STOP */ data |= XIIC_TX_DYN_STOP_MASK; dev_dbg(i2c->adap.dev.parent, "%s TX STOP\n", __func__); @@ -381,6 +384,7 @@ static irqreturn_t xiic_process(int irq, void *dev_id) int xfer_more = 0; int wakeup_req = 0; int wakeup_code = 0; + int ret; /* Get the interrupt Status from the IPIF. There is no clearing of * interrupts in the IPIF. Interrupts must be cleared at the source. @@ -401,8 +405,8 @@ static irqreturn_t xiic_process(int irq, void *dev_id) /* Service requesting interrupt */ if ((pend & XIIC_INTR_ARB_LOST_MASK) || - ((pend & XIIC_INTR_TX_ERROR_MASK) && - !(pend & XIIC_INTR_RX_FULL_MASK))) { + ((pend & XIIC_INTR_TX_ERROR_MASK) && + !(pend & XIIC_INTR_RX_FULL_MASK))) { /* bus arbritration lost, or... * Transmit error _OR_ RX completed * if this happens when RX_FULL is not set @@ -415,7 +419,9 @@ static irqreturn_t xiic_process(int irq, void *dev_id) * fifos and the next message is a TX with len 0 (only addr) * reset the IP instead of just flush fifos */ - xiic_reinit(i2c); + ret = xiic_reinit(i2c); + if (!ret) + dev_dbg(i2c->adap.dev.parent, "reinit failed\n"); if (i2c->rx_msg) { wakeup_req = 1; @@ -462,24 +468,6 @@ static irqreturn_t xiic_process(int irq, void *dev_id) } } } - if (pend & XIIC_INTR_BNB_MASK) { - /* IIC bus has transitioned to not busy */ - clr |= XIIC_INTR_BNB_MASK; - - /* The bus is not busy, disable BusNotBusy interrupt */ - xiic_irq_dis(i2c, XIIC_INTR_BNB_MASK); - - if (!i2c->tx_msg) - goto out; - - wakeup_req = 1; - - if (i2c->nmsgs == 1 && !i2c->rx_msg && - xiic_tx_space(i2c) == 0) - wakeup_code = STATE_DONE; - else - wakeup_code = STATE_ERROR; - } if (pend & (XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_HALF_MASK)) { /* Transmit register/FIFO is empty or ½ empty */ @@ -516,6 +504,26 @@ static irqreturn_t xiic_process(int irq, void *dev_id) */ xiic_irq_dis(i2c, XIIC_INTR_TX_HALF_MASK); } + + if (pend & XIIC_INTR_BNB_MASK) { + /* IIC bus has transitioned to not busy */ + clr |= XIIC_INTR_BNB_MASK; + + /* The bus is not busy, disable BusNotBusy interrupt */ + xiic_irq_dis(i2c, XIIC_INTR_BNB_MASK); + + if (!i2c->tx_msg) + goto out; + + wakeup_req = 1; + + if (i2c->nmsgs == 1 && !i2c->rx_msg && + xiic_tx_space(i2c) == 0) + wakeup_code = STATE_DONE; + else + wakeup_code = STATE_ERROR; + } + out: dev_dbg(i2c->adap.dev.parent, "%s clr: 0x%x\n", __func__, clr); @@ -570,7 +578,7 @@ static int xiic_busy(struct xiic_i2c *i2c) static void xiic_start_recv(struct xiic_i2c *i2c) { - u8 rx_watermark; + u16 rx_watermark; struct i2c_msg *msg = i2c->rx_msg = i2c->tx_msg; /* Clear and enable Rx full interrupt. */ @@ -585,7 +593,7 @@ static void xiic_start_recv(struct xiic_i2c *i2c) rx_watermark = msg->len; if (rx_watermark > IIC_RX_FIFO_DEPTH) rx_watermark = IIC_RX_FIFO_DEPTH; - xiic_setreg8(i2c, XIIC_RFD_REG_OFFSET, rx_watermark - 1); + xiic_setreg8(i2c, XIIC_RFD_REG_OFFSET, (u8)(rx_watermark - 1)); if (!(msg->flags & I2C_M_NOSTART)) /* write the address */ @@ -638,6 +646,7 @@ static void xiic_start_send(struct xiic_i2c *i2c) static void __xiic_start_xfer(struct xiic_i2c *i2c) { int fifo_space = xiic_tx_fifo_space(i2c); + dev_dbg(i2c->adap.dev.parent, "%s entry, msg: %p, fifos space: %d\n", __func__, i2c->tx_msg, fifo_space); @@ -739,7 +748,6 @@ static const struct i2c_adapter xiic_adapter = { .quirks = &xiic_quirks, }; - static int xiic_i2c_probe(struct platform_device *pdev) { struct xiic_i2c *i2c; @@ -899,6 +907,7 @@ static const struct dev_pm_ops xiic_dev_pm_ops = { SET_RUNTIME_PM_OPS(xiic_i2c_runtime_suspend, xiic_i2c_runtime_resume, NULL) }; + static struct platform_driver xiic_i2c_driver = { .probe = xiic_i2c_probe, .remove = xiic_i2c_remove, @@ -914,4 +923,3 @@ module_platform_driver(xiic_i2c_driver); MODULE_AUTHOR("info@mocean-labs.com"); MODULE_DESCRIPTION("Xilinx I2C bus driver"); MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:"DRIVER_NAME); |