diff options
-rw-r--r-- | drivers/i2c/busses/i2c-pxa.c | 45 |
1 files changed, 25 insertions, 20 deletions
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index bb5466b27b5..00fad11733a 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -31,6 +31,8 @@ #include <linux/interrupt.h> #include <linux/i2c-pxa.h> #include <linux/platform_device.h> +#include <linux/err.h> +#include <linux/clk.h> #include <asm/hardware.h> #include <asm/irq.h> @@ -48,6 +50,7 @@ struct pxa_i2c { unsigned int slave_addr; struct i2c_adapter adap; + struct clk *clk; #ifdef CONFIG_I2C_PXA_SLAVE struct i2c_slave_client *slave; #endif @@ -869,6 +872,12 @@ static int i2c_pxa_probe(struct platform_device *dev) sprintf(i2c->adap.name, "pxa_i2c-i2c.%u", dev->id); + i2c->clk = clk_get(&dev->dev, "I2CCLK"); + if (IS_ERR(i2c->clk)) { + ret = PTR_ERR(i2c->clk); + goto eclk; + } + i2c->reg_base = ioremap(res->start, res_len(res)); if (!i2c->reg_base) { ret = -EIO; @@ -889,22 +898,19 @@ static int i2c_pxa_probe(struct platform_device *dev) } #endif + clk_enable(i2c->clk); +#ifdef CONFIG_PXA27x switch (dev->id) { case 0: -#ifdef CONFIG_PXA27x pxa_gpio_mode(GPIO117_I2CSCL_MD); pxa_gpio_mode(GPIO118_I2CSDA_MD); -#endif - pxa_set_cken(CKEN_I2C, 1); break; -#ifdef CONFIG_PXA27x case 1: local_irq_disable(); PCFR |= PCFR_PI2CEN; local_irq_enable(); - pxa_set_cken(CKEN_PWRI2C, 1); -#endif } +#endif ret = request_irq(irq, i2c_pxa_handler, IRQF_DISABLED, i2c->adap.name, i2c); @@ -948,19 +954,18 @@ static int i2c_pxa_probe(struct platform_device *dev) eadapt: free_irq(irq, i2c); ereqirq: - switch (dev->id) { - case 0: - pxa_set_cken(CKEN_I2C, 0); - break; + clk_disable(i2c->clk); + #ifdef CONFIG_PXA27x - case 1: - pxa_set_cken(CKEN_PWRI2C, 0); + if (dev->id == 1) { local_irq_disable(); PCFR &= ~PCFR_PI2CEN; local_irq_enable(); -#endif } +#endif eremap: + clk_put(i2c->clk); +eclk: kfree(i2c); emalloc: release_mem_region(res->start, res_len(res)); @@ -975,18 +980,18 @@ static int i2c_pxa_remove(struct platform_device *dev) i2c_del_adapter(&i2c->adap); free_irq(i2c->irq, i2c); - switch (dev->id) { - case 0: - pxa_set_cken(CKEN_I2C, 0); - break; + + clk_disable(i2c->clk); + clk_put(i2c->clk); + #ifdef CONFIG_PXA27x - case 1: - pxa_set_cken(CKEN_PWRI2C, 0); + if (dev->id == 1) { local_irq_disable(); PCFR &= ~PCFR_PI2CEN; local_irq_enable(); -#endif } +#endif + release_mem_region(i2c->iobase, i2c->iosize); kfree(i2c); |