xref: /openbmc/linux/drivers/i2c/busses/i2c-pnx.c (revision 55e43d6abd078ed6d219902ce8cb4d68e3c993ba)
141561f28SVitaly Wool /*
241561f28SVitaly Wool  * Provides I2C support for Philips PNX010x/PNX4008 boards.
341561f28SVitaly Wool  *
441561f28SVitaly Wool  * Authors: Dennis Kovalev <dkovalev@ru.mvista.com>
541561f28SVitaly Wool  *	    Vitaly Wool <vwool@ru.mvista.com>
641561f28SVitaly Wool  *
741561f28SVitaly Wool  * 2004-2006 (c) MontaVista Software, Inc. This file is licensed under
841561f28SVitaly Wool  * the terms of the GNU General Public License version 2. This program
941561f28SVitaly Wool  * is licensed "as is" without any warranty of any kind, whether express
1041561f28SVitaly Wool  * or implied.
1141561f28SVitaly Wool  */
1241561f28SVitaly Wool 
1341561f28SVitaly Wool #include <linux/module.h>
1441561f28SVitaly Wool #include <linux/interrupt.h>
1541561f28SVitaly Wool #include <linux/ioport.h>
1641561f28SVitaly Wool #include <linux/delay.h>
1741561f28SVitaly Wool #include <linux/i2c.h>
1841561f28SVitaly Wool #include <linux/completion.h>
1941561f28SVitaly Wool #include <linux/platform_device.h>
20a7d73d8cSKevin Wells #include <linux/io.h>
210321cb83SRussell King #include <linux/err.h>
220321cb83SRussell King #include <linux/clk.h>
235a0e3ad6STejun Heo #include <linux/slab.h>
244edd65e6SSachin Kamat #include <linux/of.h>
250321cb83SRussell King 
26b41a216dSRoland Stigge #define I2C_PNX_TIMEOUT_DEFAULT		10 /* msec */
27b41a216dSRoland Stigge #define I2C_PNX_SPEED_KHZ_DEFAULT	100
2841561f28SVitaly Wool #define I2C_PNX_REGION_SIZE		0x100
2941561f28SVitaly Wool 
30caaccda1SWolfram Sang struct i2c_pnx_mif {
31caaccda1SWolfram Sang 	int			ret;		/* Return value */
32caaccda1SWolfram Sang 	int			mode;		/* Interface mode */
33caaccda1SWolfram Sang 	struct completion	complete;	/* I/O completion */
34caaccda1SWolfram Sang 	u8 *			buf;		/* Data buffer */
35caaccda1SWolfram Sang 	int			len;		/* Length of data buffer */
36caaccda1SWolfram Sang 	int			order;		/* RX Bytes to order via TX */
37caaccda1SWolfram Sang };
38caaccda1SWolfram Sang 
39caaccda1SWolfram Sang struct i2c_pnx_algo_data {
40caaccda1SWolfram Sang 	void __iomem		*ioaddr;
41caaccda1SWolfram Sang 	struct i2c_pnx_mif	mif;
42caaccda1SWolfram Sang 	int			last;
43caaccda1SWolfram Sang 	struct clk		*clk;
44caaccda1SWolfram Sang 	struct i2c_adapter	adapter;
45caaccda1SWolfram Sang 	int			irq;
46caaccda1SWolfram Sang 	u32			timeout;
47caaccda1SWolfram Sang };
48caaccda1SWolfram Sang 
49be460385SRoland Stigge enum {
50be460385SRoland Stigge 	mstatus_tdi = 0x00000001,
51be460385SRoland Stigge 	mstatus_afi = 0x00000002,
52be460385SRoland Stigge 	mstatus_nai = 0x00000004,
53be460385SRoland Stigge 	mstatus_drmi = 0x00000008,
54be460385SRoland Stigge 	mstatus_active = 0x00000020,
55be460385SRoland Stigge 	mstatus_scl = 0x00000040,
56be460385SRoland Stigge 	mstatus_sda = 0x00000080,
57be460385SRoland Stigge 	mstatus_rff = 0x00000100,
58be460385SRoland Stigge 	mstatus_rfe = 0x00000200,
59be460385SRoland Stigge 	mstatus_tff = 0x00000400,
60be460385SRoland Stigge 	mstatus_tfe = 0x00000800,
61be460385SRoland Stigge };
62be460385SRoland Stigge 
63be460385SRoland Stigge enum {
64be460385SRoland Stigge 	mcntrl_tdie = 0x00000001,
65be460385SRoland Stigge 	mcntrl_afie = 0x00000002,
66be460385SRoland Stigge 	mcntrl_naie = 0x00000004,
67be460385SRoland Stigge 	mcntrl_drmie = 0x00000008,
68b3aafe80SRoland Stigge 	mcntrl_drsie = 0x00000010,
69b3aafe80SRoland Stigge 	mcntrl_rffie = 0x00000020,
70b3aafe80SRoland Stigge 	mcntrl_daie = 0x00000040,
71be460385SRoland Stigge 	mcntrl_tffie = 0x00000080,
72be460385SRoland Stigge 	mcntrl_reset = 0x00000100,
73be460385SRoland Stigge 	mcntrl_cdbmode = 0x00000400,
74be460385SRoland Stigge };
75be460385SRoland Stigge 
76be460385SRoland Stigge enum {
77be460385SRoland Stigge 	rw_bit = 1 << 0,
78be460385SRoland Stigge 	start_bit = 1 << 8,
79be460385SRoland Stigge 	stop_bit = 1 << 9,
80be460385SRoland Stigge };
81be460385SRoland Stigge 
82be460385SRoland Stigge #define I2C_REG_RX(a)	((a)->ioaddr)		/* Rx FIFO reg (RO) */
83be460385SRoland Stigge #define I2C_REG_TX(a)	((a)->ioaddr)		/* Tx FIFO reg (WO) */
84be460385SRoland Stigge #define I2C_REG_STS(a)	((a)->ioaddr + 0x04)	/* Status reg (RO) */
85be460385SRoland Stigge #define I2C_REG_CTL(a)	((a)->ioaddr + 0x08)	/* Ctl reg */
86be460385SRoland Stigge #define I2C_REG_CKL(a)	((a)->ioaddr + 0x0c)	/* Clock divider low */
87be460385SRoland Stigge #define I2C_REG_CKH(a)	((a)->ioaddr + 0x10)	/* Clock divider high */
88be460385SRoland Stigge #define I2C_REG_ADR(a)	((a)->ioaddr + 0x14)	/* I2C address */
89be460385SRoland Stigge #define I2C_REG_RFL(a)	((a)->ioaddr + 0x18)	/* Rx FIFO level (RO) */
90be460385SRoland Stigge #define I2C_REG_TFL(a)	((a)->ioaddr + 0x1c)	/* Tx FIFO level (RO) */
91be460385SRoland Stigge #define I2C_REG_RXB(a)	((a)->ioaddr + 0x20)	/* Num of bytes Rx-ed (RO) */
92be460385SRoland Stigge #define I2C_REG_TXB(a)	((a)->ioaddr + 0x24)	/* Num of bytes Tx-ed (RO) */
93be460385SRoland Stigge #define I2C_REG_TXS(a)	((a)->ioaddr + 0x28)	/* Tx slave FIFO (RO) */
94be460385SRoland Stigge #define I2C_REG_STFL(a)	((a)->ioaddr + 0x2c)	/* Tx slave FIFO level (RO) */
95be460385SRoland Stigge 
wait_timeout(struct i2c_pnx_algo_data * data)96b41a216dSRoland Stigge static inline int wait_timeout(struct i2c_pnx_algo_data *data)
9741561f28SVitaly Wool {
98*e4ee7050SVladimir Riabchun 	long timeout = jiffies_to_msecs(data->timeout);
9941561f28SVitaly Wool 	while (timeout > 0 &&
10041561f28SVitaly Wool 			(ioread32(I2C_REG_STS(data)) & mstatus_active)) {
10141561f28SVitaly Wool 		mdelay(1);
10241561f28SVitaly Wool 		timeout--;
10341561f28SVitaly Wool 	}
10441561f28SVitaly Wool 	return (timeout <= 0);
10541561f28SVitaly Wool }
10641561f28SVitaly Wool 
wait_reset(struct i2c_pnx_algo_data * data)107b41a216dSRoland Stigge static inline int wait_reset(struct i2c_pnx_algo_data *data)
10841561f28SVitaly Wool {
109*e4ee7050SVladimir Riabchun 	long timeout = jiffies_to_msecs(data->timeout);
11041561f28SVitaly Wool 	while (timeout > 0 &&
11141561f28SVitaly Wool 			(ioread32(I2C_REG_CTL(data)) & mcntrl_reset)) {
11241561f28SVitaly Wool 		mdelay(1);
11341561f28SVitaly Wool 		timeout--;
11441561f28SVitaly Wool 	}
11541561f28SVitaly Wool 	return (timeout <= 0);
11641561f28SVitaly Wool }
11741561f28SVitaly Wool 
11841561f28SVitaly Wool /**
11941561f28SVitaly Wool  * i2c_pnx_start - start a device
12041561f28SVitaly Wool  * @slave_addr:		slave address
1213e0f8672SLee Jones  * @alg_data:		pointer to local driver data structure
12241561f28SVitaly Wool  *
12341561f28SVitaly Wool  * Generate a START signal in the desired mode.
12441561f28SVitaly Wool  */
i2c_pnx_start(unsigned char slave_addr,struct i2c_pnx_algo_data * alg_data)12581d6724aSRussell King static int i2c_pnx_start(unsigned char slave_addr,
12681d6724aSRussell King 	struct i2c_pnx_algo_data *alg_data)
12741561f28SVitaly Wool {
12881d6724aSRussell King 	dev_dbg(&alg_data->adapter.dev, "%s(): addr 0x%x mode %d\n", __func__,
12941561f28SVitaly Wool 		slave_addr, alg_data->mif.mode);
13041561f28SVitaly Wool 
13141561f28SVitaly Wool 	/* Check for 7 bit slave addresses only */
13241561f28SVitaly Wool 	if (slave_addr & ~0x7f) {
1334be53dbeSRussell King 		dev_err(&alg_data->adapter.dev,
1344be53dbeSRussell King 			"%s: Invalid slave address %x. Only 7-bit addresses are supported\n",
13581d6724aSRussell King 			alg_data->adapter.name, slave_addr);
13641561f28SVitaly Wool 		return -EINVAL;
13741561f28SVitaly Wool 	}
13841561f28SVitaly Wool 
13941561f28SVitaly Wool 	/* First, make sure bus is idle */
140b41a216dSRoland Stigge 	if (wait_timeout(alg_data)) {
14141561f28SVitaly Wool 		/* Somebody else is monopolizing the bus */
1424be53dbeSRussell King 		dev_err(&alg_data->adapter.dev,
1434be53dbeSRussell King 			"%s: Bus busy. Slave addr = %02x, cntrl = %x, stat = %x\n",
14481d6724aSRussell King 			alg_data->adapter.name, slave_addr,
14541561f28SVitaly Wool 			ioread32(I2C_REG_CTL(alg_data)),
14641561f28SVitaly Wool 			ioread32(I2C_REG_STS(alg_data)));
14741561f28SVitaly Wool 		return -EBUSY;
14841561f28SVitaly Wool 	} else if (ioread32(I2C_REG_STS(alg_data)) & mstatus_afi) {
14941561f28SVitaly Wool 		/* Sorry, we lost the bus */
1504be53dbeSRussell King 		dev_err(&alg_data->adapter.dev,
1514be53dbeSRussell King 		        "%s: Arbitration failure. Slave addr = %02x\n",
1524be53dbeSRussell King 			alg_data->adapter.name, slave_addr);
15341561f28SVitaly Wool 		return -EIO;
15441561f28SVitaly Wool 	}
15541561f28SVitaly Wool 
15641561f28SVitaly Wool 	/*
15741561f28SVitaly Wool 	 * OK, I2C is enabled and we have the bus.
15841561f28SVitaly Wool 	 * Clear the current TDI and AFI status flags.
15941561f28SVitaly Wool 	 */
16041561f28SVitaly Wool 	iowrite32(ioread32(I2C_REG_STS(alg_data)) | mstatus_tdi | mstatus_afi,
16141561f28SVitaly Wool 		  I2C_REG_STS(alg_data));
16241561f28SVitaly Wool 
16381d6724aSRussell King 	dev_dbg(&alg_data->adapter.dev, "%s(): sending %#x\n", __func__,
16441561f28SVitaly Wool 		(slave_addr << 1) | start_bit | alg_data->mif.mode);
16541561f28SVitaly Wool 
16641561f28SVitaly Wool 	/* Write the slave address, START bit and R/W bit */
16741561f28SVitaly Wool 	iowrite32((slave_addr << 1) | start_bit | alg_data->mif.mode,
16841561f28SVitaly Wool 		  I2C_REG_TX(alg_data));
16941561f28SVitaly Wool 
17081d6724aSRussell King 	dev_dbg(&alg_data->adapter.dev, "%s(): exit\n", __func__);
17141561f28SVitaly Wool 
17241561f28SVitaly Wool 	return 0;
17341561f28SVitaly Wool }
17441561f28SVitaly Wool 
17541561f28SVitaly Wool /**
17641561f28SVitaly Wool  * i2c_pnx_stop - stop a device
1773e0f8672SLee Jones  * @alg_data:		pointer to local driver data structure
17841561f28SVitaly Wool  *
17941561f28SVitaly Wool  * Generate a STOP signal to terminate the master transaction.
18041561f28SVitaly Wool  */
i2c_pnx_stop(struct i2c_pnx_algo_data * alg_data)18181d6724aSRussell King static void i2c_pnx_stop(struct i2c_pnx_algo_data *alg_data)
18241561f28SVitaly Wool {
18341561f28SVitaly Wool 	/* Only 1 msec max timeout due to interrupt context */
18441561f28SVitaly Wool 	long timeout = 1000;
18541561f28SVitaly Wool 
18681d6724aSRussell King 	dev_dbg(&alg_data->adapter.dev, "%s(): entering: stat = %04x.\n",
18708882d20SHarvey Harrison 		__func__, ioread32(I2C_REG_STS(alg_data)));
18841561f28SVitaly Wool 
18941561f28SVitaly Wool 	/* Write a STOP bit to TX FIFO */
19041561f28SVitaly Wool 	iowrite32(0xff | stop_bit, I2C_REG_TX(alg_data));
19141561f28SVitaly Wool 
19241561f28SVitaly Wool 	/* Wait until the STOP is seen. */
19341561f28SVitaly Wool 	while (timeout > 0 &&
19441561f28SVitaly Wool 	       (ioread32(I2C_REG_STS(alg_data)) & mstatus_active)) {
19541561f28SVitaly Wool 		/* may be called from interrupt context */
19641561f28SVitaly Wool 		udelay(1);
19741561f28SVitaly Wool 		timeout--;
19841561f28SVitaly Wool 	}
19941561f28SVitaly Wool 
20081d6724aSRussell King 	dev_dbg(&alg_data->adapter.dev, "%s(): exiting: stat = %04x.\n",
20108882d20SHarvey Harrison 		__func__, ioread32(I2C_REG_STS(alg_data)));
20241561f28SVitaly Wool }
20341561f28SVitaly Wool 
20441561f28SVitaly Wool /**
20541561f28SVitaly Wool  * i2c_pnx_master_xmit - transmit data to slave
2063e0f8672SLee Jones  * @alg_data:		pointer to local driver data structure
20741561f28SVitaly Wool  *
20841561f28SVitaly Wool  * Sends one byte of data to the slave
20941561f28SVitaly Wool  */
i2c_pnx_master_xmit(struct i2c_pnx_algo_data * alg_data)21081d6724aSRussell King static int i2c_pnx_master_xmit(struct i2c_pnx_algo_data *alg_data)
21141561f28SVitaly Wool {
21241561f28SVitaly Wool 	u32 val;
21341561f28SVitaly Wool 
21481d6724aSRussell King 	dev_dbg(&alg_data->adapter.dev, "%s(): entering: stat = %04x.\n",
21508882d20SHarvey Harrison 		__func__, ioread32(I2C_REG_STS(alg_data)));
21641561f28SVitaly Wool 
21741561f28SVitaly Wool 	if (alg_data->mif.len > 0) {
21841561f28SVitaly Wool 		/* We still have something to talk about... */
21941561f28SVitaly Wool 		val = *alg_data->mif.buf++;
22041561f28SVitaly Wool 
22128ad3321SKevin Wells 		if (alg_data->mif.len == 1)
22228ad3321SKevin Wells 			val |= stop_bit;
22328ad3321SKevin Wells 
22441561f28SVitaly Wool 		alg_data->mif.len--;
22541561f28SVitaly Wool 		iowrite32(val, I2C_REG_TX(alg_data));
22641561f28SVitaly Wool 
2274be53dbeSRussell King 		dev_dbg(&alg_data->adapter.dev, "%s(): xmit %#x [%d]\n",
2284be53dbeSRussell King 			__func__, val, alg_data->mif.len + 1);
22941561f28SVitaly Wool 
23041561f28SVitaly Wool 		if (alg_data->mif.len == 0) {
23141561f28SVitaly Wool 			if (alg_data->last) {
23241561f28SVitaly Wool 				/* Wait until the STOP is seen. */
233b41a216dSRoland Stigge 				if (wait_timeout(alg_data))
2344be53dbeSRussell King 					dev_err(&alg_data->adapter.dev,
2354be53dbeSRussell King 						"The bus is still active after timeout\n");
23641561f28SVitaly Wool 			}
23741561f28SVitaly Wool 			/* Disable master interrupts */
23841561f28SVitaly Wool 			iowrite32(ioread32(I2C_REG_CTL(alg_data)) &
23941561f28SVitaly Wool 				~(mcntrl_afie | mcntrl_naie | mcntrl_drmie),
24041561f28SVitaly Wool 				  I2C_REG_CTL(alg_data));
24141561f28SVitaly Wool 
2424be53dbeSRussell King 			dev_dbg(&alg_data->adapter.dev,
2434be53dbeSRussell King 				"%s(): Waking up xfer routine.\n",
24408882d20SHarvey Harrison 				__func__);
24541561f28SVitaly Wool 
24641561f28SVitaly Wool 			complete(&alg_data->mif.complete);
24741561f28SVitaly Wool 		}
24841561f28SVitaly Wool 	} else if (alg_data->mif.len == 0) {
24941561f28SVitaly Wool 		/* zero-sized transfer */
25081d6724aSRussell King 		i2c_pnx_stop(alg_data);
25141561f28SVitaly Wool 
25241561f28SVitaly Wool 		/* Disable master interrupts. */
25341561f28SVitaly Wool 		iowrite32(ioread32(I2C_REG_CTL(alg_data)) &
25441561f28SVitaly Wool 			~(mcntrl_afie | mcntrl_naie | mcntrl_drmie),
25541561f28SVitaly Wool 			  I2C_REG_CTL(alg_data));
25641561f28SVitaly Wool 
2574be53dbeSRussell King 		dev_dbg(&alg_data->adapter.dev,
2584be53dbeSRussell King 			"%s(): Waking up xfer routine after zero-xfer.\n",
2594be53dbeSRussell King 			__func__);
26041561f28SVitaly Wool 
26141561f28SVitaly Wool 		complete(&alg_data->mif.complete);
26241561f28SVitaly Wool 	}
26341561f28SVitaly Wool 
26481d6724aSRussell King 	dev_dbg(&alg_data->adapter.dev, "%s(): exiting: stat = %04x.\n",
26508882d20SHarvey Harrison 		__func__, ioread32(I2C_REG_STS(alg_data)));
26641561f28SVitaly Wool 
26741561f28SVitaly Wool 	return 0;
26841561f28SVitaly Wool }
26941561f28SVitaly Wool 
27041561f28SVitaly Wool /**
27141561f28SVitaly Wool  * i2c_pnx_master_rcv - receive data from slave
2723e0f8672SLee Jones  * @alg_data:		pointer to local driver data structure
27341561f28SVitaly Wool  *
27441561f28SVitaly Wool  * Reads one byte data from the slave
27541561f28SVitaly Wool  */
i2c_pnx_master_rcv(struct i2c_pnx_algo_data * alg_data)27681d6724aSRussell King static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data)
27741561f28SVitaly Wool {
27841561f28SVitaly Wool 	unsigned int val = 0;
27941561f28SVitaly Wool 	u32 ctl = 0;
28041561f28SVitaly Wool 
28181d6724aSRussell King 	dev_dbg(&alg_data->adapter.dev, "%s(): entering: stat = %04x.\n",
28208882d20SHarvey Harrison 		__func__, ioread32(I2C_REG_STS(alg_data)));
28341561f28SVitaly Wool 
28441561f28SVitaly Wool 	/* Check, whether there is already data,
28541561f28SVitaly Wool 	 * or we didn't 'ask' for it yet.
28641561f28SVitaly Wool 	 */
28741561f28SVitaly Wool 	if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) {
288c076ada4SRoland Stigge 		/* 'Asking' is done asynchronously, e.g. dummy TX of several
289c076ada4SRoland Stigge 		 * bytes is done before the first actual RX arrives in FIFO.
290c076ada4SRoland Stigge 		 * Therefore, ordered bytes (via TX) are counted separately.
291c076ada4SRoland Stigge 		 */
292c076ada4SRoland Stigge 		if (alg_data->mif.order) {
2934be53dbeSRussell King 			dev_dbg(&alg_data->adapter.dev,
2944be53dbeSRussell King 				"%s(): Write dummy data to fill Rx-fifo...\n",
2954be53dbeSRussell King 				__func__);
29641561f28SVitaly Wool 
297c076ada4SRoland Stigge 			if (alg_data->mif.order == 1) {
29828ad3321SKevin Wells 				/* Last byte, do not acknowledge next rcv. */
29928ad3321SKevin Wells 				val |= stop_bit;
30028ad3321SKevin Wells 
30141561f28SVitaly Wool 				/*
30241561f28SVitaly Wool 				 * Enable interrupt RFDAIE (data in Rx fifo),
30341561f28SVitaly Wool 				 * and disable DRMIE (need data for Tx)
30441561f28SVitaly Wool 				 */
30541561f28SVitaly Wool 				ctl = ioread32(I2C_REG_CTL(alg_data));
30641561f28SVitaly Wool 				ctl |= mcntrl_rffie | mcntrl_daie;
30741561f28SVitaly Wool 				ctl &= ~mcntrl_drmie;
30841561f28SVitaly Wool 				iowrite32(ctl, I2C_REG_CTL(alg_data));
30941561f28SVitaly Wool 			}
31041561f28SVitaly Wool 
31141561f28SVitaly Wool 			/*
31241561f28SVitaly Wool 			 * Now we'll 'ask' for data:
31341561f28SVitaly Wool 			 * For each byte we want to receive, we must
31441561f28SVitaly Wool 			 * write a (dummy) byte to the Tx-FIFO.
31541561f28SVitaly Wool 			 */
31641561f28SVitaly Wool 			iowrite32(val, I2C_REG_TX(alg_data));
317c076ada4SRoland Stigge 			alg_data->mif.order--;
318c076ada4SRoland Stigge 		}
31941561f28SVitaly Wool 		return 0;
32041561f28SVitaly Wool 	}
32141561f28SVitaly Wool 
32241561f28SVitaly Wool 	/* Handle data. */
32341561f28SVitaly Wool 	if (alg_data->mif.len > 0) {
32441561f28SVitaly Wool 		val = ioread32(I2C_REG_RX(alg_data));
32541561f28SVitaly Wool 		*alg_data->mif.buf++ = (u8) (val & 0xff);
3264be53dbeSRussell King 		dev_dbg(&alg_data->adapter.dev, "%s(): rcv 0x%x [%d]\n",
3274be53dbeSRussell King 			__func__, val, alg_data->mif.len);
32841561f28SVitaly Wool 
32941561f28SVitaly Wool 		alg_data->mif.len--;
33041561f28SVitaly Wool 		if (alg_data->mif.len == 0) {
33141561f28SVitaly Wool 			if (alg_data->last)
33241561f28SVitaly Wool 				/* Wait until the STOP is seen. */
333b41a216dSRoland Stigge 				if (wait_timeout(alg_data))
3344be53dbeSRussell King 					dev_err(&alg_data->adapter.dev,
3354be53dbeSRussell King 						"The bus is still active after timeout\n");
33641561f28SVitaly Wool 
33741561f28SVitaly Wool 			/* Disable master interrupts */
33841561f28SVitaly Wool 			ctl = ioread32(I2C_REG_CTL(alg_data));
33941561f28SVitaly Wool 			ctl &= ~(mcntrl_afie | mcntrl_naie | mcntrl_rffie |
34041561f28SVitaly Wool 				 mcntrl_drmie | mcntrl_daie);
34141561f28SVitaly Wool 			iowrite32(ctl, I2C_REG_CTL(alg_data));
34241561f28SVitaly Wool 
34341561f28SVitaly Wool 			complete(&alg_data->mif.complete);
34441561f28SVitaly Wool 		}
34541561f28SVitaly Wool 	}
34641561f28SVitaly Wool 
34781d6724aSRussell King 	dev_dbg(&alg_data->adapter.dev, "%s(): exiting: stat = %04x.\n",
34808882d20SHarvey Harrison 		__func__, ioread32(I2C_REG_STS(alg_data)));
34941561f28SVitaly Wool 
35041561f28SVitaly Wool 	return 0;
35141561f28SVitaly Wool }
35241561f28SVitaly Wool 
i2c_pnx_interrupt(int irq,void * dev_id)3536c566fb7SVitaly Wool static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)
35441561f28SVitaly Wool {
35581d6724aSRussell King 	struct i2c_pnx_algo_data *alg_data = dev_id;
35641561f28SVitaly Wool 	u32 stat, ctl;
35741561f28SVitaly Wool 
3584be53dbeSRussell King 	dev_dbg(&alg_data->adapter.dev,
3594be53dbeSRussell King 		"%s(): mstat = %x mctrl = %x, mode = %d\n",
36008882d20SHarvey Harrison 		__func__,
36141561f28SVitaly Wool 		ioread32(I2C_REG_STS(alg_data)),
36241561f28SVitaly Wool 		ioread32(I2C_REG_CTL(alg_data)),
36341561f28SVitaly Wool 		alg_data->mif.mode);
36441561f28SVitaly Wool 	stat = ioread32(I2C_REG_STS(alg_data));
36541561f28SVitaly Wool 
36641561f28SVitaly Wool 	/* let's see what kind of event this is */
36741561f28SVitaly Wool 	if (stat & mstatus_afi) {
36841561f28SVitaly Wool 		/* We lost arbitration in the midst of a transfer */
36941561f28SVitaly Wool 		alg_data->mif.ret = -EIO;
37041561f28SVitaly Wool 
37141561f28SVitaly Wool 		/* Disable master interrupts. */
37241561f28SVitaly Wool 		ctl = ioread32(I2C_REG_CTL(alg_data));
37341561f28SVitaly Wool 		ctl &= ~(mcntrl_afie | mcntrl_naie | mcntrl_rffie |
37441561f28SVitaly Wool 			 mcntrl_drmie);
37541561f28SVitaly Wool 		iowrite32(ctl, I2C_REG_CTL(alg_data));
37641561f28SVitaly Wool 
37741561f28SVitaly Wool 		complete(&alg_data->mif.complete);
37841561f28SVitaly Wool 	} else if (stat & mstatus_nai) {
37941561f28SVitaly Wool 		/* Slave did not acknowledge, generate a STOP */
3804be53dbeSRussell King 		dev_dbg(&alg_data->adapter.dev,
3814be53dbeSRussell King 			"%s(): Slave did not acknowledge, generating a STOP.\n",
38208882d20SHarvey Harrison 			__func__);
38381d6724aSRussell King 		i2c_pnx_stop(alg_data);
38441561f28SVitaly Wool 
38541561f28SVitaly Wool 		/* Disable master interrupts. */
38641561f28SVitaly Wool 		ctl = ioread32(I2C_REG_CTL(alg_data));
38741561f28SVitaly Wool 		ctl &= ~(mcntrl_afie | mcntrl_naie | mcntrl_rffie |
38841561f28SVitaly Wool 			 mcntrl_drmie);
38941561f28SVitaly Wool 		iowrite32(ctl, I2C_REG_CTL(alg_data));
39041561f28SVitaly Wool 
39141561f28SVitaly Wool 		/* Our return value. */
39241561f28SVitaly Wool 		alg_data->mif.ret = -EIO;
39341561f28SVitaly Wool 
39441561f28SVitaly Wool 		complete(&alg_data->mif.complete);
39541561f28SVitaly Wool 	} else {
39641561f28SVitaly Wool 		/*
39741561f28SVitaly Wool 		 * Two options:
39841561f28SVitaly Wool 		 * - Master Tx needs data.
39941561f28SVitaly Wool 		 * - There is data in the Rx-fifo
40041561f28SVitaly Wool 		 * The latter is only the case if we have requested for data,
40141561f28SVitaly Wool 		 * via a dummy write. (See 'i2c_pnx_master_rcv'.)
40241561f28SVitaly Wool 		 * We therefore check, as a sanity check, whether that interrupt
40341561f28SVitaly Wool 		 * has been enabled.
40441561f28SVitaly Wool 		 */
40541561f28SVitaly Wool 		if ((stat & mstatus_drmi) || !(stat & mstatus_rfe)) {
40641561f28SVitaly Wool 			if (alg_data->mif.mode == I2C_SMBUS_WRITE) {
40781d6724aSRussell King 				i2c_pnx_master_xmit(alg_data);
40841561f28SVitaly Wool 			} else if (alg_data->mif.mode == I2C_SMBUS_READ) {
40981d6724aSRussell King 				i2c_pnx_master_rcv(alg_data);
41041561f28SVitaly Wool 			}
41141561f28SVitaly Wool 		}
41241561f28SVitaly Wool 	}
41341561f28SVitaly Wool 
41441561f28SVitaly Wool 	/* Clear TDI and AFI bits */
41541561f28SVitaly Wool 	stat = ioread32(I2C_REG_STS(alg_data));
41641561f28SVitaly Wool 	iowrite32(stat | mstatus_tdi | mstatus_afi, I2C_REG_STS(alg_data));
41741561f28SVitaly Wool 
4184be53dbeSRussell King 	dev_dbg(&alg_data->adapter.dev,
4194be53dbeSRussell King 		"%s(): exiting, stat = %x ctrl = %x.\n",
42008882d20SHarvey Harrison 		 __func__, ioread32(I2C_REG_STS(alg_data)),
42141561f28SVitaly Wool 		 ioread32(I2C_REG_CTL(alg_data)));
42241561f28SVitaly Wool 
42341561f28SVitaly Wool 	return IRQ_HANDLED;
42441561f28SVitaly Wool }
42541561f28SVitaly Wool 
i2c_pnx_timeout(struct i2c_pnx_algo_data * alg_data)42692e494a7SPiotr Wojtaszczyk static void i2c_pnx_timeout(struct i2c_pnx_algo_data *alg_data)
42741561f28SVitaly Wool {
42841561f28SVitaly Wool 	u32 ctl;
42941561f28SVitaly Wool 
4304be53dbeSRussell King 	dev_err(&alg_data->adapter.dev,
4314be53dbeSRussell King 		"Master timed out. stat = %04x, cntrl = %04x. Resetting master...\n",
43241561f28SVitaly Wool 		ioread32(I2C_REG_STS(alg_data)),
43341561f28SVitaly Wool 		ioread32(I2C_REG_CTL(alg_data)));
43441561f28SVitaly Wool 
43541561f28SVitaly Wool 	/* Reset master and disable interrupts */
43641561f28SVitaly Wool 	ctl = ioread32(I2C_REG_CTL(alg_data));
43741561f28SVitaly Wool 	ctl &= ~(mcntrl_afie | mcntrl_naie | mcntrl_rffie | mcntrl_drmie);
43841561f28SVitaly Wool 	iowrite32(ctl, I2C_REG_CTL(alg_data));
43941561f28SVitaly Wool 
44041561f28SVitaly Wool 	ctl |= mcntrl_reset;
44141561f28SVitaly Wool 	iowrite32(ctl, I2C_REG_CTL(alg_data));
442b41a216dSRoland Stigge 	wait_reset(alg_data);
44341561f28SVitaly Wool 	alg_data->mif.ret = -EIO;
44441561f28SVitaly Wool }
44541561f28SVitaly Wool 
bus_reset_if_active(struct i2c_pnx_algo_data * alg_data)44681d6724aSRussell King static inline void bus_reset_if_active(struct i2c_pnx_algo_data *alg_data)
44741561f28SVitaly Wool {
44841561f28SVitaly Wool 	u32 stat;
44941561f28SVitaly Wool 
45041561f28SVitaly Wool 	if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_active) {
45181d6724aSRussell King 		dev_err(&alg_data->adapter.dev,
45241561f28SVitaly Wool 			"%s: Bus is still active after xfer. Reset it...\n",
45381d6724aSRussell King 			alg_data->adapter.name);
45441561f28SVitaly Wool 		iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset,
45541561f28SVitaly Wool 			  I2C_REG_CTL(alg_data));
456b41a216dSRoland Stigge 		wait_reset(alg_data);
45741561f28SVitaly Wool 	} else if (!(stat & mstatus_rfe) || !(stat & mstatus_tfe)) {
45841561f28SVitaly Wool 		/* If there is data in the fifo's after transfer,
45941561f28SVitaly Wool 		 * flush fifo's by reset.
46041561f28SVitaly Wool 		 */
46141561f28SVitaly Wool 		iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset,
46241561f28SVitaly Wool 			  I2C_REG_CTL(alg_data));
463b41a216dSRoland Stigge 		wait_reset(alg_data);
46441561f28SVitaly Wool 	} else if (stat & mstatus_nai) {
46541561f28SVitaly Wool 		iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset,
46641561f28SVitaly Wool 			  I2C_REG_CTL(alg_data));
467b41a216dSRoland Stigge 		wait_reset(alg_data);
46841561f28SVitaly Wool 	}
46941561f28SVitaly Wool }
47041561f28SVitaly Wool 
47141561f28SVitaly Wool /**
47241561f28SVitaly Wool  * i2c_pnx_xfer - generic transfer entry point
47341561f28SVitaly Wool  * @adap:		pointer to I2C adapter structure
47441561f28SVitaly Wool  * @msgs:		array of messages
47541561f28SVitaly Wool  * @num:		number of messages
47641561f28SVitaly Wool  *
47741561f28SVitaly Wool  * Initiates the transfer
47841561f28SVitaly Wool  */
47941561f28SVitaly Wool static int
i2c_pnx_xfer(struct i2c_adapter * adap,struct i2c_msg * msgs,int num)48041561f28SVitaly Wool i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
48141561f28SVitaly Wool {
48241561f28SVitaly Wool 	struct i2c_msg *pmsg;
48341561f28SVitaly Wool 	int rc = 0, completed = 0, i;
48441561f28SVitaly Wool 	struct i2c_pnx_algo_data *alg_data = adap->algo_data;
48592e494a7SPiotr Wojtaszczyk 	unsigned long time_left;
48677133e1cSWolfram Sang 	u32 stat;
48741561f28SVitaly Wool 
4884be53dbeSRussell King 	dev_dbg(&alg_data->adapter.dev,
4894be53dbeSRussell King 		"%s(): entering: %d messages, stat = %04x.\n",
49008882d20SHarvey Harrison 		__func__, num, ioread32(I2C_REG_STS(alg_data)));
49141561f28SVitaly Wool 
49281d6724aSRussell King 	bus_reset_if_active(alg_data);
49341561f28SVitaly Wool 
49441561f28SVitaly Wool 	/* Process transactions in a loop. */
49541561f28SVitaly Wool 	for (i = 0; rc >= 0 && i < num; i++) {
49641561f28SVitaly Wool 		u8 addr;
49741561f28SVitaly Wool 
49841561f28SVitaly Wool 		pmsg = &msgs[i];
49941561f28SVitaly Wool 		addr = pmsg->addr;
50041561f28SVitaly Wool 
50141561f28SVitaly Wool 		if (pmsg->flags & I2C_M_TEN) {
50281d6724aSRussell King 			dev_err(&alg_data->adapter.dev,
50341561f28SVitaly Wool 				"%s: 10 bits addr not supported!\n",
50481d6724aSRussell King 				alg_data->adapter.name);
50541561f28SVitaly Wool 			rc = -EINVAL;
50641561f28SVitaly Wool 			break;
50741561f28SVitaly Wool 		}
50841561f28SVitaly Wool 
50941561f28SVitaly Wool 		alg_data->mif.buf = pmsg->buf;
51041561f28SVitaly Wool 		alg_data->mif.len = pmsg->len;
511c076ada4SRoland Stigge 		alg_data->mif.order = pmsg->len;
51241561f28SVitaly Wool 		alg_data->mif.mode = (pmsg->flags & I2C_M_RD) ?
51341561f28SVitaly Wool 			I2C_SMBUS_READ : I2C_SMBUS_WRITE;
51441561f28SVitaly Wool 		alg_data->mif.ret = 0;
51541561f28SVitaly Wool 		alg_data->last = (i == num - 1);
51641561f28SVitaly Wool 
5174be53dbeSRussell King 		dev_dbg(&alg_data->adapter.dev, "%s(): mode %d, %d bytes\n",
5184be53dbeSRussell King 			__func__, alg_data->mif.mode, alg_data->mif.len);
51941561f28SVitaly Wool 
52041561f28SVitaly Wool 
52141561f28SVitaly Wool 		/* initialize the completion var */
52241561f28SVitaly Wool 		init_completion(&alg_data->mif.complete);
52341561f28SVitaly Wool 
52441561f28SVitaly Wool 		/* Enable master interrupt */
52541561f28SVitaly Wool 		iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_afie |
52641561f28SVitaly Wool 				mcntrl_naie | mcntrl_drmie,
52741561f28SVitaly Wool 			  I2C_REG_CTL(alg_data));
52841561f28SVitaly Wool 
52941561f28SVitaly Wool 		/* Put start-code and slave-address on the bus. */
53081d6724aSRussell King 		rc = i2c_pnx_start(addr, alg_data);
53141561f28SVitaly Wool 		if (rc < 0)
53241561f28SVitaly Wool 			break;
53341561f28SVitaly Wool 
53441561f28SVitaly Wool 		/* Wait for completion */
53592e494a7SPiotr Wojtaszczyk 		time_left = wait_for_completion_timeout(&alg_data->mif.complete,
53692e494a7SPiotr Wojtaszczyk 							alg_data->timeout);
53792e494a7SPiotr Wojtaszczyk 		if (time_left == 0)
53892e494a7SPiotr Wojtaszczyk 			i2c_pnx_timeout(alg_data);
53941561f28SVitaly Wool 
54041561f28SVitaly Wool 		if (!(rc = alg_data->mif.ret))
54141561f28SVitaly Wool 			completed++;
5424be53dbeSRussell King 		dev_dbg(&alg_data->adapter.dev,
5434be53dbeSRussell King 			"%s(): Complete, return code = %d.\n",
54408882d20SHarvey Harrison 			__func__, rc);
54541561f28SVitaly Wool 
54641561f28SVitaly Wool 		/* Clear TDI and AFI bits in case they are set. */
54741561f28SVitaly Wool 		if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_tdi) {
54881d6724aSRussell King 			dev_dbg(&alg_data->adapter.dev,
54941561f28SVitaly Wool 				"%s: TDI still set... clearing now.\n",
55081d6724aSRussell King 				alg_data->adapter.name);
55141561f28SVitaly Wool 			iowrite32(stat, I2C_REG_STS(alg_data));
55241561f28SVitaly Wool 		}
55341561f28SVitaly Wool 		if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_afi) {
55481d6724aSRussell King 			dev_dbg(&alg_data->adapter.dev,
55541561f28SVitaly Wool 				"%s: AFI still set... clearing now.\n",
55681d6724aSRussell King 				alg_data->adapter.name);
55741561f28SVitaly Wool 			iowrite32(stat, I2C_REG_STS(alg_data));
55841561f28SVitaly Wool 		}
55941561f28SVitaly Wool 	}
56041561f28SVitaly Wool 
56181d6724aSRussell King 	bus_reset_if_active(alg_data);
56241561f28SVitaly Wool 
56341561f28SVitaly Wool 	/* Cleanup to be sure... */
56441561f28SVitaly Wool 	alg_data->mif.buf = NULL;
56541561f28SVitaly Wool 	alg_data->mif.len = 0;
566c076ada4SRoland Stigge 	alg_data->mif.order = 0;
56741561f28SVitaly Wool 
56881d6724aSRussell King 	dev_dbg(&alg_data->adapter.dev, "%s(): exiting, stat = %x\n",
56908882d20SHarvey Harrison 		__func__, ioread32(I2C_REG_STS(alg_data)));
57041561f28SVitaly Wool 
57141561f28SVitaly Wool 	if (completed != num)
57241561f28SVitaly Wool 		return ((rc < 0) ? rc : -EREMOTEIO);
57341561f28SVitaly Wool 
57441561f28SVitaly Wool 	return num;
57541561f28SVitaly Wool }
57641561f28SVitaly Wool 
i2c_pnx_func(struct i2c_adapter * adapter)57741561f28SVitaly Wool static u32 i2c_pnx_func(struct i2c_adapter *adapter)
57841561f28SVitaly Wool {
57941561f28SVitaly Wool 	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
58041561f28SVitaly Wool }
58141561f28SVitaly Wool 
582ad3caf8aSBhumika Goyal static const struct i2c_algorithm pnx_algorithm = {
58341561f28SVitaly Wool 	.master_xfer = i2c_pnx_xfer,
58441561f28SVitaly Wool 	.functionality = i2c_pnx_func,
58541561f28SVitaly Wool };
58641561f28SVitaly Wool 
i2c_pnx_controller_suspend(struct device * dev)587783414baSRafael J. Wysocki static int i2c_pnx_controller_suspend(struct device *dev)
58841561f28SVitaly Wool {
589783414baSRafael J. Wysocki 	struct i2c_pnx_algo_data *alg_data = dev_get_drvdata(dev);
5900321cb83SRussell King 
5915dd32eaeSVladimir Zapolskiy 	clk_disable_unprepare(alg_data->clk);
5920321cb83SRussell King 
5930321cb83SRussell King 	return 0;
59441561f28SVitaly Wool }
59541561f28SVitaly Wool 
i2c_pnx_controller_resume(struct device * dev)596783414baSRafael J. Wysocki static int i2c_pnx_controller_resume(struct device *dev)
59741561f28SVitaly Wool {
598783414baSRafael J. Wysocki 	struct i2c_pnx_algo_data *alg_data = dev_get_drvdata(dev);
5990321cb83SRussell King 
6005dd32eaeSVladimir Zapolskiy 	return clk_prepare_enable(alg_data->clk);
60141561f28SVitaly Wool }
602783414baSRafael J. Wysocki 
6036184f92fSPaul Cercueil static DEFINE_SIMPLE_DEV_PM_OPS(i2c_pnx_pm,
6046184f92fSPaul Cercueil 				i2c_pnx_controller_suspend,
6056184f92fSPaul Cercueil 				i2c_pnx_controller_resume);
60641561f28SVitaly Wool 
i2c_pnx_probe(struct platform_device * pdev)6070b255e92SBill Pemberton static int i2c_pnx_probe(struct platform_device *pdev)
60841561f28SVitaly Wool {
60941561f28SVitaly Wool 	unsigned long tmp;
61041561f28SVitaly Wool 	int ret = 0;
61141561f28SVitaly Wool 	struct i2c_pnx_algo_data *alg_data;
6126fff3da9SRussell King 	unsigned long freq;
6131451ba3aSRoland Stigge 	struct resource *res;
614b41a216dSRoland Stigge 	u32 speed = I2C_PNX_SPEED_KHZ_DEFAULT * 1000;
61541561f28SVitaly Wool 
616d1ccc125SJingoo Han 	alg_data = devm_kzalloc(&pdev->dev, sizeof(*alg_data), GFP_KERNEL);
617d1ccc125SJingoo Han 	if (!alg_data)
618d1ccc125SJingoo Han 		return -ENOMEM;
61944c5d739SRussell King 
6209d7f7363SRussell King 	platform_set_drvdata(pdev, alg_data);
62141561f28SVitaly Wool 
6229d7f7363SRussell King 	alg_data->adapter.dev.parent = &pdev->dev;
6239d7f7363SRussell King 	alg_data->adapter.algo = &pnx_algorithm;
6249d7f7363SRussell King 	alg_data->adapter.algo_data = alg_data;
6259d7f7363SRussell King 	alg_data->adapter.nr = pdev->id;
6260321cb83SRussell King 
62792e494a7SPiotr Wojtaszczyk 	alg_data->timeout = msecs_to_jiffies(I2C_PNX_TIMEOUT_DEFAULT);
62892e494a7SPiotr Wojtaszczyk 	if (alg_data->timeout <= 1)
62992e494a7SPiotr Wojtaszczyk 		alg_data->timeout = 2;
63092e494a7SPiotr Wojtaszczyk 
631b41a216dSRoland Stigge #ifdef CONFIG_OF
632b41a216dSRoland Stigge 	alg_data->adapter.dev.of_node = of_node_get(pdev->dev.of_node);
633b41a216dSRoland Stigge 	if (pdev->dev.of_node) {
634b41a216dSRoland Stigge 		of_property_read_u32(pdev->dev.of_node, "clock-frequency",
635b41a216dSRoland Stigge 				     &speed);
636b41a216dSRoland Stigge 		/*
637b41a216dSRoland Stigge 		 * At this point, it is planned to add an OF timeout property.
638b41a216dSRoland Stigge 		 * As soon as there is a consensus about how to call and handle
639b41a216dSRoland Stigge 		 * this, sth. like the following can be put here:
640b41a216dSRoland Stigge 		 *
641b41a216dSRoland Stigge 		 * of_property_read_u32(pdev->dev.of_node, "timeout",
642b41a216dSRoland Stigge 		 *                      &alg_data->timeout);
643b41a216dSRoland Stigge 		 */
644b41a216dSRoland Stigge 	}
645b41a216dSRoland Stigge #endif
646d1ccc125SJingoo Han 	alg_data->clk = devm_clk_get(&pdev->dev, NULL);
647d1ccc125SJingoo Han 	if (IS_ERR(alg_data->clk))
648d1ccc125SJingoo Han 		return PTR_ERR(alg_data->clk);
6490321cb83SRussell King 
6501451ba3aSRoland Stigge 	snprintf(alg_data->adapter.name, sizeof(alg_data->adapter.name),
6511451ba3aSRoland Stigge 		 "%s", pdev->name);
6521451ba3aSRoland Stigge 
65341561f28SVitaly Wool 	/* Register I/O resource */
65408e3351bSYangtao Li 	alg_data->ioaddr = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
655d1ccc125SJingoo Han 	if (IS_ERR(alg_data->ioaddr))
656d1ccc125SJingoo Han 		return PTR_ERR(alg_data->ioaddr);
65741561f28SVitaly Wool 
6585dd32eaeSVladimir Zapolskiy 	ret = clk_prepare_enable(alg_data->clk);
659ebdbbf20SRussell King 	if (ret)
660d1ccc125SJingoo Han 		return ret;
66141561f28SVitaly Wool 
6626fff3da9SRussell King 	freq = clk_get_rate(alg_data->clk);
6636fff3da9SRussell King 
66441561f28SVitaly Wool 	/*
66541561f28SVitaly Wool 	 * Clock Divisor High This value is the number of system clocks
66641561f28SVitaly Wool 	 * the serial clock (SCL) will be high.
66741561f28SVitaly Wool 	 * For example, if the system clock period is 50 ns and the maximum
66841561f28SVitaly Wool 	 * desired serial period is 10000 ns (100 kHz), then CLKHI would be
66941561f28SVitaly Wool 	 * set to 0.5*(f_sys/f_i2c)-2=0.5*(20e6/100e3)-2=98. The actual value
67041561f28SVitaly Wool 	 * programmed into CLKHI will vary from this slightly due to
67141561f28SVitaly Wool 	 * variations in the output pad's rise and fall times as well as
67241561f28SVitaly Wool 	 * the deglitching filter length.
67341561f28SVitaly Wool 	 */
67441561f28SVitaly Wool 
675b41a216dSRoland Stigge 	tmp = (freq / speed) / 2 - 2;
676be80dbaaSKevin Wells 	if (tmp > 0x3FF)
677be80dbaaSKevin Wells 		tmp = 0x3FF;
67841561f28SVitaly Wool 	iowrite32(tmp, I2C_REG_CKH(alg_data));
67941561f28SVitaly Wool 	iowrite32(tmp, I2C_REG_CKL(alg_data));
68041561f28SVitaly Wool 
68141561f28SVitaly Wool 	iowrite32(mcntrl_reset, I2C_REG_CTL(alg_data));
682b41a216dSRoland Stigge 	if (wait_reset(alg_data)) {
68341561f28SVitaly Wool 		ret = -ENODEV;
684ebdbbf20SRussell King 		goto out_clock;
68541561f28SVitaly Wool 	}
68641561f28SVitaly Wool 	init_completion(&alg_data->mif.complete);
68741561f28SVitaly Wool 
6881451ba3aSRoland Stigge 	alg_data->irq = platform_get_irq(pdev, 0);
6891451ba3aSRoland Stigge 	if (alg_data->irq < 0) {
690498c0146SWei Yongjun 		ret = alg_data->irq;
691498c0146SWei Yongjun 		goto out_clock;
6921451ba3aSRoland Stigge 	}
693d1ccc125SJingoo Han 	ret = devm_request_irq(&pdev->dev, alg_data->irq, i2c_pnx_interrupt,
69481d6724aSRussell King 			       0, pdev->name, alg_data);
69541561f28SVitaly Wool 	if (ret)
69641561f28SVitaly Wool 		goto out_clock;
69741561f28SVitaly Wool 
69841561f28SVitaly Wool 	/* Register this adapter with the I2C subsystem */
6999d7f7363SRussell King 	ret = i2c_add_numbered_adapter(&alg_data->adapter);
700ea734404SWolfram Sang 	if (ret < 0)
701d1ccc125SJingoo Han 		goto out_clock;
70241561f28SVitaly Wool 
70317b3fe8bSKrzysztof Kozlowski 	dev_dbg(&pdev->dev, "%s: Master at %pap, irq %d.\n",
70417b3fe8bSKrzysztof Kozlowski 		alg_data->adapter.name, &res->start, alg_data->irq);
70541561f28SVitaly Wool 
70641561f28SVitaly Wool 	return 0;
70741561f28SVitaly Wool 
70841561f28SVitaly Wool out_clock:
7095dd32eaeSVladimir Zapolskiy 	clk_disable_unprepare(alg_data->clk);
71041561f28SVitaly Wool 	return ret;
71141561f28SVitaly Wool }
71241561f28SVitaly Wool 
i2c_pnx_remove(struct platform_device * pdev)713e190a0c3SUwe Kleine-König static void i2c_pnx_remove(struct platform_device *pdev)
71441561f28SVitaly Wool {
7159d7f7363SRussell King 	struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev);
71641561f28SVitaly Wool 
7179d7f7363SRussell King 	i2c_del_adapter(&alg_data->adapter);
7185dd32eaeSVladimir Zapolskiy 	clk_disable_unprepare(alg_data->clk);
71941561f28SVitaly Wool }
72041561f28SVitaly Wool 
721b41a216dSRoland Stigge #ifdef CONFIG_OF
722b41a216dSRoland Stigge static const struct of_device_id i2c_pnx_of_match[] = {
723b41a216dSRoland Stigge 	{ .compatible = "nxp,pnx-i2c" },
724b41a216dSRoland Stigge 	{ },
725b41a216dSRoland Stigge };
726b41a216dSRoland Stigge MODULE_DEVICE_TABLE(of, i2c_pnx_of_match);
727b41a216dSRoland Stigge #endif
728b41a216dSRoland Stigge 
72941561f28SVitaly Wool static struct platform_driver i2c_pnx_driver = {
73041561f28SVitaly Wool 	.driver = {
73141561f28SVitaly Wool 		.name = "pnx-i2c",
732b41a216dSRoland Stigge 		.of_match_table = of_match_ptr(i2c_pnx_of_match),
7336184f92fSPaul Cercueil 		.pm = pm_sleep_ptr(&i2c_pnx_pm),
73441561f28SVitaly Wool 	},
73541561f28SVitaly Wool 	.probe = i2c_pnx_probe,
736e190a0c3SUwe Kleine-König 	.remove_new = i2c_pnx_remove,
73741561f28SVitaly Wool };
73841561f28SVitaly Wool 
i2c_adap_pnx_init(void)73941561f28SVitaly Wool static int __init i2c_adap_pnx_init(void)
74041561f28SVitaly Wool {
74141561f28SVitaly Wool 	return platform_driver_register(&i2c_pnx_driver);
74241561f28SVitaly Wool }
74341561f28SVitaly Wool 
i2c_adap_pnx_exit(void)74441561f28SVitaly Wool static void __exit i2c_adap_pnx_exit(void)
74541561f28SVitaly Wool {
74641561f28SVitaly Wool 	platform_driver_unregister(&i2c_pnx_driver);
74741561f28SVitaly Wool }
74841561f28SVitaly Wool 
749f80531c8SJarkko Nikula MODULE_AUTHOR("Vitaly Wool");
750f80531c8SJarkko Nikula MODULE_AUTHOR("Dennis Kovalev <source@mvista.com>");
75141561f28SVitaly Wool MODULE_DESCRIPTION("I2C driver for Philips IP3204-based I2C busses");
75241561f28SVitaly Wool MODULE_LICENSE("GPL");
753add8eda7SKay Sievers MODULE_ALIAS("platform:pnx-i2c");
75441561f28SVitaly Wool 
75541561f28SVitaly Wool /* We need to make sure I2C is initialized before USB */
75641561f28SVitaly Wool subsys_initcall(i2c_adap_pnx_init);
75741561f28SVitaly Wool module_exit(i2c_adap_pnx_exit);
758