diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2007-08-20 05:19:10 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2007-10-12 16:14:58 -0400 |
commit | c3cef3f3c07bb98e023e4d5441e60538516a4741 (patch) | |
tree | a9b681736bef0d150635c494ff2dfe479742ad34 /drivers/i2c | |
parent | 72e3524c0b591c30c3a2e2058dd78327ec99efed (diff) |
[ARM] pxa: update pxa i2c driver to use clk support
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/i2c')
-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 bb5466b27b59..00fad11733ad 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c | |||
@@ -31,6 +31,8 @@ | |||
31 | #include <linux/interrupt.h> | 31 | #include <linux/interrupt.h> |
32 | #include <linux/i2c-pxa.h> | 32 | #include <linux/i2c-pxa.h> |
33 | #include <linux/platform_device.h> | 33 | #include <linux/platform_device.h> |
34 | #include <linux/err.h> | ||
35 | #include <linux/clk.h> | ||
34 | 36 | ||
35 | #include <asm/hardware.h> | 37 | #include <asm/hardware.h> |
36 | #include <asm/irq.h> | 38 | #include <asm/irq.h> |
@@ -48,6 +50,7 @@ struct pxa_i2c { | |||
48 | unsigned int slave_addr; | 50 | unsigned int slave_addr; |
49 | 51 | ||
50 | struct i2c_adapter adap; | 52 | struct i2c_adapter adap; |
53 | struct clk *clk; | ||
51 | #ifdef CONFIG_I2C_PXA_SLAVE | 54 | #ifdef CONFIG_I2C_PXA_SLAVE |
52 | struct i2c_slave_client *slave; | 55 | struct i2c_slave_client *slave; |
53 | #endif | 56 | #endif |
@@ -869,6 +872,12 @@ static int i2c_pxa_probe(struct platform_device *dev) | |||
869 | 872 | ||
870 | sprintf(i2c->adap.name, "pxa_i2c-i2c.%u", dev->id); | 873 | sprintf(i2c->adap.name, "pxa_i2c-i2c.%u", dev->id); |
871 | 874 | ||
875 | i2c->clk = clk_get(&dev->dev, "I2CCLK"); | ||
876 | if (IS_ERR(i2c->clk)) { | ||
877 | ret = PTR_ERR(i2c->clk); | ||
878 | goto eclk; | ||
879 | } | ||
880 | |||
872 | i2c->reg_base = ioremap(res->start, res_len(res)); | 881 | i2c->reg_base = ioremap(res->start, res_len(res)); |
873 | if (!i2c->reg_base) { | 882 | if (!i2c->reg_base) { |
874 | ret = -EIO; | 883 | ret = -EIO; |
@@ -889,22 +898,19 @@ static int i2c_pxa_probe(struct platform_device *dev) | |||
889 | } | 898 | } |
890 | #endif | 899 | #endif |
891 | 900 | ||
901 | clk_enable(i2c->clk); | ||
902 | #ifdef CONFIG_PXA27x | ||
892 | switch (dev->id) { | 903 | switch (dev->id) { |
893 | case 0: | 904 | case 0: |
894 | #ifdef CONFIG_PXA27x | ||
895 | pxa_gpio_mode(GPIO117_I2CSCL_MD); | 905 | pxa_gpio_mode(GPIO117_I2CSCL_MD); |
896 | pxa_gpio_mode(GPIO118_I2CSDA_MD); | 906 | pxa_gpio_mode(GPIO118_I2CSDA_MD); |
897 | #endif | ||
898 | pxa_set_cken(CKEN_I2C, 1); | ||
899 | break; | 907 | break; |
900 | #ifdef CONFIG_PXA27x | ||
901 | case 1: | 908 | case 1: |
902 | local_irq_disable(); | 909 | local_irq_disable(); |
903 | PCFR |= PCFR_PI2CEN; | 910 | PCFR |= PCFR_PI2CEN; |
904 | local_irq_enable(); | 911 | local_irq_enable(); |
905 | pxa_set_cken(CKEN_PWRI2C, 1); | ||
906 | #endif | ||
907 | } | 912 | } |
913 | #endif | ||
908 | 914 | ||
909 | ret = request_irq(irq, i2c_pxa_handler, IRQF_DISABLED, | 915 | ret = request_irq(irq, i2c_pxa_handler, IRQF_DISABLED, |
910 | i2c->adap.name, i2c); | 916 | i2c->adap.name, i2c); |
@@ -948,19 +954,18 @@ static int i2c_pxa_probe(struct platform_device *dev) | |||
948 | eadapt: | 954 | eadapt: |
949 | free_irq(irq, i2c); | 955 | free_irq(irq, i2c); |
950 | ereqirq: | 956 | ereqirq: |
951 | switch (dev->id) { | 957 | clk_disable(i2c->clk); |
952 | case 0: | 958 | |
953 | pxa_set_cken(CKEN_I2C, 0); | ||
954 | break; | ||
955 | #ifdef CONFIG_PXA27x | 959 | #ifdef CONFIG_PXA27x |
956 | case 1: | 960 | if (dev->id == 1) { |
957 | pxa_set_cken(CKEN_PWRI2C, 0); | ||
958 | local_irq_disable(); | 961 | local_irq_disable(); |
959 | PCFR &= ~PCFR_PI2CEN; | 962 | PCFR &= ~PCFR_PI2CEN; |
960 | local_irq_enable(); | 963 | local_irq_enable(); |
961 | #endif | ||
962 | } | 964 | } |
965 | #endif | ||
963 | eremap: | 966 | eremap: |
967 | clk_put(i2c->clk); | ||
968 | eclk: | ||
964 | kfree(i2c); | 969 | kfree(i2c); |
965 | emalloc: | 970 | emalloc: |
966 | release_mem_region(res->start, res_len(res)); | 971 | release_mem_region(res->start, res_len(res)); |
@@ -975,18 +980,18 @@ static int i2c_pxa_remove(struct platform_device *dev) | |||
975 | 980 | ||
976 | i2c_del_adapter(&i2c->adap); | 981 | i2c_del_adapter(&i2c->adap); |
977 | free_irq(i2c->irq, i2c); | 982 | free_irq(i2c->irq, i2c); |
978 | switch (dev->id) { | 983 | |
979 | case 0: | 984 | clk_disable(i2c->clk); |
980 | pxa_set_cken(CKEN_I2C, 0); | 985 | clk_put(i2c->clk); |
981 | break; | 986 | |
982 | #ifdef CONFIG_PXA27x | 987 | #ifdef CONFIG_PXA27x |
983 | case 1: | 988 | if (dev->id == 1) { |
984 | pxa_set_cken(CKEN_PWRI2C, 0); | ||
985 | local_irq_disable(); | 989 | local_irq_disable(); |
986 | PCFR &= ~PCFR_PI2CEN; | 990 | PCFR &= ~PCFR_PI2CEN; |
987 | local_irq_enable(); | 991 | local_irq_enable(); |
988 | #endif | ||
989 | } | 992 | } |
993 | #endif | ||
994 | |||
990 | release_mem_region(i2c->iobase, i2c->iosize); | 995 | release_mem_region(i2c->iobase, i2c->iosize); |
991 | kfree(i2c); | 996 | kfree(i2c); |
992 | 997 | ||