diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-21 18:40:55 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-21 18:40:55 -0400 |
commit | 85b375a613085b78531ec86369a51c2f3b922f95 (patch) | |
tree | 716437d598de92bbd7acaf24622e9a7d74fc209a /arch/arm/plat-omap | |
parent | ec965350bb98bd291eb34f6ecddfdcfc36da1e6e (diff) | |
parent | cf816ecb533ab96b883dfdc0db174598b5b5c4d2 (diff) |
Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm: (212 commits)
[ARM] pxa: Phycore pcm-990-specific code for the PXA270 Quick Capture driver
[ARM] pxa: V4L2 soc_camera driver for PXA270
[ARM] pxa: restrict availability of pxa2xx PCMCIA drivers
[ARM] 5005/1: BAST: Fix kset_name initialiser
[ARM] 4967/1: Adds functions to set clkout rate for Samsung S3C2410
[ARM] 4988/1: Add GPIO lib support to the EP93xx
[ARM] Add initial sparsemem support
[ARM] pxa: initialise PXA devices before platform init code
[ARM] 5002/1: tosa: add two more leds
[ARM] 5004/1: Tosa: make several unreferenced structures static.
[ARM] 5003/1: Shut up sparse warnings
[ARM] 4977/2: soc - pxa2xx-ac97 - Add missing clk_enable()
[ARM] 4976/1: zylonite: Configure GPIO for WM9713 IRQ line
[ARM] 4974/1: Drop unused leds-tosa.
[ARM] 4973/1: Tosa: use leds-gpio driver.
[ARM] 4972/1: Tosa: convert scoop GPIOs usage to generic gpio code
[ARM] 4971/1: pxaficp_ir: provide startup and shutdown hooks
[ARM] pxa: lubbock: move mis-placed SPI info
[ARM] 4970/1: tosa: correct gpio used for wake up.
[ARM] 4966/1: magician: add MFP pin configuration
...
Diffstat (limited to 'arch/arm/plat-omap')
-rw-r--r-- | arch/arm/plat-omap/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/plat-omap/clock.c | 42 | ||||
-rw-r--r-- | arch/arm/plat-omap/common.c | 64 | ||||
-rw-r--r-- | arch/arm/plat-omap/gpio.c | 176 | ||||
-rw-r--r-- | arch/arm/plat-omap/mux.c | 174 | ||||
-rw-r--r-- | arch/arm/plat-omap/timer32k.c | 269 | ||||
-rw-r--r-- | arch/arm/plat-omap/usb.c | 67 |
7 files changed, 285 insertions, 509 deletions
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile index 8f56c255d1ee..bc639a30d6d1 100644 --- a/arch/arm/plat-omap/Makefile +++ b/arch/arm/plat-omap/Makefile | |||
@@ -9,8 +9,6 @@ obj-m := | |||
9 | obj-n := | 9 | obj-n := |
10 | obj- := | 10 | obj- := |
11 | 11 | ||
12 | obj-$(CONFIG_OMAP_32K_TIMER) += timer32k.o | ||
13 | |||
14 | # OCPI interconnect support for 1710, 1610 and 5912 | 12 | # OCPI interconnect support for 1710, 1610 and 5912 |
15 | obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o | 13 | obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o |
16 | 14 | ||
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c index 0a603242f367..32a533ba9ada 100644 --- a/arch/arm/plat-omap/clock.c +++ b/arch/arm/plat-omap/clock.c | |||
@@ -304,6 +304,23 @@ void propagate_rate(struct clk * tclk) | |||
304 | } | 304 | } |
305 | } | 305 | } |
306 | 306 | ||
307 | /** | ||
308 | * recalculate_root_clocks - recalculate and propagate all root clocks | ||
309 | * | ||
310 | * Recalculates all root clocks (clocks with no parent), which if the | ||
311 | * clock's .recalc is set correctly, should also propagate their rates. | ||
312 | * Called at init. | ||
313 | */ | ||
314 | void recalculate_root_clocks(void) | ||
315 | { | ||
316 | struct clk *clkp; | ||
317 | |||
318 | list_for_each_entry(clkp, &clocks, node) { | ||
319 | if (unlikely(!clkp->parent) && likely((u32)clkp->recalc)) | ||
320 | clkp->recalc(clkp); | ||
321 | } | ||
322 | } | ||
323 | |||
307 | int clk_register(struct clk *clk) | 324 | int clk_register(struct clk *clk) |
308 | { | 325 | { |
309 | if (clk == NULL || IS_ERR(clk)) | 326 | if (clk == NULL || IS_ERR(clk)) |
@@ -358,6 +375,30 @@ void clk_allow_idle(struct clk *clk) | |||
358 | } | 375 | } |
359 | EXPORT_SYMBOL(clk_allow_idle); | 376 | EXPORT_SYMBOL(clk_allow_idle); |
360 | 377 | ||
378 | void clk_enable_init_clocks(void) | ||
379 | { | ||
380 | struct clk *clkp; | ||
381 | |||
382 | list_for_each_entry(clkp, &clocks, node) { | ||
383 | if (clkp->flags & ENABLE_ON_INIT) | ||
384 | clk_enable(clkp); | ||
385 | } | ||
386 | } | ||
387 | EXPORT_SYMBOL(clk_enable_init_clocks); | ||
388 | |||
389 | #ifdef CONFIG_CPU_FREQ | ||
390 | void clk_init_cpufreq_table(struct cpufreq_frequency_table **table) | ||
391 | { | ||
392 | unsigned long flags; | ||
393 | |||
394 | spin_lock_irqsave(&clockfw_lock, flags); | ||
395 | if (arch_clock->clk_init_cpufreq_table) | ||
396 | arch_clock->clk_init_cpufreq_table(table); | ||
397 | spin_unlock_irqrestore(&clockfw_lock, flags); | ||
398 | } | ||
399 | EXPORT_SYMBOL(clk_init_cpufreq_table); | ||
400 | #endif | ||
401 | |||
361 | /*-------------------------------------------------------------------------*/ | 402 | /*-------------------------------------------------------------------------*/ |
362 | 403 | ||
363 | #ifdef CONFIG_OMAP_RESET_CLOCKS | 404 | #ifdef CONFIG_OMAP_RESET_CLOCKS |
@@ -396,3 +437,4 @@ int __init clk_init(struct clk_functions * custom_clocks) | |||
396 | 437 | ||
397 | return 0; | 438 | return 0; |
398 | } | 439 | } |
440 | |||
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c index 4f0f9c4e938e..bd1cef2c3c14 100644 --- a/arch/arm/plat-omap/common.c +++ b/arch/arm/plat-omap/common.c | |||
@@ -27,11 +27,16 @@ | |||
27 | #include <asm/setup.h> | 27 | #include <asm/setup.h> |
28 | 28 | ||
29 | #include <asm/arch/board.h> | 29 | #include <asm/arch/board.h> |
30 | #include <asm/arch/control.h> | ||
30 | #include <asm/arch/mux.h> | 31 | #include <asm/arch/mux.h> |
31 | #include <asm/arch/fpga.h> | 32 | #include <asm/arch/fpga.h> |
32 | 33 | ||
33 | #include <asm/arch/clock.h> | 34 | #include <asm/arch/clock.h> |
34 | 35 | ||
36 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) | ||
37 | # include "../mach-omap2/sdrc.h" | ||
38 | #endif | ||
39 | |||
35 | #define NO_LENGTH_CHECK 0xffffffff | 40 | #define NO_LENGTH_CHECK 0xffffffff |
36 | 41 | ||
37 | unsigned char omap_bootloader_tag[512]; | 42 | unsigned char omap_bootloader_tag[512]; |
@@ -171,8 +176,8 @@ console_initcall(omap_add_serial_console); | |||
171 | 176 | ||
172 | #if defined(CONFIG_ARCH_OMAP16XX) | 177 | #if defined(CONFIG_ARCH_OMAP16XX) |
173 | #define TIMER_32K_SYNCHRONIZED 0xfffbc410 | 178 | #define TIMER_32K_SYNCHRONIZED 0xfffbc410 |
174 | #elif defined(CONFIG_ARCH_OMAP24XX) | 179 | #elif defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) |
175 | #define TIMER_32K_SYNCHRONIZED (OMAP24XX_32KSYNCT_BASE + 0x10) | 180 | #define TIMER_32K_SYNCHRONIZED (OMAP2_32KSYNCT_BASE + 0x10) |
176 | #endif | 181 | #endif |
177 | 182 | ||
178 | #ifdef TIMER_32K_SYNCHRONIZED | 183 | #ifdef TIMER_32K_SYNCHRONIZED |
@@ -193,12 +198,35 @@ static struct clocksource clocksource_32k = { | |||
193 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 198 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
194 | }; | 199 | }; |
195 | 200 | ||
201 | /* | ||
202 | * Rounds down to nearest nsec. | ||
203 | */ | ||
204 | unsigned long long omap_32k_ticks_to_nsecs(unsigned long ticks_32k) | ||
205 | { | ||
206 | return cyc2ns(&clocksource_32k, ticks_32k); | ||
207 | } | ||
208 | |||
209 | /* | ||
210 | * Returns current time from boot in nsecs. It's OK for this to wrap | ||
211 | * around for now, as it's just a relative time stamp. | ||
212 | */ | ||
213 | unsigned long long sched_clock(void) | ||
214 | { | ||
215 | return omap_32k_ticks_to_nsecs(omap_32k_read()); | ||
216 | } | ||
217 | |||
196 | static int __init omap_init_clocksource_32k(void) | 218 | static int __init omap_init_clocksource_32k(void) |
197 | { | 219 | { |
198 | static char err[] __initdata = KERN_ERR | 220 | static char err[] __initdata = KERN_ERR |
199 | "%s: can't register clocksource!\n"; | 221 | "%s: can't register clocksource!\n"; |
200 | 222 | ||
201 | if (cpu_is_omap16xx() || cpu_is_omap24xx()) { | 223 | if (cpu_is_omap16xx() || cpu_class_is_omap2()) { |
224 | struct clk *sync_32k_ick; | ||
225 | |||
226 | sync_32k_ick = clk_get(NULL, "omap_32ksync_ick"); | ||
227 | if (sync_32k_ick) | ||
228 | clk_enable(sync_32k_ick); | ||
229 | |||
202 | clocksource_32k.mult = clocksource_hz2mult(32768, | 230 | clocksource_32k.mult = clocksource_hz2mult(32768, |
203 | clocksource_32k.shift); | 231 | clocksource_32k.shift); |
204 | 232 | ||
@@ -210,3 +238,33 @@ static int __init omap_init_clocksource_32k(void) | |||
210 | arch_initcall(omap_init_clocksource_32k); | 238 | arch_initcall(omap_init_clocksource_32k); |
211 | 239 | ||
212 | #endif /* TIMER_32K_SYNCHRONIZED */ | 240 | #endif /* TIMER_32K_SYNCHRONIZED */ |
241 | |||
242 | /* Global address base setup code */ | ||
243 | |||
244 | #if defined(CONFIG_ARCH_OMAP2420) | ||
245 | void __init omap2_set_globals_242x(void) | ||
246 | { | ||
247 | omap2_sdrc_base = OMAP2420_SDRC_BASE; | ||
248 | omap2_sms_base = OMAP2420_SMS_BASE; | ||
249 | omap_ctrl_base_set(OMAP2420_CTRL_BASE); | ||
250 | } | ||
251 | #endif | ||
252 | |||
253 | #if defined(CONFIG_ARCH_OMAP2430) | ||
254 | void __init omap2_set_globals_243x(void) | ||
255 | { | ||
256 | omap2_sdrc_base = OMAP243X_SDRC_BASE; | ||
257 | omap2_sms_base = OMAP243X_SMS_BASE; | ||
258 | omap_ctrl_base_set(OMAP243X_CTRL_BASE); | ||
259 | } | ||
260 | #endif | ||
261 | |||
262 | #if defined(CONFIG_ARCH_OMAP3430) | ||
263 | void __init omap2_set_globals_343x(void) | ||
264 | { | ||
265 | omap2_sdrc_base = OMAP343X_SDRC_BASE; | ||
266 | omap2_sms_base = OMAP343X_SMS_BASE; | ||
267 | omap_ctrl_base_set(OMAP343X_CTRL_BASE); | ||
268 | } | ||
269 | #endif | ||
270 | |||
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 8c78e4e57b5c..1903a3491ee9 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c | |||
@@ -136,7 +136,6 @@ struct gpio_bank { | |||
136 | u16 irq; | 136 | u16 irq; |
137 | u16 virtual_irq_start; | 137 | u16 virtual_irq_start; |
138 | int method; | 138 | int method; |
139 | u32 reserved_map; | ||
140 | #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) | 139 | #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) |
141 | u32 suspend_wakeup; | 140 | u32 suspend_wakeup; |
142 | u32 saved_wakeup; | 141 | u32 saved_wakeup; |
@@ -149,7 +148,9 @@ struct gpio_bank { | |||
149 | u32 saved_fallingdetect; | 148 | u32 saved_fallingdetect; |
150 | u32 saved_risingdetect; | 149 | u32 saved_risingdetect; |
151 | #endif | 150 | #endif |
151 | u32 level_mask; | ||
152 | spinlock_t lock; | 152 | spinlock_t lock; |
153 | struct gpio_chip chip; | ||
153 | }; | 154 | }; |
154 | 155 | ||
155 | #define METHOD_MPUIO 0 | 156 | #define METHOD_MPUIO 0 |
@@ -538,10 +539,9 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, | |||
538 | bank->enabled_non_wakeup_gpios &= ~gpio_bit; | 539 | bank->enabled_non_wakeup_gpios &= ~gpio_bit; |
539 | } | 540 | } |
540 | 541 | ||
541 | /* | 542 | bank->level_mask = |
542 | * FIXME: Possibly do 'set_irq_handler(j, handle_level_irq)' if only | 543 | __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0) | |
543 | * level triggering requested. | 544 | __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1); |
544 | */ | ||
545 | } | 545 | } |
546 | #endif | 546 | #endif |
547 | 547 | ||
@@ -652,6 +652,12 @@ static int gpio_irq_type(unsigned irq, unsigned type) | |||
652 | irq_desc[irq].status |= type; | 652 | irq_desc[irq].status |= type; |
653 | } | 653 | } |
654 | spin_unlock_irqrestore(&bank->lock, flags); | 654 | spin_unlock_irqrestore(&bank->lock, flags); |
655 | |||
656 | if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) | ||
657 | __set_irq_handler_unlocked(irq, handle_level_irq); | ||
658 | else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) | ||
659 | __set_irq_handler_unlocked(irq, handle_edge_irq); | ||
660 | |||
655 | return retval; | 661 | return retval; |
656 | } | 662 | } |
657 | 663 | ||
@@ -903,19 +909,17 @@ int omap_request_gpio(int gpio) | |||
903 | { | 909 | { |
904 | struct gpio_bank *bank; | 910 | struct gpio_bank *bank; |
905 | unsigned long flags; | 911 | unsigned long flags; |
912 | int status; | ||
906 | 913 | ||
907 | if (check_gpio(gpio) < 0) | 914 | if (check_gpio(gpio) < 0) |
908 | return -EINVAL; | 915 | return -EINVAL; |
909 | 916 | ||
917 | status = gpio_request(gpio, NULL); | ||
918 | if (status < 0) | ||
919 | return status; | ||
920 | |||
910 | bank = get_gpio_bank(gpio); | 921 | bank = get_gpio_bank(gpio); |
911 | spin_lock_irqsave(&bank->lock, flags); | 922 | spin_lock_irqsave(&bank->lock, flags); |
912 | if (unlikely(bank->reserved_map & (1 << get_gpio_index(gpio)))) { | ||
913 | printk(KERN_ERR "omap-gpio: GPIO %d is already reserved!\n", gpio); | ||
914 | dump_stack(); | ||
915 | spin_unlock_irqrestore(&bank->lock, flags); | ||
916 | return -1; | ||
917 | } | ||
918 | bank->reserved_map |= (1 << get_gpio_index(gpio)); | ||
919 | 923 | ||
920 | /* Set trigger to none. You need to enable the desired trigger with | 924 | /* Set trigger to none. You need to enable the desired trigger with |
921 | * request_irq() or set_irq_type(). | 925 | * request_irq() or set_irq_type(). |
@@ -945,10 +949,11 @@ void omap_free_gpio(int gpio) | |||
945 | return; | 949 | return; |
946 | bank = get_gpio_bank(gpio); | 950 | bank = get_gpio_bank(gpio); |
947 | spin_lock_irqsave(&bank->lock, flags); | 951 | spin_lock_irqsave(&bank->lock, flags); |
948 | if (unlikely(!(bank->reserved_map & (1 << get_gpio_index(gpio))))) { | 952 | if (unlikely(!gpiochip_is_requested(&bank->chip, |
953 | get_gpio_index(gpio)))) { | ||
954 | spin_unlock_irqrestore(&bank->lock, flags); | ||
949 | printk(KERN_ERR "omap-gpio: GPIO %d wasn't reserved!\n", gpio); | 955 | printk(KERN_ERR "omap-gpio: GPIO %d wasn't reserved!\n", gpio); |
950 | dump_stack(); | 956 | dump_stack(); |
951 | spin_unlock_irqrestore(&bank->lock, flags); | ||
952 | return; | 957 | return; |
953 | } | 958 | } |
954 | #ifdef CONFIG_ARCH_OMAP16XX | 959 | #ifdef CONFIG_ARCH_OMAP16XX |
@@ -965,9 +970,9 @@ void omap_free_gpio(int gpio) | |||
965 | __raw_writel(1 << get_gpio_index(gpio), reg); | 970 | __raw_writel(1 << get_gpio_index(gpio), reg); |
966 | } | 971 | } |
967 | #endif | 972 | #endif |
968 | bank->reserved_map &= ~(1 << get_gpio_index(gpio)); | ||
969 | _reset_gpio(bank, gpio); | 973 | _reset_gpio(bank, gpio); |
970 | spin_unlock_irqrestore(&bank->lock, flags); | 974 | spin_unlock_irqrestore(&bank->lock, flags); |
975 | gpio_free(gpio); | ||
971 | } | 976 | } |
972 | 977 | ||
973 | /* | 978 | /* |
@@ -1022,12 +1027,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
1022 | isr &= 0x0000ffff; | 1027 | isr &= 0x0000ffff; |
1023 | 1028 | ||
1024 | if (cpu_class_is_omap2()) { | 1029 | if (cpu_class_is_omap2()) { |
1025 | level_mask = | 1030 | level_mask = bank->level_mask & enabled; |
1026 | __raw_readl(bank->base + | ||
1027 | OMAP24XX_GPIO_LEVELDETECT0) | | ||
1028 | __raw_readl(bank->base + | ||
1029 | OMAP24XX_GPIO_LEVELDETECT1); | ||
1030 | level_mask &= enabled; | ||
1031 | } | 1031 | } |
1032 | 1032 | ||
1033 | /* clear edge sensitive interrupts before handler(s) are | 1033 | /* clear edge sensitive interrupts before handler(s) are |
@@ -1052,51 +1052,13 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
1052 | gpio_irq = bank->virtual_irq_start; | 1052 | gpio_irq = bank->virtual_irq_start; |
1053 | for (; isr != 0; isr >>= 1, gpio_irq++) { | 1053 | for (; isr != 0; isr >>= 1, gpio_irq++) { |
1054 | struct irq_desc *d; | 1054 | struct irq_desc *d; |
1055 | int irq_mask; | 1055 | |
1056 | if (!(isr & 1)) | 1056 | if (!(isr & 1)) |
1057 | continue; | 1057 | continue; |
1058 | d = irq_desc + gpio_irq; | 1058 | d = irq_desc + gpio_irq; |
1059 | /* Don't run the handler if it's already running | ||
1060 | * or was disabled lazely. | ||
1061 | */ | ||
1062 | if (unlikely((d->depth || | ||
1063 | (d->status & IRQ_INPROGRESS)))) { | ||
1064 | irq_mask = 1 << | ||
1065 | (gpio_irq - bank->virtual_irq_start); | ||
1066 | /* The unmasking will be done by | ||
1067 | * enable_irq in case it is disabled or | ||
1068 | * after returning from the handler if | ||
1069 | * it's already running. | ||
1070 | */ | ||
1071 | _enable_gpio_irqbank(bank, irq_mask, 0); | ||
1072 | if (!d->depth) { | ||
1073 | /* Level triggered interrupts | ||
1074 | * won't ever be reentered | ||
1075 | */ | ||
1076 | BUG_ON(level_mask & irq_mask); | ||
1077 | d->status |= IRQ_PENDING; | ||
1078 | } | ||
1079 | continue; | ||
1080 | } | ||
1081 | 1059 | ||
1082 | desc_handle_irq(gpio_irq, d); | 1060 | desc_handle_irq(gpio_irq, d); |
1083 | |||
1084 | if (unlikely((d->status & IRQ_PENDING) && !d->depth)) { | ||
1085 | irq_mask = 1 << | ||
1086 | (gpio_irq - bank->virtual_irq_start); | ||
1087 | d->status &= ~IRQ_PENDING; | ||
1088 | _enable_gpio_irqbank(bank, irq_mask, 1); | ||
1089 | retrigger |= irq_mask; | ||
1090 | } | ||
1091 | } | 1061 | } |
1092 | |||
1093 | if (cpu_class_is_omap2()) { | ||
1094 | /* clear level sensitive interrupts after handler(s) */ | ||
1095 | _enable_gpio_irqbank(bank, isr_saved & level_mask, 0); | ||
1096 | _clear_gpio_irqbank(bank, isr_saved & level_mask); | ||
1097 | _enable_gpio_irqbank(bank, isr_saved & level_mask, 1); | ||
1098 | } | ||
1099 | |||
1100 | } | 1062 | } |
1101 | /* if bank has any level sensitive GPIO pin interrupt | 1063 | /* if bank has any level sensitive GPIO pin interrupt |
1102 | configured, we must unmask the bank interrupt only after | 1064 | configured, we must unmask the bank interrupt only after |
@@ -1135,6 +1097,14 @@ static void gpio_unmask_irq(unsigned int irq) | |||
1135 | { | 1097 | { |
1136 | unsigned int gpio = irq - IH_GPIO_BASE; | 1098 | unsigned int gpio = irq - IH_GPIO_BASE; |
1137 | struct gpio_bank *bank = get_irq_chip_data(irq); | 1099 | struct gpio_bank *bank = get_irq_chip_data(irq); |
1100 | unsigned int irq_mask = 1 << get_gpio_index(gpio); | ||
1101 | |||
1102 | /* For level-triggered GPIOs, the clearing must be done after | ||
1103 | * the HW source is cleared, thus after the handler has run */ | ||
1104 | if (bank->level_mask & irq_mask) { | ||
1105 | _set_gpio_irqenable(bank, gpio, 0); | ||
1106 | _clear_gpio_irqstatus(bank, gpio); | ||
1107 | } | ||
1138 | 1108 | ||
1139 | _set_gpio_irqenable(bank, gpio, 1); | 1109 | _set_gpio_irqenable(bank, gpio, 1); |
1140 | } | 1110 | } |
@@ -1266,6 +1236,53 @@ static inline void mpuio_init(void) {} | |||
1266 | 1236 | ||
1267 | /*---------------------------------------------------------------------*/ | 1237 | /*---------------------------------------------------------------------*/ |
1268 | 1238 | ||
1239 | /* REVISIT these are stupid implementations! replace by ones that | ||
1240 | * don't switch on METHOD_* and which mostly avoid spinlocks | ||
1241 | */ | ||
1242 | |||
1243 | static int gpio_input(struct gpio_chip *chip, unsigned offset) | ||
1244 | { | ||
1245 | struct gpio_bank *bank; | ||
1246 | unsigned long flags; | ||
1247 | |||
1248 | bank = container_of(chip, struct gpio_bank, chip); | ||
1249 | spin_lock_irqsave(&bank->lock, flags); | ||
1250 | _set_gpio_direction(bank, offset, 1); | ||
1251 | spin_unlock_irqrestore(&bank->lock, flags); | ||
1252 | return 0; | ||
1253 | } | ||
1254 | |||
1255 | static int gpio_get(struct gpio_chip *chip, unsigned offset) | ||
1256 | { | ||
1257 | return omap_get_gpio_datain(chip->base + offset); | ||
1258 | } | ||
1259 | |||
1260 | static int gpio_output(struct gpio_chip *chip, unsigned offset, int value) | ||
1261 | { | ||
1262 | struct gpio_bank *bank; | ||
1263 | unsigned long flags; | ||
1264 | |||
1265 | bank = container_of(chip, struct gpio_bank, chip); | ||
1266 | spin_lock_irqsave(&bank->lock, flags); | ||
1267 | _set_gpio_dataout(bank, offset, value); | ||
1268 | _set_gpio_direction(bank, offset, 0); | ||
1269 | spin_unlock_irqrestore(&bank->lock, flags); | ||
1270 | return 0; | ||
1271 | } | ||
1272 | |||
1273 | static void gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
1274 | { | ||
1275 | struct gpio_bank *bank; | ||
1276 | unsigned long flags; | ||
1277 | |||
1278 | bank = container_of(chip, struct gpio_bank, chip); | ||
1279 | spin_lock_irqsave(&bank->lock, flags); | ||
1280 | _set_gpio_dataout(bank, offset, value); | ||
1281 | spin_unlock_irqrestore(&bank->lock, flags); | ||
1282 | } | ||
1283 | |||
1284 | /*---------------------------------------------------------------------*/ | ||
1285 | |||
1269 | static int initialized; | 1286 | static int initialized; |
1270 | #if !defined(CONFIG_ARCH_OMAP3) | 1287 | #if !defined(CONFIG_ARCH_OMAP3) |
1271 | static struct clk * gpio_ick; | 1288 | static struct clk * gpio_ick; |
@@ -1293,6 +1310,7 @@ static struct lock_class_key gpio_lock_class; | |||
1293 | static int __init _omap_gpio_init(void) | 1310 | static int __init _omap_gpio_init(void) |
1294 | { | 1311 | { |
1295 | int i; | 1312 | int i; |
1313 | int gpio = 0; | ||
1296 | struct gpio_bank *bank; | 1314 | struct gpio_bank *bank; |
1297 | #if defined(CONFIG_ARCH_OMAP3) | 1315 | #if defined(CONFIG_ARCH_OMAP3) |
1298 | char clk_name[11]; | 1316 | char clk_name[11]; |
@@ -1423,7 +1441,6 @@ static int __init _omap_gpio_init(void) | |||
1423 | int j, gpio_count = 16; | 1441 | int j, gpio_count = 16; |
1424 | 1442 | ||
1425 | bank = &gpio_bank[i]; | 1443 | bank = &gpio_bank[i]; |
1426 | bank->reserved_map = 0; | ||
1427 | bank->base = IO_ADDRESS(bank->base); | 1444 | bank->base = IO_ADDRESS(bank->base); |
1428 | spin_lock_init(&bank->lock); | 1445 | spin_lock_init(&bank->lock); |
1429 | if (bank_is_mpuio(bank)) | 1446 | if (bank_is_mpuio(bank)) |
@@ -1461,6 +1478,26 @@ static int __init _omap_gpio_init(void) | |||
1461 | gpio_count = 32; | 1478 | gpio_count = 32; |
1462 | } | 1479 | } |
1463 | #endif | 1480 | #endif |
1481 | |||
1482 | /* REVISIT eventually switch from OMAP-specific gpio structs | ||
1483 | * over to the generic ones | ||
1484 | */ | ||
1485 | bank->chip.direction_input = gpio_input; | ||
1486 | bank->chip.get = gpio_get; | ||
1487 | bank->chip.direction_output = gpio_output; | ||
1488 | bank->chip.set = gpio_set; | ||
1489 | if (bank_is_mpuio(bank)) { | ||
1490 | bank->chip.label = "mpuio"; | ||
1491 | bank->chip.base = OMAP_MPUIO(0); | ||
1492 | } else { | ||
1493 | bank->chip.label = "gpio"; | ||
1494 | bank->chip.base = gpio; | ||
1495 | gpio += gpio_count; | ||
1496 | } | ||
1497 | bank->chip.ngpio = gpio_count; | ||
1498 | |||
1499 | gpiochip_add(&bank->chip); | ||
1500 | |||
1464 | for (j = bank->virtual_irq_start; | 1501 | for (j = bank->virtual_irq_start; |
1465 | j < bank->virtual_irq_start + gpio_count; j++) { | 1502 | j < bank->virtual_irq_start + gpio_count; j++) { |
1466 | lockdep_set_class(&irq_desc[j].lock, &gpio_lock_class); | 1503 | lockdep_set_class(&irq_desc[j].lock, &gpio_lock_class); |
@@ -1757,8 +1794,10 @@ static int dbg_gpio_show(struct seq_file *s, void *unused) | |||
1757 | 1794 | ||
1758 | for (j = 0; j < bankwidth; j++, gpio++, mask <<= 1) { | 1795 | for (j = 0; j < bankwidth; j++, gpio++, mask <<= 1) { |
1759 | unsigned irq, value, is_in, irqstat; | 1796 | unsigned irq, value, is_in, irqstat; |
1797 | const char *label; | ||
1760 | 1798 | ||
1761 | if (!(bank->reserved_map & mask)) | 1799 | label = gpiochip_is_requested(&bank->chip, j); |
1800 | if (!label) | ||
1762 | continue; | 1801 | continue; |
1763 | 1802 | ||
1764 | irq = bank->virtual_irq_start + j; | 1803 | irq = bank->virtual_irq_start + j; |
@@ -1766,13 +1805,16 @@ static int dbg_gpio_show(struct seq_file *s, void *unused) | |||
1766 | is_in = gpio_is_input(bank, mask); | 1805 | is_in = gpio_is_input(bank, mask); |
1767 | 1806 | ||
1768 | if (bank_is_mpuio(bank)) | 1807 | if (bank_is_mpuio(bank)) |
1769 | seq_printf(s, "MPUIO %2d: ", j); | 1808 | seq_printf(s, "MPUIO %2d ", j); |
1770 | else | 1809 | else |
1771 | seq_printf(s, "GPIO %3d: ", gpio); | 1810 | seq_printf(s, "GPIO %3d ", gpio); |
1772 | seq_printf(s, "%s %s", | 1811 | seq_printf(s, "(%10s): %s %s", |
1812 | label, | ||
1773 | is_in ? "in " : "out", | 1813 | is_in ? "in " : "out", |
1774 | value ? "hi" : "lo"); | 1814 | value ? "hi" : "lo"); |
1775 | 1815 | ||
1816 | /* FIXME for at least omap2, show pullup/pulldown state */ | ||
1817 | |||
1776 | irqstat = irq_desc[irq].status; | 1818 | irqstat = irq_desc[irq].status; |
1777 | if (is_in && ((bank->suspend_wakeup & mask) | 1819 | if (is_in && ((bank->suspend_wakeup & mask) |
1778 | || irqstat & IRQ_TYPE_SENSE_MASK)) { | 1820 | || irqstat & IRQ_TYPE_SENSE_MASK)) { |
@@ -1795,10 +1837,10 @@ static int dbg_gpio_show(struct seq_file *s, void *unused) | |||
1795 | trigger = "high"; | 1837 | trigger = "high"; |
1796 | break; | 1838 | break; |
1797 | case IRQ_TYPE_NONE: | 1839 | case IRQ_TYPE_NONE: |
1798 | trigger = "(unspecified)"; | 1840 | trigger = "(?)"; |
1799 | break; | 1841 | break; |
1800 | } | 1842 | } |
1801 | seq_printf(s, ", irq-%d %s%s", | 1843 | seq_printf(s, ", irq-%d %-8s%s", |
1802 | irq, trigger, | 1844 | irq, trigger, |
1803 | (bank->suspend_wakeup & mask) | 1845 | (bank->suspend_wakeup & mask) |
1804 | ? " wakeup" : ""); | 1846 | ? " wakeup" : ""); |
diff --git a/arch/arm/plat-omap/mux.c b/arch/arm/plat-omap/mux.c index 75211f20ccb3..6f3f459731c8 100644 --- a/arch/arm/plat-omap/mux.c +++ b/arch/arm/plat-omap/mux.c | |||
@@ -3,9 +3,9 @@ | |||
3 | * | 3 | * |
4 | * Utility to set the Omap MUX and PULL_DWN registers from a table in mux.h | 4 | * Utility to set the Omap MUX and PULL_DWN registers from a table in mux.h |
5 | * | 5 | * |
6 | * Copyright (C) 2003 - 2005 Nokia Corporation | 6 | * Copyright (C) 2003 - 2008 Nokia Corporation |
7 | * | 7 | * |
8 | * Written by Tony Lindgren <tony.lindgren@nokia.com> | 8 | * Written by Tony Lindgren |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
@@ -32,21 +32,17 @@ | |||
32 | 32 | ||
33 | #ifdef CONFIG_OMAP_MUX | 33 | #ifdef CONFIG_OMAP_MUX |
34 | 34 | ||
35 | #define OMAP24XX_L4_BASE 0x48000000 | 35 | static struct omap_mux_cfg *mux_cfg; |
36 | #define OMAP24XX_PULL_ENA (1 << 3) | ||
37 | #define OMAP24XX_PULL_UP (1 << 4) | ||
38 | 36 | ||
39 | static struct pin_config * pin_table; | 37 | int __init omap_mux_register(struct omap_mux_cfg *arch_mux_cfg) |
40 | static unsigned long pin_table_sz; | ||
41 | |||
42 | extern struct pin_config * omap730_pins; | ||
43 | extern struct pin_config * omap1xxx_pins; | ||
44 | extern struct pin_config * omap24xx_pins; | ||
45 | |||
46 | int __init omap_mux_register(struct pin_config * pins, unsigned long size) | ||
47 | { | 38 | { |
48 | pin_table = pins; | 39 | if (!arch_mux_cfg || !arch_mux_cfg->pins || arch_mux_cfg->size == 0 |
49 | pin_table_sz = size; | 40 | || !arch_mux_cfg->cfg_reg) { |
41 | printk(KERN_ERR "Invalid pin table\n"); | ||
42 | return -EINVAL; | ||
43 | } | ||
44 | |||
45 | mux_cfg = arch_mux_cfg; | ||
50 | 46 | ||
51 | return 0; | 47 | return 0; |
52 | } | 48 | } |
@@ -56,152 +52,26 @@ int __init omap_mux_register(struct pin_config * pins, unsigned long size) | |||
56 | */ | 52 | */ |
57 | int __init_or_module omap_cfg_reg(const unsigned long index) | 53 | int __init_or_module omap_cfg_reg(const unsigned long index) |
58 | { | 54 | { |
59 | static DEFINE_SPINLOCK(mux_spin_lock); | 55 | struct pin_config *reg; |
60 | |||
61 | unsigned long flags; | ||
62 | struct pin_config *cfg; | ||
63 | unsigned int reg_orig = 0, reg = 0, pu_pd_orig = 0, pu_pd = 0, | ||
64 | pull_orig = 0, pull = 0; | ||
65 | unsigned int mask, warn = 0; | ||
66 | 56 | ||
67 | if (!pin_table) | 57 | if (mux_cfg == NULL) { |
68 | BUG(); | 58 | printk(KERN_ERR "Pin mux table not initialized\n"); |
59 | return -ENODEV; | ||
60 | } | ||
69 | 61 | ||
70 | if (index >= pin_table_sz) { | 62 | if (index >= mux_cfg->size) { |
71 | printk(KERN_ERR "Invalid pin mux index: %lu (%lu)\n", | 63 | printk(KERN_ERR "Invalid pin mux index: %lu (%lu)\n", |
72 | index, pin_table_sz); | 64 | index, mux_cfg->size); |
73 | dump_stack(); | 65 | dump_stack(); |
74 | return -ENODEV; | 66 | return -ENODEV; |
75 | } | 67 | } |
76 | 68 | ||
77 | cfg = (struct pin_config *)&pin_table[index]; | 69 | reg = (struct pin_config *)&mux_cfg->pins[index]; |
78 | if (cpu_is_omap24xx()) { | ||
79 | u8 reg = 0; | ||
80 | |||
81 | reg |= cfg->mask & 0x7; | ||
82 | if (cfg->pull_val) | ||
83 | reg |= OMAP24XX_PULL_ENA; | ||
84 | if(cfg->pu_pd_val) | ||
85 | reg |= OMAP24XX_PULL_UP; | ||
86 | #if defined(CONFIG_OMAP_MUX_DEBUG) || defined(CONFIG_OMAP_MUX_WARNINGS) | ||
87 | { | ||
88 | u8 orig = omap_readb(OMAP24XX_L4_BASE + cfg->mux_reg); | ||
89 | u8 debug = 0; | ||
90 | |||
91 | #ifdef CONFIG_OMAP_MUX_DEBUG | ||
92 | debug = cfg->debug; | ||
93 | #endif | ||
94 | warn = (orig != reg); | ||
95 | if (debug || warn) | ||
96 | printk("MUX: setup %s (0x%08x): 0x%02x -> 0x%02x\n", | ||
97 | cfg->name, | ||
98 | OMAP24XX_L4_BASE + cfg->mux_reg, | ||
99 | orig, reg); | ||
100 | } | ||
101 | #endif | ||
102 | omap_writeb(reg, OMAP24XX_L4_BASE + cfg->mux_reg); | ||
103 | 70 | ||
104 | return 0; | 71 | if (!mux_cfg->cfg_reg) |
105 | } | 72 | return -ENODEV; |
106 | |||
107 | /* Check the mux register in question */ | ||
108 | if (cfg->mux_reg) { | ||
109 | unsigned tmp1, tmp2; | ||
110 | |||
111 | spin_lock_irqsave(&mux_spin_lock, flags); | ||
112 | reg_orig = omap_readl(cfg->mux_reg); | ||
113 | |||
114 | /* The mux registers always seem to be 3 bits long */ | ||
115 | mask = (0x7 << cfg->mask_offset); | ||
116 | tmp1 = reg_orig & mask; | ||
117 | reg = reg_orig & ~mask; | ||
118 | |||
119 | tmp2 = (cfg->mask << cfg->mask_offset); | ||
120 | reg |= tmp2; | ||
121 | |||
122 | if (tmp1 != tmp2) | ||
123 | warn = 1; | ||
124 | |||
125 | omap_writel(reg, cfg->mux_reg); | ||
126 | spin_unlock_irqrestore(&mux_spin_lock, flags); | ||
127 | } | ||
128 | |||
129 | /* Check for pull up or pull down selection on 1610 */ | ||
130 | if (!cpu_is_omap15xx()) { | ||
131 | if (cfg->pu_pd_reg && cfg->pull_val) { | ||
132 | spin_lock_irqsave(&mux_spin_lock, flags); | ||
133 | pu_pd_orig = omap_readl(cfg->pu_pd_reg); | ||
134 | mask = 1 << cfg->pull_bit; | ||
135 | |||
136 | if (cfg->pu_pd_val) { | ||
137 | if (!(pu_pd_orig & mask)) | ||
138 | warn = 1; | ||
139 | /* Use pull up */ | ||
140 | pu_pd = pu_pd_orig | mask; | ||
141 | } else { | ||
142 | if (pu_pd_orig & mask) | ||
143 | warn = 1; | ||
144 | /* Use pull down */ | ||
145 | pu_pd = pu_pd_orig & ~mask; | ||
146 | } | ||
147 | omap_writel(pu_pd, cfg->pu_pd_reg); | ||
148 | spin_unlock_irqrestore(&mux_spin_lock, flags); | ||
149 | } | ||
150 | } | ||
151 | |||
152 | /* Check for an associated pull down register */ | ||
153 | if (cfg->pull_reg) { | ||
154 | spin_lock_irqsave(&mux_spin_lock, flags); | ||
155 | pull_orig = omap_readl(cfg->pull_reg); | ||
156 | mask = 1 << cfg->pull_bit; | ||
157 | |||
158 | if (cfg->pull_val) { | ||
159 | if (pull_orig & mask) | ||
160 | warn = 1; | ||
161 | /* Low bit = pull enabled */ | ||
162 | pull = pull_orig & ~mask; | ||
163 | } else { | ||
164 | if (!(pull_orig & mask)) | ||
165 | warn = 1; | ||
166 | /* High bit = pull disabled */ | ||
167 | pull = pull_orig | mask; | ||
168 | } | ||
169 | |||
170 | omap_writel(pull, cfg->pull_reg); | ||
171 | spin_unlock_irqrestore(&mux_spin_lock, flags); | ||
172 | } | ||
173 | |||
174 | if (warn) { | ||
175 | #ifdef CONFIG_OMAP_MUX_WARNINGS | ||
176 | printk(KERN_WARNING "MUX: initialized %s\n", cfg->name); | ||
177 | #endif | ||
178 | } | ||
179 | |||
180 | #ifdef CONFIG_OMAP_MUX_DEBUG | ||
181 | if (cfg->debug || warn) { | ||
182 | printk("MUX: Setting register %s\n", cfg->name); | ||
183 | printk(" %s (0x%08x) = 0x%08x -> 0x%08x\n", | ||
184 | cfg->mux_reg_name, cfg->mux_reg, reg_orig, reg); | ||
185 | |||
186 | if (!cpu_is_omap15xx()) { | ||
187 | if (cfg->pu_pd_reg && cfg->pull_val) { | ||
188 | printk(" %s (0x%08x) = 0x%08x -> 0x%08x\n", | ||
189 | cfg->pu_pd_name, cfg->pu_pd_reg, | ||
190 | pu_pd_orig, pu_pd); | ||
191 | } | ||
192 | } | ||
193 | |||
194 | if (cfg->pull_reg) | ||
195 | printk(" %s (0x%08x) = 0x%08x -> 0x%08x\n", | ||
196 | cfg->pull_name, cfg->pull_reg, pull_orig, pull); | ||
197 | } | ||
198 | #endif | ||
199 | 73 | ||
200 | #ifdef CONFIG_OMAP_MUX_ERRORS | 74 | return mux_cfg->cfg_reg(reg); |
201 | return warn ? -ETXTBSY : 0; | ||
202 | #else | ||
203 | return 0; | ||
204 | #endif | ||
205 | } | 75 | } |
206 | EXPORT_SYMBOL(omap_cfg_reg); | 76 | EXPORT_SYMBOL(omap_cfg_reg); |
207 | #else | 77 | #else |
diff --git a/arch/arm/plat-omap/timer32k.c b/arch/arm/plat-omap/timer32k.c deleted file mode 100644 index ea76f1979a3d..000000000000 --- a/arch/arm/plat-omap/timer32k.c +++ /dev/null | |||
@@ -1,269 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/plat-omap/timer32k.c | ||
3 | * | ||
4 | * OMAP 32K Timer | ||
5 | * | ||
6 | * Copyright (C) 2004 - 2005 Nokia Corporation | ||
7 | * Partial timer rewrite and additional dynamic tick timer support by | ||
8 | * Tony Lindgen <tony@atomide.com> and | ||
9 | * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> | ||
10 | * OMAP Dual-mode timer framework support by Timo Teras | ||
11 | * | ||
12 | * MPU timer code based on the older MPU timer code for OMAP | ||
13 | * Copyright (C) 2000 RidgeRun, Inc. | ||
14 | * Author: Greg Lonnon <glonnon@ridgerun.com> | ||
15 | * | ||
16 | * This program is free software; you can redistribute it and/or modify it | ||
17 | * under the terms of the GNU General Public License as published by the | ||
18 | * Free Software Foundation; either version 2 of the License, or (at your | ||
19 | * option) any later version. | ||
20 | * | ||
21 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
22 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
23 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
24 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
25 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
26 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
27 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
28 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
30 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
31 | * | ||
32 | * You should have received a copy of the GNU General Public License along | ||
33 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
34 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
35 | */ | ||
36 | |||
37 | #include <linux/kernel.h> | ||
38 | #include <linux/init.h> | ||
39 | #include <linux/delay.h> | ||
40 | #include <linux/interrupt.h> | ||
41 | #include <linux/sched.h> | ||
42 | #include <linux/spinlock.h> | ||
43 | #include <linux/err.h> | ||
44 | #include <linux/clk.h> | ||
45 | #include <linux/clocksource.h> | ||
46 | #include <linux/clockchips.h> | ||
47 | |||
48 | #include <asm/system.h> | ||
49 | #include <asm/hardware.h> | ||
50 | #include <asm/io.h> | ||
51 | #include <asm/leds.h> | ||
52 | #include <asm/irq.h> | ||
53 | #include <asm/mach/irq.h> | ||
54 | #include <asm/mach/time.h> | ||
55 | #include <asm/arch/dmtimer.h> | ||
56 | |||
57 | struct sys_timer omap_timer; | ||
58 | |||
59 | /* | ||
60 | * --------------------------------------------------------------------------- | ||
61 | * 32KHz OS timer | ||
62 | * | ||
63 | * This currently works only on 16xx, as 1510 does not have the continuous | ||
64 | * 32KHz synchronous timer. The 32KHz synchronous timer is used to keep track | ||
65 | * of time in addition to the 32KHz OS timer. Using only the 32KHz OS timer | ||
66 | * on 1510 would be possible, but the timer would not be as accurate as | ||
67 | * with the 32KHz synchronized timer. | ||
68 | * --------------------------------------------------------------------------- | ||
69 | */ | ||
70 | |||
71 | #if defined(CONFIG_ARCH_OMAP16XX) | ||
72 | #define TIMER_32K_SYNCHRONIZED 0xfffbc410 | ||
73 | #elif defined(CONFIG_ARCH_OMAP24XX) | ||
74 | #define TIMER_32K_SYNCHRONIZED (OMAP24XX_32KSYNCT_BASE + 0x10) | ||
75 | #else | ||
76 | #error OMAP 32KHz timer does not currently work on 15XX! | ||
77 | #endif | ||
78 | |||
79 | /* 16xx specific defines */ | ||
80 | #define OMAP1_32K_TIMER_BASE 0xfffb9000 | ||
81 | #define OMAP1_32K_TIMER_CR 0x08 | ||
82 | #define OMAP1_32K_TIMER_TVR 0x00 | ||
83 | #define OMAP1_32K_TIMER_TCR 0x04 | ||
84 | |||
85 | #define OMAP_32K_TICKS_PER_SEC (32768) | ||
86 | |||
87 | /* | ||
88 | * TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1 | ||
89 | * so with HZ = 128, TVR = 255. | ||
90 | */ | ||
91 | #define OMAP_32K_TIMER_TICK_PERIOD ((OMAP_32K_TICKS_PER_SEC / HZ) - 1) | ||
92 | |||
93 | #define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate) \ | ||
94 | (((nr_jiffies) * (clock_rate)) / HZ) | ||
95 | |||
96 | #if defined(CONFIG_ARCH_OMAP1) | ||
97 | |||
98 | static inline void omap_32k_timer_write(int val, int reg) | ||
99 | { | ||
100 | omap_writew(val, OMAP1_32K_TIMER_BASE + reg); | ||
101 | } | ||
102 | |||
103 | static inline unsigned long omap_32k_timer_read(int reg) | ||
104 | { | ||
105 | return omap_readl(OMAP1_32K_TIMER_BASE + reg) & 0xffffff; | ||
106 | } | ||
107 | |||
108 | static inline void omap_32k_timer_start(unsigned long load_val) | ||
109 | { | ||
110 | if (!load_val) | ||
111 | load_val = 1; | ||
112 | omap_32k_timer_write(load_val, OMAP1_32K_TIMER_TVR); | ||
113 | omap_32k_timer_write(0x0f, OMAP1_32K_TIMER_CR); | ||
114 | } | ||
115 | |||
116 | static inline void omap_32k_timer_stop(void) | ||
117 | { | ||
118 | omap_32k_timer_write(0x0, OMAP1_32K_TIMER_CR); | ||
119 | } | ||
120 | |||
121 | #define omap_32k_timer_ack_irq() | ||
122 | |||
123 | #elif defined(CONFIG_ARCH_OMAP2) | ||
124 | |||
125 | static struct omap_dm_timer *gptimer; | ||
126 | |||
127 | static inline void omap_32k_timer_start(unsigned long load_val) | ||
128 | { | ||
129 | omap_dm_timer_set_load(gptimer, 1, 0xffffffff - load_val); | ||
130 | omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW); | ||
131 | omap_dm_timer_start(gptimer); | ||
132 | } | ||
133 | |||
134 | static inline void omap_32k_timer_stop(void) | ||
135 | { | ||
136 | omap_dm_timer_stop(gptimer); | ||
137 | } | ||
138 | |||
139 | static inline void omap_32k_timer_ack_irq(void) | ||
140 | { | ||
141 | u32 status = omap_dm_timer_read_status(gptimer); | ||
142 | omap_dm_timer_write_status(gptimer, status); | ||
143 | } | ||
144 | |||
145 | #endif | ||
146 | |||
147 | static void omap_32k_timer_set_mode(enum clock_event_mode mode, | ||
148 | struct clock_event_device *evt) | ||
149 | { | ||
150 | omap_32k_timer_stop(); | ||
151 | |||
152 | switch (mode) { | ||
153 | case CLOCK_EVT_MODE_PERIODIC: | ||
154 | omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD); | ||
155 | break; | ||
156 | case CLOCK_EVT_MODE_ONESHOT: | ||
157 | case CLOCK_EVT_MODE_UNUSED: | ||
158 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
159 | break; | ||
160 | case CLOCK_EVT_MODE_RESUME: | ||
161 | break; | ||
162 | } | ||
163 | } | ||
164 | |||
165 | static struct clock_event_device clockevent_32k_timer = { | ||
166 | .name = "32k-timer", | ||
167 | .features = CLOCK_EVT_FEAT_PERIODIC, | ||
168 | .shift = 32, | ||
169 | .set_mode = omap_32k_timer_set_mode, | ||
170 | }; | ||
171 | |||
172 | /* | ||
173 | * The 32KHz synchronized timer is an additional timer on 16xx. | ||
174 | * It is always running. | ||
175 | */ | ||
176 | static inline unsigned long omap_32k_sync_timer_read(void) | ||
177 | { | ||
178 | return omap_readl(TIMER_32K_SYNCHRONIZED); | ||
179 | } | ||
180 | |||
181 | /* | ||
182 | * Rounds down to nearest usec. Note that this will overflow for larger values. | ||
183 | */ | ||
184 | static inline unsigned long omap_32k_ticks_to_usecs(unsigned long ticks_32k) | ||
185 | { | ||
186 | return (ticks_32k * 5*5*5*5*5*5) >> 9; | ||
187 | } | ||
188 | |||
189 | /* | ||
190 | * Rounds down to nearest nsec. | ||
191 | */ | ||
192 | static inline unsigned long long | ||
193 | omap_32k_ticks_to_nsecs(unsigned long ticks_32k) | ||
194 | { | ||
195 | return (unsigned long long) ticks_32k * 1000 * 5*5*5*5*5*5 >> 9; | ||
196 | } | ||
197 | |||
198 | /* | ||
199 | * Returns current time from boot in nsecs. It's OK for this to wrap | ||
200 | * around for now, as it's just a relative time stamp. | ||
201 | */ | ||
202 | unsigned long long sched_clock(void) | ||
203 | { | ||
204 | return omap_32k_ticks_to_nsecs(omap_32k_sync_timer_read()); | ||
205 | } | ||
206 | |||
207 | static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id) | ||
208 | { | ||
209 | struct clock_event_device *evt = &clockevent_32k_timer; | ||
210 | omap_32k_timer_ack_irq(); | ||
211 | |||
212 | evt->event_handler(evt); | ||
213 | |||
214 | return IRQ_HANDLED; | ||
215 | } | ||
216 | |||
217 | static struct irqaction omap_32k_timer_irq = { | ||
218 | .name = "32KHz timer", | ||
219 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, | ||
220 | .handler = omap_32k_timer_interrupt, | ||
221 | }; | ||
222 | |||
223 | static __init void omap_init_32k_timer(void) | ||
224 | { | ||
225 | if (cpu_class_is_omap1()) | ||
226 | setup_irq(INT_OS_TIMER, &omap_32k_timer_irq); | ||
227 | |||
228 | #ifdef CONFIG_ARCH_OMAP2 | ||
229 | /* REVISIT: Check 24xx TIOCP_CFG settings after idle works */ | ||
230 | if (cpu_is_omap24xx()) { | ||
231 | gptimer = omap_dm_timer_request_specific(1); | ||
232 | BUG_ON(gptimer == NULL); | ||
233 | |||
234 | omap_dm_timer_set_source(gptimer, OMAP_TIMER_SRC_32_KHZ); | ||
235 | setup_irq(omap_dm_timer_get_irq(gptimer), &omap_32k_timer_irq); | ||
236 | omap_dm_timer_set_int_enable(gptimer, | ||
237 | OMAP_TIMER_INT_CAPTURE | OMAP_TIMER_INT_OVERFLOW | | ||
238 | OMAP_TIMER_INT_MATCH); | ||
239 | } | ||
240 | #endif | ||
241 | |||
242 | clockevent_32k_timer.mult = div_sc(OMAP_32K_TICKS_PER_SEC, | ||
243 | NSEC_PER_SEC, | ||
244 | clockevent_32k_timer.shift); | ||
245 | clockevent_32k_timer.max_delta_ns = | ||
246 | clockevent_delta2ns(0xfffffffe, &clockevent_32k_timer); | ||
247 | clockevent_32k_timer.min_delta_ns = | ||
248 | clockevent_delta2ns(1, &clockevent_32k_timer); | ||
249 | |||
250 | clockevent_32k_timer.cpumask = cpumask_of_cpu(0); | ||
251 | clockevents_register_device(&clockevent_32k_timer); | ||
252 | } | ||
253 | |||
254 | /* | ||
255 | * --------------------------------------------------------------------------- | ||
256 | * Timer initialization | ||
257 | * --------------------------------------------------------------------------- | ||
258 | */ | ||
259 | static void __init omap_timer_init(void) | ||
260 | { | ||
261 | #ifdef CONFIG_OMAP_DM_TIMER | ||
262 | omap_dm_timer_init(); | ||
263 | #endif | ||
264 | omap_init_32k_timer(); | ||
265 | } | ||
266 | |||
267 | struct sys_timer omap_timer = { | ||
268 | .init = omap_timer_init, | ||
269 | }; | ||
diff --git a/arch/arm/plat-omap/usb.c b/arch/arm/plat-omap/usb.c index a5aedf964b88..a619475c4b76 100644 --- a/arch/arm/plat-omap/usb.c +++ b/arch/arm/plat-omap/usb.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <asm/system.h> | 33 | #include <asm/system.h> |
34 | #include <asm/hardware.h> | 34 | #include <asm/hardware.h> |
35 | 35 | ||
36 | #include <asm/arch/control.h> | ||
36 | #include <asm/arch/mux.h> | 37 | #include <asm/arch/mux.h> |
37 | #include <asm/arch/usb.h> | 38 | #include <asm/arch/usb.h> |
38 | #include <asm/arch/board.h> | 39 | #include <asm/arch/board.h> |
@@ -76,7 +77,7 @@ | |||
76 | 77 | ||
77 | /*-------------------------------------------------------------------------*/ | 78 | /*-------------------------------------------------------------------------*/ |
78 | 79 | ||
79 | #ifdef CONFIG_ARCH_OMAP_OTG | 80 | #if defined(CONFIG_ARCH_OMAP_OTG) || defined(CONFIG_USB_MUSB_OTG) |
80 | 81 | ||
81 | static struct otg_transceiver *xceiv; | 82 | static struct otg_transceiver *xceiv; |
82 | 83 | ||
@@ -110,12 +111,48 @@ EXPORT_SYMBOL(otg_set_transceiver); | |||
110 | 111 | ||
111 | #if defined(CONFIG_ARCH_OMAP_OTG) || defined(CONFIG_ARCH_OMAP15XX) | 112 | #if defined(CONFIG_ARCH_OMAP_OTG) || defined(CONFIG_ARCH_OMAP15XX) |
112 | 113 | ||
114 | static void omap2_usb_devconf_clear(u8 port, u32 mask) | ||
115 | { | ||
116 | u32 r; | ||
117 | |||
118 | r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); | ||
119 | r &= ~USBTXWRMODEI(port, mask); | ||
120 | omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0); | ||
121 | } | ||
122 | |||
123 | static void omap2_usb_devconf_set(u8 port, u32 mask) | ||
124 | { | ||
125 | u32 r; | ||
126 | |||
127 | r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); | ||
128 | r |= USBTXWRMODEI(port, mask); | ||
129 | omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0); | ||
130 | } | ||
131 | |||
132 | static void omap2_usb2_disable_5pinbitll(void) | ||
133 | { | ||
134 | u32 r; | ||
135 | |||
136 | r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); | ||
137 | r &= ~(USBTXWRMODEI(2, USB_BIDIR_TLL) | USBT2TLL5PI); | ||
138 | omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0); | ||
139 | } | ||
140 | |||
141 | static void omap2_usb2_enable_5pinunitll(void) | ||
142 | { | ||
143 | u32 r; | ||
144 | |||
145 | r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); | ||
146 | r |= USBTXWRMODEI(2, USB_UNIDIR_TLL) | USBT2TLL5PI; | ||
147 | omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0); | ||
148 | } | ||
149 | |||
113 | static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device) | 150 | static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device) |
114 | { | 151 | { |
115 | u32 syscon1 = 0; | 152 | u32 syscon1 = 0; |
116 | 153 | ||
117 | if (cpu_is_omap24xx()) | 154 | if (cpu_is_omap24xx()) |
118 | CONTROL_DEVCONF_REG &= ~USBT0WRMODEI(USB_BIDIR_TLL); | 155 | omap2_usb_devconf_clear(0, USB_BIDIR_TLL); |
119 | 156 | ||
120 | if (nwires == 0) { | 157 | if (nwires == 0) { |
121 | if (cpu_class_is_omap1() && !cpu_is_omap15xx()) { | 158 | if (cpu_class_is_omap1() && !cpu_is_omap15xx()) { |
@@ -187,19 +224,19 @@ static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device) | |||
187 | case 3: | 224 | case 3: |
188 | syscon1 = 2; | 225 | syscon1 = 2; |
189 | if (cpu_is_omap24xx()) | 226 | if (cpu_is_omap24xx()) |
190 | CONTROL_DEVCONF_REG |= USBT0WRMODEI(USB_BIDIR); | 227 | omap2_usb_devconf_set(0, USB_BIDIR); |
191 | break; | 228 | break; |
192 | case 4: | 229 | case 4: |
193 | syscon1 = 1; | 230 | syscon1 = 1; |
194 | if (cpu_is_omap24xx()) | 231 | if (cpu_is_omap24xx()) |
195 | CONTROL_DEVCONF_REG |= USBT0WRMODEI(USB_BIDIR); | 232 | omap2_usb_devconf_set(0, USB_BIDIR); |
196 | break; | 233 | break; |
197 | case 6: | 234 | case 6: |
198 | syscon1 = 3; | 235 | syscon1 = 3; |
199 | if (cpu_is_omap24xx()) { | 236 | if (cpu_is_omap24xx()) { |
200 | omap_cfg_reg(J19_24XX_USB0_VP); | 237 | omap_cfg_reg(J19_24XX_USB0_VP); |
201 | omap_cfg_reg(K20_24XX_USB0_VM); | 238 | omap_cfg_reg(K20_24XX_USB0_VM); |
202 | CONTROL_DEVCONF_REG |= USBT0WRMODEI(USB_UNIDIR); | 239 | omap2_usb_devconf_set(0, USB_UNIDIR); |
203 | } else { | 240 | } else { |
204 | omap_cfg_reg(AA9_USB0_VP); | 241 | omap_cfg_reg(AA9_USB0_VP); |
205 | omap_cfg_reg(R9_USB0_VM); | 242 | omap_cfg_reg(R9_USB0_VM); |
@@ -220,7 +257,7 @@ static u32 __init omap_usb1_init(unsigned nwires) | |||
220 | if (cpu_class_is_omap1() && !cpu_is_omap15xx() && nwires != 6) | 257 | if (cpu_class_is_omap1() && !cpu_is_omap15xx() && nwires != 6) |
221 | USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB1_UNI_R; | 258 | USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB1_UNI_R; |
222 | if (cpu_is_omap24xx()) | 259 | if (cpu_is_omap24xx()) |
223 | CONTROL_DEVCONF_REG &= ~USBT1WRMODEI(USB_BIDIR_TLL); | 260 | omap2_usb_devconf_clear(1, USB_BIDIR_TLL); |
224 | 261 | ||
225 | if (nwires == 0) | 262 | if (nwires == 0) |
226 | return 0; | 263 | return 0; |
@@ -261,17 +298,17 @@ static u32 __init omap_usb1_init(unsigned nwires) | |||
261 | * this TLL link is not using DP/DM | 298 | * this TLL link is not using DP/DM |
262 | */ | 299 | */ |
263 | syscon1 = 1; | 300 | syscon1 = 1; |
264 | CONTROL_DEVCONF_REG |= USBT1WRMODEI(USB_BIDIR_TLL); | 301 | omap2_usb_devconf_set(1, USB_BIDIR_TLL); |
265 | break; | 302 | break; |
266 | case 3: | 303 | case 3: |
267 | syscon1 = 2; | 304 | syscon1 = 2; |
268 | if (cpu_is_omap24xx()) | 305 | if (cpu_is_omap24xx()) |
269 | CONTROL_DEVCONF_REG |= USBT1WRMODEI(USB_BIDIR); | 306 | omap2_usb_devconf_set(1, USB_BIDIR); |
270 | break; | 307 | break; |
271 | case 4: | 308 | case 4: |
272 | syscon1 = 1; | 309 | syscon1 = 1; |
273 | if (cpu_is_omap24xx()) | 310 | if (cpu_is_omap24xx()) |
274 | CONTROL_DEVCONF_REG |= USBT1WRMODEI(USB_BIDIR); | 311 | omap2_usb_devconf_set(1, USB_BIDIR); |
275 | break; | 312 | break; |
276 | case 6: | 313 | case 6: |
277 | if (cpu_is_omap24xx()) | 314 | if (cpu_is_omap24xx()) |
@@ -295,8 +332,7 @@ static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup) | |||
295 | u32 syscon1 = 0; | 332 | u32 syscon1 = 0; |
296 | 333 | ||
297 | if (cpu_is_omap24xx()) { | 334 | if (cpu_is_omap24xx()) { |
298 | CONTROL_DEVCONF_REG &= ~(USBT2WRMODEI(USB_BIDIR_TLL) | 335 | omap2_usb2_disable_5pinbitll(); |
299 | | USBT2TLL5PI); | ||
300 | alt_pingroup = 0; | 336 | alt_pingroup = 0; |
301 | } | 337 | } |
302 | 338 | ||
@@ -343,17 +379,17 @@ static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup) | |||
343 | * this TLL link is not using DP/DM | 379 | * this TLL link is not using DP/DM |
344 | */ | 380 | */ |
345 | syscon1 = 1; | 381 | syscon1 = 1; |
346 | CONTROL_DEVCONF_REG |= USBT2WRMODEI(USB_BIDIR_TLL); | 382 | omap2_usb_devconf_set(2, USB_BIDIR_TLL); |
347 | break; | 383 | break; |
348 | case 3: | 384 | case 3: |
349 | syscon1 = 2; | 385 | syscon1 = 2; |
350 | if (cpu_is_omap24xx()) | 386 | if (cpu_is_omap24xx()) |
351 | CONTROL_DEVCONF_REG |= USBT2WRMODEI(USB_BIDIR); | 387 | omap2_usb_devconf_set(2, USB_BIDIR); |
352 | break; | 388 | break; |
353 | case 4: | 389 | case 4: |
354 | syscon1 = 1; | 390 | syscon1 = 1; |
355 | if (cpu_is_omap24xx()) | 391 | if (cpu_is_omap24xx()) |
356 | CONTROL_DEVCONF_REG |= USBT2WRMODEI(USB_BIDIR); | 392 | omap2_usb_devconf_set(2, USB_BIDIR); |
357 | break; | 393 | break; |
358 | case 5: | 394 | case 5: |
359 | if (!cpu_is_omap24xx()) | 395 | if (!cpu_is_omap24xx()) |
@@ -364,8 +400,7 @@ static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup) | |||
364 | * set up OTG_SYSCON2.HMC_TLL{ATTACH,SPEED} | 400 | * set up OTG_SYSCON2.HMC_TLL{ATTACH,SPEED} |
365 | */ | 401 | */ |
366 | syscon1 = 3; | 402 | syscon1 = 3; |
367 | CONTROL_DEVCONF_REG |= USBT2WRMODEI(USB_UNIDIR_TLL) | 403 | omap2_usb2_enable_5pinunitll(); |
368 | | USBT2TLL5PI; | ||
369 | break; | 404 | break; |
370 | case 6: | 405 | case 6: |
371 | if (cpu_is_omap24xx()) | 406 | if (cpu_is_omap24xx()) |