Commit a8780906 authored by Wolfram Sang's avatar Wolfram Sang
Browse files

Merge tag 'i2c-host-fixes-6.16-rc6' of...

Merge tag 'i2c-host-fixes-6.16-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/andi.shyti/linux into i2c/for-current

i2c-host-fixes for v6.16-rc6

omap: add missing error check and fix PM disable in probe error
path.

stm32: unmap DMA buffer on transfer failure and use correct
device when mapping and unmapping during transfers.
parents d7b8f8e2 6aae87fe
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -1472,7 +1472,9 @@ omap_i2c_probe(struct platform_device *pdev)
	}

	/* reset ASAP, clearing any IRQs */
	omap_i2c_init(omap);
	r = omap_i2c_init(omap);
	if (r)
		goto err_mux_state_deselect;

	if (omap->rev < OMAP_I2C_OMAP1_REV_2)
		r = devm_request_irq(&pdev->dev, omap->irq, omap_i2c_omap1_isr,
@@ -1515,12 +1517,13 @@ omap_i2c_probe(struct platform_device *pdev)

err_unuse_clocks:
	omap_i2c_write_reg(omap, OMAP_I2C_CON_REG, 0);
err_mux_state_deselect:
	if (omap->mux_state)
		mux_state_deselect(omap->mux_state);
err_put_pm:
	pm_runtime_dont_use_autosuspend(omap->dev);
	pm_runtime_put_sync(omap->dev);
err_disable_pm:
	pm_runtime_dont_use_autosuspend(omap->dev);
	pm_runtime_disable(&pdev->dev);

	return r;
+3 −5
Original line number Diff line number Diff line
@@ -102,7 +102,6 @@ int stm32_i2c_prep_dma_xfer(struct device *dev, struct stm32_i2c_dma *dma,
			    void *dma_async_param)
{
	struct dma_async_tx_descriptor *txdesc;
	struct device *chan_dev;
	int ret;

	if (rd_wr) {
@@ -116,11 +115,10 @@ int stm32_i2c_prep_dma_xfer(struct device *dev, struct stm32_i2c_dma *dma,
	}

	dma->dma_len = len;
	chan_dev = dma->chan_using->device->dev;

	dma->dma_buf = dma_map_single(chan_dev, buf, dma->dma_len,
	dma->dma_buf = dma_map_single(dev, buf, dma->dma_len,
				      dma->dma_data_dir);
	if (dma_mapping_error(chan_dev, dma->dma_buf)) {
	if (dma_mapping_error(dev, dma->dma_buf)) {
		dev_err(dev, "DMA mapping failed\n");
		return -EINVAL;
	}
@@ -150,7 +148,7 @@ int stm32_i2c_prep_dma_xfer(struct device *dev, struct stm32_i2c_dma *dma,
	return 0;

err:
	dma_unmap_single(chan_dev, dma->dma_buf, dma->dma_len,
	dma_unmap_single(dev, dma->dma_buf, dma->dma_len,
			 dma->dma_data_dir);
	return ret;
}
+9 −15
Original line number Diff line number Diff line
@@ -739,12 +739,13 @@ static void stm32f7_i2c_disable_dma_req(struct stm32f7_i2c_dev *i2c_dev)

static void stm32f7_i2c_dma_callback(void *arg)
{
	struct stm32f7_i2c_dev *i2c_dev = (struct stm32f7_i2c_dev *)arg;
	struct stm32f7_i2c_dev *i2c_dev = arg;
	struct stm32_i2c_dma *dma = i2c_dev->dma;
	struct device *dev = dma->chan_using->device->dev;

	stm32f7_i2c_disable_dma_req(i2c_dev);
	dma_unmap_single(dev, dma->dma_buf, dma->dma_len, dma->dma_data_dir);
	dmaengine_terminate_async(dma->chan_using);
	dma_unmap_single(i2c_dev->dev, dma->dma_buf, dma->dma_len,
			 dma->dma_data_dir);
	complete(&dma->dma_complete);
}

@@ -1510,7 +1511,6 @@ static irqreturn_t stm32f7_i2c_handle_isr_errs(struct stm32f7_i2c_dev *i2c_dev,
	u16 addr = f7_msg->addr;
	void __iomem *base = i2c_dev->base;
	struct device *dev = i2c_dev->dev;
	struct stm32_i2c_dma *dma = i2c_dev->dma;

	/* Bus error */
	if (status & STM32F7_I2C_ISR_BERR) {
@@ -1551,10 +1551,8 @@ static irqreturn_t stm32f7_i2c_handle_isr_errs(struct stm32f7_i2c_dev *i2c_dev,
	}

	/* Disable dma */
	if (i2c_dev->use_dma) {
		stm32f7_i2c_disable_dma_req(i2c_dev);
		dmaengine_terminate_async(dma->chan_using);
	}
	if (i2c_dev->use_dma)
		stm32f7_i2c_dma_callback(i2c_dev);

	i2c_dev->master_mode = false;
	complete(&i2c_dev->complete);
@@ -1600,7 +1598,6 @@ static irqreturn_t stm32f7_i2c_isr_event_thread(int irq, void *data)
{
	struct stm32f7_i2c_dev *i2c_dev = data;
	struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
	struct stm32_i2c_dma *dma = i2c_dev->dma;
	void __iomem *base = i2c_dev->base;
	u32 status, mask;
	int ret;
@@ -1619,10 +1616,8 @@ static irqreturn_t stm32f7_i2c_isr_event_thread(int irq, void *data)
		dev_dbg(i2c_dev->dev, "<%s>: Receive NACK (addr %x)\n",
			__func__, f7_msg->addr);
		writel_relaxed(STM32F7_I2C_ICR_NACKCF, base + STM32F7_I2C_ICR);
		if (i2c_dev->use_dma) {
			stm32f7_i2c_disable_dma_req(i2c_dev);
			dmaengine_terminate_async(dma->chan_using);
		}
		if (i2c_dev->use_dma)
			stm32f7_i2c_dma_callback(i2c_dev);
		f7_msg->result = -ENXIO;
	}

@@ -1640,8 +1635,7 @@ static irqreturn_t stm32f7_i2c_isr_event_thread(int irq, void *data)
			ret = wait_for_completion_timeout(&i2c_dev->dma->dma_complete, HZ);
			if (!ret) {
				dev_dbg(i2c_dev->dev, "<%s>: Timed out\n", __func__);
				stm32f7_i2c_disable_dma_req(i2c_dev);
				dmaengine_terminate_async(dma->chan_using);
				stm32f7_i2c_dma_callback(i2c_dev);
				f7_msg->result = -ETIMEDOUT;
			}
		}