diff options
Diffstat (limited to 'arch/arm/mach-u300')
-rw-r--r-- | arch/arm/mach-u300/Kconfig | 2 | ||||
-rw-r--r-- | arch/arm/mach-u300/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-u300/clock.c | 14 | ||||
-rw-r--r-- | arch/arm/mach-u300/clock.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-u300/core.c | 226 | ||||
-rw-r--r-- | arch/arm/mach-u300/dummyspichip.c | 5 | ||||
-rw-r--r-- | arch/arm/mach-u300/gpio.c | 700 | ||||
-rw-r--r-- | arch/arm/mach-u300/include/mach/coh901318.h | 11 | ||||
-rw-r--r-- | arch/arm/mach-u300/include/mach/debug-macro.S | 11 | ||||
-rw-r--r-- | arch/arm/mach-u300/include/mach/memory.h | 6 | ||||
-rw-r--r-- | arch/arm/mach-u300/include/mach/u300-regs.h | 24 | ||||
-rw-r--r-- | arch/arm/mach-u300/mmc.c | 160 | ||||
-rw-r--r-- | arch/arm/mach-u300/spi.c | 31 | ||||
-rw-r--r-- | arch/arm/mach-u300/timer.c | 41 | ||||
-rw-r--r-- | arch/arm/mach-u300/u300.c | 4 |
15 files changed, 297 insertions, 942 deletions
diff --git a/arch/arm/mach-u300/Kconfig b/arch/arm/mach-u300/Kconfig index 801b21e7f677..32a7b0f7e9f7 100644 --- a/arch/arm/mach-u300/Kconfig +++ b/arch/arm/mach-u300/Kconfig | |||
@@ -64,7 +64,7 @@ config MACH_U300_DUAL_RAM | |||
64 | bool "Dual RAM" | 64 | bool "Dual RAM" |
65 | help | 65 | help |
66 | Select this if you want support for Dual RAM phones. | 66 | Select this if you want support for Dual RAM phones. |
67 | This is two RAM memorys on different EMIFs. | 67 | This is two RAM memories on different EMIFs. |
68 | endchoice | 68 | endchoice |
69 | 69 | ||
70 | config U300_DEBUG | 70 | config U300_DEBUG |
diff --git a/arch/arm/mach-u300/Makefile b/arch/arm/mach-u300/Makefile index fab46fe9a71f..8fd354aaf0a7 100644 --- a/arch/arm/mach-u300/Makefile +++ b/arch/arm/mach-u300/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for the linux kernel, U300 machine. | 2 | # Makefile for the linux kernel, U300 machine. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := core.o clock.o timer.o gpio.o padmux.o | 5 | obj-y := core.o clock.o timer.o padmux.o |
6 | obj-m := | 6 | obj-m := |
7 | obj-n := | 7 | obj-n := |
8 | obj- := | 8 | obj- := |
diff --git a/arch/arm/mach-u300/clock.c b/arch/arm/mach-u300/clock.c index 60acf9e708ae..5535dd0a78c9 100644 --- a/arch/arm/mach-u300/clock.c +++ b/arch/arm/mach-u300/clock.c | |||
@@ -25,8 +25,8 @@ | |||
25 | #include <linux/timer.h> | 25 | #include <linux/timer.h> |
26 | #include <linux/io.h> | 26 | #include <linux/io.h> |
27 | #include <linux/seq_file.h> | 27 | #include <linux/seq_file.h> |
28 | #include <linux/clkdev.h> | ||
28 | 29 | ||
29 | #include <asm/clkdev.h> | ||
30 | #include <mach/hardware.h> | 30 | #include <mach/hardware.h> |
31 | #include <mach/syscon.h> | 31 | #include <mach/syscon.h> |
32 | 32 | ||
@@ -66,7 +66,7 @@ static DEFINE_SPINLOCK(syscon_resetreg_lock); | |||
66 | * AMBA bus | 66 | * AMBA bus |
67 | * | | 67 | * | |
68 | * +- CPU | 68 | * +- CPU |
69 | * +- NANDIF NAND Flash interface | 69 | * +- FSMC NANDIF NAND Flash interface |
70 | * +- SEMI Shared Memory interface | 70 | * +- SEMI Shared Memory interface |
71 | * +- ISP Image Signal Processor (U335 only) | 71 | * +- ISP Image Signal Processor (U335 only) |
72 | * +- CDS (U335 only) | 72 | * +- CDS (U335 only) |
@@ -263,7 +263,7 @@ static void disable_i2s0_vcxo(void) | |||
263 | val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR); | 263 | val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR); |
264 | val &= ~U300_SYSCON_CCR_I2S0_USE_VCXO; | 264 | val &= ~U300_SYSCON_CCR_I2S0_USE_VCXO; |
265 | writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); | 265 | writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); |
266 | /* Deactivate VCXO if noone else is using VCXO */ | 266 | /* Deactivate VCXO if no one else is using VCXO */ |
267 | if (!(val & U300_SYSCON_CCR_I2S1_USE_VCXO)) | 267 | if (!(val & U300_SYSCON_CCR_I2S1_USE_VCXO)) |
268 | val &= ~U300_SYSCON_CCR_TURN_VCXO_ON; | 268 | val &= ~U300_SYSCON_CCR_TURN_VCXO_ON; |
269 | writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); | 269 | writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); |
@@ -283,7 +283,7 @@ static void disable_i2s1_vcxo(void) | |||
283 | val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR); | 283 | val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR); |
284 | val &= ~U300_SYSCON_CCR_I2S1_USE_VCXO; | 284 | val &= ~U300_SYSCON_CCR_I2S1_USE_VCXO; |
285 | writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); | 285 | writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); |
286 | /* Deactivate VCXO if noone else is using VCXO */ | 286 | /* Deactivate VCXO if no one else is using VCXO */ |
287 | if (!(val & U300_SYSCON_CCR_I2S0_USE_VCXO)) | 287 | if (!(val & U300_SYSCON_CCR_I2S0_USE_VCXO)) |
288 | val &= ~U300_SYSCON_CCR_TURN_VCXO_ON; | 288 | val &= ~U300_SYSCON_CCR_TURN_VCXO_ON; |
289 | writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); | 289 | writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR); |
@@ -649,7 +649,7 @@ static unsigned long clk_round_rate_cpuclk(struct clk *clk, unsigned long rate) | |||
649 | */ | 649 | */ |
650 | long clk_round_rate(struct clk *clk, unsigned long rate) | 650 | long clk_round_rate(struct clk *clk, unsigned long rate) |
651 | { | 651 | { |
652 | /* TODO: get apropriate switches for EMIFCLK, AHBCLK and MCLK */ | 652 | /* TODO: get appropriate switches for EMIFCLK, AHBCLK and MCLK */ |
653 | /* Else default to fixed value */ | 653 | /* Else default to fixed value */ |
654 | 654 | ||
655 | if (clk->round_rate) { | 655 | if (clk->round_rate) { |
@@ -726,7 +726,7 @@ static struct clk cpu_clk = { | |||
726 | }; | 726 | }; |
727 | 727 | ||
728 | static struct clk nandif_clk = { | 728 | static struct clk nandif_clk = { |
729 | .name = "NANDIF", | 729 | .name = "FSMC", |
730 | .parent = &amba_clk, | 730 | .parent = &amba_clk, |
731 | .hw_ctrld = false, | 731 | .hw_ctrld = false, |
732 | .reset = true, | 732 | .reset = true, |
@@ -1259,7 +1259,7 @@ static struct clk_lookup lookups[] = { | |||
1259 | /* Connected directly to the AMBA bus */ | 1259 | /* Connected directly to the AMBA bus */ |
1260 | DEF_LOOKUP("amba", &amba_clk), | 1260 | DEF_LOOKUP("amba", &amba_clk), |
1261 | DEF_LOOKUP("cpu", &cpu_clk), | 1261 | DEF_LOOKUP("cpu", &cpu_clk), |
1262 | DEF_LOOKUP("fsmc", &nandif_clk), | 1262 | DEF_LOOKUP("fsmc-nand", &nandif_clk), |
1263 | DEF_LOOKUP("semi", &semi_clk), | 1263 | DEF_LOOKUP("semi", &semi_clk), |
1264 | #ifdef CONFIG_MACH_U300_BS335 | 1264 | #ifdef CONFIG_MACH_U300_BS335 |
1265 | DEF_LOOKUP("isp", &isp_clk), | 1265 | DEF_LOOKUP("isp", &isp_clk), |
diff --git a/arch/arm/mach-u300/clock.h b/arch/arm/mach-u300/clock.h index c34f3ea3017c..4f50ca8f901e 100644 --- a/arch/arm/mach-u300/clock.h +++ b/arch/arm/mach-u300/clock.h | |||
@@ -31,7 +31,7 @@ struct clk { | |||
31 | bool reset; | 31 | bool reset; |
32 | __u16 clk_val; | 32 | __u16 clk_val; |
33 | __s8 usecount; | 33 | __s8 usecount; |
34 | __u32 res_reg; | 34 | void __iomem * res_reg; |
35 | __u16 res_mask; | 35 | __u16 res_mask; |
36 | 36 | ||
37 | bool hw_ctrld; | 37 | bool hw_ctrld; |
diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index ea41c236be0f..513d6abec1f5 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * arch/arm/mach-u300/core.c | 3 | * arch/arm/mach-u300/core.c |
4 | * | 4 | * |
5 | * | 5 | * |
6 | * Copyright (C) 2007-2010 ST-Ericsson AB | 6 | * Copyright (C) 2007-2010 ST-Ericsson SA |
7 | * License terms: GNU General Public License (GPL) version 2 | 7 | * License terms: GNU General Public License (GPL) version 2 |
8 | * Core platform support, IRQ handling and device definitions. | 8 | * Core platform support, IRQ handling and device definitions. |
9 | * Author: Linus Walleij <linus.walleij@stericsson.com> | 9 | * Author: Linus Walleij <linus.walleij@stericsson.com> |
@@ -16,12 +16,15 @@ | |||
16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
17 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
18 | #include <linux/termios.h> | 18 | #include <linux/termios.h> |
19 | #include <linux/dmaengine.h> | ||
19 | #include <linux/amba/bus.h> | 20 | #include <linux/amba/bus.h> |
21 | #include <linux/amba/serial.h> | ||
20 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
21 | #include <linux/gpio.h> | 23 | #include <linux/gpio.h> |
22 | #include <linux/clk.h> | 24 | #include <linux/clk.h> |
23 | #include <linux/err.h> | 25 | #include <linux/err.h> |
24 | #include <mach/coh901318.h> | 26 | #include <linux/mtd/nand.h> |
27 | #include <linux/mtd/fsmc.h> | ||
25 | 28 | ||
26 | #include <asm/types.h> | 29 | #include <asm/types.h> |
27 | #include <asm/setup.h> | 30 | #include <asm/setup.h> |
@@ -30,6 +33,7 @@ | |||
30 | #include <asm/mach/map.h> | 33 | #include <asm/mach/map.h> |
31 | #include <asm/mach/irq.h> | 34 | #include <asm/mach/irq.h> |
32 | 35 | ||
36 | #include <mach/coh901318.h> | ||
33 | #include <mach/hardware.h> | 37 | #include <mach/hardware.h> |
34 | #include <mach/syscon.h> | 38 | #include <mach/syscon.h> |
35 | #include <mach/dma_channels.h> | 39 | #include <mach/dma_channels.h> |
@@ -94,10 +98,20 @@ void __init u300_map_io(void) | |||
94 | * Declaration of devices found on the U300 board and | 98 | * Declaration of devices found on the U300 board and |
95 | * their respective memory locations. | 99 | * their respective memory locations. |
96 | */ | 100 | */ |
101 | |||
102 | static struct amba_pl011_data uart0_plat_data = { | ||
103 | #ifdef CONFIG_COH901318 | ||
104 | .dma_filter = coh901318_filter_id, | ||
105 | .dma_rx_param = (void *) U300_DMA_UART0_RX, | ||
106 | .dma_tx_param = (void *) U300_DMA_UART0_TX, | ||
107 | #endif | ||
108 | }; | ||
109 | |||
97 | static struct amba_device uart0_device = { | 110 | static struct amba_device uart0_device = { |
98 | .dev = { | 111 | .dev = { |
112 | .coherent_dma_mask = ~0, | ||
99 | .init_name = "uart0", /* Slow device at 0x3000 offset */ | 113 | .init_name = "uart0", /* Slow device at 0x3000 offset */ |
100 | .platform_data = NULL, | 114 | .platform_data = &uart0_plat_data, |
101 | }, | 115 | }, |
102 | .res = { | 116 | .res = { |
103 | .start = U300_UART0_BASE, | 117 | .start = U300_UART0_BASE, |
@@ -109,10 +123,19 @@ static struct amba_device uart0_device = { | |||
109 | 123 | ||
110 | /* The U335 have an additional UART1 on the APP CPU */ | 124 | /* The U335 have an additional UART1 on the APP CPU */ |
111 | #ifdef CONFIG_MACH_U300_BS335 | 125 | #ifdef CONFIG_MACH_U300_BS335 |
126 | static struct amba_pl011_data uart1_plat_data = { | ||
127 | #ifdef CONFIG_COH901318 | ||
128 | .dma_filter = coh901318_filter_id, | ||
129 | .dma_rx_param = (void *) U300_DMA_UART1_RX, | ||
130 | .dma_tx_param = (void *) U300_DMA_UART1_TX, | ||
131 | #endif | ||
132 | }; | ||
133 | |||
112 | static struct amba_device uart1_device = { | 134 | static struct amba_device uart1_device = { |
113 | .dev = { | 135 | .dev = { |
136 | .coherent_dma_mask = ~0, | ||
114 | .init_name = "uart1", /* Fast device at 0x7000 offset */ | 137 | .init_name = "uart1", /* Fast device at 0x7000 offset */ |
115 | .platform_data = NULL, | 138 | .platform_data = &uart1_plat_data, |
116 | }, | 139 | }, |
117 | .res = { | 140 | .res = { |
118 | .start = U300_UART1_BASE, | 141 | .start = U300_UART1_BASE, |
@@ -285,6 +308,13 @@ static struct resource rtc_resources[] = { | |||
285 | */ | 308 | */ |
286 | static struct resource fsmc_resources[] = { | 309 | static struct resource fsmc_resources[] = { |
287 | { | 310 | { |
311 | .name = "nand_data", | ||
312 | .start = U300_NAND_CS0_PHYS_BASE, | ||
313 | .end = U300_NAND_CS0_PHYS_BASE + SZ_16K - 1, | ||
314 | .flags = IORESOURCE_MEM, | ||
315 | }, | ||
316 | { | ||
317 | .name = "fsmc_regs", | ||
288 | .start = U300_NAND_IF_PHYS_BASE, | 318 | .start = U300_NAND_IF_PHYS_BASE, |
289 | .end = U300_NAND_IF_PHYS_BASE + SZ_4K - 1, | 319 | .end = U300_NAND_IF_PHYS_BASE + SZ_4K - 1, |
290 | .flags = IORESOURCE_MEM, | 320 | .flags = IORESOURCE_MEM, |
@@ -951,42 +981,37 @@ const struct coh_dma_channel chan_config[U300_DMA_CHANNELS] = { | |||
951 | .priority_high = 0, | 981 | .priority_high = 0, |
952 | .dev_addr = U300_MSL_BASE + 6 * 0x40 + 0x220, | 982 | .dev_addr = U300_MSL_BASE + 6 * 0x40 + 0x220, |
953 | }, | 983 | }, |
984 | /* | ||
985 | * Don't set up device address, burst count or size of src | ||
986 | * or dst bus for this peripheral - handled by PrimeCell | ||
987 | * DMA extension. | ||
988 | */ | ||
954 | { | 989 | { |
955 | .number = U300_DMA_MMCSD_RX_TX, | 990 | .number = U300_DMA_MMCSD_RX_TX, |
956 | .name = "MMCSD RX TX", | 991 | .name = "MMCSD RX TX", |
957 | .priority_high = 0, | 992 | .priority_high = 0, |
958 | .dev_addr = U300_MMCSD_BASE + 0x080, | ||
959 | .param.config = COH901318_CX_CFG_CH_DISABLE | | 993 | .param.config = COH901318_CX_CFG_CH_DISABLE | |
960 | COH901318_CX_CFG_LCR_DISABLE | | 994 | COH901318_CX_CFG_LCR_DISABLE | |
961 | COH901318_CX_CFG_TC_IRQ_ENABLE | | 995 | COH901318_CX_CFG_TC_IRQ_ENABLE | |
962 | COH901318_CX_CFG_BE_IRQ_ENABLE, | 996 | COH901318_CX_CFG_BE_IRQ_ENABLE, |
963 | .param.ctrl_lli_chained = 0 | | 997 | .param.ctrl_lli_chained = 0 | |
964 | COH901318_CX_CTRL_TC_ENABLE | | 998 | COH901318_CX_CTRL_TC_ENABLE | |
965 | COH901318_CX_CTRL_BURST_COUNT_32_BYTES | | ||
966 | COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | | ||
967 | COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | | ||
968 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | 999 | COH901318_CX_CTRL_MASTER_MODE_M1RW | |
969 | COH901318_CX_CTRL_TCP_ENABLE | | 1000 | COH901318_CX_CTRL_TCP_ENABLE | |
970 | COH901318_CX_CTRL_TC_IRQ_ENABLE | | 1001 | COH901318_CX_CTRL_TC_IRQ_DISABLE | |
971 | COH901318_CX_CTRL_HSP_ENABLE | | 1002 | COH901318_CX_CTRL_HSP_ENABLE | |
972 | COH901318_CX_CTRL_HSS_DISABLE | | 1003 | COH901318_CX_CTRL_HSS_DISABLE | |
973 | COH901318_CX_CTRL_DDMA_LEGACY, | 1004 | COH901318_CX_CTRL_DDMA_LEGACY, |
974 | .param.ctrl_lli = 0 | | 1005 | .param.ctrl_lli = 0 | |
975 | COH901318_CX_CTRL_TC_ENABLE | | 1006 | COH901318_CX_CTRL_TC_ENABLE | |
976 | COH901318_CX_CTRL_BURST_COUNT_32_BYTES | | ||
977 | COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | | ||
978 | COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | | ||
979 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | 1007 | COH901318_CX_CTRL_MASTER_MODE_M1RW | |
980 | COH901318_CX_CTRL_TCP_ENABLE | | 1008 | COH901318_CX_CTRL_TCP_ENABLE | |
981 | COH901318_CX_CTRL_TC_IRQ_ENABLE | | 1009 | COH901318_CX_CTRL_TC_IRQ_DISABLE | |
982 | COH901318_CX_CTRL_HSP_ENABLE | | 1010 | COH901318_CX_CTRL_HSP_ENABLE | |
983 | COH901318_CX_CTRL_HSS_DISABLE | | 1011 | COH901318_CX_CTRL_HSS_DISABLE | |
984 | COH901318_CX_CTRL_DDMA_LEGACY, | 1012 | COH901318_CX_CTRL_DDMA_LEGACY, |
985 | .param.ctrl_lli_last = 0 | | 1013 | .param.ctrl_lli_last = 0 | |
986 | COH901318_CX_CTRL_TC_ENABLE | | 1014 | COH901318_CX_CTRL_TC_ENABLE | |
987 | COH901318_CX_CTRL_BURST_COUNT_32_BYTES | | ||
988 | COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | | ||
989 | COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | | ||
990 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | 1015 | COH901318_CX_CTRL_MASTER_MODE_M1RW | |
991 | COH901318_CX_CTRL_TCP_DISABLE | | 1016 | COH901318_CX_CTRL_TCP_DISABLE | |
992 | COH901318_CX_CTRL_TC_IRQ_ENABLE | | 1017 | COH901318_CX_CTRL_TC_IRQ_ENABLE | |
@@ -1005,15 +1030,76 @@ const struct coh_dma_channel chan_config[U300_DMA_CHANNELS] = { | |||
1005 | .name = "MSPRO RX", | 1030 | .name = "MSPRO RX", |
1006 | .priority_high = 0, | 1031 | .priority_high = 0, |
1007 | }, | 1032 | }, |
1033 | /* | ||
1034 | * Don't set up device address, burst count or size of src | ||
1035 | * or dst bus for this peripheral - handled by PrimeCell | ||
1036 | * DMA extension. | ||
1037 | */ | ||
1008 | { | 1038 | { |
1009 | .number = U300_DMA_UART0_TX, | 1039 | .number = U300_DMA_UART0_TX, |
1010 | .name = "UART0 TX", | 1040 | .name = "UART0 TX", |
1011 | .priority_high = 0, | 1041 | .priority_high = 0, |
1042 | .param.config = COH901318_CX_CFG_CH_DISABLE | | ||
1043 | COH901318_CX_CFG_LCR_DISABLE | | ||
1044 | COH901318_CX_CFG_TC_IRQ_ENABLE | | ||
1045 | COH901318_CX_CFG_BE_IRQ_ENABLE, | ||
1046 | .param.ctrl_lli_chained = 0 | | ||
1047 | COH901318_CX_CTRL_TC_ENABLE | | ||
1048 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | ||
1049 | COH901318_CX_CTRL_TCP_ENABLE | | ||
1050 | COH901318_CX_CTRL_TC_IRQ_DISABLE | | ||
1051 | COH901318_CX_CTRL_HSP_ENABLE | | ||
1052 | COH901318_CX_CTRL_HSS_DISABLE | | ||
1053 | COH901318_CX_CTRL_DDMA_LEGACY, | ||
1054 | .param.ctrl_lli = 0 | | ||
1055 | COH901318_CX_CTRL_TC_ENABLE | | ||
1056 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | ||
1057 | COH901318_CX_CTRL_TCP_ENABLE | | ||
1058 | COH901318_CX_CTRL_TC_IRQ_ENABLE | | ||
1059 | COH901318_CX_CTRL_HSP_ENABLE | | ||
1060 | COH901318_CX_CTRL_HSS_DISABLE | | ||
1061 | COH901318_CX_CTRL_DDMA_LEGACY, | ||
1062 | .param.ctrl_lli_last = 0 | | ||
1063 | COH901318_CX_CTRL_TC_ENABLE | | ||
1064 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | ||
1065 | COH901318_CX_CTRL_TCP_ENABLE | | ||
1066 | COH901318_CX_CTRL_TC_IRQ_ENABLE | | ||
1067 | COH901318_CX_CTRL_HSP_ENABLE | | ||
1068 | COH901318_CX_CTRL_HSS_DISABLE | | ||
1069 | COH901318_CX_CTRL_DDMA_LEGACY, | ||
1012 | }, | 1070 | }, |
1013 | { | 1071 | { |
1014 | .number = U300_DMA_UART0_RX, | 1072 | .number = U300_DMA_UART0_RX, |
1015 | .name = "UART0 RX", | 1073 | .name = "UART0 RX", |
1016 | .priority_high = 0, | 1074 | .priority_high = 0, |
1075 | .param.config = COH901318_CX_CFG_CH_DISABLE | | ||
1076 | COH901318_CX_CFG_LCR_DISABLE | | ||
1077 | COH901318_CX_CFG_TC_IRQ_ENABLE | | ||
1078 | COH901318_CX_CFG_BE_IRQ_ENABLE, | ||
1079 | .param.ctrl_lli_chained = 0 | | ||
1080 | COH901318_CX_CTRL_TC_ENABLE | | ||
1081 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | ||
1082 | COH901318_CX_CTRL_TCP_ENABLE | | ||
1083 | COH901318_CX_CTRL_TC_IRQ_DISABLE | | ||
1084 | COH901318_CX_CTRL_HSP_ENABLE | | ||
1085 | COH901318_CX_CTRL_HSS_DISABLE | | ||
1086 | COH901318_CX_CTRL_DDMA_LEGACY, | ||
1087 | .param.ctrl_lli = 0 | | ||
1088 | COH901318_CX_CTRL_TC_ENABLE | | ||
1089 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | ||
1090 | COH901318_CX_CTRL_TCP_ENABLE | | ||
1091 | COH901318_CX_CTRL_TC_IRQ_ENABLE | | ||
1092 | COH901318_CX_CTRL_HSP_ENABLE | | ||
1093 | COH901318_CX_CTRL_HSS_DISABLE | | ||
1094 | COH901318_CX_CTRL_DDMA_LEGACY, | ||
1095 | .param.ctrl_lli_last = 0 | | ||
1096 | COH901318_CX_CTRL_TC_ENABLE | | ||
1097 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | ||
1098 | COH901318_CX_CTRL_TCP_ENABLE | | ||
1099 | COH901318_CX_CTRL_TC_IRQ_ENABLE | | ||
1100 | COH901318_CX_CTRL_HSP_ENABLE | | ||
1101 | COH901318_CX_CTRL_HSS_DISABLE | | ||
1102 | COH901318_CX_CTRL_DDMA_LEGACY, | ||
1017 | }, | 1103 | }, |
1018 | { | 1104 | { |
1019 | .number = U300_DMA_APEX_TX, | 1105 | .number = U300_DMA_APEX_TX, |
@@ -1071,7 +1157,7 @@ const struct coh_dma_channel chan_config[U300_DMA_CHANNELS] = { | |||
1071 | COH901318_CX_CTRL_DST_ADDR_INC_DISABLE | | 1157 | COH901318_CX_CTRL_DST_ADDR_INC_DISABLE | |
1072 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | 1158 | COH901318_CX_CTRL_MASTER_MODE_M1RW | |
1073 | COH901318_CX_CTRL_TCP_ENABLE | | 1159 | COH901318_CX_CTRL_TCP_ENABLE | |
1074 | COH901318_CX_CTRL_TC_IRQ_ENABLE | | 1160 | COH901318_CX_CTRL_TC_IRQ_DISABLE | |
1075 | COH901318_CX_CTRL_HSP_ENABLE | | 1161 | COH901318_CX_CTRL_HSP_ENABLE | |
1076 | COH901318_CX_CTRL_HSS_DISABLE | | 1162 | COH901318_CX_CTRL_HSS_DISABLE | |
1077 | COH901318_CX_CTRL_DDMA_LEGACY | | 1163 | COH901318_CX_CTRL_DDMA_LEGACY | |
@@ -1243,15 +1329,77 @@ const struct coh_dma_channel chan_config[U300_DMA_CHANNELS] = { | |||
1243 | .name = "XGAM PDI", | 1329 | .name = "XGAM PDI", |
1244 | .priority_high = 0, | 1330 | .priority_high = 0, |
1245 | }, | 1331 | }, |
1332 | /* | ||
1333 | * Don't set up device address, burst count or size of src | ||
1334 | * or dst bus for this peripheral - handled by PrimeCell | ||
1335 | * DMA extension. | ||
1336 | */ | ||
1246 | { | 1337 | { |
1247 | .number = U300_DMA_SPI_TX, | 1338 | .number = U300_DMA_SPI_TX, |
1248 | .name = "SPI TX", | 1339 | .name = "SPI TX", |
1249 | .priority_high = 0, | 1340 | .priority_high = 0, |
1341 | .param.config = COH901318_CX_CFG_CH_DISABLE | | ||
1342 | COH901318_CX_CFG_LCR_DISABLE | | ||
1343 | COH901318_CX_CFG_TC_IRQ_ENABLE | | ||
1344 | COH901318_CX_CFG_BE_IRQ_ENABLE, | ||
1345 | .param.ctrl_lli_chained = 0 | | ||
1346 | COH901318_CX_CTRL_TC_ENABLE | | ||
1347 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | ||
1348 | COH901318_CX_CTRL_TCP_DISABLE | | ||
1349 | COH901318_CX_CTRL_TC_IRQ_DISABLE | | ||
1350 | COH901318_CX_CTRL_HSP_ENABLE | | ||
1351 | COH901318_CX_CTRL_HSS_DISABLE | | ||
1352 | COH901318_CX_CTRL_DDMA_LEGACY, | ||
1353 | .param.ctrl_lli = 0 | | ||
1354 | COH901318_CX_CTRL_TC_ENABLE | | ||
1355 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | ||
1356 | COH901318_CX_CTRL_TCP_DISABLE | | ||
1357 | COH901318_CX_CTRL_TC_IRQ_ENABLE | | ||
1358 | COH901318_CX_CTRL_HSP_ENABLE | | ||
1359 | COH901318_CX_CTRL_HSS_DISABLE | | ||
1360 | COH901318_CX_CTRL_DDMA_LEGACY, | ||
1361 | .param.ctrl_lli_last = 0 | | ||
1362 | COH901318_CX_CTRL_TC_ENABLE | | ||
1363 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | ||
1364 | COH901318_CX_CTRL_TCP_DISABLE | | ||
1365 | COH901318_CX_CTRL_TC_IRQ_ENABLE | | ||
1366 | COH901318_CX_CTRL_HSP_ENABLE | | ||
1367 | COH901318_CX_CTRL_HSS_DISABLE | | ||
1368 | COH901318_CX_CTRL_DDMA_LEGACY, | ||
1250 | }, | 1369 | }, |
1251 | { | 1370 | { |
1252 | .number = U300_DMA_SPI_RX, | 1371 | .number = U300_DMA_SPI_RX, |
1253 | .name = "SPI RX", | 1372 | .name = "SPI RX", |
1254 | .priority_high = 0, | 1373 | .priority_high = 0, |
1374 | .param.config = COH901318_CX_CFG_CH_DISABLE | | ||
1375 | COH901318_CX_CFG_LCR_DISABLE | | ||
1376 | COH901318_CX_CFG_TC_IRQ_ENABLE | | ||
1377 | COH901318_CX_CFG_BE_IRQ_ENABLE, | ||
1378 | .param.ctrl_lli_chained = 0 | | ||
1379 | COH901318_CX_CTRL_TC_ENABLE | | ||
1380 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | ||
1381 | COH901318_CX_CTRL_TCP_DISABLE | | ||
1382 | COH901318_CX_CTRL_TC_IRQ_DISABLE | | ||
1383 | COH901318_CX_CTRL_HSP_ENABLE | | ||
1384 | COH901318_CX_CTRL_HSS_DISABLE | | ||
1385 | COH901318_CX_CTRL_DDMA_LEGACY, | ||
1386 | .param.ctrl_lli = 0 | | ||
1387 | COH901318_CX_CTRL_TC_ENABLE | | ||
1388 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | ||
1389 | COH901318_CX_CTRL_TCP_DISABLE | | ||
1390 | COH901318_CX_CTRL_TC_IRQ_ENABLE | | ||
1391 | COH901318_CX_CTRL_HSP_ENABLE | | ||
1392 | COH901318_CX_CTRL_HSS_DISABLE | | ||
1393 | COH901318_CX_CTRL_DDMA_LEGACY, | ||
1394 | .param.ctrl_lli_last = 0 | | ||
1395 | COH901318_CX_CTRL_TC_ENABLE | | ||
1396 | COH901318_CX_CTRL_MASTER_MODE_M1RW | | ||
1397 | COH901318_CX_CTRL_TCP_DISABLE | | ||
1398 | COH901318_CX_CTRL_TC_IRQ_ENABLE | | ||
1399 | COH901318_CX_CTRL_HSP_ENABLE | | ||
1400 | COH901318_CX_CTRL_HSS_DISABLE | | ||
1401 | COH901318_CX_CTRL_DDMA_LEGACY, | ||
1402 | |||
1255 | }, | 1403 | }, |
1256 | { | 1404 | { |
1257 | .number = U300_DMA_GENERAL_PURPOSE_0, | 1405 | .number = U300_DMA_GENERAL_PURPOSE_0, |
@@ -1429,11 +1577,39 @@ static struct platform_device rtc_device = { | |||
1429 | .resource = rtc_resources, | 1577 | .resource = rtc_resources, |
1430 | }; | 1578 | }; |
1431 | 1579 | ||
1432 | static struct platform_device fsmc_device = { | 1580 | static struct mtd_partition u300_partitions[] = { |
1433 | .name = "nandif", | 1581 | { |
1582 | .name = "bootrecords", | ||
1583 | .offset = 0, | ||
1584 | .size = SZ_128K, | ||
1585 | }, | ||
1586 | { | ||
1587 | .name = "free", | ||
1588 | .offset = SZ_128K, | ||
1589 | .size = 8064 * SZ_1K, | ||
1590 | }, | ||
1591 | { | ||
1592 | .name = "platform", | ||
1593 | .offset = 8192 * SZ_1K, | ||
1594 | .size = 253952 * SZ_1K, | ||
1595 | }, | ||
1596 | }; | ||
1597 | |||
1598 | static struct fsmc_nand_platform_data nand_platform_data = { | ||
1599 | .partitions = u300_partitions, | ||
1600 | .nr_partitions = ARRAY_SIZE(u300_partitions), | ||
1601 | .options = NAND_SKIP_BBTSCAN, | ||
1602 | .width = FSMC_NAND_BW8, | ||
1603 | }; | ||
1604 | |||
1605 | static struct platform_device nand_device = { | ||
1606 | .name = "fsmc-nand", | ||
1434 | .id = -1, | 1607 | .id = -1, |
1435 | .num_resources = ARRAY_SIZE(fsmc_resources), | ||
1436 | .resource = fsmc_resources, | 1608 | .resource = fsmc_resources, |
1609 | .num_resources = ARRAY_SIZE(fsmc_resources), | ||
1610 | .dev = { | ||
1611 | .platform_data = &nand_platform_data, | ||
1612 | }, | ||
1437 | }; | 1613 | }; |
1438 | 1614 | ||
1439 | static struct platform_device ave_device = { | 1615 | static struct platform_device ave_device = { |
@@ -1465,7 +1641,7 @@ static struct platform_device *platform_devs[] __initdata = { | |||
1465 | &keypad_device, | 1641 | &keypad_device, |
1466 | &rtc_device, | 1642 | &rtc_device, |
1467 | &gpio_device, | 1643 | &gpio_device, |
1468 | &fsmc_device, | 1644 | &nand_device, |
1469 | &wdog_device, | 1645 | &wdog_device, |
1470 | &ave_device | 1646 | &ave_device |
1471 | }; | 1647 | }; |
@@ -1580,7 +1756,7 @@ static void __init u300_init_check_chip(void) | |||
1580 | #endif | 1756 | #endif |
1581 | #ifdef CONFIG_MACH_U300_BS335 | 1757 | #ifdef CONFIG_MACH_U300_BS335 |
1582 | if ((val & 0xFF00U) != 0xf000 && (val & 0xFF00U) != 0xf100) { | 1758 | if ((val & 0xFF00U) != 0xf000 && (val & 0xFF00U) != 0xf100) { |
1583 | printk(KERN_ERR "Platform configured for BS365 " \ | 1759 | printk(KERN_ERR "Platform configured for BS335 " \ |
1584 | " with DB3350 but %s detected, expect problems!", | 1760 | " with DB3350 but %s detected, expect problems!", |
1585 | chipname); | 1761 | chipname); |
1586 | } | 1762 | } |
@@ -1655,12 +1831,12 @@ void __init u300_init_devices(void) | |||
1655 | /* Register subdevices on the I2C buses */ | 1831 | /* Register subdevices on the I2C buses */ |
1656 | u300_i2c_register_board_devices(); | 1832 | u300_i2c_register_board_devices(); |
1657 | 1833 | ||
1658 | /* Register subdevices on the SPI bus */ | ||
1659 | u300_spi_register_board_devices(); | ||
1660 | |||
1661 | /* Register the platform devices */ | 1834 | /* Register the platform devices */ |
1662 | platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); | 1835 | platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); |
1663 | 1836 | ||
1837 | /* Register subdevices on the SPI bus */ | ||
1838 | u300_spi_register_board_devices(); | ||
1839 | |||
1664 | #ifndef CONFIG_MACH_U300_SEMI_IS_SHARED | 1840 | #ifndef CONFIG_MACH_U300_SEMI_IS_SHARED |
1665 | /* | 1841 | /* |
1666 | * Enable SEMI self refresh. Self-refresh of the SDRAM is entered when | 1842 | * Enable SEMI self refresh. Self-refresh of the SDRAM is entered when |
diff --git a/arch/arm/mach-u300/dummyspichip.c b/arch/arm/mach-u300/dummyspichip.c index 5f55012b7c9e..03f793612594 100644 --- a/arch/arm/mach-u300/dummyspichip.c +++ b/arch/arm/mach-u300/dummyspichip.c | |||
@@ -46,7 +46,6 @@ static ssize_t dummy_looptest(struct device *dev, | |||
46 | * struct, this is just used here to alter the behaviour of the chip | 46 | * struct, this is just used here to alter the behaviour of the chip |
47 | * in order to perform tests. | 47 | * in order to perform tests. |
48 | */ | 48 | */ |
49 | struct pl022_config_chip *chip_info = spi->controller_data; | ||
50 | int status; | 49 | int status; |
51 | u8 txbuf[14] = {0xDE, 0xAD, 0xBE, 0xEF, 0x2B, 0xAD, | 50 | u8 txbuf[14] = {0xDE, 0xAD, 0xBE, 0xEF, 0x2B, 0xAD, |
52 | 0xCA, 0xFE, 0xBA, 0xBE, 0xB1, 0x05, | 51 | 0xCA, 0xFE, 0xBA, 0xBE, 0xB1, 0x05, |
@@ -72,7 +71,7 @@ static ssize_t dummy_looptest(struct device *dev, | |||
72 | * Force chip to 8 bit mode | 71 | * Force chip to 8 bit mode |
73 | * WARNING: NEVER DO THIS IN REAL DRIVER CODE, THIS SHOULD BE STATIC! | 72 | * WARNING: NEVER DO THIS IN REAL DRIVER CODE, THIS SHOULD BE STATIC! |
74 | */ | 73 | */ |
75 | chip_info->data_size = SSP_DATA_BITS_8; | 74 | spi->bits_per_word = 8; |
76 | /* You should NOT DO THIS EITHER */ | 75 | /* You should NOT DO THIS EITHER */ |
77 | spi->master->setup(spi); | 76 | spi->master->setup(spi); |
78 | 77 | ||
@@ -159,7 +158,7 @@ static ssize_t dummy_looptest(struct device *dev, | |||
159 | * Force chip to 16 bit mode | 158 | * Force chip to 16 bit mode |
160 | * WARNING: NEVER DO THIS IN REAL DRIVER CODE, THIS SHOULD BE STATIC! | 159 | * WARNING: NEVER DO THIS IN REAL DRIVER CODE, THIS SHOULD BE STATIC! |
161 | */ | 160 | */ |
162 | chip_info->data_size = SSP_DATA_BITS_16; | 161 | spi->bits_per_word = 16; |
163 | /* You should NOT DO THIS EITHER */ | 162 | /* You should NOT DO THIS EITHER */ |
164 | spi->master->setup(spi); | 163 | spi->master->setup(spi); |
165 | 164 | ||
diff --git a/arch/arm/mach-u300/gpio.c b/arch/arm/mach-u300/gpio.c deleted file mode 100644 index d92790140fe5..000000000000 --- a/arch/arm/mach-u300/gpio.c +++ /dev/null | |||
@@ -1,700 +0,0 @@ | |||
1 | /* | ||
2 | * | ||
3 | * arch/arm/mach-u300/gpio.c | ||
4 | * | ||
5 | * | ||
6 | * Copyright (C) 2007-2009 ST-Ericsson AB | ||
7 | * License terms: GNU General Public License (GPL) version 2 | ||
8 | * U300 GPIO module. | ||
9 | * This can driver either of the two basic GPIO cores | ||
10 | * available in the U300 platforms: | ||
11 | * COH 901 335 - Used in DB3150 (U300 1.0) and DB3200 (U330 1.0) | ||
12 | * COH 901 571/3 - Used in DB3210 (U365 2.0) and DB3350 (U335 1.0) | ||
13 | * Notice that you also have inline macros in <asm-arch/gpio.h> | ||
14 | * Author: Linus Walleij <linus.walleij@stericsson.com> | ||
15 | * Author: Jonas Aaberg <jonas.aberg@stericsson.com> | ||
16 | * | ||
17 | */ | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <linux/errno.h> | ||
22 | #include <linux/io.h> | ||
23 | #include <linux/clk.h> | ||
24 | #include <linux/err.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/gpio.h> | ||
27 | |||
28 | /* Reference to GPIO block clock */ | ||
29 | static struct clk *clk; | ||
30 | |||
31 | /* Memory resource */ | ||
32 | static struct resource *memres; | ||
33 | static void __iomem *virtbase; | ||
34 | static struct device *gpiodev; | ||
35 | |||
36 | struct u300_gpio_port { | ||
37 | const char *name; | ||
38 | int irq; | ||
39 | int number; | ||
40 | }; | ||
41 | |||
42 | |||
43 | static struct u300_gpio_port gpio_ports[] = { | ||
44 | { | ||
45 | .name = "gpio0", | ||
46 | .number = 0, | ||
47 | }, | ||
48 | { | ||
49 | .name = "gpio1", | ||
50 | .number = 1, | ||
51 | }, | ||
52 | { | ||
53 | .name = "gpio2", | ||
54 | .number = 2, | ||
55 | }, | ||
56 | #ifdef U300_COH901571_3 | ||
57 | { | ||
58 | .name = "gpio3", | ||
59 | .number = 3, | ||
60 | }, | ||
61 | { | ||
62 | .name = "gpio4", | ||
63 | .number = 4, | ||
64 | }, | ||
65 | #ifdef CONFIG_MACH_U300_BS335 | ||
66 | { | ||
67 | .name = "gpio5", | ||
68 | .number = 5, | ||
69 | }, | ||
70 | { | ||
71 | .name = "gpio6", | ||
72 | .number = 6, | ||
73 | }, | ||
74 | #endif | ||
75 | #endif | ||
76 | |||
77 | }; | ||
78 | |||
79 | |||
80 | #ifdef U300_COH901571_3 | ||
81 | |||
82 | /* Default input value */ | ||
83 | #define DEFAULT_OUTPUT_LOW 0 | ||
84 | #define DEFAULT_OUTPUT_HIGH 1 | ||
85 | |||
86 | /* GPIO Pull-Up status */ | ||
87 | #define DISABLE_PULL_UP 0 | ||
88 | #define ENABLE_PULL_UP 1 | ||
89 | |||
90 | #define GPIO_NOT_USED 0 | ||
91 | #define GPIO_IN 1 | ||
92 | #define GPIO_OUT 2 | ||
93 | |||
94 | struct u300_gpio_configuration_data { | ||
95 | unsigned char pin_usage; | ||
96 | unsigned char default_output_value; | ||
97 | unsigned char pull_up; | ||
98 | }; | ||
99 | |||
100 | /* Initial configuration */ | ||
101 | const struct u300_gpio_configuration_data | ||
102 | u300_gpio_config[U300_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = { | ||
103 | #ifdef CONFIG_MACH_U300_BS335 | ||
104 | /* Port 0, pins 0-7 */ | ||
105 | { | ||
106 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
107 | {GPIO_OUT, DEFAULT_OUTPUT_HIGH, DISABLE_PULL_UP}, | ||
108 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
109 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
110 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
111 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
112 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
113 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP} | ||
114 | }, | ||
115 | /* Port 1, pins 0-7 */ | ||
116 | { | ||
117 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
118 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
119 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
120 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | ||
121 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
122 | {GPIO_OUT, DEFAULT_OUTPUT_HIGH, DISABLE_PULL_UP}, | ||
123 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
124 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP} | ||
125 | }, | ||
126 | /* Port 2, pins 0-7 */ | ||
127 | { | ||
128 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
129 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
130 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
131 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
132 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
133 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | ||
134 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
135 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP} | ||
136 | }, | ||
137 | /* Port 3, pins 0-7 */ | ||
138 | { | ||
139 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | ||
140 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
141 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
142 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
143 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
144 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
145 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
146 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP} | ||
147 | }, | ||
148 | /* Port 4, pins 0-7 */ | ||
149 | { | ||
150 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
151 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
152 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
153 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
154 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
155 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
156 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
157 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP} | ||
158 | }, | ||
159 | /* Port 5, pins 0-7 */ | ||
160 | { | ||
161 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
162 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
163 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
164 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
165 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
166 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
167 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
168 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP} | ||
169 | }, | ||
170 | /* Port 6, pind 0-7 */ | ||
171 | { | ||
172 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
173 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
174 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
175 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
176 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
177 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
178 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
179 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP} | ||
180 | } | ||
181 | #endif | ||
182 | |||
183 | #ifdef CONFIG_MACH_U300_BS365 | ||
184 | /* Port 0, pins 0-7 */ | ||
185 | { | ||
186 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
187 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
188 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
189 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
190 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
191 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
192 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | ||
193 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP} | ||
194 | }, | ||
195 | /* Port 1, pins 0-7 */ | ||
196 | { | ||
197 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
198 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
199 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
200 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
201 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
202 | {GPIO_OUT, DEFAULT_OUTPUT_HIGH, DISABLE_PULL_UP}, | ||
203 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
204 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP} | ||
205 | }, | ||
206 | /* Port 2, pins 0-7 */ | ||
207 | { | ||
208 | {GPIO_IN, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
209 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | ||
210 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
211 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, DISABLE_PULL_UP}, | ||
212 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | ||
213 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | ||
214 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | ||
215 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP} | ||
216 | }, | ||
217 | /* Port 3, pins 0-7 */ | ||
218 | { | ||
219 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | ||
220 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | ||
221 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | ||
222 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | ||
223 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | ||
224 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | ||
225 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | ||
226 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP} | ||
227 | }, | ||
228 | /* Port 4, pins 0-7 */ | ||
229 | { | ||
230 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | ||
231 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | ||
232 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | ||
233 | {GPIO_IN, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | ||
234 | /* These 4 pins doesn't exist on DB3210 */ | ||
235 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | ||
236 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | ||
237 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP}, | ||
238 | {GPIO_OUT, DEFAULT_OUTPUT_LOW, ENABLE_PULL_UP} | ||
239 | } | ||
240 | #endif | ||
241 | }; | ||
242 | #endif | ||
243 | |||
244 | |||
245 | /* No users == we can power down GPIO */ | ||
246 | static int gpio_users; | ||
247 | |||
248 | struct gpio_struct { | ||
249 | int (*callback)(void *); | ||
250 | void *data; | ||
251 | int users; | ||
252 | }; | ||
253 | |||
254 | static struct gpio_struct gpio_pin[U300_GPIO_MAX]; | ||
255 | |||
256 | /* | ||
257 | * Let drivers register callback in order to get notified when there is | ||
258 | * an interrupt on the gpio pin | ||
259 | */ | ||
260 | int gpio_register_callback(unsigned gpio, int (*func)(void *arg), void *data) | ||
261 | { | ||
262 | if (gpio_pin[gpio].callback) | ||
263 | dev_warn(gpiodev, "%s: WARNING: callback already " | ||
264 | "registered for gpio pin#%d\n", __func__, gpio); | ||
265 | gpio_pin[gpio].callback = func; | ||
266 | gpio_pin[gpio].data = data; | ||
267 | |||
268 | return 0; | ||
269 | } | ||
270 | EXPORT_SYMBOL(gpio_register_callback); | ||
271 | |||
272 | int gpio_unregister_callback(unsigned gpio) | ||
273 | { | ||
274 | if (!gpio_pin[gpio].callback) | ||
275 | dev_warn(gpiodev, "%s: WARNING: callback already " | ||
276 | "unregistered for gpio pin#%d\n", __func__, gpio); | ||
277 | gpio_pin[gpio].callback = NULL; | ||
278 | gpio_pin[gpio].data = NULL; | ||
279 | |||
280 | return 0; | ||
281 | } | ||
282 | EXPORT_SYMBOL(gpio_unregister_callback); | ||
283 | |||
284 | /* Non-zero means valid */ | ||
285 | int gpio_is_valid(int number) | ||
286 | { | ||
287 | if (number >= 0 && | ||
288 | number < (U300_GPIO_NUM_PORTS * U300_GPIO_PINS_PER_PORT)) | ||
289 | return 1; | ||
290 | return 0; | ||
291 | } | ||
292 | EXPORT_SYMBOL(gpio_is_valid); | ||
293 | |||
294 | int gpio_request(unsigned gpio, const char *label) | ||
295 | { | ||
296 | if (gpio_pin[gpio].users) | ||
297 | return -EINVAL; | ||
298 | else | ||
299 | gpio_pin[gpio].users++; | ||
300 | |||
301 | gpio_users++; | ||
302 | |||
303 | return 0; | ||
304 | } | ||
305 | EXPORT_SYMBOL(gpio_request); | ||
306 | |||
307 | void gpio_free(unsigned gpio) | ||
308 | { | ||
309 | gpio_users--; | ||
310 | gpio_pin[gpio].users--; | ||
311 | if (unlikely(gpio_pin[gpio].users < 0)) { | ||
312 | dev_warn(gpiodev, "warning: gpio#%d release mismatch\n", | ||
313 | gpio); | ||
314 | gpio_pin[gpio].users = 0; | ||
315 | } | ||
316 | |||
317 | return; | ||
318 | } | ||
319 | EXPORT_SYMBOL(gpio_free); | ||
320 | |||
321 | /* This returns zero or nonzero */ | ||
322 | int gpio_get_value(unsigned gpio) | ||
323 | { | ||
324 | return readl(virtbase + U300_GPIO_PXPDIR + | ||
325 | PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING) & (1 << (gpio & 0x07)); | ||
326 | } | ||
327 | EXPORT_SYMBOL(gpio_get_value); | ||
328 | |||
329 | /* | ||
330 | * We hope that the compiler will optimize away the unused branch | ||
331 | * in case "value" is a constant | ||
332 | */ | ||
333 | void gpio_set_value(unsigned gpio, int value) | ||
334 | { | ||
335 | u32 val; | ||
336 | unsigned long flags; | ||
337 | |||
338 | local_irq_save(flags); | ||
339 | if (value) { | ||
340 | /* set */ | ||
341 | val = readl(virtbase + U300_GPIO_PXPDOR + | ||
342 | PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING) | ||
343 | & (1 << (gpio & 0x07)); | ||
344 | writel(val | (1 << (gpio & 0x07)), virtbase + | ||
345 | U300_GPIO_PXPDOR + | ||
346 | PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING); | ||
347 | } else { | ||
348 | /* clear */ | ||
349 | val = readl(virtbase + U300_GPIO_PXPDOR + | ||
350 | PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING) | ||
351 | & (1 << (gpio & 0x07)); | ||
352 | writel(val & ~(1 << (gpio & 0x07)), virtbase + | ||
353 | U300_GPIO_PXPDOR + | ||
354 | PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING); | ||
355 | } | ||
356 | local_irq_restore(flags); | ||
357 | } | ||
358 | EXPORT_SYMBOL(gpio_set_value); | ||
359 | |||
360 | int gpio_direction_input(unsigned gpio) | ||
361 | { | ||
362 | unsigned long flags; | ||
363 | u32 val; | ||
364 | |||
365 | if (gpio > U300_GPIO_MAX) | ||
366 | return -EINVAL; | ||
367 | |||
368 | local_irq_save(flags); | ||
369 | val = readl(virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) * | ||
370 | U300_GPIO_PORTX_SPACING); | ||
371 | /* Mask out this pin*/ | ||
372 | val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << ((gpio & 0x07) << 1)); | ||
373 | /* This is not needed since it sets the bits to zero.*/ | ||
374 | /* val |= (U300_GPIO_PXPCR_PIN_MODE_INPUT << (gpio*2)); */ | ||
375 | writel(val, virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) * | ||
376 | U300_GPIO_PORTX_SPACING); | ||
377 | local_irq_restore(flags); | ||
378 | return 0; | ||
379 | } | ||
380 | EXPORT_SYMBOL(gpio_direction_input); | ||
381 | |||
382 | int gpio_direction_output(unsigned gpio, int value) | ||
383 | { | ||
384 | unsigned long flags; | ||
385 | u32 val; | ||
386 | |||
387 | if (gpio > U300_GPIO_MAX) | ||
388 | return -EINVAL; | ||
389 | |||
390 | local_irq_save(flags); | ||
391 | val = readl(virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) * | ||
392 | U300_GPIO_PORTX_SPACING); | ||
393 | /* Mask out this pin */ | ||
394 | val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << ((gpio & 0x07) << 1)); | ||
395 | /* | ||
396 | * FIXME: configure for push/pull, open drain or open source per pin | ||
397 | * in setup. The current driver will only support push/pull. | ||
398 | */ | ||
399 | val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL | ||
400 | << ((gpio & 0x07) << 1)); | ||
401 | writel(val, virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) * | ||
402 | U300_GPIO_PORTX_SPACING); | ||
403 | gpio_set_value(gpio, value); | ||
404 | local_irq_restore(flags); | ||
405 | return 0; | ||
406 | } | ||
407 | EXPORT_SYMBOL(gpio_direction_output); | ||
408 | |||
409 | /* | ||
410 | * Enable an IRQ, edge is rising edge (!= 0) or falling edge (==0). | ||
411 | */ | ||
412 | void enable_irq_on_gpio_pin(unsigned gpio, int edge) | ||
413 | { | ||
414 | u32 val; | ||
415 | unsigned long flags; | ||
416 | local_irq_save(flags); | ||
417 | |||
418 | val = readl(virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) * | ||
419 | U300_GPIO_PORTX_SPACING); | ||
420 | val |= (1 << (gpio & 0x07)); | ||
421 | writel(val, virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) * | ||
422 | U300_GPIO_PORTX_SPACING); | ||
423 | val = readl(virtbase + U300_GPIO_PXICR + PIN_TO_PORT(gpio) * | ||
424 | U300_GPIO_PORTX_SPACING); | ||
425 | if (edge) | ||
426 | val |= (1 << (gpio & 0x07)); | ||
427 | else | ||
428 | val &= ~(1 << (gpio & 0x07)); | ||
429 | writel(val, virtbase + U300_GPIO_PXICR + PIN_TO_PORT(gpio) * | ||
430 | U300_GPIO_PORTX_SPACING); | ||
431 | local_irq_restore(flags); | ||
432 | } | ||
433 | EXPORT_SYMBOL(enable_irq_on_gpio_pin); | ||
434 | |||
435 | void disable_irq_on_gpio_pin(unsigned gpio) | ||
436 | { | ||
437 | u32 val; | ||
438 | unsigned long flags; | ||
439 | |||
440 | local_irq_save(flags); | ||
441 | val = readl(virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) * | ||
442 | U300_GPIO_PORTX_SPACING); | ||
443 | val &= ~(1 << (gpio & 0x07)); | ||
444 | writel(val, virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) * | ||
445 | U300_GPIO_PORTX_SPACING); | ||
446 | local_irq_restore(flags); | ||
447 | } | ||
448 | EXPORT_SYMBOL(disable_irq_on_gpio_pin); | ||
449 | |||
450 | /* Enable (value == 0) or disable (value == 1) internal pullup */ | ||
451 | void gpio_pullup(unsigned gpio, int value) | ||
452 | { | ||
453 | u32 val; | ||
454 | unsigned long flags; | ||
455 | |||
456 | local_irq_save(flags); | ||
457 | if (value) { | ||
458 | val = readl(virtbase + U300_GPIO_PXPER + PIN_TO_PORT(gpio) * | ||
459 | U300_GPIO_PORTX_SPACING); | ||
460 | writel(val | (1 << (gpio & 0x07)), virtbase + U300_GPIO_PXPER + | ||
461 | PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING); | ||
462 | } else { | ||
463 | val = readl(virtbase + U300_GPIO_PXPER + PIN_TO_PORT(gpio) * | ||
464 | U300_GPIO_PORTX_SPACING); | ||
465 | writel(val & ~(1 << (gpio & 0x07)), virtbase + U300_GPIO_PXPER + | ||
466 | PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING); | ||
467 | } | ||
468 | local_irq_restore(flags); | ||
469 | } | ||
470 | EXPORT_SYMBOL(gpio_pullup); | ||
471 | |||
472 | static irqreturn_t gpio_irq_handler(int irq, void *dev_id) | ||
473 | { | ||
474 | struct u300_gpio_port *port = dev_id; | ||
475 | u32 val; | ||
476 | int pin; | ||
477 | |||
478 | /* Read event register */ | ||
479 | val = readl(virtbase + U300_GPIO_PXIEV + port->number * | ||
480 | U300_GPIO_PORTX_SPACING); | ||
481 | /* Mask with enable register */ | ||
482 | val &= readl(virtbase + U300_GPIO_PXIEV + port->number * | ||
483 | U300_GPIO_PORTX_SPACING); | ||
484 | /* Mask relevant bits */ | ||
485 | val &= U300_GPIO_PXIEV_ALL_IRQ_EVENT_MASK; | ||
486 | /* ACK IRQ (clear event) */ | ||
487 | writel(val, virtbase + U300_GPIO_PXIEV + port->number * | ||
488 | U300_GPIO_PORTX_SPACING); | ||
489 | /* Print message */ | ||
490 | while (val != 0) { | ||
491 | unsigned gpio; | ||
492 | |||
493 | pin = __ffs(val); | ||
494 | /* mask off this pin */ | ||
495 | val &= ~(1 << pin); | ||
496 | gpio = (port->number << 3) + pin; | ||
497 | |||
498 | if (gpio_pin[gpio].callback) | ||
499 | (void)gpio_pin[gpio].callback(gpio_pin[gpio].data); | ||
500 | else | ||
501 | dev_dbg(gpiodev, "stray GPIO IRQ on line %d\n", | ||
502 | gpio); | ||
503 | } | ||
504 | return IRQ_HANDLED; | ||
505 | } | ||
506 | |||
507 | static void gpio_set_initial_values(void) | ||
508 | { | ||
509 | #ifdef U300_COH901571_3 | ||
510 | int i, j; | ||
511 | unsigned long flags; | ||
512 | u32 val; | ||
513 | |||
514 | /* Write default values to all pins */ | ||
515 | for (i = 0; i < U300_GPIO_NUM_PORTS; i++) { | ||
516 | val = 0; | ||
517 | for (j = 0; j < 8; j++) | ||
518 | val |= (u32) (u300_gpio_config[i][j].default_output_value != DEFAULT_OUTPUT_LOW) << j; | ||
519 | local_irq_save(flags); | ||
520 | writel(val, virtbase + U300_GPIO_PXPDOR + i * U300_GPIO_PORTX_SPACING); | ||
521 | local_irq_restore(flags); | ||
522 | } | ||
523 | |||
524 | /* | ||
525 | * Put all pins that are set to either 'GPIO_OUT' or 'GPIO_NOT_USED' | ||
526 | * to output and 'GPIO_IN' to input for each port. And initialize | ||
527 | * default value on outputs. | ||
528 | */ | ||
529 | for (i = 0; i < U300_GPIO_NUM_PORTS; i++) { | ||
530 | for (j = 0; j < U300_GPIO_PINS_PER_PORT; j++) { | ||
531 | local_irq_save(flags); | ||
532 | val = readl(virtbase + U300_GPIO_PXPCR + | ||
533 | i * U300_GPIO_PORTX_SPACING); | ||
534 | /* Mask out this pin */ | ||
535 | val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << (j << 1)); | ||
536 | |||
537 | if (u300_gpio_config[i][j].pin_usage != GPIO_IN) | ||
538 | val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL << (j << 1)); | ||
539 | writel(val, virtbase + U300_GPIO_PXPCR + | ||
540 | i * U300_GPIO_PORTX_SPACING); | ||
541 | local_irq_restore(flags); | ||
542 | } | ||
543 | } | ||
544 | |||
545 | /* Enable or disable the internal pull-ups in the GPIO ASIC block */ | ||
546 | for (i = 0; i < U300_GPIO_MAX; i++) { | ||
547 | val = 0; | ||
548 | for (j = 0; j < 8; j++) | ||
549 | val |= (u32)((u300_gpio_config[i][j].pull_up == DISABLE_PULL_UP) << j); | ||
550 | local_irq_save(flags); | ||
551 | writel(val, virtbase + U300_GPIO_PXPER + i * U300_GPIO_PORTX_SPACING); | ||
552 | local_irq_restore(flags); | ||
553 | } | ||
554 | #endif | ||
555 | } | ||
556 | |||
557 | static int __init gpio_probe(struct platform_device *pdev) | ||
558 | { | ||
559 | u32 val; | ||
560 | int err = 0; | ||
561 | int i; | ||
562 | int num_irqs; | ||
563 | |||
564 | gpiodev = &pdev->dev; | ||
565 | memset(gpio_pin, 0, sizeof(gpio_pin)); | ||
566 | |||
567 | /* Get GPIO clock */ | ||
568 | clk = clk_get(&pdev->dev, NULL); | ||
569 | if (IS_ERR(clk)) { | ||
570 | err = PTR_ERR(clk); | ||
571 | dev_err(gpiodev, "could not get GPIO clock\n"); | ||
572 | goto err_no_clk; | ||
573 | } | ||
574 | err = clk_enable(clk); | ||
575 | if (err) { | ||
576 | dev_err(gpiodev, "could not enable GPIO clock\n"); | ||
577 | goto err_no_clk_enable; | ||
578 | } | ||
579 | |||
580 | memres = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
581 | if (!memres) | ||
582 | goto err_no_resource; | ||
583 | |||
584 | if (request_mem_region(memres->start, memres->end - memres->start, "GPIO Controller") | ||
585 | == NULL) { | ||
586 | err = -ENODEV; | ||
587 | goto err_no_ioregion; | ||
588 | } | ||
589 | |||
590 | virtbase = ioremap(memres->start, resource_size(memres)); | ||
591 | if (!virtbase) { | ||
592 | err = -ENOMEM; | ||
593 | goto err_no_ioremap; | ||
594 | } | ||
595 | dev_info(gpiodev, "remapped 0x%08x to %p\n", | ||
596 | memres->start, virtbase); | ||
597 | |||
598 | #ifdef U300_COH901335 | ||
599 | dev_info(gpiodev, "initializing GPIO Controller COH 901 335\n"); | ||
600 | /* Turn on the GPIO block */ | ||
601 | writel(U300_GPIO_CR_BLOCK_CLOCK_ENABLE, virtbase + U300_GPIO_CR); | ||
602 | #endif | ||
603 | |||
604 | #ifdef U300_COH901571_3 | ||
605 | dev_info(gpiodev, "initializing GPIO Controller COH 901 571/3\n"); | ||
606 | val = readl(virtbase + U300_GPIO_CR); | ||
607 | dev_info(gpiodev, "COH901571/3 block version: %d, " \ | ||
608 | "number of cores: %d\n", | ||
609 | ((val & 0x0000FE00) >> 9), | ||
610 | ((val & 0x000001FC) >> 2)); | ||
611 | writel(U300_GPIO_CR_BLOCK_CLKRQ_ENABLE, virtbase + U300_GPIO_CR); | ||
612 | #endif | ||
613 | |||
614 | gpio_set_initial_values(); | ||
615 | |||
616 | for (num_irqs = 0 ; num_irqs < U300_GPIO_NUM_PORTS; num_irqs++) { | ||
617 | |||
618 | gpio_ports[num_irqs].irq = | ||
619 | platform_get_irq_byname(pdev, | ||
620 | gpio_ports[num_irqs].name); | ||
621 | |||
622 | err = request_irq(gpio_ports[num_irqs].irq, | ||
623 | gpio_irq_handler, IRQF_DISABLED, | ||
624 | gpio_ports[num_irqs].name, | ||
625 | &gpio_ports[num_irqs]); | ||
626 | if (err) { | ||
627 | dev_err(gpiodev, "cannot allocate IRQ for %s!\n", | ||
628 | gpio_ports[num_irqs].name); | ||
629 | goto err_no_irq; | ||
630 | } | ||
631 | /* Turns off PortX_irq_force */ | ||
632 | writel(0x0, virtbase + U300_GPIO_PXIFR + | ||
633 | num_irqs * U300_GPIO_PORTX_SPACING); | ||
634 | } | ||
635 | |||
636 | return 0; | ||
637 | |||
638 | err_no_irq: | ||
639 | for (i = 0; i < num_irqs; i++) | ||
640 | free_irq(gpio_ports[i].irq, &gpio_ports[i]); | ||
641 | iounmap(virtbase); | ||
642 | err_no_ioremap: | ||
643 | release_mem_region(memres->start, memres->end - memres->start); | ||
644 | err_no_ioregion: | ||
645 | err_no_resource: | ||
646 | clk_disable(clk); | ||
647 | err_no_clk_enable: | ||
648 | clk_put(clk); | ||
649 | err_no_clk: | ||
650 | dev_info(gpiodev, "module ERROR:%d\n", err); | ||
651 | return err; | ||
652 | } | ||
653 | |||
654 | static int __exit gpio_remove(struct platform_device *pdev) | ||
655 | { | ||
656 | int i; | ||
657 | |||
658 | /* Turn off the GPIO block */ | ||
659 | writel(0x00000000U, virtbase + U300_GPIO_CR); | ||
660 | for (i = 0 ; i < U300_GPIO_NUM_PORTS; i++) | ||
661 | free_irq(gpio_ports[i].irq, &gpio_ports[i]); | ||
662 | iounmap(virtbase); | ||
663 | release_mem_region(memres->start, memres->end - memres->start); | ||
664 | clk_disable(clk); | ||
665 | clk_put(clk); | ||
666 | return 0; | ||
667 | } | ||
668 | |||
669 | static struct platform_driver gpio_driver = { | ||
670 | .driver = { | ||
671 | .name = "u300-gpio", | ||
672 | }, | ||
673 | .remove = __exit_p(gpio_remove), | ||
674 | }; | ||
675 | |||
676 | |||
677 | static int __init u300_gpio_init(void) | ||
678 | { | ||
679 | return platform_driver_probe(&gpio_driver, gpio_probe); | ||
680 | } | ||
681 | |||
682 | static void __exit u300_gpio_exit(void) | ||
683 | { | ||
684 | platform_driver_unregister(&gpio_driver); | ||
685 | } | ||
686 | |||
687 | arch_initcall(u300_gpio_init); | ||
688 | module_exit(u300_gpio_exit); | ||
689 | |||
690 | MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>"); | ||
691 | |||
692 | #ifdef U300_COH901571_3 | ||
693 | MODULE_DESCRIPTION("ST-Ericsson AB COH 901 571/3 GPIO driver"); | ||
694 | #endif | ||
695 | |||
696 | #ifdef U300_COH901335 | ||
697 | MODULE_DESCRIPTION("ST-Ericsson AB COH 901 335 GPIO driver"); | ||
698 | #endif | ||
699 | |||
700 | MODULE_LICENSE("GPL"); | ||
diff --git a/arch/arm/mach-u300/include/mach/coh901318.h b/arch/arm/mach-u300/include/mach/coh901318.h index 193da2df732c..7c3b2b2d25b6 100644 --- a/arch/arm/mach-u300/include/mach/coh901318.h +++ b/arch/arm/mach-u300/include/mach/coh901318.h | |||
@@ -24,7 +24,7 @@ | |||
24 | * @src_addr: transfer source address | 24 | * @src_addr: transfer source address |
25 | * @dst_addr: transfer destination address | 25 | * @dst_addr: transfer destination address |
26 | * @link_addr: physical address to next lli | 26 | * @link_addr: physical address to next lli |
27 | * @virt_link_addr: virtual addres of next lli (only used by pool_free) | 27 | * @virt_link_addr: virtual address of next lli (only used by pool_free) |
28 | * @phy_this: physical address of current lli (only used by pool_free) | 28 | * @phy_this: physical address of current lli (only used by pool_free) |
29 | */ | 29 | */ |
30 | struct coh901318_lli { | 30 | struct coh901318_lli { |
@@ -90,7 +90,7 @@ struct powersave { | |||
90 | * struct coh901318_platform - platform arch structure | 90 | * struct coh901318_platform - platform arch structure |
91 | * @chans_slave: specifying dma slave channels | 91 | * @chans_slave: specifying dma slave channels |
92 | * @chans_memcpy: specifying dma memcpy channels | 92 | * @chans_memcpy: specifying dma memcpy channels |
93 | * @access_memory_state: requesting DMA memeory access (on / off) | 93 | * @access_memory_state: requesting DMA memory access (on / off) |
94 | * @chan_conf: dma channel configurations | 94 | * @chan_conf: dma channel configurations |
95 | * @max_channels: max number of dma chanenls | 95 | * @max_channels: max number of dma chanenls |
96 | */ | 96 | */ |
@@ -102,6 +102,7 @@ struct coh901318_platform { | |||
102 | const int max_channels; | 102 | const int max_channels; |
103 | }; | 103 | }; |
104 | 104 | ||
105 | #ifdef CONFIG_COH901318 | ||
105 | /** | 106 | /** |
106 | * coh901318_filter_id() - DMA channel filter function | 107 | * coh901318_filter_id() - DMA channel filter function |
107 | * @chan: dma channel handle | 108 | * @chan: dma channel handle |
@@ -110,6 +111,12 @@ struct coh901318_platform { | |||
110 | * In dma_request_channel() it specifies what channel id to be requested | 111 | * In dma_request_channel() it specifies what channel id to be requested |
111 | */ | 112 | */ |
112 | bool coh901318_filter_id(struct dma_chan *chan, void *chan_id); | 113 | bool coh901318_filter_id(struct dma_chan *chan, void *chan_id); |
114 | #else | ||
115 | static inline bool coh901318_filter_id(struct dma_chan *chan, void *chan_id) | ||
116 | { | ||
117 | return false; | ||
118 | } | ||
119 | #endif | ||
113 | 120 | ||
114 | /* | 121 | /* |
115 | * DMA Controller - this access the static mappings of the coh901318 dma. | 122 | * DMA Controller - this access the static mappings of the coh901318 dma. |
diff --git a/arch/arm/mach-u300/include/mach/debug-macro.S b/arch/arm/mach-u300/include/mach/debug-macro.S index 92c12420256f..df715707bead 100644 --- a/arch/arm/mach-u300/include/mach/debug-macro.S +++ b/arch/arm/mach-u300/include/mach/debug-macro.S | |||
@@ -10,13 +10,12 @@ | |||
10 | */ | 10 | */ |
11 | #include <mach/hardware.h> | 11 | #include <mach/hardware.h> |
12 | 12 | ||
13 | .macro addruart, rx, tmp | 13 | .macro addruart, rp, rv |
14 | /* If we move the address using MMU, use this. */ | 14 | /* If we move the address using MMU, use this. */ |
15 | mrc p15, 0, \rx, c1, c0 | 15 | ldr \rp, = U300_SLOW_PER_PHYS_BASE @ MMU off, physical address |
16 | tst \rx, #1 @ MMU enabled? | 16 | ldr \rv, = U300_SLOW_PER_VIRT_BASE @ MMU on, virtual address |
17 | ldreq \rx, = U300_SLOW_PER_PHYS_BASE @ MMU off, physical address | 17 | orr \rp, \rp, #0x00003000 |
18 | ldrne \rx, = U300_SLOW_PER_VIRT_BASE @ MMU on, virtual address | 18 | orr \rv, \rv, #0x00003000 |
19 | orr \rx, \rx, #0x00003000 | ||
20 | .endm | 19 | .endm |
21 | 20 | ||
22 | #include <asm/hardware/debug-pl01x.S> | 21 | #include <asm/hardware/debug-pl01x.S> |
diff --git a/arch/arm/mach-u300/include/mach/memory.h b/arch/arm/mach-u300/include/mach/memory.h index bf134bcc129d..888e2e351ee1 100644 --- a/arch/arm/mach-u300/include/mach/memory.h +++ b/arch/arm/mach-u300/include/mach/memory.h | |||
@@ -15,17 +15,17 @@ | |||
15 | 15 | ||
16 | #ifdef CONFIG_MACH_U300_DUAL_RAM | 16 | #ifdef CONFIG_MACH_U300_DUAL_RAM |
17 | 17 | ||
18 | #define PHYS_OFFSET UL(0x48000000) | 18 | #define PLAT_PHYS_OFFSET UL(0x48000000) |
19 | #define BOOT_PARAMS_OFFSET (PHYS_OFFSET + 0x100) | 19 | #define BOOT_PARAMS_OFFSET (PHYS_OFFSET + 0x100) |
20 | 20 | ||
21 | #else | 21 | #else |
22 | 22 | ||
23 | #ifdef CONFIG_MACH_U300_2MB_ALIGNMENT_FIX | 23 | #ifdef CONFIG_MACH_U300_2MB_ALIGNMENT_FIX |
24 | #define PHYS_OFFSET (0x28000000 + \ | 24 | #define PLAT_PHYS_OFFSET (0x28000000 + \ |
25 | (CONFIG_MACH_U300_ACCESS_MEM_SIZE - \ | 25 | (CONFIG_MACH_U300_ACCESS_MEM_SIZE - \ |
26 | (CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1))*1024*1024) | 26 | (CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1))*1024*1024) |
27 | #else | 27 | #else |
28 | #define PHYS_OFFSET (0x28000000 + \ | 28 | #define PLAT_PHYS_OFFSET (0x28000000 + \ |
29 | (CONFIG_MACH_U300_ACCESS_MEM_SIZE + \ | 29 | (CONFIG_MACH_U300_ACCESS_MEM_SIZE + \ |
30 | (CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1))*1024*1024) | 30 | (CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1))*1024*1024) |
31 | #endif | 31 | #endif |
diff --git a/arch/arm/mach-u300/include/mach/u300-regs.h b/arch/arm/mach-u300/include/mach/u300-regs.h index 56721a0cd2af..035fdc9dbdb0 100644 --- a/arch/arm/mach-u300/include/mach/u300-regs.h +++ b/arch/arm/mach-u300/include/mach/u300-regs.h | |||
@@ -18,13 +18,17 @@ | |||
18 | * the defines are used for setting up the I/O memory mapping. | 18 | * the defines are used for setting up the I/O memory mapping. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #ifdef __ASSEMBLER__ | ||
22 | #define IOMEM(a) (a) | ||
23 | #else | ||
24 | #define IOMEM(a) (void __iomem *) a | ||
25 | #endif | ||
26 | |||
21 | /* NAND Flash CS0 */ | 27 | /* NAND Flash CS0 */ |
22 | #define U300_NAND_CS0_PHYS_BASE 0x80000000 | 28 | #define U300_NAND_CS0_PHYS_BASE 0x80000000 |
23 | #define U300_NAND_CS0_VIRT_BASE 0xff040000 | ||
24 | 29 | ||
25 | /* NFIF */ | 30 | /* NFIF */ |
26 | #define U300_NAND_IF_PHYS_BASE 0x9f800000 | 31 | #define U300_NAND_IF_PHYS_BASE 0x9f800000 |
27 | #define U300_NAND_IF_VIRT_BASE 0xff030000 | ||
28 | 32 | ||
29 | /* AHB Peripherals */ | 33 | /* AHB Peripherals */ |
30 | #define U300_AHB_PER_PHYS_BASE 0xa0000000 | 34 | #define U300_AHB_PER_PHYS_BASE 0xa0000000 |
@@ -50,13 +54,6 @@ | |||
50 | #endif | 54 | #endif |
51 | 55 | ||
52 | /* | 56 | /* |
53 | * All the following peripherals are specified at their PHYSICAL address, | ||
54 | * so if you need to access them (in the kernel), you MUST use the macros | ||
55 | * defined in <asm/io.h> to map to the IO_ADDRESS_AHB() IO_ADDRESS_FAST() | ||
56 | * etc. | ||
57 | */ | ||
58 | |||
59 | /* | ||
60 | * AHB peripherals | 57 | * AHB peripherals |
61 | */ | 58 | */ |
62 | 59 | ||
@@ -65,11 +62,11 @@ | |||
65 | 62 | ||
66 | /* Vectored Interrupt Controller 0, servicing 32 interrupts */ | 63 | /* Vectored Interrupt Controller 0, servicing 32 interrupts */ |
67 | #define U300_INTCON0_BASE (U300_AHB_PER_PHYS_BASE+0x1000) | 64 | #define U300_INTCON0_BASE (U300_AHB_PER_PHYS_BASE+0x1000) |
68 | #define U300_INTCON0_VBASE (U300_AHB_PER_VIRT_BASE+0x1000) | 65 | #define U300_INTCON0_VBASE IOMEM(U300_AHB_PER_VIRT_BASE+0x1000) |
69 | 66 | ||
70 | /* Vectored Interrupt Controller 1, servicing 32 interrupts */ | 67 | /* Vectored Interrupt Controller 1, servicing 32 interrupts */ |
71 | #define U300_INTCON1_BASE (U300_AHB_PER_PHYS_BASE+0x2000) | 68 | #define U300_INTCON1_BASE (U300_AHB_PER_PHYS_BASE+0x2000) |
72 | #define U300_INTCON1_VBASE (U300_AHB_PER_VIRT_BASE+0x2000) | 69 | #define U300_INTCON1_VBASE IOMEM(U300_AHB_PER_VIRT_BASE+0x2000) |
73 | 70 | ||
74 | /* Memory Stick Pro (MSPRO) controller */ | 71 | /* Memory Stick Pro (MSPRO) controller */ |
75 | #define U300_MSPRO_BASE (U300_AHB_PER_PHYS_BASE+0x3000) | 72 | #define U300_MSPRO_BASE (U300_AHB_PER_PHYS_BASE+0x3000) |
@@ -117,7 +114,7 @@ | |||
117 | 114 | ||
118 | /* SYSCON */ | 115 | /* SYSCON */ |
119 | #define U300_SYSCON_BASE (U300_SLOW_PER_PHYS_BASE+0x1000) | 116 | #define U300_SYSCON_BASE (U300_SLOW_PER_PHYS_BASE+0x1000) |
120 | #define U300_SYSCON_VBASE (U300_SLOW_PER_VIRT_BASE+0x1000) | 117 | #define U300_SYSCON_VBASE IOMEM(U300_SLOW_PER_VIRT_BASE+0x1000) |
121 | 118 | ||
122 | /* Watchdog */ | 119 | /* Watchdog */ |
123 | #define U300_WDOG_BASE (U300_SLOW_PER_PHYS_BASE+0x2000) | 120 | #define U300_WDOG_BASE (U300_SLOW_PER_PHYS_BASE+0x2000) |
@@ -127,7 +124,7 @@ | |||
127 | 124 | ||
128 | /* APP side special timer */ | 125 | /* APP side special timer */ |
129 | #define U300_TIMER_APP_BASE (U300_SLOW_PER_PHYS_BASE+0x4000) | 126 | #define U300_TIMER_APP_BASE (U300_SLOW_PER_PHYS_BASE+0x4000) |
130 | #define U300_TIMER_APP_VBASE (U300_SLOW_PER_VIRT_BASE+0x4000) | 127 | #define U300_TIMER_APP_VBASE IOMEM(U300_SLOW_PER_VIRT_BASE+0x4000) |
131 | 128 | ||
132 | /* Keypad */ | 129 | /* Keypad */ |
133 | #define U300_KEYPAD_BASE (U300_SLOW_PER_PHYS_BASE+0x5000) | 130 | #define U300_KEYPAD_BASE (U300_SLOW_PER_PHYS_BASE+0x5000) |
@@ -183,5 +180,4 @@ | |||
183 | * Virtual accessor macros for static devices | 180 | * Virtual accessor macros for static devices |
184 | */ | 181 | */ |
185 | 182 | ||
186 | |||
187 | #endif | 183 | #endif |
diff --git a/arch/arm/mach-u300/mmc.c b/arch/arm/mach-u300/mmc.c index de1ac9ad2213..677ccef5cd32 100644 --- a/arch/arm/mach-u300/mmc.c +++ b/arch/arm/mach-u300/mmc.c | |||
@@ -3,159 +3,52 @@ | |||
3 | * arch/arm/mach-u300/mmc.c | 3 | * arch/arm/mach-u300/mmc.c |
4 | * | 4 | * |
5 | * | 5 | * |
6 | * Copyright (C) 2009 ST-Ericsson AB | 6 | * Copyright (C) 2009 ST-Ericsson SA |
7 | * License terms: GNU General Public License (GPL) version 2 | 7 | * License terms: GNU General Public License (GPL) version 2 |
8 | * | 8 | * |
9 | * Author: Linus Walleij <linus.walleij@stericsson.com> | 9 | * Author: Linus Walleij <linus.walleij@stericsson.com> |
10 | * Author: Johan Lundin <johan.lundin@stericsson.com> | 10 | * Author: Johan Lundin |
11 | * Author: Jonas Aaberg <jonas.aberg@stericsson.com> | 11 | * Author: Jonas Aaberg <jonas.aberg@stericsson.com> |
12 | */ | 12 | */ |
13 | #include <linux/device.h> | 13 | #include <linux/device.h> |
14 | #include <linux/amba/bus.h> | 14 | #include <linux/amba/bus.h> |
15 | #include <linux/mmc/host.h> | 15 | #include <linux/mmc/host.h> |
16 | #include <linux/input.h> | ||
17 | #include <linux/workqueue.h> | ||
18 | #include <linux/delay.h> | ||
19 | #include <linux/regulator/consumer.h> | ||
20 | #include <linux/regulator/machine.h> | ||
21 | #include <linux/gpio.h> | 16 | #include <linux/gpio.h> |
17 | #include <linux/dmaengine.h> | ||
22 | #include <linux/amba/mmci.h> | 18 | #include <linux/amba/mmci.h> |
23 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <mach/coh901318.h> | ||
21 | #include <mach/dma_channels.h> | ||
24 | 22 | ||
25 | #include "mmc.h" | 23 | #include "mmc.h" |
26 | #include "padmux.h" | 24 | #include "padmux.h" |
27 | 25 | ||
28 | struct mmci_card_event { | 26 | static struct mmci_platform_data mmc0_plat_data = { |
29 | struct input_dev *mmc_input; | 27 | /* |
30 | int mmc_inserted; | 28 | * Do not set ocr_mask or voltage translation function, |
31 | struct work_struct workq; | 29 | * we have a regulator we can control instead. |
32 | struct mmci_platform_data mmc0_plat_data; | 30 | */ |
31 | /* Nominally 2.85V on our platform */ | ||
32 | .f_max = 24000000, | ||
33 | .gpio_wp = -1, | ||
34 | .gpio_cd = U300_GPIO_PIN_MMC_CD, | ||
35 | .cd_invert = true, | ||
36 | .capabilities = MMC_CAP_MMC_HIGHSPEED | | ||
37 | MMC_CAP_SD_HIGHSPEED | MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, | ||
38 | #ifdef CONFIG_COH901318 | ||
39 | .dma_filter = coh901318_filter_id, | ||
40 | .dma_rx_param = (void *) U300_DMA_MMCSD_RX_TX, | ||
41 | /* Don't specify a TX channel, this RX channel is bidirectional */ | ||
42 | #endif | ||
33 | }; | 43 | }; |
34 | 44 | ||
35 | static unsigned int mmc_status(struct device *dev) | ||
36 | { | ||
37 | struct mmci_card_event *mmci_card = container_of( | ||
38 | dev->platform_data, | ||
39 | struct mmci_card_event, mmc0_plat_data); | ||
40 | |||
41 | return mmci_card->mmc_inserted; | ||
42 | } | ||
43 | |||
44 | static int mmci_callback(void *data) | ||
45 | { | ||
46 | struct mmci_card_event *mmci_card = data; | ||
47 | |||
48 | disable_irq_on_gpio_pin(U300_GPIO_PIN_MMC_CD); | ||
49 | schedule_work(&mmci_card->workq); | ||
50 | |||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | |||
55 | static ssize_t gpio_show(struct device *dev, struct device_attribute *attr, | ||
56 | char *buf) | ||
57 | { | ||
58 | struct mmci_card_event *mmci_card = container_of( | ||
59 | dev->platform_data, | ||
60 | struct mmci_card_event, mmc0_plat_data); | ||
61 | |||
62 | |||
63 | return sprintf(buf, "%d\n", !mmci_card->mmc_inserted); | ||
64 | } | ||
65 | |||
66 | static DEVICE_ATTR(mmc_inserted, S_IRUGO, gpio_show, NULL); | ||
67 | |||
68 | static void _mmci_callback(struct work_struct *ws) | ||
69 | { | ||
70 | |||
71 | struct mmci_card_event *mmci_card = container_of( | ||
72 | ws, | ||
73 | struct mmci_card_event, workq); | ||
74 | |||
75 | mdelay(20); | ||
76 | |||
77 | mmci_card->mmc_inserted = !gpio_get_value(U300_GPIO_PIN_MMC_CD); | ||
78 | |||
79 | input_report_switch(mmci_card->mmc_input, KEY_INSERT, | ||
80 | mmci_card->mmc_inserted); | ||
81 | input_sync(mmci_card->mmc_input); | ||
82 | |||
83 | pr_debug("MMC/SD card was %s\n", | ||
84 | mmci_card->mmc_inserted ? "inserted" : "removed"); | ||
85 | |||
86 | enable_irq_on_gpio_pin(U300_GPIO_PIN_MMC_CD, mmci_card->mmc_inserted); | ||
87 | } | ||
88 | |||
89 | int __devinit mmc_init(struct amba_device *adev) | 45 | int __devinit mmc_init(struct amba_device *adev) |
90 | { | 46 | { |
91 | struct mmci_card_event *mmci_card; | ||
92 | struct device *mmcsd_device = &adev->dev; | 47 | struct device *mmcsd_device = &adev->dev; |
93 | struct pmx *pmx; | 48 | struct pmx *pmx; |
94 | int ret = 0; | 49 | int ret = 0; |
95 | 50 | ||
96 | mmci_card = kzalloc(sizeof(struct mmci_card_event), GFP_KERNEL); | 51 | mmcsd_device->platform_data = &mmc0_plat_data; |
97 | if (!mmci_card) | ||
98 | return -ENOMEM; | ||
99 | |||
100 | /* | ||
101 | * Do not set ocr_mask or voltage translation function, | ||
102 | * we have a regulator we can control instead. | ||
103 | */ | ||
104 | /* Nominally 2.85V on our platform */ | ||
105 | mmci_card->mmc0_plat_data.f_max = 24000000; | ||
106 | mmci_card->mmc0_plat_data.status = mmc_status; | ||
107 | mmci_card->mmc0_plat_data.gpio_wp = -1; | ||
108 | mmci_card->mmc0_plat_data.gpio_cd = -1; | ||
109 | mmci_card->mmc0_plat_data.capabilities = MMC_CAP_MMC_HIGHSPEED | | ||
110 | MMC_CAP_SD_HIGHSPEED | MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA; | ||
111 | |||
112 | mmcsd_device->platform_data = (void *) &mmci_card->mmc0_plat_data; | ||
113 | |||
114 | INIT_WORK(&mmci_card->workq, _mmci_callback); | ||
115 | |||
116 | ret = gpio_request(U300_GPIO_PIN_MMC_CD, "MMC card detection"); | ||
117 | if (ret) { | ||
118 | printk(KERN_CRIT "Could not allocate MMC card detection " \ | ||
119 | "GPIO pin\n"); | ||
120 | goto out; | ||
121 | } | ||
122 | |||
123 | ret = gpio_direction_input(U300_GPIO_PIN_MMC_CD); | ||
124 | if (ret) { | ||
125 | printk(KERN_CRIT "Invalid GPIO pin requested\n"); | ||
126 | goto out; | ||
127 | } | ||
128 | |||
129 | ret = sysfs_create_file(&mmcsd_device->kobj, | ||
130 | &dev_attr_mmc_inserted.attr); | ||
131 | if (ret) | ||
132 | goto out; | ||
133 | |||
134 | mmci_card->mmc_input = input_allocate_device(); | ||
135 | if (!mmci_card->mmc_input) { | ||
136 | printk(KERN_CRIT "Could not allocate MMC input device\n"); | ||
137 | return -ENOMEM; | ||
138 | } | ||
139 | |||
140 | mmci_card->mmc_input->name = "MMC insert notification"; | ||
141 | mmci_card->mmc_input->id.bustype = BUS_HOST; | ||
142 | mmci_card->mmc_input->id.vendor = 0; | ||
143 | mmci_card->mmc_input->id.product = 0; | ||
144 | mmci_card->mmc_input->id.version = 0x0100; | ||
145 | mmci_card->mmc_input->dev.parent = mmcsd_device; | ||
146 | input_set_capability(mmci_card->mmc_input, EV_SW, KEY_INSERT); | ||
147 | |||
148 | /* | ||
149 | * Since this must always be compiled into the kernel, this input | ||
150 | * is never unregistered or free:ed. | ||
151 | */ | ||
152 | ret = input_register_device(mmci_card->mmc_input); | ||
153 | if (ret) { | ||
154 | input_free_device(mmci_card->mmc_input); | ||
155 | goto out; | ||
156 | } | ||
157 | |||
158 | input_set_drvdata(mmci_card->mmc_input, mmci_card); | ||
159 | 52 | ||
160 | /* | 53 | /* |
161 | * Setup padmuxing for MMC. Since this must always be | 54 | * Setup padmuxing for MMC. Since this must always be |
@@ -171,12 +64,5 @@ int __devinit mmc_init(struct amba_device *adev) | |||
171 | pr_warning("Could not activate padmuxing\n"); | 64 | pr_warning("Could not activate padmuxing\n"); |
172 | } | 65 | } |
173 | 66 | ||
174 | ret = gpio_register_callback(U300_GPIO_PIN_MMC_CD, mmci_callback, | ||
175 | mmci_card); | ||
176 | |||
177 | schedule_work(&mmci_card->workq); | ||
178 | |||
179 | printk(KERN_INFO "Registered MMC insert/remove notification\n"); | ||
180 | out: | ||
181 | return ret; | 67 | return ret; |
182 | } | 68 | } |
diff --git a/arch/arm/mach-u300/spi.c b/arch/arm/mach-u300/spi.c index f0e887bea30e..5767208f1c1d 100644 --- a/arch/arm/mach-u300/spi.c +++ b/arch/arm/mach-u300/spi.c | |||
@@ -11,6 +11,9 @@ | |||
11 | #include <linux/spi/spi.h> | 11 | #include <linux/spi/spi.h> |
12 | #include <linux/amba/pl022.h> | 12 | #include <linux/amba/pl022.h> |
13 | #include <linux/err.h> | 13 | #include <linux/err.h> |
14 | #include <mach/coh901318.h> | ||
15 | #include <mach/dma_channels.h> | ||
16 | |||
14 | #include "padmux.h" | 17 | #include "padmux.h" |
15 | 18 | ||
16 | /* | 19 | /* |
@@ -30,26 +33,15 @@ static void select_dummy_chip(u32 chipselect) | |||
30 | } | 33 | } |
31 | 34 | ||
32 | struct pl022_config_chip dummy_chip_info = { | 35 | struct pl022_config_chip dummy_chip_info = { |
33 | /* Nominally this is LOOPBACK_DISABLED, but this is our dummy chip! */ | 36 | /* available POLLING_TRANSFER, INTERRUPT_TRANSFER, DMA_TRANSFER */ |
34 | .lbm = LOOPBACK_ENABLED, | 37 | .com_mode = DMA_TRANSFER, |
35 | /* | ||
36 | * available POLLING_TRANSFER and INTERRUPT_TRANSFER, | ||
37 | * DMA_TRANSFER does not work | ||
38 | */ | ||
39 | .com_mode = INTERRUPT_TRANSFER, | ||
40 | .iface = SSP_INTERFACE_MOTOROLA_SPI, | 38 | .iface = SSP_INTERFACE_MOTOROLA_SPI, |
41 | /* We can only act as master but SSP_SLAVE is possible in theory */ | 39 | /* We can only act as master but SSP_SLAVE is possible in theory */ |
42 | .hierarchy = SSP_MASTER, | 40 | .hierarchy = SSP_MASTER, |
43 | /* 0 = drive TX even as slave, 1 = do not drive TX as slave */ | 41 | /* 0 = drive TX even as slave, 1 = do not drive TX as slave */ |
44 | .slave_tx_disable = 0, | 42 | .slave_tx_disable = 0, |
45 | /* LSB first */ | ||
46 | .endian_tx = SSP_TX_LSB, | ||
47 | .endian_rx = SSP_RX_LSB, | ||
48 | .data_size = SSP_DATA_BITS_8, /* used to be 12 in some default */ | ||
49 | .rx_lev_trig = SSP_RX_1_OR_MORE_ELEM, | 43 | .rx_lev_trig = SSP_RX_1_OR_MORE_ELEM, |
50 | .tx_lev_trig = SSP_TX_1_OR_MORE_EMPTY_LOC, | 44 | .tx_lev_trig = SSP_TX_1_OR_MORE_EMPTY_LOC, |
51 | .clk_phase = SSP_CLK_SECOND_EDGE, | ||
52 | .clk_pol = SSP_CLK_POL_IDLE_LOW, | ||
53 | .ctrl_len = SSP_BITS_12, | 45 | .ctrl_len = SSP_BITS_12, |
54 | .wait_state = SSP_MWIRE_WAIT_ZERO, | 46 | .wait_state = SSP_MWIRE_WAIT_ZERO, |
55 | .duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX, | 47 | .duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX, |
@@ -75,7 +67,7 @@ static struct spi_board_info u300_spi_devices[] = { | |||
75 | .bus_num = 0, /* Only one bus on this chip */ | 67 | .bus_num = 0, /* Only one bus on this chip */ |
76 | .chip_select = 0, | 68 | .chip_select = 0, |
77 | /* Means SPI_CS_HIGH, change if e.g low CS */ | 69 | /* Means SPI_CS_HIGH, change if e.g low CS */ |
78 | .mode = 0, | 70 | .mode = SPI_MODE_1 | SPI_LOOP, |
79 | }, | 71 | }, |
80 | #endif | 72 | #endif |
81 | }; | 73 | }; |
@@ -83,8 +75,6 @@ static struct spi_board_info u300_spi_devices[] = { | |||
83 | static struct pl022_ssp_controller ssp_platform_data = { | 75 | static struct pl022_ssp_controller ssp_platform_data = { |
84 | /* If you have several SPI buses this varies, we have only bus 0 */ | 76 | /* If you have several SPI buses this varies, we have only bus 0 */ |
85 | .bus_id = 0, | 77 | .bus_id = 0, |
86 | /* Set this to 1 when we think we got DMA working */ | ||
87 | .enable_dma = 0, | ||
88 | /* | 78 | /* |
89 | * On the APP CPU GPIO 4, 5 and 6 are connected as generic | 79 | * On the APP CPU GPIO 4, 5 and 6 are connected as generic |
90 | * chip selects for SPI. (Same on U330, U335 and U365.) | 80 | * chip selects for SPI. (Same on U330, U335 and U365.) |
@@ -92,6 +82,14 @@ static struct pl022_ssp_controller ssp_platform_data = { | |||
92 | * and do padmuxing accordingly too. | 82 | * and do padmuxing accordingly too. |
93 | */ | 83 | */ |
94 | .num_chipselect = 3, | 84 | .num_chipselect = 3, |
85 | #ifdef CONFIG_COH901318 | ||
86 | .enable_dma = 1, | ||
87 | .dma_filter = coh901318_filter_id, | ||
88 | .dma_rx_param = (void *) U300_DMA_SPI_RX, | ||
89 | .dma_tx_param = (void *) U300_DMA_SPI_TX, | ||
90 | #else | ||
91 | .enable_dma = 0, | ||
92 | #endif | ||
95 | }; | 93 | }; |
96 | 94 | ||
97 | 95 | ||
@@ -117,6 +115,7 @@ void __init u300_spi_init(struct amba_device *adev) | |||
117 | } | 115 | } |
118 | 116 | ||
119 | } | 117 | } |
118 | |||
120 | void __init u300_spi_register_board_devices(void) | 119 | void __init u300_spi_register_board_devices(void) |
121 | { | 120 | { |
122 | /* Register any SPI devices */ | 121 | /* Register any SPI devices */ |
diff --git a/arch/arm/mach-u300/timer.c b/arch/arm/mach-u300/timer.c index 3fc4472719be..18d7fa0603c2 100644 --- a/arch/arm/mach-u300/timer.c +++ b/arch/arm/mach-u300/timer.c | |||
@@ -9,6 +9,7 @@ | |||
9 | * Author: Linus Walleij <linus.walleij@stericsson.com> | 9 | * Author: Linus Walleij <linus.walleij@stericsson.com> |
10 | */ | 10 | */ |
11 | #include <linux/interrupt.h> | 11 | #include <linux/interrupt.h> |
12 | #include <linux/sched.h> | ||
12 | #include <linux/time.h> | 13 | #include <linux/time.h> |
13 | #include <linux/timex.h> | 14 | #include <linux/timex.h> |
14 | #include <linux/clockchips.h> | 15 | #include <linux/clockchips.h> |
@@ -21,6 +22,7 @@ | |||
21 | #include <mach/hardware.h> | 22 | #include <mach/hardware.h> |
22 | 23 | ||
23 | /* Generic stuff */ | 24 | /* Generic stuff */ |
25 | #include <asm/sched_clock.h> | ||
24 | #include <asm/mach/map.h> | 26 | #include <asm/mach/map.h> |
25 | #include <asm/mach/time.h> | 27 | #include <asm/mach/time.h> |
26 | #include <asm/mach/irq.h> | 28 | #include <asm/mach/irq.h> |
@@ -331,20 +333,6 @@ static struct irqaction u300_timer_irq = { | |||
331 | .handler = u300_timer_interrupt, | 333 | .handler = u300_timer_interrupt, |
332 | }; | 334 | }; |
333 | 335 | ||
334 | /* Use general purpose timer 2 as clock source */ | ||
335 | static cycle_t u300_get_cycles(struct clocksource *cs) | ||
336 | { | ||
337 | return (cycles_t) readl(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC); | ||
338 | } | ||
339 | |||
340 | static struct clocksource clocksource_u300_1mhz = { | ||
341 | .name = "GPT2", | ||
342 | .rating = 300, /* Reasonably fast and accurate clock source */ | ||
343 | .read = u300_get_cycles, | ||
344 | .mask = CLOCKSOURCE_MASK(32), /* 32 bits */ | ||
345 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
346 | }; | ||
347 | |||
348 | /* | 336 | /* |
349 | * Override the global weak sched_clock symbol with this | 337 | * Override the global weak sched_clock symbol with this |
350 | * local implementation which uses the clocksource to get some | 338 | * local implementation which uses the clocksource to get some |
@@ -352,12 +340,18 @@ static struct clocksource clocksource_u300_1mhz = { | |||
352 | * this wraps around for now, since it is just a relative time | 340 | * this wraps around for now, since it is just a relative time |
353 | * stamp. (Inspired by OMAP implementation.) | 341 | * stamp. (Inspired by OMAP implementation.) |
354 | */ | 342 | */ |
343 | static DEFINE_CLOCK_DATA(cd); | ||
344 | |||
355 | unsigned long long notrace sched_clock(void) | 345 | unsigned long long notrace sched_clock(void) |
356 | { | 346 | { |
357 | return clocksource_cyc2ns(clocksource_u300_1mhz.read( | 347 | u32 cyc = readl(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC); |
358 | &clocksource_u300_1mhz), | 348 | return cyc_to_sched_clock(&cd, cyc, (u32)~0); |
359 | clocksource_u300_1mhz.mult, | 349 | } |
360 | clocksource_u300_1mhz.shift); | 350 | |
351 | static void notrace u300_update_sched_clock(void) | ||
352 | { | ||
353 | u32 cyc = readl(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC); | ||
354 | update_sched_clock(&cd, cyc, (u32)~0); | ||
361 | } | 355 | } |
362 | 356 | ||
363 | 357 | ||
@@ -375,6 +369,8 @@ static void __init u300_timer_init(void) | |||
375 | clk_enable(clk); | 369 | clk_enable(clk); |
376 | rate = clk_get_rate(clk); | 370 | rate = clk_get_rate(clk); |
377 | 371 | ||
372 | init_sched_clock(&cd, u300_update_sched_clock, 32, rate); | ||
373 | |||
378 | /* | 374 | /* |
379 | * Disable the "OS" and "DD" timers - these are designed for Symbian! | 375 | * Disable the "OS" and "DD" timers - these are designed for Symbian! |
380 | * Example usage in cnh1601578 cpu subsystem pd_timer_app.c | 376 | * Example usage in cnh1601578 cpu subsystem pd_timer_app.c |
@@ -412,11 +408,10 @@ static void __init u300_timer_init(void) | |||
412 | writel(U300_TIMER_APP_EGPT2_TIMER_ENABLE, | 408 | writel(U300_TIMER_APP_EGPT2_TIMER_ENABLE, |
413 | U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT2); | 409 | U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT2); |
414 | 410 | ||
415 | clocksource_calc_mult_shift(&clocksource_u300_1mhz, | 411 | /* Use general purpose timer 2 as clock source */ |
416 | rate, APPTIMER_MIN_RANGE); | 412 | if (clocksource_mmio_init(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC, |
417 | if (clocksource_register(&clocksource_u300_1mhz)) | 413 | "GPT2", rate, 300, 32, clocksource_mmio_readl_up)) |
418 | printk(KERN_ERR "timer: failed to initialize clock " | 414 | pr_err("timer: failed to initialize U300 clock source\n"); |
419 | "source %s\n", clocksource_u300_1mhz.name); | ||
420 | 415 | ||
421 | clockevents_calc_mult_shift(&clockevent_u300_1mhz, | 416 | clockevents_calc_mult_shift(&clockevent_u300_1mhz, |
422 | rate, APPTIMER_MIN_RANGE); | 417 | rate, APPTIMER_MIN_RANGE); |
diff --git a/arch/arm/mach-u300/u300.c b/arch/arm/mach-u300/u300.c index bfcda9820888..48b3b7f39966 100644 --- a/arch/arm/mach-u300/u300.c +++ b/arch/arm/mach-u300/u300.c | |||
@@ -19,9 +19,9 @@ | |||
19 | #include <linux/io.h> | 19 | #include <linux/io.h> |
20 | #include <mach/hardware.h> | 20 | #include <mach/hardware.h> |
21 | #include <mach/platform.h> | 21 | #include <mach/platform.h> |
22 | #include <mach/memory.h> | ||
23 | #include <asm/mach-types.h> | 22 | #include <asm/mach-types.h> |
24 | #include <asm/mach/arch.h> | 23 | #include <asm/mach/arch.h> |
24 | #include <asm/memory.h> | ||
25 | 25 | ||
26 | static void __init u300_reserve(void) | 26 | static void __init u300_reserve(void) |
27 | { | 27 | { |
@@ -61,8 +61,6 @@ static void __init u300_init_machine(void) | |||
61 | 61 | ||
62 | MACHINE_START(U300, MACH_U300_STRING) | 62 | MACHINE_START(U300, MACH_U300_STRING) |
63 | /* Maintainer: Linus Walleij <linus.walleij@stericsson.com> */ | 63 | /* Maintainer: Linus Walleij <linus.walleij@stericsson.com> */ |
64 | .phys_io = U300_AHB_PER_PHYS_BASE, | ||
65 | .io_pg_offst = ((U300_AHB_PER_VIRT_BASE) >> 18) & 0xfffc, | ||
66 | .boot_params = BOOT_PARAMS_OFFSET, | 64 | .boot_params = BOOT_PARAMS_OFFSET, |
67 | .map_io = u300_map_io, | 65 | .map_io = u300_map_io, |
68 | .reserve = u300_reserve, | 66 | .reserve = u300_reserve, |