diff options
Diffstat (limited to 'drivers/i2c')
28 files changed, 824 insertions, 389 deletions
diff --git a/drivers/i2c/busses/i2c-amd756-s4882.c b/drivers/i2c/busses/i2c-amd756-s4882.c index 378fcb5d578..07f01ac853f 100644 --- a/drivers/i2c/busses/i2c-amd756-s4882.c +++ b/drivers/i2c/busses/i2c-amd756-s4882.c @@ -169,11 +169,7 @@ static int __init amd756_s4882_init(void)  	}  	/* Unregister physical bus */ -	error = i2c_del_adapter(&amd756_smbus); -	if (error) { -		dev_err(&amd756_smbus.dev, "Physical bus removal failed\n"); -		goto ERROR0; -	} +	i2c_del_adapter(&amd756_smbus);  	printk(KERN_INFO "Enabling SMBus multiplexing for Tyan S4882\n");  	/* Define the 5 virtual adapters and algorithms structures */ diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c index 75195e3f5dd..6bb839b688b 100644 --- a/drivers/i2c/busses/i2c-at91.c +++ b/drivers/i2c/busses/i2c-at91.c @@ -603,15 +603,18 @@ static const struct of_device_id atmel_twi_dt_ids[] = {  	}  };  MODULE_DEVICE_TABLE(of, atmel_twi_dt_ids); -#else -#define atmel_twi_dt_ids NULL  #endif -static bool filter(struct dma_chan *chan, void *slave) +static bool filter(struct dma_chan *chan, void *pdata)  { -	struct at_dma_slave *sl = slave; +	struct at91_twi_pdata *sl_pdata = pdata; +	struct at_dma_slave *sl; + +	if (!sl_pdata) +		return false; -	if (sl->dma_dev == chan->device->dev) { +	sl = &sl_pdata->dma_slave; +	if (sl && (sl->dma_dev == chan->device->dev)) {  		chan->private = sl;  		return true;  	} else { @@ -622,11 +625,10 @@ static bool filter(struct dma_chan *chan, void *slave)  static int at91_twi_configure_dma(struct at91_twi_dev *dev, u32 phy_addr)  {  	int ret = 0; -	struct at_dma_slave *sdata; +	struct at91_twi_pdata *pdata = dev->pdata;  	struct dma_slave_config slave_config;  	struct at91_twi_dma *dma = &dev->dma; - -	sdata = &dev->pdata->dma_slave; +	dma_cap_mask_t mask;  	memset(&slave_config, 0, sizeof(slave_config));  	slave_config.src_addr = (dma_addr_t)phy_addr + AT91_TWI_RHR; @@ -637,25 +639,22 @@ static int at91_twi_configure_dma(struct at91_twi_dev *dev, u32 phy_addr)  	slave_config.dst_maxburst = 1;  	slave_config.device_fc = false; -	if (sdata && sdata->dma_dev) { -		dma_cap_mask_t mask; +	dma_cap_zero(mask); +	dma_cap_set(DMA_SLAVE, mask); -		dma_cap_zero(mask); -		dma_cap_set(DMA_SLAVE, mask); -		dma->chan_tx = dma_request_channel(mask, filter, sdata); -		if (!dma->chan_tx) { -			dev_err(dev->dev, "no DMA channel available for tx\n"); -			ret = -EBUSY; -			goto error; -		} -		dma->chan_rx = dma_request_channel(mask, filter, sdata); -		if (!dma->chan_rx) { -			dev_err(dev->dev, "no DMA channel available for rx\n"); -			ret = -EBUSY; -			goto error; -		} -	} else { -		ret = -EINVAL; +	dma->chan_tx = dma_request_slave_channel_compat(mask, filter, pdata, +							dev->dev, "tx"); +	if (!dma->chan_tx) { +		dev_err(dev->dev, "can't get a DMA channel for tx\n"); +		ret = -EBUSY; +		goto error; +	} + +	dma->chan_rx = dma_request_slave_channel_compat(mask, filter, pdata, +							dev->dev, "rx"); +	if (!dma->chan_rx) { +		dev_err(dev->dev, "can't get a DMA channel for rx\n"); +		ret = -EBUSY;  		goto error;  	} @@ -785,12 +784,11 @@ static int at91_twi_probe(struct platform_device *pdev)  static int at91_twi_remove(struct platform_device *pdev)  {  	struct at91_twi_dev *dev = platform_get_drvdata(pdev); -	int rc; -	rc = i2c_del_adapter(&dev->adapter); +	i2c_del_adapter(&dev->adapter);  	clk_disable_unprepare(dev->clk); -	return rc; +	return 0;  }  #ifdef CONFIG_PM @@ -828,7 +826,7 @@ static struct platform_driver at91_twi_driver = {  	.driver		= {  		.name	= "at91_i2c",  		.owner	= THIS_MODULE, -		.of_match_table = atmel_twi_dt_ids, +		.of_match_table = of_match_ptr(atmel_twi_dt_ids),  		.pm	= at91_twi_pm_ops,  	},  }; diff --git a/drivers/i2c/busses/i2c-cbus-gpio.c b/drivers/i2c/busses/i2c-cbus-gpio.c index 98386d65931..1be13ac11dc 100644 --- a/drivers/i2c/busses/i2c-cbus-gpio.c +++ b/drivers/i2c/busses/i2c-cbus-gpio.c @@ -206,7 +206,9 @@ static int cbus_i2c_remove(struct platform_device *pdev)  {  	struct i2c_adapter *adapter = platform_get_drvdata(pdev); -	return i2c_del_adapter(adapter); +	i2c_del_adapter(adapter); + +	return 0;  }  static int cbus_i2c_probe(struct platform_device *pdev) diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 7d1e590a7bb..cf20e06a88e 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -137,7 +137,7 @@ static inline u16 davinci_i2c_read_reg(struct davinci_i2c_dev *i2c_dev, int reg)  }  /* Generate a pulse on the i2c clock pin. */ -static void generic_i2c_clock_pulse(unsigned int scl_pin) +static void davinci_i2c_clock_pulse(unsigned int scl_pin)  {  	u16 i; @@ -155,7 +155,7 @@ static void generic_i2c_clock_pulse(unsigned int scl_pin)  /* This routine does i2c bus recovery as specified in the   * i2c protocol Rev. 03 section 3.16 titled "Bus clear"   */ -static void i2c_recover_bus(struct davinci_i2c_dev *dev) +static void davinci_i2c_recover_bus(struct davinci_i2c_dev *dev)  {  	u32 flag = 0;  	struct davinci_i2c_platform_data *pdata = dev->pdata; @@ -166,7 +166,7 @@ static void i2c_recover_bus(struct davinci_i2c_dev *dev)  	flag |=  DAVINCI_I2C_MDR_NACK;  	/* write the data into mode register */  	davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); -	generic_i2c_clock_pulse(pdata->scl_pin); +	davinci_i2c_clock_pulse(pdata->scl_pin);  	/* Send STOP */  	flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);  	flag |= DAVINCI_I2C_MDR_STP; @@ -289,7 +289,7 @@ static int i2c_davinci_wait_bus_not_busy(struct davinci_i2c_dev *dev,  				return -ETIMEDOUT;  			} else {  				to_cnt = 0; -				i2c_recover_bus(dev); +				davinci_i2c_recover_bus(dev);  				i2c_davinci_init(dev);  			}  		} @@ -379,7 +379,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)  						      dev->adapter.timeout);  	if (r == 0) {  		dev_err(dev->dev, "controller timed out\n"); -		i2c_recover_bus(dev); +		davinci_i2c_recover_bus(dev);  		i2c_davinci_init(dev);  		dev->buf_len = 0;  		return -ETIMEDOUT; @@ -643,7 +643,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)  {  	struct davinci_i2c_dev *dev;  	struct i2c_adapter *adap; -	struct resource *mem, *irq, *ioarea; +	struct resource *mem, *irq;  	int r;  	/* NOTE: driver uses the static register mapping */ @@ -659,24 +659,18 @@ static int davinci_i2c_probe(struct platform_device *pdev)  		return -ENODEV;  	} -	ioarea = request_mem_region(mem->start, resource_size(mem), -				    pdev->name); -	if (!ioarea) { -		dev_err(&pdev->dev, "I2C region already claimed\n"); -		return -EBUSY; -	} - -	dev = kzalloc(sizeof(struct davinci_i2c_dev), GFP_KERNEL); +	dev = devm_kzalloc(&pdev->dev, sizeof(struct davinci_i2c_dev), +			GFP_KERNEL);  	if (!dev) { -		r = -ENOMEM; -		goto err_release_region; +		dev_err(&pdev->dev, "Memory allocation failed\n"); +		return -ENOMEM;  	}  	init_completion(&dev->cmd_complete);  #ifdef CONFIG_CPU_FREQ  	init_completion(&dev->xfr_complete);  #endif -	dev->dev = get_device(&pdev->dev); +	dev->dev = &pdev->dev;  	dev->irq = irq->start;  	dev->pdata = dev->dev->platform_data;  	platform_set_drvdata(pdev, dev); @@ -686,10 +680,9 @@ static int davinci_i2c_probe(struct platform_device *pdev)  		dev->pdata = devm_kzalloc(&pdev->dev,  			sizeof(struct davinci_i2c_platform_data), GFP_KERNEL); -		if (!dev->pdata) { -			r = -ENOMEM; -			goto err_free_mem; -		} +		if (!dev->pdata) +			return -ENOMEM; +  		memcpy(dev->pdata, &davinci_i2c_platform_data_default,  			sizeof(struct davinci_i2c_platform_data));  		if (!of_property_read_u32(pdev->dev.of_node, "clock-frequency", @@ -699,22 +692,21 @@ static int davinci_i2c_probe(struct platform_device *pdev)  		dev->pdata = &davinci_i2c_platform_data_default;  	} -	dev->clk = clk_get(&pdev->dev, NULL); -	if (IS_ERR(dev->clk)) { -		r = -ENODEV; -		goto err_free_mem; -	} +	dev->clk = devm_clk_get(&pdev->dev, NULL); +	if (IS_ERR(dev->clk)) +		return -ENODEV;  	clk_prepare_enable(dev->clk); -	dev->base = ioremap(mem->start, resource_size(mem)); -	if (!dev->base) { -		r = -EBUSY; -		goto err_mem_ioremap; +	dev->base = devm_ioremap_resource(&pdev->dev, mem); +	if (IS_ERR(dev->base)) { +		r = PTR_ERR(dev->base); +		goto err_unuse_clocks;  	}  	i2c_davinci_init(dev); -	r = request_irq(dev->irq, i2c_davinci_isr, 0, pdev->name, dev); +	r = devm_request_irq(&pdev->dev, dev->irq, i2c_davinci_isr, 0, +			pdev->name, dev);  	if (r) {  		dev_err(&pdev->dev, "failure requesting irq %i\n", dev->irq);  		goto err_unuse_clocks; @@ -723,7 +715,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)  	r = i2c_davinci_cpufreq_register(dev);  	if (r) {  		dev_err(&pdev->dev, "failed to register cpufreq\n"); -		goto err_free_irq; +		goto err_unuse_clocks;  	}  	adap = &dev->adapter; @@ -740,50 +732,31 @@ static int davinci_i2c_probe(struct platform_device *pdev)  	r = i2c_add_numbered_adapter(adap);  	if (r) {  		dev_err(&pdev->dev, "failure adding adapter\n"); -		goto err_free_irq; +		goto err_unuse_clocks;  	}  	of_i2c_register_devices(adap);  	return 0; -err_free_irq: -	free_irq(dev->irq, dev);  err_unuse_clocks: -	iounmap(dev->base); -err_mem_ioremap:  	clk_disable_unprepare(dev->clk); -	clk_put(dev->clk);  	dev->clk = NULL; -err_free_mem: -	put_device(&pdev->dev); -	kfree(dev); -err_release_region: -	release_mem_region(mem->start, resource_size(mem)); -  	return r;  }  static int davinci_i2c_remove(struct platform_device *pdev)  {  	struct davinci_i2c_dev *dev = platform_get_drvdata(pdev); -	struct resource *mem;  	i2c_davinci_cpufreq_deregister(dev);  	i2c_del_adapter(&dev->adapter); -	put_device(&pdev->dev);  	clk_disable_unprepare(dev->clk); -	clk_put(dev->clk);  	dev->clk = NULL;  	davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, 0); -	free_irq(dev->irq, dev); -	iounmap(dev->base); -	kfree(dev); -	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	release_mem_region(mem->start, resource_size(mem));  	return 0;  } diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c index 94fd8187540..21fbb340ad6 100644 --- a/drivers/i2c/busses/i2c-designware-core.c +++ b/drivers/i2c/busses/i2c-designware-core.c @@ -68,6 +68,7 @@  #define DW_IC_TXFLR		0x74  #define DW_IC_RXFLR		0x78  #define DW_IC_TX_ABRT_SOURCE	0x80 +#define DW_IC_ENABLE_STATUS	0x9c  #define DW_IC_COMP_PARAM_1	0xf4  #define DW_IC_COMP_TYPE		0xfc  #define DW_IC_COMP_TYPE_VALUE	0x44570140 @@ -248,6 +249,27 @@ static u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset)  	return ((ic_clk * (tLOW + tf) + 5000) / 10000) - 1 + offset;  } +static void __i2c_dw_enable(struct dw_i2c_dev *dev, bool enable) +{ +	int timeout = 100; + +	do { +		dw_writel(dev, enable, DW_IC_ENABLE); +		if ((dw_readl(dev, DW_IC_ENABLE_STATUS) & 1) == enable) +			return; + +		/* +		 * Wait 10 times the signaling period of the highest I2C +		 * transfer supported by the driver (for 400KHz this is +		 * 25us) as described in the DesignWare I2C databook. +		 */ +		usleep_range(25, 250); +	} while (timeout--); + +	dev_warn(dev->dev, "timeout in %sabling adapter\n", +		 enable ? "en" : "dis"); +} +  /**   * i2c_dw_init() - initialize the designware i2c master hardware   * @dev: device private data @@ -278,7 +300,7 @@ int i2c_dw_init(struct dw_i2c_dev *dev)  	}  	/* Disable the adapter */ -	dw_writel(dev, 0, DW_IC_ENABLE); +	__i2c_dw_enable(dev, false);  	/* set standard and fast speed deviders for high/low periods */ @@ -333,7 +355,7 @@ static int i2c_dw_wait_bus_not_busy(struct dw_i2c_dev *dev)  			return -ETIMEDOUT;  		}  		timeout--; -		mdelay(1); +		usleep_range(1000, 1100);  	}  	return 0; @@ -345,7 +367,7 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)  	u32 ic_con;  	/* Disable the adapter */ -	dw_writel(dev, 0, DW_IC_ENABLE); +	__i2c_dw_enable(dev, false);  	/* set the slave (target) address */  	dw_writel(dev, msgs[dev->msg_write_idx].addr, DW_IC_TAR); @@ -359,7 +381,7 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)  	dw_writel(dev, ic_con, DW_IC_CON);  	/* Enable the adapter */ -	dw_writel(dev, 1, DW_IC_ENABLE); +	__i2c_dw_enable(dev, true);  	/* Enable interrupts */  	dw_writel(dev, DW_IC_INTR_DEFAULT_MASK, DW_IC_INTR_MASK); @@ -565,7 +587,7 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)  	/* no error */  	if (likely(!dev->cmd_err)) {  		/* Disable the adapter */ -		dw_writel(dev, 0, DW_IC_ENABLE); +		__i2c_dw_enable(dev, false);  		ret = num;  		goto done;  	} @@ -578,7 +600,8 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)  	ret = -EIO;  done: -	pm_runtime_put(dev->dev); +	pm_runtime_mark_last_busy(dev->dev); +	pm_runtime_put_autosuspend(dev->dev);  	mutex_unlock(&dev->lock);  	return ret; @@ -700,7 +723,7 @@ EXPORT_SYMBOL_GPL(i2c_dw_isr);  void i2c_dw_enable(struct dw_i2c_dev *dev)  {         /* Enable the adapter */ -	dw_writel(dev, 1, DW_IC_ENABLE); +	__i2c_dw_enable(dev, true);  }  EXPORT_SYMBOL_GPL(i2c_dw_enable); @@ -713,7 +736,7 @@ EXPORT_SYMBOL_GPL(i2c_dw_is_enabled);  void i2c_dw_disable(struct dw_i2c_dev *dev)  {  	/* Disable controller */ -	dw_writel(dev, 0, DW_IC_ENABLE); +	__i2c_dw_enable(dev, false);  	/* Disable all interupts */  	dw_writel(dev, 0, DW_IC_INTR_MASK); diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c index 7c5e383c350..f6ed06c966e 100644 --- a/drivers/i2c/busses/i2c-designware-pcidrv.c +++ b/drivers/i2c/busses/i2c-designware-pcidrv.c @@ -208,68 +208,45 @@ static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev)  }  static int i2c_dw_pci_probe(struct pci_dev *pdev, -const struct pci_device_id *id) +			    const struct pci_device_id *id)  {  	struct dw_i2c_dev *dev;  	struct i2c_adapter *adap; -	unsigned long start, len; -	void __iomem *base;  	int r;  	struct  dw_pci_controller *controller;  	if (id->driver_data >= ARRAY_SIZE(dw_pci_controllers)) { -		printk(KERN_ERR "dw_i2c_pci_probe: invalid driver data %ld\n", +		dev_err(&pdev->dev, "%s: invalid driver data %ld\n", __func__,  			id->driver_data);  		return -EINVAL;  	}  	controller = &dw_pci_controllers[id->driver_data]; -	r = pci_enable_device(pdev); +	r = pcim_enable_device(pdev);  	if (r) {  		dev_err(&pdev->dev, "Failed to enable I2C PCI device (%d)\n",  			r); -		goto exit; +		return r;  	} -	/* Determine the address of the I2C area */ -	start = pci_resource_start(pdev, 0); -	len = pci_resource_len(pdev, 0); -	if (!start || len == 0) { -		dev_err(&pdev->dev, "base address not set\n"); -		r = -ENODEV; -		goto exit; -	} - -	r = pci_request_region(pdev, 0, DRIVER_NAME); +	r = pcim_iomap_regions(pdev, 1 << 0, pci_name(pdev));  	if (r) { -		dev_err(&pdev->dev, "failed to request I2C region " -			"0x%lx-0x%lx\n", start, -			(unsigned long)pci_resource_end(pdev, 0)); -		goto exit; -	} - -	base = ioremap_nocache(start, len); -	if (!base) {  		dev_err(&pdev->dev, "I/O memory remapping failed\n"); -		r = -ENOMEM; -		goto err_release_region; +		return r;  	} - -	dev = kzalloc(sizeof(struct dw_i2c_dev), GFP_KERNEL); -	if (!dev) { -		r = -ENOMEM; -		goto err_release_region; -	} +	dev = devm_kzalloc(&pdev->dev, sizeof(struct dw_i2c_dev), GFP_KERNEL); +	if (!dev) +		return -ENOMEM;  	init_completion(&dev->cmd_complete);  	mutex_init(&dev->lock);  	dev->clk = NULL;  	dev->controller = controller;  	dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz; -	dev->base = base; -	dev->dev = get_device(&pdev->dev); +	dev->base = pcim_iomap_table(pdev)[0]; +	dev->dev = &pdev->dev;  	dev->functionality =  		I2C_FUNC_I2C |  		I2C_FUNC_SMBUS_BYTE | @@ -284,7 +261,7 @@ const struct pci_device_id *id)  	dev->rx_fifo_depth = controller->rx_fifo_depth;  	r = i2c_dw_init(dev);  	if (r) -		goto err_iounmap; +		return r;  	adap = &dev->adapter;  	i2c_set_adapdata(adap, dev); @@ -296,10 +273,11 @@ const struct pci_device_id *id)  	snprintf(adap->name, sizeof(adap->name), "i2c-designware-pci-%d",  		adap->nr); -	r = request_irq(pdev->irq, i2c_dw_isr, IRQF_SHARED, adap->name, dev); +	r = devm_request_irq(&pdev->dev, pdev->irq, i2c_dw_isr, IRQF_SHARED, +			adap->name, dev);  	if (r) {  		dev_err(&pdev->dev, "failure requesting irq %i\n", dev->irq); -		goto err_iounmap; +		return r;  	}  	i2c_dw_disable_int(dev); @@ -307,24 +285,14 @@ const struct pci_device_id *id)  	r = i2c_add_numbered_adapter(adap);  	if (r) {  		dev_err(&pdev->dev, "failure adding adapter\n"); -		goto err_free_irq; +		return r;  	} -	pm_runtime_put_noidle(&pdev->dev); +	pm_runtime_set_autosuspend_delay(&pdev->dev, 1000); +	pm_runtime_use_autosuspend(&pdev->dev);  	pm_runtime_allow(&pdev->dev);  	return 0; - -err_free_irq: -	free_irq(pdev->irq, dev); -err_iounmap: -	iounmap(dev->base); -	put_device(&pdev->dev); -	kfree(dev); -err_release_region: -	pci_release_region(pdev, 0); -exit: -	return r;  }  static void i2c_dw_pci_remove(struct pci_dev *pdev) @@ -336,11 +304,6 @@ static void i2c_dw_pci_remove(struct pci_dev *pdev)  	pm_runtime_get_noresume(&pdev->dev);  	i2c_del_adapter(&dev->adapter); -	put_device(&pdev->dev); - -	free_irq(dev->irq, dev); -	kfree(dev); -	pci_release_region(pdev, 0);  }  /* work with hotplug and coldplug */ diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index e3085c487ac..8ec91335d95 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -56,20 +56,11 @@ static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev)  static int dw_i2c_acpi_configure(struct platform_device *pdev)  {  	struct dw_i2c_dev *dev = platform_get_drvdata(pdev); -	struct acpi_device *adev; -	int busno, ret;  	if (!ACPI_HANDLE(&pdev->dev))  		return -ENODEV; -	ret = acpi_bus_get_device(ACPI_HANDLE(&pdev->dev), &adev); -	if (ret) -		return -ENODEV; -  	dev->adapter.nr = -1; -	if (adev->pnp.unique_id && !kstrtoint(adev->pnp.unique_id, 0, &busno)) -		dev->adapter.nr = busno; -  	dev->tx_fifo_depth = 32;  	dev->rx_fifo_depth = 32;  	return 0; @@ -92,7 +83,7 @@ static int dw_i2c_probe(struct platform_device *pdev)  {  	struct dw_i2c_dev *dev;  	struct i2c_adapter *adap; -	struct resource *mem, *ioarea; +	struct resource *mem;  	int irq, r;  	/* NOTE: driver uses the static register mapping */ @@ -108,32 +99,25 @@ static int dw_i2c_probe(struct platform_device *pdev)  		return irq; /* -ENXIO */  	} -	ioarea = request_mem_region(mem->start, resource_size(mem), -			pdev->name); -	if (!ioarea) { -		dev_err(&pdev->dev, "I2C region already claimed\n"); -		return -EBUSY; -	} +	dev = devm_kzalloc(&pdev->dev, sizeof(struct dw_i2c_dev), GFP_KERNEL); +	if (!dev) +		return -ENOMEM; -	dev = kzalloc(sizeof(struct dw_i2c_dev), GFP_KERNEL); -	if (!dev) { -		r = -ENOMEM; -		goto err_release_region; -	} +	dev->base = devm_ioremap_resource(&pdev->dev, mem); +	if (IS_ERR(dev->base)) +		return PTR_ERR(dev->base);  	init_completion(&dev->cmd_complete);  	mutex_init(&dev->lock); -	dev->dev = get_device(&pdev->dev); +	dev->dev = &pdev->dev;  	dev->irq = irq;  	platform_set_drvdata(pdev, dev); -	dev->clk = clk_get(&pdev->dev, NULL); +	dev->clk = devm_clk_get(&pdev->dev, NULL);  	dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz; -	if (IS_ERR(dev->clk)) { -		r = -ENODEV; -		goto err_free_mem; -	} +	if (IS_ERR(dev->clk)) +		return PTR_ERR(dev->clk);  	clk_prepare_enable(dev->clk);  	dev->functionality = @@ -146,13 +130,6 @@ static int dw_i2c_probe(struct platform_device *pdev)  	dev->master_cfg =  DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE |  		DW_IC_CON_RESTART_EN | DW_IC_CON_SPEED_FAST; -	dev->base = ioremap(mem->start, resource_size(mem)); -	if (dev->base == NULL) { -		dev_err(&pdev->dev, "failure mapping io resources\n"); -		r = -EBUSY; -		goto err_unuse_clocks; -	} -  	/* Try first if we can configure the device from ACPI */  	r = dw_i2c_acpi_configure(pdev);  	if (r) { @@ -164,13 +141,14 @@ static int dw_i2c_probe(struct platform_device *pdev)  	}  	r = i2c_dw_init(dev);  	if (r) -		goto err_iounmap; +		return r;  	i2c_dw_disable_int(dev); -	r = request_irq(dev->irq, i2c_dw_isr, IRQF_SHARED, pdev->name, dev); +	r = devm_request_irq(&pdev->dev, dev->irq, i2c_dw_isr, IRQF_SHARED, +			pdev->name, dev);  	if (r) {  		dev_err(&pdev->dev, "failure requesting irq %i\n", dev->irq); -		goto err_iounmap; +		return r;  	}  	adap = &dev->adapter; @@ -186,57 +164,32 @@ static int dw_i2c_probe(struct platform_device *pdev)  	r = i2c_add_numbered_adapter(adap);  	if (r) {  		dev_err(&pdev->dev, "failure adding adapter\n"); -		goto err_free_irq; +		return r;  	}  	of_i2c_register_devices(adap);  	acpi_i2c_register_devices(adap); +	pm_runtime_set_autosuspend_delay(&pdev->dev, 1000); +	pm_runtime_use_autosuspend(&pdev->dev);  	pm_runtime_set_active(&pdev->dev);  	pm_runtime_enable(&pdev->dev); -	pm_runtime_put(&pdev->dev);  	return 0; - -err_free_irq: -	free_irq(dev->irq, dev); -err_iounmap: -	iounmap(dev->base); -err_unuse_clocks: -	clk_disable_unprepare(dev->clk); -	clk_put(dev->clk); -	dev->clk = NULL; -err_free_mem: -	put_device(&pdev->dev); -	kfree(dev); -err_release_region: -	release_mem_region(mem->start, resource_size(mem)); - -	return r;  }  static int dw_i2c_remove(struct platform_device *pdev)  {  	struct dw_i2c_dev *dev = platform_get_drvdata(pdev); -	struct resource *mem;  	pm_runtime_get_sync(&pdev->dev);  	i2c_del_adapter(&dev->adapter); -	put_device(&pdev->dev); - -	clk_disable_unprepare(dev->clk); -	clk_put(dev->clk); -	dev->clk = NULL;  	i2c_dw_disable(dev); -	free_irq(dev->irq, dev); -	kfree(dev);  	pm_runtime_put(&pdev->dev);  	pm_runtime_disable(&pdev->dev); -	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	release_mem_region(mem->start, resource_size(mem));  	return 0;  } diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c index f3fa4332bbd..bc6e139c6e7 100644 --- a/drivers/i2c/busses/i2c-gpio.c +++ b/drivers/i2c/busses/i2c-gpio.c @@ -85,23 +85,29 @@ static int i2c_gpio_getscl(void *data)  	return gpio_get_value(pdata->scl_pin);  } -static int of_i2c_gpio_probe(struct device_node *np, -			     struct i2c_gpio_platform_data *pdata) +static int of_i2c_gpio_get_pins(struct device_node *np, +				unsigned int *sda_pin, unsigned int *scl_pin)  { -	u32 reg; -  	if (of_gpio_count(np) < 2)  		return -ENODEV; -	pdata->sda_pin = of_get_gpio(np, 0); -	pdata->scl_pin = of_get_gpio(np, 1); +	*sda_pin = of_get_gpio(np, 0); +	*scl_pin = of_get_gpio(np, 1); -	if (!gpio_is_valid(pdata->sda_pin) || !gpio_is_valid(pdata->scl_pin)) { +	if (!gpio_is_valid(*sda_pin) || !gpio_is_valid(*scl_pin)) {  		pr_err("%s: invalid GPIO pins, sda=%d/scl=%d\n", -		       np->full_name, pdata->sda_pin, pdata->scl_pin); +		       np->full_name, *sda_pin, *scl_pin);  		return -ENODEV;  	} +	return 0; +} + +static void of_i2c_gpio_get_props(struct device_node *np, +				  struct i2c_gpio_platform_data *pdata) +{ +	u32 reg; +  	of_property_read_u32(np, "i2c-gpio,delay-us", &pdata->udelay);  	if (!of_property_read_u32(np, "i2c-gpio,timeout-ms", ®)) @@ -113,8 +119,6 @@ static int of_i2c_gpio_probe(struct device_node *np,  		of_property_read_bool(np, "i2c-gpio,scl-open-drain");  	pdata->scl_is_output_only =  		of_property_read_bool(np, "i2c-gpio,scl-output-only"); - -	return 0;  }  static int i2c_gpio_probe(struct platform_device *pdev) @@ -123,31 +127,52 @@ static int i2c_gpio_probe(struct platform_device *pdev)  	struct i2c_gpio_platform_data *pdata;  	struct i2c_algo_bit_data *bit_data;  	struct i2c_adapter *adap; +	unsigned int sda_pin, scl_pin;  	int ret; -	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); -	if (!priv) -		return -ENOMEM; -	adap = &priv->adap; -	bit_data = &priv->bit_data; -	pdata = &priv->pdata; - +	/* First get the GPIO pins; if it fails, we'll defer the probe. */  	if (pdev->dev.of_node) { -		ret = of_i2c_gpio_probe(pdev->dev.of_node, pdata); +		ret = of_i2c_gpio_get_pins(pdev->dev.of_node, +					   &sda_pin, &scl_pin);  		if (ret)  			return ret;  	} else {  		if (!pdev->dev.platform_data)  			return -ENXIO; -		memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata)); +		pdata = pdev->dev.platform_data; +		sda_pin = pdata->sda_pin; +		scl_pin = pdata->scl_pin;  	} -	ret = gpio_request(pdata->sda_pin, "sda"); -	if (ret) +	ret = gpio_request(sda_pin, "sda"); +	if (ret) { +		if (ret == -EINVAL) +			ret = -EPROBE_DEFER;	/* Try again later */  		goto err_request_sda; -	ret = gpio_request(pdata->scl_pin, "scl"); -	if (ret) +	} +	ret = gpio_request(scl_pin, "scl"); +	if (ret) { +		if (ret == -EINVAL) +			ret = -EPROBE_DEFER;	/* Try again later */  		goto err_request_scl; +	} + +	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); +	if (!priv) { +		ret = -ENOMEM; +		goto err_add_bus; +	} +	adap = &priv->adap; +	bit_data = &priv->bit_data; +	pdata = &priv->pdata; + +	if (pdev->dev.of_node) { +		pdata->sda_pin = sda_pin; +		pdata->scl_pin = scl_pin; +		of_i2c_gpio_get_props(pdev->dev.of_node, pdata); +	} else { +		memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata)); +	}  	if (pdata->sda_is_open_drain) {  		gpio_direction_output(pdata->sda_pin, 1); @@ -211,9 +236,9 @@ static int i2c_gpio_probe(struct platform_device *pdev)  	return 0;  err_add_bus: -	gpio_free(pdata->scl_pin); +	gpio_free(scl_pin);  err_request_scl: -	gpio_free(pdata->sda_pin); +	gpio_free(sda_pin);  err_request_sda:  	return ret;  } diff --git a/drivers/i2c/busses/i2c-intel-mid.c b/drivers/i2c/busses/i2c-intel-mid.c index 323fa018ffd..0fb659726ff 100644 --- a/drivers/i2c/busses/i2c-intel-mid.c +++ b/drivers/i2c/busses/i2c-intel-mid.c @@ -1082,8 +1082,7 @@ static void intel_mid_i2c_remove(struct pci_dev *dev)  {  	struct intel_mid_i2c_private *mrst = pci_get_drvdata(dev);  	intel_mid_i2c_disable(&mrst->adap); -	if (i2c_del_adapter(&mrst->adap)) -		dev_err(&dev->dev, "Failed to delete i2c adapter"); +	i2c_del_adapter(&mrst->adap);  	free_irq(dev->irq, mrst);  	iounmap(mrst->base); diff --git a/drivers/i2c/busses/i2c-ismt.c b/drivers/i2c/busses/i2c-ismt.c index 130f02cc9d9..cd82eb44e4c 100644 --- a/drivers/i2c/busses/i2c-ismt.c +++ b/drivers/i2c/busses/i2c-ismt.c @@ -183,7 +183,7 @@ struct ismt_priv {  /**   * ismt_ids - PCI device IDs supported by this driver   */ -static const DEFINE_PCI_DEVICE_TABLE(ismt_ids) = { +static DEFINE_PCI_DEVICE_TABLE(ismt_ids) = {  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_S1200_SMT0) },  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_S1200_SMT1) },  	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_AVOTON_SMT) }, diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index 8b20ef8524a..3bbd65d35a5 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c @@ -701,9 +701,8 @@ static int  mv64xxx_i2c_remove(struct platform_device *dev)  {  	struct mv64xxx_i2c_data		*drv_data = platform_get_drvdata(dev); -	int	rc; -	rc = i2c_del_adapter(&drv_data->adapter); +	i2c_del_adapter(&drv_data->adapter);  	free_irq(drv_data->irq, drv_data);  	mv64xxx_i2c_unmap_regs(drv_data);  #if defined(CONFIG_HAVE_CLK) @@ -715,7 +714,7 @@ mv64xxx_i2c_remove(struct platform_device *dev)  #endif  	kfree(drv_data); -	return rc; +	return 0;  }  static const struct of_device_id mv64xxx_i2c_of_match_table[] = { diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c index d1ba6b403b8..2039f230482 100644 --- a/drivers/i2c/busses/i2c-mxs.c +++ b/drivers/i2c/busses/i2c-mxs.c @@ -55,6 +55,7 @@  #define MXS_I2C_CTRL1_SET	(0x44)  #define MXS_I2C_CTRL1_CLR	(0x48) +#define MXS_I2C_CTRL1_CLR_GOT_A_NAK		0x10000000  #define MXS_I2C_CTRL1_BUS_FREE_IRQ		0x80  #define MXS_I2C_CTRL1_DATA_ENGINE_CMPLT_IRQ	0x40  #define MXS_I2C_CTRL1_NO_SLAVE_ACK_IRQ		0x20 @@ -64,6 +65,10 @@  #define MXS_I2C_CTRL1_SLAVE_STOP_IRQ		0x02  #define MXS_I2C_CTRL1_SLAVE_IRQ			0x01 +#define MXS_I2C_STAT		(0x50) +#define MXS_I2C_STAT_BUS_BUSY			0x00000800 +#define MXS_I2C_STAT_CLK_GEN_BUSY		0x00000400 +  #define MXS_I2C_DATA		(0xa0)  #define MXS_I2C_DEBUG0		(0xb0) @@ -294,12 +299,10 @@ static int mxs_i2c_pio_wait_dmareq(struct mxs_i2c_dev *i2c)  		cond_resched();  	} -	writel(MXS_I2C_DEBUG0_DMAREQ, i2c->regs + MXS_I2C_DEBUG0_CLR); -  	return 0;  } -static int mxs_i2c_pio_wait_cplt(struct mxs_i2c_dev *i2c) +static int mxs_i2c_pio_wait_cplt(struct mxs_i2c_dev *i2c, int last)  {  	unsigned long timeout = jiffies + msecs_to_jiffies(1000); @@ -320,9 +323,50 @@ static int mxs_i2c_pio_wait_cplt(struct mxs_i2c_dev *i2c)  	writel(MXS_I2C_CTRL1_DATA_ENGINE_CMPLT_IRQ,  		i2c->regs + MXS_I2C_CTRL1_CLR); +	/* +	 * When ending a transfer with a stop, we have to wait for the bus to +	 * go idle before we report the transfer as completed. Otherwise the +	 * start of the next transfer may race with the end of the current one. +	 */ +	while (last && (readl(i2c->regs + MXS_I2C_STAT) & +			(MXS_I2C_STAT_BUS_BUSY | MXS_I2C_STAT_CLK_GEN_BUSY))) { +		if (time_after(jiffies, timeout)) +			return -ETIMEDOUT; +		cond_resched(); +	} +  	return 0;  } +static int mxs_i2c_pio_check_error_state(struct mxs_i2c_dev *i2c) +{ +	u32 state; + +	state = readl(i2c->regs + MXS_I2C_CTRL1_CLR) & MXS_I2C_IRQ_MASK; + +	if (state & MXS_I2C_CTRL1_NO_SLAVE_ACK_IRQ) +		i2c->cmd_err = -ENXIO; +	else if (state & (MXS_I2C_CTRL1_EARLY_TERM_IRQ | +			  MXS_I2C_CTRL1_MASTER_LOSS_IRQ | +			  MXS_I2C_CTRL1_SLAVE_STOP_IRQ | +			  MXS_I2C_CTRL1_SLAVE_IRQ)) +		i2c->cmd_err = -EIO; + +	return i2c->cmd_err; +} + +static void mxs_i2c_pio_trigger_cmd(struct mxs_i2c_dev *i2c, u32 cmd) +{ +	u32 reg; + +	writel(cmd, i2c->regs + MXS_I2C_CTRL0); + +	/* readback makes sure the write is latched into hardware */ +	reg = readl(i2c->regs + MXS_I2C_CTRL0); +	reg |= MXS_I2C_CTRL0_RUN; +	writel(reg, i2c->regs + MXS_I2C_CTRL0); +} +  static int mxs_i2c_pio_setup_xfer(struct i2c_adapter *adap,  			struct i2c_msg *msg, uint32_t flags)  { @@ -338,23 +382,26 @@ static int mxs_i2c_pio_setup_xfer(struct i2c_adapter *adap,  		addr_data |= I2C_SMBUS_READ;  		/* SELECT command. */ -		writel(MXS_I2C_CTRL0_RUN | MXS_CMD_I2C_SELECT, -			i2c->regs + MXS_I2C_CTRL0); +		mxs_i2c_pio_trigger_cmd(i2c, MXS_CMD_I2C_SELECT);  		ret = mxs_i2c_pio_wait_dmareq(i2c);  		if (ret)  			return ret;  		writel(addr_data, i2c->regs + MXS_I2C_DATA); +		writel(MXS_I2C_DEBUG0_DMAREQ, i2c->regs + MXS_I2C_DEBUG0_CLR); -		ret = mxs_i2c_pio_wait_cplt(i2c); +		ret = mxs_i2c_pio_wait_cplt(i2c, 0);  		if (ret)  			return ret; +		if (mxs_i2c_pio_check_error_state(i2c)) +			goto cleanup; +  		/* READ command. */ -		writel(MXS_I2C_CTRL0_RUN | MXS_CMD_I2C_READ | flags | -			MXS_I2C_CTRL0_XFER_COUNT(msg->len), -			i2c->regs + MXS_I2C_CTRL0); +		mxs_i2c_pio_trigger_cmd(i2c, +					MXS_CMD_I2C_READ | flags | +					MXS_I2C_CTRL0_XFER_COUNT(msg->len));  		for (i = 0; i < msg->len; i++) {  			if ((i & 3) == 0) { @@ -362,6 +409,8 @@ static int mxs_i2c_pio_setup_xfer(struct i2c_adapter *adap,  				if (ret)  					return ret;  				data = readl(i2c->regs + MXS_I2C_DATA); +				writel(MXS_I2C_DEBUG0_DMAREQ, +				       i2c->regs + MXS_I2C_DEBUG0_CLR);  			}  			msg->buf[i] = data & 0xff;  			data >>= 8; @@ -370,9 +419,9 @@ static int mxs_i2c_pio_setup_xfer(struct i2c_adapter *adap,  		addr_data |= I2C_SMBUS_WRITE;  		/* WRITE command. */ -		writel(MXS_I2C_CTRL0_RUN | MXS_CMD_I2C_WRITE | flags | -			MXS_I2C_CTRL0_XFER_COUNT(msg->len + 1), -			i2c->regs + MXS_I2C_CTRL0); +		mxs_i2c_pio_trigger_cmd(i2c, +					MXS_CMD_I2C_WRITE | flags | +					MXS_I2C_CTRL0_XFER_COUNT(msg->len + 1));  		/*  		 * The LSB of data buffer is the first byte blasted across @@ -388,6 +437,8 @@ static int mxs_i2c_pio_setup_xfer(struct i2c_adapter *adap,  				if (ret)  					return ret;  				writel(data, i2c->regs + MXS_I2C_DATA); +				writel(MXS_I2C_DEBUG0_DMAREQ, +				       i2c->regs + MXS_I2C_DEBUG0_CLR);  			}  		} @@ -398,13 +449,19 @@ static int mxs_i2c_pio_setup_xfer(struct i2c_adapter *adap,  			if (ret)  				return ret;  			writel(data, i2c->regs + MXS_I2C_DATA); +			writel(MXS_I2C_DEBUG0_DMAREQ, +			       i2c->regs + MXS_I2C_DEBUG0_CLR);  		}  	} -	ret = mxs_i2c_pio_wait_cplt(i2c); +	ret = mxs_i2c_pio_wait_cplt(i2c, flags & MXS_I2C_CTRL0_POST_SEND_STOP);  	if (ret)  		return ret; +	/* make sure we capture any occurred error into cmd_err */ +	mxs_i2c_pio_check_error_state(i2c); + +cleanup:  	/* Clear any dangling IRQs and re-enable interrupts. */  	writel(MXS_I2C_IRQ_MASK, i2c->regs + MXS_I2C_CTRL1_CLR);  	writel(MXS_I2C_IRQ_MASK << 8, i2c->regs + MXS_I2C_CTRL1_SET); @@ -436,12 +493,12 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,  	 * using PIO mode while longer transfers use DMA. The 8 byte border is  	 * based on this empirical measurement and a lot of previous frobbing.  	 */ +	i2c->cmd_err = 0;  	if (msg->len < 8) {  		ret = mxs_i2c_pio_setup_xfer(adap, msg, flags);  		if (ret)  			mxs_i2c_reset(i2c);  	} else { -		i2c->cmd_err = 0;  		INIT_COMPLETION(i2c->cmd_complete);  		ret = mxs_i2c_dma_setup_xfer(adap, msg, flags);  		if (ret) @@ -451,13 +508,19 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,  						msecs_to_jiffies(1000));  		if (ret == 0)  			goto timeout; +	} -		if (i2c->cmd_err == -ENXIO) -			mxs_i2c_reset(i2c); - -		ret = i2c->cmd_err; +	if (i2c->cmd_err == -ENXIO) { +		/* +		 * If the transfer fails with a NAK from the slave the +		 * controller halts until it gets told to return to idle state. +		 */ +		writel(MXS_I2C_CTRL1_CLR_GOT_A_NAK, +		       i2c->regs + MXS_I2C_CTRL1_SET);  	} +	ret = i2c->cmd_err; +  	dev_dbg(i2c->dev, "Done with err=%d\n", ret);  	return ret; @@ -652,11 +715,8 @@ static int mxs_i2c_probe(struct platform_device *pdev)  static int mxs_i2c_remove(struct platform_device *pdev)  {  	struct mxs_i2c_dev *i2c = platform_get_drvdata(pdev); -	int ret; -	ret = i2c_del_adapter(&i2c->adapter); -	if (ret) -		return -EBUSY; +	i2c_del_adapter(&i2c->adapter);  	if (i2c->dmach)  		dma_release_channel(i2c->dmach); diff --git a/drivers/i2c/busses/i2c-nforce2-s4985.c b/drivers/i2c/busses/i2c-nforce2-s4985.c index 29015eb9ca4..2ca268d6140 100644 --- a/drivers/i2c/busses/i2c-nforce2-s4985.c +++ b/drivers/i2c/busses/i2c-nforce2-s4985.c @@ -164,11 +164,7 @@ static int __init nforce2_s4985_init(void)  	}  	/* Unregister physical bus */ -	error = i2c_del_adapter(nforce2_smbus); -	if (error) { -		dev_err(&nforce2_smbus->dev, "Physical bus removal failed\n"); -		goto ERROR0; -	} +	i2c_del_adapter(nforce2_smbus);  	printk(KERN_INFO "Enabling SMBus multiplexing for Tyan S4985\n");  	/* Define the 5 virtual adapters and algorithms structures */ diff --git a/drivers/i2c/busses/i2c-octeon.c b/drivers/i2c/busses/i2c-octeon.c index 935585ef4d3..956fe320f31 100644 --- a/drivers/i2c/busses/i2c-octeon.c +++ b/drivers/i2c/busses/i2c-octeon.c @@ -183,7 +183,7 @@ static irqreturn_t octeon_i2c_isr(int irq, void *dev_id)  	struct octeon_i2c *i2c = dev_id;  	octeon_i2c_int_disable(i2c); -	wake_up_interruptible(&i2c->queue); +	wake_up(&i2c->queue);  	return IRQ_HANDLED;  } @@ -206,9 +206,9 @@ static int octeon_i2c_wait(struct octeon_i2c *i2c)  	octeon_i2c_int_enable(i2c); -	result = wait_event_interruptible_timeout(i2c->queue, -						  octeon_i2c_test_iflg(i2c), -						  i2c->adap.timeout); +	result = wait_event_timeout(i2c->queue, +					octeon_i2c_test_iflg(i2c), +					i2c->adap.timeout);  	octeon_i2c_int_disable(i2c); @@ -440,7 +440,7 @@ static struct i2c_adapter octeon_i2c_ops = {  	.owner = THIS_MODULE,  	.name = "OCTEON adapter",  	.algo = &octeon_i2c_algo, -	.timeout = 2, +	.timeout = HZ / 50,  };  /** diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c index da54e673449..8dc90da1e6e 100644 --- a/drivers/i2c/busses/i2c-powermac.c +++ b/drivers/i2c/busses/i2c-powermac.c @@ -213,14 +213,8 @@ static const struct i2c_algorithm i2c_powermac_algorithm = {  static int i2c_powermac_remove(struct platform_device *dev)  {  	struct i2c_adapter	*adapter = platform_get_drvdata(dev); -	int			rc; -	rc = i2c_del_adapter(adapter); -	/* We aren't that prepared to deal with this... */ -	if (rc) -		printk(KERN_WARNING -		       "i2c-powermac.c: Failed to remove bus %s !\n", -		       adapter->name); +	i2c_del_adapter(adapter);  	memset(adapter, 0, sizeof(*adapter));  	return 0; diff --git a/drivers/i2c/busses/i2c-puv3.c b/drivers/i2c/busses/i2c-puv3.c index 261d7db437e..37a84c87c5f 100644 --- a/drivers/i2c/busses/i2c-puv3.c +++ b/drivers/i2c/busses/i2c-puv3.c @@ -199,7 +199,7 @@ static int puv3_i2c_probe(struct platform_device *pdev)  	adapter = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);  	if (adapter == NULL) { -		dev_err(&pdev->dev, "can't allocate inteface!\n"); +		dev_err(&pdev->dev, "can't allocate interface!\n");  		rc = -ENOMEM;  		goto fail_nomem;  	} @@ -234,21 +234,15 @@ static int puv3_i2c_remove(struct platform_device *pdev)  {  	struct i2c_adapter *adapter = platform_get_drvdata(pdev);  	struct resource *mem; -	int rc; -	rc = i2c_del_adapter(adapter); -	if (rc) { -		dev_err(&pdev->dev, "Adapter '%s' delete fail\n", -				adapter->name); -		return rc; -	} +	i2c_del_adapter(adapter);  	put_device(&pdev->dev);  	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);  	release_mem_region(mem->start, resource_size(mem)); -	return rc; +	return 0;  }  #ifdef CONFIG_PM diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 1e88e8d66c5..ea6d45d1dcd 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -1053,16 +1053,13 @@ static int i2c_pxa_probe_dt(struct platform_device *pdev, struct pxa_i2c *i2c,  	struct device_node *np = pdev->dev.of_node;  	const struct of_device_id *of_id =  			of_match_device(i2c_pxa_dt_ids, &pdev->dev); -	int ret;  	if (!of_id)  		return 1; -	ret = of_alias_get_id(np, "i2c"); -	if (ret < 0) { -		dev_err(&pdev->dev, "failed to get alias id, errno %d\n", ret); -		return ret; -	} -	pdev->id = ret; + +	/* For device tree we always use the dynamic or alias-assigned ID */ +	i2c->adap.nr = -1; +  	if (of_get_property(np, "mrvl,i2c-polling", NULL))  		i2c->use_pio = 1;  	if (of_get_property(np, "mrvl,i2c-fast-mode", NULL)) @@ -1100,6 +1097,9 @@ static int i2c_pxa_probe(struct platform_device *dev)  		goto emalloc;  	} +	/* Default adapter num to device id; i2c_pxa_probe_dt can override. */ +	i2c->adap.nr = dev->id; +  	ret = i2c_pxa_probe_dt(dev, i2c, &i2c_type);  	if (ret > 0)  		ret = i2c_pxa_probe_pdata(dev, i2c, &i2c_type); @@ -1124,9 +1124,7 @@ static int i2c_pxa_probe(struct platform_device *dev)  	spin_lock_init(&i2c->lock);  	init_waitqueue_head(&i2c->wait); -	i2c->adap.nr = dev->id; -	snprintf(i2c->adap.name, sizeof(i2c->adap.name), "pxa_i2c-i2c.%u", -		 i2c->adap.nr); +	strlcpy(i2c->adap.name, "pxa_i2c-i2c", sizeof(i2c->adap.name));  	i2c->clk = clk_get(&dev->dev, NULL);  	if (IS_ERR(i2c->clk)) { @@ -1169,7 +1167,7 @@ static int i2c_pxa_probe(struct platform_device *dev)  	} else {  		i2c->adap.algo = &i2c_pxa_algorithm;  		ret = request_irq(irq, i2c_pxa_handler, IRQF_SHARED, -				  i2c->adap.name, i2c); +				  dev_name(&dev->dev), i2c);  		if (ret)  			goto ereqirq;  	} diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index f6b880ba193..6e8ee92ab55 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -42,9 +42,46 @@  #include <asm/irq.h> -#include <plat/regs-iic.h>  #include <linux/platform_data/i2c-s3c2410.h> +/* see s3c2410x user guide, v1.1, section 9 (p447) for more info */ + +#define S3C2410_IICCON			0x00 +#define S3C2410_IICSTAT			0x04 +#define S3C2410_IICADD			0x08 +#define S3C2410_IICDS			0x0C +#define S3C2440_IICLC			0x10 + +#define S3C2410_IICCON_ACKEN		(1 << 7) +#define S3C2410_IICCON_TXDIV_16		(0 << 6) +#define S3C2410_IICCON_TXDIV_512	(1 << 6) +#define S3C2410_IICCON_IRQEN		(1 << 5) +#define S3C2410_IICCON_IRQPEND		(1 << 4) +#define S3C2410_IICCON_SCALE(x)		((x) & 0xf) +#define S3C2410_IICCON_SCALEMASK	(0xf) + +#define S3C2410_IICSTAT_MASTER_RX	(2 << 6) +#define S3C2410_IICSTAT_MASTER_TX	(3 << 6) +#define S3C2410_IICSTAT_SLAVE_RX	(0 << 6) +#define S3C2410_IICSTAT_SLAVE_TX	(1 << 6) +#define S3C2410_IICSTAT_MODEMASK	(3 << 6) + +#define S3C2410_IICSTAT_START		(1 << 5) +#define S3C2410_IICSTAT_BUSBUSY		(1 << 5) +#define S3C2410_IICSTAT_TXRXEN		(1 << 4) +#define S3C2410_IICSTAT_ARBITR		(1 << 3) +#define S3C2410_IICSTAT_ASSLAVE		(1 << 2) +#define S3C2410_IICSTAT_ADDR0		(1 << 1) +#define S3C2410_IICSTAT_LASTBIT		(1 << 0) + +#define S3C2410_IICLC_SDA_DELAY0	(0 << 0) +#define S3C2410_IICLC_SDA_DELAY5	(1 << 0) +#define S3C2410_IICLC_SDA_DELAY10	(2 << 0) +#define S3C2410_IICLC_SDA_DELAY15	(3 << 0) +#define S3C2410_IICLC_SDA_DELAY_MASK	(3 << 0) + +#define S3C2410_IICLC_FILTER_ON		(1 << 2) +  /* Treat S3C2410 as baseline hardware, anything else is supported via quirks */  #define QUIRK_S3C2440		(1 << 0)  #define QUIRK_HDMIPHY		(1 << 1) @@ -309,6 +346,12 @@ static inline int is_lastmsg(struct s3c24xx_i2c *i2c)  static inline int is_msglast(struct s3c24xx_i2c *i2c)  { +	/* msg->len is always 1 for the first byte of smbus block read. +	 * Actual length will be read from slave. More bytes will be +	 * read according to the length then. */ +	if (i2c->msg->flags & I2C_M_RECV_LEN && i2c->msg->len == 1) +		return 0; +  	return i2c->msg_ptr == i2c->msg->len-1;  } @@ -448,6 +491,9 @@ static int i2c_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)  		byte = readb(i2c->regs + S3C2410_IICDS);  		i2c->msg->buf[i2c->msg_ptr++] = byte; +		/* Add actual length to read for smbus block read */ +		if (i2c->msg->flags & I2C_M_RECV_LEN && i2c->msg->len == 1) +			i2c->msg->len += byte;   prepare_read:  		if (is_msglast(i2c)) {  			/* last byte of buffer */ diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index b714776b6dd..b60ff90adc3 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -25,7 +25,6 @@  #include <linux/interrupt.h>  #include <linux/delay.h>  #include <linux/slab.h> -#include <linux/i2c-tegra.h>  #include <linux/of_i2c.h>  #include <linux/of_device.h>  #include <linux/module.h> @@ -172,7 +171,7 @@ struct tegra_i2c_dev {  	u8 *msg_buf;  	size_t msg_buf_remaining;  	int msg_read; -	unsigned long bus_clk_rate; +	u32 bus_clk_rate;  	bool is_suspended;  }; @@ -694,7 +693,6 @@ static const struct tegra_i2c_hw_feature tegra114_i2c_hw = {  	.clk_divisor_std_fast_mode = 0x19,  }; -#if defined(CONFIG_OF)  /* Match table for of_platform binding */  static const struct of_device_id tegra_i2c_of_match[] = {  	{ .compatible = "nvidia,tegra114-i2c", .data = &tegra114_i2c_hw, }, @@ -704,16 +702,13 @@ static const struct of_device_id tegra_i2c_of_match[] = {  	{},  };  MODULE_DEVICE_TABLE(of, tegra_i2c_of_match); -#endif  static int tegra_i2c_probe(struct platform_device *pdev)  {  	struct tegra_i2c_dev *i2c_dev; -	struct tegra_i2c_platform_data *pdata = pdev->dev.platform_data;  	struct resource *res;  	struct clk *div_clk;  	struct clk *fast_clk; -	const unsigned int *prop;  	void __iomem *base;  	int irq;  	int ret = 0; @@ -754,23 +749,16 @@ static int tegra_i2c_probe(struct platform_device *pdev)  	i2c_dev->cont_id = pdev->id;  	i2c_dev->dev = &pdev->dev; -	i2c_dev->bus_clk_rate = 100000; /* default clock rate */ -	if (pdata) { -		i2c_dev->bus_clk_rate = pdata->bus_clk_rate; - -	} else if (i2c_dev->dev->of_node) {    /* if there is a device tree node ... */ -		prop = of_get_property(i2c_dev->dev->of_node, -				"clock-frequency", NULL); -		if (prop) -			i2c_dev->bus_clk_rate = be32_to_cpup(prop); -	} +	ret = of_property_read_u32(i2c_dev->dev->of_node, "clock-frequency", +					&i2c_dev->bus_clk_rate); +	if (ret) +		i2c_dev->bus_clk_rate = 100000; /* default clock rate */  	i2c_dev->hw = &tegra20_i2c_hw;  	if (pdev->dev.of_node) {  		const struct of_device_id *match; -		match = of_match_device(of_match_ptr(tegra_i2c_of_match), -						&pdev->dev); +		match = of_match_device(tegra_i2c_of_match, &pdev->dev);  		i2c_dev->hw = match->data;  		i2c_dev->is_dvc = of_device_is_compatible(pdev->dev.of_node,  						"nvidia,tegra20-i2c-dvc"); @@ -876,7 +864,7 @@ static struct platform_driver tegra_i2c_driver = {  	.driver  = {  		.name  = "tegra-i2c",  		.owner = THIS_MODULE, -		.of_match_table = of_match_ptr(tegra_i2c_of_match), +		.of_match_table = tegra_i2c_of_match,  		.pm    = TEGRA_I2C_PM,  	},  }; diff --git a/drivers/i2c/busses/i2c-viperboard.c b/drivers/i2c/busses/i2c-viperboard.c index f45c32c1ace..c68450cd8d5 100644 --- a/drivers/i2c/busses/i2c-viperboard.c +++ b/drivers/i2c/busses/i2c-viperboard.c @@ -421,11 +421,10 @@ error:  static int vprbrd_i2c_remove(struct platform_device *pdev)  {  	struct vprbrd_i2c *vb_i2c = platform_get_drvdata(pdev); -	int ret; -	ret = i2c_del_adapter(&vb_i2c->i2c); +	i2c_del_adapter(&vb_i2c->i2c); -	return ret; +	return 0;  }  static struct platform_driver vprbrd_i2c_driver = { diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c index 332c720fb3f..3d0f0520c1b 100644 --- a/drivers/i2c/busses/i2c-xiic.c +++ b/drivers/i2c/busses/i2c-xiic.c @@ -312,10 +312,8 @@ static void xiic_fill_tx_fifo(struct xiic_i2c *i2c)  			/* last message in transfer -> STOP */  			data |= XIIC_TX_DYN_STOP_MASK;  			dev_dbg(i2c->adap.dev.parent, "%s TX STOP\n", __func__); - -			xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET, data); -		} else -			xiic_setreg8(i2c, XIIC_DTR_REG_OFFSET, data); +		} +		xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET, data);  	}  } diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 991d38daa87..6b63cc7eb71 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -27,7 +27,9 @@  #include <linux/module.h>  #include <linux/kernel.h> +#include <linux/delay.h>  #include <linux/errno.h> +#include <linux/gpio.h>  #include <linux/slab.h>  #include <linux/i2c.h>  #include <linux/init.h> @@ -47,7 +49,7 @@  /* core_lock protects i2c_adapter_idr, and guarantees     that device detection, deletion of detected devices, and attach_adapter -   and detach_adapter calls are serialized */ +   calls are serialized */  static DEFINE_MUTEX(core_lock);  static DEFINE_IDR(i2c_adapter_idr); @@ -91,7 +93,6 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv)  	return 0;  } -#ifdef	CONFIG_HOTPLUG  /* uevent helps with hotplug: modprobe -q $(MODALIAS) */  static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env) @@ -105,9 +106,129 @@ static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env)  	return 0;  } -#else -#define i2c_device_uevent	NULL -#endif	/* CONFIG_HOTPLUG */ +/* i2c bus recovery routines */ +static int get_scl_gpio_value(struct i2c_adapter *adap) +{ +	return gpio_get_value(adap->bus_recovery_info->scl_gpio); +} + +static void set_scl_gpio_value(struct i2c_adapter *adap, int val) +{ +	gpio_set_value(adap->bus_recovery_info->scl_gpio, val); +} + +static int get_sda_gpio_value(struct i2c_adapter *adap) +{ +	return gpio_get_value(adap->bus_recovery_info->sda_gpio); +} + +static int i2c_get_gpios_for_recovery(struct i2c_adapter *adap) +{ +	struct i2c_bus_recovery_info *bri = adap->bus_recovery_info; +	struct device *dev = &adap->dev; +	int ret = 0; + +	ret = gpio_request_one(bri->scl_gpio, GPIOF_OPEN_DRAIN | +			GPIOF_OUT_INIT_HIGH, "i2c-scl"); +	if (ret) { +		dev_warn(dev, "Can't get SCL gpio: %d\n", bri->scl_gpio); +		return ret; +	} + +	if (bri->get_sda) { +		if (gpio_request_one(bri->sda_gpio, GPIOF_IN, "i2c-sda")) { +			/* work without SDA polling */ +			dev_warn(dev, "Can't get SDA gpio: %d. Not using SDA polling\n", +					bri->sda_gpio); +			bri->get_sda = NULL; +		} +	} + +	return ret; +} + +static void i2c_put_gpios_for_recovery(struct i2c_adapter *adap) +{ +	struct i2c_bus_recovery_info *bri = adap->bus_recovery_info; + +	if (bri->get_sda) +		gpio_free(bri->sda_gpio); + +	gpio_free(bri->scl_gpio); +} + +/* + * We are generating clock pulses. ndelay() determines durating of clk pulses. + * We will generate clock with rate 100 KHz and so duration of both clock levels + * is: delay in ns = (10^6 / 100) / 2 + */ +#define RECOVERY_NDELAY		5000 +#define RECOVERY_CLK_CNT	9 + +static int i2c_generic_recovery(struct i2c_adapter *adap) +{ +	struct i2c_bus_recovery_info *bri = adap->bus_recovery_info; +	int i = 0, val = 1, ret = 0; + +	if (bri->prepare_recovery) +		bri->prepare_recovery(bri); + +	/* +	 * By this time SCL is high, as we need to give 9 falling-rising edges +	 */ +	while (i++ < RECOVERY_CLK_CNT * 2) { +		if (val) { +			/* Break if SDA is high */ +			if (bri->get_sda && bri->get_sda(adap)) +					break; +			/* SCL shouldn't be low here */ +			if (!bri->get_scl(adap)) { +				dev_err(&adap->dev, +					"SCL is stuck low, exit recovery\n"); +				ret = -EBUSY; +				break; +			} +		} + +		val = !val; +		bri->set_scl(adap, val); +		ndelay(RECOVERY_NDELAY); +	} + +	if (bri->unprepare_recovery) +		bri->unprepare_recovery(bri); + +	return ret; +} + +int i2c_generic_scl_recovery(struct i2c_adapter *adap) +{ +	adap->bus_recovery_info->set_scl(adap, 1); +	return i2c_generic_recovery(adap); +} + +int i2c_generic_gpio_recovery(struct i2c_adapter *adap) +{ +	int ret; + +	ret = i2c_get_gpios_for_recovery(adap); +	if (ret) +		return ret; + +	ret = i2c_generic_recovery(adap); +	i2c_put_gpios_for_recovery(adap); + +	return ret; +} + +int i2c_recover_bus(struct i2c_adapter *adap) +{ +	if (!adap->bus_recovery_info) +		return -EOPNOTSUPP; + +	dev_dbg(&adap->dev, "Trying i2c bus recovery\n"); +	return adap->bus_recovery_info->recover_bus(adap); +}  static int i2c_device_probe(struct device *dev)  { @@ -902,6 +1023,39 @@ static int i2c_register_adapter(struct i2c_adapter *adap)  			 "Failed to create compatibility class link\n");  #endif +	/* bus recovery specific initialization */ +	if (adap->bus_recovery_info) { +		struct i2c_bus_recovery_info *bri = adap->bus_recovery_info; + +		if (!bri->recover_bus) { +			dev_err(&adap->dev, "No recover_bus() found, not using recovery\n"); +			adap->bus_recovery_info = NULL; +			goto exit_recovery; +		} + +		/* Generic GPIO recovery */ +		if (bri->recover_bus == i2c_generic_gpio_recovery) { +			if (!gpio_is_valid(bri->scl_gpio)) { +				dev_err(&adap->dev, "Invalid SCL gpio, not using recovery\n"); +				adap->bus_recovery_info = NULL; +				goto exit_recovery; +			} + +			if (gpio_is_valid(bri->sda_gpio)) +				bri->get_sda = get_sda_gpio_value; +			else +				bri->get_sda = NULL; + +			bri->get_scl = get_scl_gpio_value; +			bri->set_scl = set_scl_gpio_value; +		} else if (!bri->set_scl || !bri->get_scl) { +			/* Generic SCL recovery */ +			dev_err(&adap->dev, "No {get|set}_gpio() found, not using recovery\n"); +			adap->bus_recovery_info = NULL; +		} +	} + +exit_recovery:  	/* create pre-declared device nodes */  	if (adap->nr < __i2c_first_dynamic_bus_num)  		i2c_scan_static_board_info(adap); @@ -921,13 +1075,35 @@ out_list:  }  /** + * __i2c_add_numbered_adapter - i2c_add_numbered_adapter where nr is never -1 + * @adap: the adapter to register (with adap->nr initialized) + * Context: can sleep + * + * See i2c_add_numbered_adapter() for details. + */ +static int __i2c_add_numbered_adapter(struct i2c_adapter *adap) +{ +	int	id; + +	mutex_lock(&core_lock); +	id = idr_alloc(&i2c_adapter_idr, adap, adap->nr, adap->nr + 1, +		       GFP_KERNEL); +	mutex_unlock(&core_lock); +	if (id < 0) +		return id == -ENOSPC ? -EBUSY : id; + +	return i2c_register_adapter(adap); +} + +/**   * i2c_add_adapter - declare i2c adapter, use dynamic bus number   * @adapter: the adapter to add   * Context: can sleep   *   * This routine is used to declare an I2C adapter when its bus number - * doesn't matter.  Examples: for I2C adapters dynamically added by - * USB links or PCI plugin cards. + * doesn't matter or when its bus number is specified by an dt alias. + * Examples of bases when the bus number doesn't matter: I2C adapters + * dynamically added by USB links or PCI plugin cards.   *   * When this returns zero, a new bus number was allocated and stored   * in adap->nr, and the specified adapter became available for clients. @@ -935,8 +1111,17 @@ out_list:   */  int i2c_add_adapter(struct i2c_adapter *adapter)  { +	struct device *dev = &adapter->dev;  	int id; +	if (dev->of_node) { +		id = of_alias_get_id(dev->of_node, "i2c"); +		if (id >= 0) { +			adapter->nr = id; +			return __i2c_add_numbered_adapter(adapter); +		} +	} +  	mutex_lock(&core_lock);  	id = idr_alloc(&i2c_adapter_idr, adapter,  		       __i2c_first_dynamic_bus_num, 0, GFP_KERNEL); @@ -975,26 +1160,17 @@ EXPORT_SYMBOL(i2c_add_adapter);   */  int i2c_add_numbered_adapter(struct i2c_adapter *adap)  { -	int	id; -  	if (adap->nr == -1) /* -1 means dynamically assign bus id */  		return i2c_add_adapter(adap); -	mutex_lock(&core_lock); -	id = idr_alloc(&i2c_adapter_idr, adap, adap->nr, adap->nr + 1, -		       GFP_KERNEL); -	mutex_unlock(&core_lock); -	if (id < 0) -		return id == -ENOSPC ? -EBUSY : id; -	return i2c_register_adapter(adap); +	return __i2c_add_numbered_adapter(adap);  }  EXPORT_SYMBOL_GPL(i2c_add_numbered_adapter); -static int i2c_do_del_adapter(struct i2c_driver *driver, +static void i2c_do_del_adapter(struct i2c_driver *driver,  			      struct i2c_adapter *adapter)  {  	struct i2c_client *client, *_n; -	int res;  	/* Remove the devices we created ourselves as the result of hardware  	 * probing (using a driver's detect method) */ @@ -1006,16 +1182,6 @@ static int i2c_do_del_adapter(struct i2c_driver *driver,  			i2c_unregister_device(client);  		}  	} - -	if (!driver->detach_adapter) -		return 0; -	dev_warn(&adapter->dev, "%s: detach_adapter method is deprecated\n", -		 driver->driver.name); -	res = driver->detach_adapter(adapter); -	if (res) -		dev_err(&adapter->dev, "detach_adapter failed (%d) " -			"for driver [%s]\n", res, driver->driver.name); -	return res;  }  static int __unregister_client(struct device *dev, void *dummy) @@ -1036,7 +1202,8 @@ static int __unregister_dummy(struct device *dev, void *dummy)  static int __process_removed_adapter(struct device_driver *d, void *data)  { -	return i2c_do_del_adapter(to_i2c_driver(d), data); +	i2c_do_del_adapter(to_i2c_driver(d), data); +	return 0;  }  /** @@ -1047,9 +1214,8 @@ static int __process_removed_adapter(struct device_driver *d, void *data)   * This unregisters an I2C adapter which was previously registered   * by @i2c_add_adapter or @i2c_add_numbered_adapter.   */ -int i2c_del_adapter(struct i2c_adapter *adap) +void i2c_del_adapter(struct i2c_adapter *adap)  { -	int res = 0;  	struct i2c_adapter *found;  	struct i2c_client *client, *next; @@ -1060,16 +1226,14 @@ int i2c_del_adapter(struct i2c_adapter *adap)  	if (found != adap) {  		pr_debug("i2c-core: attempting to delete unregistered "  			 "adapter [%s]\n", adap->name); -		return -EINVAL; +		return;  	}  	/* Tell drivers about this removal */  	mutex_lock(&core_lock); -	res = bus_for_each_drv(&i2c_bus_type, NULL, adap, +	bus_for_each_drv(&i2c_bus_type, NULL, adap,  			       __process_removed_adapter);  	mutex_unlock(&core_lock); -	if (res) -		return res;  	/* Remove devices instantiated from sysfs */  	mutex_lock_nested(&adap->userspace_clients_lock, @@ -1088,8 +1252,8 @@ int i2c_del_adapter(struct i2c_adapter *adap)  	 * we can't remove the dummy devices during the first pass: they  	 * could have been instantiated by real devices wishing to clean  	 * them up properly, so we give them a chance to do that first. */ -	res = device_for_each_child(&adap->dev, NULL, __unregister_client); -	res = device_for_each_child(&adap->dev, NULL, __unregister_dummy); +	device_for_each_child(&adap->dev, NULL, __unregister_client); +	device_for_each_child(&adap->dev, NULL, __unregister_dummy);  #ifdef CONFIG_I2C_COMPAT  	class_compat_remove_link(i2c_adapter_compat_class, &adap->dev, @@ -1114,8 +1278,6 @@ int i2c_del_adapter(struct i2c_adapter *adap)  	/* Clear the device structure in case this adapter is ever going to be  	   added again */  	memset(&adap->dev, 0, sizeof(adap->dev)); - -	return 0;  }  EXPORT_SYMBOL(i2c_del_adapter); @@ -1185,9 +1347,9 @@ EXPORT_SYMBOL(i2c_register_driver);  static int __process_removed_driver(struct device *dev, void *data)  { -	if (dev->type != &i2c_adapter_type) -		return 0; -	return i2c_do_del_adapter(data, to_i2c_adapter(dev)); +	if (dev->type == &i2c_adapter_type) +		i2c_do_del_adapter(data, to_i2c_adapter(dev)); +	return 0;  }  /** diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c index d94e0ce7827..7409ebb33c4 100644 --- a/drivers/i2c/i2c-mux.c +++ b/drivers/i2c/i2c-mux.c @@ -191,17 +191,12 @@ struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent,  }  EXPORT_SYMBOL_GPL(i2c_add_mux_adapter); -int i2c_del_mux_adapter(struct i2c_adapter *adap) +void i2c_del_mux_adapter(struct i2c_adapter *adap)  {  	struct i2c_mux_priv *priv = adap->algo_data; -	int ret; -	ret = i2c_del_adapter(adap); -	if (ret < 0) -		return ret; +	i2c_del_adapter(adap);  	kfree(priv); - -	return 0;  }  EXPORT_SYMBOL_GPL(i2c_del_mux_adapter); diff --git a/drivers/i2c/muxes/Kconfig b/drivers/i2c/muxes/Kconfig index 0be5b83c08f..5faf244d247 100644 --- a/drivers/i2c/muxes/Kconfig +++ b/drivers/i2c/muxes/Kconfig @@ -5,6 +5,18 @@  menu "Multiplexer I2C Chip support"  	depends on I2C_MUX +config I2C_ARB_GPIO_CHALLENGE +	tristate "GPIO-based I2C arbitration" +	depends on GENERIC_GPIO && OF +	help +	  If you say yes to this option, support will be included for an +	  I2C multimaster arbitration scheme using GPIOs and a challenge & +	  response mechanism where masters have to claim the bus by asserting +	  a GPIO. + +	  This driver can also be built as a module.  If so, the module +	  will be called i2c-arb-gpio-challenge. +  config I2C_MUX_GPIO  	tristate "GPIO-based I2C multiplexer"  	depends on GENERIC_GPIO diff --git a/drivers/i2c/muxes/Makefile b/drivers/i2c/muxes/Makefile index 76da8692aff..465778b5d5d 100644 --- a/drivers/i2c/muxes/Makefile +++ b/drivers/i2c/muxes/Makefile @@ -1,6 +1,8 @@  #  # Makefile for multiplexer I2C chip drivers. +obj-$(CONFIG_I2C_ARB_GPIO_CHALLENGE)	+= i2c-arb-gpio-challenge.o +  obj-$(CONFIG_I2C_MUX_GPIO)	+= i2c-mux-gpio.o  obj-$(CONFIG_I2C_MUX_PCA9541)	+= i2c-mux-pca9541.o  obj-$(CONFIG_I2C_MUX_PCA954x)	+= i2c-mux-pca954x.o diff --git a/drivers/i2c/muxes/i2c-arb-gpio-challenge.c b/drivers/i2c/muxes/i2c-arb-gpio-challenge.c new file mode 100644 index 00000000000..210b6f7b902 --- /dev/null +++ b/drivers/i2c/muxes/i2c-arb-gpio-challenge.c @@ -0,0 +1,251 @@ +/* + * GPIO-based I2C Arbitration Using a Challenge & Response Mechanism + * + * Copyright (C) 2012 Google, Inc + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + */ + +#include <linux/delay.h> +#include <linux/gpio.h> +#include <linux/kernel.h> +#include <linux/i2c.h> +#include <linux/i2c-mux.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/of_i2c.h> +#include <linux/of_gpio.h> +#include <linux/platform_device.h> +#include <linux/slab.h> + + +/** + * struct i2c_arbitrator_data - Driver data for I2C arbitrator + * + * @parent: Parent adapter + * @child: Child bus + * @our_gpio: GPIO we'll use to claim. + * @our_gpio_release: 0 if active high; 1 if active low; AKA if the GPIO == + *   this then consider it released. + * @their_gpio: GPIO that the other side will use to claim. + * @their_gpio_release: 0 if active high; 1 if active low; AKA if the GPIO == + *   this then consider it released. + * @slew_delay_us: microseconds to wait for a GPIO to go high. + * @wait_retry_us: we'll attempt another claim after this many microseconds. + * @wait_free_us: we'll give up after this many microseconds. + */ + +struct i2c_arbitrator_data { +	struct i2c_adapter *parent; +	struct i2c_adapter *child; +	int our_gpio; +	int our_gpio_release; +	int their_gpio; +	int their_gpio_release; +	unsigned int slew_delay_us; +	unsigned int wait_retry_us; +	unsigned int wait_free_us; +}; + + +/** + * i2c_arbitrator_select - claim the I2C bus + * + * Use the GPIO-based signalling protocol; return -EBUSY if we fail. + */ +static int i2c_arbitrator_select(struct i2c_adapter *adap, void *data, u32 chan) +{ +	const struct i2c_arbitrator_data *arb = data; +	unsigned long stop_retry, stop_time; + +	/* Start a round of trying to claim the bus */ +	stop_time = jiffies + usecs_to_jiffies(arb->wait_free_us) + 1; +	do { +		/* Indicate that we want to claim the bus */ +		gpio_set_value(arb->our_gpio, !arb->our_gpio_release); +		udelay(arb->slew_delay_us); + +		/* Wait for the other master to release it */ +		stop_retry = jiffies + usecs_to_jiffies(arb->wait_retry_us) + 1; +		while (time_before(jiffies, stop_retry)) { +			int gpio_val = !!gpio_get_value(arb->their_gpio); + +			if (gpio_val == arb->their_gpio_release) { +				/* We got it, so return */ +				return 0; +			} + +			usleep_range(50, 200); +		} + +		/* It didn't release, so give up, wait, and try again */ +		gpio_set_value(arb->our_gpio, arb->our_gpio_release); + +		usleep_range(arb->wait_retry_us, arb->wait_retry_us * 2); +	} while (time_before(jiffies, stop_time)); + +	/* Give up, release our claim */ +	gpio_set_value(arb->our_gpio, arb->our_gpio_release); +	udelay(arb->slew_delay_us); +	dev_err(&adap->dev, "Could not claim bus, timeout\n"); +	return -EBUSY; +} + +/** + * i2c_arbitrator_deselect - release the I2C bus + * + * Release the I2C bus using the GPIO-based signalling protocol. + */ +static int i2c_arbitrator_deselect(struct i2c_adapter *adap, void *data, +				   u32 chan) +{ +	const struct i2c_arbitrator_data *arb = data; + +	/* Release the bus and wait for the other master to notice */ +	gpio_set_value(arb->our_gpio, arb->our_gpio_release); +	udelay(arb->slew_delay_us); + +	return 0; +} + +static int i2c_arbitrator_probe(struct platform_device *pdev) +{ +	struct device *dev = &pdev->dev; +	struct device_node *np = dev->of_node; +	struct device_node *parent_np; +	struct i2c_arbitrator_data *arb; +	enum of_gpio_flags gpio_flags; +	unsigned long out_init; +	int ret; + +	/* We only support probing from device tree; no platform_data */ +	if (!np) { +		dev_err(dev, "Cannot find device tree node\n"); +		return -ENODEV; +	} +	if (dev->platform_data) { +		dev_err(dev, "Platform data is not supported\n"); +		return -EINVAL; +	} + +	arb = devm_kzalloc(dev, sizeof(*arb), GFP_KERNEL); +	if (!arb) { +		dev_err(dev, "Cannot allocate i2c_arbitrator_data\n"); +		return -ENOMEM; +	} +	platform_set_drvdata(pdev, arb); + +	/* Request GPIOs */ +	ret = of_get_named_gpio_flags(np, "our-claim-gpio", 0, &gpio_flags); +	if (!gpio_is_valid(ret)) { +		if (ret != -EPROBE_DEFER) +			dev_err(dev, "Error getting our-claim-gpio\n"); +		return ret; +	} +	arb->our_gpio = ret; +	arb->our_gpio_release = !!(gpio_flags & OF_GPIO_ACTIVE_LOW); +	out_init = (gpio_flags & OF_GPIO_ACTIVE_LOW) ? +		GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; +	ret = devm_gpio_request_one(dev, arb->our_gpio, out_init, +				    "our-claim-gpio"); +	if (ret) { +		if (ret != -EPROBE_DEFER) +			dev_err(dev, "Error requesting our-claim-gpio\n"); +		return ret; +	} + +	ret = of_get_named_gpio_flags(np, "their-claim-gpios", 0, &gpio_flags); +	if (!gpio_is_valid(ret)) { +		if (ret != -EPROBE_DEFER) +			dev_err(dev, "Error getting their-claim-gpio\n"); +		return ret; +	} +	arb->their_gpio = ret; +	arb->their_gpio_release = !!(gpio_flags & OF_GPIO_ACTIVE_LOW); +	ret = devm_gpio_request_one(dev, arb->their_gpio, GPIOF_IN, +				    "their-claim-gpio"); +	if (ret) { +		if (ret != -EPROBE_DEFER) +			dev_err(dev, "Error requesting their-claim-gpio\n"); +		return ret; +	} + +	/* At the moment we only support a single two master (us + 1 other) */ +	if (gpio_is_valid(of_get_named_gpio(np, "their-claim-gpios", 1))) { +		dev_err(dev, "Only one other master is supported\n"); +		return -EINVAL; +	} + +	/* Arbitration parameters */ +	if (of_property_read_u32(np, "slew-delay-us", &arb->slew_delay_us)) +		arb->slew_delay_us = 10; +	if (of_property_read_u32(np, "wait-retry-us", &arb->wait_retry_us)) +		arb->wait_retry_us = 3000; +	if (of_property_read_u32(np, "wait-free-us", &arb->wait_free_us)) +		arb->wait_free_us = 50000; + +	/* Find our parent */ +	parent_np = of_parse_phandle(np, "i2c-parent", 0); +	if (!parent_np) { +		dev_err(dev, "Cannot parse i2c-parent\n"); +		return -EINVAL; +	} +	arb->parent = of_find_i2c_adapter_by_node(parent_np); +	if (!arb->parent) { +		dev_err(dev, "Cannot find parent bus\n"); +		return -EINVAL; +	} + +	/* Actually add the mux adapter */ +	arb->child = i2c_add_mux_adapter(arb->parent, dev, arb, 0, 0, 0, +					 i2c_arbitrator_select, +					 i2c_arbitrator_deselect); +	if (!arb->child) { +		dev_err(dev, "Failed to add adapter\n"); +		ret = -ENODEV; +		i2c_put_adapter(arb->parent); +	} + +	return ret; +} + +static int i2c_arbitrator_remove(struct platform_device *pdev) +{ +	struct i2c_arbitrator_data *arb = platform_get_drvdata(pdev); + +	i2c_del_mux_adapter(arb->child); +	i2c_put_adapter(arb->parent); + +	return 0; +} + +static const struct of_device_id i2c_arbitrator_of_match[] = { +	{ .compatible = "i2c-arb-gpio-challenge", }, +	{}, +}; +MODULE_DEVICE_TABLE(of, i2c_arbitrator_of_match); + +static struct platform_driver i2c_arbitrator_driver = { +	.probe	= i2c_arbitrator_probe, +	.remove	= i2c_arbitrator_remove, +	.driver	= { +		.owner	= THIS_MODULE, +		.name	= "i2c-arb-gpio-challenge", +		.of_match_table = of_match_ptr(i2c_arbitrator_of_match), +	}, +}; + +module_platform_driver(i2c_arbitrator_driver); + +MODULE_DESCRIPTION("GPIO-based I2C Arbitration"); +MODULE_AUTHOR("Doug Anderson <dianders@chromium.org>"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:i2c-arb-gpio-challenge"); diff --git a/drivers/i2c/muxes/i2c-mux-gpio.c b/drivers/i2c/muxes/i2c-mux-gpio.c index abc2e55aa24..5a0ce0081dc 100644 --- a/drivers/i2c/muxes/i2c-mux-gpio.c +++ b/drivers/i2c/muxes/i2c-mux-gpio.c @@ -201,10 +201,21 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)  	for (i = 0; i < mux->data.n_gpios; i++) {  		ret = gpio_request(gpio_base + mux->data.gpios[i], "i2c-mux-gpio"); -		if (ret) +		if (ret) { +			dev_err(&pdev->dev, "Failed to request GPIO %d\n", +				mux->data.gpios[i]);  			goto err_request_gpio; -		gpio_direction_output(gpio_base + mux->data.gpios[i], -				      initial_state & (1 << i)); +		} + +		ret = gpio_direction_output(gpio_base + mux->data.gpios[i], +					    initial_state & (1 << i)); +		if (ret) { +			dev_err(&pdev->dev, +				"Failed to set direction of GPIO %d to output\n", +				mux->data.gpios[i]); +			i++;	/* gpio_request above succeeded, so must free */ +			goto err_request_gpio; +		}  	}  	for (i = 0; i < mux->data.n_values; i++) { diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c index 8e4387235b6..a531d801dbe 100644 --- a/drivers/i2c/muxes/i2c-mux-pca954x.c +++ b/drivers/i2c/muxes/i2c-mux-pca954x.c @@ -262,13 +262,11 @@ static int pca954x_remove(struct i2c_client *client)  {  	struct pca954x *data = i2c_get_clientdata(client);  	const struct chip_desc *chip = &chips[data->type]; -	int i, err; +	int i;  	for (i = 0; i < chip->nchans; ++i)  		if (data->virt_adaps[i]) { -			err = i2c_del_mux_adapter(data->virt_adaps[i]); -			if (err) -				return err; +			i2c_del_mux_adapter(data->virt_adaps[i]);  			data->virt_adaps[i] = NULL;  		}  |