aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-04-21 18:40:55 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-21 18:40:55 -0400
commit85b375a613085b78531ec86369a51c2f3b922f95 (patch)
tree716437d598de92bbd7acaf24622e9a7d74fc209a /arch/arm/plat-omap
parentec965350bb98bd291eb34f6ecddfdcfc36da1e6e (diff)
parentcf816ecb533ab96b883dfdc0db174598b5b5c4d2 (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/Makefile2
-rw-r--r--arch/arm/plat-omap/clock.c42
-rw-r--r--arch/arm/plat-omap/common.c64
-rw-r--r--arch/arm/plat-omap/gpio.c176
-rw-r--r--arch/arm/plat-omap/mux.c174
-rw-r--r--arch/arm/plat-omap/timer32k.c269
-rw-r--r--arch/arm/plat-omap/usb.c67
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 :=
9obj-n := 9obj-n :=
10obj- := 10obj- :=
11 11
12obj-$(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
15obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o 13obj-$(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 */
314void 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
307int clk_register(struct clk *clk) 324int 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}
359EXPORT_SYMBOL(clk_allow_idle); 376EXPORT_SYMBOL(clk_allow_idle);
360 377
378void 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}
387EXPORT_SYMBOL(clk_enable_init_clocks);
388
389#ifdef CONFIG_CPU_FREQ
390void 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}
399EXPORT_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
37unsigned char omap_bootloader_tag[512]; 42unsigned 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 */
204unsigned 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 */
213unsigned long long sched_clock(void)
214{
215 return omap_32k_ticks_to_nsecs(omap_32k_read());
216}
217
196static int __init omap_init_clocksource_32k(void) 218static 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)
210arch_initcall(omap_init_clocksource_32k); 238arch_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)
245void __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)
254void __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)
263void __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
1243static 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
1255static int gpio_get(struct gpio_chip *chip, unsigned offset)
1256{
1257 return omap_get_gpio_datain(chip->base + offset);
1258}
1259
1260static 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
1273static 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
1269static int initialized; 1286static int initialized;
1270#if !defined(CONFIG_ARCH_OMAP3) 1287#if !defined(CONFIG_ARCH_OMAP3)
1271static struct clk * gpio_ick; 1288static struct clk * gpio_ick;
@@ -1293,6 +1310,7 @@ static struct lock_class_key gpio_lock_class;
1293static int __init _omap_gpio_init(void) 1310static 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 35static struct omap_mux_cfg *mux_cfg;
36#define OMAP24XX_PULL_ENA (1 << 3)
37#define OMAP24XX_PULL_UP (1 << 4)
38 36
39static struct pin_config * pin_table; 37int __init omap_mux_register(struct omap_mux_cfg *arch_mux_cfg)
40static unsigned long pin_table_sz;
41
42extern struct pin_config * omap730_pins;
43extern struct pin_config * omap1xxx_pins;
44extern struct pin_config * omap24xx_pins;
45
46int __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 */
57int __init_or_module omap_cfg_reg(const unsigned long index) 53int __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}
206EXPORT_SYMBOL(omap_cfg_reg); 76EXPORT_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
57struct 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
98static inline void omap_32k_timer_write(int val, int reg)
99{
100 omap_writew(val, OMAP1_32K_TIMER_BASE + reg);
101}
102
103static inline unsigned long omap_32k_timer_read(int reg)
104{
105 return omap_readl(OMAP1_32K_TIMER_BASE + reg) & 0xffffff;
106}
107
108static 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
116static 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
125static struct omap_dm_timer *gptimer;
126
127static 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
134static inline void omap_32k_timer_stop(void)
135{
136 omap_dm_timer_stop(gptimer);
137}
138
139static 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
147static 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
165static 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 */
176static 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 */
184static 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 */
192static inline unsigned long long
193omap_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 */
202unsigned long long sched_clock(void)
203{
204 return omap_32k_ticks_to_nsecs(omap_32k_sync_timer_read());
205}
206
207static 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
217static 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
223static __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 */
259static 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
267struct 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
81static struct otg_transceiver *xceiv; 82static 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
114static 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
123static 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
132static 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
141static 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
113static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device) 150static 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())