diff options
Diffstat (limited to 'arch/arm')
51 files changed, 1418 insertions, 1454 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index ea7640af0f1e..f9362ee9955f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -17,6 +17,10 @@ config ARM | |||
17 | Europe. There is an ARM Linux project with a web page at | 17 | Europe. There is an ARM Linux project with a web page at |
18 | <http://www.arm.linux.org.uk/>. | 18 | <http://www.arm.linux.org.uk/>. |
19 | 19 | ||
20 | config GENERIC_TIME | ||
21 | bool | ||
22 | default n | ||
23 | |||
20 | config MMU | 24 | config MMU |
21 | bool | 25 | bool |
22 | default y | 26 | default y |
@@ -222,6 +226,7 @@ config ARCH_IOP33X | |||
222 | config ARCH_IXP4XX | 226 | config ARCH_IXP4XX |
223 | bool "IXP4xx-based" | 227 | bool "IXP4xx-based" |
224 | depends on MMU | 228 | depends on MMU |
229 | select GENERIC_TIME | ||
225 | help | 230 | help |
226 | Support for Intel's IXP4XX (XScale) family of processors. | 231 | Support for Intel's IXP4XX (XScale) family of processors. |
227 | 232 | ||
diff --git a/arch/arm/common/icst307.c b/arch/arm/common/icst307.c index bafe8b19be82..6d094c157540 100644 --- a/arch/arm/common/icst307.c +++ b/arch/arm/common/icst307.c | |||
@@ -57,7 +57,7 @@ icst307_khz_to_vco(const struct icst307_params *p, unsigned long freq) | |||
57 | break; | 57 | break; |
58 | } while (i < ARRAY_SIZE(idx2s)); | 58 | } while (i < ARRAY_SIZE(idx2s)); |
59 | 59 | ||
60 | if (i > ARRAY_SIZE(idx2s)) | 60 | if (i >= ARRAY_SIZE(idx2s)) |
61 | return vco; | 61 | return vco; |
62 | 62 | ||
63 | vco.s = idx2s[i]; | 63 | vco.s = idx2s[i]; |
@@ -119,7 +119,7 @@ icst307_ps_to_vco(const struct icst307_params *p, unsigned long period) | |||
119 | break; | 119 | break; |
120 | } while (i < ARRAY_SIZE(idx2s)); | 120 | } while (i < ARRAY_SIZE(idx2s)); |
121 | 121 | ||
122 | if (i > ARRAY_SIZE(idx2s)) | 122 | if (i >= ARRAY_SIZE(idx2s)) |
123 | return vco; | 123 | return vco; |
124 | 124 | ||
125 | vco.s = idx2s[i]; | 125 | vco.s = idx2s[i]; |
diff --git a/arch/arm/common/icst525.c b/arch/arm/common/icst525.c index 943ef88c0379..3d377c5bdef6 100644 --- a/arch/arm/common/icst525.c +++ b/arch/arm/common/icst525.c | |||
@@ -55,7 +55,7 @@ icst525_khz_to_vco(const struct icst525_params *p, unsigned long freq) | |||
55 | break; | 55 | break; |
56 | } while (i < ARRAY_SIZE(idx2s)); | 56 | } while (i < ARRAY_SIZE(idx2s)); |
57 | 57 | ||
58 | if (i > ARRAY_SIZE(idx2s)) | 58 | if (i >= ARRAY_SIZE(idx2s)) |
59 | return vco; | 59 | return vco; |
60 | 60 | ||
61 | vco.s = idx2s[i]; | 61 | vco.s = idx2s[i]; |
@@ -118,7 +118,7 @@ icst525_ps_to_vco(const struct icst525_params *p, unsigned long period) | |||
118 | break; | 118 | break; |
119 | } while (i < ARRAY_SIZE(idx2s)); | 119 | } while (i < ARRAY_SIZE(idx2s)); |
120 | 120 | ||
121 | if (i > ARRAY_SIZE(idx2s)) | 121 | if (i >= ARRAY_SIZE(idx2s)) |
122 | return vco; | 122 | return vco; |
123 | 123 | ||
124 | vco.s = idx2s[i]; | 124 | vco.s = idx2s[i]; |
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c index 4e0dcaef6eb2..181ef1ead5b8 100644 --- a/arch/arm/common/locomo.c +++ b/arch/arm/common/locomo.c | |||
@@ -121,6 +121,13 @@ static struct locomo_dev_info locomo_devices[] = { | |||
121 | .offset = 0, | 121 | .offset = 0, |
122 | .length = 0, | 122 | .length = 0, |
123 | }, | 123 | }, |
124 | { | ||
125 | .devid = LOCOMO_DEVID_SPI, | ||
126 | .irq = {}, | ||
127 | .name = "locomo-spi", | ||
128 | .offset = LOCOMO_SPI, | ||
129 | .length = 0x30, | ||
130 | }, | ||
124 | }; | 131 | }; |
125 | 132 | ||
126 | 133 | ||
@@ -374,7 +381,7 @@ static void locomo_spi_handler(unsigned int irq, struct irqdesc *desc, | |||
374 | struct irqdesc *d; | 381 | struct irqdesc *d; |
375 | void __iomem *mapbase = get_irq_chipdata(irq); | 382 | void __iomem *mapbase = get_irq_chipdata(irq); |
376 | 383 | ||
377 | req = locomo_readl(mapbase + LOCOMO_SPIIR) & 0x000F; | 384 | req = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIR) & 0x000F; |
378 | if (req) { | 385 | if (req) { |
379 | irq = LOCOMO_IRQ_SPI_START; | 386 | irq = LOCOMO_IRQ_SPI_START; |
380 | d = irq_desc + irq; | 387 | d = irq_desc + irq; |
@@ -391,35 +398,35 @@ static void locomo_spi_ack_irq(unsigned int irq) | |||
391 | { | 398 | { |
392 | void __iomem *mapbase = get_irq_chipdata(irq); | 399 | void __iomem *mapbase = get_irq_chipdata(irq); |
393 | unsigned int r; | 400 | unsigned int r; |
394 | r = locomo_readl(mapbase + LOCOMO_SPIWE); | 401 | r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIWE); |
395 | r |= (0x0001 << (irq - LOCOMO_IRQ_SPI_START)); | 402 | r |= (0x0001 << (irq - LOCOMO_IRQ_SPI_START)); |
396 | locomo_writel(r, mapbase + LOCOMO_SPIWE); | 403 | locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIWE); |
397 | 404 | ||
398 | r = locomo_readl(mapbase + LOCOMO_SPIIS); | 405 | r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIS); |
399 | r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START)); | 406 | r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START)); |
400 | locomo_writel(r, mapbase + LOCOMO_SPIIS); | 407 | locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIIS); |
401 | 408 | ||
402 | r = locomo_readl(mapbase + LOCOMO_SPIWE); | 409 | r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIWE); |
403 | r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START)); | 410 | r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START)); |
404 | locomo_writel(r, mapbase + LOCOMO_SPIWE); | 411 | locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIWE); |
405 | } | 412 | } |
406 | 413 | ||
407 | static void locomo_spi_mask_irq(unsigned int irq) | 414 | static void locomo_spi_mask_irq(unsigned int irq) |
408 | { | 415 | { |
409 | void __iomem *mapbase = get_irq_chipdata(irq); | 416 | void __iomem *mapbase = get_irq_chipdata(irq); |
410 | unsigned int r; | 417 | unsigned int r; |
411 | r = locomo_readl(mapbase + LOCOMO_SPIIE); | 418 | r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIE); |
412 | r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START)); | 419 | r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START)); |
413 | locomo_writel(r, mapbase + LOCOMO_SPIIE); | 420 | locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIIE); |
414 | } | 421 | } |
415 | 422 | ||
416 | static void locomo_spi_unmask_irq(unsigned int irq) | 423 | static void locomo_spi_unmask_irq(unsigned int irq) |
417 | { | 424 | { |
418 | void __iomem *mapbase = get_irq_chipdata(irq); | 425 | void __iomem *mapbase = get_irq_chipdata(irq); |
419 | unsigned int r; | 426 | unsigned int r; |
420 | r = locomo_readl(mapbase + LOCOMO_SPIIE); | 427 | r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIE); |
421 | r |= (0x0001 << (irq - LOCOMO_IRQ_SPI_START)); | 428 | r |= (0x0001 << (irq - LOCOMO_IRQ_SPI_START)); |
422 | locomo_writel(r, mapbase + LOCOMO_SPIIE); | 429 | locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIIE); |
423 | } | 430 | } |
424 | 431 | ||
425 | static struct irq_chip locomo_spi_chip = { | 432 | static struct irq_chip locomo_spi_chip = { |
@@ -814,12 +821,15 @@ static inline struct locomo *locomo_chip_driver(struct locomo_dev *ldev) | |||
814 | return (struct locomo *)dev_get_drvdata(ldev->dev.parent); | 821 | return (struct locomo *)dev_get_drvdata(ldev->dev.parent); |
815 | } | 822 | } |
816 | 823 | ||
817 | void locomo_gpio_set_dir(struct locomo_dev *ldev, unsigned int bits, unsigned int dir) | 824 | void locomo_gpio_set_dir(struct device *dev, unsigned int bits, unsigned int dir) |
818 | { | 825 | { |
819 | struct locomo *lchip = locomo_chip_driver(ldev); | 826 | struct locomo *lchip = dev_get_drvdata(dev); |
820 | unsigned long flags; | 827 | unsigned long flags; |
821 | unsigned int r; | 828 | unsigned int r; |
822 | 829 | ||
830 | if (!lchip) | ||
831 | return; | ||
832 | |||
823 | spin_lock_irqsave(&lchip->lock, flags); | 833 | spin_lock_irqsave(&lchip->lock, flags); |
824 | 834 | ||
825 | r = locomo_readl(lchip->base + LOCOMO_GPD); | 835 | r = locomo_readl(lchip->base + LOCOMO_GPD); |
@@ -836,12 +846,15 @@ void locomo_gpio_set_dir(struct locomo_dev *ldev, unsigned int bits, unsigned in | |||
836 | spin_unlock_irqrestore(&lchip->lock, flags); | 846 | spin_unlock_irqrestore(&lchip->lock, flags); |
837 | } | 847 | } |
838 | 848 | ||
839 | unsigned int locomo_gpio_read_level(struct locomo_dev *ldev, unsigned int bits) | 849 | int locomo_gpio_read_level(struct device *dev, unsigned int bits) |
840 | { | 850 | { |
841 | struct locomo *lchip = locomo_chip_driver(ldev); | 851 | struct locomo *lchip = dev_get_drvdata(dev); |
842 | unsigned long flags; | 852 | unsigned long flags; |
843 | unsigned int ret; | 853 | unsigned int ret; |
844 | 854 | ||
855 | if (!lchip) | ||
856 | return -ENODEV; | ||
857 | |||
845 | spin_lock_irqsave(&lchip->lock, flags); | 858 | spin_lock_irqsave(&lchip->lock, flags); |
846 | ret = locomo_readl(lchip->base + LOCOMO_GPL); | 859 | ret = locomo_readl(lchip->base + LOCOMO_GPL); |
847 | spin_unlock_irqrestore(&lchip->lock, flags); | 860 | spin_unlock_irqrestore(&lchip->lock, flags); |
@@ -850,12 +863,15 @@ unsigned int locomo_gpio_read_level(struct locomo_dev *ldev, unsigned int bits) | |||
850 | return ret; | 863 | return ret; |
851 | } | 864 | } |
852 | 865 | ||
853 | unsigned int locomo_gpio_read_output(struct locomo_dev *ldev, unsigned int bits) | 866 | int locomo_gpio_read_output(struct device *dev, unsigned int bits) |
854 | { | 867 | { |
855 | struct locomo *lchip = locomo_chip_driver(ldev); | 868 | struct locomo *lchip = dev_get_drvdata(dev); |
856 | unsigned long flags; | 869 | unsigned long flags; |
857 | unsigned int ret; | 870 | unsigned int ret; |
858 | 871 | ||
872 | if (!lchip) | ||
873 | return -ENODEV; | ||
874 | |||
859 | spin_lock_irqsave(&lchip->lock, flags); | 875 | spin_lock_irqsave(&lchip->lock, flags); |
860 | ret = locomo_readl(lchip->base + LOCOMO_GPO); | 876 | ret = locomo_readl(lchip->base + LOCOMO_GPO); |
861 | spin_unlock_irqrestore(&lchip->lock, flags); | 877 | spin_unlock_irqrestore(&lchip->lock, flags); |
@@ -864,12 +880,15 @@ unsigned int locomo_gpio_read_output(struct locomo_dev *ldev, unsigned int bits) | |||
864 | return ret; | 880 | return ret; |
865 | } | 881 | } |
866 | 882 | ||
867 | void locomo_gpio_write(struct locomo_dev *ldev, unsigned int bits, unsigned int set) | 883 | void locomo_gpio_write(struct device *dev, unsigned int bits, unsigned int set) |
868 | { | 884 | { |
869 | struct locomo *lchip = locomo_chip_driver(ldev); | 885 | struct locomo *lchip = dev_get_drvdata(dev); |
870 | unsigned long flags; | 886 | unsigned long flags; |
871 | unsigned int r; | 887 | unsigned int r; |
872 | 888 | ||
889 | if (!lchip) | ||
890 | return; | ||
891 | |||
873 | spin_lock_irqsave(&lchip->lock, flags); | 892 | spin_lock_irqsave(&lchip->lock, flags); |
874 | 893 | ||
875 | r = locomo_readl(lchip->base + LOCOMO_GPO); | 894 | r = locomo_readl(lchip->base + LOCOMO_GPO); |
@@ -1058,9 +1077,9 @@ void locomo_frontlight_set(struct locomo_dev *dev, int duty, int vr, int bpwf) | |||
1058 | struct locomo *lchip = locomo_chip_driver(dev); | 1077 | struct locomo *lchip = locomo_chip_driver(dev); |
1059 | 1078 | ||
1060 | if (vr) | 1079 | if (vr) |
1061 | locomo_gpio_write(dev, LOCOMO_GPIO_FL_VR, 1); | 1080 | locomo_gpio_write(dev->dev.parent, LOCOMO_GPIO_FL_VR, 1); |
1062 | else | 1081 | else |
1063 | locomo_gpio_write(dev, LOCOMO_GPIO_FL_VR, 0); | 1082 | locomo_gpio_write(dev->dev.parent, LOCOMO_GPIO_FL_VR, 0); |
1064 | 1083 | ||
1065 | spin_lock_irqsave(&lchip->lock, flags); | 1084 | spin_lock_irqsave(&lchip->lock, flags); |
1066 | locomo_writel(bpwf, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS); | 1085 | locomo_writel(bpwf, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS); |
diff --git a/arch/arm/common/sharpsl_pm.c b/arch/arm/common/sharpsl_pm.c index 59b5ddec480f..f412dedda684 100644 --- a/arch/arm/common/sharpsl_pm.c +++ b/arch/arm/common/sharpsl_pm.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #define SHARPSL_CHARGE_FINISH_TIME (msecs_to_jiffies(10*60*1000)) /* 10 min */ | 40 | #define SHARPSL_CHARGE_FINISH_TIME (msecs_to_jiffies(10*60*1000)) /* 10 min */ |
41 | #define SHARPSL_BATCHK_TIME (msecs_to_jiffies(15*1000)) /* 15 sec */ | 41 | #define SHARPSL_BATCHK_TIME (msecs_to_jiffies(15*1000)) /* 15 sec */ |
42 | #define SHARPSL_BATCHK_TIME_SUSPEND (60*10) /* 10 min */ | 42 | #define SHARPSL_BATCHK_TIME_SUSPEND (60*10) /* 10 min */ |
43 | |||
43 | #define SHARPSL_WAIT_CO_TIME 15 /* 15 sec */ | 44 | #define SHARPSL_WAIT_CO_TIME 15 /* 15 sec */ |
44 | #define SHARPSL_WAIT_DISCHARGE_ON 100 /* 100 msec */ | 45 | #define SHARPSL_WAIT_DISCHARGE_ON 100 /* 100 msec */ |
45 | #define SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP 10 /* 10 msec */ | 46 | #define SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP 10 /* 10 msec */ |
@@ -575,6 +576,9 @@ static int corgi_pxa_pm_enter(suspend_state_t state) | |||
575 | while (corgi_enter_suspend(alarm_time,alarm_status,state)) | 576 | while (corgi_enter_suspend(alarm_time,alarm_status,state)) |
576 | {} | 577 | {} |
577 | 578 | ||
579 | if (sharpsl_pm.machinfo->earlyresume) | ||
580 | sharpsl_pm.machinfo->earlyresume(); | ||
581 | |||
578 | dev_dbg(sharpsl_pm.dev, "SharpSL resuming...\n"); | 582 | dev_dbg(sharpsl_pm.dev, "SharpSL resuming...\n"); |
579 | 583 | ||
580 | return 0; | 584 | return 0; |
diff --git a/arch/arm/kernel/apm.c b/arch/arm/kernel/apm.c index 33c55689f999..ecf4f9472d94 100644 --- a/arch/arm/kernel/apm.c +++ b/arch/arm/kernel/apm.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/list.h> | 25 | #include <linux/list.h> |
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/completion.h> | 27 | #include <linux/completion.h> |
28 | #include <linux/kthread.h> | ||
28 | 29 | ||
29 | #include <asm/apm.h> /* apm_power_info */ | 30 | #include <asm/apm.h> /* apm_power_info */ |
30 | #include <asm/system.h> | 31 | #include <asm/system.h> |
@@ -80,7 +81,7 @@ struct apm_user { | |||
80 | */ | 81 | */ |
81 | static int suspends_pending; | 82 | static int suspends_pending; |
82 | static int apm_disabled; | 83 | static int apm_disabled; |
83 | static int arm_apm_active; | 84 | static struct task_struct *kapmd_tsk; |
84 | 85 | ||
85 | static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue); | 86 | static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue); |
86 | static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); | 87 | static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); |
@@ -97,7 +98,6 @@ static LIST_HEAD(apm_user_list); | |||
97 | * to be suspending the system. | 98 | * to be suspending the system. |
98 | */ | 99 | */ |
99 | static DECLARE_WAIT_QUEUE_HEAD(kapmd_wait); | 100 | static DECLARE_WAIT_QUEUE_HEAD(kapmd_wait); |
100 | static DECLARE_COMPLETION(kapmd_exit); | ||
101 | static DEFINE_SPINLOCK(kapmd_queue_lock); | 101 | static DEFINE_SPINLOCK(kapmd_queue_lock); |
102 | static struct apm_queue kapmd_queue; | 102 | static struct apm_queue kapmd_queue; |
103 | 103 | ||
@@ -468,16 +468,13 @@ static int apm_get_info(char *buf, char **start, off_t fpos, int length) | |||
468 | 468 | ||
469 | static int kapmd(void *arg) | 469 | static int kapmd(void *arg) |
470 | { | 470 | { |
471 | daemonize("kapmd"); | ||
472 | current->flags |= PF_NOFREEZE; | ||
473 | |||
474 | do { | 471 | do { |
475 | apm_event_t event; | 472 | apm_event_t event; |
476 | 473 | ||
477 | wait_event_interruptible(kapmd_wait, | 474 | wait_event_interruptible(kapmd_wait, |
478 | !queue_empty(&kapmd_queue) || !arm_apm_active); | 475 | !queue_empty(&kapmd_queue) || kthread_should_stop()); |
479 | 476 | ||
480 | if (!arm_apm_active) | 477 | if (kthread_should_stop()) |
481 | break; | 478 | break; |
482 | 479 | ||
483 | spin_lock_irq(&kapmd_queue_lock); | 480 | spin_lock_irq(&kapmd_queue_lock); |
@@ -508,7 +505,7 @@ static int kapmd(void *arg) | |||
508 | } | 505 | } |
509 | } while (1); | 506 | } while (1); |
510 | 507 | ||
511 | complete_and_exit(&kapmd_exit, 0); | 508 | return 0; |
512 | } | 509 | } |
513 | 510 | ||
514 | static int __init apm_init(void) | 511 | static int __init apm_init(void) |
@@ -520,13 +517,14 @@ static int __init apm_init(void) | |||
520 | return -ENODEV; | 517 | return -ENODEV; |
521 | } | 518 | } |
522 | 519 | ||
523 | arm_apm_active = 1; | 520 | kapmd_tsk = kthread_create(kapmd, NULL, "kapmd"); |
524 | 521 | if (IS_ERR(kapmd_tsk)) { | |
525 | ret = kernel_thread(kapmd, NULL, CLONE_KERNEL); | 522 | ret = PTR_ERR(kapmd_tsk); |
526 | if (ret < 0) { | 523 | kapmd_tsk = NULL; |
527 | arm_apm_active = 0; | ||
528 | return ret; | 524 | return ret; |
529 | } | 525 | } |
526 | kapmd_tsk->flags |= PF_NOFREEZE; | ||
527 | wake_up_process(kapmd_tsk); | ||
530 | 528 | ||
531 | #ifdef CONFIG_PROC_FS | 529 | #ifdef CONFIG_PROC_FS |
532 | create_proc_info_entry("apm", 0, NULL, apm_get_info); | 530 | create_proc_info_entry("apm", 0, NULL, apm_get_info); |
@@ -535,10 +533,7 @@ static int __init apm_init(void) | |||
535 | ret = misc_register(&apm_device); | 533 | ret = misc_register(&apm_device); |
536 | if (ret != 0) { | 534 | if (ret != 0) { |
537 | remove_proc_entry("apm", NULL); | 535 | remove_proc_entry("apm", NULL); |
538 | 536 | kthread_stop(kapmd_tsk); | |
539 | arm_apm_active = 0; | ||
540 | wake_up(&kapmd_wait); | ||
541 | wait_for_completion(&kapmd_exit); | ||
542 | } | 537 | } |
543 | 538 | ||
544 | return ret; | 539 | return ret; |
@@ -549,9 +544,7 @@ static void __exit apm_exit(void) | |||
549 | misc_deregister(&apm_device); | 544 | misc_deregister(&apm_device); |
550 | remove_proc_entry("apm", NULL); | 545 | remove_proc_entry("apm", NULL); |
551 | 546 | ||
552 | arm_apm_active = 0; | 547 | kthread_stop(kapmd_tsk); |
553 | wake_up(&kapmd_wait); | ||
554 | wait_for_completion(&kapmd_exit); | ||
555 | } | 548 | } |
556 | 549 | ||
557 | module_init(apm_init); | 550 | module_init(apm_init); |
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index 09a67d771857..d4dceb5f06e9 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c | |||
@@ -69,10 +69,12 @@ EXPORT_SYMBOL(profile_pc); | |||
69 | */ | 69 | */ |
70 | int (*set_rtc)(void); | 70 | int (*set_rtc)(void); |
71 | 71 | ||
72 | #ifndef CONFIG_GENERIC_TIME | ||
72 | static unsigned long dummy_gettimeoffset(void) | 73 | static unsigned long dummy_gettimeoffset(void) |
73 | { | 74 | { |
74 | return 0; | 75 | return 0; |
75 | } | 76 | } |
77 | #endif | ||
76 | 78 | ||
77 | /* | 79 | /* |
78 | * Scheduler clock - returns current time in nanosec units. | 80 | * Scheduler clock - returns current time in nanosec units. |
@@ -230,6 +232,7 @@ static inline void do_leds(void) | |||
230 | #define do_leds() | 232 | #define do_leds() |
231 | #endif | 233 | #endif |
232 | 234 | ||
235 | #ifndef CONFIG_GENERIC_TIME | ||
233 | void do_gettimeofday(struct timeval *tv) | 236 | void do_gettimeofday(struct timeval *tv) |
234 | { | 237 | { |
235 | unsigned long flags; | 238 | unsigned long flags; |
@@ -291,6 +294,7 @@ int do_settimeofday(struct timespec *tv) | |||
291 | } | 294 | } |
292 | 295 | ||
293 | EXPORT_SYMBOL(do_settimeofday); | 296 | EXPORT_SYMBOL(do_settimeofday); |
297 | #endif /* !CONFIG_GENERIC_TIME */ | ||
294 | 298 | ||
295 | /** | 299 | /** |
296 | * save_time_delta - Save the offset between system time and RTC time | 300 | * save_time_delta - Save the offset between system time and RTC time |
@@ -500,8 +504,10 @@ device_initcall(timer_init_sysfs); | |||
500 | 504 | ||
501 | void __init time_init(void) | 505 | void __init time_init(void) |
502 | { | 506 | { |
507 | #ifndef CONFIG_GENERIC_TIME | ||
503 | if (system_timer->offset == NULL) | 508 | if (system_timer->offset == NULL) |
504 | system_timer->offset = dummy_gettimeoffset; | 509 | system_timer->offset = dummy_gettimeoffset; |
510 | #endif | ||
505 | system_timer->init(); | 511 | system_timer->init(); |
506 | 512 | ||
507 | #ifdef CONFIG_NO_IDLE_HZ | 513 | #ifdef CONFIG_NO_IDLE_HZ |
diff --git a/arch/arm/mach-at91rm9200/at91rm9200.c b/arch/arm/mach-at91rm9200/at91rm9200.c index 0985b1c42c7c..dcf6136fedf9 100644 --- a/arch/arm/mach-at91rm9200/at91rm9200.c +++ b/arch/arm/mach-at91rm9200/at91rm9200.c | |||
@@ -17,6 +17,7 @@ | |||
17 | 17 | ||
18 | #include <asm/hardware.h> | 18 | #include <asm/hardware.h> |
19 | #include "generic.h" | 19 | #include "generic.h" |
20 | #include "clock.h" | ||
20 | 21 | ||
21 | static struct map_desc at91rm9200_io_desc[] __initdata = { | 22 | static struct map_desc at91rm9200_io_desc[] __initdata = { |
22 | { | 23 | { |
@@ -26,87 +27,224 @@ static struct map_desc at91rm9200_io_desc[] __initdata = { | |||
26 | .type = MT_DEVICE, | 27 | .type = MT_DEVICE, |
27 | }, { | 28 | }, { |
28 | .virtual = AT91_VA_BASE_SPI, | 29 | .virtual = AT91_VA_BASE_SPI, |
29 | .pfn = __phys_to_pfn(AT91_BASE_SPI), | 30 | .pfn = __phys_to_pfn(AT91RM9200_BASE_SPI), |
30 | .length = SZ_16K, | ||
31 | .type = MT_DEVICE, | ||
32 | }, { | ||
33 | .virtual = AT91_VA_BASE_SSC2, | ||
34 | .pfn = __phys_to_pfn(AT91_BASE_SSC2), | ||
35 | .length = SZ_16K, | ||
36 | .type = MT_DEVICE, | ||
37 | }, { | ||
38 | .virtual = AT91_VA_BASE_SSC1, | ||
39 | .pfn = __phys_to_pfn(AT91_BASE_SSC1), | ||
40 | .length = SZ_16K, | ||
41 | .type = MT_DEVICE, | ||
42 | }, { | ||
43 | .virtual = AT91_VA_BASE_SSC0, | ||
44 | .pfn = __phys_to_pfn(AT91_BASE_SSC0), | ||
45 | .length = SZ_16K, | ||
46 | .type = MT_DEVICE, | ||
47 | }, { | ||
48 | .virtual = AT91_VA_BASE_US3, | ||
49 | .pfn = __phys_to_pfn(AT91_BASE_US3), | ||
50 | .length = SZ_16K, | ||
51 | .type = MT_DEVICE, | ||
52 | }, { | ||
53 | .virtual = AT91_VA_BASE_US2, | ||
54 | .pfn = __phys_to_pfn(AT91_BASE_US2), | ||
55 | .length = SZ_16K, | ||
56 | .type = MT_DEVICE, | ||
57 | }, { | ||
58 | .virtual = AT91_VA_BASE_US1, | ||
59 | .pfn = __phys_to_pfn(AT91_BASE_US1), | ||
60 | .length = SZ_16K, | ||
61 | .type = MT_DEVICE, | ||
62 | }, { | ||
63 | .virtual = AT91_VA_BASE_US0, | ||
64 | .pfn = __phys_to_pfn(AT91_BASE_US0), | ||
65 | .length = SZ_16K, | 31 | .length = SZ_16K, |
66 | .type = MT_DEVICE, | 32 | .type = MT_DEVICE, |
67 | }, { | 33 | }, { |
68 | .virtual = AT91_VA_BASE_EMAC, | 34 | .virtual = AT91_VA_BASE_EMAC, |
69 | .pfn = __phys_to_pfn(AT91_BASE_EMAC), | 35 | .pfn = __phys_to_pfn(AT91RM9200_BASE_EMAC), |
70 | .length = SZ_16K, | 36 | .length = SZ_16K, |
71 | .type = MT_DEVICE, | 37 | .type = MT_DEVICE, |
72 | }, { | 38 | }, { |
73 | .virtual = AT91_VA_BASE_TWI, | 39 | .virtual = AT91_VA_BASE_TWI, |
74 | .pfn = __phys_to_pfn(AT91_BASE_TWI), | 40 | .pfn = __phys_to_pfn(AT91RM9200_BASE_TWI), |
75 | .length = SZ_16K, | 41 | .length = SZ_16K, |
76 | .type = MT_DEVICE, | 42 | .type = MT_DEVICE, |
77 | }, { | 43 | }, { |
78 | .virtual = AT91_VA_BASE_MCI, | 44 | .virtual = AT91_VA_BASE_MCI, |
79 | .pfn = __phys_to_pfn(AT91_BASE_MCI), | 45 | .pfn = __phys_to_pfn(AT91RM9200_BASE_MCI), |
80 | .length = SZ_16K, | 46 | .length = SZ_16K, |
81 | .type = MT_DEVICE, | 47 | .type = MT_DEVICE, |
82 | }, { | 48 | }, { |
83 | .virtual = AT91_VA_BASE_UDP, | 49 | .virtual = AT91_VA_BASE_UDP, |
84 | .pfn = __phys_to_pfn(AT91_BASE_UDP), | 50 | .pfn = __phys_to_pfn(AT91RM9200_BASE_UDP), |
85 | .length = SZ_16K, | ||
86 | .type = MT_DEVICE, | ||
87 | }, { | ||
88 | .virtual = AT91_VA_BASE_TCB1, | ||
89 | .pfn = __phys_to_pfn(AT91_BASE_TCB1), | ||
90 | .length = SZ_16K, | ||
91 | .type = MT_DEVICE, | ||
92 | }, { | ||
93 | .virtual = AT91_VA_BASE_TCB0, | ||
94 | .pfn = __phys_to_pfn(AT91_BASE_TCB0), | ||
95 | .length = SZ_16K, | 51 | .length = SZ_16K, |
96 | .type = MT_DEVICE, | 52 | .type = MT_DEVICE, |
97 | }, { | 53 | }, { |
98 | .virtual = AT91_SRAM_VIRT_BASE, | 54 | .virtual = AT91_SRAM_VIRT_BASE, |
99 | .pfn = __phys_to_pfn(AT91_SRAM_BASE), | 55 | .pfn = __phys_to_pfn(AT91RM9200_SRAM_BASE), |
100 | .length = AT91_SRAM_SIZE, | 56 | .length = AT91RM9200_SRAM_SIZE, |
101 | .type = MT_DEVICE, | 57 | .type = MT_DEVICE, |
102 | }, | 58 | }, |
103 | }; | 59 | }; |
104 | 60 | ||
105 | void __init at91rm9200_map_io(void) | 61 | /* -------------------------------------------------------------------- |
62 | * Clocks | ||
63 | * -------------------------------------------------------------------- */ | ||
64 | |||
65 | /* | ||
66 | * The peripheral clocks. | ||
67 | */ | ||
68 | static struct clk udc_clk = { | ||
69 | .name = "udc_clk", | ||
70 | .pmc_mask = 1 << AT91RM9200_ID_UDP, | ||
71 | .type = CLK_TYPE_PERIPHERAL, | ||
72 | }; | ||
73 | static struct clk ohci_clk = { | ||
74 | .name = "ohci_clk", | ||
75 | .pmc_mask = 1 << AT91RM9200_ID_UHP, | ||
76 | .type = CLK_TYPE_PERIPHERAL, | ||
77 | }; | ||
78 | static struct clk ether_clk = { | ||
79 | .name = "ether_clk", | ||
80 | .pmc_mask = 1 << AT91RM9200_ID_EMAC, | ||
81 | .type = CLK_TYPE_PERIPHERAL, | ||
82 | }; | ||
83 | static struct clk mmc_clk = { | ||
84 | .name = "mci_clk", | ||
85 | .pmc_mask = 1 << AT91RM9200_ID_MCI, | ||
86 | .type = CLK_TYPE_PERIPHERAL, | ||
87 | }; | ||
88 | static struct clk twi_clk = { | ||
89 | .name = "twi_clk", | ||
90 | .pmc_mask = 1 << AT91RM9200_ID_TWI, | ||
91 | .type = CLK_TYPE_PERIPHERAL, | ||
92 | }; | ||
93 | static struct clk usart0_clk = { | ||
94 | .name = "usart0_clk", | ||
95 | .pmc_mask = 1 << AT91RM9200_ID_US0, | ||
96 | .type = CLK_TYPE_PERIPHERAL, | ||
97 | }; | ||
98 | static struct clk usart1_clk = { | ||
99 | .name = "usart1_clk", | ||
100 | .pmc_mask = 1 << AT91RM9200_ID_US1, | ||
101 | .type = CLK_TYPE_PERIPHERAL, | ||
102 | }; | ||
103 | static struct clk usart2_clk = { | ||
104 | .name = "usart2_clk", | ||
105 | .pmc_mask = 1 << AT91RM9200_ID_US2, | ||
106 | .type = CLK_TYPE_PERIPHERAL, | ||
107 | }; | ||
108 | static struct clk usart3_clk = { | ||
109 | .name = "usart3_clk", | ||
110 | .pmc_mask = 1 << AT91RM9200_ID_US3, | ||
111 | .type = CLK_TYPE_PERIPHERAL, | ||
112 | }; | ||
113 | static struct clk spi_clk = { | ||
114 | .name = "spi_clk", | ||
115 | .pmc_mask = 1 << AT91RM9200_ID_SPI, | ||
116 | .type = CLK_TYPE_PERIPHERAL, | ||
117 | }; | ||
118 | static struct clk pioA_clk = { | ||
119 | .name = "pioA_clk", | ||
120 | .pmc_mask = 1 << AT91RM9200_ID_PIOA, | ||
121 | .type = CLK_TYPE_PERIPHERAL, | ||
122 | }; | ||
123 | static struct clk pioB_clk = { | ||
124 | .name = "pioB_clk", | ||
125 | .pmc_mask = 1 << AT91RM9200_ID_PIOB, | ||
126 | .type = CLK_TYPE_PERIPHERAL, | ||
127 | }; | ||
128 | static struct clk pioC_clk = { | ||
129 | .name = "pioC_clk", | ||
130 | .pmc_mask = 1 << AT91RM9200_ID_PIOC, | ||
131 | .type = CLK_TYPE_PERIPHERAL, | ||
132 | }; | ||
133 | static struct clk pioD_clk = { | ||
134 | .name = "pioD_clk", | ||
135 | .pmc_mask = 1 << AT91RM9200_ID_PIOD, | ||
136 | .type = CLK_TYPE_PERIPHERAL, | ||
137 | }; | ||
138 | |||
139 | static struct clk *periph_clocks[] __initdata = { | ||
140 | &pioA_clk, | ||
141 | &pioB_clk, | ||
142 | &pioC_clk, | ||
143 | &pioD_clk, | ||
144 | &usart0_clk, | ||
145 | &usart1_clk, | ||
146 | &usart2_clk, | ||
147 | &usart3_clk, | ||
148 | &mmc_clk, | ||
149 | &udc_clk, | ||
150 | &twi_clk, | ||
151 | &spi_clk, | ||
152 | // ssc 0 .. ssc2 | ||
153 | // tc0 .. tc5 | ||
154 | &ohci_clk, | ||
155 | ðer_clk, | ||
156 | // irq0 .. irq6 | ||
157 | }; | ||
158 | |||
159 | /* | ||
160 | * The four programmable clocks. | ||
161 | * You must configure pin multiplexing to bring these signals out. | ||
162 | */ | ||
163 | static struct clk pck0 = { | ||
164 | .name = "pck0", | ||
165 | .pmc_mask = AT91_PMC_PCK0, | ||
166 | .type = CLK_TYPE_PROGRAMMABLE, | ||
167 | .id = 0, | ||
168 | }; | ||
169 | static struct clk pck1 = { | ||
170 | .name = "pck1", | ||
171 | .pmc_mask = AT91_PMC_PCK1, | ||
172 | .type = CLK_TYPE_PROGRAMMABLE, | ||
173 | .id = 1, | ||
174 | }; | ||
175 | static struct clk pck2 = { | ||
176 | .name = "pck2", | ||
177 | .pmc_mask = AT91_PMC_PCK2, | ||
178 | .type = CLK_TYPE_PROGRAMMABLE, | ||
179 | .id = 2, | ||
180 | }; | ||
181 | static struct clk pck3 = { | ||
182 | .name = "pck3", | ||
183 | .pmc_mask = AT91_PMC_PCK3, | ||
184 | .type = CLK_TYPE_PROGRAMMABLE, | ||
185 | .id = 3, | ||
186 | }; | ||
187 | |||
188 | static void __init at91rm9200_register_clocks(void) | ||
106 | { | 189 | { |
190 | int i; | ||
191 | |||
192 | for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) | ||
193 | clk_register(periph_clocks[i]); | ||
194 | |||
195 | clk_register(&pck0); | ||
196 | clk_register(&pck1); | ||
197 | clk_register(&pck2); | ||
198 | clk_register(&pck3); | ||
199 | } | ||
200 | |||
201 | /* -------------------------------------------------------------------- | ||
202 | * GPIO | ||
203 | * -------------------------------------------------------------------- */ | ||
204 | |||
205 | static struct at91_gpio_bank at91rm9200_gpio[] = { | ||
206 | { | ||
207 | .id = AT91RM9200_ID_PIOA, | ||
208 | .offset = AT91_PIOA, | ||
209 | .clock = &pioA_clk, | ||
210 | }, { | ||
211 | .id = AT91RM9200_ID_PIOB, | ||
212 | .offset = AT91_PIOB, | ||
213 | .clock = &pioB_clk, | ||
214 | }, { | ||
215 | .id = AT91RM9200_ID_PIOC, | ||
216 | .offset = AT91_PIOC, | ||
217 | .clock = &pioC_clk, | ||
218 | }, { | ||
219 | .id = AT91RM9200_ID_PIOD, | ||
220 | .offset = AT91_PIOD, | ||
221 | .clock = &pioD_clk, | ||
222 | } | ||
223 | }; | ||
224 | |||
225 | /* -------------------------------------------------------------------- | ||
226 | * AT91RM9200 processor initialization | ||
227 | * -------------------------------------------------------------------- */ | ||
228 | void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks) | ||
229 | { | ||
230 | /* Map peripherals */ | ||
107 | iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc)); | 231 | iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc)); |
232 | |||
233 | /* Init clock subsystem */ | ||
234 | at91_clock_init(main_clock); | ||
235 | |||
236 | /* Register the processor-specific clocks */ | ||
237 | at91rm9200_register_clocks(); | ||
238 | |||
239 | /* Initialize GPIO subsystem */ | ||
240 | at91_gpio_init(at91rm9200_gpio, banks); | ||
108 | } | 241 | } |
109 | 242 | ||
243 | |||
244 | /* -------------------------------------------------------------------- | ||
245 | * Interrupt initialization | ||
246 | * -------------------------------------------------------------------- */ | ||
247 | |||
110 | /* | 248 | /* |
111 | * The default interrupt priority levels (0 = lowest, 7 = highest). | 249 | * The default interrupt priority levels (0 = lowest, 7 = highest). |
112 | */ | 250 | */ |
@@ -145,10 +283,14 @@ static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = { | |||
145 | 0 /* Advanced Interrupt Controller (IRQ6) */ | 283 | 0 /* Advanced Interrupt Controller (IRQ6) */ |
146 | }; | 284 | }; |
147 | 285 | ||
148 | void __init at91rm9200_init_irq(unsigned int priority[NR_AIC_IRQS]) | 286 | void __init at91rm9200_init_interrupts(unsigned int priority[NR_AIC_IRQS]) |
149 | { | 287 | { |
150 | if (!priority) | 288 | if (!priority) |
151 | priority = at91rm9200_default_irq_priority; | 289 | priority = at91rm9200_default_irq_priority; |
152 | 290 | ||
291 | /* Initialize the AIC interrupt controller */ | ||
153 | at91_aic_init(priority); | 292 | at91_aic_init(priority); |
293 | |||
294 | /* Enable GPIO interrupts */ | ||
295 | at91_gpio_irq_setup(); | ||
154 | } | 296 | } |
diff --git a/arch/arm/mach-at91rm9200/board-1arm.c b/arch/arm/mach-at91rm9200/board-1arm.c index dc79e0992af7..36eecd7161f5 100644 --- a/arch/arm/mach-at91rm9200/board-1arm.c +++ b/arch/arm/mach-at91rm9200/board-1arm.c | |||
@@ -34,20 +34,11 @@ | |||
34 | #include <asm/mach/map.h> | 34 | #include <asm/mach/map.h> |
35 | #include <asm/mach/irq.h> | 35 | #include <asm/mach/irq.h> |
36 | 36 | ||
37 | #include <asm/hardware.h> | ||
38 | #include <asm/arch/board.h> | 37 | #include <asm/arch/board.h> |
39 | #include <asm/arch/gpio.h> | 38 | #include <asm/arch/gpio.h> |
40 | 39 | ||
41 | #include "generic.h" | 40 | #include "generic.h" |
42 | 41 | ||
43 | static void __init onearm_init_irq(void) | ||
44 | { | ||
45 | /* Initialize AIC controller */ | ||
46 | at91rm9200_init_irq(NULL); | ||
47 | |||
48 | /* Set up the GPIO interrupts */ | ||
49 | at91_gpio_irq_setup(PQFP_GPIO_BANKS); | ||
50 | } | ||
51 | 42 | ||
52 | /* | 43 | /* |
53 | * Serial port configuration. | 44 | * Serial port configuration. |
@@ -62,15 +53,18 @@ static struct at91_uart_config __initdata onearm_uart_config = { | |||
62 | 53 | ||
63 | static void __init onearm_map_io(void) | 54 | static void __init onearm_map_io(void) |
64 | { | 55 | { |
65 | at91rm9200_map_io(); | 56 | /* Initialize processor: 18.432 MHz crystal */ |
66 | 57 | at91rm9200_initialize(18432000, AT91RM9200_PQFP); | |
67 | /* Initialize clocks: 18.432 MHz crystal */ | ||
68 | at91_clock_init(18432000); | ||
69 | 58 | ||
70 | /* Setup the serial ports and console */ | 59 | /* Setup the serial ports and console */ |
71 | at91_init_serial(&onearm_uart_config); | 60 | at91_init_serial(&onearm_uart_config); |
72 | } | 61 | } |
73 | 62 | ||
63 | static void __init onearm_init_irq(void) | ||
64 | { | ||
65 | at91rm9200_init_interrupts(NULL); | ||
66 | } | ||
67 | |||
74 | static struct at91_eth_data __initdata onearm_eth_data = { | 68 | static struct at91_eth_data __initdata onearm_eth_data = { |
75 | .phy_irq_pin = AT91_PIN_PC4, | 69 | .phy_irq_pin = AT91_PIN_PC4, |
76 | .is_rmii = 1, | 70 | .is_rmii = 1, |
diff --git a/arch/arm/mach-at91rm9200/board-carmeva.c b/arch/arm/mach-at91rm9200/board-carmeva.c index 2c138b542ebe..50e513681ae6 100644 --- a/arch/arm/mach-at91rm9200/board-carmeva.c +++ b/arch/arm/mach-at91rm9200/board-carmeva.c | |||
@@ -35,20 +35,11 @@ | |||
35 | #include <asm/mach/map.h> | 35 | #include <asm/mach/map.h> |
36 | #include <asm/mach/irq.h> | 36 | #include <asm/mach/irq.h> |
37 | 37 | ||
38 | #include <asm/hardware.h> | ||
39 | #include <asm/arch/board.h> | 38 | #include <asm/arch/board.h> |
40 | #include <asm/arch/gpio.h> | 39 | #include <asm/arch/gpio.h> |
41 | 40 | ||
42 | #include "generic.h" | 41 | #include "generic.h" |
43 | 42 | ||
44 | static void __init carmeva_init_irq(void) | ||
45 | { | ||
46 | /* Initialize AIC controller */ | ||
47 | at91rm9200_init_irq(NULL); | ||
48 | |||
49 | /* Set up the GPIO interrupts */ | ||
50 | at91_gpio_irq_setup(BGA_GPIO_BANKS); | ||
51 | } | ||
52 | 43 | ||
53 | /* | 44 | /* |
54 | * Serial port configuration. | 45 | * Serial port configuration. |
@@ -63,15 +54,19 @@ static struct at91_uart_config __initdata carmeva_uart_config = { | |||
63 | 54 | ||
64 | static void __init carmeva_map_io(void) | 55 | static void __init carmeva_map_io(void) |
65 | { | 56 | { |
66 | at91rm9200_map_io(); | 57 | /* Initialize processor: 20.000 MHz crystal */ |
67 | 58 | at91rm9200_initialize(20000000, AT91RM9200_BGA); | |
68 | /* Initialize clocks: 20.000 MHz crystal */ | ||
69 | at91_clock_init(20000000); | ||
70 | 59 | ||
71 | /* Setup the serial ports and console */ | 60 | /* Setup the serial ports and console */ |
72 | at91_init_serial(&carmeva_uart_config); | 61 | at91_init_serial(&carmeva_uart_config); |
73 | } | 62 | } |
74 | 63 | ||
64 | static void __init carmeva_init_irq(void) | ||
65 | { | ||
66 | at91rm9200_init_interrupts(NULL); | ||
67 | } | ||
68 | |||
69 | |||
75 | static struct at91_eth_data __initdata carmeva_eth_data = { | 70 | static struct at91_eth_data __initdata carmeva_eth_data = { |
76 | .phy_irq_pin = AT91_PIN_PC4, | 71 | .phy_irq_pin = AT91_PIN_PC4, |
77 | .is_rmii = 1, | 72 | .is_rmii = 1, |
diff --git a/arch/arm/mach-at91rm9200/board-csb337.c b/arch/arm/mach-at91rm9200/board-csb337.c index 794d3fbb449b..8eeae491ce71 100644 --- a/arch/arm/mach-at91rm9200/board-csb337.c +++ b/arch/arm/mach-at91rm9200/board-csb337.c | |||
@@ -34,20 +34,11 @@ | |||
34 | #include <asm/mach/map.h> | 34 | #include <asm/mach/map.h> |
35 | #include <asm/mach/irq.h> | 35 | #include <asm/mach/irq.h> |
36 | 36 | ||
37 | #include <asm/hardware.h> | ||
38 | #include <asm/arch/board.h> | 37 | #include <asm/arch/board.h> |
39 | #include <asm/arch/gpio.h> | 38 | #include <asm/arch/gpio.h> |
40 | 39 | ||
41 | #include "generic.h" | 40 | #include "generic.h" |
42 | 41 | ||
43 | static void __init csb337_init_irq(void) | ||
44 | { | ||
45 | /* Initialize AIC controller */ | ||
46 | at91rm9200_init_irq(NULL); | ||
47 | |||
48 | /* Set up the GPIO interrupts */ | ||
49 | at91_gpio_irq_setup(BGA_GPIO_BANKS); | ||
50 | } | ||
51 | 42 | ||
52 | /* | 43 | /* |
53 | * Serial port configuration. | 44 | * Serial port configuration. |
@@ -62,10 +53,8 @@ static struct at91_uart_config __initdata csb337_uart_config = { | |||
62 | 53 | ||
63 | static void __init csb337_map_io(void) | 54 | static void __init csb337_map_io(void) |
64 | { | 55 | { |
65 | at91rm9200_map_io(); | 56 | /* Initialize processor: 3.6864 MHz crystal */ |
66 | 57 | at91rm9200_initialize(3686400, AT91RM9200_BGA); | |
67 | /* Initialize clocks: 3.6864 MHz crystal */ | ||
68 | at91_clock_init(3686400); | ||
69 | 58 | ||
70 | /* Setup the LEDs */ | 59 | /* Setup the LEDs */ |
71 | at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1); | 60 | at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1); |
@@ -74,6 +63,11 @@ static void __init csb337_map_io(void) | |||
74 | at91_init_serial(&csb337_uart_config); | 63 | at91_init_serial(&csb337_uart_config); |
75 | } | 64 | } |
76 | 65 | ||
66 | static void __init csb337_init_irq(void) | ||
67 | { | ||
68 | at91rm9200_init_interrupts(NULL); | ||
69 | } | ||
70 | |||
77 | static struct at91_eth_data __initdata csb337_eth_data = { | 71 | static struct at91_eth_data __initdata csb337_eth_data = { |
78 | .phy_irq_pin = AT91_PIN_PC2, | 72 | .phy_irq_pin = AT91_PIN_PC2, |
79 | .is_rmii = 0, | 73 | .is_rmii = 0, |
diff --git a/arch/arm/mach-at91rm9200/board-csb637.c b/arch/arm/mach-at91rm9200/board-csb637.c index c8b6f334246a..a29fa0e822ce 100644 --- a/arch/arm/mach-at91rm9200/board-csb637.c +++ b/arch/arm/mach-at91rm9200/board-csb637.c | |||
@@ -33,20 +33,11 @@ | |||
33 | #include <asm/mach/map.h> | 33 | #include <asm/mach/map.h> |
34 | #include <asm/mach/irq.h> | 34 | #include <asm/mach/irq.h> |
35 | 35 | ||
36 | #include <asm/hardware.h> | ||
37 | #include <asm/arch/board.h> | 36 | #include <asm/arch/board.h> |
38 | #include <asm/arch/gpio.h> | 37 | #include <asm/arch/gpio.h> |
39 | 38 | ||
40 | #include "generic.h" | 39 | #include "generic.h" |
41 | 40 | ||
42 | static void __init csb637_init_irq(void) | ||
43 | { | ||
44 | /* Initialize AIC controller */ | ||
45 | at91rm9200_init_irq(NULL); | ||
46 | |||
47 | /* Set up the GPIO interrupts */ | ||
48 | at91_gpio_irq_setup(BGA_GPIO_BANKS); | ||
49 | } | ||
50 | 41 | ||
51 | /* | 42 | /* |
52 | * Serial port configuration. | 43 | * Serial port configuration. |
@@ -61,10 +52,8 @@ static struct at91_uart_config __initdata csb637_uart_config = { | |||
61 | 52 | ||
62 | static void __init csb637_map_io(void) | 53 | static void __init csb637_map_io(void) |
63 | { | 54 | { |
64 | at91rm9200_map_io(); | 55 | /* Initialize processor: 3.6864 MHz crystal */ |
65 | 56 | at91rm9200_initialize(3686400, AT91RM9200_BGA); | |
66 | /* Initialize clocks: 3.6864 MHz crystal */ | ||
67 | at91_clock_init(3686400); | ||
68 | 57 | ||
69 | /* Setup the LEDs */ | 58 | /* Setup the LEDs */ |
70 | at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2); | 59 | at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2); |
@@ -73,6 +62,11 @@ static void __init csb637_map_io(void) | |||
73 | at91_init_serial(&csb637_uart_config); | 62 | at91_init_serial(&csb637_uart_config); |
74 | } | 63 | } |
75 | 64 | ||
65 | static void __init csb637_init_irq(void) | ||
66 | { | ||
67 | at91rm9200_init_interrupts(NULL); | ||
68 | } | ||
69 | |||
76 | static struct at91_eth_data __initdata csb637_eth_data = { | 70 | static struct at91_eth_data __initdata csb637_eth_data = { |
77 | .phy_irq_pin = AT91_PIN_PC0, | 71 | .phy_irq_pin = AT91_PIN_PC0, |
78 | .is_rmii = 0, | 72 | .is_rmii = 0, |
diff --git a/arch/arm/mach-at91rm9200/board-dk.c b/arch/arm/mach-at91rm9200/board-dk.c index 65873037e02a..c699f3984d4b 100644 --- a/arch/arm/mach-at91rm9200/board-dk.c +++ b/arch/arm/mach-at91rm9200/board-dk.c | |||
@@ -37,20 +37,11 @@ | |||
37 | #include <asm/mach/map.h> | 37 | #include <asm/mach/map.h> |
38 | #include <asm/mach/irq.h> | 38 | #include <asm/mach/irq.h> |
39 | 39 | ||
40 | #include <asm/hardware.h> | ||
41 | #include <asm/arch/board.h> | 40 | #include <asm/arch/board.h> |
42 | #include <asm/arch/gpio.h> | 41 | #include <asm/arch/gpio.h> |
43 | 42 | ||
44 | #include "generic.h" | 43 | #include "generic.h" |
45 | 44 | ||
46 | static void __init dk_init_irq(void) | ||
47 | { | ||
48 | /* Initialize AIC controller */ | ||
49 | at91rm9200_init_irq(NULL); | ||
50 | |||
51 | /* Set up the GPIO interrupts */ | ||
52 | at91_gpio_irq_setup(BGA_GPIO_BANKS); | ||
53 | } | ||
54 | 45 | ||
55 | /* | 46 | /* |
56 | * Serial port configuration. | 47 | * Serial port configuration. |
@@ -65,10 +56,8 @@ static struct at91_uart_config __initdata dk_uart_config = { | |||
65 | 56 | ||
66 | static void __init dk_map_io(void) | 57 | static void __init dk_map_io(void) |
67 | { | 58 | { |
68 | at91rm9200_map_io(); | 59 | /* Initialize processor: 18.432 MHz crystal */ |
69 | 60 | at91rm9200_initialize(18432000, AT91RM9200_BGA); | |
70 | /* Initialize clocks: 18.432 MHz crystal */ | ||
71 | at91_clock_init(18432000); | ||
72 | 61 | ||
73 | /* Setup the LEDs */ | 62 | /* Setup the LEDs */ |
74 | at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2); | 63 | at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2); |
@@ -77,6 +66,11 @@ static void __init dk_map_io(void) | |||
77 | at91_init_serial(&dk_uart_config); | 66 | at91_init_serial(&dk_uart_config); |
78 | } | 67 | } |
79 | 68 | ||
69 | static void __init dk_init_irq(void) | ||
70 | { | ||
71 | at91rm9200_init_interrupts(NULL); | ||
72 | } | ||
73 | |||
80 | static struct at91_eth_data __initdata dk_eth_data = { | 74 | static struct at91_eth_data __initdata dk_eth_data = { |
81 | .phy_irq_pin = AT91_PIN_PC4, | 75 | .phy_irq_pin = AT91_PIN_PC4, |
82 | .is_rmii = 1, | 76 | .is_rmii = 1, |
@@ -128,6 +122,29 @@ static struct spi_board_info dk_spi_devices[] = { | |||
128 | #endif | 122 | #endif |
129 | }; | 123 | }; |
130 | 124 | ||
125 | static struct mtd_partition __initdata dk_nand_partition[] = { | ||
126 | { | ||
127 | .name = "NAND Partition 1", | ||
128 | .offset = 0, | ||
129 | .size = MTDPART_SIZ_FULL, | ||
130 | }, | ||
131 | }; | ||
132 | |||
133 | static struct mtd_partition *nand_partitions(int size, int *num_partitions) | ||
134 | { | ||
135 | *num_partitions = ARRAY_SIZE(dk_nand_partition); | ||
136 | return dk_nand_partition; | ||
137 | } | ||
138 | |||
139 | static struct at91_nand_data __initdata dk_nand_data = { | ||
140 | .ale = 22, | ||
141 | .cle = 21, | ||
142 | .det_pin = AT91_PIN_PB1, | ||
143 | .rdy_pin = AT91_PIN_PC2, | ||
144 | // .enable_pin = ... not there | ||
145 | .partition_info = nand_partitions, | ||
146 | }; | ||
147 | |||
131 | static void __init dk_board_init(void) | 148 | static void __init dk_board_init(void) |
132 | { | 149 | { |
133 | /* Serial */ | 150 | /* Serial */ |
@@ -153,6 +170,8 @@ static void __init dk_board_init(void) | |||
153 | at91_set_gpio_output(AT91_PIN_PB7, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */ | 170 | at91_set_gpio_output(AT91_PIN_PB7, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */ |
154 | at91_add_device_mmc(&dk_mmc_data); | 171 | at91_add_device_mmc(&dk_mmc_data); |
155 | #endif | 172 | #endif |
173 | /* NAND */ | ||
174 | at91_add_device_nand(&dk_nand_data); | ||
156 | /* VGA */ | 175 | /* VGA */ |
157 | // dk_add_device_video(); | 176 | // dk_add_device_video(); |
158 | } | 177 | } |
diff --git a/arch/arm/mach-at91rm9200/board-eb9200.c b/arch/arm/mach-at91rm9200/board-eb9200.c index a3e2df968a66..c6e0d51fbea0 100644 --- a/arch/arm/mach-at91rm9200/board-eb9200.c +++ b/arch/arm/mach-at91rm9200/board-eb9200.c | |||
@@ -35,20 +35,11 @@ | |||
35 | #include <asm/mach/map.h> | 35 | #include <asm/mach/map.h> |
36 | #include <asm/mach/irq.h> | 36 | #include <asm/mach/irq.h> |
37 | 37 | ||
38 | #include <asm/hardware.h> | ||
39 | #include <asm/arch/board.h> | 38 | #include <asm/arch/board.h> |
40 | #include <asm/arch/gpio.h> | 39 | #include <asm/arch/gpio.h> |
41 | 40 | ||
42 | #include "generic.h" | 41 | #include "generic.h" |
43 | 42 | ||
44 | static void __init eb9200_init_irq(void) | ||
45 | { | ||
46 | /* Initialize AIC controller */ | ||
47 | at91rm9200_init_irq(NULL); | ||
48 | |||
49 | /* Set up the GPIO interrupts */ | ||
50 | at91_gpio_irq_setup(BGA_GPIO_BANKS); | ||
51 | } | ||
52 | 43 | ||
53 | /* | 44 | /* |
54 | * Serial port configuration. | 45 | * Serial port configuration. |
@@ -63,15 +54,18 @@ static struct at91_uart_config __initdata eb9200_uart_config = { | |||
63 | 54 | ||
64 | static void __init eb9200_map_io(void) | 55 | static void __init eb9200_map_io(void) |
65 | { | 56 | { |
66 | at91rm9200_map_io(); | 57 | /* Initialize processor: 18.432 MHz crystal */ |
67 | 58 | at91rm9200_initialize(18432000, AT91RM9200_BGA); | |
68 | /* Initialize clocks: 18.432 MHz crystal */ | ||
69 | at91_clock_init(18432000); | ||
70 | 59 | ||
71 | /* Setup the serial ports and console */ | 60 | /* Setup the serial ports and console */ |
72 | at91_init_serial(&eb9200_uart_config); | 61 | at91_init_serial(&eb9200_uart_config); |
73 | } | 62 | } |
74 | 63 | ||
64 | static void __init eb9200_init_irq(void) | ||
65 | { | ||
66 | at91rm9200_init_interrupts(NULL); | ||
67 | } | ||
68 | |||
75 | static struct at91_eth_data __initdata eb9200_eth_data = { | 69 | static struct at91_eth_data __initdata eb9200_eth_data = { |
76 | .phy_irq_pin = AT91_PIN_PC4, | 70 | .phy_irq_pin = AT91_PIN_PC4, |
77 | .is_rmii = 1, | 71 | .is_rmii = 1, |
diff --git a/arch/arm/mach-at91rm9200/board-ek.c b/arch/arm/mach-at91rm9200/board-ek.c index 868192351dda..830eb7932178 100644 --- a/arch/arm/mach-at91rm9200/board-ek.c +++ b/arch/arm/mach-at91rm9200/board-ek.c | |||
@@ -37,20 +37,11 @@ | |||
37 | #include <asm/mach/map.h> | 37 | #include <asm/mach/map.h> |
38 | #include <asm/mach/irq.h> | 38 | #include <asm/mach/irq.h> |
39 | 39 | ||
40 | #include <asm/hardware.h> | ||
41 | #include <asm/arch/board.h> | 40 | #include <asm/arch/board.h> |
42 | #include <asm/arch/gpio.h> | 41 | #include <asm/arch/gpio.h> |
43 | 42 | ||
44 | #include "generic.h" | 43 | #include "generic.h" |
45 | 44 | ||
46 | static void __init ek_init_irq(void) | ||
47 | { | ||
48 | /* Initialize AIC controller */ | ||
49 | at91rm9200_init_irq(NULL); | ||
50 | |||
51 | /* Set up the GPIO interrupts */ | ||
52 | at91_gpio_irq_setup(BGA_GPIO_BANKS); | ||
53 | } | ||
54 | 45 | ||
55 | /* | 46 | /* |
56 | * Serial port configuration. | 47 | * Serial port configuration. |
@@ -65,10 +56,8 @@ static struct at91_uart_config __initdata ek_uart_config = { | |||
65 | 56 | ||
66 | static void __init ek_map_io(void) | 57 | static void __init ek_map_io(void) |
67 | { | 58 | { |
68 | at91rm9200_map_io(); | 59 | /* Initialize processor: 18.432 MHz crystal */ |
69 | 60 | at91rm9200_initialize(18432000, AT91RM9200_BGA); | |
70 | /* Initialize clocks: 18.432 MHz crystal */ | ||
71 | at91_clock_init(18432000); | ||
72 | 61 | ||
73 | /* Setup the LEDs */ | 62 | /* Setup the LEDs */ |
74 | at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2); | 63 | at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2); |
@@ -77,6 +66,11 @@ static void __init ek_map_io(void) | |||
77 | at91_init_serial(&ek_uart_config); | 66 | at91_init_serial(&ek_uart_config); |
78 | } | 67 | } |
79 | 68 | ||
69 | static void __init ek_init_irq(void) | ||
70 | { | ||
71 | at91rm9200_init_interrupts(NULL); | ||
72 | } | ||
73 | |||
80 | static struct at91_eth_data __initdata ek_eth_data = { | 74 | static struct at91_eth_data __initdata ek_eth_data = { |
81 | .phy_irq_pin = AT91_PIN_PC4, | 75 | .phy_irq_pin = AT91_PIN_PC4, |
82 | .is_rmii = 1, | 76 | .is_rmii = 1, |
diff --git a/arch/arm/mach-at91rm9200/board-kafa.c b/arch/arm/mach-at91rm9200/board-kafa.c index bf760c5e0c46..91e301924f2c 100644 --- a/arch/arm/mach-at91rm9200/board-kafa.c +++ b/arch/arm/mach-at91rm9200/board-kafa.c | |||
@@ -34,20 +34,11 @@ | |||
34 | #include <asm/mach/map.h> | 34 | #include <asm/mach/map.h> |
35 | #include <asm/mach/irq.h> | 35 | #include <asm/mach/irq.h> |
36 | 36 | ||
37 | #include <asm/hardware.h> | ||
38 | #include <asm/arch/board.h> | 37 | #include <asm/arch/board.h> |
39 | #include <asm/arch/gpio.h> | 38 | #include <asm/arch/gpio.h> |
40 | 39 | ||
41 | #include "generic.h" | 40 | #include "generic.h" |
42 | 41 | ||
43 | static void __init kafa_init_irq(void) | ||
44 | { | ||
45 | /* Initialize AIC controller */ | ||
46 | at91rm9200_init_irq(NULL); | ||
47 | |||
48 | /* Set up the GPIO interrupts */ | ||
49 | at91_gpio_irq_setup(PQFP_GPIO_BANKS); | ||
50 | } | ||
51 | 42 | ||
52 | /* | 43 | /* |
53 | * Serial port configuration. | 44 | * Serial port configuration. |
@@ -62,10 +53,8 @@ static struct at91_uart_config __initdata kafa_uart_config = { | |||
62 | 53 | ||
63 | static void __init kafa_map_io(void) | 54 | static void __init kafa_map_io(void) |
64 | { | 55 | { |
65 | at91rm9200_map_io(); | 56 | /* Initialize processor: 18.432 MHz crystal */ |
66 | 57 | at91rm9200_initialize(18432000, AT91RM9200_PQFP); | |
67 | /* Initialize clocks: 18.432 MHz crystal */ | ||
68 | at91_clock_init(18432000); | ||
69 | 58 | ||
70 | /* Set up the LEDs */ | 59 | /* Set up the LEDs */ |
71 | at91_init_leds(AT91_PIN_PB4, AT91_PIN_PB4); | 60 | at91_init_leds(AT91_PIN_PB4, AT91_PIN_PB4); |
@@ -74,6 +63,11 @@ static void __init kafa_map_io(void) | |||
74 | at91_init_serial(&kafa_uart_config); | 63 | at91_init_serial(&kafa_uart_config); |
75 | } | 64 | } |
76 | 65 | ||
66 | static void __init kafa_init_irq(void) | ||
67 | { | ||
68 | at91rm9200_init_interrupts(NULL); | ||
69 | } | ||
70 | |||
77 | static struct at91_eth_data __initdata kafa_eth_data = { | 71 | static struct at91_eth_data __initdata kafa_eth_data = { |
78 | .phy_irq_pin = AT91_PIN_PC4, | 72 | .phy_irq_pin = AT91_PIN_PC4, |
79 | .is_rmii = 0, | 73 | .is_rmii = 0, |
diff --git a/arch/arm/mach-at91rm9200/board-kb9202.c b/arch/arm/mach-at91rm9200/board-kb9202.c index f06d2b54cc9a..272fe43bceca 100644 --- a/arch/arm/mach-at91rm9200/board-kb9202.c +++ b/arch/arm/mach-at91rm9200/board-kb9202.c | |||
@@ -35,20 +35,11 @@ | |||
35 | #include <asm/mach/map.h> | 35 | #include <asm/mach/map.h> |
36 | #include <asm/mach/irq.h> | 36 | #include <asm/mach/irq.h> |
37 | 37 | ||
38 | #include <asm/hardware.h> | ||
39 | #include <asm/arch/board.h> | 38 | #include <asm/arch/board.h> |
40 | #include <asm/arch/gpio.h> | 39 | #include <asm/arch/gpio.h> |
41 | 40 | ||
42 | #include "generic.h" | 41 | #include "generic.h" |
43 | 42 | ||
44 | static void __init kb9202_init_irq(void) | ||
45 | { | ||
46 | /* Initialize AIC controller */ | ||
47 | at91rm9200_init_irq(NULL); | ||
48 | |||
49 | /* Set up the GPIO interrupts */ | ||
50 | at91_gpio_irq_setup(PQFP_GPIO_BANKS); | ||
51 | } | ||
52 | 43 | ||
53 | /* | 44 | /* |
54 | * Serial port configuration. | 45 | * Serial port configuration. |
@@ -63,10 +54,8 @@ static struct at91_uart_config __initdata kb9202_uart_config = { | |||
63 | 54 | ||
64 | static void __init kb9202_map_io(void) | 55 | static void __init kb9202_map_io(void) |
65 | { | 56 | { |
66 | at91rm9200_map_io(); | 57 | /* Initialize processor: 10 MHz crystal */ |
67 | 58 | at91rm9200_initialize(10000000, AT91RM9200_PQFP); | |
68 | /* Initialize clocks: 10 MHz crystal */ | ||
69 | at91_clock_init(10000000); | ||
70 | 59 | ||
71 | /* Set up the LEDs */ | 60 | /* Set up the LEDs */ |
72 | at91_init_leds(AT91_PIN_PC19, AT91_PIN_PC18); | 61 | at91_init_leds(AT91_PIN_PC19, AT91_PIN_PC18); |
@@ -75,6 +64,11 @@ static void __init kb9202_map_io(void) | |||
75 | at91_init_serial(&kb9202_uart_config); | 64 | at91_init_serial(&kb9202_uart_config); |
76 | } | 65 | } |
77 | 66 | ||
67 | static void __init kb9202_init_irq(void) | ||
68 | { | ||
69 | at91rm9200_init_interrupts(NULL); | ||
70 | } | ||
71 | |||
78 | static struct at91_eth_data __initdata kb9202_eth_data = { | 72 | static struct at91_eth_data __initdata kb9202_eth_data = { |
79 | .phy_irq_pin = AT91_PIN_PB29, | 73 | .phy_irq_pin = AT91_PIN_PB29, |
80 | .is_rmii = 0, | 74 | .is_rmii = 0, |
@@ -95,6 +89,29 @@ static struct at91_mmc_data __initdata kb9202_mmc_data = { | |||
95 | .wire4 = 1, | 89 | .wire4 = 1, |
96 | }; | 90 | }; |
97 | 91 | ||
92 | static struct mtd_partition __initdata kb9202_nand_partition[] = { | ||
93 | { | ||
94 | .name = "nand_fs", | ||
95 | .offset = 0, | ||
96 | .size = MTDPART_SIZ_FULL, | ||
97 | }, | ||
98 | }; | ||
99 | |||
100 | static struct mtd_partition *nand_partitions(int size, int *num_partitions) | ||
101 | { | ||
102 | *num_partitions = ARRAY_SIZE(kb9202_nand_partition); | ||
103 | return kb9202_nand_partition; | ||
104 | } | ||
105 | |||
106 | static struct at91_nand_data __initdata kb9202_nand_data = { | ||
107 | .ale = 22, | ||
108 | .cle = 21, | ||
109 | // .det_pin = ... not there | ||
110 | .rdy_pin = AT91_PIN_PC29, | ||
111 | .enable_pin = AT91_PIN_PC28, | ||
112 | .partition_info = nand_partitions, | ||
113 | }; | ||
114 | |||
98 | static void __init kb9202_board_init(void) | 115 | static void __init kb9202_board_init(void) |
99 | { | 116 | { |
100 | /* Serial */ | 117 | /* Serial */ |
@@ -111,6 +128,8 @@ static void __init kb9202_board_init(void) | |||
111 | at91_add_device_i2c(); | 128 | at91_add_device_i2c(); |
112 | /* SPI */ | 129 | /* SPI */ |
113 | at91_add_device_spi(NULL, 0); | 130 | at91_add_device_spi(NULL, 0); |
131 | /* NAND */ | ||
132 | at91_add_device_nand(&kb9202_nand_data); | ||
114 | } | 133 | } |
115 | 134 | ||
116 | MACHINE_START(KB9200, "KB920x") | 135 | MACHINE_START(KB9200, "KB920x") |
diff --git a/arch/arm/mach-at91rm9200/clock.c b/arch/arm/mach-at91rm9200/clock.c index edc2cc837ae6..a43b061a7c85 100644 --- a/arch/arm/mach-at91rm9200/clock.c +++ b/arch/arm/mach-at91rm9200/clock.c | |||
@@ -29,7 +29,7 @@ | |||
29 | 29 | ||
30 | #include <asm/hardware.h> | 30 | #include <asm/hardware.h> |
31 | 31 | ||
32 | #include "generic.h" | 32 | #include "clock.h" |
33 | 33 | ||
34 | 34 | ||
35 | /* | 35 | /* |
@@ -38,23 +38,15 @@ | |||
38 | * PLLB be used at other rates (on boards that don't need USB), etc. | 38 | * PLLB be used at other rates (on boards that don't need USB), etc. |
39 | */ | 39 | */ |
40 | 40 | ||
41 | struct clk { | 41 | #define clk_is_primary(x) ((x)->type & CLK_TYPE_PRIMARY) |
42 | const char *name; /* unique clock name */ | 42 | #define clk_is_programmable(x) ((x)->type & CLK_TYPE_PROGRAMMABLE) |
43 | const char *function; /* function of the clock */ | 43 | #define clk_is_peripheral(x) ((x)->type & CLK_TYPE_PERIPHERAL) |
44 | struct device *dev; /* device associated with function */ | 44 | |
45 | unsigned long rate_hz; | 45 | |
46 | struct clk *parent; | 46 | static LIST_HEAD(clocks); |
47 | u32 pmc_mask; | 47 | static DEFINE_SPINLOCK(clk_lock); |
48 | void (*mode)(struct clk *, int); | ||
49 | unsigned id:2; /* PCK0..3, or 32k/main/a/b */ | ||
50 | unsigned primary:1; | ||
51 | unsigned pll:1; | ||
52 | unsigned programmable:1; | ||
53 | u16 users; | ||
54 | }; | ||
55 | 48 | ||
56 | static spinlock_t clk_lock; | 49 | static u32 at91_pllb_usb_init; |
57 | static u32 at91_pllb_usb_init; | ||
58 | 50 | ||
59 | /* | 51 | /* |
60 | * Four primary clock sources: two crystal oscillators (32K, main), and | 52 | * Four primary clock sources: two crystal oscillators (32K, main), and |
@@ -67,21 +59,20 @@ static struct clk clk32k = { | |||
67 | .rate_hz = AT91_SLOW_CLOCK, | 59 | .rate_hz = AT91_SLOW_CLOCK, |
68 | .users = 1, /* always on */ | 60 | .users = 1, /* always on */ |
69 | .id = 0, | 61 | .id = 0, |
70 | .primary = 1, | 62 | .type = CLK_TYPE_PRIMARY, |
71 | }; | 63 | }; |
72 | static struct clk main_clk = { | 64 | static struct clk main_clk = { |
73 | .name = "main", | 65 | .name = "main", |
74 | .pmc_mask = AT91_PMC_MOSCS, /* in PMC_SR */ | 66 | .pmc_mask = AT91_PMC_MOSCS, /* in PMC_SR */ |
75 | .id = 1, | 67 | .id = 1, |
76 | .primary = 1, | 68 | .type = CLK_TYPE_PRIMARY, |
77 | }; | 69 | }; |
78 | static struct clk plla = { | 70 | static struct clk plla = { |
79 | .name = "plla", | 71 | .name = "plla", |
80 | .parent = &main_clk, | 72 | .parent = &main_clk, |
81 | .pmc_mask = AT91_PMC_LOCKA, /* in PMC_SR */ | 73 | .pmc_mask = AT91_PMC_LOCKA, /* in PMC_SR */ |
82 | .id = 2, | 74 | .id = 2, |
83 | .primary = 1, | 75 | .type = CLK_TYPE_PRIMARY | CLK_TYPE_PLL, |
84 | .pll = 1, | ||
85 | }; | 76 | }; |
86 | 77 | ||
87 | static void pllb_mode(struct clk *clk, int is_on) | 78 | static void pllb_mode(struct clk *clk, int is_on) |
@@ -94,6 +85,7 @@ static void pllb_mode(struct clk *clk, int is_on) | |||
94 | } else | 85 | } else |
95 | value = 0; | 86 | value = 0; |
96 | 87 | ||
88 | // REVISIT: Add work-around for AT91RM9200 Errata #26 ? | ||
97 | at91_sys_write(AT91_CKGR_PLLBR, value); | 89 | at91_sys_write(AT91_CKGR_PLLBR, value); |
98 | 90 | ||
99 | do { | 91 | do { |
@@ -107,8 +99,7 @@ static struct clk pllb = { | |||
107 | .pmc_mask = AT91_PMC_LOCKB, /* in PMC_SR */ | 99 | .pmc_mask = AT91_PMC_LOCKB, /* in PMC_SR */ |
108 | .mode = pllb_mode, | 100 | .mode = pllb_mode, |
109 | .id = 3, | 101 | .id = 3, |
110 | .primary = 1, | 102 | .type = CLK_TYPE_PRIMARY | CLK_TYPE_PLL, |
111 | .pll = 1, | ||
112 | }; | 103 | }; |
113 | 104 | ||
114 | static void pmc_sys_mode(struct clk *clk, int is_on) | 105 | static void pmc_sys_mode(struct clk *clk, int is_on) |
@@ -133,41 +124,6 @@ static struct clk uhpck = { | |||
133 | .mode = pmc_sys_mode, | 124 | .mode = pmc_sys_mode, |
134 | }; | 125 | }; |
135 | 126 | ||
136 | #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS | ||
137 | /* | ||
138 | * The four programmable clocks can be parented by any primary clock. | ||
139 | * You must configure pin multiplexing to bring these signals out. | ||
140 | */ | ||
141 | static struct clk pck0 = { | ||
142 | .name = "pck0", | ||
143 | .pmc_mask = AT91_PMC_PCK0, | ||
144 | .mode = pmc_sys_mode, | ||
145 | .programmable = 1, | ||
146 | .id = 0, | ||
147 | }; | ||
148 | static struct clk pck1 = { | ||
149 | .name = "pck1", | ||
150 | .pmc_mask = AT91_PMC_PCK1, | ||
151 | .mode = pmc_sys_mode, | ||
152 | .programmable = 1, | ||
153 | .id = 1, | ||
154 | }; | ||
155 | static struct clk pck2 = { | ||
156 | .name = "pck2", | ||
157 | .pmc_mask = AT91_PMC_PCK2, | ||
158 | .mode = pmc_sys_mode, | ||
159 | .programmable = 1, | ||
160 | .id = 2, | ||
161 | }; | ||
162 | static struct clk pck3 = { | ||
163 | .name = "pck3", | ||
164 | .pmc_mask = AT91_PMC_PCK3, | ||
165 | .mode = pmc_sys_mode, | ||
166 | .programmable = 1, | ||
167 | .id = 3, | ||
168 | }; | ||
169 | #endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */ | ||
170 | |||
171 | 127 | ||
172 | /* | 128 | /* |
173 | * The master clock is divided from the CPU clock (by 1-4). It's used for | 129 | * The master clock is divided from the CPU clock (by 1-4). It's used for |
@@ -187,131 +143,21 @@ static void pmc_periph_mode(struct clk *clk, int is_on) | |||
187 | at91_sys_write(AT91_PMC_PCDR, clk->pmc_mask); | 143 | at91_sys_write(AT91_PMC_PCDR, clk->pmc_mask); |
188 | } | 144 | } |
189 | 145 | ||
190 | static struct clk udc_clk = { | 146 | static struct clk __init *at91_css_to_clk(unsigned long css) |
191 | .name = "udc_clk", | 147 | { |
192 | .parent = &mck, | 148 | switch (css) { |
193 | .pmc_mask = 1 << AT91_ID_UDP, | 149 | case AT91_PMC_CSS_SLOW: |
194 | .mode = pmc_periph_mode, | 150 | return &clk32k; |
195 | }; | 151 | case AT91_PMC_CSS_MAIN: |
196 | static struct clk ohci_clk = { | 152 | return &main_clk; |
197 | .name = "ohci_clk", | 153 | case AT91_PMC_CSS_PLLA: |
198 | .parent = &mck, | 154 | return &plla; |
199 | .pmc_mask = 1 << AT91_ID_UHP, | 155 | case AT91_PMC_CSS_PLLB: |
200 | .mode = pmc_periph_mode, | 156 | return &pllb; |
201 | }; | 157 | } |
202 | static struct clk ether_clk = { | ||
203 | .name = "ether_clk", | ||
204 | .parent = &mck, | ||
205 | .pmc_mask = 1 << AT91_ID_EMAC, | ||
206 | .mode = pmc_periph_mode, | ||
207 | }; | ||
208 | static struct clk mmc_clk = { | ||
209 | .name = "mci_clk", | ||
210 | .parent = &mck, | ||
211 | .pmc_mask = 1 << AT91_ID_MCI, | ||
212 | .mode = pmc_periph_mode, | ||
213 | }; | ||
214 | static struct clk twi_clk = { | ||
215 | .name = "twi_clk", | ||
216 | .parent = &mck, | ||
217 | .pmc_mask = 1 << AT91_ID_TWI, | ||
218 | .mode = pmc_periph_mode, | ||
219 | }; | ||
220 | static struct clk usart0_clk = { | ||
221 | .name = "usart0_clk", | ||
222 | .parent = &mck, | ||
223 | .pmc_mask = 1 << AT91_ID_US0, | ||
224 | .mode = pmc_periph_mode, | ||
225 | }; | ||
226 | static struct clk usart1_clk = { | ||
227 | .name = "usart1_clk", | ||
228 | .parent = &mck, | ||
229 | .pmc_mask = 1 << AT91_ID_US1, | ||
230 | .mode = pmc_periph_mode, | ||
231 | }; | ||
232 | static struct clk usart2_clk = { | ||
233 | .name = "usart2_clk", | ||
234 | .parent = &mck, | ||
235 | .pmc_mask = 1 << AT91_ID_US2, | ||
236 | .mode = pmc_periph_mode, | ||
237 | }; | ||
238 | static struct clk usart3_clk = { | ||
239 | .name = "usart3_clk", | ||
240 | .parent = &mck, | ||
241 | .pmc_mask = 1 << AT91_ID_US3, | ||
242 | .mode = pmc_periph_mode, | ||
243 | }; | ||
244 | static struct clk spi_clk = { | ||
245 | .name = "spi0_clk", | ||
246 | .parent = &mck, | ||
247 | .pmc_mask = 1 << AT91_ID_SPI, | ||
248 | .mode = pmc_periph_mode, | ||
249 | }; | ||
250 | static struct clk pioA_clk = { | ||
251 | .name = "pioA_clk", | ||
252 | .parent = &mck, | ||
253 | .pmc_mask = 1 << AT91_ID_PIOA, | ||
254 | .mode = pmc_periph_mode, | ||
255 | }; | ||
256 | static struct clk pioB_clk = { | ||
257 | .name = "pioB_clk", | ||
258 | .parent = &mck, | ||
259 | .pmc_mask = 1 << AT91_ID_PIOB, | ||
260 | .mode = pmc_periph_mode, | ||
261 | }; | ||
262 | static struct clk pioC_clk = { | ||
263 | .name = "pioC_clk", | ||
264 | .parent = &mck, | ||
265 | .pmc_mask = 1 << AT91_ID_PIOC, | ||
266 | .mode = pmc_periph_mode, | ||
267 | }; | ||
268 | static struct clk pioD_clk = { | ||
269 | .name = "pioD_clk", | ||
270 | .parent = &mck, | ||
271 | .pmc_mask = 1 << AT91_ID_PIOD, | ||
272 | .mode = pmc_periph_mode, | ||
273 | }; | ||
274 | |||
275 | static struct clk *const clock_list[] = { | ||
276 | /* four primary clocks -- MUST BE FIRST! */ | ||
277 | &clk32k, | ||
278 | &main_clk, | ||
279 | &plla, | ||
280 | &pllb, | ||
281 | |||
282 | /* PLLB children (USB) */ | ||
283 | &udpck, | ||
284 | &uhpck, | ||
285 | |||
286 | #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS | ||
287 | /* programmable clocks */ | ||
288 | &pck0, | ||
289 | &pck1, | ||
290 | &pck2, | ||
291 | &pck3, | ||
292 | #endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */ | ||
293 | |||
294 | /* MCK and peripherals */ | ||
295 | &mck, | ||
296 | &usart0_clk, | ||
297 | &usart1_clk, | ||
298 | &usart2_clk, | ||
299 | &usart3_clk, | ||
300 | &mmc_clk, | ||
301 | &udc_clk, | ||
302 | &twi_clk, | ||
303 | &spi_clk, | ||
304 | &pioA_clk, | ||
305 | &pioB_clk, | ||
306 | &pioC_clk, | ||
307 | &pioD_clk, | ||
308 | // ssc0..ssc2 | ||
309 | // tc0..tc5 | ||
310 | // irq0..irq6 | ||
311 | &ohci_clk, | ||
312 | ðer_clk, | ||
313 | }; | ||
314 | 158 | ||
159 | return NULL; | ||
160 | } | ||
315 | 161 | ||
316 | /* | 162 | /* |
317 | * Associate a particular clock with a function (eg, "uart") and device. | 163 | * Associate a particular clock with a function (eg, "uart") and device. |
@@ -329,14 +175,12 @@ void __init at91_clock_associate(const char *id, struct device *dev, const char | |||
329 | clk->dev = dev; | 175 | clk->dev = dev; |
330 | } | 176 | } |
331 | 177 | ||
332 | /* clocks are all static for now; no refcounting necessary */ | 178 | /* clocks cannot be de-registered no refcounting necessary */ |
333 | struct clk *clk_get(struct device *dev, const char *id) | 179 | struct clk *clk_get(struct device *dev, const char *id) |
334 | { | 180 | { |
335 | int i; | 181 | struct clk *clk; |
336 | |||
337 | for (i = 0; i < ARRAY_SIZE(clock_list); i++) { | ||
338 | struct clk *clk = clock_list[i]; | ||
339 | 182 | ||
183 | list_for_each_entry(clk, &clocks, node) { | ||
340 | if (strcmp(id, clk->name) == 0) | 184 | if (strcmp(id, clk->name) == 0) |
341 | return clk; | 185 | return clk; |
342 | if (clk->function && (dev == clk->dev) && strcmp(id, clk->function) == 0) | 186 | if (clk->function && (dev == clk->dev) && strcmp(id, clk->function) == 0) |
@@ -424,7 +268,7 @@ long clk_round_rate(struct clk *clk, unsigned long rate) | |||
424 | unsigned prescale; | 268 | unsigned prescale; |
425 | unsigned long actual; | 269 | unsigned long actual; |
426 | 270 | ||
427 | if (!clk->programmable) | 271 | if (!clk_is_programmable(clk)) |
428 | return -EINVAL; | 272 | return -EINVAL; |
429 | spin_lock_irqsave(&clk_lock, flags); | 273 | spin_lock_irqsave(&clk_lock, flags); |
430 | 274 | ||
@@ -446,7 +290,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate) | |||
446 | unsigned prescale; | 290 | unsigned prescale; |
447 | unsigned long actual; | 291 | unsigned long actual; |
448 | 292 | ||
449 | if (!clk->programmable) | 293 | if (!clk_is_programmable(clk)) |
450 | return -EINVAL; | 294 | return -EINVAL; |
451 | if (clk->users) | 295 | if (clk->users) |
452 | return -EBUSY; | 296 | return -EBUSY; |
@@ -484,7 +328,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent) | |||
484 | 328 | ||
485 | if (clk->users) | 329 | if (clk->users) |
486 | return -EBUSY; | 330 | return -EBUSY; |
487 | if (!parent->primary || !clk->programmable) | 331 | if (!clk_is_primary(parent) || !clk_is_programmable(clk)) |
488 | return -EINVAL; | 332 | return -EINVAL; |
489 | spin_lock_irqsave(&clk_lock, flags); | 333 | spin_lock_irqsave(&clk_lock, flags); |
490 | 334 | ||
@@ -497,6 +341,18 @@ int clk_set_parent(struct clk *clk, struct clk *parent) | |||
497 | } | 341 | } |
498 | EXPORT_SYMBOL(clk_set_parent); | 342 | EXPORT_SYMBOL(clk_set_parent); |
499 | 343 | ||
344 | /* establish PCK0..PCK3 parentage and rate */ | ||
345 | static void init_programmable_clock(struct clk *clk) | ||
346 | { | ||
347 | struct clk *parent; | ||
348 | u32 pckr; | ||
349 | |||
350 | pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); | ||
351 | parent = at91_css_to_clk(pckr & AT91_PMC_CSS); | ||
352 | clk->parent = parent; | ||
353 | clk->rate_hz = parent->rate_hz / (1 << ((pckr >> 2) & 3)); | ||
354 | } | ||
355 | |||
500 | #endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */ | 356 | #endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */ |
501 | 357 | ||
502 | /*------------------------------------------------------------------------*/ | 358 | /*------------------------------------------------------------------------*/ |
@@ -506,6 +362,7 @@ EXPORT_SYMBOL(clk_set_parent); | |||
506 | static int at91_clk_show(struct seq_file *s, void *unused) | 362 | static int at91_clk_show(struct seq_file *s, void *unused) |
507 | { | 363 | { |
508 | u32 scsr, pcsr, sr; | 364 | u32 scsr, pcsr, sr; |
365 | struct clk *clk; | ||
509 | unsigned i; | 366 | unsigned i; |
510 | 367 | ||
511 | seq_printf(s, "SCSR = %8x\n", scsr = at91_sys_read(AT91_PMC_SCSR)); | 368 | seq_printf(s, "SCSR = %8x\n", scsr = at91_sys_read(AT91_PMC_SCSR)); |
@@ -523,9 +380,8 @@ static int at91_clk_show(struct seq_file *s, void *unused) | |||
523 | 380 | ||
524 | seq_printf(s, "\n"); | 381 | seq_printf(s, "\n"); |
525 | 382 | ||
526 | for (i = 0; i < ARRAY_SIZE(clock_list); i++) { | 383 | list_for_each_entry(clk, &clocks, node) { |
527 | char *state; | 384 | char *state; |
528 | struct clk *clk = clock_list[i]; | ||
529 | 385 | ||
530 | if (clk->mode == pmc_sys_mode) | 386 | if (clk->mode == pmc_sys_mode) |
531 | state = (scsr & clk->pmc_mask) ? "on" : "off"; | 387 | state = (scsr & clk->pmc_mask) ? "on" : "off"; |
@@ -570,6 +426,28 @@ postcore_initcall(at91_clk_debugfs_init); | |||
570 | 426 | ||
571 | /*------------------------------------------------------------------------*/ | 427 | /*------------------------------------------------------------------------*/ |
572 | 428 | ||
429 | /* Register a new clock */ | ||
430 | int __init clk_register(struct clk *clk) | ||
431 | { | ||
432 | if (clk_is_peripheral(clk)) { | ||
433 | clk->parent = &mck; | ||
434 | clk->mode = pmc_periph_mode; | ||
435 | list_add_tail(&clk->node, &clocks); | ||
436 | } | ||
437 | #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS | ||
438 | else if (clk_is_programmable(clk)) { | ||
439 | clk->mode = pmc_sys_mode; | ||
440 | init_programmable_clock(clk); | ||
441 | list_add_tail(&clk->node, &clocks); | ||
442 | } | ||
443 | #endif | ||
444 | |||
445 | return 0; | ||
446 | } | ||
447 | |||
448 | |||
449 | /*------------------------------------------------------------------------*/ | ||
450 | |||
573 | static u32 __init at91_pll_rate(struct clk *pll, u32 freq, u32 reg) | 451 | static u32 __init at91_pll_rate(struct clk *pll, u32 freq, u32 reg) |
574 | { | 452 | { |
575 | unsigned mul, div; | 453 | unsigned mul, div; |
@@ -640,20 +518,17 @@ fail: | |||
640 | return 0; | 518 | return 0; |
641 | } | 519 | } |
642 | 520 | ||
643 | |||
644 | /* | 521 | /* |
645 | * Several unused clocks may be active. Turn them off. | 522 | * Several unused clocks may be active. Turn them off. |
646 | */ | 523 | */ |
647 | static void at91_periphclk_reset(void) | 524 | static void __init at91_periphclk_reset(void) |
648 | { | 525 | { |
649 | unsigned long reg; | 526 | unsigned long reg; |
650 | int i; | 527 | struct clk *clk; |
651 | 528 | ||
652 | reg = at91_sys_read(AT91_PMC_PCSR); | 529 | reg = at91_sys_read(AT91_PMC_PCSR); |
653 | 530 | ||
654 | for (i = 0; i < ARRAY_SIZE(clock_list); i++) { | 531 | list_for_each_entry(clk, &clocks, node) { |
655 | struct clk *clk = clock_list[i]; | ||
656 | |||
657 | if (clk->mode != pmc_periph_mode) | 532 | if (clk->mode != pmc_periph_mode) |
658 | continue; | 533 | continue; |
659 | 534 | ||
@@ -664,11 +539,25 @@ static void at91_periphclk_reset(void) | |||
664 | at91_sys_write(AT91_PMC_PCDR, reg); | 539 | at91_sys_write(AT91_PMC_PCDR, reg); |
665 | } | 540 | } |
666 | 541 | ||
542 | static struct clk *const standard_pmc_clocks[] __initdata = { | ||
543 | /* four primary clocks */ | ||
544 | &clk32k, | ||
545 | &main_clk, | ||
546 | &plla, | ||
547 | &pllb, | ||
548 | |||
549 | /* PLLB children (USB) */ | ||
550 | &udpck, | ||
551 | &uhpck, | ||
552 | |||
553 | /* MCK */ | ||
554 | &mck | ||
555 | }; | ||
556 | |||
667 | int __init at91_clock_init(unsigned long main_clock) | 557 | int __init at91_clock_init(unsigned long main_clock) |
668 | { | 558 | { |
669 | unsigned tmp, freq, mckr; | 559 | unsigned tmp, freq, mckr; |
670 | 560 | int i; | |
671 | spin_lock_init(&clk_lock); | ||
672 | 561 | ||
673 | /* | 562 | /* |
674 | * When the bootloader initialized the main oscillator correctly, | 563 | * When the bootloader initialized the main oscillator correctly, |
@@ -709,11 +598,15 @@ int __init at91_clock_init(unsigned long main_clock) | |||
709 | * For now, assume this parentage won't change. | 598 | * For now, assume this parentage won't change. |
710 | */ | 599 | */ |
711 | mckr = at91_sys_read(AT91_PMC_MCKR); | 600 | mckr = at91_sys_read(AT91_PMC_MCKR); |
712 | mck.parent = clock_list[mckr & AT91_PMC_CSS]; | 601 | mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS); |
713 | freq = mck.parent->rate_hz; | 602 | freq = mck.parent->rate_hz; |
714 | freq /= (1 << ((mckr >> 2) & 3)); /* prescale */ | 603 | freq /= (1 << ((mckr >> 2) & 3)); /* prescale */ |
715 | mck.rate_hz = freq / (1 + ((mckr >> 8) & 3)); /* mdiv */ | 604 | mck.rate_hz = freq / (1 + ((mckr >> 8) & 3)); /* mdiv */ |
716 | 605 | ||
606 | /* Register the PMC's standard clocks */ | ||
607 | for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++) | ||
608 | list_add_tail(&standard_pmc_clocks[i]->node, &clocks); | ||
609 | |||
717 | /* MCK and CPU clock are "always on" */ | 610 | /* MCK and CPU clock are "always on" */ |
718 | clk_enable(&mck); | 611 | clk_enable(&mck); |
719 | 612 | ||
@@ -722,35 +615,8 @@ int __init at91_clock_init(unsigned long main_clock) | |||
722 | (unsigned) main_clock / 1000000, | 615 | (unsigned) main_clock / 1000000, |
723 | ((unsigned) main_clock % 1000000) / 1000); | 616 | ((unsigned) main_clock % 1000000) / 1000); |
724 | 617 | ||
725 | #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS | ||
726 | /* establish PCK0..PCK3 parentage */ | ||
727 | for (tmp = 0; tmp < ARRAY_SIZE(clock_list); tmp++) { | ||
728 | struct clk *clk = clock_list[tmp], *parent; | ||
729 | u32 pckr; | ||
730 | |||
731 | if (!clk->programmable) | ||
732 | continue; | ||
733 | |||
734 | pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); | ||
735 | parent = clock_list[pckr & AT91_PMC_CSS]; | ||
736 | clk->parent = parent; | ||
737 | clk->rate_hz = parent->rate_hz / (1 << ((pckr >> 2) & 3)); | ||
738 | |||
739 | if (clk->users == 0) { | ||
740 | /* not being used, so switch it off */ | ||
741 | at91_sys_write(AT91_PMC_SCDR, clk->pmc_mask); | ||
742 | } | ||
743 | } | ||
744 | #else | ||
745 | /* disable all programmable clocks */ | 618 | /* disable all programmable clocks */ |
746 | at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK0 | AT91_PMC_PCK1 | AT91_PMC_PCK2 | AT91_PMC_PCK3); | 619 | at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK0 | AT91_PMC_PCK1 | AT91_PMC_PCK2 | AT91_PMC_PCK3); |
747 | #endif | ||
748 | |||
749 | /* enable the PIO clocks */ | ||
750 | clk_enable(&pioA_clk); | ||
751 | clk_enable(&pioB_clk); | ||
752 | clk_enable(&pioC_clk); | ||
753 | clk_enable(&pioD_clk); | ||
754 | 620 | ||
755 | /* disable all other unused peripheral clocks */ | 621 | /* disable all other unused peripheral clocks */ |
756 | at91_periphclk_reset(); | 622 | at91_periphclk_reset(); |
diff --git a/arch/arm/mach-at91rm9200/clock.h b/arch/arm/mach-at91rm9200/clock.h new file mode 100644 index 000000000000..0592e662ab37 --- /dev/null +++ b/arch/arm/mach-at91rm9200/clock.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-at91rm9200/clock.h | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #define CLK_TYPE_PRIMARY 0x1 | ||
10 | #define CLK_TYPE_PLL 0x2 | ||
11 | #define CLK_TYPE_PROGRAMMABLE 0x4 | ||
12 | #define CLK_TYPE_PERIPHERAL 0x8 | ||
13 | |||
14 | |||
15 | struct clk { | ||
16 | struct list_head node; | ||
17 | const char *name; /* unique clock name */ | ||
18 | const char *function; /* function of the clock */ | ||
19 | struct device *dev; /* device associated with function */ | ||
20 | unsigned long rate_hz; | ||
21 | struct clk *parent; | ||
22 | u32 pmc_mask; | ||
23 | void (*mode)(struct clk *, int); | ||
24 | unsigned id:2; /* PCK0..3, or 32k/main/a/b */ | ||
25 | unsigned type; /* clock type */ | ||
26 | u16 users; | ||
27 | }; | ||
28 | |||
29 | |||
30 | extern int __init clk_register(struct clk *clk); | ||
diff --git a/arch/arm/mach-at91rm9200/devices.c b/arch/arm/mach-at91rm9200/devices.c index 4352acb88178..01525530c287 100644 --- a/arch/arm/mach-at91rm9200/devices.c +++ b/arch/arm/mach-at91rm9200/devices.c | |||
@@ -35,13 +35,13 @@ static struct at91_usbh_data usbh_data; | |||
35 | 35 | ||
36 | static struct resource at91_usbh_resources[] = { | 36 | static struct resource at91_usbh_resources[] = { |
37 | [0] = { | 37 | [0] = { |
38 | .start = AT91_UHP_BASE, | 38 | .start = AT91RM9200_UHP_BASE, |
39 | .end = AT91_UHP_BASE + SZ_1M - 1, | 39 | .end = AT91RM9200_UHP_BASE + SZ_1M - 1, |
40 | .flags = IORESOURCE_MEM, | 40 | .flags = IORESOURCE_MEM, |
41 | }, | 41 | }, |
42 | [1] = { | 42 | [1] = { |
43 | .start = AT91_ID_UHP, | 43 | .start = AT91RM9200_ID_UHP, |
44 | .end = AT91_ID_UHP, | 44 | .end = AT91RM9200_ID_UHP, |
45 | .flags = IORESOURCE_IRQ, | 45 | .flags = IORESOURCE_IRQ, |
46 | }, | 46 | }, |
47 | }; | 47 | }; |
@@ -80,13 +80,13 @@ static struct at91_udc_data udc_data; | |||
80 | 80 | ||
81 | static struct resource at91_udc_resources[] = { | 81 | static struct resource at91_udc_resources[] = { |
82 | [0] = { | 82 | [0] = { |
83 | .start = AT91_BASE_UDP, | 83 | .start = AT91RM9200_BASE_UDP, |
84 | .end = AT91_BASE_UDP + SZ_16K - 1, | 84 | .end = AT91RM9200_BASE_UDP + SZ_16K - 1, |
85 | .flags = IORESOURCE_MEM, | 85 | .flags = IORESOURCE_MEM, |
86 | }, | 86 | }, |
87 | [1] = { | 87 | [1] = { |
88 | .start = AT91_ID_UDP, | 88 | .start = AT91RM9200_ID_UDP, |
89 | .end = AT91_ID_UDP, | 89 | .end = AT91RM9200_ID_UDP, |
90 | .flags = IORESOURCE_IRQ, | 90 | .flags = IORESOURCE_IRQ, |
91 | }, | 91 | }, |
92 | }; | 92 | }; |
@@ -131,13 +131,13 @@ static struct at91_eth_data eth_data; | |||
131 | 131 | ||
132 | static struct resource at91_eth_resources[] = { | 132 | static struct resource at91_eth_resources[] = { |
133 | [0] = { | 133 | [0] = { |
134 | .start = AT91_BASE_EMAC, | 134 | .start = AT91_VA_BASE_EMAC, |
135 | .end = AT91_BASE_EMAC + SZ_16K - 1, | 135 | .end = AT91_VA_BASE_EMAC + SZ_16K - 1, |
136 | .flags = IORESOURCE_MEM, | 136 | .flags = IORESOURCE_MEM, |
137 | }, | 137 | }, |
138 | [1] = { | 138 | [1] = { |
139 | .start = AT91_ID_EMAC, | 139 | .start = AT91RM9200_ID_EMAC, |
140 | .end = AT91_ID_EMAC, | 140 | .end = AT91RM9200_ID_EMAC, |
141 | .flags = IORESOURCE_IRQ, | 141 | .flags = IORESOURCE_IRQ, |
142 | }, | 142 | }, |
143 | }; | 143 | }; |
@@ -263,13 +263,13 @@ static struct at91_mmc_data mmc_data; | |||
263 | 263 | ||
264 | static struct resource at91_mmc_resources[] = { | 264 | static struct resource at91_mmc_resources[] = { |
265 | [0] = { | 265 | [0] = { |
266 | .start = AT91_BASE_MCI, | 266 | .start = AT91RM9200_BASE_MCI, |
267 | .end = AT91_BASE_MCI + SZ_16K - 1, | 267 | .end = AT91RM9200_BASE_MCI + SZ_16K - 1, |
268 | .flags = IORESOURCE_MEM, | 268 | .flags = IORESOURCE_MEM, |
269 | }, | 269 | }, |
270 | [1] = { | 270 | [1] = { |
271 | .start = AT91_ID_MCI, | 271 | .start = AT91RM9200_ID_MCI, |
272 | .end = AT91_ID_MCI, | 272 | .end = AT91RM9200_ID_MCI, |
273 | .flags = IORESOURCE_IRQ, | 273 | .flags = IORESOURCE_IRQ, |
274 | }, | 274 | }, |
275 | }; | 275 | }; |
@@ -423,13 +423,13 @@ static u64 spi_dmamask = 0xffffffffUL; | |||
423 | 423 | ||
424 | static struct resource at91_spi_resources[] = { | 424 | static struct resource at91_spi_resources[] = { |
425 | [0] = { | 425 | [0] = { |
426 | .start = AT91_BASE_SPI, | 426 | .start = AT91RM9200_BASE_SPI, |
427 | .end = AT91_BASE_SPI + SZ_16K - 1, | 427 | .end = AT91RM9200_BASE_SPI + SZ_16K - 1, |
428 | .flags = IORESOURCE_MEM, | 428 | .flags = IORESOURCE_MEM, |
429 | }, | 429 | }, |
430 | [1] = { | 430 | [1] = { |
431 | .start = AT91_ID_SPI, | 431 | .start = AT91RM9200_ID_SPI, |
432 | .end = AT91_ID_SPI, | 432 | .end = AT91RM9200_ID_SPI, |
433 | .flags = IORESOURCE_IRQ, | 433 | .flags = IORESOURCE_IRQ, |
434 | }, | 434 | }, |
435 | }; | 435 | }; |
@@ -582,13 +582,13 @@ static inline void configure_dbgu_pins(void) | |||
582 | 582 | ||
583 | static struct resource uart0_resources[] = { | 583 | static struct resource uart0_resources[] = { |
584 | [0] = { | 584 | [0] = { |
585 | .start = AT91_BASE_US0, | 585 | .start = AT91RM9200_BASE_US0, |
586 | .end = AT91_BASE_US0 + SZ_16K - 1, | 586 | .end = AT91RM9200_BASE_US0 + SZ_16K - 1, |
587 | .flags = IORESOURCE_MEM, | 587 | .flags = IORESOURCE_MEM, |
588 | }, | 588 | }, |
589 | [1] = { | 589 | [1] = { |
590 | .start = AT91_ID_US0, | 590 | .start = AT91RM9200_ID_US0, |
591 | .end = AT91_ID_US0, | 591 | .end = AT91RM9200_ID_US0, |
592 | .flags = IORESOURCE_IRQ, | 592 | .flags = IORESOURCE_IRQ, |
593 | }, | 593 | }, |
594 | }; | 594 | }; |
@@ -624,13 +624,13 @@ static inline void configure_usart0_pins(void) | |||
624 | 624 | ||
625 | static struct resource uart1_resources[] = { | 625 | static struct resource uart1_resources[] = { |
626 | [0] = { | 626 | [0] = { |
627 | .start = AT91_BASE_US1, | 627 | .start = AT91RM9200_BASE_US1, |
628 | .end = AT91_BASE_US1 + SZ_16K - 1, | 628 | .end = AT91RM9200_BASE_US1 + SZ_16K - 1, |
629 | .flags = IORESOURCE_MEM, | 629 | .flags = IORESOURCE_MEM, |
630 | }, | 630 | }, |
631 | [1] = { | 631 | [1] = { |
632 | .start = AT91_ID_US1, | 632 | .start = AT91RM9200_ID_US1, |
633 | .end = AT91_ID_US1, | 633 | .end = AT91RM9200_ID_US1, |
634 | .flags = IORESOURCE_IRQ, | 634 | .flags = IORESOURCE_IRQ, |
635 | }, | 635 | }, |
636 | }; | 636 | }; |
@@ -665,13 +665,13 @@ static inline void configure_usart1_pins(void) | |||
665 | 665 | ||
666 | static struct resource uart2_resources[] = { | 666 | static struct resource uart2_resources[] = { |
667 | [0] = { | 667 | [0] = { |
668 | .start = AT91_BASE_US2, | 668 | .start = AT91RM9200_BASE_US2, |
669 | .end = AT91_BASE_US2 + SZ_16K - 1, | 669 | .end = AT91RM9200_BASE_US2 + SZ_16K - 1, |
670 | .flags = IORESOURCE_MEM, | 670 | .flags = IORESOURCE_MEM, |
671 | }, | 671 | }, |
672 | [1] = { | 672 | [1] = { |
673 | .start = AT91_ID_US2, | 673 | .start = AT91RM9200_ID_US2, |
674 | .end = AT91_ID_US2, | 674 | .end = AT91RM9200_ID_US2, |
675 | .flags = IORESOURCE_IRQ, | 675 | .flags = IORESOURCE_IRQ, |
676 | }, | 676 | }, |
677 | }; | 677 | }; |
@@ -700,13 +700,13 @@ static inline void configure_usart2_pins(void) | |||
700 | 700 | ||
701 | static struct resource uart3_resources[] = { | 701 | static struct resource uart3_resources[] = { |
702 | [0] = { | 702 | [0] = { |
703 | .start = AT91_BASE_US3, | 703 | .start = AT91RM9200_BASE_US3, |
704 | .end = AT91_BASE_US3 + SZ_16K - 1, | 704 | .end = AT91RM9200_BASE_US3 + SZ_16K - 1, |
705 | .flags = IORESOURCE_MEM, | 705 | .flags = IORESOURCE_MEM, |
706 | }, | 706 | }, |
707 | [1] = { | 707 | [1] = { |
708 | .start = AT91_ID_US3, | 708 | .start = AT91RM9200_ID_US3, |
709 | .end = AT91_ID_US3, | 709 | .end = AT91RM9200_ID_US3, |
710 | .flags = IORESOURCE_IRQ, | 710 | .flags = IORESOURCE_IRQ, |
711 | }, | 711 | }, |
712 | }; | 712 | }; |
diff --git a/arch/arm/mach-at91rm9200/generic.h b/arch/arm/mach-at91rm9200/generic.h index 7979d8ab7e07..694e411e285f 100644 --- a/arch/arm/mach-at91rm9200/generic.h +++ b/arch/arm/mach-at91rm9200/generic.h | |||
@@ -8,18 +8,17 @@ | |||
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | /* Processors */ | ||
12 | extern void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks); | ||
13 | |||
11 | /* Interrupts */ | 14 | /* Interrupts */ |
12 | extern void __init at91rm9200_init_irq(unsigned int priority[]); | 15 | extern void __init at91rm9200_init_interrupts(unsigned int priority[]); |
13 | extern void __init at91_aic_init(unsigned int priority[]); | 16 | extern void __init at91_aic_init(unsigned int priority[]); |
14 | extern void __init at91_gpio_irq_setup(unsigned banks); | ||
15 | 17 | ||
16 | /* Timer */ | 18 | /* Timer */ |
17 | struct sys_timer; | 19 | struct sys_timer; |
18 | extern struct sys_timer at91rm9200_timer; | 20 | extern struct sys_timer at91rm9200_timer; |
19 | 21 | ||
20 | /* Memory Map */ | ||
21 | extern void __init at91rm9200_map_io(void); | ||
22 | |||
23 | /* Clocks */ | 22 | /* Clocks */ |
24 | extern int __init at91_clock_init(unsigned long main_clock); | 23 | extern int __init at91_clock_init(unsigned long main_clock); |
25 | struct device; | 24 | struct device; |
@@ -29,3 +28,14 @@ extern void __init at91_clock_associate(const char *id, struct device *dev, cons | |||
29 | extern void at91_irq_suspend(void); | 28 | extern void at91_irq_suspend(void); |
30 | extern void at91_irq_resume(void); | 29 | extern void at91_irq_resume(void); |
31 | 30 | ||
31 | /* GPIO */ | ||
32 | #define AT91RM9200_PQFP 3 /* AT91RM9200 PQFP package has 3 banks */ | ||
33 | #define AT91RM9200_BGA 4 /* AT91RM9200 BGA package has 4 banks */ | ||
34 | |||
35 | struct at91_gpio_bank { | ||
36 | unsigned short id; /* peripheral ID */ | ||
37 | unsigned long offset; /* offset from system peripheral base */ | ||
38 | struct clk *clock; /* associated clock */ | ||
39 | }; | ||
40 | extern void __init at91_gpio_init(struct at91_gpio_bank *, int nr_banks); | ||
41 | extern void __init at91_gpio_irq_setup(void); | ||
diff --git a/arch/arm/mach-at91rm9200/gpio.c b/arch/arm/mach-at91rm9200/gpio.c index cec199fd6721..58c9bf5e9520 100644 --- a/arch/arm/mach-at91rm9200/gpio.c +++ b/arch/arm/mach-at91rm9200/gpio.c | |||
@@ -9,6 +9,7 @@ | |||
9 | * (at your option) any later version. | 9 | * (at your option) any later version. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/clk.h> | ||
12 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
13 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
14 | #include <linux/irq.h> | 15 | #include <linux/irq.h> |
@@ -20,12 +21,12 @@ | |||
20 | #include <asm/hardware.h> | 21 | #include <asm/hardware.h> |
21 | #include <asm/arch/gpio.h> | 22 | #include <asm/arch/gpio.h> |
22 | 23 | ||
23 | static const u32 pio_controller_offset[4] = { | 24 | #include "generic.h" |
24 | AT91_PIOA, | 25 | |
25 | AT91_PIOB, | 26 | |
26 | AT91_PIOC, | 27 | static struct at91_gpio_bank *gpio; |
27 | AT91_PIOD, | 28 | static int gpio_banks; |
28 | }; | 29 | |
29 | 30 | ||
30 | static inline void __iomem *pin_to_controller(unsigned pin) | 31 | static inline void __iomem *pin_to_controller(unsigned pin) |
31 | { | 32 | { |
@@ -33,8 +34,8 @@ static inline void __iomem *pin_to_controller(unsigned pin) | |||
33 | 34 | ||
34 | pin -= PIN_BASE; | 35 | pin -= PIN_BASE; |
35 | pin /= 32; | 36 | pin /= 32; |
36 | if (likely(pin < BGA_GPIO_BANKS)) | 37 | if (likely(pin < gpio_banks)) |
37 | return sys_base + pio_controller_offset[pin]; | 38 | return sys_base + gpio[pin].offset; |
38 | 39 | ||
39 | return NULL; | 40 | return NULL; |
40 | } | 41 | } |
@@ -179,7 +180,6 @@ EXPORT_SYMBOL(at91_set_multi_drive); | |||
179 | 180 | ||
180 | /*--------------------------------------------------------------------------*/ | 181 | /*--------------------------------------------------------------------------*/ |
181 | 182 | ||
182 | |||
183 | /* | 183 | /* |
184 | * assuming the pin is muxed as a gpio output, set its value. | 184 | * assuming the pin is muxed as a gpio output, set its value. |
185 | */ | 185 | */ |
@@ -216,8 +216,8 @@ EXPORT_SYMBOL(at91_get_gpio_value); | |||
216 | 216 | ||
217 | #ifdef CONFIG_PM | 217 | #ifdef CONFIG_PM |
218 | 218 | ||
219 | static u32 wakeups[BGA_GPIO_BANKS]; | 219 | static u32 wakeups[MAX_GPIO_BANKS]; |
220 | static u32 backups[BGA_GPIO_BANKS]; | 220 | static u32 backups[MAX_GPIO_BANKS]; |
221 | 221 | ||
222 | static int gpio_irq_set_wake(unsigned pin, unsigned state) | 222 | static int gpio_irq_set_wake(unsigned pin, unsigned state) |
223 | { | 223 | { |
@@ -226,7 +226,7 @@ static int gpio_irq_set_wake(unsigned pin, unsigned state) | |||
226 | pin -= PIN_BASE; | 226 | pin -= PIN_BASE; |
227 | pin /= 32; | 227 | pin /= 32; |
228 | 228 | ||
229 | if (unlikely(pin >= BGA_GPIO_BANKS)) | 229 | if (unlikely(pin >= MAX_GPIO_BANKS)) |
230 | return -EINVAL; | 230 | return -EINVAL; |
231 | 231 | ||
232 | if (state) | 232 | if (state) |
@@ -241,8 +241,8 @@ void at91_gpio_suspend(void) | |||
241 | { | 241 | { |
242 | int i; | 242 | int i; |
243 | 243 | ||
244 | for (i = 0; i < BGA_GPIO_BANKS; i++) { | 244 | for (i = 0; i < gpio_banks; i++) { |
245 | u32 pio = pio_controller_offset[i]; | 245 | u32 pio = gpio[i].offset; |
246 | 246 | ||
247 | /* | 247 | /* |
248 | * Note: drivers should have disabled GPIO interrupts that | 248 | * Note: drivers should have disabled GPIO interrupts that |
@@ -257,14 +257,14 @@ void at91_gpio_suspend(void) | |||
257 | * first place! | 257 | * first place! |
258 | */ | 258 | */ |
259 | backups[i] = at91_sys_read(pio + PIO_IMR); | 259 | backups[i] = at91_sys_read(pio + PIO_IMR); |
260 | at91_sys_write(pio_controller_offset[i] + PIO_IDR, backups[i]); | 260 | at91_sys_write(pio + PIO_IDR, backups[i]); |
261 | at91_sys_write(pio_controller_offset[i] + PIO_IER, wakeups[i]); | 261 | at91_sys_write(pio + PIO_IER, wakeups[i]); |
262 | 262 | ||
263 | if (!wakeups[i]) { | 263 | if (!wakeups[i]) { |
264 | disable_irq_wake(AT91_ID_PIOA + i); | 264 | disable_irq_wake(gpio[i].id); |
265 | at91_sys_write(AT91_PMC_PCDR, 1 << (AT91_ID_PIOA + i)); | 265 | at91_sys_write(AT91_PMC_PCDR, 1 << gpio[i].id); |
266 | } else { | 266 | } else { |
267 | enable_irq_wake(AT91_ID_PIOA + i); | 267 | enable_irq_wake(gpio[i].id); |
268 | #ifdef CONFIG_PM_DEBUG | 268 | #ifdef CONFIG_PM_DEBUG |
269 | printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", "ABCD"[i], wakeups[i]); | 269 | printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", "ABCD"[i], wakeups[i]); |
270 | #endif | 270 | #endif |
@@ -276,16 +276,13 @@ void at91_gpio_resume(void) | |||
276 | { | 276 | { |
277 | int i; | 277 | int i; |
278 | 278 | ||
279 | for (i = 0; i < BGA_GPIO_BANKS; i++) { | 279 | for (i = 0; i < gpio_banks; i++) { |
280 | at91_sys_write(pio_controller_offset[i] + PIO_IDR, wakeups[i]); | 280 | u32 pio = gpio[i].offset; |
281 | at91_sys_write(pio_controller_offset[i] + PIO_IER, backups[i]); | ||
282 | } | ||
283 | 281 | ||
284 | at91_sys_write(AT91_PMC_PCER, | 282 | at91_sys_write(pio + PIO_IDR, wakeups[i]); |
285 | (1 << AT91_ID_PIOA) | 283 | at91_sys_write(pio + PIO_IER, backups[i]); |
286 | | (1 << AT91_ID_PIOB) | 284 | at91_sys_write(AT91_PMC_PCER, 1 << gpio[i].id); |
287 | | (1 << AT91_ID_PIOC) | 285 | } |
288 | | (1 << AT91_ID_PIOD)); | ||
289 | } | 286 | } |
290 | 287 | ||
291 | #else | 288 | #else |
@@ -377,20 +374,25 @@ static void gpio_irq_handler(unsigned irq, struct irqdesc *desc, struct pt_regs | |||
377 | /* now it may re-trigger */ | 374 | /* now it may re-trigger */ |
378 | } | 375 | } |
379 | 376 | ||
380 | /* call this from board-specific init_irq */ | 377 | /*--------------------------------------------------------------------------*/ |
381 | void __init at91_gpio_irq_setup(unsigned banks) | 378 | |
379 | /* | ||
380 | * Called from the processor-specific init to enable GPIO interrupt support. | ||
381 | */ | ||
382 | void __init at91_gpio_irq_setup(void) | ||
382 | { | 383 | { |
383 | unsigned pioc, pin, id; | 384 | unsigned pioc, pin; |
384 | 385 | ||
385 | if (banks > 4) | 386 | for (pioc = 0, pin = PIN_BASE; |
386 | banks = 4; | 387 | pioc < gpio_banks; |
387 | for (pioc = 0, pin = PIN_BASE, id = AT91_ID_PIOA; | 388 | pioc++) { |
388 | pioc < banks; | ||
389 | pioc++, id++) { | ||
390 | void __iomem *controller; | 389 | void __iomem *controller; |
390 | unsigned id = gpio[pioc].id; | ||
391 | unsigned i; | 391 | unsigned i; |
392 | 392 | ||
393 | controller = (void __iomem *) AT91_VA_BASE_SYS + pio_controller_offset[pioc]; | 393 | clk_enable(gpio[pioc].clock); /* enable PIO controller's clock */ |
394 | |||
395 | controller = (void __iomem *) AT91_VA_BASE_SYS + gpio[pioc].offset; | ||
394 | __raw_writel(~0, controller + PIO_IDR); | 396 | __raw_writel(~0, controller + PIO_IDR); |
395 | 397 | ||
396 | set_irq_data(id, (void *) pin); | 398 | set_irq_data(id, (void *) pin); |
@@ -408,5 +410,16 @@ void __init at91_gpio_irq_setup(unsigned banks) | |||
408 | 410 | ||
409 | set_irq_chained_handler(id, gpio_irq_handler); | 411 | set_irq_chained_handler(id, gpio_irq_handler); |
410 | } | 412 | } |
411 | pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, banks); | 413 | pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, gpio_banks); |
414 | } | ||
415 | |||
416 | /* | ||
417 | * Called from the processor-specific init to enable GPIO pin support. | ||
418 | */ | ||
419 | void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) | ||
420 | { | ||
421 | BUG_ON(nr_banks > MAX_GPIO_BANKS); | ||
422 | |||
423 | gpio = data; | ||
424 | gpio_banks = nr_banks; | ||
412 | } | 425 | } |
diff --git a/arch/arm/mach-at91rm9200/irq.c b/arch/arm/mach-at91rm9200/irq.c index c3a5e777f9f8..3e488117ca91 100644 --- a/arch/arm/mach-at91rm9200/irq.c +++ b/arch/arm/mach-at91rm9200/irq.c | |||
@@ -34,8 +34,6 @@ | |||
34 | #include <asm/mach/irq.h> | 34 | #include <asm/mach/irq.h> |
35 | #include <asm/mach/map.h> | 35 | #include <asm/mach/map.h> |
36 | 36 | ||
37 | #include "generic.h" | ||
38 | |||
39 | 37 | ||
40 | static void at91_aic_mask_irq(unsigned int irq) | 38 | static void at91_aic_mask_irq(unsigned int irq) |
41 | { | 39 | { |
@@ -61,12 +59,12 @@ static int at91_aic_set_type(unsigned irq, unsigned type) | |||
61 | srctype = AT91_AIC_SRCTYPE_RISING; | 59 | srctype = AT91_AIC_SRCTYPE_RISING; |
62 | break; | 60 | break; |
63 | case IRQT_LOW: | 61 | case IRQT_LOW: |
64 | if ((irq > AT91_ID_FIQ) && (irq < AT91_ID_IRQ0)) /* only supported on external interrupts */ | 62 | if ((irq > AT91_ID_FIQ) && (irq < AT91RM9200_ID_IRQ0)) /* only supported on external interrupts */ |
65 | return -EINVAL; | 63 | return -EINVAL; |
66 | srctype = AT91_AIC_SRCTYPE_LOW; | 64 | srctype = AT91_AIC_SRCTYPE_LOW; |
67 | break; | 65 | break; |
68 | case IRQT_FALLING: | 66 | case IRQT_FALLING: |
69 | if ((irq > AT91_ID_FIQ) && (irq < AT91_ID_IRQ0)) /* only supported on external interrupts */ | 67 | if ((irq > AT91_ID_FIQ) && (irq < AT91RM9200_ID_IRQ0)) /* only supported on external interrupts */ |
70 | return -EINVAL; | 68 | return -EINVAL; |
71 | srctype = AT91_AIC_SRCTYPE_FALLING; | 69 | srctype = AT91_AIC_SRCTYPE_FALLING; |
72 | break; | 70 | break; |
diff --git a/arch/arm/mach-at91rm9200/pm.c b/arch/arm/mach-at91rm9200/pm.c index 47e5480feb7e..32c95d8eaacf 100644 --- a/arch/arm/mach-at91rm9200/pm.c +++ b/arch/arm/mach-at91rm9200/pm.c | |||
@@ -123,13 +123,13 @@ static int at91_pm_enter(suspend_state_t state) | |||
123 | (at91_sys_read(AT91_PMC_PCSR) | 123 | (at91_sys_read(AT91_PMC_PCSR) |
124 | | (1 << AT91_ID_FIQ) | 124 | | (1 << AT91_ID_FIQ) |
125 | | (1 << AT91_ID_SYS) | 125 | | (1 << AT91_ID_SYS) |
126 | | (1 << AT91_ID_IRQ0) | 126 | | (1 << AT91RM9200_ID_IRQ0) |
127 | | (1 << AT91_ID_IRQ1) | 127 | | (1 << AT91RM9200_ID_IRQ1) |
128 | | (1 << AT91_ID_IRQ2) | 128 | | (1 << AT91RM9200_ID_IRQ2) |
129 | | (1 << AT91_ID_IRQ3) | 129 | | (1 << AT91RM9200_ID_IRQ3) |
130 | | (1 << AT91_ID_IRQ4) | 130 | | (1 << AT91RM9200_ID_IRQ4) |
131 | | (1 << AT91_ID_IRQ5) | 131 | | (1 << AT91RM9200_ID_IRQ5) |
132 | | (1 << AT91_ID_IRQ6)) | 132 | | (1 << AT91RM9200_ID_IRQ6)) |
133 | & at91_sys_read(AT91_AIC_IMR), | 133 | & at91_sys_read(AT91_AIC_IMR), |
134 | state); | 134 | state); |
135 | 135 | ||
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index 7c25dbd5a181..35dd8b3824b0 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/bitops.h> | 26 | #include <linux/bitops.h> |
27 | #include <linux/time.h> | 27 | #include <linux/time.h> |
28 | #include <linux/timex.h> | 28 | #include <linux/timex.h> |
29 | #include <linux/clocksource.h> | ||
29 | 30 | ||
30 | #include <asm/hardware.h> | 31 | #include <asm/hardware.h> |
31 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
@@ -255,16 +256,6 @@ static unsigned volatile last_jiffy_time; | |||
255 | 256 | ||
256 | #define CLOCK_TICKS_PER_USEC ((CLOCK_TICK_RATE + USEC_PER_SEC/2) / USEC_PER_SEC) | 257 | #define CLOCK_TICKS_PER_USEC ((CLOCK_TICK_RATE + USEC_PER_SEC/2) / USEC_PER_SEC) |
257 | 258 | ||
258 | /* IRQs are disabled before entering here from do_gettimeofday() */ | ||
259 | static unsigned long ixp4xx_gettimeoffset(void) | ||
260 | { | ||
261 | u32 elapsed; | ||
262 | |||
263 | elapsed = *IXP4XX_OSTS - last_jiffy_time; | ||
264 | |||
265 | return elapsed / CLOCK_TICKS_PER_USEC; | ||
266 | } | ||
267 | |||
268 | static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 259 | static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) |
269 | { | 260 | { |
270 | write_seqlock(&xtime_lock); | 261 | write_seqlock(&xtime_lock); |
@@ -309,7 +300,6 @@ static void __init ixp4xx_timer_init(void) | |||
309 | 300 | ||
310 | struct sys_timer ixp4xx_timer = { | 301 | struct sys_timer ixp4xx_timer = { |
311 | .init = ixp4xx_timer_init, | 302 | .init = ixp4xx_timer_init, |
312 | .offset = ixp4xx_gettimeoffset, | ||
313 | }; | 303 | }; |
314 | 304 | ||
315 | static struct resource ixp46x_i2c_resources[] = { | 305 | static struct resource ixp46x_i2c_resources[] = { |
@@ -365,3 +355,29 @@ void __init ixp4xx_sys_init(void) | |||
365 | ixp4xx_exp_bus_size >> 20); | 355 | ixp4xx_exp_bus_size >> 20); |
366 | } | 356 | } |
367 | 357 | ||
358 | cycle_t ixp4xx_get_cycles(void) | ||
359 | { | ||
360 | return *IXP4XX_OSTS; | ||
361 | } | ||
362 | |||
363 | static struct clocksource clocksource_ixp4xx = { | ||
364 | .name = "OSTS", | ||
365 | .rating = 200, | ||
366 | .read = ixp4xx_get_cycles, | ||
367 | .mask = CLOCKSOURCE_MASK(32), | ||
368 | .shift = 20, | ||
369 | .is_continuous = 1, | ||
370 | }; | ||
371 | |||
372 | unsigned long ixp4xx_timer_freq = FREQ; | ||
373 | static int __init ixp4xx_clocksource_init(void) | ||
374 | { | ||
375 | clocksource_ixp4xx.mult = | ||
376 | clocksource_hz2mult(ixp4xx_timer_freq, | ||
377 | clocksource_ixp4xx.shift); | ||
378 | clocksource_register(&clocksource_ixp4xx); | ||
379 | |||
380 | return 0; | ||
381 | } | ||
382 | |||
383 | device_initcall(ixp4xx_clocksource_init); | ||
diff --git a/arch/arm/mach-ixp4xx/nslu2-setup.c b/arch/arm/mach-ixp4xx/nslu2-setup.c index 749a337494d3..162c266e5f8f 100644 --- a/arch/arm/mach-ixp4xx/nslu2-setup.c +++ b/arch/arm/mach-ixp4xx/nslu2-setup.c | |||
@@ -159,6 +159,8 @@ static void nslu2_power_off(void) | |||
159 | 159 | ||
160 | static void __init nslu2_init(void) | 160 | static void __init nslu2_init(void) |
161 | { | 161 | { |
162 | ixp4xx_timer_freq = NSLU2_FREQ; | ||
163 | |||
162 | ixp4xx_sys_init(); | 164 | ixp4xx_sys_init(); |
163 | 165 | ||
164 | nslu2_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); | 166 | nslu2_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); |
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c index f1958e882e86..638490e62d5f 100644 --- a/arch/arm/mach-omap1/clock.c +++ b/arch/arm/mach-omap1/clock.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/clk.h> | 20 | #include <linux/clk.h> |
21 | 21 | ||
22 | #include <asm/io.h> | 22 | #include <asm/io.h> |
23 | #include <asm/mach-types.h> | ||
23 | 24 | ||
24 | #include <asm/arch/cpu.h> | 25 | #include <asm/arch/cpu.h> |
25 | #include <asm/arch/usb.h> | 26 | #include <asm/arch/usb.h> |
@@ -586,77 +587,53 @@ static int omap1_clk_set_rate(struct clk *clk, unsigned long rate) | |||
586 | *-------------------------------------------------------------------------*/ | 587 | *-------------------------------------------------------------------------*/ |
587 | 588 | ||
588 | #ifdef CONFIG_OMAP_RESET_CLOCKS | 589 | #ifdef CONFIG_OMAP_RESET_CLOCKS |
589 | /* | ||
590 | * Resets some clocks that may be left on from bootloader, | ||
591 | * but leaves serial clocks on. See also omap_late_clk_reset(). | ||
592 | */ | ||
593 | static inline void omap1_early_clk_reset(void) | ||
594 | { | ||
595 | //omap_writel(0x3 << 29, MOD_CONF_CTRL_0); | ||
596 | } | ||
597 | 590 | ||
598 | static int __init omap1_late_clk_reset(void) | 591 | static void __init omap1_clk_disable_unused(struct clk *clk) |
599 | { | 592 | { |
600 | /* Turn off all unused clocks */ | ||
601 | struct clk *p; | ||
602 | __u32 regval32; | 593 | __u32 regval32; |
603 | 594 | ||
604 | /* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */ | 595 | /* Clocks in the DSP domain need api_ck. Just assume bootloader |
605 | regval32 = omap_readw(SOFT_REQ_REG) & (1 << 4); | 596 | * has not enabled any DSP clocks */ |
606 | omap_writew(regval32, SOFT_REQ_REG); | 597 | if ((u32)clk->enable_reg == DSP_IDLECT2) { |
607 | omap_writew(0, SOFT_REQ_REG2); | 598 | printk(KERN_INFO "Skipping reset check for DSP domain " |
608 | 599 | "clock \"%s\"\n", clk->name); | |
609 | list_for_each_entry(p, &clocks, node) { | 600 | return; |
610 | if (p->usecount > 0 || (p->flags & ALWAYS_ENABLED) || | 601 | } |
611 | p->enable_reg == 0) | ||
612 | continue; | ||
613 | |||
614 | /* Clocks in the DSP domain need api_ck. Just assume bootloader | ||
615 | * has not enabled any DSP clocks */ | ||
616 | if ((u32)p->enable_reg == DSP_IDLECT2) { | ||
617 | printk(KERN_INFO "Skipping reset check for DSP domain " | ||
618 | "clock \"%s\"\n", p->name); | ||
619 | continue; | ||
620 | } | ||
621 | 602 | ||
622 | /* Is the clock already disabled? */ | 603 | /* Is the clock already disabled? */ |
623 | if (p->flags & ENABLE_REG_32BIT) { | 604 | if (clk->flags & ENABLE_REG_32BIT) { |
624 | if (p->flags & VIRTUAL_IO_ADDRESS) | 605 | if (clk->flags & VIRTUAL_IO_ADDRESS) |
625 | regval32 = __raw_readl(p->enable_reg); | 606 | regval32 = __raw_readl(clk->enable_reg); |
626 | else | ||
627 | regval32 = omap_readl(p->enable_reg); | ||
628 | } else { | ||
629 | if (p->flags & VIRTUAL_IO_ADDRESS) | ||
630 | regval32 = __raw_readw(p->enable_reg); | ||
631 | else | 607 | else |
632 | regval32 = omap_readw(p->enable_reg); | 608 | regval32 = omap_readl(clk->enable_reg); |
633 | } | 609 | } else { |
634 | 610 | if (clk->flags & VIRTUAL_IO_ADDRESS) | |
635 | if ((regval32 & (1 << p->enable_bit)) == 0) | 611 | regval32 = __raw_readw(clk->enable_reg); |
636 | continue; | 612 | else |
613 | regval32 = omap_readw(clk->enable_reg); | ||
614 | } | ||
637 | 615 | ||
638 | /* FIXME: This clock seems to be necessary but no-one | 616 | if ((regval32 & (1 << clk->enable_bit)) == 0) |
639 | * has asked for its activation. */ | 617 | return; |
640 | if (p == &tc2_ck // FIX: pm.c (SRAM), CCP, Camera | ||
641 | || p == &ck_dpll1out.clk // FIX: SoSSI, SSR | ||
642 | || p == &arm_gpio_ck // FIX: GPIO code for 1510 | ||
643 | ) { | ||
644 | printk(KERN_INFO "FIXME: Clock \"%s\" seems unused\n", | ||
645 | p->name); | ||
646 | continue; | ||
647 | } | ||
648 | 618 | ||
649 | printk(KERN_INFO "Disabling unused clock \"%s\"... ", p->name); | 619 | /* FIXME: This clock seems to be necessary but no-one |
650 | p->disable(p); | 620 | * has asked for its activation. */ |
651 | printk(" done\n"); | 621 | if (clk == &tc2_ck // FIX: pm.c (SRAM), CCP, Camera |
622 | || clk == &ck_dpll1out.clk // FIX: SoSSI, SSR | ||
623 | || clk == &arm_gpio_ck // FIX: GPIO code for 1510 | ||
624 | ) { | ||
625 | printk(KERN_INFO "FIXME: Clock \"%s\" seems unused\n", | ||
626 | clk->name); | ||
627 | return; | ||
652 | } | 628 | } |
653 | 629 | ||
654 | return 0; | 630 | printk(KERN_INFO "Disabling unused clock \"%s\"... ", clk->name); |
631 | clk->disable(clk); | ||
632 | printk(" done\n"); | ||
655 | } | 633 | } |
656 | late_initcall(omap1_late_clk_reset); | ||
657 | 634 | ||
658 | #else | 635 | #else |
659 | #define omap1_early_clk_reset() {} | 636 | #define omap1_clk_disable_unused NULL |
660 | #endif | 637 | #endif |
661 | 638 | ||
662 | static struct clk_functions omap1_clk_functions = { | 639 | static struct clk_functions omap1_clk_functions = { |
@@ -664,6 +641,7 @@ static struct clk_functions omap1_clk_functions = { | |||
664 | .clk_disable = omap1_clk_disable, | 641 | .clk_disable = omap1_clk_disable, |
665 | .clk_round_rate = omap1_clk_round_rate, | 642 | .clk_round_rate = omap1_clk_round_rate, |
666 | .clk_set_rate = omap1_clk_set_rate, | 643 | .clk_set_rate = omap1_clk_set_rate, |
644 | .clk_disable_unused = omap1_clk_disable_unused, | ||
667 | }; | 645 | }; |
668 | 646 | ||
669 | int __init omap1_clk_init(void) | 647 | int __init omap1_clk_init(void) |
@@ -671,8 +649,13 @@ int __init omap1_clk_init(void) | |||
671 | struct clk ** clkp; | 649 | struct clk ** clkp; |
672 | const struct omap_clock_config *info; | 650 | const struct omap_clock_config *info; |
673 | int crystal_type = 0; /* Default 12 MHz */ | 651 | int crystal_type = 0; /* Default 12 MHz */ |
652 | u32 reg; | ||
653 | |||
654 | /* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */ | ||
655 | reg = omap_readw(SOFT_REQ_REG) & (1 << 4); | ||
656 | omap_writew(reg, SOFT_REQ_REG); | ||
657 | omap_writew(0, SOFT_REQ_REG2); | ||
674 | 658 | ||
675 | omap1_early_clk_reset(); | ||
676 | clk_init(&omap1_clk_functions); | 659 | clk_init(&omap1_clk_functions); |
677 | 660 | ||
678 | /* By default all idlect1 clocks are allowed to idle */ | 661 | /* By default all idlect1 clocks are allowed to idle */ |
@@ -772,6 +755,12 @@ int __init omap1_clk_init(void) | |||
772 | omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL); | 755 | omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL); |
773 | #endif | 756 | #endif |
774 | 757 | ||
758 | /* Amstrad Delta wants BCLK high when inactive */ | ||
759 | if (machine_is_ams_delta()) | ||
760 | omap_writel(omap_readl(ULPD_CLOCK_CTRL) | | ||
761 | (1 << SDW_MCLK_INV_BIT), | ||
762 | ULPD_CLOCK_CTRL); | ||
763 | |||
775 | /* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */ | 764 | /* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */ |
776 | /* (on 730, bit 13 must not be cleared) */ | 765 | /* (on 730, bit 13 must not be cleared) */ |
777 | if (cpu_is_omap730()) | 766 | if (cpu_is_omap730()) |
diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h index b7c68819c4e7..f7df00205c4a 100644 --- a/arch/arm/mach-omap1/clock.h +++ b/arch/arm/mach-omap1/clock.h | |||
@@ -89,6 +89,7 @@ struct arm_idlect1_clk { | |||
89 | #define EN_DSPTIMCK 5 | 89 | #define EN_DSPTIMCK 5 |
90 | 90 | ||
91 | /* Various register defines for clock controls scattered around OMAP chip */ | 91 | /* Various register defines for clock controls scattered around OMAP chip */ |
92 | #define SDW_MCLK_INV_BIT 2 /* In ULPD_CLKC_CTRL */ | ||
92 | #define USB_MCLK_EN_BIT 4 /* In ULPD_CLKC_CTRL */ | 93 | #define USB_MCLK_EN_BIT 4 /* In ULPD_CLKC_CTRL */ |
93 | #define USB_HOST_HHC_UHOST_EN 9 /* In MOD_CONF_CTRL_0 */ | 94 | #define USB_HOST_HHC_UHOST_EN 9 /* In MOD_CONF_CTRL_0 */ |
94 | #define SWD_ULPD_PLL_CLK_REQ 1 /* In SWD_CLK_DIV_CTRL_SEL */ | 95 | #define SWD_ULPD_PLL_CLK_REQ 1 /* In SWD_CLK_DIV_CTRL_SEL */ |
@@ -741,6 +742,18 @@ static struct clk i2c_fck = { | |||
741 | .disable = &omap1_clk_disable_generic, | 742 | .disable = &omap1_clk_disable_generic, |
742 | }; | 743 | }; |
743 | 744 | ||
745 | static struct clk i2c_ick = { | ||
746 | .name = "i2c_ick", | ||
747 | .id = 1, | ||
748 | .flags = CLOCK_IN_OMAP16XX | | ||
749 | VIRTUAL_CLOCK | CLOCK_NO_IDLE_PARENT | | ||
750 | ALWAYS_ENABLED, | ||
751 | .parent = &armper_ck.clk, | ||
752 | .recalc = &followparent_recalc, | ||
753 | .enable = &omap1_clk_enable_generic, | ||
754 | .disable = &omap1_clk_disable_generic, | ||
755 | }; | ||
756 | |||
744 | static struct clk * onchip_clks[] = { | 757 | static struct clk * onchip_clks[] = { |
745 | /* non-ULPD clocks */ | 758 | /* non-ULPD clocks */ |
746 | &ck_ref, | 759 | &ck_ref, |
@@ -790,6 +803,7 @@ static struct clk * onchip_clks[] = { | |||
790 | /* Virtual clocks */ | 803 | /* Virtual clocks */ |
791 | &virtual_ck_mpu, | 804 | &virtual_ck_mpu, |
792 | &i2c_fck, | 805 | &i2c_fck, |
806 | &i2c_ick, | ||
793 | }; | 807 | }; |
794 | 808 | ||
795 | #endif | 809 | #endif |
diff --git a/arch/arm/mach-omap1/mux.c b/arch/arm/mach-omap1/mux.c index fa74ef7af15f..5432335bc493 100644 --- a/arch/arm/mach-omap1/mux.c +++ b/arch/arm/mach-omap1/mux.c | |||
@@ -199,6 +199,17 @@ MUX_CFG("N14_1610_UWIRE_CS0", 8, 9, 1, 1, 21, 0, 1, 1, 1) | |||
199 | MUX_CFG("P15_1610_UWIRE_CS3", 8, 12, 1, 1, 22, 0, 1, 1, 1) | 199 | MUX_CFG("P15_1610_UWIRE_CS3", 8, 12, 1, 1, 22, 0, 1, 1, 1) |
200 | MUX_CFG("N15_1610_UWIRE_CS1", 7, 18, 2, 1, 14, 0, NA, 0, 1) | 200 | MUX_CFG("N15_1610_UWIRE_CS1", 7, 18, 2, 1, 14, 0, NA, 0, 1) |
201 | 201 | ||
202 | /* OMAP-1610 SPI */ | ||
203 | MUX_CFG("U19_1610_SPIF_SCK", 7, 21, 6, 1, 15, 0, 1, 1, 1) | ||
204 | MUX_CFG("U18_1610_SPIF_DIN", 8, 0, 6, 1, 18, 1, 1, 0, 1) | ||
205 | MUX_CFG("P20_1610_SPIF_DIN", 6, 27, 4, 1, 7, 1, 1, 0, 1) | ||
206 | MUX_CFG("W21_1610_SPIF_DOUT", 8, 3, 6, 1, 19, 0, 1, 0, 1) | ||
207 | MUX_CFG("R18_1610_SPIF_DOUT", 7, 9, 3, 1, 11, 0, 1, 0, 1) | ||
208 | MUX_CFG("N14_1610_SPIF_CS0", 8, 9, 6, 1, 21, 0, 1, 1, 1) | ||
209 | MUX_CFG("N15_1610_SPIF_CS1", 7, 18, 6, 1, 14, 0, 1, 1, 1) | ||
210 | MUX_CFG("T19_1610_SPIF_CS2", 7, 15, 4, 1, 13, 0, 1, 1, 1) | ||
211 | MUX_CFG("P15_1610_SPIF_CS3", 8, 12, 3, 1, 22, 0, 1, 1, 1) | ||
212 | |||
202 | /* OMAP-1610 Flash */ | 213 | /* OMAP-1610 Flash */ |
203 | MUX_CFG("L3_1610_FLASH_CS2B_OE",10, 6, 1, NA, 0, 0, NA, 0, 1) | 214 | MUX_CFG("L3_1610_FLASH_CS2B_OE",10, 6, 1, NA, 0, 0, NA, 0, 1) |
204 | MUX_CFG("M8_1610_FLASH_CS2B_WE",10, 3, 1, NA, 0, 0, NA, 0, 1) | 215 | MUX_CFG("M8_1610_FLASH_CS2B_WE",10, 3, 1, NA, 0, 0, NA, 0, 1) |
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c index 7993b7bae2bd..2db6b732b084 100644 --- a/arch/arm/mach-omap2/board-apollon.c +++ b/arch/arm/mach-omap2/board-apollon.c | |||
@@ -166,8 +166,8 @@ static struct omap_uart_config apollon_uart_config __initdata = { | |||
166 | 166 | ||
167 | static struct omap_mmc_config apollon_mmc_config __initdata = { | 167 | static struct omap_mmc_config apollon_mmc_config __initdata = { |
168 | .mmc [0] = { | 168 | .mmc [0] = { |
169 | .enabled = 0, | 169 | .enabled = 1, |
170 | .wire4 = 0, | 170 | .wire4 = 1, |
171 | .wp_pin = -1, | 171 | .wp_pin = -1, |
172 | .power_pin = -1, | 172 | .power_pin = -1, |
173 | .switch_pin = -1, | 173 | .switch_pin = -1, |
@@ -257,6 +257,9 @@ static void __init omap_apollon_init(void) | |||
257 | /* REVISIT: where's the correct place */ | 257 | /* REVISIT: where's the correct place */ |
258 | omap_cfg_reg(W19_24XX_SYS_NIRQ); | 258 | omap_cfg_reg(W19_24XX_SYS_NIRQ); |
259 | 259 | ||
260 | /* Use Interal loop-back in MMC/SDIO Module Input Clock selection */ | ||
261 | CONTROL_DEVCONF |= (1 << 24); | ||
262 | |||
260 | /* | 263 | /* |
261 | * Make sure the serial ports are muxed on at this point. | 264 | * Make sure the serial ports are muxed on at this point. |
262 | * You have to mux them off in device drivers later on | 265 | * You have to mux them off in device drivers later on |
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index d1b648a4efbf..0de201c3d50b 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c | |||
@@ -32,10 +32,14 @@ | |||
32 | #include "memory.h" | 32 | #include "memory.h" |
33 | #include "clock.h" | 33 | #include "clock.h" |
34 | 34 | ||
35 | #undef DEBUG | ||
36 | |||
35 | //#define DOWN_VARIABLE_DPLL 1 /* Experimental */ | 37 | //#define DOWN_VARIABLE_DPLL 1 /* Experimental */ |
36 | 38 | ||
37 | static struct prcm_config *curr_prcm_set; | 39 | static struct prcm_config *curr_prcm_set; |
38 | static u32 curr_perf_level = PRCM_FULL_SPEED; | 40 | static u32 curr_perf_level = PRCM_FULL_SPEED; |
41 | static struct clk *vclk; | ||
42 | static struct clk *sclk; | ||
39 | 43 | ||
40 | /*------------------------------------------------------------------------- | 44 | /*------------------------------------------------------------------------- |
41 | * Omap2 specific clock functions | 45 | * Omap2 specific clock functions |
@@ -79,6 +83,14 @@ static void omap2_propagate_rate(struct clk * clk) | |||
79 | propagate_rate(clk); | 83 | propagate_rate(clk); |
80 | } | 84 | } |
81 | 85 | ||
86 | static void omap2_set_osc_ck(int enable) | ||
87 | { | ||
88 | if (enable) | ||
89 | PRCM_CLKSRC_CTRL &= ~(0x3 << 3); | ||
90 | else | ||
91 | PRCM_CLKSRC_CTRL |= 0x3 << 3; | ||
92 | } | ||
93 | |||
82 | /* Enable an APLL if off */ | 94 | /* Enable an APLL if off */ |
83 | static void omap2_clk_fixed_enable(struct clk *clk) | 95 | static void omap2_clk_fixed_enable(struct clk *clk) |
84 | { | 96 | { |
@@ -101,12 +113,54 @@ static void omap2_clk_fixed_enable(struct clk *clk) | |||
101 | else if (clk == &apll54_ck) | 113 | else if (clk == &apll54_ck) |
102 | cval = (1 << 6); | 114 | cval = (1 << 6); |
103 | 115 | ||
104 | while (!CM_IDLEST_CKGEN & cval) { /* Wait for lock */ | 116 | while (!(CM_IDLEST_CKGEN & cval)) { /* Wait for lock */ |
105 | ++i; | 117 | ++i; |
106 | udelay(1); | 118 | udelay(1); |
107 | if (i == 100000) | 119 | if (i == 100000) { |
120 | printk(KERN_ERR "Clock %s didn't lock\n", clk->name); | ||
121 | break; | ||
122 | } | ||
123 | } | ||
124 | } | ||
125 | |||
126 | static void omap2_clk_wait_ready(struct clk *clk) | ||
127 | { | ||
128 | unsigned long reg, other_reg, st_reg; | ||
129 | u32 bit; | ||
130 | int i; | ||
131 | |||
132 | reg = (unsigned long) clk->enable_reg; | ||
133 | if (reg == (unsigned long) &CM_FCLKEN1_CORE || | ||
134 | reg == (unsigned long) &CM_FCLKEN2_CORE) | ||
135 | other_reg = (reg & ~0xf0) | 0x10; | ||
136 | else if (reg == (unsigned long) &CM_ICLKEN1_CORE || | ||
137 | reg == (unsigned long) &CM_ICLKEN2_CORE) | ||
138 | other_reg = (reg & ~0xf0) | 0x00; | ||
139 | else | ||
140 | return; | ||
141 | |||
142 | /* No check for DSS or cam clocks */ | ||
143 | if ((reg & 0x0f) == 0) { | ||
144 | if (clk->enable_bit <= 1 || clk->enable_bit == 31) | ||
145 | return; | ||
146 | } | ||
147 | |||
148 | /* Check if both functional and interface clocks | ||
149 | * are running. */ | ||
150 | bit = 1 << clk->enable_bit; | ||
151 | if (!(__raw_readl(other_reg) & bit)) | ||
152 | return; | ||
153 | st_reg = (other_reg & ~0xf0) | 0x20; | ||
154 | i = 0; | ||
155 | while (!(__raw_readl(st_reg) & bit)) { | ||
156 | i++; | ||
157 | if (i == 100000) { | ||
158 | printk(KERN_ERR "Timeout enabling clock %s\n", clk->name); | ||
108 | break; | 159 | break; |
160 | } | ||
109 | } | 161 | } |
162 | if (i) | ||
163 | pr_debug("Clock %s stable after %d loops\n", clk->name, i); | ||
110 | } | 164 | } |
111 | 165 | ||
112 | /* Enables clock without considering parent dependencies or use count | 166 | /* Enables clock without considering parent dependencies or use count |
@@ -119,6 +173,11 @@ static int _omap2_clk_enable(struct clk * clk) | |||
119 | if (clk->flags & ALWAYS_ENABLED) | 173 | if (clk->flags & ALWAYS_ENABLED) |
120 | return 0; | 174 | return 0; |
121 | 175 | ||
176 | if (unlikely(clk == &osc_ck)) { | ||
177 | omap2_set_osc_ck(1); | ||
178 | return 0; | ||
179 | } | ||
180 | |||
122 | if (unlikely(clk->enable_reg == 0)) { | 181 | if (unlikely(clk->enable_reg == 0)) { |
123 | printk(KERN_ERR "clock.c: Enable for %s without enable code\n", | 182 | printk(KERN_ERR "clock.c: Enable for %s without enable code\n", |
124 | clk->name); | 183 | clk->name); |
@@ -133,6 +192,9 @@ static int _omap2_clk_enable(struct clk * clk) | |||
133 | regval32 = __raw_readl(clk->enable_reg); | 192 | regval32 = __raw_readl(clk->enable_reg); |
134 | regval32 |= (1 << clk->enable_bit); | 193 | regval32 |= (1 << clk->enable_bit); |
135 | __raw_writel(regval32, clk->enable_reg); | 194 | __raw_writel(regval32, clk->enable_reg); |
195 | wmb(); | ||
196 | |||
197 | omap2_clk_wait_ready(clk); | ||
136 | 198 | ||
137 | return 0; | 199 | return 0; |
138 | } | 200 | } |
@@ -155,6 +217,11 @@ static void _omap2_clk_disable(struct clk *clk) | |||
155 | { | 217 | { |
156 | u32 regval32; | 218 | u32 regval32; |
157 | 219 | ||
220 | if (unlikely(clk == &osc_ck)) { | ||
221 | omap2_set_osc_ck(0); | ||
222 | return; | ||
223 | } | ||
224 | |||
158 | if (clk->enable_reg == 0) | 225 | if (clk->enable_reg == 0) |
159 | return; | 226 | return; |
160 | 227 | ||
@@ -166,6 +233,7 @@ static void _omap2_clk_disable(struct clk *clk) | |||
166 | regval32 = __raw_readl(clk->enable_reg); | 233 | regval32 = __raw_readl(clk->enable_reg); |
167 | regval32 &= ~(1 << clk->enable_bit); | 234 | regval32 &= ~(1 << clk->enable_bit); |
168 | __raw_writel(regval32, clk->enable_reg); | 235 | __raw_writel(regval32, clk->enable_reg); |
236 | wmb(); | ||
169 | } | 237 | } |
170 | 238 | ||
171 | static int omap2_clk_enable(struct clk *clk) | 239 | static int omap2_clk_enable(struct clk *clk) |
@@ -695,12 +763,14 @@ static int omap2_clk_set_rate(struct clk *clk, unsigned long rate) | |||
695 | reg_val = __raw_readl(reg); | 763 | reg_val = __raw_readl(reg); |
696 | reg_val &= ~(field_mask << div_off); | 764 | reg_val &= ~(field_mask << div_off); |
697 | reg_val |= (field_val << div_off); | 765 | reg_val |= (field_val << div_off); |
698 | |||
699 | __raw_writel(reg_val, reg); | 766 | __raw_writel(reg_val, reg); |
767 | wmb(); | ||
700 | clk->rate = clk->parent->rate / field_val; | 768 | clk->rate = clk->parent->rate / field_val; |
701 | 769 | ||
702 | if (clk->flags & DELAYED_APP) | 770 | if (clk->flags & DELAYED_APP) { |
703 | __raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL); | 771 | __raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL); |
772 | wmb(); | ||
773 | } | ||
704 | ret = 0; | 774 | ret = 0; |
705 | } else if (clk->set_rate != 0) | 775 | } else if (clk->set_rate != 0) |
706 | ret = clk->set_rate(clk, rate); | 776 | ret = clk->set_rate(clk, rate); |
@@ -836,10 +906,12 @@ static int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent) | |||
836 | reg_val = __raw_readl(reg) & ~(field_mask << src_off); | 906 | reg_val = __raw_readl(reg) & ~(field_mask << src_off); |
837 | reg_val |= (field_val << src_off); | 907 | reg_val |= (field_val << src_off); |
838 | __raw_writel(reg_val, reg); | 908 | __raw_writel(reg_val, reg); |
909 | wmb(); | ||
839 | 910 | ||
840 | if (clk->flags & DELAYED_APP) | 911 | if (clk->flags & DELAYED_APP) { |
841 | __raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL); | 912 | __raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL); |
842 | 913 | wmb(); | |
914 | } | ||
843 | if (clk->usecount > 0) | 915 | if (clk->usecount > 0) |
844 | _omap2_clk_enable(clk); | 916 | _omap2_clk_enable(clk); |
845 | 917 | ||
@@ -953,12 +1025,29 @@ static int omap2_select_table_rate(struct clk * clk, unsigned long rate) | |||
953 | * Omap2 clock reset and init functions | 1025 | * Omap2 clock reset and init functions |
954 | *-------------------------------------------------------------------------*/ | 1026 | *-------------------------------------------------------------------------*/ |
955 | 1027 | ||
1028 | #ifdef CONFIG_OMAP_RESET_CLOCKS | ||
1029 | static void __init omap2_clk_disable_unused(struct clk *clk) | ||
1030 | { | ||
1031 | u32 regval32; | ||
1032 | |||
1033 | regval32 = __raw_readl(clk->enable_reg); | ||
1034 | if ((regval32 & (1 << clk->enable_bit)) == 0) | ||
1035 | return; | ||
1036 | |||
1037 | printk(KERN_INFO "Disabling unused clock \"%s\"\n", clk->name); | ||
1038 | _omap2_clk_disable(clk); | ||
1039 | } | ||
1040 | #else | ||
1041 | #define omap2_clk_disable_unused NULL | ||
1042 | #endif | ||
1043 | |||
956 | static struct clk_functions omap2_clk_functions = { | 1044 | static struct clk_functions omap2_clk_functions = { |
957 | .clk_enable = omap2_clk_enable, | 1045 | .clk_enable = omap2_clk_enable, |
958 | .clk_disable = omap2_clk_disable, | 1046 | .clk_disable = omap2_clk_disable, |
959 | .clk_round_rate = omap2_clk_round_rate, | 1047 | .clk_round_rate = omap2_clk_round_rate, |
960 | .clk_set_rate = omap2_clk_set_rate, | 1048 | .clk_set_rate = omap2_clk_set_rate, |
961 | .clk_set_parent = omap2_clk_set_parent, | 1049 | .clk_set_parent = omap2_clk_set_parent, |
1050 | .clk_disable_unused = omap2_clk_disable_unused, | ||
962 | }; | 1051 | }; |
963 | 1052 | ||
964 | static void __init omap2_get_crystal_rate(struct clk *osc, struct clk *sys) | 1053 | static void __init omap2_get_crystal_rate(struct clk *osc, struct clk *sys) |
@@ -984,27 +1073,19 @@ static void __init omap2_get_crystal_rate(struct clk *osc, struct clk *sys) | |||
984 | sys->rate = sclk; | 1073 | sys->rate = sclk; |
985 | } | 1074 | } |
986 | 1075 | ||
987 | #ifdef CONFIG_OMAP_RESET_CLOCKS | 1076 | /* |
988 | static void __init omap2_disable_unused_clocks(void) | 1077 | * Set clocks for bypass mode for reboot to work. |
1078 | */ | ||
1079 | void omap2_clk_prepare_for_reboot(void) | ||
989 | { | 1080 | { |
990 | struct clk *ck; | 1081 | u32 rate; |
991 | u32 regval32; | ||
992 | 1082 | ||
993 | list_for_each_entry(ck, &clocks, node) { | 1083 | if (vclk == NULL || sclk == NULL) |
994 | if (ck->usecount > 0 || (ck->flags & ALWAYS_ENABLED) || | 1084 | return; |
995 | ck->enable_reg == 0) | ||
996 | continue; | ||
997 | |||
998 | regval32 = __raw_readl(ck->enable_reg); | ||
999 | if ((regval32 & (1 << ck->enable_bit)) == 0) | ||
1000 | continue; | ||
1001 | 1085 | ||
1002 | printk(KERN_INFO "Disabling unused clock \"%s\"\n", ck->name); | 1086 | rate = clk_get_rate(sclk); |
1003 | _omap2_clk_disable(ck); | 1087 | clk_set_rate(vclk, rate); |
1004 | } | ||
1005 | } | 1088 | } |
1006 | late_initcall(omap2_disable_unused_clocks); | ||
1007 | #endif | ||
1008 | 1089 | ||
1009 | /* | 1090 | /* |
1010 | * Switch the MPU rate if specified on cmdline. | 1091 | * Switch the MPU rate if specified on cmdline. |
@@ -1077,8 +1158,27 @@ int __init omap2_clk_init(void) | |||
1077 | */ | 1158 | */ |
1078 | clk_enable(&sync_32k_ick); | 1159 | clk_enable(&sync_32k_ick); |
1079 | clk_enable(&omapctrl_ick); | 1160 | clk_enable(&omapctrl_ick); |
1161 | |||
1162 | /* Force the APLLs active during bootup to avoid disabling and | ||
1163 | * enabling them unnecessarily. */ | ||
1164 | clk_enable(&apll96_ck); | ||
1165 | clk_enable(&apll54_ck); | ||
1166 | |||
1080 | if (cpu_is_omap2430()) | 1167 | if (cpu_is_omap2430()) |
1081 | clk_enable(&sdrc_ick); | 1168 | clk_enable(&sdrc_ick); |
1082 | 1169 | ||
1170 | /* Avoid sleeping sleeping during omap2_clk_prepare_for_reboot() */ | ||
1171 | vclk = clk_get(NULL, "virt_prcm_set"); | ||
1172 | sclk = clk_get(NULL, "sys_ck"); | ||
1173 | |||
1174 | return 0; | ||
1175 | } | ||
1176 | |||
1177 | static int __init omap2_disable_aplls(void) | ||
1178 | { | ||
1179 | clk_disable(&apll96_ck); | ||
1180 | clk_disable(&apll54_ck); | ||
1181 | |||
1083 | return 0; | 1182 | return 0; |
1084 | } | 1183 | } |
1184 | late_initcall(omap2_disable_aplls); | ||
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index 2781dfbc5164..8816f5a33a28 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h | |||
@@ -560,7 +560,7 @@ static struct clk osc_ck = { /* (*12, *13, 19.2, *26, 38.4)MHz */ | |||
560 | .name = "osc_ck", | 560 | .name = "osc_ck", |
561 | .rate = 26000000, /* fixed up in clock init */ | 561 | .rate = 26000000, /* fixed up in clock init */ |
562 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | 562 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | |
563 | RATE_FIXED | ALWAYS_ENABLED | RATE_PROPAGATES, | 563 | RATE_FIXED | RATE_PROPAGATES, |
564 | }; | 564 | }; |
565 | 565 | ||
566 | /* With out modem likely 12MHz, with modem likely 13MHz */ | 566 | /* With out modem likely 12MHz, with modem likely 13MHz */ |
@@ -1368,7 +1368,8 @@ static struct clk mcbsp5_fck = { | |||
1368 | }; | 1368 | }; |
1369 | 1369 | ||
1370 | static struct clk mcspi1_ick = { | 1370 | static struct clk mcspi1_ick = { |
1371 | .name = "mcspi1_ick", | 1371 | .name = "mcspi_ick", |
1372 | .id = 1, | ||
1372 | .parent = &l4_ck, | 1373 | .parent = &l4_ck, |
1373 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | 1374 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, |
1374 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, | 1375 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, |
@@ -1377,7 +1378,8 @@ static struct clk mcspi1_ick = { | |||
1377 | }; | 1378 | }; |
1378 | 1379 | ||
1379 | static struct clk mcspi1_fck = { | 1380 | static struct clk mcspi1_fck = { |
1380 | .name = "mcspi1_fck", | 1381 | .name = "mcspi_fck", |
1382 | .id = 1, | ||
1381 | .parent = &func_48m_ck, | 1383 | .parent = &func_48m_ck, |
1382 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | 1384 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, |
1383 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | 1385 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, |
@@ -1386,7 +1388,8 @@ static struct clk mcspi1_fck = { | |||
1386 | }; | 1388 | }; |
1387 | 1389 | ||
1388 | static struct clk mcspi2_ick = { | 1390 | static struct clk mcspi2_ick = { |
1389 | .name = "mcspi2_ick", | 1391 | .name = "mcspi_ick", |
1392 | .id = 2, | ||
1390 | .parent = &l4_ck, | 1393 | .parent = &l4_ck, |
1391 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | 1394 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, |
1392 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, | 1395 | .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, |
@@ -1395,7 +1398,8 @@ static struct clk mcspi2_ick = { | |||
1395 | }; | 1398 | }; |
1396 | 1399 | ||
1397 | static struct clk mcspi2_fck = { | 1400 | static struct clk mcspi2_fck = { |
1398 | .name = "mcspi2_fck", | 1401 | .name = "mcspi_fck", |
1402 | .id = 2, | ||
1399 | .parent = &func_48m_ck, | 1403 | .parent = &func_48m_ck, |
1400 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | 1404 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, |
1401 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, | 1405 | .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, |
@@ -1404,7 +1408,8 @@ static struct clk mcspi2_fck = { | |||
1404 | }; | 1408 | }; |
1405 | 1409 | ||
1406 | static struct clk mcspi3_ick = { | 1410 | static struct clk mcspi3_ick = { |
1407 | .name = "mcspi3_ick", | 1411 | .name = "mcspi_ick", |
1412 | .id = 3, | ||
1408 | .parent = &l4_ck, | 1413 | .parent = &l4_ck, |
1409 | .flags = CLOCK_IN_OMAP243X, | 1414 | .flags = CLOCK_IN_OMAP243X, |
1410 | .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE, | 1415 | .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE, |
@@ -1413,7 +1418,8 @@ static struct clk mcspi3_ick = { | |||
1413 | }; | 1418 | }; |
1414 | 1419 | ||
1415 | static struct clk mcspi3_fck = { | 1420 | static struct clk mcspi3_fck = { |
1416 | .name = "mcspi3_fck", | 1421 | .name = "mcspi_fck", |
1422 | .id = 3, | ||
1417 | .parent = &func_48m_ck, | 1423 | .parent = &func_48m_ck, |
1418 | .flags = CLOCK_IN_OMAP243X, | 1424 | .flags = CLOCK_IN_OMAP243X, |
1419 | .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE, | 1425 | .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE, |
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index c7a48f921fef..f4f04d87df32 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c | |||
@@ -13,6 +13,8 @@ | |||
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/err.h> | 14 | #include <linux/err.h> |
15 | #include <linux/clk.h> | 15 | #include <linux/clk.h> |
16 | #include <linux/ioport.h> | ||
17 | #include <linux/spinlock.h> | ||
16 | 18 | ||
17 | #include <asm/io.h> | 19 | #include <asm/io.h> |
18 | #include <asm/arch/gpmc.h> | 20 | #include <asm/arch/gpmc.h> |
@@ -41,6 +43,19 @@ | |||
41 | #define GPMC_CS0 0x60 | 43 | #define GPMC_CS0 0x60 |
42 | #define GPMC_CS_SIZE 0x30 | 44 | #define GPMC_CS_SIZE 0x30 |
43 | 45 | ||
46 | #define GPMC_CS_NUM 8 | ||
47 | #define GPMC_MEM_START 0x00000000 | ||
48 | #define GPMC_MEM_END 0x3FFFFFFF | ||
49 | #define BOOT_ROM_SPACE 0x100000 /* 1MB */ | ||
50 | |||
51 | #define GPMC_CHUNK_SHIFT 24 /* 16 MB */ | ||
52 | #define GPMC_SECTION_SHIFT 28 /* 128 MB */ | ||
53 | |||
54 | static struct resource gpmc_mem_root; | ||
55 | static struct resource gpmc_cs_mem[GPMC_CS_NUM]; | ||
56 | static spinlock_t gpmc_mem_lock = SPIN_LOCK_UNLOCKED; | ||
57 | static unsigned gpmc_cs_map; | ||
58 | |||
44 | static void __iomem *gpmc_base = | 59 | static void __iomem *gpmc_base = |
45 | (void __iomem *) IO_ADDRESS(GPMC_BASE); | 60 | (void __iomem *) IO_ADDRESS(GPMC_BASE); |
46 | static void __iomem *gpmc_cs_base = | 61 | static void __iomem *gpmc_cs_base = |
@@ -187,9 +202,168 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t) | |||
187 | return 0; | 202 | return 0; |
188 | } | 203 | } |
189 | 204 | ||
190 | unsigned long gpmc_cs_get_base_addr(int cs) | 205 | static void gpmc_cs_enable_mem(int cs, u32 base, u32 size) |
206 | { | ||
207 | u32 l; | ||
208 | u32 mask; | ||
209 | |||
210 | mask = (1 << GPMC_SECTION_SHIFT) - size; | ||
211 | l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); | ||
212 | l &= ~0x3f; | ||
213 | l = (base >> GPMC_CHUNK_SHIFT) & 0x3f; | ||
214 | l &= ~(0x0f << 8); | ||
215 | l |= ((mask >> GPMC_CHUNK_SHIFT) & 0x0f) << 8; | ||
216 | l |= 1 << 6; /* CSVALID */ | ||
217 | gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l); | ||
218 | } | ||
219 | |||
220 | static void gpmc_cs_disable_mem(int cs) | ||
221 | { | ||
222 | u32 l; | ||
223 | |||
224 | l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); | ||
225 | l &= ~(1 << 6); /* CSVALID */ | ||
226 | gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l); | ||
227 | } | ||
228 | |||
229 | static void gpmc_cs_get_memconf(int cs, u32 *base, u32 *size) | ||
230 | { | ||
231 | u32 l; | ||
232 | u32 mask; | ||
233 | |||
234 | l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); | ||
235 | *base = (l & 0x3f) << GPMC_CHUNK_SHIFT; | ||
236 | mask = (l >> 8) & 0x0f; | ||
237 | *size = (1 << GPMC_SECTION_SHIFT) - (mask << GPMC_CHUNK_SHIFT); | ||
238 | } | ||
239 | |||
240 | static int gpmc_cs_mem_enabled(int cs) | ||
241 | { | ||
242 | u32 l; | ||
243 | |||
244 | l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); | ||
245 | return l & (1 << 6); | ||
246 | } | ||
247 | |||
248 | static void gpmc_cs_set_reserved(int cs, int reserved) | ||
191 | { | 249 | { |
192 | return (gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7) & 0x1f) << 24; | 250 | gpmc_cs_map &= ~(1 << cs); |
251 | gpmc_cs_map |= (reserved ? 1 : 0) << cs; | ||
252 | } | ||
253 | |||
254 | static int gpmc_cs_reserved(int cs) | ||
255 | { | ||
256 | return gpmc_cs_map & (1 << cs); | ||
257 | } | ||
258 | |||
259 | static unsigned long gpmc_mem_align(unsigned long size) | ||
260 | { | ||
261 | int order; | ||
262 | |||
263 | size = (size - 1) >> (GPMC_CHUNK_SHIFT - 1); | ||
264 | order = GPMC_CHUNK_SHIFT - 1; | ||
265 | do { | ||
266 | size >>= 1; | ||
267 | order++; | ||
268 | } while (size); | ||
269 | size = 1 << order; | ||
270 | return size; | ||
271 | } | ||
272 | |||
273 | static int gpmc_cs_insert_mem(int cs, unsigned long base, unsigned long size) | ||
274 | { | ||
275 | struct resource *res = &gpmc_cs_mem[cs]; | ||
276 | int r; | ||
277 | |||
278 | size = gpmc_mem_align(size); | ||
279 | spin_lock(&gpmc_mem_lock); | ||
280 | res->start = base; | ||
281 | res->end = base + size - 1; | ||
282 | r = request_resource(&gpmc_mem_root, res); | ||
283 | spin_unlock(&gpmc_mem_lock); | ||
284 | |||
285 | return r; | ||
286 | } | ||
287 | |||
288 | int gpmc_cs_request(int cs, unsigned long size, unsigned long *base) | ||
289 | { | ||
290 | struct resource *res = &gpmc_cs_mem[cs]; | ||
291 | int r = -1; | ||
292 | |||
293 | if (cs > GPMC_CS_NUM) | ||
294 | return -ENODEV; | ||
295 | |||
296 | size = gpmc_mem_align(size); | ||
297 | if (size > (1 << GPMC_SECTION_SHIFT)) | ||
298 | return -ENOMEM; | ||
299 | |||
300 | spin_lock(&gpmc_mem_lock); | ||
301 | if (gpmc_cs_reserved(cs)) { | ||
302 | r = -EBUSY; | ||
303 | goto out; | ||
304 | } | ||
305 | if (gpmc_cs_mem_enabled(cs)) | ||
306 | r = adjust_resource(res, res->start & ~(size - 1), size); | ||
307 | if (r < 0) | ||
308 | r = allocate_resource(&gpmc_mem_root, res, size, 0, ~0, | ||
309 | size, NULL, NULL); | ||
310 | if (r < 0) | ||
311 | goto out; | ||
312 | |||
313 | gpmc_cs_enable_mem(cs, res->start, res->end - res->start + 1); | ||
314 | *base = res->start; | ||
315 | gpmc_cs_set_reserved(cs, 1); | ||
316 | out: | ||
317 | spin_unlock(&gpmc_mem_lock); | ||
318 | return r; | ||
319 | } | ||
320 | |||
321 | void gpmc_cs_free(int cs) | ||
322 | { | ||
323 | spin_lock(&gpmc_mem_lock); | ||
324 | if (cs >= GPMC_CS_NUM || !gpmc_cs_reserved(cs)) { | ||
325 | printk(KERN_ERR "Trying to free non-reserved GPMC CS%d\n", cs); | ||
326 | BUG(); | ||
327 | spin_unlock(&gpmc_mem_lock); | ||
328 | return; | ||
329 | } | ||
330 | gpmc_cs_disable_mem(cs); | ||
331 | release_resource(&gpmc_cs_mem[cs]); | ||
332 | gpmc_cs_set_reserved(cs, 0); | ||
333 | spin_unlock(&gpmc_mem_lock); | ||
334 | } | ||
335 | |||
336 | void __init gpmc_mem_init(void) | ||
337 | { | ||
338 | int cs; | ||
339 | unsigned long boot_rom_space = 0; | ||
340 | |||
341 | if (cpu_is_omap242x()) { | ||
342 | u32 l; | ||
343 | l = omap_readl(OMAP242X_CONTROL_STATUS); | ||
344 | /* In case of internal boot the 1st MB is redirected to the | ||
345 | * boot ROM memory space. | ||
346 | */ | ||
347 | if (l & (1 << 3)) | ||
348 | boot_rom_space = BOOT_ROM_SPACE; | ||
349 | } else | ||
350 | /* We assume internal boot if the mode can't be | ||
351 | * determined. | ||
352 | */ | ||
353 | boot_rom_space = BOOT_ROM_SPACE; | ||
354 | gpmc_mem_root.start = GPMC_MEM_START + boot_rom_space; | ||
355 | gpmc_mem_root.end = GPMC_MEM_END; | ||
356 | |||
357 | /* Reserve all regions that has been set up by bootloader */ | ||
358 | for (cs = 0; cs < GPMC_CS_NUM; cs++) { | ||
359 | u32 base, size; | ||
360 | |||
361 | if (!gpmc_cs_mem_enabled(cs)) | ||
362 | continue; | ||
363 | gpmc_cs_get_memconf(cs, &base, &size); | ||
364 | if (gpmc_cs_insert_mem(cs, base, size) < 0) | ||
365 | BUG(); | ||
366 | } | ||
193 | } | 367 | } |
194 | 368 | ||
195 | void __init gpmc_init(void) | 369 | void __init gpmc_init(void) |
@@ -206,4 +380,6 @@ void __init gpmc_init(void) | |||
206 | l &= 0x03 << 3; | 380 | l &= 0x03 << 3; |
207 | l |= (0x02 << 3) | (1 << 0); | 381 | l |= (0x02 << 3) | (1 << 0); |
208 | gpmc_write_reg(GPMC_SYSCONFIG, l); | 382 | gpmc_write_reg(GPMC_SYSCONFIG, l); |
383 | |||
384 | gpmc_mem_init(); | ||
209 | } | 385 | } |
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c index dfc3b35cc1ff..1ed2fff4691a 100644 --- a/arch/arm/mach-omap2/irq.c +++ b/arch/arm/mach-omap2/irq.c | |||
@@ -41,18 +41,6 @@ static struct omap_irq_bank { | |||
41 | .nr_irqs = 96, | 41 | .nr_irqs = 96, |
42 | }, { | 42 | }, { |
43 | /* XXX: DSP INTC */ | 43 | /* XXX: DSP INTC */ |
44 | |||
45 | #if 0 | ||
46 | /* | ||
47 | * Commented out for now until we fix the IVA clocking | ||
48 | */ | ||
49 | #ifdef CONFIG_ARCH_OMAP2420 | ||
50 | }, { | ||
51 | /* IVA INTC (2420 only) */ | ||
52 | .base_reg = OMAP24XX_IVA_INTC_BASE, | ||
53 | .nr_irqs = 16, /* Actually 32, but only 16 are used */ | ||
54 | #endif | ||
55 | #endif | ||
56 | } | 44 | } |
57 | }; | 45 | }; |
58 | 46 | ||
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index 60ef084faffd..f538d0fdb13c 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c | |||
@@ -104,6 +104,20 @@ MUX_CFG_24XX("P20_24XX_TSC_IRQ", 0x108, 0, 0, 0, 1) | |||
104 | MUX_CFG_24XX("K15_24XX_UART3_TX", 0x118, 0, 0, 0, 1) | 104 | MUX_CFG_24XX("K15_24XX_UART3_TX", 0x118, 0, 0, 0, 1) |
105 | MUX_CFG_24XX("K14_24XX_UART3_RX", 0x119, 0, 0, 0, 1) | 105 | MUX_CFG_24XX("K14_24XX_UART3_RX", 0x119, 0, 0, 0, 1) |
106 | 106 | ||
107 | /* MMC/SDIO */ | ||
108 | MUX_CFG_24XX("G19_24XX_MMC_CLKO", 0x0f3, 0, 0, 0, 1) | ||
109 | MUX_CFG_24XX("H18_24XX_MMC_CMD", 0x0f4, 0, 0, 0, 1) | ||
110 | MUX_CFG_24XX("F20_24XX_MMC_DAT0", 0x0f5, 0, 0, 0, 1) | ||
111 | MUX_CFG_24XX("H14_24XX_MMC_DAT1", 0x0f6, 0, 0, 0, 1) | ||
112 | MUX_CFG_24XX("E19_24XX_MMC_DAT2", 0x0f7, 0, 0, 0, 1) | ||
113 | MUX_CFG_24XX("D19_24XX_MMC_DAT3", 0x0f8, 0, 0, 0, 1) | ||
114 | MUX_CFG_24XX("F19_24XX_MMC_DAT_DIR0", 0x0f9, 0, 0, 0, 1) | ||
115 | MUX_CFG_24XX("E20_24XX_MMC_DAT_DIR1", 0x0fa, 0, 0, 0, 1) | ||
116 | MUX_CFG_24XX("F18_24XX_MMC_DAT_DIR2", 0x0fb, 0, 0, 0, 1) | ||
117 | MUX_CFG_24XX("E18_24XX_MMC_DAT_DIR3", 0x0fc, 0, 0, 0, 1) | ||
118 | MUX_CFG_24XX("G18_24XX_MMC_CMD_DIR", 0x0fd, 0, 0, 0, 1) | ||
119 | MUX_CFG_24XX("H15_24XX_MMC_CLKI", 0x0fe, 0, 0, 0, 1) | ||
120 | |||
107 | /* Keypad GPIO*/ | 121 | /* Keypad GPIO*/ |
108 | MUX_CFG_24XX("T19_24XX_KBR0", 0x106, 3, 1, 1, 1) | 122 | MUX_CFG_24XX("T19_24XX_KBR0", 0x106, 3, 1, 1, 1) |
109 | MUX_CFG_24XX("R19_24XX_KBR1", 0x107, 3, 1, 1, 1) | 123 | MUX_CFG_24XX("R19_24XX_KBR1", 0x107, 3, 1, 1, 1) |
diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c index c2bf57ef6825..90f530540c65 100644 --- a/arch/arm/mach-omap2/prcm.c +++ b/arch/arm/mach-omap2/prcm.c | |||
@@ -19,6 +19,8 @@ | |||
19 | 19 | ||
20 | #include "prcm-regs.h" | 20 | #include "prcm-regs.h" |
21 | 21 | ||
22 | extern void omap2_clk_prepare_for_reboot(void); | ||
23 | |||
22 | u32 omap_prcm_get_reset_sources(void) | 24 | u32 omap_prcm_get_reset_sources(void) |
23 | { | 25 | { |
24 | return RM_RSTST_WKUP & 0x7f; | 26 | return RM_RSTST_WKUP & 0x7f; |
@@ -28,12 +30,6 @@ EXPORT_SYMBOL(omap_prcm_get_reset_sources); | |||
28 | /* Resets clock rates and reboots the system. Only called from system.h */ | 30 | /* Resets clock rates and reboots the system. Only called from system.h */ |
29 | void omap_prcm_arch_reset(char mode) | 31 | void omap_prcm_arch_reset(char mode) |
30 | { | 32 | { |
31 | u32 rate; | 33 | omap2_clk_prepare_for_reboot(); |
32 | struct clk *vclk, *sclk; | ||
33 | |||
34 | vclk = clk_get(NULL, "virt_prcm_set"); | ||
35 | sclk = clk_get(NULL, "sys_ck"); | ||
36 | rate = clk_get_rate(sclk); | ||
37 | clk_set_rate(vclk, rate); /* go to bypass for OMAP limitation */ | ||
38 | RM_RSTCTRL_WKUP |= 2; | 34 | RM_RSTCTRL_WKUP |= 2; |
39 | } | 35 | } |
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig index e50a73f93d3d..df37594c30f8 100644 --- a/arch/arm/mach-s3c2410/Kconfig +++ b/arch/arm/mach-s3c2410/Kconfig | |||
@@ -292,7 +292,7 @@ config S3C2410_PM_CHECK_CHUNKSIZE | |||
292 | 292 | ||
293 | config PM_SIMTEC | 293 | config PM_SIMTEC |
294 | bool | 294 | bool |
295 | depends on PM && (ARCH_BAST || MACH_VR1000) | 295 | depends on PM && (ARCH_BAST || MACH_VR1000 || MACH_AML_M5900) |
296 | default y | 296 | default y |
297 | 297 | ||
298 | config S3C2410_LOWLEVEL_UART_PORT | 298 | config S3C2410_LOWLEVEL_UART_PORT |
diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c index 9c7463bf8f86..3e9f3462c61b 100644 --- a/arch/arm/mach-s3c2410/irq.c +++ b/arch/arm/mach-s3c2410/irq.c | |||
@@ -181,17 +181,19 @@ s3c_irq_unmask(unsigned int irqno) | |||
181 | } | 181 | } |
182 | 182 | ||
183 | struct irqchip s3c_irq_level_chip = { | 183 | struct irqchip s3c_irq_level_chip = { |
184 | .ack = s3c_irq_maskack, | 184 | .name = "s3c-level", |
185 | .mask = s3c_irq_mask, | 185 | .ack = s3c_irq_maskack, |
186 | .unmask = s3c_irq_unmask, | 186 | .mask = s3c_irq_mask, |
187 | .set_wake = s3c_irq_wake | 187 | .unmask = s3c_irq_unmask, |
188 | .set_wake = s3c_irq_wake | ||
188 | }; | 189 | }; |
189 | 190 | ||
190 | static struct irqchip s3c_irq_chip = { | 191 | static struct irqchip s3c_irq_chip = { |
191 | .ack = s3c_irq_ack, | 192 | .name = "s3c", |
192 | .mask = s3c_irq_mask, | 193 | .ack = s3c_irq_ack, |
193 | .unmask = s3c_irq_unmask, | 194 | .mask = s3c_irq_mask, |
194 | .set_wake = s3c_irq_wake | 195 | .unmask = s3c_irq_unmask, |
196 | .set_wake = s3c_irq_wake | ||
195 | }; | 197 | }; |
196 | 198 | ||
197 | static void | 199 | static void |
@@ -343,19 +345,21 @@ s3c_irqext_type(unsigned int irq, unsigned int type) | |||
343 | } | 345 | } |
344 | 346 | ||
345 | static struct irqchip s3c_irqext_chip = { | 347 | static struct irqchip s3c_irqext_chip = { |
346 | .mask = s3c_irqext_mask, | 348 | .name = "s3c-ext", |
347 | .unmask = s3c_irqext_unmask, | 349 | .mask = s3c_irqext_mask, |
348 | .ack = s3c_irqext_ack, | 350 | .unmask = s3c_irqext_unmask, |
349 | .set_type = s3c_irqext_type, | 351 | .ack = s3c_irqext_ack, |
350 | .set_wake = s3c_irqext_wake | 352 | .set_type = s3c_irqext_type, |
353 | .set_wake = s3c_irqext_wake | ||
351 | }; | 354 | }; |
352 | 355 | ||
353 | static struct irqchip s3c_irq_eint0t4 = { | 356 | static struct irqchip s3c_irq_eint0t4 = { |
354 | .ack = s3c_irq_ack, | 357 | .name = "s3c-ext0", |
355 | .mask = s3c_irq_mask, | 358 | .ack = s3c_irq_ack, |
356 | .unmask = s3c_irq_unmask, | 359 | .mask = s3c_irq_mask, |
357 | .set_wake = s3c_irq_wake, | 360 | .unmask = s3c_irq_unmask, |
358 | .set_type = s3c_irqext_type, | 361 | .set_wake = s3c_irq_wake, |
362 | .set_type = s3c_irqext_type, | ||
359 | }; | 363 | }; |
360 | 364 | ||
361 | /* mask values for the parent registers for each of the interrupt types */ | 365 | /* mask values for the parent registers for each of the interrupt types */ |
@@ -387,9 +391,10 @@ s3c_irq_uart0_ack(unsigned int irqno) | |||
387 | } | 391 | } |
388 | 392 | ||
389 | static struct irqchip s3c_irq_uart0 = { | 393 | static struct irqchip s3c_irq_uart0 = { |
390 | .mask = s3c_irq_uart0_mask, | 394 | .name = "s3c-uart0", |
391 | .unmask = s3c_irq_uart0_unmask, | 395 | .mask = s3c_irq_uart0_mask, |
392 | .ack = s3c_irq_uart0_ack, | 396 | .unmask = s3c_irq_uart0_unmask, |
397 | .ack = s3c_irq_uart0_ack, | ||
393 | }; | 398 | }; |
394 | 399 | ||
395 | /* UART1 */ | 400 | /* UART1 */ |
@@ -413,9 +418,10 @@ s3c_irq_uart1_ack(unsigned int irqno) | |||
413 | } | 418 | } |
414 | 419 | ||
415 | static struct irqchip s3c_irq_uart1 = { | 420 | static struct irqchip s3c_irq_uart1 = { |
416 | .mask = s3c_irq_uart1_mask, | 421 | .name = "s3c-uart1", |
417 | .unmask = s3c_irq_uart1_unmask, | 422 | .mask = s3c_irq_uart1_mask, |
418 | .ack = s3c_irq_uart1_ack, | 423 | .unmask = s3c_irq_uart1_unmask, |
424 | .ack = s3c_irq_uart1_ack, | ||
419 | }; | 425 | }; |
420 | 426 | ||
421 | /* UART2 */ | 427 | /* UART2 */ |
@@ -439,9 +445,10 @@ s3c_irq_uart2_ack(unsigned int irqno) | |||
439 | } | 445 | } |
440 | 446 | ||
441 | static struct irqchip s3c_irq_uart2 = { | 447 | static struct irqchip s3c_irq_uart2 = { |
442 | .mask = s3c_irq_uart2_mask, | 448 | .name = "s3c-uart2", |
443 | .unmask = s3c_irq_uart2_unmask, | 449 | .mask = s3c_irq_uart2_mask, |
444 | .ack = s3c_irq_uart2_ack, | 450 | .unmask = s3c_irq_uart2_unmask, |
451 | .ack = s3c_irq_uart2_ack, | ||
445 | }; | 452 | }; |
446 | 453 | ||
447 | /* ADC and Touchscreen */ | 454 | /* ADC and Touchscreen */ |
@@ -465,9 +472,10 @@ s3c_irq_adc_ack(unsigned int irqno) | |||
465 | } | 472 | } |
466 | 473 | ||
467 | static struct irqchip s3c_irq_adc = { | 474 | static struct irqchip s3c_irq_adc = { |
468 | .mask = s3c_irq_adc_mask, | 475 | .name = "s3c-adc", |
469 | .unmask = s3c_irq_adc_unmask, | 476 | .mask = s3c_irq_adc_mask, |
470 | .ack = s3c_irq_adc_ack, | 477 | .unmask = s3c_irq_adc_unmask, |
478 | .ack = s3c_irq_adc_ack, | ||
471 | }; | 479 | }; |
472 | 480 | ||
473 | /* irq demux for adc */ | 481 | /* irq demux for adc */ |
@@ -569,18 +577,46 @@ s3c_irq_demux_uart2(unsigned int irq, | |||
569 | } | 577 | } |
570 | 578 | ||
571 | static void | 579 | static void |
572 | s3c_irq_demux_extint(unsigned int irq, | 580 | s3c_irq_demux_extint8(unsigned int irq, |
573 | struct irqdesc *desc, | 581 | struct irqdesc *desc, |
574 | struct pt_regs *regs) | 582 | struct pt_regs *regs) |
575 | { | 583 | { |
576 | unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND); | 584 | unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND); |
577 | unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK); | 585 | unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK); |
578 | 586 | ||
579 | eintpnd &= ~eintmsk; | 587 | eintpnd &= ~eintmsk; |
588 | eintpnd &= ~0xff; /* ignore lower irqs */ | ||
580 | 589 | ||
581 | if (eintpnd) { | 590 | /* we may as well handle all the pending IRQs here */ |
582 | irq = fls(eintpnd); | 591 | |
583 | irq += (IRQ_EINT4 - (4 + 1)); | 592 | while (eintpnd) { |
593 | irq = __ffs(eintpnd); | ||
594 | eintpnd &= ~(1<<irq); | ||
595 | |||
596 | irq += (IRQ_EINT4 - 4); | ||
597 | desc_handle_irq(irq, irq_desc + irq, regs); | ||
598 | } | ||
599 | |||
600 | } | ||
601 | |||
602 | static void | ||
603 | s3c_irq_demux_extint4t7(unsigned int irq, | ||
604 | struct irqdesc *desc, | ||
605 | struct pt_regs *regs) | ||
606 | { | ||
607 | unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND); | ||
608 | unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK); | ||
609 | |||
610 | eintpnd &= ~eintmsk; | ||
611 | eintpnd &= 0xff; /* only lower irqs */ | ||
612 | |||
613 | /* we may as well handle all the pending IRQs here */ | ||
614 | |||
615 | while (eintpnd) { | ||
616 | irq = __ffs(eintpnd); | ||
617 | eintpnd &= ~(1<<irq); | ||
618 | |||
619 | irq += (IRQ_EINT4 - 4); | ||
584 | 620 | ||
585 | desc_handle_irq(irq, irq_desc + irq, regs); | 621 | desc_handle_irq(irq, irq_desc + irq, regs); |
586 | } | 622 | } |
@@ -727,8 +763,8 @@ void __init s3c24xx_init_irq(void) | |||
727 | 763 | ||
728 | /* setup the cascade irq handlers */ | 764 | /* setup the cascade irq handlers */ |
729 | 765 | ||
730 | set_irq_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint); | 766 | set_irq_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint4t7); |
731 | set_irq_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint); | 767 | set_irq_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint8); |
732 | 768 | ||
733 | set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0); | 769 | set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0); |
734 | set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1); | 770 | set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1); |
diff --git a/arch/arm/mach-s3c2410/mach-amlm5900.c b/arch/arm/mach-s3c2410/mach-amlm5900.c index 0c9b7dafbe90..ba5109af40b4 100644 --- a/arch/arm/mach-s3c2410/mach-amlm5900.c +++ b/arch/arm/mach-s3c2410/mach-amlm5900.c | |||
@@ -225,13 +225,34 @@ static struct s3c2410fb_mach_info __initdata amlm5900_lcd_info = { | |||
225 | }; | 225 | }; |
226 | #endif | 226 | #endif |
227 | 227 | ||
228 | static void __init amlm5900_init(void) | 228 | static irqreturn_t |
229 | amlm5900_wake_interrupt(int irq, void *ignored, struct pt_regs *regs) | ||
229 | { | 230 | { |
231 | return IRQ_HANDLED; | ||
232 | } | ||
230 | 233 | ||
234 | static void amlm5900_init_pm(void) | ||
235 | { | ||
236 | int ret = 0; | ||
237 | |||
238 | ret = request_irq(IRQ_EINT9, &amlm5900_wake_interrupt, | ||
239 | IRQF_TRIGGER_RISING | IRQF_SHARED, | ||
240 | "amlm5900_wakeup", &amlm5900_wake_interrupt); | ||
241 | if (ret != 0) { | ||
242 | printk(KERN_ERR "AML-M5900: no wakeup irq, %d?\n", ret); | ||
243 | } else { | ||
244 | enable_irq_wake(IRQ_EINT9); | ||
245 | /* configure the suspend/resume status pin */ | ||
246 | s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_OUTP); | ||
247 | s3c2410_gpio_pullup(S3C2410_GPF2, 0); | ||
248 | } | ||
249 | } | ||
250 | static void __init amlm5900_init(void) | ||
251 | { | ||
252 | amlm5900_init_pm(); | ||
231 | #ifdef CONFIG_FB_S3C2410 | 253 | #ifdef CONFIG_FB_S3C2410 |
232 | s3c24xx_fb_set_platdata(&amlm5900_lcd_info); | 254 | s3c24xx_fb_set_platdata(&amlm5900_lcd_info); |
233 | #endif | 255 | #endif |
234 | |||
235 | } | 256 | } |
236 | 257 | ||
237 | MACHINE_START(AML_M5900, "AML_M5900") | 258 | MACHINE_START(AML_M5900, "AML_M5900") |
diff --git a/arch/arm/mach-s3c2410/pm-simtec.c b/arch/arm/mach-s3c2410/pm-simtec.c index 7b244566a436..42cd05e298f8 100644 --- a/arch/arm/mach-s3c2410/pm-simtec.c +++ b/arch/arm/mach-s3c2410/pm-simtec.c | |||
@@ -49,7 +49,8 @@ static __init int pm_simtec_init(void) | |||
49 | /* check which machine we are running on */ | 49 | /* check which machine we are running on */ |
50 | 50 | ||
51 | if (!machine_is_bast() && !machine_is_vr1000() && | 51 | if (!machine_is_bast() && !machine_is_vr1000() && |
52 | !machine_is_anubis() && !machine_is_osiris()) | 52 | !machine_is_anubis() && !machine_is_osiris() && |
53 | !machine_is_aml_m5900()) | ||
53 | return 0; | 54 | return 0; |
54 | 55 | ||
55 | printk(KERN_INFO "Simtec Board Power Manangement" COPYRIGHT "\n"); | 56 | printk(KERN_INFO "Simtec Board Power Manangement" COPYRIGHT "\n"); |
diff --git a/arch/arm/mach-s3c2410/s3c2410-pm.c b/arch/arm/mach-s3c2410/s3c2410-pm.c index 3080d25a12de..e51d76669512 100644 --- a/arch/arm/mach-s3c2410/s3c2410-pm.c +++ b/arch/arm/mach-s3c2410/s3c2410-pm.c | |||
@@ -29,6 +29,8 @@ | |||
29 | #include <asm/hardware.h> | 29 | #include <asm/hardware.h> |
30 | #include <asm/io.h> | 30 | #include <asm/io.h> |
31 | 31 | ||
32 | #include <asm/mach-types.h> | ||
33 | |||
32 | #include <asm/arch/regs-gpio.h> | 34 | #include <asm/arch/regs-gpio.h> |
33 | 35 | ||
34 | #include "cpu.h" | 36 | #include "cpu.h" |
@@ -49,6 +51,10 @@ static void s3c2410_pm_prepare(void) | |||
49 | 51 | ||
50 | DBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3)); | 52 | DBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3)); |
51 | DBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4)); | 53 | DBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4)); |
54 | |||
55 | if ( machine_is_aml_m5900() ) | ||
56 | s3c2410_gpio_setpin(S3C2410_GPF2, 1); | ||
57 | |||
52 | } | 58 | } |
53 | 59 | ||
54 | int s3c2410_pm_resume(struct sys_device *dev) | 60 | int s3c2410_pm_resume(struct sys_device *dev) |
@@ -61,6 +67,9 @@ int s3c2410_pm_resume(struct sys_device *dev) | |||
61 | tmp &= S3C2410_GSTATUS2_OFFRESET; | 67 | tmp &= S3C2410_GSTATUS2_OFFRESET; |
62 | __raw_writel(tmp, S3C2410_GSTATUS2); | 68 | __raw_writel(tmp, S3C2410_GSTATUS2); |
63 | 69 | ||
70 | if ( machine_is_aml_m5900() ) | ||
71 | s3c2410_gpio_setpin(S3C2410_GPF2, 0); | ||
72 | |||
64 | return 0; | 73 | return 0; |
65 | } | 74 | } |
66 | 75 | ||
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c index a0dfa390e34b..6496eb645cee 100644 --- a/arch/arm/mach-sa1100/collie.c +++ b/arch/arm/mach-sa1100/collie.c | |||
@@ -91,30 +91,29 @@ static struct mcp_plat_data collie_mcp_data = { | |||
91 | /* | 91 | /* |
92 | * low-level UART features. | 92 | * low-level UART features. |
93 | */ | 93 | */ |
94 | static struct locomo_dev *uart_dev = NULL; | 94 | struct platform_device collie_locomo_device; |
95 | 95 | ||
96 | static void collie_uart_set_mctrl(struct uart_port *port, u_int mctrl) | 96 | static void collie_uart_set_mctrl(struct uart_port *port, u_int mctrl) |
97 | { | 97 | { |
98 | if (!uart_dev) return; | ||
99 | |||
100 | if (mctrl & TIOCM_RTS) | 98 | if (mctrl & TIOCM_RTS) |
101 | locomo_gpio_write(uart_dev, LOCOMO_GPIO_RTS, 0); | 99 | locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_RTS, 0); |
102 | else | 100 | else |
103 | locomo_gpio_write(uart_dev, LOCOMO_GPIO_RTS, 1); | 101 | locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_RTS, 1); |
104 | 102 | ||
105 | if (mctrl & TIOCM_DTR) | 103 | if (mctrl & TIOCM_DTR) |
106 | locomo_gpio_write(uart_dev, LOCOMO_GPIO_DTR, 0); | 104 | locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_DTR, 0); |
107 | else | 105 | else |
108 | locomo_gpio_write(uart_dev, LOCOMO_GPIO_DTR, 1); | 106 | locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_DTR, 1); |
109 | } | 107 | } |
110 | 108 | ||
111 | static u_int collie_uart_get_mctrl(struct uart_port *port) | 109 | static u_int collie_uart_get_mctrl(struct uart_port *port) |
112 | { | 110 | { |
113 | int ret = TIOCM_CD; | 111 | int ret = TIOCM_CD; |
114 | unsigned int r; | 112 | unsigned int r; |
115 | if (!uart_dev) return ret; | ||
116 | 113 | ||
117 | r = locomo_gpio_read_output(uart_dev, LOCOMO_GPIO_CTS & LOCOMO_GPIO_DSR); | 114 | r = locomo_gpio_read_output(&collie_locomo_device.dev, LOCOMO_GPIO_CTS & LOCOMO_GPIO_DSR); |
115 | if (r == -ENODEV) | ||
116 | return ret; | ||
118 | if (r & LOCOMO_GPIO_CTS) | 117 | if (r & LOCOMO_GPIO_CTS) |
119 | ret |= TIOCM_CTS; | 118 | ret |= TIOCM_CTS; |
120 | if (r & LOCOMO_GPIO_DSR) | 119 | if (r & LOCOMO_GPIO_DSR) |
@@ -130,13 +129,11 @@ static struct sa1100_port_fns collie_port_fns __initdata = { | |||
130 | 129 | ||
131 | static int collie_uart_probe(struct locomo_dev *dev) | 130 | static int collie_uart_probe(struct locomo_dev *dev) |
132 | { | 131 | { |
133 | uart_dev = dev; | ||
134 | return 0; | 132 | return 0; |
135 | } | 133 | } |
136 | 134 | ||
137 | static int collie_uart_remove(struct locomo_dev *dev) | 135 | static int collie_uart_remove(struct locomo_dev *dev) |
138 | { | 136 | { |
139 | uart_dev = NULL; | ||
140 | return 0; | 137 | return 0; |
141 | } | 138 | } |
142 | 139 | ||
@@ -170,7 +167,7 @@ static struct resource locomo_resources[] = { | |||
170 | }, | 167 | }, |
171 | }; | 168 | }; |
172 | 169 | ||
173 | static struct platform_device locomo_device = { | 170 | struct platform_device collie_locomo_device = { |
174 | .name = "locomo", | 171 | .name = "locomo", |
175 | .id = 0, | 172 | .id = 0, |
176 | .num_resources = ARRAY_SIZE(locomo_resources), | 173 | .num_resources = ARRAY_SIZE(locomo_resources), |
@@ -178,7 +175,7 @@ static struct platform_device locomo_device = { | |||
178 | }; | 175 | }; |
179 | 176 | ||
180 | static struct platform_device *devices[] __initdata = { | 177 | static struct platform_device *devices[] __initdata = { |
181 | &locomo_device, | 178 | &collie_locomo_device, |
182 | &colliescoop_device, | 179 | &colliescoop_device, |
183 | }; | 180 | }; |
184 | 181 | ||
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c index 7f45c7c3e673..f1179ad4be1b 100644 --- a/arch/arm/plat-omap/clock.c +++ b/arch/arm/plat-omap/clock.c | |||
@@ -100,6 +100,7 @@ void clk_disable(struct clk *clk) | |||
100 | return; | 100 | return; |
101 | 101 | ||
102 | spin_lock_irqsave(&clockfw_lock, flags); | 102 | spin_lock_irqsave(&clockfw_lock, flags); |
103 | BUG_ON(clk->usecount == 0); | ||
103 | if (arch_clock->clk_disable) | 104 | if (arch_clock->clk_disable) |
104 | arch_clock->clk_disable(clk); | 105 | arch_clock->clk_disable(clk); |
105 | spin_unlock_irqrestore(&clockfw_lock, flags); | 106 | spin_unlock_irqrestore(&clockfw_lock, flags); |
@@ -322,6 +323,31 @@ EXPORT_SYMBOL(clk_allow_idle); | |||
322 | 323 | ||
323 | /*-------------------------------------------------------------------------*/ | 324 | /*-------------------------------------------------------------------------*/ |
324 | 325 | ||
326 | #ifdef CONFIG_OMAP_RESET_CLOCKS | ||
327 | /* | ||
328 | * Disable any unused clocks left on by the bootloader | ||
329 | */ | ||
330 | static int __init clk_disable_unused(void) | ||
331 | { | ||
332 | struct clk *ck; | ||
333 | unsigned long flags; | ||
334 | |||
335 | list_for_each_entry(ck, &clocks, node) { | ||
336 | if (ck->usecount > 0 || (ck->flags & ALWAYS_ENABLED) || | ||
337 | ck->enable_reg == 0) | ||
338 | continue; | ||
339 | |||
340 | spin_lock_irqsave(&clockfw_lock, flags); | ||
341 | if (arch_clock->clk_disable_unused) | ||
342 | arch_clock->clk_disable_unused(ck); | ||
343 | spin_unlock_irqrestore(&clockfw_lock, flags); | ||
344 | } | ||
345 | |||
346 | return 0; | ||
347 | } | ||
348 | late_initcall(clk_disable_unused); | ||
349 | #endif | ||
350 | |||
325 | int __init clk_init(struct clk_functions * custom_clocks) | 351 | int __init clk_init(struct clk_functions * custom_clocks) |
326 | { | 352 | { |
327 | if (!custom_clocks) { | 353 | if (!custom_clocks) { |
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c index 1812f237d12f..dbc3f44e07a6 100644 --- a/arch/arm/plat-omap/devices.c +++ b/arch/arm/plat-omap/devices.c | |||
@@ -148,7 +148,7 @@ static inline void omap_init_kp(void) {} | |||
148 | 148 | ||
149 | #ifdef CONFIG_ARCH_OMAP24XX | 149 | #ifdef CONFIG_ARCH_OMAP24XX |
150 | #define OMAP_MMC1_BASE 0x4809c000 | 150 | #define OMAP_MMC1_BASE 0x4809c000 |
151 | #define OMAP_MMC1_INT 83 | 151 | #define OMAP_MMC1_INT INT_24XX_MMC_IRQ |
152 | #else | 152 | #else |
153 | #define OMAP_MMC1_BASE 0xfffb7800 | 153 | #define OMAP_MMC1_BASE 0xfffb7800 |
154 | #define OMAP_MMC1_INT INT_MMC | 154 | #define OMAP_MMC1_INT INT_MMC |
@@ -225,7 +225,14 @@ static void __init omap_init_mmc(void) | |||
225 | /* block 1 is always available and has just one pinout option */ | 225 | /* block 1 is always available and has just one pinout option */ |
226 | mmc = &mmc_conf->mmc[0]; | 226 | mmc = &mmc_conf->mmc[0]; |
227 | if (mmc->enabled) { | 227 | if (mmc->enabled) { |
228 | if (!cpu_is_omap24xx()) { | 228 | if (cpu_is_omap24xx()) { |
229 | omap_cfg_reg(H18_24XX_MMC_CMD); | ||
230 | omap_cfg_reg(H15_24XX_MMC_CLKI); | ||
231 | omap_cfg_reg(G19_24XX_MMC_CLKO); | ||
232 | omap_cfg_reg(F20_24XX_MMC_DAT0); | ||
233 | omap_cfg_reg(F19_24XX_MMC_DAT_DIR0); | ||
234 | omap_cfg_reg(G18_24XX_MMC_CMD_DIR); | ||
235 | } else { | ||
229 | omap_cfg_reg(MMC_CMD); | 236 | omap_cfg_reg(MMC_CMD); |
230 | omap_cfg_reg(MMC_CLK); | 237 | omap_cfg_reg(MMC_CLK); |
231 | omap_cfg_reg(MMC_DAT0); | 238 | omap_cfg_reg(MMC_DAT0); |
@@ -236,7 +243,14 @@ static void __init omap_init_mmc(void) | |||
236 | } | 243 | } |
237 | } | 244 | } |
238 | if (mmc->wire4) { | 245 | if (mmc->wire4) { |
239 | if (!cpu_is_omap24xx()) { | 246 | if (cpu_is_omap24xx()) { |
247 | omap_cfg_reg(H14_24XX_MMC_DAT1); | ||
248 | omap_cfg_reg(E19_24XX_MMC_DAT2); | ||
249 | omap_cfg_reg(D19_24XX_MMC_DAT3); | ||
250 | omap_cfg_reg(E20_24XX_MMC_DAT_DIR1); | ||
251 | omap_cfg_reg(F18_24XX_MMC_DAT_DIR2); | ||
252 | omap_cfg_reg(E18_24XX_MMC_DAT_DIR3); | ||
253 | } else { | ||
240 | omap_cfg_reg(MMC_DAT1); | 254 | omap_cfg_reg(MMC_DAT1); |
241 | /* NOTE: DAT2 can be on W10 (here) or M15 */ | 255 | /* NOTE: DAT2 can be on W10 (here) or M15 */ |
242 | if (!mmc->nomux) | 256 | if (!mmc->nomux) |
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index 9eddc9507147..1bbb431843ce 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c | |||
@@ -119,32 +119,41 @@ static void clear_lch_regs(int lch) | |||
119 | omap_writew(0, lch_base + i); | 119 | omap_writew(0, lch_base + i); |
120 | } | 120 | } |
121 | 121 | ||
122 | void omap_set_dma_priority(int dst_port, int priority) | 122 | void omap_set_dma_priority(int lch, int dst_port, int priority) |
123 | { | 123 | { |
124 | unsigned long reg; | 124 | unsigned long reg; |
125 | u32 l; | 125 | u32 l; |
126 | 126 | ||
127 | switch (dst_port) { | 127 | if (cpu_class_is_omap1()) { |
128 | case OMAP_DMA_PORT_OCP_T1: /* FFFECC00 */ | 128 | switch (dst_port) { |
129 | reg = OMAP_TC_OCPT1_PRIOR; | 129 | case OMAP_DMA_PORT_OCP_T1: /* FFFECC00 */ |
130 | break; | 130 | reg = OMAP_TC_OCPT1_PRIOR; |
131 | case OMAP_DMA_PORT_OCP_T2: /* FFFECCD0 */ | 131 | break; |
132 | reg = OMAP_TC_OCPT2_PRIOR; | 132 | case OMAP_DMA_PORT_OCP_T2: /* FFFECCD0 */ |
133 | break; | 133 | reg = OMAP_TC_OCPT2_PRIOR; |
134 | case OMAP_DMA_PORT_EMIFF: /* FFFECC08 */ | 134 | break; |
135 | reg = OMAP_TC_EMIFF_PRIOR; | 135 | case OMAP_DMA_PORT_EMIFF: /* FFFECC08 */ |
136 | break; | 136 | reg = OMAP_TC_EMIFF_PRIOR; |
137 | case OMAP_DMA_PORT_EMIFS: /* FFFECC04 */ | 137 | break; |
138 | reg = OMAP_TC_EMIFS_PRIOR; | 138 | case OMAP_DMA_PORT_EMIFS: /* FFFECC04 */ |
139 | break; | 139 | reg = OMAP_TC_EMIFS_PRIOR; |
140 | default: | 140 | break; |
141 | BUG(); | 141 | default: |
142 | return; | 142 | BUG(); |
143 | return; | ||
144 | } | ||
145 | l = omap_readl(reg); | ||
146 | l &= ~(0xf << 8); | ||
147 | l |= (priority & 0xf) << 8; | ||
148 | omap_writel(l, reg); | ||
149 | } | ||
150 | |||
151 | if (cpu_is_omap24xx()) { | ||
152 | if (priority) | ||
153 | OMAP_DMA_CCR_REG(lch) |= (1 << 6); | ||
154 | else | ||
155 | OMAP_DMA_CCR_REG(lch) &= ~(1 << 6); | ||
143 | } | 156 | } |
144 | l = omap_readl(reg); | ||
145 | l &= ~(0xf << 8); | ||
146 | l |= (priority & 0xf) << 8; | ||
147 | omap_writel(l, reg); | ||
148 | } | 157 | } |
149 | 158 | ||
150 | void omap_set_dma_transfer_params(int lch, int data_type, int elem_count, | 159 | void omap_set_dma_transfer_params(int lch, int data_type, int elem_count, |
@@ -234,6 +243,14 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color) | |||
234 | OMAP1_DMA_LCH_CTRL_REG(lch) = w; | 243 | OMAP1_DMA_LCH_CTRL_REG(lch) = w; |
235 | } | 244 | } |
236 | 245 | ||
246 | void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode) | ||
247 | { | ||
248 | if (cpu_is_omap24xx()) { | ||
249 | OMAP_DMA_CSDP_REG(lch) &= ~(0x3 << 16); | ||
250 | OMAP_DMA_CSDP_REG(lch) |= (mode << 16); | ||
251 | } | ||
252 | } | ||
253 | |||
237 | /* Note that src_port is only for omap1 */ | 254 | /* Note that src_port is only for omap1 */ |
238 | void omap_set_dma_src_params(int lch, int src_port, int src_amode, | 255 | void omap_set_dma_src_params(int lch, int src_port, int src_amode, |
239 | unsigned long src_start, | 256 | unsigned long src_start, |
@@ -698,6 +715,32 @@ void omap_stop_dma(int lch) | |||
698 | } | 715 | } |
699 | 716 | ||
700 | /* | 717 | /* |
718 | * Allows changing the DMA callback function or data. This may be needed if | ||
719 | * the driver shares a single DMA channel for multiple dma triggers. | ||
720 | */ | ||
721 | int omap_set_dma_callback(int lch, | ||
722 | void (* callback)(int lch, u16 ch_status, void *data), | ||
723 | void *data) | ||
724 | { | ||
725 | unsigned long flags; | ||
726 | |||
727 | if (lch < 0) | ||
728 | return -ENODEV; | ||
729 | |||
730 | spin_lock_irqsave(&dma_chan_lock, flags); | ||
731 | if (dma_chan[lch].dev_id == -1) { | ||
732 | printk(KERN_ERR "DMA callback for not set for free channel\n"); | ||
733 | spin_unlock_irqrestore(&dma_chan_lock, flags); | ||
734 | return -EINVAL; | ||
735 | } | ||
736 | dma_chan[lch].callback = callback; | ||
737 | dma_chan[lch].data = data; | ||
738 | spin_unlock_irqrestore(&dma_chan_lock, flags); | ||
739 | |||
740 | return 0; | ||
741 | } | ||
742 | |||
743 | /* | ||
701 | * Returns current physical source address for the given DMA channel. | 744 | * Returns current physical source address for the given DMA channel. |
702 | * If the channel is running the caller must disable interrupts prior calling | 745 | * If the channel is running the caller must disable interrupts prior calling |
703 | * this function and process the returned value before re-enabling interrupt to | 746 | * this function and process the returned value before re-enabling interrupt to |
@@ -1339,6 +1382,14 @@ static int __init omap_init_dma(void) | |||
1339 | dma_chan_count = 16; | 1382 | dma_chan_count = 16; |
1340 | } else | 1383 | } else |
1341 | dma_chan_count = 9; | 1384 | dma_chan_count = 9; |
1385 | if (cpu_is_omap16xx()) { | ||
1386 | u16 w; | ||
1387 | |||
1388 | /* this would prevent OMAP sleep */ | ||
1389 | w = omap_readw(OMAP1610_DMA_LCD_CTRL); | ||
1390 | w &= ~(1 << 8); | ||
1391 | omap_writew(w, OMAP1610_DMA_LCD_CTRL); | ||
1392 | } | ||
1342 | } else if (cpu_is_omap24xx()) { | 1393 | } else if (cpu_is_omap24xx()) { |
1343 | u8 revision = omap_readb(OMAP_DMA4_REVISION); | 1394 | u8 revision = omap_readb(OMAP_DMA4_REVISION); |
1344 | printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n", | 1395 | printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n", |
@@ -1414,11 +1465,13 @@ EXPORT_SYMBOL(omap_request_dma); | |||
1414 | EXPORT_SYMBOL(omap_free_dma); | 1465 | EXPORT_SYMBOL(omap_free_dma); |
1415 | EXPORT_SYMBOL(omap_start_dma); | 1466 | EXPORT_SYMBOL(omap_start_dma); |
1416 | EXPORT_SYMBOL(omap_stop_dma); | 1467 | EXPORT_SYMBOL(omap_stop_dma); |
1468 | EXPORT_SYMBOL(omap_set_dma_callback); | ||
1417 | EXPORT_SYMBOL(omap_enable_dma_irq); | 1469 | EXPORT_SYMBOL(omap_enable_dma_irq); |
1418 | EXPORT_SYMBOL(omap_disable_dma_irq); | 1470 | EXPORT_SYMBOL(omap_disable_dma_irq); |
1419 | 1471 | ||
1420 | EXPORT_SYMBOL(omap_set_dma_transfer_params); | 1472 | EXPORT_SYMBOL(omap_set_dma_transfer_params); |
1421 | EXPORT_SYMBOL(omap_set_dma_color_mode); | 1473 | EXPORT_SYMBOL(omap_set_dma_color_mode); |
1474 | EXPORT_SYMBOL(omap_set_dma_write_mode); | ||
1422 | 1475 | ||
1423 | EXPORT_SYMBOL(omap_set_dma_src_params); | 1476 | EXPORT_SYMBOL(omap_set_dma_src_params); |
1424 | EXPORT_SYMBOL(omap_set_dma_src_index); | 1477 | EXPORT_SYMBOL(omap_set_dma_src_index); |
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index 50524436de63..bcbb8d7392be 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c | |||
@@ -75,10 +75,14 @@ struct omap_dm_timer { | |||
75 | #endif | 75 | #endif |
76 | void __iomem *io_base; | 76 | void __iomem *io_base; |
77 | unsigned reserved:1; | 77 | unsigned reserved:1; |
78 | unsigned enabled:1; | ||
78 | }; | 79 | }; |
79 | 80 | ||
80 | #ifdef CONFIG_ARCH_OMAP1 | 81 | #ifdef CONFIG_ARCH_OMAP1 |
81 | 82 | ||
83 | #define omap_dm_clk_enable(x) | ||
84 | #define omap_dm_clk_disable(x) | ||
85 | |||
82 | static struct omap_dm_timer dm_timers[] = { | 86 | static struct omap_dm_timer dm_timers[] = { |
83 | { .phys_base = 0xfffb1400, .irq = INT_1610_GPTIMER1 }, | 87 | { .phys_base = 0xfffb1400, .irq = INT_1610_GPTIMER1 }, |
84 | { .phys_base = 0xfffb1c00, .irq = INT_1610_GPTIMER2 }, | 88 | { .phys_base = 0xfffb1c00, .irq = INT_1610_GPTIMER2 }, |
@@ -92,6 +96,9 @@ static struct omap_dm_timer dm_timers[] = { | |||
92 | 96 | ||
93 | #elif defined(CONFIG_ARCH_OMAP2) | 97 | #elif defined(CONFIG_ARCH_OMAP2) |
94 | 98 | ||
99 | #define omap_dm_clk_enable(x) clk_enable(x) | ||
100 | #define omap_dm_clk_disable(x) clk_disable(x) | ||
101 | |||
95 | static struct omap_dm_timer dm_timers[] = { | 102 | static struct omap_dm_timer dm_timers[] = { |
96 | { .phys_base = 0x48028000, .irq = INT_24XX_GPTIMER1 }, | 103 | { .phys_base = 0x48028000, .irq = INT_24XX_GPTIMER1 }, |
97 | { .phys_base = 0x4802a000, .irq = INT_24XX_GPTIMER2 }, | 104 | { .phys_base = 0x4802a000, .irq = INT_24XX_GPTIMER2 }, |
@@ -154,24 +161,28 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer) | |||
154 | { | 161 | { |
155 | u32 l; | 162 | u32 l; |
156 | 163 | ||
157 | if (timer != &dm_timers[0]) { | 164 | if (!cpu_class_is_omap2() || timer != &dm_timers[0]) { |
158 | omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06); | 165 | omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06); |
159 | omap_dm_timer_wait_for_reset(timer); | 166 | omap_dm_timer_wait_for_reset(timer); |
160 | } | 167 | } |
161 | omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_SYS_CLK); | 168 | omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ); |
162 | 169 | ||
163 | /* Set to smart-idle mode */ | 170 | /* Set to smart-idle mode */ |
164 | l = omap_dm_timer_read_reg(timer, OMAP_TIMER_OCP_CFG_REG); | 171 | l = omap_dm_timer_read_reg(timer, OMAP_TIMER_OCP_CFG_REG); |
165 | l |= 0x02 << 3; | 172 | l |= 0x02 << 3; |
173 | |||
174 | if (cpu_class_is_omap2() && timer == &dm_timers[0]) { | ||
175 | /* Enable wake-up only for GPT1 on OMAP2 CPUs*/ | ||
176 | l |= 1 << 2; | ||
177 | /* Non-posted mode */ | ||
178 | omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0); | ||
179 | } | ||
166 | omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_REG, l); | 180 | omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_REG, l); |
167 | } | 181 | } |
168 | 182 | ||
169 | static void omap_dm_timer_prepare(struct omap_dm_timer *timer) | 183 | static void omap_dm_timer_prepare(struct omap_dm_timer *timer) |
170 | { | 184 | { |
171 | #ifdef CONFIG_ARCH_OMAP2 | 185 | omap_dm_timer_enable(timer); |
172 | clk_enable(timer->iclk); | ||
173 | clk_enable(timer->fclk); | ||
174 | #endif | ||
175 | omap_dm_timer_reset(timer); | 186 | omap_dm_timer_reset(timer); |
176 | } | 187 | } |
177 | 188 | ||
@@ -223,15 +234,36 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id) | |||
223 | 234 | ||
224 | void omap_dm_timer_free(struct omap_dm_timer *timer) | 235 | void omap_dm_timer_free(struct omap_dm_timer *timer) |
225 | { | 236 | { |
237 | omap_dm_timer_enable(timer); | ||
226 | omap_dm_timer_reset(timer); | 238 | omap_dm_timer_reset(timer); |
227 | #ifdef CONFIG_ARCH_OMAP2 | 239 | omap_dm_timer_disable(timer); |
228 | clk_disable(timer->iclk); | 240 | |
229 | clk_disable(timer->fclk); | ||
230 | #endif | ||
231 | WARN_ON(!timer->reserved); | 241 | WARN_ON(!timer->reserved); |
232 | timer->reserved = 0; | 242 | timer->reserved = 0; |
233 | } | 243 | } |
234 | 244 | ||
245 | void omap_dm_timer_enable(struct omap_dm_timer *timer) | ||
246 | { | ||
247 | if (timer->enabled) | ||
248 | return; | ||
249 | |||
250 | omap_dm_clk_enable(timer->fclk); | ||
251 | omap_dm_clk_enable(timer->iclk); | ||
252 | |||
253 | timer->enabled = 1; | ||
254 | } | ||
255 | |||
256 | void omap_dm_timer_disable(struct omap_dm_timer *timer) | ||
257 | { | ||
258 | if (!timer->enabled) | ||
259 | return; | ||
260 | |||
261 | omap_dm_clk_disable(timer->iclk); | ||
262 | omap_dm_clk_disable(timer->fclk); | ||
263 | |||
264 | timer->enabled = 0; | ||
265 | } | ||
266 | |||
235 | int omap_dm_timer_get_irq(struct omap_dm_timer *timer) | 267 | int omap_dm_timer_get_irq(struct omap_dm_timer *timer) |
236 | { | 268 | { |
237 | return timer->irq; | 269 | return timer->irq; |
@@ -276,7 +308,7 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask) | |||
276 | 308 | ||
277 | struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer) | 309 | struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer) |
278 | { | 310 | { |
279 | return timer->fclk; | 311 | return timer->fclk; |
280 | } | 312 | } |
281 | 313 | ||
282 | __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask) | 314 | __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask) |
@@ -406,11 +438,16 @@ void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, | |||
406 | unsigned int value) | 438 | unsigned int value) |
407 | { | 439 | { |
408 | omap_dm_timer_write_reg(timer, OMAP_TIMER_INT_EN_REG, value); | 440 | omap_dm_timer_write_reg(timer, OMAP_TIMER_INT_EN_REG, value); |
441 | omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, value); | ||
409 | } | 442 | } |
410 | 443 | ||
411 | unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer) | 444 | unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer) |
412 | { | 445 | { |
413 | return omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG); | 446 | unsigned int l; |
447 | |||
448 | l = omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG); | ||
449 | |||
450 | return l; | ||
414 | } | 451 | } |
415 | 452 | ||
416 | void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value) | 453 | void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value) |
@@ -420,12 +457,16 @@ void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value) | |||
420 | 457 | ||
421 | unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer) | 458 | unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer) |
422 | { | 459 | { |
423 | return omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG); | 460 | unsigned int l; |
461 | |||
462 | l = omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG); | ||
463 | |||
464 | return l; | ||
424 | } | 465 | } |
425 | 466 | ||
426 | void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value) | 467 | void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value) |
427 | { | 468 | { |
428 | return omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value); | 469 | omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value); |
429 | } | 470 | } |
430 | 471 | ||
431 | int omap_dm_timers_active(void) | 472 | int omap_dm_timers_active(void) |
@@ -436,9 +477,14 @@ int omap_dm_timers_active(void) | |||
436 | struct omap_dm_timer *timer; | 477 | struct omap_dm_timer *timer; |
437 | 478 | ||
438 | timer = &dm_timers[i]; | 479 | timer = &dm_timers[i]; |
480 | |||
481 | if (!timer->enabled) | ||
482 | continue; | ||
483 | |||
439 | if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) & | 484 | if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) & |
440 | OMAP_TIMER_CTRL_ST) | 485 | OMAP_TIMER_CTRL_ST) { |
441 | return 1; | 486 | return 1; |
487 | } | ||
442 | } | 488 | } |
443 | return 0; | 489 | return 0; |
444 | } | 490 | } |
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index cd7f973fb286..f55f99ae58ae 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c | |||
@@ -94,6 +94,8 @@ | |||
94 | #define OMAP24XX_GPIO_SYSCONFIG 0x0010 | 94 | #define OMAP24XX_GPIO_SYSCONFIG 0x0010 |
95 | #define OMAP24XX_GPIO_SYSSTATUS 0x0014 | 95 | #define OMAP24XX_GPIO_SYSSTATUS 0x0014 |
96 | #define OMAP24XX_GPIO_IRQSTATUS1 0x0018 | 96 | #define OMAP24XX_GPIO_IRQSTATUS1 0x0018 |
97 | #define OMAP24XX_GPIO_IRQSTATUS2 0x0028 | ||
98 | #define OMAP24XX_GPIO_IRQENABLE2 0x002c | ||
97 | #define OMAP24XX_GPIO_IRQENABLE1 0x001c | 99 | #define OMAP24XX_GPIO_IRQENABLE1 0x001c |
98 | #define OMAP24XX_GPIO_CTRL 0x0030 | 100 | #define OMAP24XX_GPIO_CTRL 0x0030 |
99 | #define OMAP24XX_GPIO_OE 0x0034 | 101 | #define OMAP24XX_GPIO_OE 0x0034 |
@@ -110,8 +112,6 @@ | |||
110 | #define OMAP24XX_GPIO_CLEARDATAOUT 0x0090 | 112 | #define OMAP24XX_GPIO_CLEARDATAOUT 0x0090 |
111 | #define OMAP24XX_GPIO_SETDATAOUT 0x0094 | 113 | #define OMAP24XX_GPIO_SETDATAOUT 0x0094 |
112 | 114 | ||
113 | #define OMAP_MPUIO_MASK (~OMAP_MAX_GPIO_LINES & 0xff) | ||
114 | |||
115 | struct gpio_bank { | 115 | struct gpio_bank { |
116 | void __iomem *base; | 116 | void __iomem *base; |
117 | u16 irq; | 117 | u16 irq; |
@@ -216,11 +216,13 @@ static inline int gpio_valid(int gpio) | |||
216 | { | 216 | { |
217 | if (gpio < 0) | 217 | if (gpio < 0) |
218 | return -1; | 218 | return -1; |
219 | #ifndef CONFIG_ARCH_OMAP24XX | ||
219 | if (OMAP_GPIO_IS_MPUIO(gpio)) { | 220 | if (OMAP_GPIO_IS_MPUIO(gpio)) { |
220 | if ((gpio & OMAP_MPUIO_MASK) > 16) | 221 | if (gpio >= OMAP_MAX_GPIO_LINES + 16) |
221 | return -1; | 222 | return -1; |
222 | return 0; | 223 | return 0; |
223 | } | 224 | } |
225 | #endif | ||
224 | #ifdef CONFIG_ARCH_OMAP15XX | 226 | #ifdef CONFIG_ARCH_OMAP15XX |
225 | if (cpu_is_omap15xx() && gpio < 16) | 227 | if (cpu_is_omap15xx() && gpio < 16) |
226 | return 0; | 228 | return 0; |
@@ -529,6 +531,10 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) | |||
529 | return; | 531 | return; |
530 | } | 532 | } |
531 | __raw_writel(gpio_mask, reg); | 533 | __raw_writel(gpio_mask, reg); |
534 | |||
535 | /* Workaround for clearing DSP GPIO interrupts to allow retention */ | ||
536 | if (cpu_is_omap2420()) | ||
537 | __raw_writel(gpio_mask, bank->base + OMAP24XX_GPIO_IRQSTATUS2); | ||
532 | } | 538 | } |
533 | 539 | ||
534 | static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio) | 540 | static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio) |
@@ -662,6 +668,14 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) | |||
662 | } | 668 | } |
663 | } | 669 | } |
664 | 670 | ||
671 | static void _reset_gpio(struct gpio_bank *bank, int gpio) | ||
672 | { | ||
673 | _set_gpio_direction(bank, get_gpio_index(gpio), 1); | ||
674 | _set_gpio_irqenable(bank, gpio, 0); | ||
675 | _clear_gpio_irqstatus(bank, gpio); | ||
676 | _set_gpio_triggering(bank, get_gpio_index(gpio), IRQT_NOEDGE); | ||
677 | } | ||
678 | |||
665 | /* Use disable_irq_wake() and enable_irq_wake() functions from drivers */ | 679 | /* Use disable_irq_wake() and enable_irq_wake() functions from drivers */ |
666 | static int gpio_wake_enable(unsigned int irq, unsigned int enable) | 680 | static int gpio_wake_enable(unsigned int irq, unsigned int enable) |
667 | { | 681 | { |
@@ -672,9 +686,7 @@ static int gpio_wake_enable(unsigned int irq, unsigned int enable) | |||
672 | if (check_gpio(gpio) < 0) | 686 | if (check_gpio(gpio) < 0) |
673 | return -ENODEV; | 687 | return -ENODEV; |
674 | bank = get_gpio_bank(gpio); | 688 | bank = get_gpio_bank(gpio); |
675 | spin_lock(&bank->lock); | ||
676 | retval = _set_gpio_wakeup(bank, get_gpio_index(gpio), enable); | 689 | retval = _set_gpio_wakeup(bank, get_gpio_index(gpio), enable); |
677 | spin_unlock(&bank->lock); | ||
678 | 690 | ||
679 | return retval; | 691 | return retval; |
680 | } | 692 | } |
@@ -696,7 +708,9 @@ int omap_request_gpio(int gpio) | |||
696 | } | 708 | } |
697 | bank->reserved_map |= (1 << get_gpio_index(gpio)); | 709 | bank->reserved_map |= (1 << get_gpio_index(gpio)); |
698 | 710 | ||
699 | /* Set trigger to none. You need to enable the trigger after request_irq */ | 711 | /* Set trigger to none. You need to enable the desired trigger with |
712 | * request_irq() or set_irq_type(). | ||
713 | */ | ||
700 | _set_gpio_triggering(bank, get_gpio_index(gpio), IRQT_NOEDGE); | 714 | _set_gpio_triggering(bank, get_gpio_index(gpio), IRQT_NOEDGE); |
701 | 715 | ||
702 | #ifdef CONFIG_ARCH_OMAP15XX | 716 | #ifdef CONFIG_ARCH_OMAP15XX |
@@ -756,9 +770,7 @@ void omap_free_gpio(int gpio) | |||
756 | } | 770 | } |
757 | #endif | 771 | #endif |
758 | bank->reserved_map &= ~(1 << get_gpio_index(gpio)); | 772 | bank->reserved_map &= ~(1 << get_gpio_index(gpio)); |
759 | _set_gpio_direction(bank, get_gpio_index(gpio), 1); | 773 | _reset_gpio(bank, gpio); |
760 | _set_gpio_irqenable(bank, gpio, 0); | ||
761 | _clear_gpio_irqstatus(bank, gpio); | ||
762 | spin_unlock(&bank->lock); | 774 | spin_unlock(&bank->lock); |
763 | } | 775 | } |
764 | 776 | ||
@@ -898,6 +910,14 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc, | |||
898 | 910 | ||
899 | } | 911 | } |
900 | 912 | ||
913 | static void gpio_irq_shutdown(unsigned int irq) | ||
914 | { | ||
915 | unsigned int gpio = irq - IH_GPIO_BASE; | ||
916 | struct gpio_bank *bank = get_gpio_bank(gpio); | ||
917 | |||
918 | _reset_gpio(bank, gpio); | ||
919 | } | ||
920 | |||
901 | static void gpio_ack_irq(unsigned int irq) | 921 | static void gpio_ack_irq(unsigned int irq) |
902 | { | 922 | { |
903 | unsigned int gpio = irq - IH_GPIO_BASE; | 923 | unsigned int gpio = irq - IH_GPIO_BASE; |
@@ -946,6 +966,7 @@ static void mpuio_unmask_irq(unsigned int irq) | |||
946 | 966 | ||
947 | static struct irq_chip gpio_irq_chip = { | 967 | static struct irq_chip gpio_irq_chip = { |
948 | .name = "GPIO", | 968 | .name = "GPIO", |
969 | .shutdown = gpio_irq_shutdown, | ||
949 | .ack = gpio_ack_irq, | 970 | .ack = gpio_ack_irq, |
950 | .mask = gpio_mask_irq, | 971 | .mask = gpio_mask_irq, |
951 | .unmask = gpio_unmask_irq, | 972 | .unmask = gpio_unmask_irq, |
@@ -985,7 +1006,7 @@ static int __init _omap_gpio_init(void) | |||
985 | else | 1006 | else |
986 | clk_enable(gpio_ick); | 1007 | clk_enable(gpio_ick); |
987 | gpio_fck = clk_get(NULL, "gpios_fck"); | 1008 | gpio_fck = clk_get(NULL, "gpios_fck"); |
988 | if (IS_ERR(gpio_ick)) | 1009 | if (IS_ERR(gpio_fck)) |
989 | printk("Could not get gpios_fck\n"); | 1010 | printk("Could not get gpios_fck\n"); |
990 | else | 1011 | else |
991 | clk_enable(gpio_fck); | 1012 | clk_enable(gpio_fck); |
@@ -1144,8 +1165,8 @@ static int omap_gpio_resume(struct sys_device *dev) | |||
1144 | wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; | 1165 | wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; |
1145 | break; | 1166 | break; |
1146 | case METHOD_GPIO_24XX: | 1167 | case METHOD_GPIO_24XX: |
1147 | wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA; | 1168 | wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA; |
1148 | wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; | 1169 | wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA; |
1149 | break; | 1170 | break; |
1150 | default: | 1171 | default: |
1151 | continue; | 1172 | continue; |
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index 196aac3ac329..ade9a0fa6ef6 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c | |||
@@ -75,8 +75,6 @@ static struct clk *mcbsp1_ick = 0; | |||
75 | static struct clk *mcbsp1_fck = 0; | 75 | static struct clk *mcbsp1_fck = 0; |
76 | static struct clk *mcbsp2_ick = 0; | 76 | static struct clk *mcbsp2_ick = 0; |
77 | static struct clk *mcbsp2_fck = 0; | 77 | static struct clk *mcbsp2_fck = 0; |
78 | static struct clk *sys_ck = 0; | ||
79 | static struct clk *sys_clkout = 0; | ||
80 | #endif | 78 | #endif |
81 | 79 | ||
82 | static void omap_mcbsp_dump_reg(u8 id) | 80 | static void omap_mcbsp_dump_reg(u8 id) |
@@ -232,7 +230,6 @@ static void omap2_mcbsp2_mux_setup(void) | |||
232 | omap_cfg_reg(W15_24XX_MCBSP2_DR); | 230 | omap_cfg_reg(W15_24XX_MCBSP2_DR); |
233 | omap_cfg_reg(V15_24XX_MCBSP2_DX); | 231 | omap_cfg_reg(V15_24XX_MCBSP2_DX); |
234 | omap_cfg_reg(V14_24XX_GPIO117); | 232 | omap_cfg_reg(V14_24XX_GPIO117); |
235 | omap_cfg_reg(W14_24XX_SYS_CLKOUT); | ||
236 | } | 233 | } |
237 | #endif | 234 | #endif |
238 | 235 | ||
@@ -984,13 +981,7 @@ static int __init omap_mcbsp_init(void) | |||
984 | if (cpu_is_omap24xx()) { | 981 | if (cpu_is_omap24xx()) { |
985 | mcbsp_info = mcbsp_24xx; | 982 | mcbsp_info = mcbsp_24xx; |
986 | mcbsp_count = ARRAY_SIZE(mcbsp_24xx); | 983 | mcbsp_count = ARRAY_SIZE(mcbsp_24xx); |
987 | |||
988 | /* REVISIT: where's the right place? */ | ||
989 | omap2_mcbsp2_mux_setup(); | 984 | omap2_mcbsp2_mux_setup(); |
990 | sys_ck = clk_get(0, "sys_ck"); | ||
991 | sys_clkout = clk_get(0, "sys_clkout"); | ||
992 | clk_set_parent(sys_clkout, sys_ck); | ||
993 | clk_enable(sys_clkout); | ||
994 | } | 985 | } |
995 | #endif | 986 | #endif |
996 | for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) { | 987 | for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) { |
diff --git a/arch/arm/plat-omap/pm.c b/arch/arm/plat-omap/pm.c deleted file mode 100644 index 04b4102727a8..000000000000 --- a/arch/arm/plat-omap/pm.c +++ /dev/null | |||
@@ -1,670 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/plat-omap/pm.c | ||
3 | * | ||
4 | * OMAP Power Management Routines | ||
5 | * | ||
6 | * Original code for the SA11x0: | ||
7 | * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com> | ||
8 | * | ||
9 | * Modified for the PXA250 by Nicolas Pitre: | ||
10 | * Copyright (c) 2002 Monta Vista Software, Inc. | ||
11 | * | ||
12 | * Modified for the OMAP1510 by David Singleton: | ||
13 | * Copyright (c) 2002 Monta Vista Software, Inc. | ||
14 | * | ||
15 | * Cleanup 2004 for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.com> | ||
16 | * | ||
17 | * This program is free software; you can redistribute it and/or modify it | ||
18 | * under the terms of the GNU General Public License as published by the | ||
19 | * Free Software Foundation; either version 2 of the License, or (at your | ||
20 | * option) any later version. | ||
21 | * | ||
22 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
23 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
24 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
25 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
27 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
28 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
29 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
31 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
32 | * | ||
33 | * You should have received a copy of the GNU General Public License along | ||
34 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
35 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
36 | */ | ||
37 | |||
38 | #include <linux/pm.h> | ||
39 | #include <linux/sched.h> | ||
40 | #include <linux/proc_fs.h> | ||
41 | #include <linux/pm.h> | ||
42 | #include <linux/interrupt.h> | ||
43 | |||
44 | #include <asm/io.h> | ||
45 | #include <asm/irq.h> | ||
46 | #include <asm/mach/time.h> | ||
47 | #include <asm/mach/irq.h> | ||
48 | |||
49 | #include <asm/mach-types.h> | ||
50 | #include <asm/arch/irqs.h> | ||
51 | #include <asm/arch/tc.h> | ||
52 | #include <asm/arch/pm.h> | ||
53 | #include <asm/arch/mux.h> | ||
54 | #include <asm/arch/tps65010.h> | ||
55 | #include <asm/arch/dsp_common.h> | ||
56 | |||
57 | #include <asm/arch/clock.h> | ||
58 | #include <asm/arch/sram.h> | ||
59 | |||
60 | static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE]; | ||
61 | static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE]; | ||
62 | static unsigned int mpui730_sleep_save[MPUI730_SLEEP_SAVE_SIZE]; | ||
63 | static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE]; | ||
64 | static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE]; | ||
65 | |||
66 | static void (*omap_sram_idle)(void) = NULL; | ||
67 | static void (*omap_sram_suspend)(unsigned long r0, unsigned long r1) = NULL; | ||
68 | |||
69 | /* | ||
70 | * Let's power down on idle, but only if we are really | ||
71 | * idle, because once we start down the path of | ||
72 | * going idle we continue to do idle even if we get | ||
73 | * a clock tick interrupt . . | ||
74 | */ | ||
75 | void omap_pm_idle(void) | ||
76 | { | ||
77 | unsigned int mask32 = 0; | ||
78 | |||
79 | /* | ||
80 | * If the DSP is being used let's just idle the CPU, the overhead | ||
81 | * to wake up from Big Sleep is big, milliseconds versus micro | ||
82 | * seconds for wait for interrupt. | ||
83 | */ | ||
84 | |||
85 | local_irq_disable(); | ||
86 | local_fiq_disable(); | ||
87 | if (need_resched()) { | ||
88 | local_fiq_enable(); | ||
89 | local_irq_enable(); | ||
90 | return; | ||
91 | } | ||
92 | mask32 = omap_readl(ARM_SYSST); | ||
93 | |||
94 | /* | ||
95 | * Prevent the ULPD from entering low power state by setting | ||
96 | * POWER_CTRL_REG:4 = 0 | ||
97 | */ | ||
98 | omap_writew(omap_readw(ULPD_POWER_CTRL) & | ||
99 | ~ULPD_DEEP_SLEEP_TRANSITION_EN, ULPD_POWER_CTRL); | ||
100 | |||
101 | /* | ||
102 | * Since an interrupt may set up a timer, we don't want to | ||
103 | * reprogram the hardware timer with interrupts enabled. | ||
104 | * Re-enable interrupts only after returning from idle. | ||
105 | */ | ||
106 | timer_dyn_reprogram(); | ||
107 | |||
108 | if ((mask32 & DSP_IDLE) == 0) { | ||
109 | __asm__ volatile ("mcr p15, 0, r0, c7, c0, 4"); | ||
110 | } else | ||
111 | omap_sram_idle(); | ||
112 | |||
113 | local_fiq_enable(); | ||
114 | local_irq_enable(); | ||
115 | } | ||
116 | |||
117 | /* | ||
118 | * Configuration of the wakeup event is board specific. For the | ||
119 | * moment we put it into this helper function. Later it may move | ||
120 | * to board specific files. | ||
121 | */ | ||
122 | static void omap_pm_wakeup_setup(void) | ||
123 | { | ||
124 | u32 level1_wake = 0; | ||
125 | u32 level2_wake = OMAP_IRQ_BIT(INT_UART2); | ||
126 | |||
127 | /* | ||
128 | * Turn off all interrupts except GPIO bank 1, L1-2nd level cascade, | ||
129 | * and the L2 wakeup interrupts: keypad and UART2. Note that the | ||
130 | * drivers must still separately call omap_set_gpio_wakeup() to | ||
131 | * wake up to a GPIO interrupt. | ||
132 | */ | ||
133 | if (cpu_is_omap730()) | ||
134 | level1_wake = OMAP_IRQ_BIT(INT_730_GPIO_BANK1) | | ||
135 | OMAP_IRQ_BIT(INT_730_IH2_IRQ); | ||
136 | else if (cpu_is_omap1510()) | ||
137 | level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) | | ||
138 | OMAP_IRQ_BIT(INT_1510_IH2_IRQ); | ||
139 | else if (cpu_is_omap16xx()) | ||
140 | level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) | | ||
141 | OMAP_IRQ_BIT(INT_1610_IH2_IRQ); | ||
142 | |||
143 | omap_writel(~level1_wake, OMAP_IH1_MIR); | ||
144 | |||
145 | if (cpu_is_omap730()) { | ||
146 | omap_writel(~level2_wake, OMAP_IH2_0_MIR); | ||
147 | omap_writel(~(OMAP_IRQ_BIT(INT_730_WAKE_UP_REQ) | OMAP_IRQ_BIT(INT_730_MPUIO_KEYPAD)), OMAP_IH2_1_MIR); | ||
148 | } else if (cpu_is_omap1510()) { | ||
149 | level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD); | ||
150 | omap_writel(~level2_wake, OMAP_IH2_MIR); | ||
151 | } else if (cpu_is_omap16xx()) { | ||
152 | level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD); | ||
153 | omap_writel(~level2_wake, OMAP_IH2_0_MIR); | ||
154 | |||
155 | /* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */ | ||
156 | omap_writel(~OMAP_IRQ_BIT(INT_1610_WAKE_UP_REQ), OMAP_IH2_1_MIR); | ||
157 | omap_writel(~0x0, OMAP_IH2_2_MIR); | ||
158 | omap_writel(~0x0, OMAP_IH2_3_MIR); | ||
159 | } | ||
160 | |||
161 | /* New IRQ agreement, recalculate in cascade order */ | ||
162 | omap_writel(1, OMAP_IH2_CONTROL); | ||
163 | omap_writel(1, OMAP_IH1_CONTROL); | ||
164 | } | ||
165 | |||
166 | void omap_pm_suspend(void) | ||
167 | { | ||
168 | unsigned long arg0 = 0, arg1 = 0; | ||
169 | |||
170 | printk("PM: OMAP%x is trying to enter deep sleep...\n", system_rev); | ||
171 | |||
172 | omap_serial_wake_trigger(1); | ||
173 | |||
174 | if (machine_is_omap_osk()) { | ||
175 | /* Stop LED1 (D9) blink */ | ||
176 | tps65010_set_led(LED1, OFF); | ||
177 | } | ||
178 | |||
179 | omap_writew(0xffff, ULPD_SOFT_DISABLE_REQ_REG); | ||
180 | |||
181 | /* | ||
182 | * Step 1: turn off interrupts (FIXME: NOTE: already disabled) | ||
183 | */ | ||
184 | |||
185 | local_irq_disable(); | ||
186 | local_fiq_disable(); | ||
187 | |||
188 | /* | ||
189 | * Step 2: save registers | ||
190 | * | ||
191 | * The omap is a strange/beautiful device. The caches, memory | ||
192 | * and register state are preserved across power saves. | ||
193 | * We have to save and restore very little register state to | ||
194 | * idle the omap. | ||
195 | * | ||
196 | * Save interrupt, MPUI, ARM and UPLD control registers. | ||
197 | */ | ||
198 | |||
199 | if (cpu_is_omap730()) { | ||
200 | MPUI730_SAVE(OMAP_IH1_MIR); | ||
201 | MPUI730_SAVE(OMAP_IH2_0_MIR); | ||
202 | MPUI730_SAVE(OMAP_IH2_1_MIR); | ||
203 | MPUI730_SAVE(MPUI_CTRL); | ||
204 | MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG); | ||
205 | MPUI730_SAVE(MPUI_DSP_API_CONFIG); | ||
206 | MPUI730_SAVE(EMIFS_CONFIG); | ||
207 | MPUI730_SAVE(EMIFF_SDRAM_CONFIG); | ||
208 | |||
209 | } else if (cpu_is_omap1510()) { | ||
210 | MPUI1510_SAVE(OMAP_IH1_MIR); | ||
211 | MPUI1510_SAVE(OMAP_IH2_MIR); | ||
212 | MPUI1510_SAVE(MPUI_CTRL); | ||
213 | MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG); | ||
214 | MPUI1510_SAVE(MPUI_DSP_API_CONFIG); | ||
215 | MPUI1510_SAVE(EMIFS_CONFIG); | ||
216 | MPUI1510_SAVE(EMIFF_SDRAM_CONFIG); | ||
217 | } else if (cpu_is_omap16xx()) { | ||
218 | MPUI1610_SAVE(OMAP_IH1_MIR); | ||
219 | MPUI1610_SAVE(OMAP_IH2_0_MIR); | ||
220 | MPUI1610_SAVE(OMAP_IH2_1_MIR); | ||
221 | MPUI1610_SAVE(OMAP_IH2_2_MIR); | ||
222 | MPUI1610_SAVE(OMAP_IH2_3_MIR); | ||
223 | MPUI1610_SAVE(MPUI_CTRL); | ||
224 | MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG); | ||
225 | MPUI1610_SAVE(MPUI_DSP_API_CONFIG); | ||
226 | MPUI1610_SAVE(EMIFS_CONFIG); | ||
227 | MPUI1610_SAVE(EMIFF_SDRAM_CONFIG); | ||
228 | } | ||
229 | |||
230 | ARM_SAVE(ARM_CKCTL); | ||
231 | ARM_SAVE(ARM_IDLECT1); | ||
232 | ARM_SAVE(ARM_IDLECT2); | ||
233 | if (!(cpu_is_omap1510())) | ||
234 | ARM_SAVE(ARM_IDLECT3); | ||
235 | ARM_SAVE(ARM_EWUPCT); | ||
236 | ARM_SAVE(ARM_RSTCT1); | ||
237 | ARM_SAVE(ARM_RSTCT2); | ||
238 | ARM_SAVE(ARM_SYSST); | ||
239 | ULPD_SAVE(ULPD_CLOCK_CTRL); | ||
240 | ULPD_SAVE(ULPD_STATUS_REQ); | ||
241 | |||
242 | /* (Step 3 removed - we now allow deep sleep by default) */ | ||
243 | |||
244 | /* | ||
245 | * Step 4: OMAP DSP Shutdown | ||
246 | */ | ||
247 | |||
248 | |||
249 | /* | ||
250 | * Step 5: Wakeup Event Setup | ||
251 | */ | ||
252 | |||
253 | omap_pm_wakeup_setup(); | ||
254 | |||
255 | /* | ||
256 | * Step 6: ARM and Traffic controller shutdown | ||
257 | */ | ||
258 | |||
259 | /* disable ARM watchdog */ | ||
260 | omap_writel(0x00F5, OMAP_WDT_TIMER_MODE); | ||
261 | omap_writel(0x00A0, OMAP_WDT_TIMER_MODE); | ||
262 | |||
263 | /* | ||
264 | * Step 6b: ARM and Traffic controller shutdown | ||
265 | * | ||
266 | * Step 6 continues here. Prepare jump to power management | ||
267 | * assembly code in internal SRAM. | ||
268 | * | ||
269 | * Since the omap_cpu_suspend routine has been copied to | ||
270 | * SRAM, we'll do an indirect procedure call to it and pass the | ||
271 | * contents of arm_idlect1 and arm_idlect2 so it can restore | ||
272 | * them when it wakes up and it will return. | ||
273 | */ | ||
274 | |||
275 | arg0 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT1]; | ||
276 | arg1 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT2]; | ||
277 | |||
278 | /* | ||
279 | * Step 6c: ARM and Traffic controller shutdown | ||
280 | * | ||
281 | * Jump to assembly code. The processor will stay there | ||
282 | * until wake up. | ||
283 | */ | ||
284 | omap_sram_suspend(arg0, arg1); | ||
285 | |||
286 | /* | ||
287 | * If we are here, processor is woken up! | ||
288 | */ | ||
289 | |||
290 | /* | ||
291 | * Restore ARM state, except ARM_IDLECT1/2 which omap_cpu_suspend did | ||
292 | */ | ||
293 | |||
294 | if (!(cpu_is_omap1510())) | ||
295 | ARM_RESTORE(ARM_IDLECT3); | ||
296 | ARM_RESTORE(ARM_CKCTL); | ||
297 | ARM_RESTORE(ARM_EWUPCT); | ||
298 | ARM_RESTORE(ARM_RSTCT1); | ||
299 | ARM_RESTORE(ARM_RSTCT2); | ||
300 | ARM_RESTORE(ARM_SYSST); | ||
301 | ULPD_RESTORE(ULPD_CLOCK_CTRL); | ||
302 | ULPD_RESTORE(ULPD_STATUS_REQ); | ||
303 | |||
304 | if (cpu_is_omap730()) { | ||
305 | MPUI730_RESTORE(EMIFS_CONFIG); | ||
306 | MPUI730_RESTORE(EMIFF_SDRAM_CONFIG); | ||
307 | MPUI730_RESTORE(OMAP_IH1_MIR); | ||
308 | MPUI730_RESTORE(OMAP_IH2_0_MIR); | ||
309 | MPUI730_RESTORE(OMAP_IH2_1_MIR); | ||
310 | } else if (cpu_is_omap1510()) { | ||
311 | MPUI1510_RESTORE(MPUI_CTRL); | ||
312 | MPUI1510_RESTORE(MPUI_DSP_BOOT_CONFIG); | ||
313 | MPUI1510_RESTORE(MPUI_DSP_API_CONFIG); | ||
314 | MPUI1510_RESTORE(EMIFS_CONFIG); | ||
315 | MPUI1510_RESTORE(EMIFF_SDRAM_CONFIG); | ||
316 | MPUI1510_RESTORE(OMAP_IH1_MIR); | ||
317 | MPUI1510_RESTORE(OMAP_IH2_MIR); | ||
318 | } else if (cpu_is_omap16xx()) { | ||
319 | MPUI1610_RESTORE(MPUI_CTRL); | ||
320 | MPUI1610_RESTORE(MPUI_DSP_BOOT_CONFIG); | ||
321 | MPUI1610_RESTORE(MPUI_DSP_API_CONFIG); | ||
322 | MPUI1610_RESTORE(EMIFS_CONFIG); | ||
323 | MPUI1610_RESTORE(EMIFF_SDRAM_CONFIG); | ||
324 | |||
325 | MPUI1610_RESTORE(OMAP_IH1_MIR); | ||
326 | MPUI1610_RESTORE(OMAP_IH2_0_MIR); | ||
327 | MPUI1610_RESTORE(OMAP_IH2_1_MIR); | ||
328 | MPUI1610_RESTORE(OMAP_IH2_2_MIR); | ||
329 | MPUI1610_RESTORE(OMAP_IH2_3_MIR); | ||
330 | } | ||
331 | |||
332 | omap_writew(0, ULPD_SOFT_DISABLE_REQ_REG); | ||
333 | |||
334 | /* | ||
335 | * Reenable interrupts | ||
336 | */ | ||
337 | |||
338 | local_irq_enable(); | ||
339 | local_fiq_enable(); | ||
340 | |||
341 | omap_serial_wake_trigger(0); | ||
342 | |||
343 | printk("PM: OMAP%x is re-starting from deep sleep...\n", system_rev); | ||
344 | |||
345 | if (machine_is_omap_osk()) { | ||
346 | /* Let LED1 (D9) blink again */ | ||
347 | tps65010_set_led(LED1, BLINK); | ||
348 | } | ||
349 | } | ||
350 | |||
351 | #if defined(DEBUG) && defined(CONFIG_PROC_FS) | ||
352 | static int g_read_completed; | ||
353 | |||
354 | /* | ||
355 | * Read system PM registers for debugging | ||
356 | */ | ||
357 | static int omap_pm_read_proc( | ||
358 | char *page_buffer, | ||
359 | char **my_first_byte, | ||
360 | off_t virtual_start, | ||
361 | int length, | ||
362 | int *eof, | ||
363 | void *data) | ||
364 | { | ||
365 | int my_buffer_offset = 0; | ||
366 | char * const my_base = page_buffer; | ||
367 | |||
368 | ARM_SAVE(ARM_CKCTL); | ||
369 | ARM_SAVE(ARM_IDLECT1); | ||
370 | ARM_SAVE(ARM_IDLECT2); | ||
371 | if (!(cpu_is_omap1510())) | ||
372 | ARM_SAVE(ARM_IDLECT3); | ||
373 | ARM_SAVE(ARM_EWUPCT); | ||
374 | ARM_SAVE(ARM_RSTCT1); | ||
375 | ARM_SAVE(ARM_RSTCT2); | ||
376 | ARM_SAVE(ARM_SYSST); | ||
377 | |||
378 | ULPD_SAVE(ULPD_IT_STATUS); | ||
379 | ULPD_SAVE(ULPD_CLOCK_CTRL); | ||
380 | ULPD_SAVE(ULPD_SOFT_REQ); | ||
381 | ULPD_SAVE(ULPD_STATUS_REQ); | ||
382 | ULPD_SAVE(ULPD_DPLL_CTRL); | ||
383 | ULPD_SAVE(ULPD_POWER_CTRL); | ||
384 | |||
385 | if (cpu_is_omap730()) { | ||
386 | MPUI730_SAVE(MPUI_CTRL); | ||
387 | MPUI730_SAVE(MPUI_DSP_STATUS); | ||
388 | MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG); | ||
389 | MPUI730_SAVE(MPUI_DSP_API_CONFIG); | ||
390 | MPUI730_SAVE(EMIFF_SDRAM_CONFIG); | ||
391 | MPUI730_SAVE(EMIFS_CONFIG); | ||
392 | } else if (cpu_is_omap1510()) { | ||
393 | MPUI1510_SAVE(MPUI_CTRL); | ||
394 | MPUI1510_SAVE(MPUI_DSP_STATUS); | ||
395 | MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG); | ||
396 | MPUI1510_SAVE(MPUI_DSP_API_CONFIG); | ||
397 | MPUI1510_SAVE(EMIFF_SDRAM_CONFIG); | ||
398 | MPUI1510_SAVE(EMIFS_CONFIG); | ||
399 | } else if (cpu_is_omap16xx()) { | ||
400 | MPUI1610_SAVE(MPUI_CTRL); | ||
401 | MPUI1610_SAVE(MPUI_DSP_STATUS); | ||
402 | MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG); | ||
403 | MPUI1610_SAVE(MPUI_DSP_API_CONFIG); | ||
404 | MPUI1610_SAVE(EMIFF_SDRAM_CONFIG); | ||
405 | MPUI1610_SAVE(EMIFS_CONFIG); | ||
406 | } | ||
407 | |||
408 | if (virtual_start == 0) { | ||
409 | g_read_completed = 0; | ||
410 | |||
411 | my_buffer_offset += sprintf(my_base + my_buffer_offset, | ||
412 | "ARM_CKCTL_REG: 0x%-8x \n" | ||
413 | "ARM_IDLECT1_REG: 0x%-8x \n" | ||
414 | "ARM_IDLECT2_REG: 0x%-8x \n" | ||
415 | "ARM_IDLECT3_REG: 0x%-8x \n" | ||
416 | "ARM_EWUPCT_REG: 0x%-8x \n" | ||
417 | "ARM_RSTCT1_REG: 0x%-8x \n" | ||
418 | "ARM_RSTCT2_REG: 0x%-8x \n" | ||
419 | "ARM_SYSST_REG: 0x%-8x \n" | ||
420 | "ULPD_IT_STATUS_REG: 0x%-4x \n" | ||
421 | "ULPD_CLOCK_CTRL_REG: 0x%-4x \n" | ||
422 | "ULPD_SOFT_REQ_REG: 0x%-4x \n" | ||
423 | "ULPD_DPLL_CTRL_REG: 0x%-4x \n" | ||
424 | "ULPD_STATUS_REQ_REG: 0x%-4x \n" | ||
425 | "ULPD_POWER_CTRL_REG: 0x%-4x \n", | ||
426 | ARM_SHOW(ARM_CKCTL), | ||
427 | ARM_SHOW(ARM_IDLECT1), | ||
428 | ARM_SHOW(ARM_IDLECT2), | ||
429 | ARM_SHOW(ARM_IDLECT3), | ||
430 | ARM_SHOW(ARM_EWUPCT), | ||
431 | ARM_SHOW(ARM_RSTCT1), | ||
432 | ARM_SHOW(ARM_RSTCT2), | ||
433 | ARM_SHOW(ARM_SYSST), | ||
434 | ULPD_SHOW(ULPD_IT_STATUS), | ||
435 | ULPD_SHOW(ULPD_CLOCK_CTRL), | ||
436 | ULPD_SHOW(ULPD_SOFT_REQ), | ||
437 | ULPD_SHOW(ULPD_DPLL_CTRL), | ||
438 | ULPD_SHOW(ULPD_STATUS_REQ), | ||
439 | ULPD_SHOW(ULPD_POWER_CTRL)); | ||
440 | |||
441 | if (cpu_is_omap730()) { | ||
442 | my_buffer_offset += sprintf(my_base + my_buffer_offset, | ||
443 | "MPUI730_CTRL_REG 0x%-8x \n" | ||
444 | "MPUI730_DSP_STATUS_REG: 0x%-8x \n" | ||
445 | "MPUI730_DSP_BOOT_CONFIG_REG: 0x%-8x \n" | ||
446 | "MPUI730_DSP_API_CONFIG_REG: 0x%-8x \n" | ||
447 | "MPUI730_SDRAM_CONFIG_REG: 0x%-8x \n" | ||
448 | "MPUI730_EMIFS_CONFIG_REG: 0x%-8x \n", | ||
449 | MPUI730_SHOW(MPUI_CTRL), | ||
450 | MPUI730_SHOW(MPUI_DSP_STATUS), | ||
451 | MPUI730_SHOW(MPUI_DSP_BOOT_CONFIG), | ||
452 | MPUI730_SHOW(MPUI_DSP_API_CONFIG), | ||
453 | MPUI730_SHOW(EMIFF_SDRAM_CONFIG), | ||
454 | MPUI730_SHOW(EMIFS_CONFIG)); | ||
455 | } else if (cpu_is_omap1510()) { | ||
456 | my_buffer_offset += sprintf(my_base + my_buffer_offset, | ||
457 | "MPUI1510_CTRL_REG 0x%-8x \n" | ||
458 | "MPUI1510_DSP_STATUS_REG: 0x%-8x \n" | ||
459 | "MPUI1510_DSP_BOOT_CONFIG_REG: 0x%-8x \n" | ||
460 | "MPUI1510_DSP_API_CONFIG_REG: 0x%-8x \n" | ||
461 | "MPUI1510_SDRAM_CONFIG_REG: 0x%-8x \n" | ||
462 | "MPUI1510_EMIFS_CONFIG_REG: 0x%-8x \n", | ||
463 | MPUI1510_SHOW(MPUI_CTRL), | ||
464 | MPUI1510_SHOW(MPUI_DSP_STATUS), | ||
465 | MPUI1510_SHOW(MPUI_DSP_BOOT_CONFIG), | ||
466 | MPUI1510_SHOW(MPUI_DSP_API_CONFIG), | ||
467 | MPUI1510_SHOW(EMIFF_SDRAM_CONFIG), | ||
468 | MPUI1510_SHOW(EMIFS_CONFIG)); | ||
469 | } else if (cpu_is_omap16xx()) { | ||
470 | my_buffer_offset += sprintf(my_base + my_buffer_offset, | ||
471 | "MPUI1610_CTRL_REG 0x%-8x \n" | ||
472 | "MPUI1610_DSP_STATUS_REG: 0x%-8x \n" | ||
473 | "MPUI1610_DSP_BOOT_CONFIG_REG: 0x%-8x \n" | ||
474 | "MPUI1610_DSP_API_CONFIG_REG: 0x%-8x \n" | ||
475 | "MPUI1610_SDRAM_CONFIG_REG: 0x%-8x \n" | ||
476 | "MPUI1610_EMIFS_CONFIG_REG: 0x%-8x \n", | ||
477 | MPUI1610_SHOW(MPUI_CTRL), | ||
478 | MPUI1610_SHOW(MPUI_DSP_STATUS), | ||
479 | MPUI1610_SHOW(MPUI_DSP_BOOT_CONFIG), | ||
480 | MPUI1610_SHOW(MPUI_DSP_API_CONFIG), | ||
481 | MPUI1610_SHOW(EMIFF_SDRAM_CONFIG), | ||
482 | MPUI1610_SHOW(EMIFS_CONFIG)); | ||
483 | } | ||
484 | |||
485 | g_read_completed++; | ||
486 | } else if (g_read_completed >= 1) { | ||
487 | *eof = 1; | ||
488 | return 0; | ||
489 | } | ||
490 | g_read_completed++; | ||
491 | |||
492 | *my_first_byte = page_buffer; | ||
493 | return my_buffer_offset; | ||
494 | } | ||
495 | |||
496 | static void omap_pm_init_proc(void) | ||
497 | { | ||
498 | struct proc_dir_entry *entry; | ||
499 | |||
500 | entry = create_proc_read_entry("driver/omap_pm", | ||
501 | S_IWUSR | S_IRUGO, NULL, | ||
502 | omap_pm_read_proc, NULL); | ||
503 | } | ||
504 | |||
505 | #endif /* DEBUG && CONFIG_PROC_FS */ | ||
506 | |||
507 | /* | ||
508 | * omap_pm_prepare - Do preliminary suspend work. | ||
509 | * @state: suspend state we're entering. | ||
510 | * | ||
511 | */ | ||
512 | //#include <asm/hardware.h> | ||
513 | |||
514 | static int omap_pm_prepare(suspend_state_t state) | ||
515 | { | ||
516 | int error = 0; | ||
517 | |||
518 | switch (state) | ||
519 | { | ||
520 | case PM_SUSPEND_STANDBY: | ||
521 | case PM_SUSPEND_MEM: | ||
522 | break; | ||
523 | |||
524 | case PM_SUSPEND_DISK: | ||
525 | return -ENOTSUPP; | ||
526 | |||
527 | default: | ||
528 | return -EINVAL; | ||
529 | } | ||
530 | |||
531 | return error; | ||
532 | } | ||
533 | |||
534 | |||
535 | /* | ||
536 | * omap_pm_enter - Actually enter a sleep state. | ||
537 | * @state: State we're entering. | ||
538 | * | ||
539 | */ | ||
540 | |||
541 | static int omap_pm_enter(suspend_state_t state) | ||
542 | { | ||
543 | switch (state) | ||
544 | { | ||
545 | case PM_SUSPEND_STANDBY: | ||
546 | case PM_SUSPEND_MEM: | ||
547 | omap_pm_suspend(); | ||
548 | break; | ||
549 | |||
550 | case PM_SUSPEND_DISK: | ||
551 | return -ENOTSUPP; | ||
552 | |||
553 | default: | ||
554 | return -EINVAL; | ||
555 | } | ||
556 | |||
557 | return 0; | ||
558 | } | ||
559 | |||
560 | |||
561 | /** | ||
562 | * omap_pm_finish - Finish up suspend sequence. | ||
563 | * @state: State we're coming out of. | ||
564 | * | ||
565 | * This is called after we wake back up (or if entering the sleep state | ||
566 | * failed). | ||
567 | */ | ||
568 | |||
569 | static int omap_pm_finish(suspend_state_t state) | ||
570 | { | ||
571 | return 0; | ||
572 | } | ||
573 | |||
574 | |||
575 | static irqreturn_t omap_wakeup_interrupt(int irq, void * dev, | ||
576 | struct pt_regs * regs) | ||
577 | { | ||
578 | return IRQ_HANDLED; | ||
579 | } | ||
580 | |||
581 | static struct irqaction omap_wakeup_irq = { | ||
582 | .name = "peripheral wakeup", | ||
583 | .flags = IRQF_DISABLED, | ||
584 | .handler = omap_wakeup_interrupt | ||
585 | }; | ||
586 | |||
587 | |||
588 | |||
589 | static struct pm_ops omap_pm_ops ={ | ||
590 | .pm_disk_mode = 0, | ||
591 | .prepare = omap_pm_prepare, | ||
592 | .enter = omap_pm_enter, | ||
593 | .finish = omap_pm_finish, | ||
594 | }; | ||
595 | |||
596 | static int __init omap_pm_init(void) | ||
597 | { | ||
598 | printk("Power Management for TI OMAP.\n"); | ||
599 | /* | ||
600 | * We copy the assembler sleep/wakeup routines to SRAM. | ||
601 | * These routines need to be in SRAM as that's the only | ||
602 | * memory the MPU can see when it wakes up. | ||
603 | */ | ||
604 | if (cpu_is_omap730()) { | ||
605 | omap_sram_idle = omap_sram_push(omap730_idle_loop_suspend, | ||
606 | omap730_idle_loop_suspend_sz); | ||
607 | omap_sram_suspend = omap_sram_push(omap730_cpu_suspend, | ||
608 | omap730_cpu_suspend_sz); | ||
609 | } else if (cpu_is_omap1510()) { | ||
610 | omap_sram_idle = omap_sram_push(omap1510_idle_loop_suspend, | ||
611 | omap1510_idle_loop_suspend_sz); | ||
612 | omap_sram_suspend = omap_sram_push(omap1510_cpu_suspend, | ||
613 | omap1510_cpu_suspend_sz); | ||
614 | } else if (cpu_is_omap16xx()) { | ||
615 | omap_sram_idle = omap_sram_push(omap1610_idle_loop_suspend, | ||
616 | omap1610_idle_loop_suspend_sz); | ||
617 | omap_sram_suspend = omap_sram_push(omap1610_cpu_suspend, | ||
618 | omap1610_cpu_suspend_sz); | ||
619 | } | ||
620 | |||
621 | if (omap_sram_idle == NULL || omap_sram_suspend == NULL) { | ||
622 | printk(KERN_ERR "PM not initialized: Missing SRAM support\n"); | ||
623 | return -ENODEV; | ||
624 | } | ||
625 | |||
626 | pm_idle = omap_pm_idle; | ||
627 | |||
628 | if (cpu_is_omap730()) | ||
629 | setup_irq(INT_730_WAKE_UP_REQ, &omap_wakeup_irq); | ||
630 | else if (cpu_is_omap16xx()) | ||
631 | setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq); | ||
632 | |||
633 | #if 0 | ||
634 | /* --- BEGIN BOARD-DEPENDENT CODE --- */ | ||
635 | /* Sleepx mask direction */ | ||
636 | omap_writew((omap_readw(0xfffb5008) & ~2), 0xfffb5008); | ||
637 | /* Unmask sleepx signal */ | ||
638 | omap_writew((omap_readw(0xfffb5004) & ~2), 0xfffb5004); | ||
639 | /* --- END BOARD-DEPENDENT CODE --- */ | ||
640 | #endif | ||
641 | |||
642 | /* Program new power ramp-up time | ||
643 | * (0 for most boards since we don't lower voltage when in deep sleep) | ||
644 | */ | ||
645 | omap_writew(ULPD_SETUP_ANALOG_CELL_3_VAL, ULPD_SETUP_ANALOG_CELL_3); | ||
646 | |||
647 | /* Setup ULPD POWER_CTRL_REG - enter deep sleep whenever possible */ | ||
648 | omap_writew(ULPD_POWER_CTRL_REG_VAL, ULPD_POWER_CTRL); | ||
649 | |||
650 | /* Configure IDLECT3 */ | ||
651 | if (cpu_is_omap730()) | ||
652 | omap_writel(OMAP730_IDLECT3_VAL, OMAP730_IDLECT3); | ||
653 | else if (cpu_is_omap16xx()) | ||
654 | omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3); | ||
655 | |||
656 | pm_set_ops(&omap_pm_ops); | ||
657 | |||
658 | #if defined(DEBUG) && defined(CONFIG_PROC_FS) | ||
659 | omap_pm_init_proc(); | ||
660 | #endif | ||
661 | |||
662 | if (cpu_is_omap16xx()) { | ||
663 | /* configure LOW_PWR pin */ | ||
664 | omap_cfg_reg(T20_1610_LOW_PWR); | ||
665 | } | ||
666 | |||
667 | return 0; | ||
668 | } | ||
669 | __initcall(omap_pm_init); | ||
670 | |||
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index e75718301b0f..19014b2ff4c6 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c | |||
@@ -174,10 +174,7 @@ void __init omap_map_sram(void) | |||
174 | if (cpu_is_omap24xx()) { | 174 | if (cpu_is_omap24xx()) { |
175 | omap_sram_io_desc[0].virtual = OMAP2_SRAM_VA; | 175 | omap_sram_io_desc[0].virtual = OMAP2_SRAM_VA; |
176 | 176 | ||
177 | if (is_sram_locked()) | 177 | base = OMAP2_SRAM_PA; |
178 | base = OMAP2_SRAM_PUB_PA; | ||
179 | else | ||
180 | base = OMAP2_SRAM_PA; | ||
181 | base = ROUND_DOWN(base, PAGE_SIZE); | 178 | base = ROUND_DOWN(base, PAGE_SIZE); |
182 | omap_sram_io_desc[0].pfn = __phys_to_pfn(base); | 179 | omap_sram_io_desc[0].pfn = __phys_to_pfn(base); |
183 | } | 180 | } |
diff --git a/arch/arm/plat-omap/timer32k.c b/arch/arm/plat-omap/timer32k.c index 281ecc7fcdfc..cf6df3378d37 100644 --- a/arch/arm/plat-omap/timer32k.c +++ b/arch/arm/plat-omap/timer32k.c | |||
@@ -105,6 +105,8 @@ static inline unsigned long omap_32k_timer_read(int reg) | |||
105 | 105 | ||
106 | static inline void omap_32k_timer_start(unsigned long load_val) | 106 | static inline void omap_32k_timer_start(unsigned long load_val) |
107 | { | 107 | { |
108 | if (!load_val) | ||
109 | load_val = 1; | ||
108 | omap_32k_timer_write(load_val, OMAP1_32K_TIMER_TVR); | 110 | omap_32k_timer_write(load_val, OMAP1_32K_TIMER_TVR); |
109 | omap_32k_timer_write(0x0f, OMAP1_32K_TIMER_CR); | 111 | omap_32k_timer_write(0x0f, OMAP1_32K_TIMER_CR); |
110 | } | 112 | } |
@@ -192,14 +194,11 @@ unsigned long long sched_clock(void) | |||
192 | * issues with dynamic tick. In the dynamic tick case, we need to lock | 194 | * issues with dynamic tick. In the dynamic tick case, we need to lock |
193 | * with irqsave. | 195 | * with irqsave. |
194 | */ | 196 | */ |
195 | static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, | 197 | static inline irqreturn_t _omap_32k_timer_interrupt(int irq, void *dev_id, |
196 | struct pt_regs *regs) | 198 | struct pt_regs *regs) |
197 | { | 199 | { |
198 | unsigned long flags; | ||
199 | unsigned long now; | 200 | unsigned long now; |
200 | 201 | ||
201 | write_seqlock_irqsave(&xtime_lock, flags); | ||
202 | |||
203 | omap_32k_timer_ack_irq(); | 202 | omap_32k_timer_ack_irq(); |
204 | now = omap_32k_sync_timer_read(); | 203 | now = omap_32k_sync_timer_read(); |
205 | 204 | ||
@@ -215,6 +214,23 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, | |||
215 | * continuous timer can be overridden from pm_idle to be longer. | 214 | * continuous timer can be overridden from pm_idle to be longer. |
216 | */ | 215 | */ |
217 | omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now); | 216 | omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now); |
217 | |||
218 | return IRQ_HANDLED; | ||
219 | } | ||
220 | |||
221 | static irqreturn_t omap_32k_timer_handler(int irq, void *dev_id, | ||
222 | struct pt_regs *regs) | ||
223 | { | ||
224 | return _omap_32k_timer_interrupt(irq, dev_id, regs); | ||
225 | } | ||
226 | |||
227 | static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, | ||
228 | struct pt_regs *regs) | ||
229 | { | ||
230 | unsigned long flags; | ||
231 | |||
232 | write_seqlock_irqsave(&xtime_lock, flags); | ||
233 | _omap_32k_timer_interrupt(irq, dev_id, regs); | ||
218 | write_sequnlock_irqrestore(&xtime_lock, flags); | 234 | write_sequnlock_irqrestore(&xtime_lock, flags); |
219 | 235 | ||
220 | return IRQ_HANDLED; | 236 | return IRQ_HANDLED; |
@@ -230,7 +246,15 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, | |||
230 | */ | 246 | */ |
231 | void omap_32k_timer_reprogram(unsigned long next_tick) | 247 | void omap_32k_timer_reprogram(unsigned long next_tick) |
232 | { | 248 | { |
233 | omap_32k_timer_start(JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1); | 249 | unsigned long ticks = JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1; |
250 | unsigned long now = omap_32k_sync_timer_read(); | ||
251 | unsigned long idled = now - omap_32k_last_tick; | ||
252 | |||
253 | if (idled + 1 < ticks) | ||
254 | ticks -= idled; | ||
255 | else | ||
256 | ticks = 1; | ||
257 | omap_32k_timer_start(ticks); | ||
234 | } | 258 | } |
235 | 259 | ||
236 | static struct irqaction omap_32k_timer_irq; | 260 | static struct irqaction omap_32k_timer_irq; |
@@ -252,7 +276,7 @@ static struct dyn_tick_timer omap_dyn_tick_timer = { | |||
252 | .enable = omap_32k_timer_enable_dyn_tick, | 276 | .enable = omap_32k_timer_enable_dyn_tick, |
253 | .disable = omap_32k_timer_disable_dyn_tick, | 277 | .disable = omap_32k_timer_disable_dyn_tick, |
254 | .reprogram = omap_32k_timer_reprogram, | 278 | .reprogram = omap_32k_timer_reprogram, |
255 | .handler = omap_32k_timer_interrupt, | 279 | .handler = omap_32k_timer_handler, |
256 | }; | 280 | }; |
257 | #endif /* CONFIG_NO_IDLE_HZ */ | 281 | #endif /* CONFIG_NO_IDLE_HZ */ |
258 | 282 | ||