Commit b484f3c3 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull i2c fixes from Wolfram Sang:
 "Some driver bugfixes and an old API removal now that all users are
  gone"

* 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
  i2c: tegra: Synchronize DMA before termination
  i2c: tegra: Better handle case where CPU0 is busy for a long time
  i2c: remove i2c_new_probed_device API
  i2c: altera: use proper variable to hold errno
  i2c: designware: platdrv: Remove DPM_FLAG_SMART_SUSPEND flag on BYT and CHT
parents fecca689 8814044f
Loading
Loading
Loading
Loading
+4 −5
Original line number Diff line number Diff line
@@ -384,7 +384,6 @@ static int altr_i2c_probe(struct platform_device *pdev)
	struct altr_i2c_dev *idev = NULL;
	struct resource *res;
	int irq, ret;
	u32 val;

	idev = devm_kzalloc(&pdev->dev, sizeof(*idev), GFP_KERNEL);
	if (!idev)
@@ -411,17 +410,17 @@ static int altr_i2c_probe(struct platform_device *pdev)
	init_completion(&idev->msg_complete);
	spin_lock_init(&idev->lock);

	val = device_property_read_u32(idev->dev, "fifo-size",
	ret = device_property_read_u32(idev->dev, "fifo-size",
				       &idev->fifo_size);
	if (val) {
	if (ret) {
		dev_err(&pdev->dev, "FIFO size set to default of %d\n",
			ALTR_I2C_DFLT_FIFO_SZ);
		idev->fifo_size = ALTR_I2C_DFLT_FIFO_SZ;
	}

	val = device_property_read_u32(idev->dev, "clock-frequency",
	ret = device_property_read_u32(idev->dev, "clock-frequency",
				       &idev->bus_clk_rate);
	if (val) {
	if (ret) {
		dev_err(&pdev->dev, "Default to 100kHz\n");
		idev->bus_clk_rate = I2C_MAX_STANDARD_MODE_FREQ;	/* default clock rate */
	}
+10 −4
Original line number Diff line number Diff line
@@ -354,10 +354,16 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
	adap->dev.of_node = pdev->dev.of_node;
	adap->nr = -1;

	if (dev->flags & ACCESS_NO_IRQ_SUSPEND) {
		dev_pm_set_driver_flags(&pdev->dev,
					DPM_FLAG_SMART_PREPARE |
					DPM_FLAG_LEAVE_SUSPENDED);
	} else {
		dev_pm_set_driver_flags(&pdev->dev,
					DPM_FLAG_SMART_PREPARE |
					DPM_FLAG_SMART_SUSPEND |
					DPM_FLAG_LEAVE_SUSPENDED);
	}

	/* The code below assumes runtime PM to be disabled. */
	WARN_ON(pm_runtime_enabled(&pdev->dev));
+24 −12
Original line number Diff line number Diff line
@@ -996,7 +996,7 @@ tegra_i2c_poll_completion_timeout(struct tegra_i2c_dev *i2c_dev,
	do {
		u32 status = i2c_readl(i2c_dev, I2C_INT_STATUS);

		if (status) {
		if (status)
			tegra_i2c_isr(i2c_dev->irq, i2c_dev);

		if (completion_done(complete)) {
@@ -1004,7 +1004,6 @@ tegra_i2c_poll_completion_timeout(struct tegra_i2c_dev *i2c_dev,

			return msecs_to_jiffies(delta) ?: 1;
		}
		}

		ktime = ktime_get();

@@ -1030,14 +1029,18 @@ tegra_i2c_wait_completion_timeout(struct tegra_i2c_dev *i2c_dev,
		disable_irq(i2c_dev->irq);

		/*
		 * There is a chance that completion may happen after IRQ
		 * synchronization, which is done by disable_irq().
		 * Under some rare circumstances (like running KASAN +
		 * NFS root) CPU, which handles interrupt, may stuck in
		 * uninterruptible state for a significant time.  In this
		 * case we will get timeout if I2C transfer is running on
		 * a sibling CPU, despite of IRQ being raised.
		 *
		 * In order to handle this rare condition, the IRQ status
		 * needs to be checked after timeout.
		 */
		if (ret == 0 && completion_done(complete)) {
			dev_warn(i2c_dev->dev,
				 "completion done after timeout\n");
			ret = 1;
		}
		if (ret == 0)
			ret = tegra_i2c_poll_completion_timeout(i2c_dev,
								complete, 0);
	}

	return ret;
@@ -1216,6 +1219,15 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
		time_left = tegra_i2c_wait_completion_timeout(
				i2c_dev, &i2c_dev->dma_complete, xfer_time);

		/*
		 * Synchronize DMA first, since dmaengine_terminate_sync()
		 * performs synchronization after the transfer's termination
		 * and we want to get a completion if transfer succeeded.
		 */
		dmaengine_synchronize(i2c_dev->msg_read ?
				      i2c_dev->rx_dma_chan :
				      i2c_dev->tx_dma_chan);

		dmaengine_terminate_sync(i2c_dev->msg_read ?
					 i2c_dev->rx_dma_chan :
					 i2c_dev->tx_dma_chan);
+0 −13
Original line number Diff line number Diff line
@@ -2273,19 +2273,6 @@ i2c_new_scanned_device(struct i2c_adapter *adap,
}
EXPORT_SYMBOL_GPL(i2c_new_scanned_device);

struct i2c_client *
i2c_new_probed_device(struct i2c_adapter *adap,
		      struct i2c_board_info *info,
		      unsigned short const *addr_list,
		      int (*probe)(struct i2c_adapter *adap, unsigned short addr))
{
	struct i2c_client *client;

	client = i2c_new_scanned_device(adap, info, addr_list, probe);
	return IS_ERR(client) ? NULL : client;
}
EXPORT_SYMBOL_GPL(i2c_new_probed_device);

struct i2c_adapter *i2c_get_adapter(int nr)
{
	struct i2c_adapter *adapter;
+0 −6
Original line number Diff line number Diff line
@@ -461,12 +461,6 @@ i2c_new_scanned_device(struct i2c_adapter *adap,
		       unsigned short const *addr_list,
		       int (*probe)(struct i2c_adapter *adap, unsigned short addr));

struct i2c_client *
i2c_new_probed_device(struct i2c_adapter *adap,
		       struct i2c_board_info *info,
		       unsigned short const *addr_list,
		       int (*probe)(struct i2c_adapter *adap, unsigned short addr));

/* Common custom probe functions */
int i2c_probe_func_quick_read(struct i2c_adapter *adap, unsigned short addr);