diff options
Diffstat (limited to 'arch/arm/mach-omap1')
-rw-r--r-- | arch/arm/mach-omap1/Makefile | 3 | ||||
-rw-r--r-- | arch/arm/mach-omap1/board-osk.c | 138 | ||||
-rw-r--r-- | arch/arm/mach-omap1/leds-osk.c | 80 | ||||
-rw-r--r-- | arch/arm/mach-omap1/mux.c | 146 | ||||
-rw-r--r-- | arch/arm/mach-omap1/time.c | 49 | ||||
-rw-r--r-- | arch/arm/mach-omap1/timer32k.c | 209 |
6 files changed, 432 insertions, 193 deletions
diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile index 015a66b3ca8e..c06f5254c0f3 100644 --- a/arch/arm/mach-omap1/Makefile +++ b/arch/arm/mach-omap1/Makefile | |||
@@ -5,7 +5,8 @@ | |||
5 | # Common support | 5 | # Common support |
6 | obj-y := io.o id.o clock.o irq.o mux.o serial.o devices.o | 6 | obj-y := io.o id.o clock.o irq.o mux.o serial.o devices.o |
7 | 7 | ||
8 | obj-$(CONFIG_OMAP_MPU_TIMER) += time.o | 8 | obj-$(CONFIG_OMAP_MPU_TIMER) += time.o |
9 | obj-$(CONFIG_OMAP_32K_TIMER) += timer32k.o | ||
9 | 10 | ||
10 | # Power Management | 11 | # Power Management |
11 | obj-$(CONFIG_PM) += pm.o sleep.o | 12 | obj-$(CONFIG_PM) += pm.o sleep.o |
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index 5279e35a8aec..4f9baba7d893 100644 --- a/arch/arm/mach-omap1/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/interrupt.h> | 32 | #include <linux/interrupt.h> |
33 | #include <linux/irq.h> | 33 | #include <linux/irq.h> |
34 | #include <linux/i2c.h> | 34 | #include <linux/i2c.h> |
35 | #include <linux/leds.h> | ||
35 | 36 | ||
36 | #include <linux/mtd/mtd.h> | 37 | #include <linux/mtd/mtd.h> |
37 | #include <linux/mtd/partitions.h> | 38 | #include <linux/mtd/partitions.h> |
@@ -183,11 +184,80 @@ static struct platform_device *osk5912_devices[] __initdata = { | |||
183 | &osk5912_mcbsp1_device, | 184 | &osk5912_mcbsp1_device, |
184 | }; | 185 | }; |
185 | 186 | ||
187 | static struct gpio_led tps_leds[] = { | ||
188 | /* NOTE: D9 and D2 have hardware blink support. | ||
189 | * Also, D9 requires non-battery power. | ||
190 | */ | ||
191 | { .gpio = OSK_TPS_GPIO_LED_D9, .name = "d9", }, | ||
192 | { .gpio = OSK_TPS_GPIO_LED_D2, .name = "d2", }, | ||
193 | { .gpio = OSK_TPS_GPIO_LED_D3, .name = "d3", .active_low = 1, | ||
194 | .default_trigger = "heartbeat", }, | ||
195 | }; | ||
196 | |||
197 | static struct gpio_led_platform_data tps_leds_data = { | ||
198 | .num_leds = 3, | ||
199 | .leds = tps_leds, | ||
200 | }; | ||
201 | |||
202 | static struct platform_device osk5912_tps_leds = { | ||
203 | .name = "leds-gpio", | ||
204 | .id = 0, | ||
205 | .dev.platform_data = &tps_leds_data, | ||
206 | }; | ||
207 | |||
208 | static int osk_tps_setup(struct i2c_client *client, void *context) | ||
209 | { | ||
210 | /* Set GPIO 1 HIGH to disable VBUS power supply; | ||
211 | * OHCI driver powers it up/down as needed. | ||
212 | */ | ||
213 | gpio_request(OSK_TPS_GPIO_USB_PWR_EN, "n_vbus_en"); | ||
214 | gpio_direction_output(OSK_TPS_GPIO_USB_PWR_EN, 1); | ||
215 | |||
216 | /* Set GPIO 2 high so LED D3 is off by default */ | ||
217 | tps65010_set_gpio_out_value(GPIO2, HIGH); | ||
218 | |||
219 | /* Set GPIO 3 low to take ethernet out of reset */ | ||
220 | gpio_request(OSK_TPS_GPIO_LAN_RESET, "smc_reset"); | ||
221 | gpio_direction_output(OSK_TPS_GPIO_LAN_RESET, 0); | ||
222 | |||
223 | /* GPIO4 is VDD_DSP */ | ||
224 | gpio_request(OSK_TPS_GPIO_DSP_PWR_EN, "dsp_power"); | ||
225 | gpio_direction_output(OSK_TPS_GPIO_DSP_PWR_EN, 1); | ||
226 | /* REVISIT if DSP support isn't configured, power it off ... */ | ||
227 | |||
228 | /* Let LED1 (D9) blink; leds-gpio may override it */ | ||
229 | tps65010_set_led(LED1, BLINK); | ||
230 | |||
231 | /* Set LED2 off by default */ | ||
232 | tps65010_set_led(LED2, OFF); | ||
233 | |||
234 | /* Enable LOW_PWR handshake */ | ||
235 | tps65010_set_low_pwr(ON); | ||
236 | |||
237 | /* Switch VLDO2 to 3.0V for AIC23 */ | ||
238 | tps65010_config_vregs1(TPS_LDO2_ENABLE | TPS_VLDO2_3_0V | ||
239 | | TPS_LDO1_ENABLE); | ||
240 | |||
241 | /* register these three LEDs */ | ||
242 | osk5912_tps_leds.dev.parent = &client->dev; | ||
243 | platform_device_register(&osk5912_tps_leds); | ||
244 | |||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | static struct tps65010_board tps_board = { | ||
249 | .base = OSK_TPS_GPIO_BASE, | ||
250 | .outmask = 0x0f, | ||
251 | .setup = osk_tps_setup, | ||
252 | }; | ||
253 | |||
186 | static struct i2c_board_info __initdata osk_i2c_board_info[] = { | 254 | static struct i2c_board_info __initdata osk_i2c_board_info[] = { |
187 | { | 255 | { |
188 | I2C_BOARD_INFO("tps65010", 0x48), | 256 | I2C_BOARD_INFO("tps65010", 0x48), |
189 | .type = "tps65010", | 257 | .type = "tps65010", |
190 | .irq = OMAP_GPIO_IRQ(OMAP_MPUIO(1)), | 258 | .irq = OMAP_GPIO_IRQ(OMAP_MPUIO(1)), |
259 | .platform_data = &tps_board, | ||
260 | |||
191 | }, | 261 | }, |
192 | /* TODO when driver support is ready: | 262 | /* TODO when driver support is ready: |
193 | * - aic23 audio chip at 0x1a | 263 | * - aic23 audio chip at 0x1a |
@@ -198,7 +268,7 @@ static struct i2c_board_info __initdata osk_i2c_board_info[] = { | |||
198 | 268 | ||
199 | static void __init osk_init_smc91x(void) | 269 | static void __init osk_init_smc91x(void) |
200 | { | 270 | { |
201 | if ((omap_request_gpio(0)) < 0) { | 271 | if ((gpio_request(0, "smc_irq")) < 0) { |
202 | printk("Error requesting gpio 0 for smc91x irq\n"); | 272 | printk("Error requesting gpio 0 for smc91x irq\n"); |
203 | return; | 273 | return; |
204 | } | 274 | } |
@@ -210,7 +280,7 @@ static void __init osk_init_smc91x(void) | |||
210 | static void __init osk_init_cf(void) | 280 | static void __init osk_init_cf(void) |
211 | { | 281 | { |
212 | omap_cfg_reg(M7_1610_GPIO62); | 282 | omap_cfg_reg(M7_1610_GPIO62); |
213 | if ((omap_request_gpio(62)) < 0) { | 283 | if ((gpio_request(62, "cf_irq")) < 0) { |
214 | printk("Error requesting gpio 62 for CF irq\n"); | 284 | printk("Error requesting gpio 62 for CF irq\n"); |
215 | return; | 285 | return; |
216 | } | 286 | } |
@@ -334,7 +404,7 @@ static struct platform_device *mistral_devices[] __initdata = { | |||
334 | 404 | ||
335 | static int mistral_get_pendown_state(void) | 405 | static int mistral_get_pendown_state(void) |
336 | { | 406 | { |
337 | return !omap_get_gpio_datain(4); | 407 | return !gpio_get_value(4); |
338 | } | 408 | } |
339 | 409 | ||
340 | static const struct ads7846_platform_data mistral_ts_info = { | 410 | static const struct ads7846_platform_data mistral_ts_info = { |
@@ -396,25 +466,31 @@ static void __init osk_mistral_init(void) | |||
396 | omap_cfg_reg(W14_1610_CCP_DATAP); | 466 | omap_cfg_reg(W14_1610_CCP_DATAP); |
397 | 467 | ||
398 | /* CAM_PWDN */ | 468 | /* CAM_PWDN */ |
399 | if (omap_request_gpio(11) == 0) { | 469 | if (gpio_request(11, "cam_pwdn") == 0) { |
400 | omap_cfg_reg(N20_1610_GPIO11); | 470 | omap_cfg_reg(N20_1610_GPIO11); |
401 | omap_set_gpio_direction(11, 0 /* out */); | 471 | gpio_direction_output(11, 0); |
402 | omap_set_gpio_dataout(11, 0 /* off */); | ||
403 | } else | 472 | } else |
404 | pr_debug("OSK+Mistral: CAM_PWDN is awol\n"); | 473 | pr_debug("OSK+Mistral: CAM_PWDN is awol\n"); |
405 | 474 | ||
406 | 475 | ||
407 | /* omap_cfg_reg(P19_1610_GPIO6); */ /* BUSY */ | 476 | /* omap_cfg_reg(P19_1610_GPIO6); */ /* BUSY */ |
477 | gpio_request(6, "ts_busy"); | ||
478 | gpio_direction_input(6); | ||
479 | |||
408 | omap_cfg_reg(P20_1610_GPIO4); /* PENIRQ */ | 480 | omap_cfg_reg(P20_1610_GPIO4); /* PENIRQ */ |
481 | gpio_request(4, "ts_int"); | ||
482 | gpio_direction_input(4); | ||
409 | set_irq_type(OMAP_GPIO_IRQ(4), IRQT_FALLING); | 483 | set_irq_type(OMAP_GPIO_IRQ(4), IRQT_FALLING); |
484 | |||
410 | spi_register_board_info(mistral_boardinfo, | 485 | spi_register_board_info(mistral_boardinfo, |
411 | ARRAY_SIZE(mistral_boardinfo)); | 486 | ARRAY_SIZE(mistral_boardinfo)); |
412 | 487 | ||
413 | /* the sideways button (SW1) is for use as a "wakeup" button */ | 488 | /* the sideways button (SW1) is for use as a "wakeup" button */ |
414 | omap_cfg_reg(N15_1610_MPUIO2); | 489 | omap_cfg_reg(N15_1610_MPUIO2); |
415 | if (omap_request_gpio(OMAP_MPUIO(2)) == 0) { | 490 | if (gpio_request(OMAP_MPUIO(2), "wakeup") == 0) { |
416 | int ret = 0; | 491 | int ret = 0; |
417 | omap_set_gpio_direction(OMAP_MPUIO(2), 1); | 492 | |
493 | gpio_direction_input(OMAP_MPUIO(2)); | ||
418 | set_irq_type(OMAP_GPIO_IRQ(OMAP_MPUIO(2)), IRQT_RISING); | 494 | set_irq_type(OMAP_GPIO_IRQ(OMAP_MPUIO(2)), IRQT_RISING); |
419 | #ifdef CONFIG_PM | 495 | #ifdef CONFIG_PM |
420 | /* share the IRQ in case someone wants to use the | 496 | /* share the IRQ in case someone wants to use the |
@@ -425,7 +501,7 @@ static void __init osk_mistral_init(void) | |||
425 | IRQF_SHARED, "mistral_wakeup", | 501 | IRQF_SHARED, "mistral_wakeup", |
426 | &osk_mistral_wake_interrupt); | 502 | &osk_mistral_wake_interrupt); |
427 | if (ret != 0) { | 503 | if (ret != 0) { |
428 | omap_free_gpio(OMAP_MPUIO(2)); | 504 | gpio_free(OMAP_MPUIO(2)); |
429 | printk(KERN_ERR "OSK+Mistral: no wakeup irq, %d?\n", | 505 | printk(KERN_ERR "OSK+Mistral: no wakeup irq, %d?\n", |
430 | ret); | 506 | ret); |
431 | } else | 507 | } else |
@@ -438,10 +514,8 @@ static void __init osk_mistral_init(void) | |||
438 | * board, like the touchscreen, EEPROM, and wakeup (!) switch. | 514 | * board, like the touchscreen, EEPROM, and wakeup (!) switch. |
439 | */ | 515 | */ |
440 | omap_cfg_reg(PWL); | 516 | omap_cfg_reg(PWL); |
441 | if (omap_request_gpio(2) == 0) { | 517 | if (gpio_request(2, "lcd_pwr") == 0) |
442 | omap_set_gpio_direction(2, 0 /* out */); | 518 | gpio_direction_output(2, 1); |
443 | omap_set_gpio_dataout(2, 1 /* on */); | ||
444 | } | ||
445 | 519 | ||
446 | platform_add_devices(mistral_devices, ARRAY_SIZE(mistral_devices)); | 520 | platform_add_devices(mistral_devices, ARRAY_SIZE(mistral_devices)); |
447 | } | 521 | } |
@@ -484,44 +558,6 @@ static void __init osk_map_io(void) | |||
484 | omap1_map_common_io(); | 558 | omap1_map_common_io(); |
485 | } | 559 | } |
486 | 560 | ||
487 | #ifdef CONFIG_TPS65010 | ||
488 | static int __init osk_tps_init(void) | ||
489 | { | ||
490 | if (!machine_is_omap_osk()) | ||
491 | return 0; | ||
492 | |||
493 | /* Let LED1 (D9) blink */ | ||
494 | tps65010_set_led(LED1, BLINK); | ||
495 | |||
496 | /* Disable LED 2 (D2) */ | ||
497 | tps65010_set_led(LED2, OFF); | ||
498 | |||
499 | /* Set GPIO 1 HIGH to disable VBUS power supply; | ||
500 | * OHCI driver powers it up/down as needed. | ||
501 | */ | ||
502 | tps65010_set_gpio_out_value(GPIO1, HIGH); | ||
503 | |||
504 | /* Set GPIO 2 low to turn on LED D3 */ | ||
505 | tps65010_set_gpio_out_value(GPIO2, HIGH); | ||
506 | |||
507 | /* Set GPIO 3 low to take ethernet out of reset */ | ||
508 | tps65010_set_gpio_out_value(GPIO3, LOW); | ||
509 | |||
510 | /* gpio4 for VDD_DSP */ | ||
511 | /* FIXME send power to DSP iff it's configured */ | ||
512 | |||
513 | /* Enable LOW_PWR */ | ||
514 | tps65010_set_low_pwr(ON); | ||
515 | |||
516 | /* Switch VLDO2 to 3.0V for AIC23 */ | ||
517 | tps65010_config_vregs1(TPS_LDO2_ENABLE | TPS_VLDO2_3_0V | ||
518 | | TPS_LDO1_ENABLE); | ||
519 | |||
520 | return 0; | ||
521 | } | ||
522 | fs_initcall(osk_tps_init); | ||
523 | #endif | ||
524 | |||
525 | MACHINE_START(OMAP_OSK, "TI-OSK") | 561 | MACHINE_START(OMAP_OSK, "TI-OSK") |
526 | /* Maintainer: Dirk Behme <dirk.behme@de.bosch.com> */ | 562 | /* Maintainer: Dirk Behme <dirk.behme@de.bosch.com> */ |
527 | .phys_io = 0xfff00000, | 563 | .phys_io = 0xfff00000, |
diff --git a/arch/arm/mach-omap1/leds-osk.c b/arch/arm/mach-omap1/leds-osk.c index 026685ed461a..754383dde807 100644 --- a/arch/arm/mach-omap1/leds-osk.c +++ b/arch/arm/mach-omap1/leds-osk.c | |||
@@ -1,11 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * linux/arch/arm/mach-omap1/leds-osk.c | 2 | * linux/arch/arm/mach-omap1/leds-osk.c |
3 | * | 3 | * |
4 | * LED driver for OSK, and optionally Mistral QVGA, boards | 4 | * LED driver for OSK with optional Mistral QVGA board |
5 | */ | 5 | */ |
6 | #include <linux/init.h> | 6 | #include <linux/init.h> |
7 | #include <linux/workqueue.h> | ||
8 | #include <linux/i2c/tps65010.h> | ||
9 | 7 | ||
10 | #include <asm/hardware.h> | 8 | #include <asm/hardware.h> |
11 | #include <asm/leds.h> | 9 | #include <asm/leds.h> |
@@ -20,49 +18,11 @@ | |||
20 | #define LED_STATE_CLAIMED (1 << 1) | 18 | #define LED_STATE_CLAIMED (1 << 1) |
21 | static u8 led_state; | 19 | static u8 led_state; |
22 | 20 | ||
23 | #define GREEN_LED (1 << 0) /* TPS65010 LED1 */ | ||
24 | #define AMBER_LED (1 << 1) /* TPS65010 LED2 */ | ||
25 | #define RED_LED (1 << 2) /* TPS65010 GPIO2 */ | ||
26 | #define TIMER_LED (1 << 3) /* Mistral board */ | 21 | #define TIMER_LED (1 << 3) /* Mistral board */ |
27 | #define IDLE_LED (1 << 4) /* Mistral board */ | 22 | #define IDLE_LED (1 << 4) /* Mistral board */ |
28 | static u8 hw_led_state; | 23 | static u8 hw_led_state; |
29 | 24 | ||
30 | 25 | ||
31 | /* TPS65010 leds are changed using i2c -- from a task context. | ||
32 | * Using one of these for the "idle" LED would be impractical... | ||
33 | */ | ||
34 | #define TPS_LEDS (GREEN_LED | RED_LED | AMBER_LED) | ||
35 | |||
36 | static u8 tps_leds_change; | ||
37 | |||
38 | static void tps_work(struct work_struct *unused) | ||
39 | { | ||
40 | for (;;) { | ||
41 | u8 leds; | ||
42 | |||
43 | local_irq_disable(); | ||
44 | leds = tps_leds_change; | ||
45 | tps_leds_change = 0; | ||
46 | local_irq_enable(); | ||
47 | |||
48 | if (!leds) | ||
49 | break; | ||
50 | |||
51 | /* careful: the set_led() value is on/off/blink */ | ||
52 | if (leds & GREEN_LED) | ||
53 | tps65010_set_led(LED1, !!(hw_led_state & GREEN_LED)); | ||
54 | if (leds & AMBER_LED) | ||
55 | tps65010_set_led(LED2, !!(hw_led_state & AMBER_LED)); | ||
56 | |||
57 | /* the gpio led doesn't have that issue */ | ||
58 | if (leds & RED_LED) | ||
59 | tps65010_set_gpio_out_value(GPIO2, | ||
60 | !(hw_led_state & RED_LED)); | ||
61 | } | ||
62 | } | ||
63 | |||
64 | static DECLARE_WORK(work, tps_work); | ||
65 | |||
66 | #ifdef CONFIG_OMAP_OSK_MISTRAL | 26 | #ifdef CONFIG_OMAP_OSK_MISTRAL |
67 | 27 | ||
68 | /* For now, all system indicators require the Mistral board, since that | 28 | /* For now, all system indicators require the Mistral board, since that |
@@ -112,7 +72,6 @@ void osk_leds_event(led_event_t evt) | |||
112 | case led_stop: | 72 | case led_stop: |
113 | led_state &= ~LED_STATE_ENABLED; | 73 | led_state &= ~LED_STATE_ENABLED; |
114 | hw_led_state = 0; | 74 | hw_led_state = 0; |
115 | /* NOTE: work may still be pending!! */ | ||
116 | break; | 75 | break; |
117 | 76 | ||
118 | case led_claim: | 77 | case led_claim: |
@@ -145,48 +104,11 @@ void osk_leds_event(led_event_t evt) | |||
145 | 104 | ||
146 | #endif /* CONFIG_OMAP_OSK_MISTRAL */ | 105 | #endif /* CONFIG_OMAP_OSK_MISTRAL */ |
147 | 106 | ||
148 | /* "green" == tps LED1 (leftmost, normally power-good) | ||
149 | * works only with DC adapter, not on battery power! | ||
150 | */ | ||
151 | case led_green_on: | ||
152 | if (led_state & LED_STATE_CLAIMED) | ||
153 | hw_led_state |= GREEN_LED; | ||
154 | break; | ||
155 | case led_green_off: | ||
156 | if (led_state & LED_STATE_CLAIMED) | ||
157 | hw_led_state &= ~GREEN_LED; | ||
158 | break; | ||
159 | |||
160 | /* "amber" == tps LED2 (middle) */ | ||
161 | case led_amber_on: | ||
162 | if (led_state & LED_STATE_CLAIMED) | ||
163 | hw_led_state |= AMBER_LED; | ||
164 | break; | ||
165 | case led_amber_off: | ||
166 | if (led_state & LED_STATE_CLAIMED) | ||
167 | hw_led_state &= ~AMBER_LED; | ||
168 | break; | ||
169 | |||
170 | /* "red" == LED on tps gpio3 (rightmost) */ | ||
171 | case led_red_on: | ||
172 | if (led_state & LED_STATE_CLAIMED) | ||
173 | hw_led_state |= RED_LED; | ||
174 | break; | ||
175 | case led_red_off: | ||
176 | if (led_state & LED_STATE_CLAIMED) | ||
177 | hw_led_state &= ~RED_LED; | ||
178 | break; | ||
179 | |||
180 | default: | 107 | default: |
181 | break; | 108 | break; |
182 | } | 109 | } |
183 | 110 | ||
184 | leds ^= hw_led_state; | 111 | leds ^= hw_led_state; |
185 | leds &= TPS_LEDS; | ||
186 | if (leds && (led_state & LED_STATE_CLAIMED)) { | ||
187 | tps_leds_change |= leds; | ||
188 | schedule_work(&work); | ||
189 | } | ||
190 | 112 | ||
191 | done: | 113 | done: |
192 | local_irq_restore(flags); | 114 | local_irq_restore(flags); |
diff --git a/arch/arm/mach-omap1/mux.c b/arch/arm/mach-omap1/mux.c index 52c70e5fcf65..e207bf7cb853 100644 --- a/arch/arm/mach-omap1/mux.c +++ b/arch/arm/mach-omap1/mux.c | |||
@@ -3,9 +3,9 @@ | |||
3 | * | 3 | * |
4 | * OMAP1 pin multiplexing configurations | 4 | * OMAP1 pin multiplexing configurations |
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,8 +32,10 @@ | |||
32 | 32 | ||
33 | #ifdef CONFIG_OMAP_MUX | 33 | #ifdef CONFIG_OMAP_MUX |
34 | 34 | ||
35 | static struct omap_mux_cfg arch_mux_cfg; | ||
36 | |||
35 | #ifdef CONFIG_ARCH_OMAP730 | 37 | #ifdef CONFIG_ARCH_OMAP730 |
36 | struct pin_config __initdata_or_module omap730_pins[] = { | 38 | static struct pin_config __initdata_or_module omap730_pins[] = { |
37 | MUX_CFG_730("E2_730_KBR0", 12, 21, 0, 20, 1, 0) | 39 | MUX_CFG_730("E2_730_KBR0", 12, 21, 0, 20, 1, 0) |
38 | MUX_CFG_730("J7_730_KBR1", 12, 25, 0, 24, 1, 0) | 40 | MUX_CFG_730("J7_730_KBR1", 12, 25, 0, 24, 1, 0) |
39 | MUX_CFG_730("E1_730_KBR2", 12, 29, 0, 28, 1, 0) | 41 | MUX_CFG_730("E1_730_KBR2", 12, 29, 0, 28, 1, 0) |
@@ -49,10 +51,14 @@ MUX_CFG_730("AA17_730_USB_DM", 2, 21, 0, 20, 0, 0) | |||
49 | MUX_CFG_730("W16_730_USB_PU_EN", 2, 25, 0, 24, 0, 0) | 51 | MUX_CFG_730("W16_730_USB_PU_EN", 2, 25, 0, 24, 0, 0) |
50 | MUX_CFG_730("W17_730_USB_VBUSI", 2, 29, 0, 28, 0, 0) | 52 | MUX_CFG_730("W17_730_USB_VBUSI", 2, 29, 0, 28, 0, 0) |
51 | }; | 53 | }; |
52 | #endif | 54 | #define OMAP730_PINS_SZ ARRAY_SIZE(omap730_pins) |
55 | #else | ||
56 | #define omap730_pins NULL | ||
57 | #define OMAP730_PINS_SZ 0 | ||
58 | #endif /* CONFIG_ARCH_OMAP730 */ | ||
53 | 59 | ||
54 | #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) | 60 | #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) |
55 | struct pin_config __initdata_or_module omap1xxx_pins[] = { | 61 | static struct pin_config __initdata_or_module omap1xxx_pins[] = { |
56 | /* | 62 | /* |
57 | * description mux mode mux pull pull pull pu_pd pu dbg | 63 | * description mux mode mux pull pull pull pu_pd pu dbg |
58 | * reg offset mode reg bit ena reg | 64 | * reg offset mode reg bit ena reg |
@@ -306,22 +312,136 @@ MUX_CFG("Y12_1610_CCP_CLKP", 8, 18, 6, 1, 24, 1, 1, 0, 0) | |||
306 | MUX_CFG("W13_1610_CCP_CLKM", 9, 0, 6, 1, 28, 1, 1, 0, 0) | 312 | MUX_CFG("W13_1610_CCP_CLKM", 9, 0, 6, 1, 28, 1, 1, 0, 0) |
307 | MUX_CFG("W14_1610_CCP_DATAP", 9, 24, 6, 2, 4, 1, 2, 0, 0) | 313 | MUX_CFG("W14_1610_CCP_DATAP", 9, 24, 6, 2, 4, 1, 2, 0, 0) |
308 | MUX_CFG("Y14_1610_CCP_DATAM", 9, 21, 6, 2, 3, 1, 2, 0, 0) | 314 | MUX_CFG("Y14_1610_CCP_DATAM", 9, 21, 6, 2, 3, 1, 2, 0, 0) |
309 | |||
310 | }; | 315 | }; |
316 | #define OMAP1XXX_PINS_SZ ARRAY_SIZE(omap1xxx_pins) | ||
317 | #else | ||
318 | #define omap1xxx_pins NULL | ||
319 | #define OMAP1XXX_PINS_SZ 0 | ||
311 | #endif /* CONFIG_ARCH_OMAP15XX || CONFIG_ARCH_OMAP16XX */ | 320 | #endif /* CONFIG_ARCH_OMAP15XX || CONFIG_ARCH_OMAP16XX */ |
312 | 321 | ||
313 | int __init omap1_mux_init(void) | 322 | int __init_or_module omap1_cfg_reg(const struct pin_config *cfg) |
314 | { | 323 | { |
315 | 324 | static DEFINE_SPINLOCK(mux_spin_lock); | |
316 | #ifdef CONFIG_ARCH_OMAP730 | 325 | unsigned long flags; |
317 | omap_mux_register(omap730_pins, ARRAY_SIZE(omap730_pins)); | 326 | unsigned int reg_orig = 0, reg = 0, pu_pd_orig = 0, pu_pd = 0, |
327 | pull_orig = 0, pull = 0; | ||
328 | unsigned int mask, warn = 0; | ||
329 | |||
330 | /* Check the mux register in question */ | ||
331 | if (cfg->mux_reg) { | ||
332 | unsigned tmp1, tmp2; | ||
333 | |||
334 | spin_lock_irqsave(&mux_spin_lock, flags); | ||
335 | reg_orig = omap_readl(cfg->mux_reg); | ||
336 | |||
337 | /* The mux registers always seem to be 3 bits long */ | ||
338 | mask = (0x7 << cfg->mask_offset); | ||
339 | tmp1 = reg_orig & mask; | ||
340 | reg = reg_orig & ~mask; | ||
341 | |||
342 | tmp2 = (cfg->mask << cfg->mask_offset); | ||
343 | reg |= tmp2; | ||
344 | |||
345 | if (tmp1 != tmp2) | ||
346 | warn = 1; | ||
347 | |||
348 | omap_writel(reg, cfg->mux_reg); | ||
349 | spin_unlock_irqrestore(&mux_spin_lock, flags); | ||
350 | } | ||
351 | |||
352 | /* Check for pull up or pull down selection on 1610 */ | ||
353 | if (!cpu_is_omap15xx()) { | ||
354 | if (cfg->pu_pd_reg && cfg->pull_val) { | ||
355 | spin_lock_irqsave(&mux_spin_lock, flags); | ||
356 | pu_pd_orig = omap_readl(cfg->pu_pd_reg); | ||
357 | mask = 1 << cfg->pull_bit; | ||
358 | |||
359 | if (cfg->pu_pd_val) { | ||
360 | if (!(pu_pd_orig & mask)) | ||
361 | warn = 1; | ||
362 | /* Use pull up */ | ||
363 | pu_pd = pu_pd_orig | mask; | ||
364 | } else { | ||
365 | if (pu_pd_orig & mask) | ||
366 | warn = 1; | ||
367 | /* Use pull down */ | ||
368 | pu_pd = pu_pd_orig & ~mask; | ||
369 | } | ||
370 | omap_writel(pu_pd, cfg->pu_pd_reg); | ||
371 | spin_unlock_irqrestore(&mux_spin_lock, flags); | ||
372 | } | ||
373 | } | ||
374 | |||
375 | /* Check for an associated pull down register */ | ||
376 | if (cfg->pull_reg) { | ||
377 | spin_lock_irqsave(&mux_spin_lock, flags); | ||
378 | pull_orig = omap_readl(cfg->pull_reg); | ||
379 | mask = 1 << cfg->pull_bit; | ||
380 | |||
381 | if (cfg->pull_val) { | ||
382 | if (pull_orig & mask) | ||
383 | warn = 1; | ||
384 | /* Low bit = pull enabled */ | ||
385 | pull = pull_orig & ~mask; | ||
386 | } else { | ||
387 | if (!(pull_orig & mask)) | ||
388 | warn = 1; | ||
389 | /* High bit = pull disabled */ | ||
390 | pull = pull_orig | mask; | ||
391 | } | ||
392 | |||
393 | omap_writel(pull, cfg->pull_reg); | ||
394 | spin_unlock_irqrestore(&mux_spin_lock, flags); | ||
395 | } | ||
396 | |||
397 | if (warn) { | ||
398 | #ifdef CONFIG_OMAP_MUX_WARNINGS | ||
399 | printk(KERN_WARNING "MUX: initialized %s\n", cfg->name); | ||
318 | #endif | 400 | #endif |
319 | 401 | } | |
320 | #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) | 402 | |
321 | omap_mux_register(omap1xxx_pins, ARRAY_SIZE(omap1xxx_pins)); | 403 | #ifdef CONFIG_OMAP_MUX_DEBUG |
404 | if (cfg->debug || warn) { | ||
405 | printk("MUX: Setting register %s\n", cfg->name); | ||
406 | printk(" %s (0x%08x) = 0x%08x -> 0x%08x\n", | ||
407 | cfg->mux_reg_name, cfg->mux_reg, reg_orig, reg); | ||
408 | |||
409 | if (!cpu_is_omap15xx()) { | ||
410 | if (cfg->pu_pd_reg && cfg->pull_val) { | ||
411 | printk(" %s (0x%08x) = 0x%08x -> 0x%08x\n", | ||
412 | cfg->pu_pd_name, cfg->pu_pd_reg, | ||
413 | pu_pd_orig, pu_pd); | ||
414 | } | ||
415 | } | ||
416 | |||
417 | if (cfg->pull_reg) | ||
418 | printk(" %s (0x%08x) = 0x%08x -> 0x%08x\n", | ||
419 | cfg->pull_name, cfg->pull_reg, pull_orig, pull); | ||
420 | } | ||
322 | #endif | 421 | #endif |
323 | 422 | ||
423 | #ifdef CONFIG_OMAP_MUX_ERRORS | ||
424 | return warn ? -ETXTBSY : 0; | ||
425 | #else | ||
324 | return 0; | 426 | return 0; |
427 | #endif | ||
428 | } | ||
429 | |||
430 | int __init omap1_mux_init(void) | ||
431 | { | ||
432 | if (cpu_is_omap730()) { | ||
433 | arch_mux_cfg.pins = omap730_pins; | ||
434 | arch_mux_cfg.size = OMAP730_PINS_SZ; | ||
435 | arch_mux_cfg.cfg_reg = omap1_cfg_reg; | ||
436 | } | ||
437 | |||
438 | if (cpu_is_omap15xx() || cpu_is_omap16xx()) { | ||
439 | arch_mux_cfg.pins = omap1xxx_pins; | ||
440 | arch_mux_cfg.size = OMAP1XXX_PINS_SZ; | ||
441 | arch_mux_cfg.cfg_reg = omap1_cfg_reg; | ||
442 | } | ||
443 | |||
444 | return omap_mux_register(&arch_mux_cfg); | ||
325 | } | 445 | } |
326 | 446 | ||
327 | #endif | 447 | #endif |
diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c index a4f8b2055437..5d2b270935a2 100644 --- a/arch/arm/mach-omap1/time.c +++ b/arch/arm/mach-omap1/time.c | |||
@@ -56,37 +56,6 @@ | |||
56 | #define OMAP_MPU_TIMER_BASE OMAP_MPU_TIMER1_BASE | 56 | #define OMAP_MPU_TIMER_BASE OMAP_MPU_TIMER1_BASE |
57 | #define OMAP_MPU_TIMER_OFFSET 0x100 | 57 | #define OMAP_MPU_TIMER_OFFSET 0x100 |
58 | 58 | ||
59 | /* cycles to nsec conversions taken from arch/i386/kernel/timers/timer_tsc.c, | ||
60 | * converted to use kHz by Kevin Hilman */ | ||
61 | /* convert from cycles(64bits) => nanoseconds (64bits) | ||
62 | * basic equation: | ||
63 | * ns = cycles / (freq / ns_per_sec) | ||
64 | * ns = cycles * (ns_per_sec / freq) | ||
65 | * ns = cycles * (10^9 / (cpu_khz * 10^3)) | ||
66 | * ns = cycles * (10^6 / cpu_khz) | ||
67 | * | ||
68 | * Then we use scaling math (suggested by george at mvista.com) to get: | ||
69 | * ns = cycles * (10^6 * SC / cpu_khz / SC | ||
70 | * ns = cycles * cyc2ns_scale / SC | ||
71 | * | ||
72 | * And since SC is a constant power of two, we can convert the div | ||
73 | * into a shift. | ||
74 | * -johnstul at us.ibm.com "math is hard, lets go shopping!" | ||
75 | */ | ||
76 | static unsigned long cyc2ns_scale; | ||
77 | #define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */ | ||
78 | |||
79 | static inline void set_cyc2ns_scale(unsigned long cpu_khz) | ||
80 | { | ||
81 | cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz; | ||
82 | } | ||
83 | |||
84 | static inline unsigned long long cycles_2_ns(unsigned long long cyc) | ||
85 | { | ||
86 | return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR; | ||
87 | } | ||
88 | |||
89 | |||
90 | typedef struct { | 59 | typedef struct { |
91 | u32 cntl; /* CNTL_TIMER, R/W */ | 60 | u32 cntl; /* CNTL_TIMER, R/W */ |
92 | u32 load_tim; /* LOAD_TIM, W */ | 61 | u32 load_tim; /* LOAD_TIM, W */ |
@@ -194,8 +163,6 @@ static struct irqaction omap_mpu_timer1_irq = { | |||
194 | 163 | ||
195 | static __init void omap_init_mpu_timer(unsigned long rate) | 164 | static __init void omap_init_mpu_timer(unsigned long rate) |
196 | { | 165 | { |
197 | set_cyc2ns_scale(rate / 1000); | ||
198 | |||
199 | setup_irq(INT_TIMER1, &omap_mpu_timer1_irq); | 166 | setup_irq(INT_TIMER1, &omap_mpu_timer1_irq); |
200 | omap_mpu_timer_start(0, (rate / HZ) - 1, 1); | 167 | omap_mpu_timer_start(0, (rate / HZ) - 1, 1); |
201 | 168 | ||
@@ -260,22 +227,6 @@ static void __init omap_init_clocksource(unsigned long rate) | |||
260 | printk(err, clocksource_mpu.name); | 227 | printk(err, clocksource_mpu.name); |
261 | } | 228 | } |
262 | 229 | ||
263 | |||
264 | /* | ||
265 | * Scheduler clock - returns current time in nanosec units. | ||
266 | */ | ||
267 | unsigned long long sched_clock(void) | ||
268 | { | ||
269 | unsigned long ticks = 0 - omap_mpu_timer_read(1); | ||
270 | unsigned long long ticks64; | ||
271 | |||
272 | ticks64 = omap_mpu_timer2_overflows; | ||
273 | ticks64 <<= 32; | ||
274 | ticks64 |= ticks; | ||
275 | |||
276 | return cycles_2_ns(ticks64); | ||
277 | } | ||
278 | |||
279 | /* | 230 | /* |
280 | * --------------------------------------------------------------------------- | 231 | * --------------------------------------------------------------------------- |
281 | * Timer initialization | 232 | * Timer initialization |
diff --git a/arch/arm/mach-omap1/timer32k.c b/arch/arm/mach-omap1/timer32k.c new file mode 100644 index 000000000000..fbbdb806c95a --- /dev/null +++ b/arch/arm/mach-omap1/timer32k.c | |||
@@ -0,0 +1,209 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-omap1/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 | #else | ||
74 | #error OMAP 32KHz timer does not currently work on 15XX! | ||
75 | #endif | ||
76 | |||
77 | /* 16xx specific defines */ | ||
78 | #define OMAP1_32K_TIMER_BASE 0xfffb9000 | ||
79 | #define OMAP1_32K_TIMER_CR 0x08 | ||
80 | #define OMAP1_32K_TIMER_TVR 0x00 | ||
81 | #define OMAP1_32K_TIMER_TCR 0x04 | ||
82 | |||
83 | #define OMAP_32K_TICKS_PER_SEC (32768) | ||
84 | |||
85 | /* | ||
86 | * TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1 | ||
87 | * so with HZ = 128, TVR = 255. | ||
88 | */ | ||
89 | #define OMAP_32K_TIMER_TICK_PERIOD ((OMAP_32K_TICKS_PER_SEC / HZ) - 1) | ||
90 | |||
91 | #define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate) \ | ||
92 | (((nr_jiffies) * (clock_rate)) / HZ) | ||
93 | |||
94 | static inline void omap_32k_timer_write(int val, int reg) | ||
95 | { | ||
96 | omap_writew(val, OMAP1_32K_TIMER_BASE + reg); | ||
97 | } | ||
98 | |||
99 | static inline unsigned long omap_32k_timer_read(int reg) | ||
100 | { | ||
101 | return omap_readl(OMAP1_32K_TIMER_BASE + reg) & 0xffffff; | ||
102 | } | ||
103 | |||
104 | static inline void omap_32k_timer_start(unsigned long load_val) | ||
105 | { | ||
106 | if (!load_val) | ||
107 | load_val = 1; | ||
108 | omap_32k_timer_write(load_val, OMAP1_32K_TIMER_TVR); | ||
109 | omap_32k_timer_write(0x0f, OMAP1_32K_TIMER_CR); | ||
110 | } | ||
111 | |||
112 | static inline void omap_32k_timer_stop(void) | ||
113 | { | ||
114 | omap_32k_timer_write(0x0, OMAP1_32K_TIMER_CR); | ||
115 | } | ||
116 | |||
117 | #define omap_32k_timer_ack_irq() | ||
118 | |||
119 | static int omap_32k_timer_set_next_event(unsigned long delta, | ||
120 | struct clock_event_device *dev) | ||
121 | { | ||
122 | omap_32k_timer_start(delta); | ||
123 | |||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | static void omap_32k_timer_set_mode(enum clock_event_mode mode, | ||
128 | struct clock_event_device *evt) | ||
129 | { | ||
130 | omap_32k_timer_stop(); | ||
131 | |||
132 | switch (mode) { | ||
133 | case CLOCK_EVT_MODE_PERIODIC: | ||
134 | omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD); | ||
135 | break; | ||
136 | case CLOCK_EVT_MODE_ONESHOT: | ||
137 | case CLOCK_EVT_MODE_UNUSED: | ||
138 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
139 | break; | ||
140 | case CLOCK_EVT_MODE_RESUME: | ||
141 | break; | ||
142 | } | ||
143 | } | ||
144 | |||
145 | static struct clock_event_device clockevent_32k_timer = { | ||
146 | .name = "32k-timer", | ||
147 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | ||
148 | .shift = 32, | ||
149 | .set_next_event = omap_32k_timer_set_next_event, | ||
150 | .set_mode = omap_32k_timer_set_mode, | ||
151 | }; | ||
152 | |||
153 | /* | ||
154 | * The 32KHz synchronized timer is an additional timer on 16xx. | ||
155 | * It is always running. | ||
156 | */ | ||
157 | static inline unsigned long omap_32k_sync_timer_read(void) | ||
158 | { | ||
159 | return omap_readl(TIMER_32K_SYNCHRONIZED); | ||
160 | } | ||
161 | |||
162 | static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id) | ||
163 | { | ||
164 | struct clock_event_device *evt = &clockevent_32k_timer; | ||
165 | omap_32k_timer_ack_irq(); | ||
166 | |||
167 | evt->event_handler(evt); | ||
168 | |||
169 | return IRQ_HANDLED; | ||
170 | } | ||
171 | |||
172 | static struct irqaction omap_32k_timer_irq = { | ||
173 | .name = "32KHz timer", | ||
174 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, | ||
175 | .handler = omap_32k_timer_interrupt, | ||
176 | }; | ||
177 | |||
178 | static __init void omap_init_32k_timer(void) | ||
179 | { | ||
180 | setup_irq(INT_OS_TIMER, &omap_32k_timer_irq); | ||
181 | |||
182 | clockevent_32k_timer.mult = div_sc(OMAP_32K_TICKS_PER_SEC, | ||
183 | NSEC_PER_SEC, | ||
184 | clockevent_32k_timer.shift); | ||
185 | clockevent_32k_timer.max_delta_ns = | ||
186 | clockevent_delta2ns(0xfffffffe, &clockevent_32k_timer); | ||
187 | clockevent_32k_timer.min_delta_ns = | ||
188 | clockevent_delta2ns(1, &clockevent_32k_timer); | ||
189 | |||
190 | clockevent_32k_timer.cpumask = cpumask_of_cpu(0); | ||
191 | clockevents_register_device(&clockevent_32k_timer); | ||
192 | } | ||
193 | |||
194 | /* | ||
195 | * --------------------------------------------------------------------------- | ||
196 | * Timer initialization | ||
197 | * --------------------------------------------------------------------------- | ||
198 | */ | ||
199 | static void __init omap_timer_init(void) | ||
200 | { | ||
201 | #ifdef CONFIG_OMAP_DM_TIMER | ||
202 | omap_dm_timer_init(); | ||
203 | #endif | ||
204 | omap_init_32k_timer(); | ||
205 | } | ||
206 | |||
207 | struct sys_timer omap_timer = { | ||
208 | .init = omap_timer_init, | ||
209 | }; | ||