diff options
Diffstat (limited to 'drivers/i2c/busses')
| -rw-r--r-- | drivers/i2c/busses/Kconfig | 1 | ||||
| -rw-r--r-- | drivers/i2c/busses/Makefile | 1 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-at91.c | 7 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-i801.c | 11 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-mxs.c | 188 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-nomadik.c | 9 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-omap.c | 36 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-s3c2410.c | 1 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-stub.c | 222 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-tegra.c | 2 | 
10 files changed, 55 insertions, 423 deletions
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 65dd599a026..e9df4612b7e 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -81,7 +81,6 @@ config I2C_I801  	tristate "Intel 82801 (ICH/PCH)"  	depends on PCI  	select CHECK_SIGNATURE if X86 && DMI -	select GPIOLIB if I2C_MUX  	help  	  If you say yes to this option, support will be included for the Intel  	  801 family of mainboard I2C interfaces.  Specifically, the following diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 2d33d62952c..395b516ffa0 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -85,7 +85,6 @@ obj-$(CONFIG_I2C_ACORN)		+= i2c-acorn.o  obj-$(CONFIG_I2C_ELEKTOR)	+= i2c-elektor.o  obj-$(CONFIG_I2C_PCA_ISA)	+= i2c-pca-isa.o  obj-$(CONFIG_I2C_SIBYTE)	+= i2c-sibyte.o -obj-$(CONFIG_I2C_STUB)		+= i2c-stub.o  obj-$(CONFIG_SCx200_ACB)	+= scx200_acb.o  obj-$(CONFIG_SCx200_I2C)	+= scx200_i2c.o diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c index aa59a254be2..c02bf208084 100644 --- a/drivers/i2c/busses/i2c-at91.c +++ b/drivers/i2c/busses/i2c-at91.c @@ -39,6 +39,7 @@  #define	AT91_TWI_STOP		0x0002	/* Send a Stop Condition */  #define	AT91_TWI_MSEN		0x0004	/* Master Transfer Enable */  #define	AT91_TWI_SVDIS		0x0020	/* Slave Transfer Disable */ +#define	AT91_TWI_QUICK		0x0040	/* SMBus quick command */  #define	AT91_TWI_SWRST		0x0080	/* Software Reset */  #define	AT91_TWI_MMR		0x0004	/* Master Mode Register */ @@ -212,7 +213,11 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)  	INIT_COMPLETION(dev->cmd_complete);  	dev->transfer_status = 0; -	if (dev->msg->flags & I2C_M_RD) { + +	if (!dev->buf_len) { +		at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_QUICK); +		at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_TXCOMP); +	} else if (dev->msg->flags & I2C_M_RD) {  		unsigned start_flags = AT91_TWI_START;  		if (at91_twi_read(dev, AT91_TWI_SR) & AT91_TWI_RXRDY) { diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 37793156bd9..6abc00d5988 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -82,7 +82,8 @@  #include <linux/wait.h>  #include <linux/err.h> -#if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE +#if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \ +		defined CONFIG_DMI  #include <linux/gpio.h>  #include <linux/i2c-mux-gpio.h>  #include <linux/platform_device.h> @@ -192,7 +193,8 @@ struct i801_priv {  	int len;  	u8 *data; -#if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE +#if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \ +		defined CONFIG_DMI  	const struct i801_mux_config *mux_drvdata;  	struct platform_device *mux_pdev;  #endif @@ -921,7 +923,8 @@ static void __init input_apanel_init(void) {}  static void __devinit i801_probe_optional_slaves(struct i801_priv *priv) {}  #endif	/* CONFIG_X86 && CONFIG_DMI */ -#if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE +#if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \ +		defined CONFIG_DMI  static struct i801_mux_config i801_mux_config_asus_z8_d12 = {  	.gpio_chip = "gpio_ich",  	.values = { 0x02, 0x03 }, @@ -1059,7 +1062,7 @@ static unsigned int __devinit i801_get_adapter_class(struct i801_priv *priv)  	id = dmi_first_match(mux_dmi_table);  	if (id) { -		/* Remove from branch classes from trunk */ +		/* Remove branch classes from trunk */  		mux_config = id->driver_data;  		for (i = 0; i < mux_config->n_values; i++)  			class &= ~mux_config->classes[i]; diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c index 1f58197062c..0670da79ee5 100644 --- a/drivers/i2c/busses/i2c-mxs.c +++ b/drivers/i2c/busses/i2c-mxs.c @@ -1,7 +1,7 @@  /*   * Freescale MXS I2C bus driver   * - * Copyright (C) 2011 Wolfram Sang, Pengutronix e.K. + * Copyright (C) 2011-2012 Wolfram Sang, Pengutronix e.K.   *   * based on a (non-working) driver which was:   * @@ -35,10 +35,6 @@  #define DRIVER_NAME "mxs-i2c" -static bool use_pioqueue; -module_param(use_pioqueue, bool, 0); -MODULE_PARM_DESC(use_pioqueue, "Use PIOQUEUE mode for transfer instead of DMA"); -  #define MXS_I2C_CTRL0		(0x00)  #define MXS_I2C_CTRL0_SET	(0x04) @@ -75,23 +71,6 @@ MODULE_PARM_DESC(use_pioqueue, "Use PIOQUEUE mode for transfer instead of DMA");  				 MXS_I2C_CTRL1_SLAVE_STOP_IRQ | \  				 MXS_I2C_CTRL1_SLAVE_IRQ) -#define MXS_I2C_QUEUECTRL	(0x60) -#define MXS_I2C_QUEUECTRL_SET	(0x64) -#define MXS_I2C_QUEUECTRL_CLR	(0x68) - -#define MXS_I2C_QUEUECTRL_QUEUE_RUN		0x20 -#define MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE	0x04 - -#define MXS_I2C_QUEUESTAT	(0x70) -#define MXS_I2C_QUEUESTAT_RD_QUEUE_EMPTY        0x00002000 -#define MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK	0x0000001F - -#define MXS_I2C_QUEUECMD	(0x80) - -#define MXS_I2C_QUEUEDATA	(0x90) - -#define MXS_I2C_DATA		(0xa0) -  #define MXS_CMD_I2C_SELECT	(MXS_I2C_CTRL0_RETAIN_CLOCK |	\  				 MXS_I2C_CTRL0_PRE_SEND_START |	\ @@ -153,7 +132,6 @@ struct mxs_i2c_dev {  	const struct mxs_i2c_speed_config *speed;  	/* DMA support components */ -	bool				dma_mode;  	int				dma_channel;  	struct dma_chan         	*dmach;  	struct mxs_dma_data		dma_data; @@ -172,99 +150,6 @@ static void mxs_i2c_reset(struct mxs_i2c_dev *i2c)  	writel(i2c->speed->timing2, i2c->regs + MXS_I2C_TIMING2);  	writel(MXS_I2C_IRQ_MASK << 8, i2c->regs + MXS_I2C_CTRL1_SET); -	if (i2c->dma_mode) -		writel(MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE, -			i2c->regs + MXS_I2C_QUEUECTRL_CLR); -	else -		writel(MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE, -			i2c->regs + MXS_I2C_QUEUECTRL_SET); -} - -static void mxs_i2c_pioq_setup_read(struct mxs_i2c_dev *i2c, u8 addr, int len, -					int flags) -{ -	u32 data; - -	writel(MXS_CMD_I2C_SELECT, i2c->regs + MXS_I2C_QUEUECMD); - -	data = (addr << 1) | I2C_SMBUS_READ; -	writel(data, i2c->regs + MXS_I2C_DATA); - -	data = MXS_CMD_I2C_READ | MXS_I2C_CTRL0_XFER_COUNT(len) | flags; -	writel(data, i2c->regs + MXS_I2C_QUEUECMD); -} - -static void mxs_i2c_pioq_setup_write(struct mxs_i2c_dev *i2c, -				    u8 addr, u8 *buf, int len, int flags) -{ -	u32 data; -	int i, shifts_left; - -	data = MXS_CMD_I2C_WRITE | MXS_I2C_CTRL0_XFER_COUNT(len + 1) | flags; -	writel(data, i2c->regs + MXS_I2C_QUEUECMD); - -	/* -	 * We have to copy the slave address (u8) and buffer (arbitrary number -	 * of u8) into the data register (u32). To achieve that, the u8 are put -	 * into the MSBs of 'data' which is then shifted for the next u8. When -	 * appropriate, 'data' is written to MXS_I2C_DATA. So, the first u32 -	 * looks like this: -	 * -	 *  3          2          1          0 -	 * 10987654|32109876|54321098|76543210 -	 * --------+--------+--------+-------- -	 * buffer+2|buffer+1|buffer+0|slave_addr -	 */ - -	data = ((addr << 1) | I2C_SMBUS_WRITE) << 24; - -	for (i = 0; i < len; i++) { -		data >>= 8; -		data |= buf[i] << 24; -		if ((i & 3) == 2) -			writel(data, i2c->regs + MXS_I2C_DATA); -	} - -	/* Write out the remaining bytes if any */ -	shifts_left = 24 - (i & 3) * 8; -	if (shifts_left) -		writel(data >> shifts_left, i2c->regs + MXS_I2C_DATA); -} - -/* - * TODO: should be replaceable with a waitqueue and RD_QUEUE_IRQ (setting the - * rd_threshold to 1). Couldn't get this to work, though. - */ -static int mxs_i2c_wait_for_data(struct mxs_i2c_dev *i2c) -{ -	unsigned long timeout = jiffies + msecs_to_jiffies(1000); - -	while (readl(i2c->regs + MXS_I2C_QUEUESTAT) -			& MXS_I2C_QUEUESTAT_RD_QUEUE_EMPTY) { -			if (time_after(jiffies, timeout)) -				return -ETIMEDOUT; -			cond_resched(); -	} - -	return 0; -} - -static int mxs_i2c_finish_read(struct mxs_i2c_dev *i2c, u8 *buf, int len) -{ -	u32 uninitialized_var(data); -	int i; - -	for (i = 0; i < len; i++) { -		if ((i & 3) == 0) { -			if (mxs_i2c_wait_for_data(i2c)) -				return -ETIMEDOUT; -			data = readl(i2c->regs + MXS_I2C_QUEUEDATA); -		} -		buf[i] = data & 0xff; -		data >>= 8; -	} - -	return 0;  }  static void mxs_i2c_dma_finish(struct mxs_i2c_dev *i2c) @@ -402,12 +287,14 @@ read_init_dma_fail:  select_init_dma_fail:  	dma_unmap_sg(i2c->dev, &i2c->sg_io[0], 1, DMA_TO_DEVICE);  select_init_pio_fail: +	dmaengine_terminate_all(i2c->dmach);  	return -EINVAL;  /* Write failpath. */  write_init_dma_fail:  	dma_unmap_sg(i2c->dev, i2c->sg_io, 2, DMA_TO_DEVICE);  write_init_pio_fail: +	dmaengine_terminate_all(i2c->dmach);  	return -EINVAL;  } @@ -432,39 +319,17 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,  	init_completion(&i2c->cmd_complete);  	i2c->cmd_err = 0; -	if (i2c->dma_mode) { -		ret = mxs_i2c_dma_setup_xfer(adap, msg, flags); -		if (ret) -			return ret; -	} else { -		if (msg->flags & I2C_M_RD) { -			mxs_i2c_pioq_setup_read(i2c, msg->addr, -						msg->len, flags); -		} else { -			mxs_i2c_pioq_setup_write(i2c, msg->addr, msg->buf, -						msg->len, flags); -		} - -		writel(MXS_I2C_QUEUECTRL_QUEUE_RUN, -			i2c->regs + MXS_I2C_QUEUECTRL_SET); -	} +	ret = mxs_i2c_dma_setup_xfer(adap, msg, flags); +	if (ret) +		return ret;  	ret = wait_for_completion_timeout(&i2c->cmd_complete,  						msecs_to_jiffies(1000));  	if (ret == 0)  		goto timeout; -	if (!i2c->dma_mode && !i2c->cmd_err && (msg->flags & I2C_M_RD)) { -		ret = mxs_i2c_finish_read(i2c, msg->buf, msg->len); -		if (ret) -			goto timeout; -	} -  	if (i2c->cmd_err == -ENXIO)  		mxs_i2c_reset(i2c); -	else -		writel(MXS_I2C_QUEUECTRL_QUEUE_RUN, -				i2c->regs + MXS_I2C_QUEUECTRL_CLR);  	dev_dbg(i2c->dev, "Done with err=%d\n", i2c->cmd_err); @@ -472,8 +337,7 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,  timeout:  	dev_dbg(i2c->dev, "Timeout!\n"); -	if (i2c->dma_mode) -		mxs_i2c_dma_finish(i2c); +	mxs_i2c_dma_finish(i2c);  	mxs_i2c_reset(i2c);  	return -ETIMEDOUT;  } @@ -502,7 +366,6 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id)  {  	struct mxs_i2c_dev *i2c = dev_id;  	u32 stat = readl(i2c->regs + MXS_I2C_CTRL1) & MXS_I2C_IRQ_MASK; -	bool is_last_cmd;  	if (!stat)  		return IRQ_NONE; @@ -515,14 +378,6 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id)  		/* MXS_I2C_CTRL1_OVERSIZE_XFER_TERM_IRQ is only for slaves */  		i2c->cmd_err = -EIO; -	if (!i2c->dma_mode) { -		is_last_cmd = (readl(i2c->regs + MXS_I2C_QUEUESTAT) & -			MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK) == 0; - -		if (is_last_cmd || i2c->cmd_err) -			complete(&i2c->cmd_complete); -	} -  	writel(stat, i2c->regs + MXS_I2C_CTRL1_CLR);  	return IRQ_HANDLED; @@ -556,23 +411,14 @@ static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c)  	int ret;  	/* -	 * The MXS I2C DMA mode is prefered and enabled by default. -	 * The PIO mode is still supported, but should be used only -	 * for debuging purposes etc. -	 */ -	i2c->dma_mode = !use_pioqueue; -	if (!i2c->dma_mode) -		dev_info(dev, "Using PIOQUEUE mode for I2C transfers!\n"); - -	/*  	 * TODO: This is a temporary solution and should be changed  	 * to use generic DMA binding later when the helpers get in.  	 */  	ret = of_property_read_u32(node, "fsl,i2c-dma-channel",  				   &i2c->dma_channel);  	if (ret) { -		dev_warn(dev, "Failed to get DMA channel, using PIOQUEUE!\n"); -		i2c->dma_mode = 0; +		dev_err(dev, "Failed to get DMA channel!\n"); +		return -ENODEV;  	}  	ret = of_property_read_u32(node, "clock-frequency", &speed); @@ -634,15 +480,13 @@ static int __devinit mxs_i2c_probe(struct platform_device *pdev)  	}  	/* Setup the DMA */ -	if (i2c->dma_mode) { -		dma_cap_zero(mask); -		dma_cap_set(DMA_SLAVE, mask); -		i2c->dma_data.chan_irq = dmairq; -		i2c->dmach = dma_request_channel(mask, mxs_i2c_dma_filter, i2c); -		if (!i2c->dmach) { -			dev_err(dev, "Failed to request dma\n"); -			return -ENODEV; -		} +	dma_cap_zero(mask); +	dma_cap_set(DMA_SLAVE, mask); +	i2c->dma_data.chan_irq = dmairq; +	i2c->dmach = dma_request_channel(mask, mxs_i2c_dma_filter, i2c); +	if (!i2c->dmach) { +		dev_err(dev, "Failed to request dma\n"); +		return -ENODEV;  	}  	platform_set_drvdata(pdev, i2c); diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c index 698d7acb0f0..02c3115a2df 100644 --- a/drivers/i2c/busses/i2c-nomadik.c +++ b/drivers/i2c/busses/i2c-nomadik.c @@ -644,7 +644,11 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,  	pm_runtime_get_sync(&dev->adev->dev); -	clk_enable(dev->clk); +	status = clk_prepare_enable(dev->clk); +	if (status) { +		dev_err(&dev->adev->dev, "can't prepare_enable clock\n"); +		goto out_clk; +	}  	status = init_hw(dev);  	if (status) @@ -671,7 +675,8 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,  	}  out: -	clk_disable(dev->clk); +	clk_disable_unprepare(dev->clk); +out_clk:  	pm_runtime_put_sync(&dev->adev->dev);  	dev->busy = false; diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index db31eaed6ea..3525c9e62cb 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -43,7 +43,6 @@  #include <linux/slab.h>  #include <linux/i2c-omap.h>  #include <linux/pm_runtime.h> -#include <linux/pm_qos.h>  /* I2C controller revisions */  #define OMAP_I2C_OMAP1_REV_2		0x20 @@ -187,8 +186,9 @@ struct omap_i2c_dev {  	int			reg_shift;      /* bit shift for I2C register addresses */  	struct completion	cmd_complete;  	struct resource		*ioarea; -	u32			latency;	/* maximum MPU wkup latency */ -	struct pm_qos_request	pm_qos_request; +	u32			latency;	/* maximum mpu wkup latency */ +	void			(*set_mpu_wkup_lat)(struct device *dev, +						    long latency);  	u32			speed;		/* Speed of bus in kHz */  	u32			dtrev;		/* extra revision from DT */  	u32			flags; @@ -494,7 +494,9 @@ static void omap_i2c_resize_fifo(struct omap_i2c_dev *dev, u8 size, bool is_rx)  		dev->b_hw = 1; /* Enable hardware fixes */  	/* calculate wakeup latency constraint for MPU */ -	dev->latency = (1000000 * dev->threshold) / (1000 * dev->speed / 8); +	if (dev->set_mpu_wkup_lat != NULL) +		dev->latency = (1000000 * dev->threshold) / +			(1000 * dev->speed / 8);  }  /* @@ -522,6 +524,9 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,  	dev->buf = msg->buf;  	dev->buf_len = msg->len; +	/* make sure writes to dev->buf_len are ordered */ +	barrier(); +  	omap_i2c_write_reg(dev, OMAP_I2C_CNT_REG, dev->buf_len);  	/* Clear the FIFO Buffers */ @@ -579,7 +584,6 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,  	 */  	timeout = wait_for_completion_timeout(&dev->cmd_complete,  						OMAP_I2C_TIMEOUT); -	dev->buf_len = 0;  	if (timeout == 0) {  		dev_err(dev->dev, "controller timed out\n");  		omap_i2c_init(dev); @@ -629,16 +633,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)  	if (r < 0)  		goto out; -	/* -	 * When waiting for completion of a i2c transfer, we need to -	 * set a wake up latency constraint for the MPU. This is to -	 * ensure quick enough wakeup from idle, when transfer -	 * completes. -	 */ -	if (dev->latency) -		pm_qos_add_request(&dev->pm_qos_request, -				   PM_QOS_CPU_DMA_LATENCY, -				   dev->latency); +	if (dev->set_mpu_wkup_lat != NULL) +		dev->set_mpu_wkup_lat(dev->dev, dev->latency);  	for (i = 0; i < num; i++) {  		r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1))); @@ -646,8 +642,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)  			break;  	} -	if (dev->latency) -		pm_qos_remove_request(&dev->pm_qos_request); +	if (dev->set_mpu_wkup_lat != NULL) +		dev->set_mpu_wkup_lat(dev->dev, -1);  	if (r == 0)  		r = num; @@ -1104,6 +1100,7 @@ omap_i2c_probe(struct platform_device *pdev)  	} else if (pdata != NULL) {  		dev->speed = pdata->clkrate;  		dev->flags = pdata->flags; +		dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;  		dev->dtrev = pdata->rev;  	} @@ -1159,8 +1156,9 @@ omap_i2c_probe(struct platform_device *pdev)  			dev->b_hw = 1; /* Enable hardware fixes */  		/* calculate wakeup latency constraint for MPU */ -		dev->latency = (1000000 * dev->fifo_size) / -			       (1000 * dev->speed / 8); +		if (dev->set_mpu_wkup_lat != NULL) +			dev->latency = (1000000 * dev->fifo_size) / +				       (1000 * dev->speed / 8);  	}  	/* reset ASAP, clearing any IRQs */ diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 3e0335f1fc6..9d902725bac 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -806,6 +806,7 @@ static int s3c24xx_i2c_parse_dt_gpio(struct s3c24xx_i2c *i2c)  			dev_err(i2c->dev, "invalid gpio[%d]: %d\n", idx, gpio);  			goto free_gpio;  		} +		i2c->gpios[idx] = gpio;  		ret = gpio_request(gpio, "i2c-bus");  		if (ret) { diff --git a/drivers/i2c/busses/i2c-stub.c b/drivers/i2c/busses/i2c-stub.c deleted file mode 100644 index b1b3447942c..00000000000 --- a/drivers/i2c/busses/i2c-stub.c +++ /dev/null @@ -1,222 +0,0 @@ -/* -    i2c-stub.c - I2C/SMBus chip emulator - -    Copyright (c) 2004 Mark M. Hoffman <mhoffman@lightlink.com> -    Copyright (C) 2007 Jean Delvare <khali@linux-fr.org> - -    This program is free software; you can redistribute it and/or modify -    it under the terms of the GNU General Public License as published by -    the Free Software Foundation; either version 2 of the License, or -    (at your option) any later version. - -    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. - -    You should have received a copy of the GNU General Public License -    along with this program; if not, write to the Free Software -    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#define DEBUG 1 - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/errno.h> -#include <linux/i2c.h> - -#define MAX_CHIPS 10 -#define STUB_FUNC (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | \ -		   I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | \ -		   I2C_FUNC_SMBUS_I2C_BLOCK) - -static unsigned short chip_addr[MAX_CHIPS]; -module_param_array(chip_addr, ushort, NULL, S_IRUGO); -MODULE_PARM_DESC(chip_addr, -		 "Chip addresses (up to 10, between 0x03 and 0x77)"); - -static unsigned long functionality = STUB_FUNC; -module_param(functionality, ulong, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(functionality, "Override functionality bitfield"); - -struct stub_chip { -	u8 pointer; -	u16 words[256];		/* Byte operations use the LSB as per SMBus -				   specification */ -}; - -static struct stub_chip *stub_chips; - -/* Return negative errno on error. */ -static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags, -	char read_write, u8 command, int size, union i2c_smbus_data * data) -{ -	s32 ret; -	int i, len; -	struct stub_chip *chip = NULL; - -	/* Search for the right chip */ -	for (i = 0; i < MAX_CHIPS && chip_addr[i]; i++) { -		if (addr == chip_addr[i]) { -			chip = stub_chips + i; -			break; -		} -	} -	if (!chip) -		return -ENODEV; - -	switch (size) { - -	case I2C_SMBUS_QUICK: -		dev_dbg(&adap->dev, "smbus quick - addr 0x%02x\n", addr); -		ret = 0; -		break; - -	case I2C_SMBUS_BYTE: -		if (read_write == I2C_SMBUS_WRITE) { -			chip->pointer = command; -			dev_dbg(&adap->dev, "smbus byte - addr 0x%02x, " -					"wrote 0x%02x.\n", -					addr, command); -		} else { -			data->byte = chip->words[chip->pointer++] & 0xff; -			dev_dbg(&adap->dev, "smbus byte - addr 0x%02x, " -					"read  0x%02x.\n", -					addr, data->byte); -		} - -		ret = 0; -		break; - -	case I2C_SMBUS_BYTE_DATA: -		if (read_write == I2C_SMBUS_WRITE) { -			chip->words[command] &= 0xff00; -			chip->words[command] |= data->byte; -			dev_dbg(&adap->dev, "smbus byte data - addr 0x%02x, " -					"wrote 0x%02x at 0x%02x.\n", -					addr, data->byte, command); -		} else { -			data->byte = chip->words[command] & 0xff; -			dev_dbg(&adap->dev, "smbus byte data - addr 0x%02x, " -					"read  0x%02x at 0x%02x.\n", -					addr, data->byte, command); -		} -		chip->pointer = command + 1; - -		ret = 0; -		break; - -	case I2C_SMBUS_WORD_DATA: -		if (read_write == I2C_SMBUS_WRITE) { -			chip->words[command] = data->word; -			dev_dbg(&adap->dev, "smbus word data - addr 0x%02x, " -					"wrote 0x%04x at 0x%02x.\n", -					addr, data->word, command); -		} else { -			data->word = chip->words[command]; -			dev_dbg(&adap->dev, "smbus word data - addr 0x%02x, " -					"read  0x%04x at 0x%02x.\n", -					addr, data->word, command); -		} - -		ret = 0; -		break; - -	case I2C_SMBUS_I2C_BLOCK_DATA: -		len = data->block[0]; -		if (read_write == I2C_SMBUS_WRITE) { -			for (i = 0; i < len; i++) { -				chip->words[command + i] &= 0xff00; -				chip->words[command + i] |= data->block[1 + i]; -			} -			dev_dbg(&adap->dev, "i2c block data - addr 0x%02x, " -					"wrote %d bytes at 0x%02x.\n", -					addr, len, command); -		} else { -			for (i = 0; i < len; i++) { -				data->block[1 + i] = -					chip->words[command + i] & 0xff; -			} -			dev_dbg(&adap->dev, "i2c block data - addr 0x%02x, " -					"read  %d bytes at 0x%02x.\n", -					addr, len, command); -		} - -		ret = 0; -		break; - -	default: -		dev_dbg(&adap->dev, "Unsupported I2C/SMBus command\n"); -		ret = -EOPNOTSUPP; -		break; -	} /* switch (size) */ - -	return ret; -} - -static u32 stub_func(struct i2c_adapter *adapter) -{ -	return STUB_FUNC & functionality; -} - -static const struct i2c_algorithm smbus_algorithm = { -	.functionality	= stub_func, -	.smbus_xfer	= stub_xfer, -}; - -static struct i2c_adapter stub_adapter = { -	.owner		= THIS_MODULE, -	.class		= I2C_CLASS_HWMON | I2C_CLASS_SPD, -	.algo		= &smbus_algorithm, -	.name		= "SMBus stub driver", -}; - -static int __init i2c_stub_init(void) -{ -	int i, ret; - -	if (!chip_addr[0]) { -		printk(KERN_ERR "i2c-stub: Please specify a chip address\n"); -		return -ENODEV; -	} - -	for (i = 0; i < MAX_CHIPS && chip_addr[i]; i++) { -		if (chip_addr[i] < 0x03 || chip_addr[i] > 0x77) { -			printk(KERN_ERR "i2c-stub: Invalid chip address " -			       "0x%02x\n", chip_addr[i]); -			return -EINVAL; -		} - -		printk(KERN_INFO "i2c-stub: Virtual chip at 0x%02x\n", -		       chip_addr[i]); -	} - -	/* Allocate memory for all chips at once */ -	stub_chips = kzalloc(i * sizeof(struct stub_chip), GFP_KERNEL); -	if (!stub_chips) { -		printk(KERN_ERR "i2c-stub: Out of memory\n"); -		return -ENOMEM; -	} - -	ret = i2c_add_adapter(&stub_adapter); -	if (ret) -		kfree(stub_chips); -	return ret; -} - -static void __exit i2c_stub_exit(void) -{ -	i2c_del_adapter(&stub_adapter); -	kfree(stub_chips); -} - -MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>"); -MODULE_DESCRIPTION("I2C stub driver"); -MODULE_LICENSE("GPL"); - -module_init(i2c_stub_init); -module_exit(i2c_stub_exit); - diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index f981ac4e678..dcea77bf6f5 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -742,7 +742,7 @@ static int __devinit tegra_i2c_probe(struct platform_device *pdev)  	}  	ret = devm_request_irq(&pdev->dev, i2c_dev->irq, -			tegra_i2c_isr, 0, pdev->name, i2c_dev); +			tegra_i2c_isr, 0, dev_name(&pdev->dev), i2c_dev);  	if (ret) {  		dev_err(&pdev->dev, "Failed to request irq %i\n", i2c_dev->irq);  		return ret;  |