diff options
Diffstat (limited to 'drivers/i2c')
| -rw-r--r-- | drivers/i2c/algos/i2c-algo-pca.c | 27 | ||||
| -rw-r--r-- | drivers/i2c/busses/Kconfig | 27 | ||||
| -rw-r--r-- | drivers/i2c/busses/Makefile | 1 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-at91.c | 653 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-davinci.c | 58 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-imx.c | 6 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-mpc.c | 18 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-nomadik.c | 52 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-omap.c | 470 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-rcar.c | 709 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-s3c2410.c | 18 | 
11 files changed, 1580 insertions, 459 deletions
diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c index 6f5f98d69af..f892a424009 100644 --- a/drivers/i2c/algos/i2c-algo-pca.c +++ b/drivers/i2c/algos/i2c-algo-pca.c @@ -46,14 +46,19 @@ static int i2c_debug;  #define pca_set_con(adap, val) pca_outw(adap, I2C_PCA_CON, val)  #define pca_get_con(adap) pca_inw(adap, I2C_PCA_CON)  #define pca_wait(adap) adap->wait_for_completion(adap->data) -#define pca_reset(adap) adap->reset_chip(adap->data) -static void pca9665_reset(void *pd) +static void pca_reset(struct i2c_algo_pca_data *adap)  { -	struct i2c_algo_pca_data *adap = pd; -	pca_outw(adap, I2C_PCA_INDPTR, I2C_PCA_IPRESET); -	pca_outw(adap, I2C_PCA_IND, 0xA5); -	pca_outw(adap, I2C_PCA_IND, 0x5A); +	if (adap->chip == I2C_PCA_CHIP_9665) { +		/* Ignore the reset function from the module, +		 * we can use the parallel bus reset. +		 */ +		pca_outw(adap, I2C_PCA_INDPTR, I2C_PCA_IPRESET); +		pca_outw(adap, I2C_PCA_IND, 0xA5); +		pca_outw(adap, I2C_PCA_IND, 0x5A); +	} else { +		adap->reset_chip(adap->data); +	}  }  /* @@ -378,11 +383,12 @@ static unsigned int pca_probe_chip(struct i2c_adapter *adap)  	pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IADR);  	if (pca_inw(pca_data, I2C_PCA_IND) == 0xAA) {  		printk(KERN_INFO "%s: PCA9665 detected.\n", adap->name); -		return I2C_PCA_CHIP_9665; +		pca_data->chip = I2C_PCA_CHIP_9665;  	} else {  		printk(KERN_INFO "%s: PCA9564 detected.\n", adap->name); -		return I2C_PCA_CHIP_9564; +		pca_data->chip = I2C_PCA_CHIP_9564;  	} +	return pca_data->chip;  }  static int pca_init(struct i2c_adapter *adap) @@ -456,11 +462,6 @@ static int pca_init(struct i2c_adapter *adap)  		 */  		int raise_fall_time; -		/* Ignore the reset function from the module, -		 * we can use the parallel bus reset -		 */ -		pca_data->reset_chip = pca9665_reset; -  		if (pca_data->i2c_clock > 1265800) {  			printk(KERN_WARNING "%s: I2C clock speed too high."  				" Using 1265.8kHz.\n", adap->name); diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 970a1612e79..61f3ab6a1ad 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -291,18 +291,21 @@ comment "I2C system bus drivers (mostly embedded / system-on-chip)"  config I2C_AT91  	tristate "Atmel AT91 I2C Two-Wire interface (TWI)" -	depends on ARCH_AT91 && EXPERIMENTAL && BROKEN +	depends on ARCH_AT91 && EXPERIMENTAL  	help  	  This supports the use of the I2C interface on Atmel AT91  	  processors. -	  This driver is BROKEN because the controller which it uses -	  will easily trigger RX overrun and TX underrun errors.  Using -	  low I2C clock rates may partially work around those issues -	  on some systems.  Another serious problem is that there is no -	  documented way to issue repeated START conditions, as needed +	  A serious problem is that there is no documented way to issue +	  repeated START conditions for more than two messages, as needed  	  to support combined I2C messages.  Use the i2c-gpio driver -	  unless your system can cope with those limitations. +	  unless your system can cope with this limitation. + +	  Caution! at91rm9200, at91sam9261, at91sam9260, at91sam9263 devices +	  don't have clock stretching in transmission mode. For that reason, +	  you can encounter underrun issues causing premature stop sendings if +	  the latency to fill the transmission register is too long. If you +	  are facing this situation, use the i2c-gpio driver.  config I2C_AU1550  	tristate "Au1550/Au1200/Au1300 SMBus interface" @@ -715,6 +718,16 @@ config I2C_XLR  	  This driver can also be built as a module.  If so, the module  	  will be called i2c-xlr. +config I2C_RCAR +	tristate "Renesas R-Car I2C Controller" +	depends on ARCH_SHMOBILE && I2C +	help +	  If you say yes to this option, support will be included for the +	  R-Car I2C controller. + +	  This driver can also be built as a module.  If so, the module +	  will be called i2c-rcar. +  comment "External I2C/SMBus adapter drivers"  config I2C_DIOLAN_U2C diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 37c4182cc98..2d33d62952c 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -71,6 +71,7 @@ obj-$(CONFIG_I2C_VERSATILE)	+= i2c-versatile.o  obj-$(CONFIG_I2C_OCTEON)	+= i2c-octeon.o  obj-$(CONFIG_I2C_XILINX)	+= i2c-xiic.o  obj-$(CONFIG_I2C_XLR)		+= i2c-xlr.o +obj-$(CONFIG_I2C_RCAR)		+= i2c-rcar.o  # External I2C/SMBus adapter drivers  obj-$(CONFIG_I2C_DIOLAN_U2C)	+= i2c-diolan-u2c.o diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c index e24484beef0..aa59a254be2 100644 --- a/drivers/i2c/busses/i2c-at91.c +++ b/drivers/i2c/busses/i2c-at91.c @@ -1,315 +1,554 @@  /* -    i2c Support for Atmel's AT91 Two-Wire Interface (TWI) - -    Copyright (C) 2004 Rick Bronson -    Converted to 2.6 by Andrew Victor <andrew@sanpeople.com> - -    Borrowed heavily from original work by: -    Copyright (C) 2000 Philip Edelbrock <phil@stimpy.netroedge.com> - -    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. -*/ + *  i2c Support for Atmel's AT91 Two-Wire Interface (TWI) + * + *  Copyright (C) 2011 Weinmann Medical GmbH + *  Author: Nikolaus Voss <n.voss@weinmann.de> + * + *  Evolved from original work by: + *  Copyright (C) 2004 Rick Bronson + *  Converted to 2.6 by Andrew Victor <andrew@sanpeople.com> + * + *  Borrowed heavily from original work by: + *  Copyright (C) 2000 Philip Edelbrock <phil@stimpy.netroedge.com> + * + *  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. + */ -#include <linux/module.h> -#include <linux/kernel.h> +#include <linux/clk.h> +#include <linux/completion.h>  #include <linux/err.h> -#include <linux/slab.h> -#include <linux/types.h> -#include <linux/delay.h>  #include <linux/i2c.h> -#include <linux/init.h> -#include <linux/clk.h> -#include <linux/platform_device.h> +#include <linux/interrupt.h>  #include <linux/io.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/of_i2c.h> +#include <linux/platform_device.h> +#include <linux/slab.h> + +#define TWI_CLK_HZ		100000			/* max 400 Kbits/s */ +#define AT91_I2C_TIMEOUT	msecs_to_jiffies(100)	/* transfer timeout */ + +/* AT91 TWI register definitions */ +#define	AT91_TWI_CR		0x0000	/* Control Register */ +#define	AT91_TWI_START		0x0001	/* Send a Start Condition */ +#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_SWRST		0x0080	/* Software Reset */ + +#define	AT91_TWI_MMR		0x0004	/* Master Mode Register */ +#define	AT91_TWI_IADRSZ_1	0x0100	/* Internal Device Address Size */ +#define	AT91_TWI_MREAD		0x1000	/* Master Read Direction */ -#include <mach/at91_twi.h> -#include <mach/board.h> -#include <mach/cpu.h> +#define	AT91_TWI_IADR		0x000c	/* Internal Address Register */ -#define TWI_CLOCK		100000		/* Hz. max 400 Kbits/sec */ +#define	AT91_TWI_CWGR		0x0010	/* Clock Waveform Generator Reg */ +#define	AT91_TWI_SR		0x0020	/* Status Register */ +#define	AT91_TWI_TXCOMP		0x0001	/* Transmission Complete */ +#define	AT91_TWI_RXRDY		0x0002	/* Receive Holding Register Ready */ +#define	AT91_TWI_TXRDY		0x0004	/* Transmit Holding Register Ready */ + +#define	AT91_TWI_OVRE		0x0040	/* Overrun Error */ +#define	AT91_TWI_UNRE		0x0080	/* Underrun Error */ +#define	AT91_TWI_NACK		0x0100	/* Not Acknowledged */ + +#define	AT91_TWI_IER		0x0024	/* Interrupt Enable Register */ +#define	AT91_TWI_IDR		0x0028	/* Interrupt Disable Register */ +#define	AT91_TWI_IMR		0x002c	/* Interrupt Mask Register */ +#define	AT91_TWI_RHR		0x0030	/* Receive Holding Register */ +#define	AT91_TWI_THR		0x0034	/* Transmit Holding Register */ + +struct at91_twi_pdata { +	unsigned	clk_max_div; +	unsigned	clk_offset; +	bool		has_unre_flag; +}; -static struct clk *twi_clk; -static void __iomem *twi_base; +struct at91_twi_dev { +	struct device		*dev; +	void __iomem		*base; +	struct completion	cmd_complete; +	struct clk		*clk; +	u8			*buf; +	size_t			buf_len; +	struct i2c_msg		*msg; +	int			irq; +	unsigned		transfer_status; +	struct i2c_adapter	adapter; +	unsigned		twi_cwgr_reg; +	struct at91_twi_pdata	*pdata; +}; + +static unsigned at91_twi_read(struct at91_twi_dev *dev, unsigned reg) +{ +	return readl_relaxed(dev->base + reg); +} + +static void at91_twi_write(struct at91_twi_dev *dev, unsigned reg, unsigned val) +{ +	writel_relaxed(val, dev->base + reg); +} -#define at91_twi_read(reg)		__raw_readl(twi_base + (reg)) -#define at91_twi_write(reg, val)	__raw_writel((val), twi_base + (reg)) +static void at91_disable_twi_interrupts(struct at91_twi_dev *dev) +{ +	at91_twi_write(dev, AT91_TWI_IDR, +		       AT91_TWI_TXCOMP | AT91_TWI_RXRDY | AT91_TWI_TXRDY); +} +static void at91_init_twi_bus(struct at91_twi_dev *dev) +{ +	at91_disable_twi_interrupts(dev); +	at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_SWRST); +	at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_MSEN); +	at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_SVDIS); +	at91_twi_write(dev, AT91_TWI_CWGR, dev->twi_cwgr_reg); +}  /* - * Initialize the TWI hardware registers. + * Calculate symmetric clock as stated in datasheet: + * twi_clk = F_MAIN / (2 * (cdiv * (1 << ckdiv) + offset))   */ -static void __devinit at91_twi_hwinit(void) +static void __devinit at91_calc_twi_clock(struct at91_twi_dev *dev, int twi_clk)  { -	unsigned long cdiv, ckdiv; +	int ckdiv, cdiv, div; +	struct at91_twi_pdata *pdata = dev->pdata; +	int offset = pdata->clk_offset; +	int max_ckdiv = pdata->clk_max_div; -	at91_twi_write(AT91_TWI_IDR, 0xffffffff);	/* Disable all interrupts */ -	at91_twi_write(AT91_TWI_CR, AT91_TWI_SWRST);	/* Reset peripheral */ -	at91_twi_write(AT91_TWI_CR, AT91_TWI_MSEN);	/* Set Master mode */ +	div = max(0, (int)DIV_ROUND_UP(clk_get_rate(dev->clk), +				       2 * twi_clk) - offset); +	ckdiv = fls(div >> 8); +	cdiv = div >> ckdiv; -	/* Calcuate clock dividers */ -	cdiv = (clk_get_rate(twi_clk) / (2 * TWI_CLOCK)) - 3; -	cdiv = cdiv + 1;	/* round up */ -	ckdiv = 0; -	while (cdiv > 255) { -		ckdiv++; -		cdiv = cdiv >> 1; +	if (ckdiv > max_ckdiv) { +		dev_warn(dev->dev, "%d exceeds ckdiv max value which is %d.\n", +			 ckdiv, max_ckdiv); +		ckdiv = max_ckdiv; +		cdiv = 255;  	} -	if (cpu_is_at91rm9200()) {			/* AT91RM9200 Errata #22 */ -		if (ckdiv > 5) { -			printk(KERN_ERR "AT91 I2C: Invalid TWI_CLOCK value!\n"); -			ckdiv = 5; -		} -	} +	dev->twi_cwgr_reg = (ckdiv << 16) | (cdiv << 8) | cdiv; +	dev_dbg(dev->dev, "cdiv %d ckdiv %d\n", cdiv, ckdiv); +} -	at91_twi_write(AT91_TWI_CWGR, (ckdiv << 16) | (cdiv << 8) | cdiv); +static void at91_twi_write_next_byte(struct at91_twi_dev *dev) +{ +	if (dev->buf_len <= 0) +		return; + +	at91_twi_write(dev, AT91_TWI_THR, *dev->buf); + +	/* send stop when last byte has been written */ +	if (--dev->buf_len == 0) +		at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_STOP); + +	dev_dbg(dev->dev, "wrote 0x%x, to go %d\n", *dev->buf, dev->buf_len); + +	++dev->buf;  } -/* - * Poll the i2c status register until the specified bit is set. - * Returns 0 if timed out (100 msec). - */ -static short at91_poll_status(unsigned long bit) +static void at91_twi_read_next_byte(struct at91_twi_dev *dev)  { -	int loop_cntr = 10000; +	if (dev->buf_len <= 0) +		return; + +	*dev->buf = at91_twi_read(dev, AT91_TWI_RHR) & 0xff; +	--dev->buf_len; -	do { -		udelay(10); -	} while (!(at91_twi_read(AT91_TWI_SR) & bit) && (--loop_cntr > 0)); +	/* handle I2C_SMBUS_BLOCK_DATA */ +	if (unlikely(dev->msg->flags & I2C_M_RECV_LEN)) { +		dev->msg->flags &= ~I2C_M_RECV_LEN; +		dev->buf_len += *dev->buf; +		dev->msg->len = dev->buf_len + 1; +		dev_dbg(dev->dev, "received block length %d\n", dev->buf_len); +	} + +	/* send stop if second but last byte has been read */ +	if (dev->buf_len == 1) +		at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_STOP); -	return (loop_cntr > 0); +	dev_dbg(dev->dev, "read 0x%x, to go %d\n", *dev->buf, dev->buf_len); + +	++dev->buf;  } -static int xfer_read(struct i2c_adapter *adap, unsigned char *buf, int length) +static irqreturn_t atmel_twi_interrupt(int irq, void *dev_id)  { -	/* Send Start */ -	at91_twi_write(AT91_TWI_CR, AT91_TWI_START); +	struct at91_twi_dev *dev = dev_id; +	const unsigned status = at91_twi_read(dev, AT91_TWI_SR); +	const unsigned irqstatus = status & at91_twi_read(dev, AT91_TWI_IMR); -	/* Read data */ -	while (length--) { -		if (!length)	/* need to send Stop before reading last byte */ -			at91_twi_write(AT91_TWI_CR, AT91_TWI_STOP); -		if (!at91_poll_status(AT91_TWI_RXRDY)) { -			dev_dbg(&adap->dev, "RXRDY timeout\n"); -			return -ETIMEDOUT; -		} -		*buf++ = (at91_twi_read(AT91_TWI_RHR) & 0xff); +	if (!irqstatus) +		return IRQ_NONE; +	else if (irqstatus & AT91_TWI_RXRDY) +		at91_twi_read_next_byte(dev); +	else if (irqstatus & AT91_TWI_TXRDY) +		at91_twi_write_next_byte(dev); + +	/* catch error flags */ +	dev->transfer_status |= status; + +	if (irqstatus & AT91_TWI_TXCOMP) { +		at91_disable_twi_interrupts(dev); +		complete(&dev->cmd_complete);  	} -	return 0; +	return IRQ_HANDLED;  } -static int xfer_write(struct i2c_adapter *adap, unsigned char *buf, int length) +static int at91_do_twi_transfer(struct at91_twi_dev *dev)  { -	/* Load first byte into transmitter */ -	at91_twi_write(AT91_TWI_THR, *buf++); +	int ret; +	bool has_unre_flag = dev->pdata->has_unre_flag; -	/* Send Start */ -	at91_twi_write(AT91_TWI_CR, AT91_TWI_START); +	dev_dbg(dev->dev, "transfer: %s %d bytes.\n", +		(dev->msg->flags & I2C_M_RD) ? "read" : "write", dev->buf_len); -	do { -		if (!at91_poll_status(AT91_TWI_TXRDY)) { -			dev_dbg(&adap->dev, "TXRDY timeout\n"); -			return -ETIMEDOUT; -		} +	INIT_COMPLETION(dev->cmd_complete); +	dev->transfer_status = 0; +	if (dev->msg->flags & I2C_M_RD) { +		unsigned start_flags = AT91_TWI_START; -		length--;	/* byte was transmitted */ +		if (at91_twi_read(dev, AT91_TWI_SR) & AT91_TWI_RXRDY) { +			dev_err(dev->dev, "RXRDY still set!"); +			at91_twi_read(dev, AT91_TWI_RHR); +		} -		if (length > 0)		/* more data to send? */ -			at91_twi_write(AT91_TWI_THR, *buf++); -	} while (length); +		/* if only one byte is to be read, immediately stop transfer */ +		if (dev->buf_len <= 1 && !(dev->msg->flags & I2C_M_RECV_LEN)) +			start_flags |= AT91_TWI_STOP; +		at91_twi_write(dev, AT91_TWI_CR, start_flags); +		at91_twi_write(dev, AT91_TWI_IER, +			       AT91_TWI_TXCOMP | AT91_TWI_RXRDY); +	} else { +		at91_twi_write_next_byte(dev); +		at91_twi_write(dev, AT91_TWI_IER, +			       AT91_TWI_TXCOMP | AT91_TWI_TXRDY); +	} -	/* Send Stop */ -	at91_twi_write(AT91_TWI_CR, AT91_TWI_STOP); +	ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete, +							dev->adapter.timeout); +	if (ret == 0) { +		dev_err(dev->dev, "controller timed out\n"); +		at91_init_twi_bus(dev); +		return -ETIMEDOUT; +	} +	if (dev->transfer_status & AT91_TWI_NACK) { +		dev_dbg(dev->dev, "received nack\n"); +		return -EREMOTEIO; +	} +	if (dev->transfer_status & AT91_TWI_OVRE) { +		dev_err(dev->dev, "overrun while reading\n"); +		return -EIO; +	} +	if (has_unre_flag && dev->transfer_status & AT91_TWI_UNRE) { +		dev_err(dev->dev, "underrun while writing\n"); +		return -EIO; +	} +	dev_dbg(dev->dev, "transfer complete\n");  	return 0;  } -/* - * Generic i2c master transfer entrypoint. - * - * Note: We do not use Atmel's feature of storing the "internal device address". - * Instead the "internal device address" has to be written using a separate - * i2c message. - * http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2004-September/024411.html - */ -static int at91_xfer(struct i2c_adapter *adap, struct i2c_msg *pmsg, int num) +static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num)  { -	int i, ret; +	struct at91_twi_dev *dev = i2c_get_adapdata(adap); +	int ret; +	unsigned int_addr_flag = 0; +	struct i2c_msg *m_start = msg;  	dev_dbg(&adap->dev, "at91_xfer: processing %d messages:\n", num); -	for (i = 0; i < num; i++) { -		dev_dbg(&adap->dev, " #%d: %sing %d byte%s %s 0x%02x\n", i, -			pmsg->flags & I2C_M_RD ? "read" : "writ", -			pmsg->len, pmsg->len > 1 ? "s" : "", -			pmsg->flags & I2C_M_RD ? "from" : "to",	pmsg->addr); +	/* +	 * The hardware can handle at most two messages concatenated by a +	 * repeated start via it's internal address feature. +	 */ +	if (num > 2) { +		dev_err(dev->dev, +			"cannot handle more than two concatenated messages.\n"); +		return 0; +	} else if (num == 2) { +		int internal_address = 0; +		int i; -		at91_twi_write(AT91_TWI_MMR, (pmsg->addr << 16) -			| ((pmsg->flags & I2C_M_RD) ? AT91_TWI_MREAD : 0)); - -		if (pmsg->len && pmsg->buf) {	/* sanity check */ -			if (pmsg->flags & I2C_M_RD) -				ret = xfer_read(adap, pmsg->buf, pmsg->len); -			else -				ret = xfer_write(adap, pmsg->buf, pmsg->len); +		if (msg->flags & I2C_M_RD) { +			dev_err(dev->dev, "first transfer must be write.\n"); +			return -EINVAL; +		} +		if (msg->len > 3) { +			dev_err(dev->dev, "first message size must be <= 3.\n"); +			return -EINVAL; +		} -			if (ret) -				return ret; +		/* 1st msg is put into the internal address, start with 2nd */ +		m_start = &msg[1]; +		for (i = 0; i < msg->len; ++i) { +			const unsigned addr = msg->buf[msg->len - 1 - i]; -			/* Wait until transfer is finished */ -			if (!at91_poll_status(AT91_TWI_TXCOMP)) { -				dev_dbg(&adap->dev, "TXCOMP timeout\n"); -				return -ETIMEDOUT; -			} +			internal_address |= addr << (8 * i); +			int_addr_flag += AT91_TWI_IADRSZ_1;  		} -		dev_dbg(&adap->dev, "transfer complete\n"); -		pmsg++;		/* next message */ +		at91_twi_write(dev, AT91_TWI_IADR, internal_address);  	} -	return i; + +	at91_twi_write(dev, AT91_TWI_MMR, (m_start->addr << 16) | int_addr_flag +		       | ((m_start->flags & I2C_M_RD) ? AT91_TWI_MREAD : 0)); + +	dev->buf_len = m_start->len; +	dev->buf = m_start->buf; +	dev->msg = m_start; + +	ret = at91_do_twi_transfer(dev); + +	return (ret < 0) ? ret : num;  } -/* - * Return list of supported functionality. - */ -static u32 at91_func(struct i2c_adapter *adapter) +static u32 at91_twi_func(struct i2c_adapter *adapter)  { -	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL +		| I2C_FUNC_SMBUS_READ_BLOCK_DATA;  } -static struct i2c_algorithm at91_algorithm = { -	.master_xfer	= at91_xfer, -	.functionality	= at91_func, +static struct i2c_algorithm at91_twi_algorithm = { +	.master_xfer	= at91_twi_xfer, +	.functionality	= at91_twi_func,  }; -/* - * Main initialization routine. - */ -static int __devinit at91_i2c_probe(struct platform_device *pdev) +static struct at91_twi_pdata at91rm9200_config = { +	.clk_max_div = 5, +	.clk_offset = 3, +	.has_unre_flag = true, +}; + +static struct at91_twi_pdata at91sam9261_config = { +	.clk_max_div = 5, +	.clk_offset = 4, +	.has_unre_flag = false, +}; + +static struct at91_twi_pdata at91sam9260_config = { +	.clk_max_div = 7, +	.clk_offset = 4, +	.has_unre_flag = false, +}; + +static struct at91_twi_pdata at91sam9g20_config = { +	.clk_max_div = 7, +	.clk_offset = 4, +	.has_unre_flag = false, +}; + +static struct at91_twi_pdata at91sam9g10_config = { +	.clk_max_div = 7, +	.clk_offset = 4, +	.has_unre_flag = false, +}; + +static struct at91_twi_pdata at91sam9x5_config = { +	.clk_max_div = 7, +	.clk_offset = 4, +	.has_unre_flag = false, +}; + +static const struct platform_device_id at91_twi_devtypes[] = { +	{ +		.name = "i2c-at91rm9200", +		.driver_data = (unsigned long) &at91rm9200_config, +	}, { +		.name = "i2c-at91sam9261", +		.driver_data = (unsigned long) &at91sam9261_config, +	}, { +		.name = "i2c-at91sam9260", +		.driver_data = (unsigned long) &at91sam9260_config, +	}, { +		.name = "i2c-at91sam9g20", +		.driver_data = (unsigned long) &at91sam9g20_config, +	}, { +		.name = "i2c-at91sam9g10", +		.driver_data = (unsigned long) &at91sam9g10_config, +	}, { +		/* sentinel */ +	} +}; + +#if defined(CONFIG_OF) +static const struct of_device_id atmel_twi_dt_ids[] = { +	{ +		.compatible = "atmel,at91sam9260-i2c", +		.data = &at91sam9260_config, +	} , { +		.compatible = "atmel,at91sam9g20-i2c", +		.data = &at91sam9g20_config, +	} , { +		.compatible = "atmel,at91sam9g10-i2c", +		.data = &at91sam9g10_config, +	}, { +		.compatible = "atmel,at91sam9x5-i2c", +		.data = &at91sam9x5_config, +	}, { +		/* sentinel */ +	} +}; +MODULE_DEVICE_TABLE(of, atmel_twi_dt_ids); +#else +#define atmel_twi_dt_ids NULL +#endif + +static struct at91_twi_pdata * __devinit at91_twi_get_driver_data( +					struct platform_device *pdev) +{ +	if (pdev->dev.of_node) { +		const struct of_device_id *match; +		match = of_match_node(atmel_twi_dt_ids, pdev->dev.of_node); +		if (!match) +			return NULL; +		return match->data; +	} +	return (struct at91_twi_pdata *) platform_get_device_id(pdev)->driver_data; +} + +static int __devinit at91_twi_probe(struct platform_device *pdev)  { -	struct i2c_adapter *adapter; -	struct resource *res; +	struct at91_twi_dev *dev; +	struct resource *mem;  	int rc; -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (!res) -		return -ENXIO; +	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); +	if (!dev) +		return -ENOMEM; +	init_completion(&dev->cmd_complete); +	dev->dev = &pdev->dev; + +	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	if (!mem) +		return -ENODEV; -	if (!request_mem_region(res->start, resource_size(res), "at91_i2c")) +	dev->pdata = at91_twi_get_driver_data(pdev); +	if (!dev->pdata) +		return -ENODEV; + +	dev->base = devm_request_and_ioremap(&pdev->dev, mem); +	if (!dev->base)  		return -EBUSY; -	twi_base = ioremap(res->start, resource_size(res)); -	if (!twi_base) { -		rc = -ENOMEM; -		goto fail0; -	} +	dev->irq = platform_get_irq(pdev, 0); +	if (dev->irq < 0) +		return dev->irq; -	twi_clk = clk_get(NULL, "twi_clk"); -	if (IS_ERR(twi_clk)) { -		dev_err(&pdev->dev, "no clock defined\n"); -		rc = -ENODEV; -		goto fail1; +	rc = devm_request_irq(&pdev->dev, dev->irq, atmel_twi_interrupt, 0, +			 dev_name(dev->dev), dev); +	if (rc) { +		dev_err(dev->dev, "Cannot get irq %d: %d\n", dev->irq, rc); +		return rc;  	} -	adapter = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL); -	if (adapter == NULL) { -		dev_err(&pdev->dev, "can't allocate inteface!\n"); -		rc = -ENOMEM; -		goto fail2; +	platform_set_drvdata(pdev, dev); + +	dev->clk = devm_clk_get(dev->dev, NULL); +	if (IS_ERR(dev->clk)) { +		dev_err(dev->dev, "no clock defined\n"); +		return -ENODEV;  	} -	snprintf(adapter->name, sizeof(adapter->name), "AT91"); -	adapter->algo = &at91_algorithm; -	adapter->class = I2C_CLASS_HWMON; -	adapter->dev.parent = &pdev->dev; -	/* adapter->id == 0 ... only one TWI controller for now */ +	clk_prepare_enable(dev->clk); -	platform_set_drvdata(pdev, adapter); +	at91_calc_twi_clock(dev, TWI_CLK_HZ); +	at91_init_twi_bus(dev); -	clk_enable(twi_clk);		/* enable peripheral clock */ -	at91_twi_hwinit();		/* initialize TWI controller */ +	snprintf(dev->adapter.name, sizeof(dev->adapter.name), "AT91"); +	i2c_set_adapdata(&dev->adapter, dev); +	dev->adapter.owner = THIS_MODULE; +	dev->adapter.class = I2C_CLASS_HWMON; +	dev->adapter.algo = &at91_twi_algorithm; +	dev->adapter.dev.parent = dev->dev; +	dev->adapter.nr = pdev->id; +	dev->adapter.timeout = AT91_I2C_TIMEOUT; +	dev->adapter.dev.of_node = pdev->dev.of_node; -	rc = i2c_add_numbered_adapter(adapter); +	rc = i2c_add_numbered_adapter(&dev->adapter);  	if (rc) { -		dev_err(&pdev->dev, "Adapter %s registration failed\n", -				adapter->name); -		goto fail3; +		dev_err(dev->dev, "Adapter %s registration failed\n", +			dev->adapter.name); +		clk_disable_unprepare(dev->clk); +		return rc;  	} -	dev_info(&pdev->dev, "AT91 i2c bus driver.\n"); -	return 0; - -fail3: -	platform_set_drvdata(pdev, NULL); -	kfree(adapter); -	clk_disable(twi_clk); -fail2: -	clk_put(twi_clk); -fail1: -	iounmap(twi_base); -fail0: -	release_mem_region(res->start, resource_size(res)); +	of_i2c_register_devices(&dev->adapter); -	return rc; +	dev_info(dev->dev, "AT91 i2c bus driver.\n"); +	return 0;  } -static int __devexit at91_i2c_remove(struct platform_device *pdev) +static int __devexit at91_twi_remove(struct platform_device *pdev)  { -	struct i2c_adapter *adapter = platform_get_drvdata(pdev); -	struct resource *res; +	struct at91_twi_dev *dev = platform_get_drvdata(pdev);  	int rc; -	rc = i2c_del_adapter(adapter); -	platform_set_drvdata(pdev, NULL); - -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	iounmap(twi_base); -	release_mem_region(res->start, resource_size(res)); - -	clk_disable(twi_clk);		/* disable peripheral clock */ -	clk_put(twi_clk); +	rc = i2c_del_adapter(&dev->adapter); +	clk_disable_unprepare(dev->clk);  	return rc;  }  #ifdef CONFIG_PM -/* NOTE: could save a few mA by keeping clock off outside of at91_xfer... */ - -static int at91_i2c_suspend(struct device *dev) +static int at91_twi_runtime_suspend(struct device *dev)  { -	clk_disable(twi_clk); +	struct at91_twi_dev *twi_dev = dev_get_drvdata(dev); + +	clk_disable(twi_dev->clk); +  	return 0;  } -static int at91_i2c_resume(struct device *dev) +static int at91_twi_runtime_resume(struct device *dev)  { -	return clk_enable(twi_clk); +	struct at91_twi_dev *twi_dev = dev_get_drvdata(dev); + +	return clk_enable(twi_dev->clk);  } -static SIMPLE_DEV_PM_OPS(at91_i2c_pm, at91_i2c_suspend, at91_i2c_resume); -#define AT91_I2C_PM	(&at91_i2c_pm) +static const struct dev_pm_ops at91_twi_pm = { +	.runtime_suspend	= at91_twi_runtime_suspend, +	.runtime_resume		= at91_twi_runtime_resume, +}; +#define at91_twi_pm_ops (&at91_twi_pm)  #else -#define AT91_I2C_PM	NULL +#define at91_twi_pm_ops NULL  #endif -static struct platform_driver at91_i2c_driver = { -	.probe		= at91_i2c_probe, -	.remove		= __devexit_p(at91_i2c_remove), +static struct platform_driver at91_twi_driver = { +	.probe		= at91_twi_probe, +	.remove		= __devexit_p(at91_twi_remove), +	.id_table	= at91_twi_devtypes,  	.driver		= {  		.name	= "at91_i2c",  		.owner	= THIS_MODULE, -		.pm	= AT91_I2C_PM, +		.of_match_table = atmel_twi_dt_ids, +		.pm	= at91_twi_pm_ops,  	},  }; -module_platform_driver(at91_i2c_driver); +static int __init at91_twi_init(void) +{ +	return platform_driver_register(&at91_twi_driver); +} + +static void __exit at91_twi_exit(void) +{ +	platform_driver_unregister(&at91_twi_driver); +} + +subsys_initcall(at91_twi_init); +module_exit(at91_twi_exit); -MODULE_AUTHOR("Rick Bronson"); +MODULE_AUTHOR("Nikolaus Voss <n.voss@weinmann.de>");  MODULE_DESCRIPTION("I2C (TWI) driver for Atmel AT91");  MODULE_LICENSE("GPL");  MODULE_ALIAS("platform:at91_i2c"); diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 79b4bcb3b85..85ce548ff15 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -38,6 +38,8 @@  #include <linux/slab.h>  #include <linux/cpufreq.h>  #include <linux/gpio.h> +#include <linux/of_i2c.h> +#include <linux/of_device.h>  #include <mach/hardware.h>  #include <mach/i2c.h> @@ -114,6 +116,7 @@ struct davinci_i2c_dev {  	struct completion	xfr_complete;  	struct notifier_block	freq_transition;  #endif +	struct davinci_i2c_platform_data *pdata;  };  /* default platform data to use if not supplied in the platform_device */ @@ -155,7 +158,7 @@ static void generic_i2c_clock_pulse(unsigned int scl_pin)  static void i2c_recover_bus(struct davinci_i2c_dev *dev)  {  	u32 flag = 0; -	struct davinci_i2c_platform_data *pdata = dev->dev->platform_data; +	struct davinci_i2c_platform_data *pdata = dev->pdata;  	dev_err(dev->dev, "initiating i2c bus recovery\n");  	/* Send NACK to the slave */ @@ -163,8 +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); -	if (pdata) -		generic_i2c_clock_pulse(pdata->scl_pin); +	generic_i2c_clock_pulse(pdata->scl_pin);  	/* Send STOP */  	flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);  	flag |= DAVINCI_I2C_MDR_STP; @@ -187,7 +189,7 @@ static inline void davinci_i2c_reset_ctrl(struct davinci_i2c_dev *i2c_dev,  static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev)  { -	struct davinci_i2c_platform_data *pdata = dev->dev->platform_data; +	struct davinci_i2c_platform_data *pdata = dev->pdata;  	u16 psc;  	u32 clk;  	u32 d; @@ -235,10 +237,7 @@ static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev)   */  static int i2c_davinci_init(struct davinci_i2c_dev *dev)  { -	struct davinci_i2c_platform_data *pdata = dev->dev->platform_data; - -	if (!pdata) -		pdata = &davinci_i2c_platform_data_default; +	struct davinci_i2c_platform_data *pdata = dev->pdata;  	/* put I2C into reset */  	davinci_i2c_reset_ctrl(dev, 0); @@ -260,6 +259,7 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)  	dev_dbg(dev->dev, "bus_freq = %dkHz, bus_delay = %d\n",  		pdata->bus_freq, pdata->bus_delay); +  	/* Take the I2C module out of reset: */  	davinci_i2c_reset_ctrl(dev, 1); @@ -308,13 +308,11 @@ static int  i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)  {  	struct davinci_i2c_dev *dev = i2c_get_adapdata(adap); -	struct davinci_i2c_platform_data *pdata = dev->dev->platform_data; +	struct davinci_i2c_platform_data *pdata = dev->pdata;  	u32 flag;  	u16 w;  	int r; -	if (!pdata) -		pdata = &davinci_i2c_platform_data_default;  	/* Introduce a delay, required for some boards (e.g Davinci EVM) */  	if (pdata->bus_delay)  		udelay(pdata->bus_delay); @@ -635,6 +633,12 @@ static struct i2c_algorithm i2c_davinci_algo = {  	.functionality	= i2c_davinci_func,  }; +static const struct of_device_id davinci_i2c_of_match[] = { +	{.compatible = "ti,davinci-i2c", }, +	{}, +}; +MODULE_DEVICE_TABLE(of, davinci_i2c_of_match); +  static int davinci_i2c_probe(struct platform_device *pdev)  {  	struct davinci_i2c_dev *dev; @@ -674,14 +678,33 @@ static int davinci_i2c_probe(struct platform_device *pdev)  #endif  	dev->dev = get_device(&pdev->dev);  	dev->irq = irq->start; +	dev->pdata = dev->dev->platform_data;  	platform_set_drvdata(pdev, dev); +	if (!dev->pdata && pdev->dev.of_node) { +		u32 prop; + +		dev->pdata = devm_kzalloc(&pdev->dev, +			sizeof(struct davinci_i2c_platform_data), GFP_KERNEL); +		if (!dev->pdata) { +			r = -ENOMEM; +			goto err_free_mem; +		} +		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", +			&prop)) +			dev->pdata->bus_freq = prop / 1000; +	} else if (!dev->pdata) { +		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;  	} -	clk_enable(dev->clk); +	clk_prepare_enable(dev->clk);  	dev->base = ioremap(mem->start, resource_size(mem));  	if (!dev->base) { @@ -711,6 +734,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)  	adap->algo = &i2c_davinci_algo;  	adap->dev.parent = &pdev->dev;  	adap->timeout = DAVINCI_I2C_TIMEOUT; +	adap->dev.of_node = pdev->dev.of_node;  	adap->nr = pdev->id;  	r = i2c_add_numbered_adapter(adap); @@ -718,6 +742,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)  		dev_err(&pdev->dev, "failure adding adapter\n");  		goto err_free_irq;  	} +	of_i2c_register_devices(adap);  	return 0; @@ -726,7 +751,7 @@ err_free_irq:  err_unuse_clocks:  	iounmap(dev->base);  err_mem_ioremap: -	clk_disable(dev->clk); +	clk_disable_unprepare(dev->clk);  	clk_put(dev->clk);  	dev->clk = NULL;  err_free_mem: @@ -750,7 +775,7 @@ static int davinci_i2c_remove(struct platform_device *pdev)  	i2c_del_adapter(&dev->adapter);  	put_device(&pdev->dev); -	clk_disable(dev->clk); +	clk_disable_unprepare(dev->clk);  	clk_put(dev->clk);  	dev->clk = NULL; @@ -772,7 +797,7 @@ static int davinci_i2c_suspend(struct device *dev)  	/* put I2C into reset */  	davinci_i2c_reset_ctrl(i2c_dev, 0); -	clk_disable(i2c_dev->clk); +	clk_disable_unprepare(i2c_dev->clk);  	return 0;  } @@ -782,7 +807,7 @@ static int davinci_i2c_resume(struct device *dev)  	struct platform_device *pdev = to_platform_device(dev);  	struct davinci_i2c_dev *i2c_dev = platform_get_drvdata(pdev); -	clk_enable(i2c_dev->clk); +	clk_prepare_enable(i2c_dev->clk);  	/* take I2C out of reset */  	davinci_i2c_reset_ctrl(i2c_dev, 1); @@ -809,6 +834,7 @@ static struct platform_driver davinci_i2c_driver = {  		.name	= "i2c_davinci",  		.owner	= THIS_MODULE,  		.pm	= davinci_i2c_pm_ops, +		.of_match_table = of_match_ptr(davinci_i2c_of_match),  	},  }; diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index 0722f869465..2e1d5f405f0 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -272,9 +272,9 @@ static void __init i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx,  	/* dev_dbg() can't be used, because adapter is not yet registered */  #ifdef CONFIG_I2C_DEBUG_BUS -	printk(KERN_DEBUG "I2C: <%s> I2C_CLK=%d, REQ DIV=%d\n", +	dev_dbg(&i2c_imx->adapter.dev, "<%s> I2C_CLK=%d, REQ DIV=%d\n",  		__func__, i2c_clk_rate, div); -	printk(KERN_DEBUG "I2C: <%s> IFDR[IC]=0x%x, REAL DIV=%d\n", +	dev_dbg(&i2c_imx->adapter.dev, "<%s> IFDR[IC]=0x%x, REAL DIV=%d\n",  		__func__, i2c_clk_div[i][1], i2c_clk_div[i][0]);  #endif  } @@ -564,7 +564,7 @@ static int __init i2c_imx_probe(struct platform_device *pdev)  		resource_size(res), res->start);  	dev_dbg(&i2c_imx->adapter.dev, "adapter name: \"%s\"\n",  		i2c_imx->adapter.name); -	dev_dbg(&i2c_imx->adapter.dev, "IMX I2C adapter registered\n"); +	dev_info(&i2c_imx->adapter.dev, "IMX I2C adapter registered\n");  	return 0;   /* Return OK */  } diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index b76731edbf1..64b0b4d265d 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -576,7 +576,23 @@ static int mpc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)  			    mpc_write(i2c, pmsg->addr, pmsg->buf, pmsg->len, i);  		}  	} -	mpc_i2c_stop(i2c); +	mpc_i2c_stop(i2c); /* Initiate STOP */ +	orig_jiffies = jiffies; +	/* Wait until STOP is seen, allow up to 1 s */ +	while (readb(i2c->base + MPC_I2C_SR) & CSR_MBB) { +		if (time_after(jiffies, orig_jiffies + HZ)) { +			u8 status = readb(i2c->base + MPC_I2C_SR); + +			dev_dbg(i2c->dev, "timeout\n"); +			if ((status & (CSR_MCF | CSR_MBB | CSR_RXAK)) != 0) { +				writeb(status & ~CSR_MAL, +				       i2c->base + MPC_I2C_SR); +				mpc_i2c_fixup(i2c); +			} +			return -EIO; +		} +		cond_resched(); +	}  	return (ret < 0) ? ret : num;  } diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c index 61b00edacb0..698d7acb0f0 100644 --- a/drivers/i2c/busses/i2c-nomadik.c +++ b/drivers/i2c/busses/i2c-nomadik.c @@ -22,9 +22,10 @@  #include <linux/err.h>  #include <linux/clk.h>  #include <linux/io.h> -#include <linux/regulator/consumer.h>  #include <linux/pm_runtime.h>  #include <linux/platform_data/i2c-nomadik.h> +#include <linux/of.h> +#include <linux/of_i2c.h>  #define DRIVER_NAME "nmk-i2c" @@ -146,7 +147,6 @@ struct i2c_nmk_client {   * @stop: stop condition.   * @xfer_complete: acknowledge completion for a I2C message.   * @result: controller propogated result. - * @regulator: pointer to i2c regulator.   * @busy: Busy doing transfer.   */  struct nmk_i2c_dev { @@ -160,7 +160,6 @@ struct nmk_i2c_dev {  	int				stop;  	struct completion		xfer_complete;  	int				result; -	struct regulator		*regulator;  	bool				busy;  }; @@ -643,8 +642,6 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,  	dev->busy = true; -	if (dev->regulator) -		regulator_enable(dev->regulator);  	pm_runtime_get_sync(&dev->adev->dev);  	clk_enable(dev->clk); @@ -676,8 +673,6 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,  out:  	clk_disable(dev->clk);  	pm_runtime_put_sync(&dev->adev->dev); -	if (dev->regulator) -		regulator_disable(dev->regulator);  	dev->busy = false; @@ -920,18 +915,42 @@ static struct nmk_i2c_controller u8500_i2c = {  	.sm             = I2C_FREQ_MODE_FAST,  }; +static void nmk_i2c_of_probe(struct device_node *np, +			struct nmk_i2c_controller *pdata) +{ +	of_property_read_u32(np, "clock-frequency", &pdata->clk_freq); + +	/* This driver only supports 'standard' and 'fast' modes of operation. */ +	if (pdata->clk_freq <= 100000) +		pdata->sm = I2C_FREQ_MODE_STANDARD; +	else +		pdata->sm = I2C_FREQ_MODE_FAST; +} +  static atomic_t adapter_id = ATOMIC_INIT(0);  static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)  {  	int ret = 0;  	struct nmk_i2c_controller *pdata = adev->dev.platform_data; +	struct device_node *np = adev->dev.of_node;  	struct nmk_i2c_dev	*dev;  	struct i2c_adapter *adap; -	if (!pdata) -		/* No i2c configuration found, using the default. */ -		pdata = &u8500_i2c; +	if (!pdata) { +		if (np) { +			pdata = devm_kzalloc(&adev->dev, sizeof(*pdata), GFP_KERNEL); +			if (!pdata) { +				ret = -ENOMEM; +				goto err_no_mem; +			} +			/* Provide the default configuration as a base. */ +			memcpy(pdata, &u8500_i2c, sizeof(struct nmk_i2c_controller)); +			nmk_i2c_of_probe(np, pdata); +		} else +			/* No i2c configuration found, using the default. */ +			pdata = &u8500_i2c; +	}  	dev = kzalloc(sizeof(struct nmk_i2c_dev), GFP_KERNEL);  	if (!dev) { @@ -957,12 +976,6 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)  		goto err_irq;  	} -	dev->regulator = regulator_get(&adev->dev, "v-i2c"); -	if (IS_ERR(dev->regulator)) { -		dev_warn(&adev->dev, "could not get i2c regulator\n"); -		dev->regulator = NULL; -	} -  	pm_suspend_ignore_children(&adev->dev, true);  	dev->clk = clk_get(&adev->dev, NULL); @@ -973,6 +986,7 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)  	}  	adap = &dev->adap; +	adap->dev.of_node = np;  	adap->dev.parent = &adev->dev;  	adap->owner	= THIS_MODULE;  	adap->class	= I2C_CLASS_HWMON | I2C_CLASS_SPD; @@ -1002,6 +1016,8 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)  		goto err_add_adap;  	} +	of_i2c_register_devices(adap); +  	pm_runtime_put(&adev->dev);  	return 0; @@ -1009,8 +1025,6 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)   err_add_adap:  	clk_put(dev->clk);   err_no_clk: -	if (dev->regulator) -		regulator_put(dev->regulator);  	free_irq(dev->irq, dev);   err_irq:  	iounmap(dev->virtbase); @@ -1038,8 +1052,6 @@ static int nmk_i2c_remove(struct amba_device *adev)  	if (res)  		release_mem_region(res->start, resource_size(res));  	clk_put(dev->clk); -	if (dev->regulator) -		regulator_put(dev->regulator);  	pm_runtime_disable(&adev->dev);  	amba_set_drvdata(adev, NULL);  	kfree(dev); diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 5d19a49803c..b6c6b95d4a0 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -43,6 +43,7 @@  #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 @@ -55,6 +56,9 @@  /* timeout waiting for the controller to respond */  #define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000)) +/* timeout for pm runtime autosuspend */ +#define OMAP_I2C_PM_TIMEOUT		1000	/* ms */ +  /* For OMAP3 I2C_IV has changed to I2C_WE (wakeup enable) */  enum {  	OMAP_I2C_REV_REG = 0, @@ -176,15 +180,15 @@ enum {  #define I2C_OMAP_ERRATA_I462		(1 << 1)  struct omap_i2c_dev { +	spinlock_t		lock;		/* IRQ synchronization */  	struct device		*dev;  	void __iomem		*base;		/* virtual */  	int			irq;  	int			reg_shift;      /* bit shift for I2C register addresses */  	struct completion	cmd_complete;  	struct resource		*ioarea; -	u32			latency;	/* maximum mpu wkup latency */ -	void			(*set_mpu_wkup_lat)(struct device *dev, -						    long latency); +	u32			latency;	/* maximum MPU wkup latency */ +	struct pm_qos_request	pm_qos_request;  	u32			speed;		/* Speed of bus in kHz */  	u32			dtrev;		/* extra revision from DT */  	u32			flags; @@ -193,12 +197,14 @@ struct omap_i2c_dev {  	u8			*regs;  	size_t			buf_len;  	struct i2c_adapter	adapter; +	u8			threshold;  	u8			fifo_size;	/* use as flag and value  						 * fifo_size==0 implies no fifo  						 * if set, should be trsh+1  						 */  	u8			rev;  	unsigned		b_hw:1;		/* bad h/w fixes */ +	unsigned		receiver:1;	/* true when we're in receiver mode */  	u16			iestate;	/* Saved interrupt register */  	u16			pscstate;  	u16			scllstate; @@ -417,13 +423,6 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)  	omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll);  	omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh); -	if (dev->fifo_size) { -		/* Note: setup required fifo size - 1. RTRSH and XTRSH */ -		buf = (dev->fifo_size - 1) << 8 | OMAP_I2C_BUF_RXFIF_CLR | -			(dev->fifo_size - 1) | OMAP_I2C_BUF_TXFIF_CLR; -		omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf); -	} -  	/* Take the I2C module out of reset: */  	omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); @@ -461,6 +460,43 @@ static int omap_i2c_wait_for_bb(struct omap_i2c_dev *dev)  	return 0;  } +static void omap_i2c_resize_fifo(struct omap_i2c_dev *dev, u8 size, bool is_rx) +{ +	u16		buf; + +	if (dev->flags & OMAP_I2C_FLAG_NO_FIFO) +		return; + +	/* +	 * Set up notification threshold based on message size. We're doing +	 * this to try and avoid draining feature as much as possible. Whenever +	 * we have big messages to transfer (bigger than our total fifo size) +	 * then we might use draining feature to transfer the remaining bytes. +	 */ + +	dev->threshold = clamp(size, (u8) 1, dev->fifo_size); + +	buf = omap_i2c_read_reg(dev, OMAP_I2C_BUF_REG); + +	if (is_rx) { +		/* Clear RX Threshold */ +		buf &= ~(0x3f << 8); +		buf |= ((dev->threshold - 1) << 8) | OMAP_I2C_BUF_RXFIF_CLR; +	} else { +		/* Clear TX Threshold */ +		buf &= ~0x3f; +		buf |= (dev->threshold - 1) | OMAP_I2C_BUF_TXFIF_CLR; +	} + +	omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf); + +	if (dev->rev < OMAP_I2C_REV_ON_3630_4430) +		dev->b_hw = 1; /* Enable hardware fixes */ + +	/* calculate wakeup latency constraint for MPU */ +	dev->latency = (1000000 * dev->threshold) / (1000 * dev->speed / 8); +} +  /*   * Low level master read/write transaction.   */ @@ -477,6 +513,9 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,  	if (msg->len == 0)  		return -EINVAL; +	dev->receiver = !!(msg->flags & I2C_M_RD); +	omap_i2c_resize_fifo(dev, msg->len, dev->receiver); +  	omap_i2c_write_reg(dev, OMAP_I2C_SA_REG, msg->addr);  	/* REVISIT: Could the STB bit of I2C_CON be used with probing? */ @@ -590,8 +629,16 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)  	if (r < 0)  		goto out; -	if (dev->set_mpu_wkup_lat != NULL) -		dev->set_mpu_wkup_lat(dev->dev, dev->latency); +	/* +	 * 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);  	for (i = 0; i < num; i++) {  		r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1))); @@ -599,15 +646,16 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)  			break;  	} -	if (dev->set_mpu_wkup_lat != NULL) -		dev->set_mpu_wkup_lat(dev->dev, -1); +	if (dev->latency) +		pm_qos_remove_request(&dev->pm_qos_request);  	if (r == 0)  		r = num;  	omap_i2c_wait_for_bb(dev);  out: -	pm_runtime_put(dev->dev); +	pm_runtime_mark_last_busy(dev->dev); +	pm_runtime_put_autosuspend(dev->dev);  	return r;  } @@ -725,186 +773,252 @@ omap_i2c_omap1_isr(int this_irq, void *dev_id)   * data to DATA_REG. Otherwise some data bytes can be lost while transferring   * them from the memory to the I2C interface.   */ -static int errata_omap3_i462(struct omap_i2c_dev *dev, u16 *stat, int *err) +static int errata_omap3_i462(struct omap_i2c_dev *dev)  {  	unsigned long timeout = 10000; +	u16 stat; -	while (--timeout && !(*stat & OMAP_I2C_STAT_XUDF)) { -		if (*stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) { -			omap_i2c_ack_stat(dev, *stat & (OMAP_I2C_STAT_XRDY | +	do { +		stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); +		if (stat & OMAP_I2C_STAT_XUDF) +			break; + +		if (stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) { +			omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY |  							OMAP_I2C_STAT_XDR)); -			return -ETIMEDOUT; +			if (stat & OMAP_I2C_STAT_NACK) { +				dev->cmd_err |= OMAP_I2C_STAT_NACK; +				omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK); +			} + +			if (stat & OMAP_I2C_STAT_AL) { +				dev_err(dev->dev, "Arbitration lost\n"); +				dev->cmd_err |= OMAP_I2C_STAT_AL; +				omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK); +			} + +			return -EIO;  		}  		cpu_relax(); -		*stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); -	} +	} while (--timeout);  	if (!timeout) {  		dev_err(dev->dev, "timeout waiting on XUDF bit\n");  		return 0;  	} -	*err |= OMAP_I2C_STAT_XUDF;  	return 0;  } +static void omap_i2c_receive_data(struct omap_i2c_dev *dev, u8 num_bytes, +		bool is_rdr) +{ +	u16		w; + +	while (num_bytes--) { +		w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG); +		*dev->buf++ = w; +		dev->buf_len--; + +		/* +		 * Data reg in 2430, omap3 and +		 * omap4 is 8 bit wide +		 */ +		if (dev->flags & OMAP_I2C_FLAG_16BIT_DATA_REG) { +			*dev->buf++ = w >> 8; +			dev->buf_len--; +		} +	} +} + +static int omap_i2c_transmit_data(struct omap_i2c_dev *dev, u8 num_bytes, +		bool is_xdr) +{ +	u16		w; + +	while (num_bytes--) { +		w = *dev->buf++; +		dev->buf_len--; + +		/* +		 * Data reg in 2430, omap3 and +		 * omap4 is 8 bit wide +		 */ +		if (dev->flags & OMAP_I2C_FLAG_16BIT_DATA_REG) { +			w |= *dev->buf++ << 8; +			dev->buf_len--; +		} + +		if (dev->errata & I2C_OMAP_ERRATA_I462) { +			int ret; + +			ret = errata_omap3_i462(dev); +			if (ret < 0) +				return ret; +		} + +		omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w); +	} + +	return 0; +} + +static irqreturn_t +omap_i2c_isr(int irq, void *dev_id) +{ +	struct omap_i2c_dev *dev = dev_id; +	irqreturn_t ret = IRQ_HANDLED; +	u16 mask; +	u16 stat; + +	spin_lock(&dev->lock); +	mask = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); +	stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); + +	if (stat & mask) +		ret = IRQ_WAKE_THREAD; + +	spin_unlock(&dev->lock); + +	return ret; +} +  static irqreturn_t -omap_i2c_isr(int this_irq, void *dev_id) +omap_i2c_isr_thread(int this_irq, void *dev_id)  {  	struct omap_i2c_dev *dev = dev_id; +	unsigned long flags;  	u16 bits; -	u16 stat, w; -	int err, count = 0; +	u16 stat; +	int err = 0, count = 0; -	if (pm_runtime_suspended(dev->dev)) -		return IRQ_NONE; +	spin_lock_irqsave(&dev->lock, flags); +	do { +		bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); +		stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); +		stat &= bits; + +		/* If we're in receiver mode, ignore XDR/XRDY */ +		if (dev->receiver) +			stat &= ~(OMAP_I2C_STAT_XDR | OMAP_I2C_STAT_XRDY); +		else +			stat &= ~(OMAP_I2C_STAT_RDR | OMAP_I2C_STAT_RRDY); + +		if (!stat) { +			/* my work here is done */ +			goto out; +		} -	bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); -	while ((stat = (omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG))) & bits) {  		dev_dbg(dev->dev, "IRQ (ISR = 0x%04x)\n", stat);  		if (count++ == 100) {  			dev_warn(dev->dev, "Too much work in one IRQ\n");  			break;  		} -		err = 0; -complete: -		/* -		 * Ack the stat in one go, but [R/X]DR and [R/X]RDY should be -		 * acked after the data operation is complete. -		 * Ref: TRM SWPU114Q Figure 18-31 -		 */ -		omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat & -				~(OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR | -				OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)); - -		if (stat & OMAP_I2C_STAT_NACK) +		if (stat & OMAP_I2C_STAT_NACK) {  			err |= OMAP_I2C_STAT_NACK; +			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK); +			break; +		}  		if (stat & OMAP_I2C_STAT_AL) {  			dev_err(dev->dev, "Arbitration lost\n");  			err |= OMAP_I2C_STAT_AL; +			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_AL); +			break;  		} +  		/*  		 * ProDB0017052: Clear ARDY bit twice  		 */  		if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK |  					OMAP_I2C_STAT_AL)) { -			omap_i2c_ack_stat(dev, stat & -				(OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR | -				OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR | -				OMAP_I2C_STAT_ARDY)); -			omap_i2c_complete_cmd(dev, err); -			return IRQ_HANDLED; +			omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_RRDY | +						OMAP_I2C_STAT_RDR | +						OMAP_I2C_STAT_XRDY | +						OMAP_I2C_STAT_XDR | +						OMAP_I2C_STAT_ARDY)); +			break;  		} -		if (stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)) { + +		if (stat & OMAP_I2C_STAT_RDR) {  			u8 num_bytes = 1; +			if (dev->fifo_size) +				num_bytes = dev->buf_len; + +			omap_i2c_receive_data(dev, num_bytes, true); +  			if (dev->errata & I2C_OMAP_ERRATA_I207)  				i2c_omap_errata_i207(dev, stat); -			if (dev->fifo_size) { -				if (stat & OMAP_I2C_STAT_RRDY) -					num_bytes = dev->fifo_size; -				else    /* read RXSTAT on RDR interrupt */ -					num_bytes = (omap_i2c_read_reg(dev, -							OMAP_I2C_BUFSTAT_REG) -							>> 8) & 0x3F; -			} -			while (num_bytes) { -				num_bytes--; -				w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG); -				if (dev->buf_len) { -					*dev->buf++ = w; -					dev->buf_len--; -					/* -					 * Data reg in 2430, omap3 and -					 * omap4 is 8 bit wide -					 */ -					if (dev->flags & -						 OMAP_I2C_FLAG_16BIT_DATA_REG) { -						if (dev->buf_len) { -							*dev->buf++ = w >> 8; -							dev->buf_len--; -						} -					} -				} else { -					if (stat & OMAP_I2C_STAT_RRDY) -						dev_err(dev->dev, -							"RRDY IRQ while no data" -								" requested\n"); -					if (stat & OMAP_I2C_STAT_RDR) -						dev_err(dev->dev, -							"RDR IRQ while no data" -								" requested\n"); -					break; -				} -			} -			omap_i2c_ack_stat(dev, -				stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)); +			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RDR); +			break; +		} + +		if (stat & OMAP_I2C_STAT_RRDY) { +			u8 num_bytes = 1; + +			if (dev->threshold) +				num_bytes = dev->threshold; + +			omap_i2c_receive_data(dev, num_bytes, false); +			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RRDY);  			continue;  		} -		if (stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)) { + +		if (stat & OMAP_I2C_STAT_XDR) {  			u8 num_bytes = 1; -			if (dev->fifo_size) { -				if (stat & OMAP_I2C_STAT_XRDY) -					num_bytes = dev->fifo_size; -				else    /* read TXSTAT on XDR interrupt */ -					num_bytes = omap_i2c_read_reg(dev, -							OMAP_I2C_BUFSTAT_REG) -							& 0x3F; -			} -			while (num_bytes) { -				num_bytes--; -				w = 0; -				if (dev->buf_len) { -					w = *dev->buf++; -					dev->buf_len--; -					/* -					 * Data reg in 2430, omap3 and -					 * omap4 is 8 bit wide -					 */ -					if (dev->flags & -						 OMAP_I2C_FLAG_16BIT_DATA_REG) { -						if (dev->buf_len) { -							w |= *dev->buf++ << 8; -							dev->buf_len--; -						} -					} -				} else { -					if (stat & OMAP_I2C_STAT_XRDY) -						dev_err(dev->dev, -							"XRDY IRQ while no " -							"data to send\n"); -					if (stat & OMAP_I2C_STAT_XDR) -						dev_err(dev->dev, -							"XDR IRQ while no " -							"data to send\n"); -					break; -				} +			int ret; -				if ((dev->errata & I2C_OMAP_ERRATA_I462) && -				    errata_omap3_i462(dev, &stat, &err)) -					goto complete; +			if (dev->fifo_size) +				num_bytes = dev->buf_len; -				omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w); -			} -			omap_i2c_ack_stat(dev, -				stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)); +			ret = omap_i2c_transmit_data(dev, num_bytes, true); +			if (ret < 0) +				break; + +			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XDR); +			break; +		} + +		if (stat & OMAP_I2C_STAT_XRDY) { +			u8 num_bytes = 1; +			int ret; + +			if (dev->threshold) +				num_bytes = dev->threshold; + +			ret = omap_i2c_transmit_data(dev, num_bytes, false); +			if (ret < 0) +				break; + +			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XRDY);  			continue;  		} +  		if (stat & OMAP_I2C_STAT_ROVR) {  			dev_err(dev->dev, "Receive overrun\n"); -			dev->cmd_err |= OMAP_I2C_STAT_ROVR; +			err |= OMAP_I2C_STAT_ROVR; +			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_ROVR); +			break;  		} +  		if (stat & OMAP_I2C_STAT_XUDF) {  			dev_err(dev->dev, "Transmit underflow\n"); -			dev->cmd_err |= OMAP_I2C_STAT_XUDF; +			err |= OMAP_I2C_STAT_XUDF; +			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XUDF); +			break;  		} -	} +	} while (stat); + +	omap_i2c_complete_cmd(dev, err); + +out: +	spin_unlock_irqrestore(&dev->lock, flags); -	return count ? IRQ_HANDLED : IRQ_NONE; +	return IRQ_HANDLED;  }  static const struct i2c_algorithm omap_i2c_algo = { @@ -943,11 +1057,11 @@ omap_i2c_probe(struct platform_device *pdev)  {  	struct omap_i2c_dev	*dev;  	struct i2c_adapter	*adap; -	struct resource		*mem, *irq, *ioarea; +	struct resource		*mem;  	struct omap_i2c_bus_platform_data *pdata = pdev->dev.platform_data;  	struct device_node	*node = pdev->dev.of_node;  	const struct of_device_id *match; -	irq_handler_t isr; +	int irq;  	int r;  	/* NOTE: driver uses the static register mapping */ @@ -956,23 +1070,23 @@ omap_i2c_probe(struct platform_device *pdev)  		dev_err(&pdev->dev, "no mem resource?\n");  		return -ENODEV;  	} -	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); -	if (!irq) { + +	irq = platform_get_irq(pdev, 0); +	if (irq < 0) {  		dev_err(&pdev->dev, "no irq resource?\n"); -		return -ENODEV; +		return irq;  	} -	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 omap_i2c_dev), GFP_KERNEL); +	if (!dev) { +		dev_err(&pdev->dev, "Menory allocation failed\n"); +		return -ENOMEM;  	} -	dev = kzalloc(sizeof(struct omap_i2c_dev), GFP_KERNEL); -	if (!dev) { -		r = -ENOMEM; -		goto err_release_region; +	dev->base = devm_request_and_ioremap(&pdev->dev, mem); +	if (!dev->base) { +		dev_err(&pdev->dev, "I2C region already claimed\n"); +		return -ENOMEM;  	}  	match = of_match_device(of_match_ptr(omap_i2c_of_match), &pdev->dev); @@ -989,17 +1103,13 @@ 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;  	}  	dev->dev = &pdev->dev; -	dev->irq = irq->start; -	dev->base = ioremap(mem->start, resource_size(mem)); -	if (!dev->base) { -		r = -ENOMEM; -		goto err_free_mem; -	} +	dev->irq = irq; + +	spin_lock_init(&dev->lock);  	platform_set_drvdata(pdev, dev);  	init_completion(&dev->cmd_complete); @@ -1012,6 +1122,9 @@ omap_i2c_probe(struct platform_device *pdev)  		dev->regs = (u8 *)reg_map_ip_v1;  	pm_runtime_enable(dev->dev); +	pm_runtime_set_autosuspend_delay(dev->dev, OMAP_I2C_PM_TIMEOUT); +	pm_runtime_use_autosuspend(dev->dev); +  	r = pm_runtime_get_sync(dev->dev);  	if (IS_ERR_VALUE(r))  		goto err_free_mem; @@ -1041,32 +1154,31 @@ omap_i2c_probe(struct platform_device *pdev)  		dev->fifo_size = (dev->fifo_size / 2); -		if (dev->rev >= OMAP_I2C_REV_ON_3630_4430) -			dev->b_hw = 0; /* Disable hardware fixes */ -		else +		if (dev->rev < OMAP_I2C_REV_ON_3630_4430)  			dev->b_hw = 1; /* Enable hardware fixes */  		/* calculate wakeup latency constraint for MPU */ -		if (dev->set_mpu_wkup_lat != NULL) -			dev->latency = (1000000 * dev->fifo_size) / -				       (1000 * dev->speed / 8); +		dev->latency = (1000000 * dev->fifo_size) / +			       (1000 * dev->speed / 8);  	}  	/* reset ASAP, clearing any IRQs */  	omap_i2c_init(dev); -	isr = (dev->rev < OMAP_I2C_OMAP1_REV_2) ? omap_i2c_omap1_isr : -								   omap_i2c_isr; -	r = request_irq(dev->irq, isr, IRQF_NO_SUSPEND, pdev->name, dev); +	if (dev->rev < OMAP_I2C_OMAP1_REV_2) +		r = devm_request_irq(&pdev->dev, dev->irq, omap_i2c_omap1_isr, +				IRQF_NO_SUSPEND, pdev->name, dev); +	else +		r = devm_request_threaded_irq(&pdev->dev, dev->irq, +				omap_i2c_isr, omap_i2c_isr_thread, +				IRQF_NO_SUSPEND | IRQF_ONESHOT, +				pdev->name, dev);  	if (r) {  		dev_err(dev->dev, "failure requesting irq %i\n", dev->irq);  		goto err_unuse_clocks;  	} -	dev_info(dev->dev, "bus %d rev%d.%d.%d at %d kHz\n", pdev->id, -		 dev->dtrev, dev->rev >> 4, dev->rev & 0xf, dev->speed); -  	adap = &dev->adapter;  	i2c_set_adapdata(adap, dev);  	adap->owner = THIS_MODULE; @@ -1081,27 +1193,25 @@ omap_i2c_probe(struct platform_device *pdev)  	r = i2c_add_numbered_adapter(adap);  	if (r) {  		dev_err(dev->dev, "failure adding adapter\n"); -		goto err_free_irq; +		goto err_unuse_clocks;  	} +	dev_info(dev->dev, "bus %d rev%d.%d.%d at %d kHz\n", adap->nr, +		 dev->dtrev, dev->rev >> 4, dev->rev & 0xf, dev->speed); +  	of_i2c_register_devices(adap); -	pm_runtime_put(dev->dev); +	pm_runtime_mark_last_busy(dev->dev); +	pm_runtime_put_autosuspend(dev->dev);  	return 0; -err_free_irq: -	free_irq(dev->irq, dev);  err_unuse_clocks:  	omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);  	pm_runtime_put(dev->dev); -	iounmap(dev->base);  	pm_runtime_disable(&pdev->dev);  err_free_mem:  	platform_set_drvdata(pdev, NULL); -	kfree(dev); -err_release_region: -	release_mem_region(mem->start, resource_size(mem));  	return r;  } @@ -1109,12 +1219,10 @@ err_release_region:  static int __devexit omap_i2c_remove(struct platform_device *pdev)  {  	struct omap_i2c_dev	*dev = platform_get_drvdata(pdev); -	struct resource		*mem;  	int ret;  	platform_set_drvdata(pdev, NULL); -	free_irq(dev->irq, dev);  	i2c_del_adapter(&dev->adapter);  	ret = pm_runtime_get_sync(&pdev->dev);  	if (IS_ERR_VALUE(ret)) @@ -1123,10 +1231,6 @@ static int __devexit omap_i2c_remove(struct platform_device *pdev)  	omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);  	pm_runtime_put(&pdev->dev);  	pm_runtime_disable(&pdev->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-rcar.c b/drivers/i2c/busses/i2c-rcar.c new file mode 100644 index 00000000000..f9399d163af --- /dev/null +++ b/drivers/i2c/busses/i2c-rcar.c @@ -0,0 +1,709 @@ +/* + *  drivers/i2c/busses/i2c-rcar.c + * + * Copyright (C) 2012 Renesas Solutions Corp. + * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> + * + * This file is based on the drivers/i2c/busses/i2c-sh7760.c + * (c) 2005-2008 MSC Vertriebsges.m.b.H, Manuel Lauss <mlau@msc-ge.com> + * + * This file used out-of-tree driver i2c-rcar.c + * Copyright (C) 2011-2012 Renesas Electronics Corporation + * + * 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 + * + * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + */ +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/i2c.h> +#include <linux/i2c/i2c-rcar.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> +#include <linux/slab.h> +#include <linux/spinlock.h> + +/* register offsets */ +#define ICSCR	0x00	/* slave ctrl */ +#define ICMCR	0x04	/* master ctrl */ +#define ICSSR	0x08	/* slave status */ +#define ICMSR	0x0C	/* master status */ +#define ICSIER	0x10	/* slave irq enable */ +#define ICMIER	0x14	/* master irq enable */ +#define ICCCR	0x18	/* clock dividers */ +#define ICSAR	0x1C	/* slave address */ +#define ICMAR	0x20	/* master address */ +#define ICRXTX	0x24	/* data port */ + +/* ICMCR */ +#define MDBS	(1 << 7)	/* non-fifo mode switch */ +#define FSCL	(1 << 6)	/* override SCL pin */ +#define FSDA	(1 << 5)	/* override SDA pin */ +#define OBPC	(1 << 4)	/* override pins */ +#define MIE	(1 << 3)	/* master if enable */ +#define TSBE	(1 << 2) +#define FSB	(1 << 1)	/* force stop bit */ +#define ESG	(1 << 0)	/* en startbit gen */ + +/* ICMSR */ +#define MNR	(1 << 6)	/* nack received */ +#define MAL	(1 << 5)	/* arbitration lost */ +#define MST	(1 << 4)	/* sent a stop */ +#define MDE	(1 << 3) +#define MDT	(1 << 2) +#define MDR	(1 << 1) +#define MAT	(1 << 0)	/* slave addr xfer done */ + +/* ICMIE */ +#define MNRE	(1 << 6)	/* nack irq en */ +#define MALE	(1 << 5)	/* arblos irq en */ +#define MSTE	(1 << 4)	/* stop irq en */ +#define MDEE	(1 << 3) +#define MDTE	(1 << 2) +#define MDRE	(1 << 1) +#define MATE	(1 << 0)	/* address sent irq en */ + + +enum { +	RCAR_BUS_PHASE_ADDR, +	RCAR_BUS_PHASE_DATA, +	RCAR_BUS_PHASE_STOP, +}; + +enum { +	RCAR_IRQ_CLOSE, +	RCAR_IRQ_OPEN_FOR_SEND, +	RCAR_IRQ_OPEN_FOR_RECV, +	RCAR_IRQ_OPEN_FOR_STOP, +}; + +/* + * flags + */ +#define ID_LAST_MSG	(1 << 0) +#define ID_IOERROR	(1 << 1) +#define ID_DONE		(1 << 2) +#define ID_ARBLOST	(1 << 3) +#define ID_NACK		(1 << 4) + +struct rcar_i2c_priv { +	void __iomem *io; +	struct i2c_adapter adap; +	struct i2c_msg	*msg; + +	spinlock_t lock; +	wait_queue_head_t wait; + +	int pos; +	int irq; +	u32 icccr; +	u32 flags; +}; + +#define rcar_i2c_priv_to_dev(p)		((p)->adap.dev.parent) +#define rcar_i2c_is_recv(p)		((p)->msg->flags & I2C_M_RD) + +#define rcar_i2c_flags_set(p, f)	((p)->flags |= (f)) +#define rcar_i2c_flags_has(p, f)	((p)->flags & (f)) + +#define LOOP_TIMEOUT	1024 + +/* + *		basic functions + */ +static void rcar_i2c_write(struct rcar_i2c_priv *priv, int reg, u32 val) +{ +	writel(val, priv->io + reg); +} + +static u32 rcar_i2c_read(struct rcar_i2c_priv *priv, int reg) +{ +	return readl(priv->io + reg); +} + +static void rcar_i2c_init(struct rcar_i2c_priv *priv) +{ +	/* +	 * reset slave mode. +	 * slave mode is not used on this driver +	 */ +	rcar_i2c_write(priv, ICSIER, 0); +	rcar_i2c_write(priv, ICSAR, 0); +	rcar_i2c_write(priv, ICSCR, 0); +	rcar_i2c_write(priv, ICSSR, 0); + +	/* reset master mode */ +	rcar_i2c_write(priv, ICMIER, 0); +	rcar_i2c_write(priv, ICMCR, 0); +	rcar_i2c_write(priv, ICMSR, 0); +	rcar_i2c_write(priv, ICMAR, 0); +} + +static void rcar_i2c_irq_mask(struct rcar_i2c_priv *priv, int open) +{ +	u32 val = MNRE | MALE | MSTE | MATE; /* default */ + +	switch (open) { +	case RCAR_IRQ_OPEN_FOR_SEND: +		val |= MDEE; /* default + send */ +		break; +	case RCAR_IRQ_OPEN_FOR_RECV: +		val |= MDRE; /* default + read */ +		break; +	case RCAR_IRQ_OPEN_FOR_STOP: +		val = MSTE; /* stop irq only */ +		break; +	case RCAR_IRQ_CLOSE: +	default: +		val = 0; /* all close */ +		break; +	} +	rcar_i2c_write(priv, ICMIER, val); +} + +static void rcar_i2c_set_addr(struct rcar_i2c_priv *priv, u32 recv) +{ +	rcar_i2c_write(priv, ICMAR, (priv->msg->addr << 1) | recv); +} + +/* + *		bus control functions + */ +static int rcar_i2c_bus_barrier(struct rcar_i2c_priv *priv) +{ +	int i; + +	for (i = 0; i < LOOP_TIMEOUT; i++) { +		/* make sure that bus is not busy */ +		if (!(rcar_i2c_read(priv, ICMCR) & FSDA)) +			return 0; +		udelay(1); +	} + +	return -EBUSY; +} + +static void rcar_i2c_bus_phase(struct rcar_i2c_priv *priv, int phase) +{ +	switch (phase) { +	case RCAR_BUS_PHASE_ADDR: +		rcar_i2c_write(priv, ICMCR, MDBS | MIE | ESG); +		break; +	case RCAR_BUS_PHASE_DATA: +		rcar_i2c_write(priv, ICMCR, MDBS | MIE); +		break; +	case RCAR_BUS_PHASE_STOP: +		rcar_i2c_write(priv, ICMCR, MDBS | MIE | FSB); +		break; +	} +} + +/* + *		clock function + */ +static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv, +				    u32 bus_speed, +				    struct device *dev) +{ +	struct clk *clkp = clk_get(NULL, "peripheral_clk"); +	u32 scgd, cdf; +	u32 round, ick; +	u32 scl; + +	if (!clkp) { +		dev_err(dev, "there is no peripheral_clk\n"); +		return -EIO; +	} + +	/* +	 * calculate SCL clock +	 * see +	 *	ICCCR +	 * +	 * ick	= clkp / (1 + CDF) +	 * SCL	= ick / (20 + SCGD * 8 + F[(ticf + tr + intd) * ick]) +	 * +	 * ick  : I2C internal clock < 20 MHz +	 * ticf : I2C SCL falling time  =  35 ns here +	 * tr   : I2C SCL rising  time  = 200 ns here +	 * intd : LSI internal delay    =  50 ns here +	 * clkp : peripheral_clk +	 * F[]  : integer up-valuation +	 */ +	for (cdf = 0; cdf < 4; cdf++) { +		ick = clk_get_rate(clkp) / (1 + cdf); +		if (ick < 20000000) +			goto ick_find; +	} +	dev_err(dev, "there is no best CDF\n"); +	return -EIO; + +ick_find: +	/* +	 * it is impossible to calculate large scale +	 * number on u32. separate it +	 * +	 * F[(ticf + tr + intd) * ick] +	 *  = F[(35 + 200 + 50)ns * ick] +	 *  = F[285 * ick / 1000000000] +	 *  = F[(ick / 1000000) * 285 / 1000] +	 */ +	round = (ick + 500000) / 1000000 * 285; +	round = (round + 500) / 1000; + +	/* +	 * SCL	= ick / (20 + SCGD * 8 + F[(ticf + tr + intd) * ick]) +	 * +	 * Calculation result (= SCL) should be less than +	 * bus_speed for hardware safety +	 */ +	for (scgd = 0; scgd < 0x40; scgd++) { +		scl = ick / (20 + (scgd * 8) + round); +		if (scl <= bus_speed) +			goto scgd_find; +	} +	dev_err(dev, "it is impossible to calculate best SCL\n"); +	return -EIO; + +scgd_find: +	dev_dbg(dev, "clk %d/%d(%lu), round %u, CDF:0x%x, SCGD: 0x%x\n", +		scl, bus_speed, clk_get_rate(clkp), round, cdf, scgd); + +	/* +	 * keep icccr value +	 */ +	priv->icccr = (scgd << 2 | cdf); + +	return 0; +} + +static void rcar_i2c_clock_start(struct rcar_i2c_priv *priv) +{ +	rcar_i2c_write(priv, ICCCR, priv->icccr); +} + +/* + *		status functions + */ +static u32 rcar_i2c_status_get(struct rcar_i2c_priv *priv) +{ +	return rcar_i2c_read(priv, ICMSR); +} + +#define rcar_i2c_status_clear(priv) rcar_i2c_status_bit_clear(priv, 0xffffffff) +static void rcar_i2c_status_bit_clear(struct rcar_i2c_priv *priv, u32 bit) +{ +	rcar_i2c_write(priv, ICMSR, ~bit); +} + +/* + *		recv/send functions + */ +static int rcar_i2c_recv(struct rcar_i2c_priv *priv) +{ +	rcar_i2c_set_addr(priv, 1); +	rcar_i2c_status_clear(priv); +	rcar_i2c_bus_phase(priv, RCAR_BUS_PHASE_ADDR); +	rcar_i2c_irq_mask(priv, RCAR_IRQ_OPEN_FOR_RECV); + +	return 0; +} + +static int rcar_i2c_send(struct rcar_i2c_priv *priv) +{ +	int ret; + +	/* +	 * It should check bus status when send case +	 */ +	ret = rcar_i2c_bus_barrier(priv); +	if (ret < 0) +		return ret; + +	rcar_i2c_set_addr(priv, 0); +	rcar_i2c_status_clear(priv); +	rcar_i2c_bus_phase(priv, RCAR_BUS_PHASE_ADDR); +	rcar_i2c_irq_mask(priv, RCAR_IRQ_OPEN_FOR_SEND); + +	return 0; +} + +#define rcar_i2c_send_restart(priv) rcar_i2c_status_bit_clear(priv, (MAT | MDE)) +#define rcar_i2c_recv_restart(priv) rcar_i2c_status_bit_clear(priv, (MAT | MDR)) + +/* + *		interrupt functions + */ +static int rcar_i2c_irq_send(struct rcar_i2c_priv *priv, u32 msr) +{ +	struct i2c_msg *msg = priv->msg; + +	/* +	 * FIXME +	 * sometimes, unknown interrupt happened. +	 * Do nothing +	 */ +	if (!(msr & MDE)) +		return 0; + +	/* +	 * If address transfer phase finished, +	 * goto data phase. +	 */ +	if (msr & MAT) +		rcar_i2c_bus_phase(priv, RCAR_BUS_PHASE_DATA); + +	if (priv->pos < msg->len) { +		/* +		 * Prepare next data to ICRXTX register. +		 * This data will go to _SHIFT_ register. +		 * +		 *    * +		 * [ICRXTX] -> [SHIFT] -> [I2C bus] +		 */ +		rcar_i2c_write(priv, ICRXTX, msg->buf[priv->pos]); +		priv->pos++; + +	} else { +		/* +		 * The last data was pushed to ICRXTX on _PREV_ empty irq. +		 * It is on _SHIFT_ register, and will sent to I2C bus. +		 * +		 *		  * +		 * [ICRXTX] -> [SHIFT] -> [I2C bus] +		 */ + +		if (priv->flags & ID_LAST_MSG) +			/* +			 * If current msg is the _LAST_ msg, +			 * prepare stop condition here. +			 * ID_DONE will be set on STOP irq. +			 */ +			rcar_i2c_bus_phase(priv, RCAR_BUS_PHASE_STOP); +		else +			/* +			 * If current msg is _NOT_ last msg, +			 * it doesn't call stop phase. +			 * thus, there is no STOP irq. +			 * return ID_DONE here. +			 */ +			return ID_DONE; +	} + +	rcar_i2c_send_restart(priv); + +	return 0; +} + +static int rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr) +{ +	struct i2c_msg *msg = priv->msg; + +	/* +	 * FIXME +	 * sometimes, unknown interrupt happened. +	 * Do nothing +	 */ +	if (!(msr & MDR)) +		return 0; + +	if (msr & MAT) { +		/* +		 * Address transfer phase finished, +		 * but, there is no data at this point. +		 * Do nothing. +		 */ +	} else if (priv->pos < msg->len) { +		/* +		 * get received data +		 */ +		msg->buf[priv->pos] = rcar_i2c_read(priv, ICRXTX); +		priv->pos++; +	} + +	/* +	 * If next received data is the _LAST_, +	 * go to STOP phase, +	 * otherwise, go to DATA phase. +	 */ +	if (priv->pos + 1 >= msg->len) +		rcar_i2c_bus_phase(priv, RCAR_BUS_PHASE_STOP); +	else +		rcar_i2c_bus_phase(priv, RCAR_BUS_PHASE_DATA); + +	rcar_i2c_recv_restart(priv); + +	return 0; +} + +static irqreturn_t rcar_i2c_irq(int irq, void *ptr) +{ +	struct rcar_i2c_priv *priv = ptr; +	struct device *dev = rcar_i2c_priv_to_dev(priv); +	u32 msr; + +	/*-------------- spin lock -----------------*/ +	spin_lock(&priv->lock); + +	msr = rcar_i2c_status_get(priv); + +	/* +	 * Arbitration lost +	 */ +	if (msr & MAL) { +		/* +		 * CAUTION +		 * +		 * When arbitration lost, device become _slave_ mode. +		 */ +		dev_dbg(dev, "Arbitration Lost\n"); +		rcar_i2c_flags_set(priv, (ID_DONE | ID_ARBLOST)); +		goto out; +	} + +	/* +	 * Stop +	 */ +	if (msr & MST) { +		dev_dbg(dev, "Stop\n"); +		rcar_i2c_flags_set(priv, ID_DONE); +		goto out; +	} + +	/* +	 * Nack +	 */ +	if (msr & MNR) { +		dev_dbg(dev, "Nack\n"); + +		/* go to stop phase */ +		rcar_i2c_bus_phase(priv, RCAR_BUS_PHASE_STOP); +		rcar_i2c_irq_mask(priv, RCAR_IRQ_OPEN_FOR_STOP); +		rcar_i2c_flags_set(priv, ID_NACK); +		goto out; +	} + +	/* +	 * recv/send +	 */ +	if (rcar_i2c_is_recv(priv)) +		rcar_i2c_flags_set(priv, rcar_i2c_irq_recv(priv, msr)); +	else +		rcar_i2c_flags_set(priv, rcar_i2c_irq_send(priv, msr)); + +out: +	if (rcar_i2c_flags_has(priv, ID_DONE)) { +		rcar_i2c_irq_mask(priv, RCAR_IRQ_CLOSE); +		rcar_i2c_status_clear(priv); +		wake_up(&priv->wait); +	} + +	spin_unlock(&priv->lock); +	/*-------------- spin unlock -----------------*/ + +	return IRQ_HANDLED; +} + +static int rcar_i2c_master_xfer(struct i2c_adapter *adap, +				struct i2c_msg *msgs, +				int num) +{ +	struct rcar_i2c_priv *priv = i2c_get_adapdata(adap); +	struct device *dev = rcar_i2c_priv_to_dev(priv); +	unsigned long flags; +	int i, ret, timeout; + +	pm_runtime_get_sync(dev); + +	/*-------------- spin lock -----------------*/ +	spin_lock_irqsave(&priv->lock, flags); + +	rcar_i2c_init(priv); +	rcar_i2c_clock_start(priv); + +	spin_unlock_irqrestore(&priv->lock, flags); +	/*-------------- spin unlock -----------------*/ + +	ret = -EINVAL; +	for (i = 0; i < num; i++) { +		/*-------------- spin lock -----------------*/ +		spin_lock_irqsave(&priv->lock, flags); + +		/* init each data */ +		priv->msg	= &msgs[i]; +		priv->pos	= 0; +		priv->flags	= 0; +		if (priv->msg == &msgs[num - 1]) +			rcar_i2c_flags_set(priv, ID_LAST_MSG); + +		/* start send/recv */ +		if (rcar_i2c_is_recv(priv)) +			ret = rcar_i2c_recv(priv); +		else +			ret = rcar_i2c_send(priv); + +		spin_unlock_irqrestore(&priv->lock, flags); +		/*-------------- spin unlock -----------------*/ + +		if (ret < 0) +			break; + +		/* +		 * wait result +		 */ +		timeout = wait_event_timeout(priv->wait, +					     rcar_i2c_flags_has(priv, ID_DONE), +					     5 * HZ); +		if (!timeout) { +			ret = -ETIMEDOUT; +			break; +		} + +		/* +		 * error handling +		 */ +		if (rcar_i2c_flags_has(priv, ID_NACK)) { +			ret = -EREMOTEIO; +			break; +		} + +		if (rcar_i2c_flags_has(priv, ID_ARBLOST)) { +			ret = -EAGAIN; +			break; +		} + +		if (rcar_i2c_flags_has(priv, ID_IOERROR)) { +			ret = -EIO; +			break; +		} + +		ret = i + 1; /* The number of transfer */ +	} + +	pm_runtime_put(dev); + +	if (ret < 0) +		dev_err(dev, "error %d : %x\n", ret, priv->flags); + +	return ret; +} + +static u32 rcar_i2c_func(struct i2c_adapter *adap) +{ +	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +static const struct i2c_algorithm rcar_i2c_algo = { +	.master_xfer	= rcar_i2c_master_xfer, +	.functionality	= rcar_i2c_func, +}; + +static int __devinit rcar_i2c_probe(struct platform_device *pdev) +{ +	struct i2c_rcar_platform_data *pdata = pdev->dev.platform_data; +	struct rcar_i2c_priv *priv; +	struct i2c_adapter *adap; +	struct resource *res; +	struct device *dev = &pdev->dev; +	u32 bus_speed; +	int ret; + +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	if (!res) { +		dev_err(dev, "no mmio resources\n"); +		return -ENODEV; +	} + +	priv = devm_kzalloc(dev, sizeof(struct rcar_i2c_priv), GFP_KERNEL); +	if (!priv) { +		dev_err(dev, "no mem for private data\n"); +		return -ENOMEM; +	} + +	bus_speed = 100000; /* default 100 kHz */ +	if (pdata && pdata->bus_speed) +		bus_speed = pdata->bus_speed; +	ret = rcar_i2c_clock_calculate(priv, bus_speed, dev); +	if (ret < 0) +		return ret; + +	priv->io = devm_ioremap(dev, res->start, resource_size(res)); +	if (!priv->io) { +		dev_err(dev, "cannot ioremap\n"); +		return -ENODEV; +	} + +	priv->irq = platform_get_irq(pdev, 0); +	init_waitqueue_head(&priv->wait); +	spin_lock_init(&priv->lock); + +	adap			= &priv->adap; +	adap->nr		= pdev->id; +	adap->algo		= &rcar_i2c_algo; +	adap->class		= I2C_CLASS_HWMON | I2C_CLASS_SPD; +	adap->retries		= 3; +	adap->dev.parent	= dev; +	i2c_set_adapdata(adap, priv); +	strlcpy(adap->name, pdev->name, sizeof(adap->name)); + +	ret = devm_request_irq(dev, priv->irq, rcar_i2c_irq, 0, +			       dev_name(dev), priv); +	if (ret < 0) { +		dev_err(dev, "cannot get irq %d\n", priv->irq); +		return ret; +	} + +	ret = i2c_add_numbered_adapter(adap); +	if (ret < 0) { +		dev_err(dev, "reg adap failed: %d\n", ret); +		return ret; +	} + +	pm_runtime_enable(dev); +	platform_set_drvdata(pdev, priv); + +	dev_info(dev, "probed\n"); + +	return 0; +} + +static int __devexit rcar_i2c_remove(struct platform_device *pdev) +{ +	struct rcar_i2c_priv *priv = platform_get_drvdata(pdev); +	struct device *dev = &pdev->dev; + +	i2c_del_adapter(&priv->adap); +	pm_runtime_disable(dev); + +	return 0; +} + +static struct platform_driver rcar_i2c_drv = { +	.driver	= { +		.name	= "i2c-rcar", +		.owner	= THIS_MODULE, +	}, +	.probe		= rcar_i2c_probe, +	.remove		= __devexit_p(rcar_i2c_remove), +}; + +module_platform_driver(rcar_i2c_drv); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Renesas R-Car I2C bus driver"); +MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"); diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 5ae3b0236bd..59cfcb45691 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -601,14 +601,14 @@ static int s3c24xx_i2c_xfer(struct i2c_adapter *adap,  	int ret;  	pm_runtime_get_sync(&adap->dev); -	clk_enable(i2c->clk); +	clk_prepare_enable(i2c->clk);  	for (retry = 0; retry < adap->retries; retry++) {  		ret = s3c24xx_i2c_doxfer(i2c, msgs, num);  		if (ret != -EAGAIN) { -			clk_disable(i2c->clk); +			clk_disable_unprepare(i2c->clk);  			pm_runtime_put(&adap->dev);  			return ret;  		} @@ -618,7 +618,7 @@ static int s3c24xx_i2c_xfer(struct i2c_adapter *adap,  		udelay(100);  	} -	clk_disable(i2c->clk); +	clk_disable_unprepare(i2c->clk);  	pm_runtime_put(&adap->dev);  	return -EREMOTEIO;  } @@ -977,7 +977,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)  	dev_dbg(&pdev->dev, "clock source %p\n", i2c->clk); -	clk_enable(i2c->clk); +	clk_prepare_enable(i2c->clk);  	/* map the registers */ @@ -1065,7 +1065,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)  	pm_runtime_enable(&i2c->adap.dev);  	dev_info(&pdev->dev, "%s: S3C I2C adapter\n", dev_name(&i2c->adap.dev)); -	clk_disable(i2c->clk); +	clk_disable_unprepare(i2c->clk);  	return 0;   err_cpufreq: @@ -1082,7 +1082,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)  	kfree(i2c->ioarea);   err_clk: -	clk_disable(i2c->clk); +	clk_disable_unprepare(i2c->clk);  	clk_put(i2c->clk);   err_noclk: @@ -1106,7 +1106,7 @@ static int s3c24xx_i2c_remove(struct platform_device *pdev)  	i2c_del_adapter(&i2c->adap);  	free_irq(i2c->irq, i2c); -	clk_disable(i2c->clk); +	clk_disable_unprepare(i2c->clk);  	clk_put(i2c->clk);  	iounmap(i2c->regs); @@ -1135,9 +1135,9 @@ static int s3c24xx_i2c_resume(struct device *dev)  	struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev);  	i2c->suspended = 0; -	clk_enable(i2c->clk); +	clk_prepare_enable(i2c->clk);  	s3c24xx_i2c_init(i2c); -	clk_disable(i2c->clk); +	clk_disable_unprepare(i2c->clk);  	return 0;  }  |