diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-pnx.c')
| -rw-r--r-- | drivers/i2c/busses/i2c-pnx.c | 283 | 
1 files changed, 154 insertions, 129 deletions
diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index 5d1c2603a13..2b0bd0b042d 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c @@ -20,15 +20,15 @@  #include <linux/platform_device.h>  #include <linux/i2c-pnx.h>  #include <linux/io.h> +#include <linux/err.h> +#include <linux/clk.h> +  #include <mach/hardware.h>  #include <mach/i2c.h> -#include <asm/irq.h> -#include <asm/uaccess.h>  #define I2C_PNX_TIMEOUT		10 /* msec */  #define I2C_PNX_SPEED_KHZ	100  #define I2C_PNX_REGION_SIZE	0x100 -#define PNX_DEFAULT_FREQ	13 /* MHz */  static inline int wait_timeout(long timeout, struct i2c_pnx_algo_data *data)  { @@ -50,22 +50,21 @@ static inline int wait_reset(long timeout, struct i2c_pnx_algo_data *data)  	return (timeout <= 0);  } -static inline void i2c_pnx_arm_timer(struct i2c_adapter *adap) +static inline void i2c_pnx_arm_timer(struct i2c_pnx_algo_data *alg_data)  { -	struct i2c_pnx_algo_data *data = adap->algo_data; -	struct timer_list *timer = &data->mif.timer; -	int expires = I2C_PNX_TIMEOUT / (1000 / HZ); +	struct timer_list *timer = &alg_data->mif.timer; +	unsigned long expires = msecs_to_jiffies(I2C_PNX_TIMEOUT);  	if (expires <= 1)  		expires = 2;  	del_timer_sync(timer); -	dev_dbg(&adap->dev, "Timer armed at %lu plus %u jiffies.\n", +	dev_dbg(&alg_data->adapter.dev, "Timer armed at %lu plus %lu jiffies.\n",  		jiffies, expires);  	timer->expires = jiffies + expires; -	timer->data = (unsigned long)adap; +	timer->data = (unsigned long)&alg_data;  	add_timer(timer);  } @@ -77,34 +76,34 @@ static inline void i2c_pnx_arm_timer(struct i2c_adapter *adap)   *   * Generate a START signal in the desired mode.   */ -static int i2c_pnx_start(unsigned char slave_addr, struct i2c_adapter *adap) +static int i2c_pnx_start(unsigned char slave_addr, +	struct i2c_pnx_algo_data *alg_data)  { -	struct i2c_pnx_algo_data *alg_data = adap->algo_data; - -	dev_dbg(&adap->dev, "%s(): addr 0x%x mode %d\n", __func__, +	dev_dbg(&alg_data->adapter.dev, "%s(): addr 0x%x mode %d\n", __func__,  		slave_addr, alg_data->mif.mode);  	/* Check for 7 bit slave addresses only */  	if (slave_addr & ~0x7f) { -		dev_err(&adap->dev, "%s: Invalid slave address %x. " -		       "Only 7-bit addresses are supported\n", -		       adap->name, slave_addr); +		dev_err(&alg_data->adapter.dev, +			"%s: Invalid slave address %x. Only 7-bit addresses are supported\n", +			alg_data->adapter.name, slave_addr);  		return -EINVAL;  	}  	/* First, make sure bus is idle */  	if (wait_timeout(I2C_PNX_TIMEOUT, alg_data)) {  		/* Somebody else is monopolizing the bus */ -		dev_err(&adap->dev, "%s: Bus busy. Slave addr = %02x, " -		       "cntrl = %x, stat = %x\n", -		       adap->name, slave_addr, -		       ioread32(I2C_REG_CTL(alg_data)), -		       ioread32(I2C_REG_STS(alg_data))); +		dev_err(&alg_data->adapter.dev, +			"%s: Bus busy. Slave addr = %02x, cntrl = %x, stat = %x\n", +			alg_data->adapter.name, slave_addr, +			ioread32(I2C_REG_CTL(alg_data)), +			ioread32(I2C_REG_STS(alg_data)));  		return -EBUSY;  	} else if (ioread32(I2C_REG_STS(alg_data)) & mstatus_afi) {  		/* Sorry, we lost the bus */ -		dev_err(&adap->dev, "%s: Arbitration failure. " -		       "Slave addr = %02x\n", adap->name, slave_addr); +		dev_err(&alg_data->adapter.dev, +		        "%s: Arbitration failure. Slave addr = %02x\n", +			alg_data->adapter.name, slave_addr);  		return -EIO;  	} @@ -115,14 +114,14 @@ static int i2c_pnx_start(unsigned char slave_addr, struct i2c_adapter *adap)  	iowrite32(ioread32(I2C_REG_STS(alg_data)) | mstatus_tdi | mstatus_afi,  		  I2C_REG_STS(alg_data)); -	dev_dbg(&adap->dev, "%s(): sending %#x\n", __func__, +	dev_dbg(&alg_data->adapter.dev, "%s(): sending %#x\n", __func__,  		(slave_addr << 1) | start_bit | alg_data->mif.mode);  	/* Write the slave address, START bit and R/W bit */  	iowrite32((slave_addr << 1) | start_bit | alg_data->mif.mode,  		  I2C_REG_TX(alg_data)); -	dev_dbg(&adap->dev, "%s(): exit\n", __func__); +	dev_dbg(&alg_data->adapter.dev, "%s(): exit\n", __func__);  	return 0;  } @@ -133,13 +132,12 @@ static int i2c_pnx_start(unsigned char slave_addr, struct i2c_adapter *adap)   *   * Generate a STOP signal to terminate the master transaction.   */ -static void i2c_pnx_stop(struct i2c_adapter *adap) +static void i2c_pnx_stop(struct i2c_pnx_algo_data *alg_data)  { -	struct i2c_pnx_algo_data *alg_data = adap->algo_data;  	/* Only 1 msec max timeout due to interrupt context */  	long timeout = 1000; -	dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n", +	dev_dbg(&alg_data->adapter.dev, "%s(): entering: stat = %04x.\n",  		__func__, ioread32(I2C_REG_STS(alg_data)));  	/* Write a STOP bit to TX FIFO */ @@ -153,7 +151,7 @@ static void i2c_pnx_stop(struct i2c_adapter *adap)  		timeout--;  	} -	dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n", +	dev_dbg(&alg_data->adapter.dev, "%s(): exiting: stat = %04x.\n",  		__func__, ioread32(I2C_REG_STS(alg_data)));  } @@ -163,12 +161,11 @@ static void i2c_pnx_stop(struct i2c_adapter *adap)   *   * Sends one byte of data to the slave   */ -static int i2c_pnx_master_xmit(struct i2c_adapter *adap) +static int i2c_pnx_master_xmit(struct i2c_pnx_algo_data *alg_data)  { -	struct i2c_pnx_algo_data *alg_data = adap->algo_data;  	u32 val; -	dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n", +	dev_dbg(&alg_data->adapter.dev, "%s(): entering: stat = %04x.\n",  		__func__, ioread32(I2C_REG_STS(alg_data)));  	if (alg_data->mif.len > 0) { @@ -184,15 +181,15 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap)  		alg_data->mif.len--;  		iowrite32(val, I2C_REG_TX(alg_data)); -		dev_dbg(&adap->dev, "%s(): xmit %#x [%d]\n", __func__, -			val, alg_data->mif.len + 1); +		dev_dbg(&alg_data->adapter.dev, "%s(): xmit %#x [%d]\n", +			__func__, val, alg_data->mif.len + 1);  		if (alg_data->mif.len == 0) {  			if (alg_data->last) {  				/* Wait until the STOP is seen. */  				if (wait_timeout(I2C_PNX_TIMEOUT, alg_data)) -					dev_err(&adap->dev, "The bus is still " -						"active after timeout\n"); +					dev_err(&alg_data->adapter.dev, +						"The bus is still active after timeout\n");  			}  			/* Disable master interrupts */  			iowrite32(ioread32(I2C_REG_CTL(alg_data)) & @@ -201,14 +198,15 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap)  			del_timer_sync(&alg_data->mif.timer); -			dev_dbg(&adap->dev, "%s(): Waking up xfer routine.\n", +			dev_dbg(&alg_data->adapter.dev, +				"%s(): Waking up xfer routine.\n",  				__func__);  			complete(&alg_data->mif.complete);  		}  	} else if (alg_data->mif.len == 0) {  		/* zero-sized transfer */ -		i2c_pnx_stop(adap); +		i2c_pnx_stop(alg_data);  		/* Disable master interrupts. */  		iowrite32(ioread32(I2C_REG_CTL(alg_data)) & @@ -217,13 +215,14 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap)  		/* Stop timer. */  		del_timer_sync(&alg_data->mif.timer); -		dev_dbg(&adap->dev, "%s(): Waking up xfer routine after " -			"zero-xfer.\n", __func__); +		dev_dbg(&alg_data->adapter.dev, +			"%s(): Waking up xfer routine after zero-xfer.\n", +			__func__);  		complete(&alg_data->mif.complete);  	} -	dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n", +	dev_dbg(&alg_data->adapter.dev, "%s(): exiting: stat = %04x.\n",  		__func__, ioread32(I2C_REG_STS(alg_data)));  	return 0; @@ -235,21 +234,21 @@ static int i2c_pnx_master_xmit(struct i2c_adapter *adap)   *   * Reads one byte data from the slave   */ -static int i2c_pnx_master_rcv(struct i2c_adapter *adap) +static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data)  { -	struct i2c_pnx_algo_data *alg_data = adap->algo_data;  	unsigned int val = 0;  	u32 ctl = 0; -	dev_dbg(&adap->dev, "%s(): entering: stat = %04x.\n", +	dev_dbg(&alg_data->adapter.dev, "%s(): entering: stat = %04x.\n",  		__func__, ioread32(I2C_REG_STS(alg_data)));  	/* Check, whether there is already data,  	 * or we didn't 'ask' for it yet.  	 */  	if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) { -		dev_dbg(&adap->dev, "%s(): Write dummy data to fill " -			"Rx-fifo...\n", __func__); +		dev_dbg(&alg_data->adapter.dev, +			"%s(): Write dummy data to fill Rx-fifo...\n", +			__func__);  		if (alg_data->mif.len == 1) {  			/* Last byte, do not acknowledge next rcv. */ @@ -281,16 +280,16 @@ static int i2c_pnx_master_rcv(struct i2c_adapter *adap)  	if (alg_data->mif.len > 0) {  		val = ioread32(I2C_REG_RX(alg_data));  		*alg_data->mif.buf++ = (u8) (val & 0xff); -		dev_dbg(&adap->dev, "%s(): rcv 0x%x [%d]\n", __func__, val, -			alg_data->mif.len); +		dev_dbg(&alg_data->adapter.dev, "%s(): rcv 0x%x [%d]\n", +			__func__, val, alg_data->mif.len);  		alg_data->mif.len--;  		if (alg_data->mif.len == 0) {  			if (alg_data->last)  				/* Wait until the STOP is seen. */  				if (wait_timeout(I2C_PNX_TIMEOUT, alg_data)) -					dev_err(&adap->dev, "The bus is still " -						"active after timeout\n"); +					dev_err(&alg_data->adapter.dev, +						"The bus is still active after timeout\n");  			/* Disable master interrupts */  			ctl = ioread32(I2C_REG_CTL(alg_data)); @@ -304,7 +303,7 @@ static int i2c_pnx_master_rcv(struct i2c_adapter *adap)  		}  	} -	dev_dbg(&adap->dev, "%s(): exiting: stat = %04x.\n", +	dev_dbg(&alg_data->adapter.dev, "%s(): exiting: stat = %04x.\n",  		__func__, ioread32(I2C_REG_STS(alg_data)));  	return 0; @@ -312,11 +311,11 @@ static int i2c_pnx_master_rcv(struct i2c_adapter *adap)  static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)  { +	struct i2c_pnx_algo_data *alg_data = dev_id;  	u32 stat, ctl; -	struct i2c_adapter *adap = dev_id; -	struct i2c_pnx_algo_data *alg_data = adap->algo_data; -	dev_dbg(&adap->dev, "%s(): mstat = %x mctrl = %x, mode = %d\n", +	dev_dbg(&alg_data->adapter.dev, +		"%s(): mstat = %x mctrl = %x, mode = %d\n",  		__func__,  		ioread32(I2C_REG_STS(alg_data)),  		ioread32(I2C_REG_CTL(alg_data)), @@ -339,10 +338,10 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)  		complete(&alg_data->mif.complete);  	} else if (stat & mstatus_nai) {  		/* Slave did not acknowledge, generate a STOP */ -		dev_dbg(&adap->dev, "%s(): " -			"Slave did not acknowledge, generating a STOP.\n", +		dev_dbg(&alg_data->adapter.dev, +			"%s(): Slave did not acknowledge, generating a STOP.\n",  			__func__); -		i2c_pnx_stop(adap); +		i2c_pnx_stop(alg_data);  		/* Disable master interrupts. */  		ctl = ioread32(I2C_REG_CTL(alg_data)); @@ -368,9 +367,9 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)  		 */  		if ((stat & mstatus_drmi) || !(stat & mstatus_rfe)) {  			if (alg_data->mif.mode == I2C_SMBUS_WRITE) { -				i2c_pnx_master_xmit(adap); +				i2c_pnx_master_xmit(alg_data);  			} else if (alg_data->mif.mode == I2C_SMBUS_READ) { -				i2c_pnx_master_rcv(adap); +				i2c_pnx_master_rcv(alg_data);  			}  		}  	} @@ -379,7 +378,8 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)  	stat = ioread32(I2C_REG_STS(alg_data));  	iowrite32(stat | mstatus_tdi | mstatus_afi, I2C_REG_STS(alg_data)); -	dev_dbg(&adap->dev, "%s(): exiting, stat = %x ctrl = %x.\n", +	dev_dbg(&alg_data->adapter.dev, +		"%s(): exiting, stat = %x ctrl = %x.\n",  		 __func__, ioread32(I2C_REG_STS(alg_data)),  		 ioread32(I2C_REG_CTL(alg_data))); @@ -388,14 +388,13 @@ static irqreturn_t i2c_pnx_interrupt(int irq, void *dev_id)  static void i2c_pnx_timeout(unsigned long data)  { -	struct i2c_adapter *adap = (struct i2c_adapter *)data; -	struct i2c_pnx_algo_data *alg_data = adap->algo_data; +	struct i2c_pnx_algo_data *alg_data = (struct i2c_pnx_algo_data *)data;  	u32 ctl; -	dev_err(&adap->dev, "Master timed out. stat = %04x, cntrl = %04x. " -	       "Resetting master...\n", -	       ioread32(I2C_REG_STS(alg_data)), -	       ioread32(I2C_REG_CTL(alg_data))); +	dev_err(&alg_data->adapter.dev, +		"Master timed out. stat = %04x, cntrl = %04x. Resetting master...\n", +		ioread32(I2C_REG_STS(alg_data)), +		ioread32(I2C_REG_CTL(alg_data)));  	/* Reset master and disable interrupts */  	ctl = ioread32(I2C_REG_CTL(alg_data)); @@ -409,15 +408,14 @@ static void i2c_pnx_timeout(unsigned long data)  	complete(&alg_data->mif.complete);  } -static inline void bus_reset_if_active(struct i2c_adapter *adap) +static inline void bus_reset_if_active(struct i2c_pnx_algo_data *alg_data)  { -	struct i2c_pnx_algo_data *alg_data = adap->algo_data;  	u32 stat;  	if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_active) { -		dev_err(&adap->dev, +		dev_err(&alg_data->adapter.dev,  			"%s: Bus is still active after xfer. Reset it...\n", -		       adap->name); +			alg_data->adapter.name);  		iowrite32(ioread32(I2C_REG_CTL(alg_data)) | mcntrl_reset,  			  I2C_REG_CTL(alg_data));  		wait_reset(I2C_PNX_TIMEOUT, alg_data); @@ -451,10 +449,11 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)  	struct i2c_pnx_algo_data *alg_data = adap->algo_data;  	u32 stat = ioread32(I2C_REG_STS(alg_data)); -	dev_dbg(&adap->dev, "%s(): entering: %d messages, stat = %04x.\n", +	dev_dbg(&alg_data->adapter.dev, +		"%s(): entering: %d messages, stat = %04x.\n",  		__func__, num, ioread32(I2C_REG_STS(alg_data))); -	bus_reset_if_active(adap); +	bus_reset_if_active(alg_data);  	/* Process transactions in a loop. */  	for (i = 0; rc >= 0 && i < num; i++) { @@ -464,9 +463,9 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)  		addr = pmsg->addr;  		if (pmsg->flags & I2C_M_TEN) { -			dev_err(&adap->dev, +			dev_err(&alg_data->adapter.dev,  				"%s: 10 bits addr not supported!\n", -				adap->name); +				alg_data->adapter.name);  			rc = -EINVAL;  			break;  		} @@ -478,11 +477,10 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)  		alg_data->mif.ret = 0;  		alg_data->last = (i == num - 1); -		dev_dbg(&adap->dev, "%s(): mode %d, %d bytes\n", __func__, -			alg_data->mif.mode, -			alg_data->mif.len); +		dev_dbg(&alg_data->adapter.dev, "%s(): mode %d, %d bytes\n", +			__func__, alg_data->mif.mode, alg_data->mif.len); -		i2c_pnx_arm_timer(adap); +		i2c_pnx_arm_timer(alg_data);  		/* initialize the completion var */  		init_completion(&alg_data->mif.complete); @@ -493,7 +491,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)  			  I2C_REG_CTL(alg_data));  		/* Put start-code and slave-address on the bus. */ -		rc = i2c_pnx_start(addr, adap); +		rc = i2c_pnx_start(addr, alg_data);  		if (rc < 0)  			break; @@ -502,31 +500,32 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)  		if (!(rc = alg_data->mif.ret))  			completed++; -		dev_dbg(&adap->dev, "%s(): Complete, return code = %d.\n", +		dev_dbg(&alg_data->adapter.dev, +			"%s(): Complete, return code = %d.\n",  			__func__, rc);  		/* Clear TDI and AFI bits in case they are set. */  		if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_tdi) { -			dev_dbg(&adap->dev, +			dev_dbg(&alg_data->adapter.dev,  				"%s: TDI still set... clearing now.\n", -			       adap->name); +				alg_data->adapter.name);  			iowrite32(stat, I2C_REG_STS(alg_data));  		}  		if ((stat = ioread32(I2C_REG_STS(alg_data))) & mstatus_afi) { -			dev_dbg(&adap->dev, +			dev_dbg(&alg_data->adapter.dev,  				"%s: AFI still set... clearing now.\n", -			       adap->name); +				alg_data->adapter.name);  			iowrite32(stat, I2C_REG_STS(alg_data));  		}  	} -	bus_reset_if_active(adap); +	bus_reset_if_active(alg_data);  	/* Cleanup to be sure... */  	alg_data->mif.buf = NULL;  	alg_data->mif.len = 0; -	dev_dbg(&adap->dev, "%s(): exiting, stat = %x\n", +	dev_dbg(&alg_data->adapter.dev, "%s(): exiting, stat = %x\n",  		__func__, ioread32(I2C_REG_STS(alg_data)));  	if (completed != num) @@ -545,69 +544,92 @@ static struct i2c_algorithm pnx_algorithm = {  	.functionality = i2c_pnx_func,  }; +#ifdef CONFIG_PM  static int i2c_pnx_controller_suspend(struct platform_device *pdev,  				      pm_message_t state)  { -	struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev); -	return i2c_pnx->suspend(pdev, state); +	struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev); + +	/* FIXME: shouldn't this be clk_disable? */ +	clk_enable(alg_data->clk); + +	return 0;  }  static int i2c_pnx_controller_resume(struct platform_device *pdev)  { -	struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev); -	return i2c_pnx->resume(pdev); +	struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev); + +	return clk_enable(alg_data->clk);  } +#else +#define i2c_pnx_controller_suspend	NULL +#define i2c_pnx_controller_resume	NULL +#endif  static int __devinit i2c_pnx_probe(struct platform_device *pdev)  {  	unsigned long tmp;  	int ret = 0;  	struct i2c_pnx_algo_data *alg_data; -	int freq_mhz; +	unsigned long freq;  	struct i2c_pnx_data *i2c_pnx = pdev->dev.platform_data; -	if (!i2c_pnx || !i2c_pnx->adapter) { +	if (!i2c_pnx || !i2c_pnx->name) {  		dev_err(&pdev->dev, "%s: no platform data supplied\n",  		       __func__);  		ret = -EINVAL;  		goto out;  	} -	platform_set_drvdata(pdev, i2c_pnx); - -	if (i2c_pnx->calculate_input_freq) -		freq_mhz = i2c_pnx->calculate_input_freq(pdev); -	else { -		freq_mhz = PNX_DEFAULT_FREQ; -		dev_info(&pdev->dev, "Setting bus frequency to default value: " -		       "%d MHz\n", freq_mhz); +	alg_data = kzalloc(sizeof(*alg_data), GFP_KERNEL); +	if (!alg_data) { +		ret = -ENOMEM; +		goto err_kzalloc;  	} -	i2c_pnx->adapter->algo = &pnx_algorithm; +	platform_set_drvdata(pdev, alg_data); + +	strlcpy(alg_data->adapter.name, i2c_pnx->name, +		sizeof(alg_data->adapter.name)); +	alg_data->adapter.dev.parent = &pdev->dev; +	alg_data->adapter.algo = &pnx_algorithm; +	alg_data->adapter.algo_data = alg_data; +	alg_data->adapter.nr = pdev->id; +	alg_data->i2c_pnx = i2c_pnx; + +	alg_data->clk = clk_get(&pdev->dev, NULL); +	if (IS_ERR(alg_data->clk)) { +		ret = PTR_ERR(alg_data->clk); +		goto out_drvdata; +	} -	alg_data = i2c_pnx->adapter->algo_data;  	init_timer(&alg_data->mif.timer);  	alg_data->mif.timer.function = i2c_pnx_timeout; -	alg_data->mif.timer.data = (unsigned long)i2c_pnx->adapter; +	alg_data->mif.timer.data = (unsigned long)alg_data;  	/* Register I/O resource */ -	if (!request_mem_region(alg_data->base, I2C_PNX_REGION_SIZE, +	if (!request_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE,  				pdev->name)) {  		dev_err(&pdev->dev,  		       "I/O region 0x%08x for I2C already in use.\n", -		       alg_data->base); +		       i2c_pnx->base);  		ret = -ENODEV; -		goto out_drvdata; +		goto out_clkget;  	} -	if (!(alg_data->ioaddr = -			(u32)ioremap(alg_data->base, I2C_PNX_REGION_SIZE))) { +	alg_data->ioaddr = ioremap(i2c_pnx->base, I2C_PNX_REGION_SIZE); +	if (!alg_data->ioaddr) {  		dev_err(&pdev->dev, "Couldn't ioremap I2C I/O region\n");  		ret = -ENOMEM;  		goto out_release;  	} -	i2c_pnx->set_clock_run(pdev); +	ret = clk_enable(alg_data->clk); +	if (ret) +		goto out_unmap; + +	freq = clk_get_rate(alg_data->clk);  	/*  	 * Clock Divisor High This value is the number of system clocks @@ -620,45 +642,47 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev)  	 * the deglitching filter length.  	 */ -	tmp = ((freq_mhz * 1000) / I2C_PNX_SPEED_KHZ) / 2 - 2; +	tmp = ((freq / 1000) / I2C_PNX_SPEED_KHZ) / 2 - 2;  	iowrite32(tmp, I2C_REG_CKH(alg_data));  	iowrite32(tmp, I2C_REG_CKL(alg_data));  	iowrite32(mcntrl_reset, I2C_REG_CTL(alg_data));  	if (wait_reset(I2C_PNX_TIMEOUT, alg_data)) {  		ret = -ENODEV; -		goto out_unmap; +		goto out_clock;  	}  	init_completion(&alg_data->mif.complete); -	ret = request_irq(alg_data->irq, i2c_pnx_interrupt, -			0, pdev->name, i2c_pnx->adapter); +	ret = request_irq(i2c_pnx->irq, i2c_pnx_interrupt, +			0, pdev->name, alg_data);  	if (ret)  		goto out_clock;  	/* Register this adapter with the I2C subsystem */ -	i2c_pnx->adapter->dev.parent = &pdev->dev; -	i2c_pnx->adapter->nr = pdev->id; -	ret = i2c_add_numbered_adapter(i2c_pnx->adapter); +	ret = i2c_add_numbered_adapter(&alg_data->adapter);  	if (ret < 0) {  		dev_err(&pdev->dev, "I2C: Failed to add bus\n");  		goto out_irq;  	}  	dev_dbg(&pdev->dev, "%s: Master at %#8x, irq %d.\n", -	       i2c_pnx->adapter->name, alg_data->base, alg_data->irq); +	       alg_data->adapter.name, i2c_pnx->base, i2c_pnx->irq);  	return 0;  out_irq: -	free_irq(alg_data->irq, i2c_pnx->adapter); +	free_irq(i2c_pnx->irq, alg_data);  out_clock: -	i2c_pnx->set_clock_stop(pdev); +	clk_disable(alg_data->clk);  out_unmap: -	iounmap((void *)alg_data->ioaddr); +	iounmap(alg_data->ioaddr);  out_release: -	release_mem_region(alg_data->base, I2C_PNX_REGION_SIZE); +	release_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE); +out_clkget: +	clk_put(alg_data->clk);  out_drvdata: +	kfree(alg_data); +err_kzalloc:  	platform_set_drvdata(pdev, NULL);  out:  	return ret; @@ -666,15 +690,16 @@ out:  static int __devexit i2c_pnx_remove(struct platform_device *pdev)  { -	struct i2c_pnx_data *i2c_pnx = platform_get_drvdata(pdev); -	struct i2c_adapter *adap = i2c_pnx->adapter; -	struct i2c_pnx_algo_data *alg_data = adap->algo_data; +	struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev); +	struct i2c_pnx_data *i2c_pnx = alg_data->i2c_pnx; -	free_irq(alg_data->irq, i2c_pnx->adapter); -	i2c_del_adapter(adap); -	i2c_pnx->set_clock_stop(pdev); -	iounmap((void *)alg_data->ioaddr); -	release_mem_region(alg_data->base, I2C_PNX_REGION_SIZE); +	free_irq(i2c_pnx->irq, alg_data); +	i2c_del_adapter(&alg_data->adapter); +	clk_disable(alg_data->clk); +	iounmap(alg_data->ioaddr); +	release_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE); +	clk_put(alg_data->clk); +	kfree(alg_data);  	platform_set_drvdata(pdev, NULL);  	return 0;  |