aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig5
-rw-r--r--arch/arm/common/icst307.c4
-rw-r--r--arch/arm/common/icst525.c4
-rw-r--r--arch/arm/common/locomo.c61
-rw-r--r--arch/arm/common/sharpsl_pm.c4
-rw-r--r--arch/arm/kernel/apm.c33
-rw-r--r--arch/arm/kernel/time.c6
-rw-r--r--arch/arm/mach-at91rm9200/at91rm9200.c250
-rw-r--r--arch/arm/mach-at91rm9200/board-1arm.c20
-rw-r--r--arch/arm/mach-at91rm9200/board-carmeva.c21
-rw-r--r--arch/arm/mach-at91rm9200/board-csb337.c20
-rw-r--r--arch/arm/mach-at91rm9200/board-csb637.c20
-rw-r--r--arch/arm/mach-at91rm9200/board-dk.c45
-rw-r--r--arch/arm/mach-at91rm9200/board-eb9200.c20
-rw-r--r--arch/arm/mach-at91rm9200/board-ek.c20
-rw-r--r--arch/arm/mach-at91rm9200/board-kafa.c20
-rw-r--r--arch/arm/mach-at91rm9200/board-kb9202.c45
-rw-r--r--arch/arm/mach-at91rm9200/clock.c324
-rw-r--r--arch/arm/mach-at91rm9200/clock.h30
-rw-r--r--arch/arm/mach-at91rm9200/devices.c72
-rw-r--r--arch/arm/mach-at91rm9200/generic.h20
-rw-r--r--arch/arm/mach-at91rm9200/gpio.c89
-rw-r--r--arch/arm/mach-at91rm9200/irq.c6
-rw-r--r--arch/arm/mach-at91rm9200/pm.c14
-rw-r--r--arch/arm/mach-ixp4xx/common.c38
-rw-r--r--arch/arm/mach-ixp4xx/nslu2-setup.c2
-rw-r--r--arch/arm/mach-omap1/clock.c107
-rw-r--r--arch/arm/mach-omap1/clock.h14
-rw-r--r--arch/arm/mach-omap1/mux.c11
-rw-r--r--arch/arm/mach-omap2/board-apollon.c7
-rw-r--r--arch/arm/mach-omap2/clock.c146
-rw-r--r--arch/arm/mach-omap2/clock.h20
-rw-r--r--arch/arm/mach-omap2/gpmc.c180
-rw-r--r--arch/arm/mach-omap2/irq.c12
-rw-r--r--arch/arm/mach-omap2/mux.c14
-rw-r--r--arch/arm/mach-omap2/prcm.c10
-rw-r--r--arch/arm/mach-s3c2410/Kconfig2
-rw-r--r--arch/arm/mach-s3c2410/irq.c112
-rw-r--r--arch/arm/mach-s3c2410/mach-amlm5900.c25
-rw-r--r--arch/arm/mach-s3c2410/pm-simtec.c3
-rw-r--r--arch/arm/mach-s3c2410/s3c2410-pm.c9
-rw-r--r--arch/arm/mach-sa1100/collie.c23
-rw-r--r--arch/arm/plat-omap/clock.c26
-rw-r--r--arch/arm/plat-omap/devices.c20
-rw-r--r--arch/arm/plat-omap/dma.c95
-rw-r--r--arch/arm/plat-omap/dmtimer.c76
-rw-r--r--arch/arm/plat-omap/gpio.c45
-rw-r--r--arch/arm/plat-omap/mcbsp.c9
-rw-r--r--arch/arm/plat-omap/pm.c670
-rw-r--r--arch/arm/plat-omap/sram.c5
-rw-r--r--arch/arm/plat-omap/timer32k.c38
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
20config GENERIC_TIME
21 bool
22 default n
23
20config MMU 24config MMU
21 bool 25 bool
22 default y 26 default y
@@ -222,6 +226,7 @@ config ARCH_IOP33X
222config ARCH_IXP4XX 226config 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
407static void locomo_spi_mask_irq(unsigned int irq) 414static 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
416static void locomo_spi_unmask_irq(unsigned int irq) 423static 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
425static struct irq_chip locomo_spi_chip = { 432static 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
817void locomo_gpio_set_dir(struct locomo_dev *ldev, unsigned int bits, unsigned int dir) 824void 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
839unsigned int locomo_gpio_read_level(struct locomo_dev *ldev, unsigned int bits) 849int 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
853unsigned int locomo_gpio_read_output(struct locomo_dev *ldev, unsigned int bits) 866int 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
867void locomo_gpio_write(struct locomo_dev *ldev, unsigned int bits, unsigned int set) 883void 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 */
81static int suspends_pending; 82static int suspends_pending;
82static int apm_disabled; 83static int apm_disabled;
83static int arm_apm_active; 84static struct task_struct *kapmd_tsk;
84 85
85static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue); 86static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
86static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); 87static 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 */
99static DECLARE_WAIT_QUEUE_HEAD(kapmd_wait); 100static DECLARE_WAIT_QUEUE_HEAD(kapmd_wait);
100static DECLARE_COMPLETION(kapmd_exit);
101static DEFINE_SPINLOCK(kapmd_queue_lock); 101static DEFINE_SPINLOCK(kapmd_queue_lock);
102static struct apm_queue kapmd_queue; 102static 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
469static int kapmd(void *arg) 469static 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
514static int __init apm_init(void) 511static 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
557module_init(apm_init); 550module_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 */
70int (*set_rtc)(void); 70int (*set_rtc)(void);
71 71
72#ifndef CONFIG_GENERIC_TIME
72static unsigned long dummy_gettimeoffset(void) 73static 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
233void do_gettimeofday(struct timeval *tv) 236void 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
293EXPORT_SYMBOL(do_settimeofday); 296EXPORT_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
501void __init time_init(void) 505void __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
21static struct map_desc at91rm9200_io_desc[] __initdata = { 22static 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
105void __init at91rm9200_map_io(void) 61/* --------------------------------------------------------------------
62 * Clocks
63 * -------------------------------------------------------------------- */
64
65/*
66 * The peripheral clocks.
67 */
68static struct clk udc_clk = {
69 .name = "udc_clk",
70 .pmc_mask = 1 << AT91RM9200_ID_UDP,
71 .type = CLK_TYPE_PERIPHERAL,
72};
73static struct clk ohci_clk = {
74 .name = "ohci_clk",
75 .pmc_mask = 1 << AT91RM9200_ID_UHP,
76 .type = CLK_TYPE_PERIPHERAL,
77};
78static struct clk ether_clk = {
79 .name = "ether_clk",
80 .pmc_mask = 1 << AT91RM9200_ID_EMAC,
81 .type = CLK_TYPE_PERIPHERAL,
82};
83static struct clk mmc_clk = {
84 .name = "mci_clk",
85 .pmc_mask = 1 << AT91RM9200_ID_MCI,
86 .type = CLK_TYPE_PERIPHERAL,
87};
88static struct clk twi_clk = {
89 .name = "twi_clk",
90 .pmc_mask = 1 << AT91RM9200_ID_TWI,
91 .type = CLK_TYPE_PERIPHERAL,
92};
93static struct clk usart0_clk = {
94 .name = "usart0_clk",
95 .pmc_mask = 1 << AT91RM9200_ID_US0,
96 .type = CLK_TYPE_PERIPHERAL,
97};
98static struct clk usart1_clk = {
99 .name = "usart1_clk",
100 .pmc_mask = 1 << AT91RM9200_ID_US1,
101 .type = CLK_TYPE_PERIPHERAL,
102};
103static struct clk usart2_clk = {
104 .name = "usart2_clk",
105 .pmc_mask = 1 << AT91RM9200_ID_US2,
106 .type = CLK_TYPE_PERIPHERAL,
107};
108static struct clk usart3_clk = {
109 .name = "usart3_clk",
110 .pmc_mask = 1 << AT91RM9200_ID_US3,
111 .type = CLK_TYPE_PERIPHERAL,
112};
113static struct clk spi_clk = {
114 .name = "spi_clk",
115 .pmc_mask = 1 << AT91RM9200_ID_SPI,
116 .type = CLK_TYPE_PERIPHERAL,
117};
118static struct clk pioA_clk = {
119 .name = "pioA_clk",
120 .pmc_mask = 1 << AT91RM9200_ID_PIOA,
121 .type = CLK_TYPE_PERIPHERAL,
122};
123static struct clk pioB_clk = {
124 .name = "pioB_clk",
125 .pmc_mask = 1 << AT91RM9200_ID_PIOB,
126 .type = CLK_TYPE_PERIPHERAL,
127};
128static struct clk pioC_clk = {
129 .name = "pioC_clk",
130 .pmc_mask = 1 << AT91RM9200_ID_PIOC,
131 .type = CLK_TYPE_PERIPHERAL,
132};
133static struct clk pioD_clk = {
134 .name = "pioD_clk",
135 .pmc_mask = 1 << AT91RM9200_ID_PIOD,
136 .type = CLK_TYPE_PERIPHERAL,
137};
138
139static 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 &ether_clk,
156 // irq0 .. irq6
157};
158
159/*
160 * The four programmable clocks.
161 * You must configure pin multiplexing to bring these signals out.
162 */
163static struct clk pck0 = {
164 .name = "pck0",
165 .pmc_mask = AT91_PMC_PCK0,
166 .type = CLK_TYPE_PROGRAMMABLE,
167 .id = 0,
168};
169static struct clk pck1 = {
170 .name = "pck1",
171 .pmc_mask = AT91_PMC_PCK1,
172 .type = CLK_TYPE_PROGRAMMABLE,
173 .id = 1,
174};
175static struct clk pck2 = {
176 .name = "pck2",
177 .pmc_mask = AT91_PMC_PCK2,
178 .type = CLK_TYPE_PROGRAMMABLE,
179 .id = 2,
180};
181static struct clk pck3 = {
182 .name = "pck3",
183 .pmc_mask = AT91_PMC_PCK3,
184 .type = CLK_TYPE_PROGRAMMABLE,
185 .id = 3,
186};
187
188static 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
205static 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 * -------------------------------------------------------------------- */
228void __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
148void __init at91rm9200_init_irq(unsigned int priority[NR_AIC_IRQS]) 286void __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
43static 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
63static void __init onearm_map_io(void) 54static 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
63static void __init onearm_init_irq(void)
64{
65 at91rm9200_init_interrupts(NULL);
66}
67
74static struct at91_eth_data __initdata onearm_eth_data = { 68static 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
44static 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
64static void __init carmeva_map_io(void) 55static 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
64static void __init carmeva_init_irq(void)
65{
66 at91rm9200_init_interrupts(NULL);
67}
68
69
75static struct at91_eth_data __initdata carmeva_eth_data = { 70static 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
43static 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
63static void __init csb337_map_io(void) 54static 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
66static void __init csb337_init_irq(void)
67{
68 at91rm9200_init_interrupts(NULL);
69}
70
77static struct at91_eth_data __initdata csb337_eth_data = { 71static 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
42static 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
62static void __init csb637_map_io(void) 53static 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
65static void __init csb637_init_irq(void)
66{
67 at91rm9200_init_interrupts(NULL);
68}
69
76static struct at91_eth_data __initdata csb637_eth_data = { 70static 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
46static 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
66static void __init dk_map_io(void) 57static 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
69static void __init dk_init_irq(void)
70{
71 at91rm9200_init_interrupts(NULL);
72}
73
80static struct at91_eth_data __initdata dk_eth_data = { 74static 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
125static struct mtd_partition __initdata dk_nand_partition[] = {
126 {
127 .name = "NAND Partition 1",
128 .offset = 0,
129 .size = MTDPART_SIZ_FULL,
130 },
131};
132
133static 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
139static 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
131static void __init dk_board_init(void) 148static 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
44static 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
64static void __init eb9200_map_io(void) 55static 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
64static void __init eb9200_init_irq(void)
65{
66 at91rm9200_init_interrupts(NULL);
67}
68
75static struct at91_eth_data __initdata eb9200_eth_data = { 69static 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
46static 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
66static void __init ek_map_io(void) 57static 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
69static void __init ek_init_irq(void)
70{
71 at91rm9200_init_interrupts(NULL);
72}
73
80static struct at91_eth_data __initdata ek_eth_data = { 74static 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
43static 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
63static void __init kafa_map_io(void) 54static 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
66static void __init kafa_init_irq(void)
67{
68 at91rm9200_init_interrupts(NULL);
69}
70
77static struct at91_eth_data __initdata kafa_eth_data = { 71static 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
44static 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
64static void __init kb9202_map_io(void) 55static 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
67static void __init kb9202_init_irq(void)
68{
69 at91rm9200_init_interrupts(NULL);
70}
71
78static struct at91_eth_data __initdata kb9202_eth_data = { 72static 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
92static struct mtd_partition __initdata kb9202_nand_partition[] = {
93 {
94 .name = "nand_fs",
95 .offset = 0,
96 .size = MTDPART_SIZ_FULL,
97 },
98};
99
100static 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
106static 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
98static void __init kb9202_board_init(void) 115static 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
116MACHINE_START(KB9200, "KB920x") 135MACHINE_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
41struct 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; 46static LIST_HEAD(clocks);
47 u32 pmc_mask; 47static 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
56static spinlock_t clk_lock; 49static u32 at91_pllb_usb_init;
57static 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};
72static struct clk main_clk = { 64static 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};
78static struct clk plla = { 70static 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
87static void pllb_mode(struct clk *clk, int is_on) 78static 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
114static void pmc_sys_mode(struct clk *clk, int is_on) 105static 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 */
141static struct clk pck0 = {
142 .name = "pck0",
143 .pmc_mask = AT91_PMC_PCK0,
144 .mode = pmc_sys_mode,
145 .programmable = 1,
146 .id = 0,
147};
148static struct clk pck1 = {
149 .name = "pck1",
150 .pmc_mask = AT91_PMC_PCK1,
151 .mode = pmc_sys_mode,
152 .programmable = 1,
153 .id = 1,
154};
155static struct clk pck2 = {
156 .name = "pck2",
157 .pmc_mask = AT91_PMC_PCK2,
158 .mode = pmc_sys_mode,
159 .programmable = 1,
160 .id = 2,
161};
162static 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
190static struct clk udc_clk = { 146static 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:
196static 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 }
202static struct clk ether_clk = {
203 .name = "ether_clk",
204 .parent = &mck,
205 .pmc_mask = 1 << AT91_ID_EMAC,
206 .mode = pmc_periph_mode,
207};
208static struct clk mmc_clk = {
209 .name = "mci_clk",
210 .parent = &mck,
211 .pmc_mask = 1 << AT91_ID_MCI,
212 .mode = pmc_periph_mode,
213};
214static struct clk twi_clk = {
215 .name = "twi_clk",
216 .parent = &mck,
217 .pmc_mask = 1 << AT91_ID_TWI,
218 .mode = pmc_periph_mode,
219};
220static struct clk usart0_clk = {
221 .name = "usart0_clk",
222 .parent = &mck,
223 .pmc_mask = 1 << AT91_ID_US0,
224 .mode = pmc_periph_mode,
225};
226static struct clk usart1_clk = {
227 .name = "usart1_clk",
228 .parent = &mck,
229 .pmc_mask = 1 << AT91_ID_US1,
230 .mode = pmc_periph_mode,
231};
232static struct clk usart2_clk = {
233 .name = "usart2_clk",
234 .parent = &mck,
235 .pmc_mask = 1 << AT91_ID_US2,
236 .mode = pmc_periph_mode,
237};
238static struct clk usart3_clk = {
239 .name = "usart3_clk",
240 .parent = &mck,
241 .pmc_mask = 1 << AT91_ID_US3,
242 .mode = pmc_periph_mode,
243};
244static struct clk spi_clk = {
245 .name = "spi0_clk",
246 .parent = &mck,
247 .pmc_mask = 1 << AT91_ID_SPI,
248 .mode = pmc_periph_mode,
249};
250static struct clk pioA_clk = {
251 .name = "pioA_clk",
252 .parent = &mck,
253 .pmc_mask = 1 << AT91_ID_PIOA,
254 .mode = pmc_periph_mode,
255};
256static struct clk pioB_clk = {
257 .name = "pioB_clk",
258 .parent = &mck,
259 .pmc_mask = 1 << AT91_ID_PIOB,
260 .mode = pmc_periph_mode,
261};
262static struct clk pioC_clk = {
263 .name = "pioC_clk",
264 .parent = &mck,
265 .pmc_mask = 1 << AT91_ID_PIOC,
266 .mode = pmc_periph_mode,
267};
268static 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
275static 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 &ether_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 */
333struct clk *clk_get(struct device *dev, const char *id) 179struct 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}
498EXPORT_SYMBOL(clk_set_parent); 342EXPORT_SYMBOL(clk_set_parent);
499 343
344/* establish PCK0..PCK3 parentage and rate */
345static 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);
506static int at91_clk_show(struct seq_file *s, void *unused) 362static 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 */
430int __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
573static u32 __init at91_pll_rate(struct clk *pll, u32 freq, u32 reg) 451static 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 */
647static void at91_periphclk_reset(void) 524static 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
542static 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
667int __init at91_clock_init(unsigned long main_clock) 557int __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
15struct 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
30extern 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
36static struct resource at91_usbh_resources[] = { 36static 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
81static struct resource at91_udc_resources[] = { 81static 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
132static struct resource at91_eth_resources[] = { 132static 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
264static struct resource at91_mmc_resources[] = { 264static 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
424static struct resource at91_spi_resources[] = { 424static 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
583static struct resource uart0_resources[] = { 583static 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
625static struct resource uart1_resources[] = { 625static 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
666static struct resource uart2_resources[] = { 666static 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
701static struct resource uart3_resources[] = { 701static 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 */
12extern void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks);
13
11 /* Interrupts */ 14 /* Interrupts */
12extern void __init at91rm9200_init_irq(unsigned int priority[]); 15extern void __init at91rm9200_init_interrupts(unsigned int priority[]);
13extern void __init at91_aic_init(unsigned int priority[]); 16extern void __init at91_aic_init(unsigned int priority[]);
14extern void __init at91_gpio_irq_setup(unsigned banks);
15 17
16 /* Timer */ 18 /* Timer */
17struct sys_timer; 19struct sys_timer;
18extern struct sys_timer at91rm9200_timer; 20extern struct sys_timer at91rm9200_timer;
19 21
20 /* Memory Map */
21extern void __init at91rm9200_map_io(void);
22
23 /* Clocks */ 22 /* Clocks */
24extern int __init at91_clock_init(unsigned long main_clock); 23extern int __init at91_clock_init(unsigned long main_clock);
25struct device; 24struct device;
@@ -29,3 +28,14 @@ extern void __init at91_clock_associate(const char *id, struct device *dev, cons
29extern void at91_irq_suspend(void); 28extern void at91_irq_suspend(void);
30extern void at91_irq_resume(void); 29extern 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
35struct 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};
40extern void __init at91_gpio_init(struct at91_gpio_bank *, int nr_banks);
41extern 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
23static const u32 pio_controller_offset[4] = { 24#include "generic.h"
24 AT91_PIOA, 25
25 AT91_PIOB, 26
26 AT91_PIOC, 27static struct at91_gpio_bank *gpio;
27 AT91_PIOD, 28static int gpio_banks;
28}; 29
29 30
30static inline void __iomem *pin_to_controller(unsigned pin) 31static 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
219static u32 wakeups[BGA_GPIO_BANKS]; 219static u32 wakeups[MAX_GPIO_BANKS];
220static u32 backups[BGA_GPIO_BANKS]; 220static u32 backups[MAX_GPIO_BANKS];
221 221
222static int gpio_irq_set_wake(unsigned pin, unsigned state) 222static 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/*--------------------------------------------------------------------------*/
381void __init at91_gpio_irq_setup(unsigned banks) 378
379/*
380 * Called from the processor-specific init to enable GPIO interrupt support.
381 */
382void __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 */
419void __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
40static void at91_aic_mask_irq(unsigned int irq) 38static 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() */
259static 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
268static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) 259static 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
310struct sys_timer ixp4xx_timer = { 301struct sys_timer ixp4xx_timer = {
311 .init = ixp4xx_timer_init, 302 .init = ixp4xx_timer_init,
312 .offset = ixp4xx_gettimeoffset,
313}; 303};
314 304
315static struct resource ixp46x_i2c_resources[] = { 305static 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
358cycle_t ixp4xx_get_cycles(void)
359{
360 return *IXP4XX_OSTS;
361}
362
363static 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
372unsigned long ixp4xx_timer_freq = FREQ;
373static 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
383device_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
160static void __init nslu2_init(void) 160static 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 */
593static inline void omap1_early_clk_reset(void)
594{
595 //omap_writel(0x3 << 29, MOD_CONF_CTRL_0);
596}
597 590
598static int __init omap1_late_clk_reset(void) 591static 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}
656late_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
662static struct clk_functions omap1_clk_functions = { 639static 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
669int __init omap1_clk_init(void) 647int __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
745static 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
744static struct clk * onchip_clks[] = { 757static 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)
199MUX_CFG("P15_1610_UWIRE_CS3", 8, 12, 1, 1, 22, 0, 1, 1, 1) 199MUX_CFG("P15_1610_UWIRE_CS3", 8, 12, 1, 1, 22, 0, 1, 1, 1)
200MUX_CFG("N15_1610_UWIRE_CS1", 7, 18, 2, 1, 14, 0, NA, 0, 1) 200MUX_CFG("N15_1610_UWIRE_CS1", 7, 18, 2, 1, 14, 0, NA, 0, 1)
201 201
202/* OMAP-1610 SPI */
203MUX_CFG("U19_1610_SPIF_SCK", 7, 21, 6, 1, 15, 0, 1, 1, 1)
204MUX_CFG("U18_1610_SPIF_DIN", 8, 0, 6, 1, 18, 1, 1, 0, 1)
205MUX_CFG("P20_1610_SPIF_DIN", 6, 27, 4, 1, 7, 1, 1, 0, 1)
206MUX_CFG("W21_1610_SPIF_DOUT", 8, 3, 6, 1, 19, 0, 1, 0, 1)
207MUX_CFG("R18_1610_SPIF_DOUT", 7, 9, 3, 1, 11, 0, 1, 0, 1)
208MUX_CFG("N14_1610_SPIF_CS0", 8, 9, 6, 1, 21, 0, 1, 1, 1)
209MUX_CFG("N15_1610_SPIF_CS1", 7, 18, 6, 1, 14, 0, 1, 1, 1)
210MUX_CFG("T19_1610_SPIF_CS2", 7, 15, 4, 1, 13, 0, 1, 1, 1)
211MUX_CFG("P15_1610_SPIF_CS3", 8, 12, 3, 1, 22, 0, 1, 1, 1)
212
202/* OMAP-1610 Flash */ 213/* OMAP-1610 Flash */
203MUX_CFG("L3_1610_FLASH_CS2B_OE",10, 6, 1, NA, 0, 0, NA, 0, 1) 214MUX_CFG("L3_1610_FLASH_CS2B_OE",10, 6, 1, NA, 0, 0, NA, 0, 1)
204MUX_CFG("M8_1610_FLASH_CS2B_WE",10, 3, 1, NA, 0, 0, NA, 0, 1) 215MUX_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
167static struct omap_mmc_config apollon_mmc_config __initdata = { 167static 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
37static struct prcm_config *curr_prcm_set; 39static struct prcm_config *curr_prcm_set;
38static u32 curr_perf_level = PRCM_FULL_SPEED; 40static u32 curr_perf_level = PRCM_FULL_SPEED;
41static struct clk *vclk;
42static 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
86static 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 */
83static void omap2_clk_fixed_enable(struct clk *clk) 95static 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
126static 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
171static int omap2_clk_enable(struct clk *clk) 239static 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
1029static 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
956static struct clk_functions omap2_clk_functions = { 1044static 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
964static void __init omap2_get_crystal_rate(struct clk *osc, struct clk *sys) 1053static 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/*
988static void __init omap2_disable_unused_clocks(void) 1077 * Set clocks for bypass mode for reboot to work.
1078 */
1079void 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}
1006late_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
1177static 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}
1184late_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
1370static struct clk mcspi1_ick = { 1370static 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
1379static struct clk mcspi1_fck = { 1380static 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
1388static struct clk mcspi2_ick = { 1390static 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
1397static struct clk mcspi2_fck = { 1400static 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
1406static struct clk mcspi3_ick = { 1410static 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
1415static struct clk mcspi3_fck = { 1420static 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
54static struct resource gpmc_mem_root;
55static struct resource gpmc_cs_mem[GPMC_CS_NUM];
56static spinlock_t gpmc_mem_lock = SPIN_LOCK_UNLOCKED;
57static unsigned gpmc_cs_map;
58
44static void __iomem *gpmc_base = 59static void __iomem *gpmc_base =
45 (void __iomem *) IO_ADDRESS(GPMC_BASE); 60 (void __iomem *) IO_ADDRESS(GPMC_BASE);
46static void __iomem *gpmc_cs_base = 61static 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
190unsigned long gpmc_cs_get_base_addr(int cs) 205static 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
220static 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
229static 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
240static 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
248static 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
254static int gpmc_cs_reserved(int cs)
255{
256 return gpmc_cs_map & (1 << cs);
257}
258
259static 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
273static 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
288int 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);
316out:
317 spin_unlock(&gpmc_mem_lock);
318 return r;
319}
320
321void 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
336void __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
195void __init gpmc_init(void) 369void __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)
104MUX_CFG_24XX("K15_24XX_UART3_TX", 0x118, 0, 0, 0, 1) 104MUX_CFG_24XX("K15_24XX_UART3_TX", 0x118, 0, 0, 0, 1)
105MUX_CFG_24XX("K14_24XX_UART3_RX", 0x119, 0, 0, 0, 1) 105MUX_CFG_24XX("K14_24XX_UART3_RX", 0x119, 0, 0, 0, 1)
106 106
107/* MMC/SDIO */
108MUX_CFG_24XX("G19_24XX_MMC_CLKO", 0x0f3, 0, 0, 0, 1)
109MUX_CFG_24XX("H18_24XX_MMC_CMD", 0x0f4, 0, 0, 0, 1)
110MUX_CFG_24XX("F20_24XX_MMC_DAT0", 0x0f5, 0, 0, 0, 1)
111MUX_CFG_24XX("H14_24XX_MMC_DAT1", 0x0f6, 0, 0, 0, 1)
112MUX_CFG_24XX("E19_24XX_MMC_DAT2", 0x0f7, 0, 0, 0, 1)
113MUX_CFG_24XX("D19_24XX_MMC_DAT3", 0x0f8, 0, 0, 0, 1)
114MUX_CFG_24XX("F19_24XX_MMC_DAT_DIR0", 0x0f9, 0, 0, 0, 1)
115MUX_CFG_24XX("E20_24XX_MMC_DAT_DIR1", 0x0fa, 0, 0, 0, 1)
116MUX_CFG_24XX("F18_24XX_MMC_DAT_DIR2", 0x0fb, 0, 0, 0, 1)
117MUX_CFG_24XX("E18_24XX_MMC_DAT_DIR3", 0x0fc, 0, 0, 0, 1)
118MUX_CFG_24XX("G18_24XX_MMC_CMD_DIR", 0x0fd, 0, 0, 0, 1)
119MUX_CFG_24XX("H15_24XX_MMC_CLKI", 0x0fe, 0, 0, 0, 1)
120
107/* Keypad GPIO*/ 121/* Keypad GPIO*/
108MUX_CFG_24XX("T19_24XX_KBR0", 0x106, 3, 1, 1, 1) 122MUX_CFG_24XX("T19_24XX_KBR0", 0x106, 3, 1, 1, 1)
109MUX_CFG_24XX("R19_24XX_KBR1", 0x107, 3, 1, 1, 1) 123MUX_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
22extern void omap2_clk_prepare_for_reboot(void);
23
22u32 omap_prcm_get_reset_sources(void) 24u32 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 */
29void omap_prcm_arch_reset(char mode) 31void 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
293config PM_SIMTEC 293config 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
298config S3C2410_LOWLEVEL_UART_PORT 298config 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
183struct irqchip s3c_irq_level_chip = { 183struct 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
190static struct irqchip s3c_irq_chip = { 191static 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
197static void 199static void
@@ -343,19 +345,21 @@ s3c_irqext_type(unsigned int irq, unsigned int type)
343} 345}
344 346
345static struct irqchip s3c_irqext_chip = { 347static 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
353static struct irqchip s3c_irq_eint0t4 = { 356static 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
389static struct irqchip s3c_irq_uart0 = { 393static 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
415static struct irqchip s3c_irq_uart1 = { 420static 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
441static struct irqchip s3c_irq_uart2 = { 447static 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
467static struct irqchip s3c_irq_adc = { 474static 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
571static void 579static void
572s3c_irq_demux_extint(unsigned int irq, 580s3c_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
602static void
603s3c_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
228static void __init amlm5900_init(void) 228static irqreturn_t
229amlm5900_wake_interrupt(int irq, void *ignored, struct pt_regs *regs)
229{ 230{
231 return IRQ_HANDLED;
232}
230 233
234static 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}
250static 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
237MACHINE_START(AML_M5900, "AML_M5900") 258MACHINE_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
54int s3c2410_pm_resume(struct sys_device *dev) 60int 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 */
94static struct locomo_dev *uart_dev = NULL; 94struct platform_device collie_locomo_device;
95 95
96static void collie_uart_set_mctrl(struct uart_port *port, u_int mctrl) 96static 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
111static u_int collie_uart_get_mctrl(struct uart_port *port) 109static 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
131static int collie_uart_probe(struct locomo_dev *dev) 130static int collie_uart_probe(struct locomo_dev *dev)
132{ 131{
133 uart_dev = dev;
134 return 0; 132 return 0;
135} 133}
136 134
137static int collie_uart_remove(struct locomo_dev *dev) 135static 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
173static struct platform_device locomo_device = { 170struct 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
180static struct platform_device *devices[] __initdata = { 177static 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 */
330static 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}
348late_initcall(clk_disable_unused);
349#endif
350
325int __init clk_init(struct clk_functions * custom_clocks) 351int __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
122void omap_set_dma_priority(int dst_port, int priority) 122void 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
150void omap_set_dma_transfer_params(int lch, int data_type, int elem_count, 159void 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
246void 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 */
238void omap_set_dma_src_params(int lch, int src_port, int src_amode, 255void 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 */
721int 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);
1414EXPORT_SYMBOL(omap_free_dma); 1465EXPORT_SYMBOL(omap_free_dma);
1415EXPORT_SYMBOL(omap_start_dma); 1466EXPORT_SYMBOL(omap_start_dma);
1416EXPORT_SYMBOL(omap_stop_dma); 1467EXPORT_SYMBOL(omap_stop_dma);
1468EXPORT_SYMBOL(omap_set_dma_callback);
1417EXPORT_SYMBOL(omap_enable_dma_irq); 1469EXPORT_SYMBOL(omap_enable_dma_irq);
1418EXPORT_SYMBOL(omap_disable_dma_irq); 1470EXPORT_SYMBOL(omap_disable_dma_irq);
1419 1471
1420EXPORT_SYMBOL(omap_set_dma_transfer_params); 1472EXPORT_SYMBOL(omap_set_dma_transfer_params);
1421EXPORT_SYMBOL(omap_set_dma_color_mode); 1473EXPORT_SYMBOL(omap_set_dma_color_mode);
1474EXPORT_SYMBOL(omap_set_dma_write_mode);
1422 1475
1423EXPORT_SYMBOL(omap_set_dma_src_params); 1476EXPORT_SYMBOL(omap_set_dma_src_params);
1424EXPORT_SYMBOL(omap_set_dma_src_index); 1477EXPORT_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
82static struct omap_dm_timer dm_timers[] = { 86static 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
95static struct omap_dm_timer dm_timers[] = { 102static 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
169static void omap_dm_timer_prepare(struct omap_dm_timer *timer) 183static 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
224void omap_dm_timer_free(struct omap_dm_timer *timer) 235void 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
245void 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
256void 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
235int omap_dm_timer_get_irq(struct omap_dm_timer *timer) 267int 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
277struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer) 309struct 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
411unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer) 444unsigned 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
416void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value) 453void 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
421unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer) 458unsigned 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
426void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value) 467void 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
431int omap_dm_timers_active(void) 472int 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
115struct gpio_bank { 115struct 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
534static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio) 540static 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
671static 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 */
666static int gpio_wake_enable(unsigned int irq, unsigned int enable) 680static 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
913static 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
901static void gpio_ack_irq(unsigned int irq) 921static 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
947static struct irq_chip gpio_irq_chip = { 967static 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;
75static struct clk *mcbsp1_fck = 0; 75static struct clk *mcbsp1_fck = 0;
76static struct clk *mcbsp2_ick = 0; 76static struct clk *mcbsp2_ick = 0;
77static struct clk *mcbsp2_fck = 0; 77static struct clk *mcbsp2_fck = 0;
78static struct clk *sys_ck = 0;
79static struct clk *sys_clkout = 0;
80#endif 78#endif
81 79
82static void omap_mcbsp_dump_reg(u8 id) 80static 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
60static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE];
61static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE];
62static unsigned int mpui730_sleep_save[MPUI730_SLEEP_SAVE_SIZE];
63static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE];
64static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE];
65
66static void (*omap_sram_idle)(void) = NULL;
67static 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 */
75void 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 */
122static 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
166void 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)
352static int g_read_completed;
353
354/*
355 * Read system PM registers for debugging
356 */
357static 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
496static 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
514static 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
541static 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
569static int omap_pm_finish(suspend_state_t state)
570{
571 return 0;
572}
573
574
575static irqreturn_t omap_wakeup_interrupt(int irq, void * dev,
576 struct pt_regs * regs)
577{
578 return IRQ_HANDLED;
579}
580
581static struct irqaction omap_wakeup_irq = {
582 .name = "peripheral wakeup",
583 .flags = IRQF_DISABLED,
584 .handler = omap_wakeup_interrupt
585};
586
587
588
589static 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
596static 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
106static inline void omap_32k_timer_start(unsigned long load_val) 106static 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 */
195static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, 197static 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
221static 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
227static 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 */
231void omap_32k_timer_reprogram(unsigned long next_tick) 247void 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
236static struct irqaction omap_32k_timer_irq; 260static 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