diff options
Diffstat (limited to 'drivers/i2c')
| -rw-r--r-- | drivers/i2c/busses/i2c-brcmstb.c | 27 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-designware-core.h | 1 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-designware-platdrv.c | 28 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-exynos5.c | 3 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-meson.c | 2 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-mt65xx.c | 9 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-riic.c | 6 | ||||
| -rw-r--r-- | drivers/i2c/i2c-mux.c | 2 | ||||
| -rw-r--r-- | drivers/i2c/muxes/i2c-mux-pca954x.c | 34 | 
9 files changed, 62 insertions, 50 deletions
diff --git a/drivers/i2c/busses/i2c-brcmstb.c b/drivers/i2c/busses/i2c-brcmstb.c index 0652281662a8..78792b4d6437 100644 --- a/drivers/i2c/busses/i2c-brcmstb.c +++ b/drivers/i2c/busses/i2c-brcmstb.c @@ -465,6 +465,7 @@ static int brcmstb_i2c_xfer(struct i2c_adapter *adapter,  	u8 *tmp_buf;  	int len = 0;  	int xfersz = brcmstb_i2c_get_xfersz(dev); +	u32 cond, cond_per_msg;  	if (dev->is_suspended)  		return -EBUSY; @@ -481,10 +482,11 @@ static int brcmstb_i2c_xfer(struct i2c_adapter *adapter,  			pmsg->buf ? pmsg->buf[0] : '0', pmsg->len);  		if (i < (num - 1) && (msgs[i + 1].flags & I2C_M_NOSTART)) -			brcmstb_set_i2c_start_stop(dev, ~(COND_START_STOP)); +			cond = ~COND_START_STOP;  		else -			brcmstb_set_i2c_start_stop(dev, -						   COND_RESTART | COND_NOSTOP); +			cond = COND_RESTART | COND_NOSTOP; + +		brcmstb_set_i2c_start_stop(dev, cond);  		/* Send slave address */  		if (!(pmsg->flags & I2C_M_NOSTART)) { @@ -497,13 +499,24 @@ static int brcmstb_i2c_xfer(struct i2c_adapter *adapter,  			}  		} +		cond_per_msg = cond; +  		/* Perform data transfer */  		while (len) {  			bytes_to_xfer = min(len, xfersz); -			if (len <= xfersz && i == (num - 1)) -				brcmstb_set_i2c_start_stop(dev, -							   ~(COND_START_STOP)); +			if (len <= xfersz) { +				if (i == (num - 1)) +					cond_per_msg = cond_per_msg & +						~(COND_RESTART | COND_NOSTOP); +				else +					cond_per_msg = cond; +			} else { +				cond_per_msg = (cond_per_msg & ~COND_RESTART) | +					COND_NOSTOP; +			} + +			brcmstb_set_i2c_start_stop(dev, cond_per_msg);  			rc = brcmstb_i2c_xfer_bsc_data(dev, tmp_buf,  						       bytes_to_xfer, pmsg); @@ -512,6 +525,8 @@ static int brcmstb_i2c_xfer(struct i2c_adapter *adapter,  			len -=  bytes_to_xfer;  			tmp_buf += bytes_to_xfer; + +			cond_per_msg = COND_NOSTART | COND_NOSTOP;  		}  	} diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h index c1db3a5a340f..d9aaf1790e0e 100644 --- a/drivers/i2c/busses/i2c-designware-core.h +++ b/drivers/i2c/busses/i2c-designware-core.h @@ -88,6 +88,7 @@ struct dw_i2c_dev {  	void __iomem		*base;  	struct completion	cmd_complete;  	struct clk		*clk; +	struct reset_control	*rst;  	u32			(*get_clk_rate_khz) (struct dw_i2c_dev *dev);  	struct dw_pci_controller *controller;  	int			cmd_err; diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index 6ce431323125..79c4b4ea0539 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -38,6 +38,7 @@  #include <linux/pm_runtime.h>  #include <linux/property.h>  #include <linux/io.h> +#include <linux/reset.h>  #include <linux/slab.h>  #include <linux/acpi.h>  #include <linux/platform_data/i2c-designware.h> @@ -199,6 +200,14 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)  	dev->irq = irq;  	platform_set_drvdata(pdev, dev); +	dev->rst = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL); +	if (IS_ERR(dev->rst)) { +		if (PTR_ERR(dev->rst) == -EPROBE_DEFER) +			return -EPROBE_DEFER; +	} else { +		reset_control_deassert(dev->rst); +	} +  	if (pdata) {  		dev->clk_freq = pdata->i2c_scl_freq;  	} else { @@ -235,12 +244,13 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)  	    && dev->clk_freq != 1000000 && dev->clk_freq != 3400000) {  		dev_err(&pdev->dev,  			"Only 100kHz, 400kHz, 1MHz and 3.4MHz supported"); -		return -EINVAL; +		r = -EINVAL; +		goto exit_reset;  	}  	r = i2c_dw_eval_lock_support(dev);  	if (r) -		return r; +		goto exit_reset;  	dev->functionality = I2C_FUNC_10BIT_ADDR | DW_IC_DEFAULT_FUNCTIONALITY; @@ -286,10 +296,18 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)  	}  	r = i2c_dw_probe(dev); -	if (r && !dev->pm_runtime_disabled) -		pm_runtime_disable(&pdev->dev); +	if (r) +		goto exit_probe;  	return r; + +exit_probe: +	if (!dev->pm_runtime_disabled) +		pm_runtime_disable(&pdev->dev); +exit_reset: +	if (!IS_ERR_OR_NULL(dev->rst)) +		reset_control_assert(dev->rst); +	return r;  }  static int dw_i2c_plat_remove(struct platform_device *pdev) @@ -306,6 +324,8 @@ static int dw_i2c_plat_remove(struct platform_device *pdev)  	pm_runtime_put_sync(&pdev->dev);  	if (!dev->pm_runtime_disabled)  		pm_runtime_disable(&pdev->dev); +	if (!IS_ERR_OR_NULL(dev->rst)) +		reset_control_assert(dev->rst);  	return 0;  } diff --git a/drivers/i2c/busses/i2c-exynos5.c b/drivers/i2c/busses/i2c-exynos5.c index cbd93ce0661f..736a82472101 100644 --- a/drivers/i2c/busses/i2c-exynos5.c +++ b/drivers/i2c/busses/i2c-exynos5.c @@ -457,7 +457,6 @@ static irqreturn_t exynos5_i2c_irq(int irqno, void *dev_id)  	int_status = readl(i2c->regs + HSI2C_INT_STATUS);  	writel(int_status, i2c->regs + HSI2C_INT_STATUS); -	trans_status = readl(i2c->regs + HSI2C_TRANS_STATUS);  	/* handle interrupt related to the transfer status */  	if (i2c->variant->hw == HSI2C_EXYNOS7) { @@ -482,11 +481,13 @@ static irqreturn_t exynos5_i2c_irq(int irqno, void *dev_id)  			goto stop;  		} +		trans_status = readl(i2c->regs + HSI2C_TRANS_STATUS);  		if ((trans_status & HSI2C_MASTER_ST_MASK) == HSI2C_MASTER_ST_LOSE) {  			i2c->state = -EAGAIN;  			goto stop;  		}  	} else if (int_status & HSI2C_INT_I2C) { +		trans_status = readl(i2c->regs + HSI2C_TRANS_STATUS);  		if (trans_status & HSI2C_NO_DEV_ACK) {  			dev_dbg(i2c->dev, "No ACK from device\n");  			i2c->state = -ENXIO; diff --git a/drivers/i2c/busses/i2c-meson.c b/drivers/i2c/busses/i2c-meson.c index 2aa61bbbd307..73b97c71a484 100644 --- a/drivers/i2c/busses/i2c-meson.c +++ b/drivers/i2c/busses/i2c-meson.c @@ -175,7 +175,7 @@ static void meson_i2c_put_data(struct meson_i2c *i2c, char *buf, int len)  		wdata1 |= *buf++ << ((i - 4) * 8);  	writel(wdata0, i2c->regs + REG_TOK_WDATA0); -	writel(wdata0, i2c->regs + REG_TOK_WDATA1); +	writel(wdata1, i2c->regs + REG_TOK_WDATA1);  	dev_dbg(i2c->dev, "%s: data %08x %08x len %d\n", __func__,  		wdata0, wdata1, len); diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index 4a7d9bc2142b..45d61714c81b 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -172,14 +172,6 @@ static const struct i2c_adapter_quirks mt6577_i2c_quirks = {  	.max_comb_2nd_msg_len = 31,  }; -static const struct i2c_adapter_quirks mt8173_i2c_quirks = { -	.max_num_msgs = 65535, -	.max_write_len = 65535, -	.max_read_len = 65535, -	.max_comb_1st_msg_len = 65535, -	.max_comb_2nd_msg_len = 65535, -}; -  static const struct mtk_i2c_compatible mt6577_compat = {  	.quirks = &mt6577_i2c_quirks,  	.pmic_i2c = 0, @@ -199,7 +191,6 @@ static const struct mtk_i2c_compatible mt6589_compat = {  };  static const struct mtk_i2c_compatible mt8173_compat = { -	.quirks = &mt8173_i2c_quirks,  	.pmic_i2c = 0,  	.dcm = 1,  	.auto_restart = 1, diff --git a/drivers/i2c/busses/i2c-riic.c b/drivers/i2c/busses/i2c-riic.c index 8f11d347b3ec..c811af4c8d81 100644 --- a/drivers/i2c/busses/i2c-riic.c +++ b/drivers/i2c/busses/i2c-riic.c @@ -218,8 +218,12 @@ static irqreturn_t riic_tend_isr(int irq, void *data)  	}  	if (riic->is_last || riic->err) { -		riic_clear_set_bit(riic, 0, ICIER_SPIE, RIIC_ICIER); +		riic_clear_set_bit(riic, ICIER_TEIE, ICIER_SPIE, RIIC_ICIER);  		writeb(ICCR2_SP, riic->base + RIIC_ICCR2); +	} else { +		/* Transfer is complete, but do not send STOP */ +		riic_clear_set_bit(riic, ICIER_TEIE, 0, RIIC_ICIER); +		complete(&riic->msg_done);  	}  	return IRQ_HANDLED; diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c index 83768e85a919..2178266bca79 100644 --- a/drivers/i2c/i2c-mux.c +++ b/drivers/i2c/i2c-mux.c @@ -429,6 +429,7 @@ void i2c_mux_del_adapters(struct i2c_mux_core *muxc)  	while (muxc->num_adapters) {  		struct i2c_adapter *adap = muxc->adapter[--muxc->num_adapters];  		struct i2c_mux_priv *priv = adap->algo_data; +		struct device_node *np = adap->dev.of_node;  		muxc->adapter[muxc->num_adapters] = NULL; @@ -438,6 +439,7 @@ void i2c_mux_del_adapters(struct i2c_mux_core *muxc)  		sysfs_remove_link(&priv->adap.dev.kobj, "mux_device");  		i2c_del_adapter(adap); +		of_node_put(np);  		kfree(priv);  	}  } diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c index dfc1c0e37c40..ad31d21da316 100644 --- a/drivers/i2c/muxes/i2c-mux-pca954x.c +++ b/drivers/i2c/muxes/i2c-mux-pca954x.c @@ -35,7 +35,6 @@   * warranty of any kind, whether express or implied.   */ -#include <linux/acpi.h>  #include <linux/device.h>  #include <linux/gpio/consumer.h>  #include <linux/i2c.h> @@ -117,6 +116,10 @@ static const struct chip_desc chips[] = {  		.has_irq = 1,  		.muxtype = pca954x_isswi,  	}, +	[pca_9546] = { +		.nchans = 4, +		.muxtype = pca954x_isswi, +	},  	[pca_9547] = {  		.nchans = 8,  		.enable = 0x8, @@ -134,28 +137,13 @@ static const struct i2c_device_id pca954x_id[] = {  	{ "pca9543", pca_9543 },  	{ "pca9544", pca_9544 },  	{ "pca9545", pca_9545 }, -	{ "pca9546", pca_9545 }, +	{ "pca9546", pca_9546 },  	{ "pca9547", pca_9547 },  	{ "pca9548", pca_9548 },  	{ }  };  MODULE_DEVICE_TABLE(i2c, pca954x_id); -#ifdef CONFIG_ACPI -static const struct acpi_device_id pca954x_acpi_ids[] = { -	{ .id = "PCA9540", .driver_data = pca_9540 }, -	{ .id = "PCA9542", .driver_data = pca_9542 }, -	{ .id = "PCA9543", .driver_data = pca_9543 }, -	{ .id = "PCA9544", .driver_data = pca_9544 }, -	{ .id = "PCA9545", .driver_data = pca_9545 }, -	{ .id = "PCA9546", .driver_data = pca_9545 }, -	{ .id = "PCA9547", .driver_data = pca_9547 }, -	{ .id = "PCA9548", .driver_data = pca_9548 }, -	{ } -}; -MODULE_DEVICE_TABLE(acpi, pca954x_acpi_ids); -#endif -  #ifdef CONFIG_OF  static const struct of_device_id pca954x_of_match[] = {  	{ .compatible = "nxp,pca9540", .data = &chips[pca_9540] }, @@ -393,17 +381,8 @@ static int pca954x_probe(struct i2c_client *client,  	match = of_match_device(of_match_ptr(pca954x_of_match), &client->dev);  	if (match)  		data->chip = of_device_get_match_data(&client->dev); -	else if (id) +	else  		data->chip = &chips[id->driver_data]; -	else { -		const struct acpi_device_id *acpi_id; - -		acpi_id = acpi_match_device(ACPI_PTR(pca954x_acpi_ids), -						&client->dev); -		if (!acpi_id) -			return -ENODEV; -		data->chip = &chips[acpi_id->driver_data]; -	}  	data->last_chan = 0;		   /* force the first selection */ @@ -492,7 +471,6 @@ static struct i2c_driver pca954x_driver = {  		.name	= "pca954x",  		.pm	= &pca954x_pm,  		.of_match_table = of_match_ptr(pca954x_of_match), -		.acpi_match_table = ACPI_PTR(pca954x_acpi_ids),  	},  	.probe		= pca954x_probe,  	.remove		= pca954x_remove,  | 
