From 9bed07d0fed01f7c39d128e59e5d35d7d67ff439 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Sat, 3 Sep 2005 19:39:26 +0100 Subject: [ARM] 2874/1: S3C2410 - add cpu_init() call after sleep wakeup Patch from Ben Dooks The power management sleep code needs to call cpu_init() to restore the cpu state after the system resumes from suspend. Also clear off an un-necessary comment. Thanks to Dimitry Andric for reporting the bug and for rmk for pointing out the cause. Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/mach-s3c2410/pm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-s3c2410/pm.c b/arch/arm/mach-s3c2410/pm.c index 13a48ee77484..fe57d966a34d 100644 --- a/arch/arm/mach-s3c2410/pm.c +++ b/arch/arm/mach-s3c2410/pm.c @@ -585,14 +585,16 @@ static int s3c2410_pm_enter(suspend_state_t state) s3c2410_pm_check_store(); - // need to make some form of time-delta - /* send the cpu to sleep... */ __raw_writel(0x00, S3C2410_CLKCON); /* turn off clocks over sleep */ s3c2410_cpu_suspend(regs_save); + /* restore the cpu state */ + + cpu_init(); + /* unset the return-from-sleep flag, to ensure reset */ tmp = __raw_readl(S3C2410_GSTATUS2); -- cgit 1.4.1 From ca6ca91d8c7498d45e0d35800503699164366f10 Mon Sep 17 00:00:00 2001 From: Timothy Baldwin Date: Sun, 4 Sep 2005 10:13:48 +0100 Subject: [ARM] 2875/1: Data Abort fixes Patch from Timothy Baldwin All data aborts are treated as read accesses. The existing code updates the wrong bit of r1, also the comments are wrong in that the sense of the L bit is inverted. Signed-off-by: Timothy E. Baldwin Signed-off-by: Russell King --- arch/arm/mm/proc-arm6_7.S | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S index 0ee214b824ff..189ef6a71ba1 100644 --- a/arch/arm/mm/proc-arm6_7.S +++ b/arch/arm/mm/proc-arm6_7.S @@ -38,8 +38,8 @@ ENTRY(cpu_arm7_data_abort) mrc p15, 0, r1, c5, c0, 0 @ get FSR mrc p15, 0, r0, c6, c0, 0 @ get FAR ldr r8, [r0] @ read arm instruction - tst r8, #1 << 20 @ L = 1 -> write? - orreq r1, r1, #1 << 8 @ yes. + tst r8, #1 << 20 @ L = 0 -> write? + orreq r1, r1, #1 << 11 @ yes. and r7, r8, #15 << 24 add pc, pc, r7, lsr #22 @ Now branch to the relevant processing routine nop @@ -71,8 +71,8 @@ ENTRY(cpu_arm6_data_abort) mrc p15, 0, r1, c5, c0, 0 @ get FSR mrc p15, 0, r0, c6, c0, 0 @ get FAR ldr r8, [r2] @ read arm instruction - tst r8, #1 << 20 @ L = 1 -> write? - orreq r1, r1, #1 << 8 @ yes. + tst r8, #1 << 20 @ L = 0 -> write? + orreq r1, r1, #1 << 11 @ yes. and r7, r8, #14 << 24 teq r7, #8 << 24 @ was it ldm/stm movne pc, lr -- cgit 1.4.1 From 7db078be194469490caacac7d13bace38eaebdf5 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 4 Sep 2005 11:03:15 +0100 Subject: [ARM] Stack starts at THREAD_START_SP offset, not THREAD_SIZE-8 Use the correct constants. Signed-off-by: Russell King --- arch/arm/kernel/smp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm') diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index b2085735a2ba..826164945747 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -110,7 +110,7 @@ int __cpuinit __cpu_up(unsigned int cpu) * We need to tell the secondary core where to find * its stack and the page tables. */ - secondary_data.stack = (void *)idle->thread_info + THREAD_SIZE - 8; + secondary_data.stack = (void *)idle->thread_info + THREAD_START_SP; secondary_data.pgdir = virt_to_phys(pgd); wmb(); -- cgit 1.4.1 From e24da5d316667a91b3a19b5761a211946ec649bb Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Sun, 4 Sep 2005 11:33:12 +0100 Subject: [ARM] Fix compilation in locomo.c Do not access children in struct device directly, use device_for_each_child helper instead. It fixes compilation. Signed-off-by: Pavel Machek Signed-off-by: Russell King --- arch/arm/common/locomo.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c index 41f12658c8b4..30ab1c3e1d4d 100644 --- a/arch/arm/common/locomo.c +++ b/arch/arm/common/locomo.c @@ -651,15 +651,15 @@ __locomo_probe(struct device *me, struct resource *mem, int irq) return ret; } -static void __locomo_remove(struct locomo *lchip) +static int locomo_remove_child(struct device *dev, void *data) { - struct list_head *l, *n; - - list_for_each_safe(l, n, &lchip->dev->children) { - struct device *d = list_to_dev(l); + device_unregister(dev); + return 0; +} - device_unregister(d); - } +static void __locomo_remove(struct locomo *lchip) +{ + device_for_each_child(lchip->dev, NULL, locomo_remove_child); if (lchip->irq != NO_IRQ) { set_irq_chained_handler(lchip->irq, NULL); -- cgit 1.4.1 From 7801907b8c4a49f8ec033d13a938751114a97a55 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 4 Sep 2005 19:43:13 +0100 Subject: [ARM] Change irq_chip wake/type methods to set_wake/set_type This is part of Thomas Gleixner's generic IRQ patch, which converts ARM to use the generic IRQ subsystem. Here, we rename two of the irq_chip methods - wake becomes set_wake, and type becomes set_type. Signed-off-by: Russell King --- arch/arm/common/sa1111.c | 8 ++++---- arch/arm/kernel/irq.c | 16 ++++++++-------- arch/arm/mach-imx/irq.c | 2 +- arch/arm/mach-ixp2000/core.c | 8 ++++---- arch/arm/mach-pxa/irq.c | 4 ++-- arch/arm/mach-s3c2410/irq.c | 12 ++++++------ arch/arm/mach-sa1100/irq.c | 8 ++++---- include/asm-arm/mach/irq.h | 4 ++-- 8 files changed, 31 insertions(+), 31 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 38c2eb667eb9..1a47fbf9cbbc 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -268,8 +268,8 @@ static struct irqchip sa1111_low_chip = { .mask = sa1111_mask_lowirq, .unmask = sa1111_unmask_lowirq, .retrigger = sa1111_retrigger_lowirq, - .type = sa1111_type_lowirq, - .wake = sa1111_wake_lowirq, + .set_type = sa1111_type_lowirq, + .set_wake = sa1111_wake_lowirq, }; static void sa1111_mask_highirq(unsigned int irq) @@ -364,8 +364,8 @@ static struct irqchip sa1111_high_chip = { .mask = sa1111_mask_highirq, .unmask = sa1111_unmask_highirq, .retrigger = sa1111_retrigger_highirq, - .type = sa1111_type_highirq, - .wake = sa1111_wake_highirq, + .set_type = sa1111_type_highirq, + .set_wake = sa1111_wake_highirq, }; static void sa1111_setup_irq(struct sa1111 *sachip) diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 395137a8fad2..58b3bd000834 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -207,8 +207,8 @@ void enable_irq_wake(unsigned int irq) unsigned long flags; spin_lock_irqsave(&irq_controller_lock, flags); - if (desc->chip->wake) - desc->chip->wake(irq, 1); + if (desc->chip->set_wake) + desc->chip->set_wake(irq, 1); spin_unlock_irqrestore(&irq_controller_lock, flags); } EXPORT_SYMBOL(enable_irq_wake); @@ -219,8 +219,8 @@ void disable_irq_wake(unsigned int irq) unsigned long flags; spin_lock_irqsave(&irq_controller_lock, flags); - if (desc->chip->wake) - desc->chip->wake(irq, 0); + if (desc->chip->set_wake) + desc->chip->set_wake(irq, 0); spin_unlock_irqrestore(&irq_controller_lock, flags); } EXPORT_SYMBOL(disable_irq_wake); @@ -624,9 +624,9 @@ int set_irq_type(unsigned int irq, unsigned int type) } desc = irq_desc + irq; - if (desc->chip->type) { + if (desc->chip->set_type) { spin_lock_irqsave(&irq_controller_lock, flags); - ret = desc->chip->type(irq, type); + ret = desc->chip->set_type(irq, type); spin_unlock_irqrestore(&irq_controller_lock, flags); } @@ -846,8 +846,8 @@ unsigned long probe_irq_on(void) irq_desc[i].probing = 1; irq_desc[i].triggered = 0; - if (irq_desc[i].chip->type) - irq_desc[i].chip->type(i, IRQT_PROBE); + if (irq_desc[i].chip->set_type) + irq_desc[i].chip->set_type(i, IRQT_PROBE); irq_desc[i].chip->unmask(i); irqs += 1; } diff --git a/arch/arm/mach-imx/irq.c b/arch/arm/mach-imx/irq.c index 0c2713426dfd..45d22dd5583a 100644 --- a/arch/arm/mach-imx/irq.c +++ b/arch/arm/mach-imx/irq.c @@ -214,7 +214,7 @@ static struct irqchip imx_gpio_chip = { .ack = imx_gpio_ack_irq, .mask = imx_gpio_mask_irq, .unmask = imx_gpio_unmask_irq, - .type = imx_gpio_irq_type, + .set_type = imx_gpio_irq_type, }; void __init diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c index 45b18658499f..594b4c4d5b11 100644 --- a/arch/arm/mach-ixp2000/core.c +++ b/arch/arm/mach-ixp2000/core.c @@ -380,10 +380,10 @@ static void ixp2000_GPIO_irq_unmask(unsigned int irq) } static struct irqchip ixp2000_GPIO_irq_chip = { - .type = ixp2000_GPIO_irq_type, - .ack = ixp2000_GPIO_irq_mask_ack, - .mask = ixp2000_GPIO_irq_mask, - .unmask = ixp2000_GPIO_irq_unmask + .ack = ixp2000_GPIO_irq_mask_ack, + .mask = ixp2000_GPIO_irq_mask, + .unmask = ixp2000_GPIO_irq_unmask + .set_type = ixp2000_GPIO_irq_type, }; static void ixp2000_pci_irq_mask(unsigned int irq) diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index f3cac43124a5..6cf35f674464 100644 --- a/arch/arm/mach-pxa/irq.c +++ b/arch/arm/mach-pxa/irq.c @@ -133,7 +133,7 @@ static struct irqchip pxa_low_gpio_chip = { .ack = pxa_ack_low_gpio, .mask = pxa_mask_low_irq, .unmask = pxa_unmask_low_irq, - .type = pxa_gpio_irq_type, + .set_type = pxa_gpio_irq_type, }; /* @@ -241,7 +241,7 @@ static struct irqchip pxa_muxed_gpio_chip = { .ack = pxa_ack_muxed_gpio, .mask = pxa_mask_muxed_gpio, .unmask = pxa_unmask_muxed_gpio, - .type = pxa_gpio_irq_type, + .set_type = pxa_gpio_irq_type, }; diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c index 973a5fe6769c..67138797866a 100644 --- a/arch/arm/mach-s3c2410/irq.c +++ b/arch/arm/mach-s3c2410/irq.c @@ -184,14 +184,14 @@ struct irqchip s3c_irq_level_chip = { .ack = s3c_irq_maskack, .mask = s3c_irq_mask, .unmask = s3c_irq_unmask, - .wake = s3c_irq_wake + .set_wake = s3c_irq_wake }; static struct irqchip s3c_irq_chip = { .ack = s3c_irq_ack, .mask = s3c_irq_mask, .unmask = s3c_irq_unmask, - .wake = s3c_irq_wake + .set_wake = s3c_irq_wake }; /* S3C2410_EINTMASK @@ -350,16 +350,16 @@ static struct irqchip s3c_irqext_chip = { .mask = s3c_irqext_mask, .unmask = s3c_irqext_unmask, .ack = s3c_irqext_ack, - .type = s3c_irqext_type, - .wake = s3c_irqext_wake + .set_type = s3c_irqext_type, + .set_wake = s3c_irqext_wake }; static struct irqchip s3c_irq_eint0t4 = { .ack = s3c_irq_ack, .mask = s3c_irq_mask, .unmask = s3c_irq_unmask, - .wake = s3c_irq_wake, - .type = s3c_irqext_type, + .set_wake = s3c_irq_wake, + .set_type = s3c_irqext_type, }; /* mask values for the parent registers for each of the interrupt types */ diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c index 66a929cb7bc5..cc349bc1b7c2 100644 --- a/arch/arm/mach-sa1100/irq.c +++ b/arch/arm/mach-sa1100/irq.c @@ -98,8 +98,8 @@ static struct irqchip sa1100_low_gpio_chip = { .ack = sa1100_low_gpio_ack, .mask = sa1100_low_gpio_mask, .unmask = sa1100_low_gpio_unmask, - .type = sa1100_gpio_type, - .wake = sa1100_low_gpio_wake, + .set_type = sa1100_gpio_type, + .set_wake = sa1100_low_gpio_wake, }; /* @@ -181,8 +181,8 @@ static struct irqchip sa1100_high_gpio_chip = { .ack = sa1100_high_gpio_ack, .mask = sa1100_high_gpio_mask, .unmask = sa1100_high_gpio_unmask, - .type = sa1100_gpio_type, - .wake = sa1100_high_gpio_wake, + .set_type = sa1100_gpio_type, + .set_wake = sa1100_high_gpio_wake, }; /* diff --git a/include/asm-arm/mach/irq.h b/include/asm-arm/mach/irq.h index a43a353f6c7b..bc9763db1d37 100644 --- a/include/asm-arm/mach/irq.h +++ b/include/asm-arm/mach/irq.h @@ -42,11 +42,11 @@ struct irqchip { /* * Set the type of the IRQ. */ - int (*type)(unsigned int, unsigned int); + int (*set_type)(unsigned int, unsigned int); /* * Set wakeup-enable on the selected IRQ */ - int (*wake)(unsigned int, unsigned int); + int (*set_wake)(unsigned int, unsigned int); #ifdef CONFIG_SMP /* -- cgit 1.4.1 From 664399e1fbdceb18da9c9c5534dedd62327c63e8 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 4 Sep 2005 19:45:00 +0100 Subject: [ARM] Wrap calls to descriptor handlers This is part of Thomas Gleixner's generic IRQ patch, which converts ARM to use the generic IRQ subsystem. Here, we wrap calls to desc->handler() in an inline function, desc_handle_irq(). This reduces the size of Thomas' patch since the changes become more localised. Signed-off-by: Russell King --- arch/arm/common/locomo.c | 10 +++++----- arch/arm/kernel/ecard.c | 4 ++-- arch/arm/kernel/irq.c | 4 ++-- arch/arm/mach-footbridge/isa-irq.c | 2 +- arch/arm/mach-h720x/common.c | 2 +- arch/arm/mach-h720x/cpu-h7202.c | 2 +- arch/arm/mach-imx/irq.c | 2 +- arch/arm/mach-integrator/integrator_cp.c | 2 +- arch/arm/mach-ixp2000/core.c | 2 +- arch/arm/mach-ixp2000/ixdp2x00.c | 2 +- arch/arm/mach-ixp2000/ixdp2x01.c | 2 +- arch/arm/mach-lh7a40x/common.h | 2 +- arch/arm/mach-omap1/fpga.c | 2 +- arch/arm/mach-pxa/irq.c | 8 ++++---- arch/arm/mach-pxa/lubbock.c | 2 +- arch/arm/mach-pxa/mainstone.c | 2 +- arch/arm/mach-s3c2410/bast-irq.c | 2 +- arch/arm/mach-s3c2410/irq.c | 10 +++++----- arch/arm/mach-s3c2410/s3c2440-irq.c | 8 ++++---- arch/arm/mach-sa1100/irq.c | 2 +- arch/arm/mach-sa1100/neponset.c | 6 +++--- arch/arm/mach-versatile/core.c | 2 +- arch/arm/plat-omap/gpio.c | 2 +- include/asm-arm/mach/irq.h | 8 ++++++++ 24 files changed, 49 insertions(+), 41 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c index 30ab1c3e1d4d..51f430cc2fbf 100644 --- a/arch/arm/common/locomo.c +++ b/arch/arm/common/locomo.c @@ -177,7 +177,7 @@ static void locomo_handler(unsigned int irq, struct irqdesc *desc, d = irq_desc + irq; for (i = 0; i <= 3; i++, d++, irq++) { if (req & (0x0100 << i)) { - d->handle(irq, d, regs); + desc_handle_irq(irq, d, regs); } } @@ -220,7 +220,7 @@ static void locomo_key_handler(unsigned int irq, struct irqdesc *desc, if (locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC) & 0x0001) { d = irq_desc + LOCOMO_IRQ_KEY_START; - d->handle(LOCOMO_IRQ_KEY_START, d, regs); + desc_handle_irq(LOCOMO_IRQ_KEY_START, d, regs); } } @@ -273,7 +273,7 @@ static void locomo_gpio_handler(unsigned int irq, struct irqdesc *desc, d = irq_desc + LOCOMO_IRQ_GPIO_START; for (i = 0; i <= 15; i++, irq++, d++) { if (req & (0x0001 << i)) { - d->handle(irq, d, regs); + desc_handle_irq(irq, d, regs); } } } @@ -328,7 +328,7 @@ static void locomo_lt_handler(unsigned int irq, struct irqdesc *desc, if (locomo_readl(mapbase + LOCOMO_LTINT) & 0x0001) { d = irq_desc + LOCOMO_IRQ_LT_START; - d->handle(LOCOMO_IRQ_LT_START, d, regs); + desc_handle_irq(LOCOMO_IRQ_LT_START, d, regs); } } @@ -379,7 +379,7 @@ static void locomo_spi_handler(unsigned int irq, struct irqdesc *desc, for (i = 0; i <= 3; i++, irq++, d++) { if (req & (0x0001 << i)) { - d->handle(irq, d, regs); + desc_handle_irq(irq, d, regs); } } } diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c index 6540db691338..dceb826bd216 100644 --- a/arch/arm/kernel/ecard.c +++ b/arch/arm/kernel/ecard.c @@ -585,7 +585,7 @@ ecard_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) if (pending) { struct irqdesc *d = irq_desc + ec->irq; - d->handle(ec->irq, d, regs); + desc_handle_irq(ec->irq, d, regs); called ++; } } @@ -632,7 +632,7 @@ ecard_irqexp_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *reg * Serial cards should go in 0/1, ethernet/scsi in 2/3 * otherwise you will lose serial data at high speeds! */ - d->handle(ec->irq, d, regs); + desc_handle_irq(ec->irq, d, regs); } else { printk(KERN_WARNING "card%d: interrupt from unclaimed " "card???\n", slot); diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 58b3bd000834..3284118f356b 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -517,7 +517,7 @@ static void do_pending_irqs(struct pt_regs *regs) list_for_each_safe(l, n, &head) { desc = list_entry(l, struct irqdesc, pend); list_del_init(&desc->pend); - desc->handle(desc - irq_desc, desc, regs); + desc_handle_irq(desc - irq_desc, desc, regs); } /* @@ -545,7 +545,7 @@ asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs) irq_enter(); spin_lock(&irq_controller_lock); - desc->handle(irq, desc, regs); + desc_handle_irq(irq, desc, regs); /* * Now re-run any pending interrupts. diff --git a/arch/arm/mach-footbridge/isa-irq.c b/arch/arm/mach-footbridge/isa-irq.c index b21016070ea3..e1c43b331d64 100644 --- a/arch/arm/mach-footbridge/isa-irq.c +++ b/arch/arm/mach-footbridge/isa-irq.c @@ -95,7 +95,7 @@ isa_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) } desc = irq_desc + isa_irq; - desc->handle(isa_irq, desc, regs); + desc_handle_irq(isa_irq, desc, regs); } static struct irqaction irq_cascade = { .handler = no_action, .name = "cascade", }; diff --git a/arch/arm/mach-h720x/common.c b/arch/arm/mach-h720x/common.c index 96aa3af70d86..5110e2e65ddd 100644 --- a/arch/arm/mach-h720x/common.c +++ b/arch/arm/mach-h720x/common.c @@ -108,7 +108,7 @@ h720x_gpio_handler(unsigned int mask, unsigned int irq, while (mask) { if (mask & 1) { IRQDBG("handling irq %d\n", irq); - desc->handle(irq, desc, regs); + desc_handle_irq(irq, desc, regs); } irq++; desc++; diff --git a/arch/arm/mach-h720x/cpu-h7202.c b/arch/arm/mach-h720x/cpu-h7202.c index 593b6a2a30e1..4b3199319e68 100644 --- a/arch/arm/mach-h720x/cpu-h7202.c +++ b/arch/arm/mach-h720x/cpu-h7202.c @@ -126,7 +126,7 @@ h7202_timerx_demux_handler(unsigned int irq_unused, struct irqdesc *desc, desc = irq_desc + irq; while (mask) { if (mask & 1) - desc->handle(irq, desc, regs); + desc_handle_irq(irq, desc, regs); irq++; desc++; mask >>= 1; diff --git a/arch/arm/mach-imx/irq.c b/arch/arm/mach-imx/irq.c index 45d22dd5583a..eeb8a6d4a399 100644 --- a/arch/arm/mach-imx/irq.c +++ b/arch/arm/mach-imx/irq.c @@ -152,7 +152,7 @@ imx_gpio_handler(unsigned int mask, unsigned int irq, while (mask) { if (mask & 1) { DEBUG_IRQ("handling irq %d\n", irq); - desc->handle(irq, desc, regs); + desc_handle_irq(irq, desc, regs); } irq++; desc++; diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 569f328c479d..2be5c03ab87f 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -170,7 +170,7 @@ sic_handle_irq(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) irq += IRQ_SIC_START; desc = irq_desc + irq; - desc->handle(irq, desc, regs); + desc_handle_irq(irq, desc, regs); } while (status); } diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c index 594b4c4d5b11..781d10ae00b7 100644 --- a/arch/arm/mach-ixp2000/core.c +++ b/arch/arm/mach-ixp2000/core.c @@ -317,7 +317,7 @@ static void ixp2000_GPIO_irq_handler(unsigned int irq, struct irqdesc *desc, str for (i = 0; i <= 7; i++) { if (status & (1<handle(i + IRQ_IXP2000_GPIO0, desc, regs); + desc_handle_irq(i + IRQ_IXP2000_GPIO0, desc, regs); } } } diff --git a/arch/arm/mach-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c index a43369ad876c..63ba0191aa65 100644 --- a/arch/arm/mach-ixp2000/ixdp2x00.c +++ b/arch/arm/mach-ixp2000/ixdp2x00.c @@ -133,7 +133,7 @@ static void ixdp2x00_irq_handler(unsigned int irq, struct irqdesc *desc, struct struct irqdesc *cpld_desc; int cpld_irq = IXP2000_BOARD_IRQ(0) + i; cpld_desc = irq_desc + cpld_irq; - cpld_desc->handle(cpld_irq, cpld_desc, regs); + desc_handle_irq(cpld_irq, cpld_desc, regs); } } diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c index 43447dad1657..7a5109921287 100644 --- a/arch/arm/mach-ixp2000/ixdp2x01.c +++ b/arch/arm/mach-ixp2000/ixdp2x01.c @@ -82,7 +82,7 @@ static void ixdp2x01_irq_handler(unsigned int irq, struct irqdesc *desc, struct struct irqdesc *cpld_desc; int cpld_irq = IXP2000_BOARD_IRQ(0) + i; cpld_desc = irq_desc + cpld_irq; - cpld_desc->handle(cpld_irq, cpld_desc, regs); + desc_handle_irq(cpld_irq, cpld_desc, regs); } } diff --git a/arch/arm/mach-lh7a40x/common.h b/arch/arm/mach-lh7a40x/common.h index beda7c2602fb..578a52461fdb 100644 --- a/arch/arm/mach-lh7a40x/common.h +++ b/arch/arm/mach-lh7a40x/common.h @@ -13,4 +13,4 @@ extern struct sys_timer lh7a40x_timer; extern void lh7a400_init_irq (void); extern void lh7a404_init_irq (void); -#define IRQ_DISPATCH(irq) irq_desc[irq].handle ((irq), &irq_desc[irq], regs) +#define IRQ_DISPATCH(irq) desc_handle_irq((irq),(irq_desc + irq), regs) diff --git a/arch/arm/mach-omap1/fpga.c b/arch/arm/mach-omap1/fpga.c index 7c08f6c2e1d0..c12a78335625 100644 --- a/arch/arm/mach-omap1/fpga.c +++ b/arch/arm/mach-omap1/fpga.c @@ -102,7 +102,7 @@ void innovator_fpga_IRQ_demux(unsigned int irq, struct irqdesc *desc, fpga_irq++, stat >>= 1) { if (stat & 1) { d = irq_desc + fpga_irq; - d->handle(fpga_irq, d, regs); + desc_handle_irq(fpga_irq, d, regs); } } } diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index 6cf35f674464..539b596005fc 100644 --- a/arch/arm/mach-pxa/irq.c +++ b/arch/arm/mach-pxa/irq.c @@ -157,7 +157,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc, mask >>= 2; do { if (mask & 1) - desc->handle(irq, desc, regs); + desc_handle_irq(irq, desc, regs); irq++; desc++; mask >>= 1; @@ -172,7 +172,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc, desc = irq_desc + irq; do { if (mask & 1) - desc->handle(irq, desc, regs); + desc_handle_irq(irq, desc, regs); irq++; desc++; mask >>= 1; @@ -187,7 +187,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc, desc = irq_desc + irq; do { if (mask & 1) - desc->handle(irq, desc, regs); + desc_handle_irq(irq, desc, regs); irq++; desc++; mask >>= 1; @@ -203,7 +203,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc, desc = irq_desc + irq; do { if (mask & 1) - desc->handle(irq, desc, regs); + desc_handle_irq(irq, desc, regs); irq++; desc++; mask >>= 1; diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index 6309853b59be..923f6eb774c0 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -84,7 +84,7 @@ static void lubbock_irq_handler(unsigned int irq, struct irqdesc *desc, if (likely(pending)) { irq = LUBBOCK_IRQ(0) + __ffs(pending); desc = irq_desc + irq; - desc->handle(irq, desc, regs); + desc_handle_irq(irq, desc, regs); } pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled; } while (pending); diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 827b7b5a5be8..85fdb5b1470a 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -72,7 +72,7 @@ static void mainstone_irq_handler(unsigned int irq, struct irqdesc *desc, if (likely(pending)) { irq = MAINSTONE_IRQ(0) + __ffs(pending); desc = irq_desc + irq; - desc->handle(irq, desc, regs); + desc_handle_irq(irq, desc, regs); } pending = MST_INTSETCLR & mainstone_irq_enabled; } while (pending); diff --git a/arch/arm/mach-s3c2410/bast-irq.c b/arch/arm/mach-s3c2410/bast-irq.c index 5e5bbe893cbb..49914709fa09 100644 --- a/arch/arm/mach-s3c2410/bast-irq.c +++ b/arch/arm/mach-s3c2410/bast-irq.c @@ -124,7 +124,7 @@ bast_irq_pc104_demux(unsigned int irq, irqno = bast_pc104_irqs[i]; desc = irq_desc + irqno; - desc->handle(irqno, desc, regs); + desc_handle_irq(irqno, desc, regs); } stat >>= 1; diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c index 67138797866a..66d8c068e940 100644 --- a/arch/arm/mach-s3c2410/irq.c +++ b/arch/arm/mach-s3c2410/irq.c @@ -496,11 +496,11 @@ static void s3c_irq_demux_adc(unsigned int irq, if (subsrc != 0) { if (subsrc & 1) { mydesc = irq_desc + IRQ_TC; - mydesc->handle( IRQ_TC, mydesc, regs); + desc_handle_irq(IRQ_TC, mydesc, regs); } if (subsrc & 2) { mydesc = irq_desc + IRQ_ADC; - mydesc->handle(IRQ_ADC, mydesc, regs); + desc_handle_irq(IRQ_ADC, mydesc, regs); } } } @@ -529,17 +529,17 @@ static void s3c_irq_demux_uart(unsigned int start, desc = irq_desc + start; if (subsrc & 1) - desc->handle(start, desc, regs); + desc_handle_irq(start, desc, regs); desc++; if (subsrc & 2) - desc->handle(start+1, desc, regs); + desc_handle_irq(start+1, desc, regs); desc++; if (subsrc & 4) - desc->handle(start+2, desc, regs); + desc_handle_irq(start+2, desc, regs); } } diff --git a/arch/arm/mach-s3c2410/s3c2440-irq.c b/arch/arm/mach-s3c2410/s3c2440-irq.c index 7cb9912242a3..278d0044c85d 100644 --- a/arch/arm/mach-s3c2410/s3c2440-irq.c +++ b/arch/arm/mach-s3c2410/s3c2440-irq.c @@ -64,11 +64,11 @@ static void s3c_irq_demux_wdtac97(unsigned int irq, if (subsrc != 0) { if (subsrc & 1) { mydesc = irq_desc + IRQ_S3C2440_WDT; - mydesc->handle( IRQ_S3C2440_WDT, mydesc, regs); + desc_handle_irq(IRQ_S3C2440_WDT, mydesc, regs); } if (subsrc & 2) { mydesc = irq_desc + IRQ_S3C2440_AC97; - mydesc->handle(IRQ_S3C2440_AC97, mydesc, regs); + desc_handle_irq(IRQ_S3C2440_AC97, mydesc, regs); } } } @@ -122,11 +122,11 @@ static void s3c_irq_demux_cam(unsigned int irq, if (subsrc != 0) { if (subsrc & 1) { mydesc = irq_desc + IRQ_S3C2440_CAM_C; - mydesc->handle( IRQ_S3C2440_WDT, mydesc, regs); + desc_handle_irq(IRQ_S3C2440_CAM_C, mydesc, regs); } if (subsrc & 2) { mydesc = irq_desc + IRQ_S3C2440_CAM_P; - mydesc->handle(IRQ_S3C2440_AC97, mydesc, regs); + desc_handle_irq(IRQ_S3C2440_CAM_P, mydesc, regs); } } } diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c index cc349bc1b7c2..c131a5201b5b 100644 --- a/arch/arm/mach-sa1100/irq.c +++ b/arch/arm/mach-sa1100/irq.c @@ -126,7 +126,7 @@ sa1100_high_gpio_handler(unsigned int irq, struct irqdesc *desc, mask >>= 11; do { if (mask & 1) - desc->handle(irq, desc, regs); + desc_handle_irq(irq, desc, regs); mask >>= 1; irq++; desc++; diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c index 1405383463ea..fc061641b7be 100644 --- a/arch/arm/mach-sa1100/neponset.c +++ b/arch/arm/mach-sa1100/neponset.c @@ -61,12 +61,12 @@ neponset_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *reg if (irr & IRR_ETHERNET) { d = irq_desc + IRQ_NEPONSET_SMC9196; - d->handle(IRQ_NEPONSET_SMC9196, d, regs); + desc_handle_irq(IRQ_NEPONSET_SMC9196, d, regs); } if (irr & IRR_USAR) { d = irq_desc + IRQ_NEPONSET_USAR; - d->handle(IRQ_NEPONSET_USAR, d, regs); + desc_handle_irq(IRQ_NEPONSET_USAR, d, regs); } desc->chip->unmask(irq); @@ -74,7 +74,7 @@ neponset_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *reg if (irr & IRR_SA1111) { d = irq_desc + IRQ_NEPONSET_SA1111; - d->handle(IRQ_NEPONSET_SA1111, d, regs); + desc_handle_irq(IRQ_NEPONSET_SA1111, d, regs); } } } diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index f01c0f8a2bb3..3c8862fde51a 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -108,7 +108,7 @@ sic_handle_irq(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) irq += IRQ_SIC_START; desc = irq_desc + irq; - desc->handle(irq, desc, regs); + desc_handle_irq(irq, desc, regs); } while (status); } diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 1c85b4e536c2..aa481ea3d702 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -590,7 +590,7 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc, if (!(isr & 1)) continue; d = irq_desc + gpio_irq; - d->handle(gpio_irq, d, regs); + desc_handle_irq(gpio_irq, d, regs); } } diff --git a/include/asm-arm/mach/irq.h b/include/asm-arm/mach/irq.h index bc9763db1d37..0ce6ca588d8c 100644 --- a/include/asm-arm/mach/irq.h +++ b/include/asm-arm/mach/irq.h @@ -91,6 +91,14 @@ struct irqdesc { extern struct irqdesc irq_desc[]; +/* + * Helpful inline function for calling irq descriptor handlers. + */ +static inline void desc_handle_irq(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) +{ + desc->handle(irq, desc, regs); +} + /* * This is internal. Do not use it. */ -- cgit 1.4.1 From 027da01d734db0ca9dd1a084339dab07ab576935 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 5 Sep 2005 20:47:53 +0100 Subject: [ARM] 2876/1: N30 - remove task to toggle USB D+ line Patch from Ben Dooks The n30 machine file is using a kernel thread to change the state of the USB D+ pull-up resistor, which is not the proper way to do this. Once the usb-gadget support for the 24xx is merge, the proper access method will be added. This patch also removes the problem of using HZ for the msleep calls, from Nishanth Aravamudan. Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/mach-s3c2410/mach-n30.c | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index 79044d9bce38..66bf5bb2b3db 100644 --- a/arch/arm/mach-s3c2410/mach-n30.c +++ b/arch/arm/mach-s3c2410/mach-n30.c @@ -110,34 +110,24 @@ void __init n30_init_irq(void) s3c24xx_init_irq(); } - -static int n30_usbstart_thread(void *unused) -{ - /* Turn off suspend on both USB ports, and switch the - * selectable USB port to USB device mode. */ - writel(readl(S3C2410_MISCCR) & ~0x00003008, S3C2410_MISCCR); - - /* Turn off the D+ pull up for 3 seconds so that the USB host - * at the other end will do a rescan of the USB bus. */ - s3c2410_gpio_setpin(S3C2410_GPB3, 0); - - msleep_interruptible(3*HZ); - - s3c2410_gpio_setpin(S3C2410_GPB3, 1); - - return 0; -} - +/* GPB3 is the line that controls the pull-up for the USB D+ line */ void __init n30_init(void) { s3c_device_i2c.dev.platform_data = &n30_i2ccfg; - kthread_run(n30_usbstart_thread, NULL, "n30_usbstart"); + /* Turn off suspend on both USB ports, and switch the + * selectable USB port to USB device mode. */ + + s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST | + S3C2410_MISCCR_USBSUSPND0 | + S3C2410_MISCCR_USBSUSPND1, 0x0); } MACHINE_START(N30, "Acer-N30") - /* Maintainer: Christer Weinigel , Ben Dooks */ + /* Maintainer: Christer Weinigel , + Ben Dooks + */ .phys_ram = S3C2410_SDRAM_PA, .phys_io = S3C2410_PA_UART, .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, -- cgit 1.4.1 From 0ce7625f3c1e3f921f6b83f7e944e00031a39dfa Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Mon, 5 Sep 2005 20:49:54 +0100 Subject: [ARM] 2882/1: pxa2xx_sharpsl: Update PCMCIA driver to support variety of new hardware Patch from Richard Purdie This patch updates the PCMCIA pxa2xx_sharpsl driver to support multiple scoop devices by adding a scoop to pcmcia slot mapping structure. It adds platform support for poodle, is known to work on spitz (which is dual slot) and should also support collie with a minor amount of further work. Signed-off-by: Richard Purdie Signed-off-by: Russell King --- arch/arm/common/scoop.c | 6 +++ arch/arm/mach-pxa/corgi.c | 12 +++++ arch/arm/mach-pxa/poodle.c | 12 +++++ drivers/pcmcia/pxa2xx_sharpsl.c | 114 +++++++++++++++++++++------------------ include/asm-arm/hardware/scoop.h | 13 +++++ 5 files changed, 105 insertions(+), 52 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c index cfd0d3e550d9..688a595598c8 100644 --- a/arch/arm/common/scoop.c +++ b/arch/arm/common/scoop.c @@ -17,6 +17,12 @@ #define SCOOP_REG(d,adr) (*(volatile unsigned short*)(d +(adr))) +/* PCMCIA to Scoop linkage structures for pxa2xx_sharpsl.c + There is no easy way to link multiple scoop devices into one + single entity for the pxa2xx_pcmcia device */ +int scoop_num; +struct scoop_pcmcia_dev *scoop_devs; + struct scoop_dev { void *base; spinlock_t scoop_lock; diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index 86b862f56e7e..06ea730e8675 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -60,6 +60,15 @@ static struct scoop_config corgi_scoop_setup = { .io_out = CORGI_SCOOP_IO_OUT, }; +static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = { +{ + .dev = &corgiscoop_device.dev, + .irq = CORGI_IRQ_GPIO_CF_IRQ, + .cd_irq = CORGI_IRQ_GPIO_CF_CD, + .cd_irq_str = "PCMCIA0 CD", +}, +}; + struct platform_device corgiscoop_device = { .name = "sharp-scoop", .id = -1, @@ -241,6 +250,9 @@ static void __init corgi_init(void) pxa_set_udc_info(&udc_info); pxa_set_mci_info(&corgi_mci_platform_data); + scoop_num = 1; + scoop_devs = &corgi_pcmcia_scoop[0]; + platform_add_devices(devices, ARRAY_SIZE(devices)); } diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index 0e4f6fab100a..47cfb8bb8318 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c @@ -62,6 +62,15 @@ struct platform_device poodle_scoop_device = { .resource = poodle_scoop_resources, }; +static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = { +{ + .dev = &poodle_scoop_device.dev, + .irq = POODLE_IRQ_GPIO_CF_IRQ, + .cd_irq = POODLE_IRQ_GPIO_CF_CD, + .cd_irq_str = "PCMCIA0 CD", +}, +}; + /* LoCoMo device */ static struct resource locomo_resources[] = { @@ -147,6 +156,9 @@ static void __init poodle_init(void) set_pxa_fb_info(&poodle_fb_info); + scoop_num = 1; + scoop_devs = &poodle_pcmcia_scoop[0]; + ret = platform_add_devices(devices, ARRAY_SIZE(devices)); if (ret) { printk(KERN_WARNING "poodle: Unable to register LoCoMo device\n"); diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c index 7bac2f7d8b3f..a1178a600e3c 100644 --- a/drivers/pcmcia/pxa2xx_sharpsl.c +++ b/drivers/pcmcia/pxa2xx_sharpsl.c @@ -20,27 +20,18 @@ #include #include - #include -#include #include #include "soc_common.h" #define NO_KEEP_VS 0x0001 -static unsigned char keep_vs; -static unsigned char keep_rd; - -static struct pcmcia_irqs irqs[] = { - { 0, CORGI_IRQ_GPIO_CF_CD, "PCMCIA0 CD"}, -}; - -static void sharpsl_pcmcia_init_reset(void) +static void sharpsl_pcmcia_init_reset(struct scoop_pcmcia_dev *scoopdev) { - reset_scoop(&corgiscoop_device.dev); - keep_vs = NO_KEEP_VS; - keep_rd = 0; + reset_scoop(scoopdev->dev); + scoopdev->keep_vs = NO_KEEP_VS; + scoopdev->keep_rd = 0; } static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt) @@ -71,29 +62,35 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt) pxa_gpio_mode(GPIO57_nIOIS16_MD); /* Register interrupts */ - ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); - - if (ret) { - printk(KERN_ERR "Request for Compact Flash IRQ failed\n"); - return ret; + if (scoop_devs[skt->nr].cd_irq >= 0) { + struct pcmcia_irqs cd_irq; + + cd_irq.sock = skt->nr; + cd_irq.irq = scoop_devs[skt->nr].cd_irq; + cd_irq.str = scoop_devs[skt->nr].cd_irq_str; + ret = soc_pcmcia_request_irqs(skt, &cd_irq, 1); + + if (ret) { + printk(KERN_ERR "Request for Compact Flash IRQ failed\n"); + return ret; + } } - /* Enable interrupt */ - write_scoop_reg(&corgiscoop_device.dev, SCOOP_IMR, 0x00C0); - write_scoop_reg(&corgiscoop_device.dev, SCOOP_MCR, 0x0101); - keep_vs = NO_KEEP_VS; - - skt->irq = CORGI_IRQ_GPIO_CF_IRQ; + skt->irq = scoop_devs[skt->nr].irq; return 0; } static void sharpsl_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) { - soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); + if (scoop_devs[skt->nr].cd_irq >= 0) { + struct pcmcia_irqs cd_irq; - /* CF_BUS_OFF */ - sharpsl_pcmcia_init_reset(); + cd_irq.sock = skt->nr; + cd_irq.irq = scoop_devs[skt->nr].cd_irq; + cd_irq.str = scoop_devs[skt->nr].cd_irq_str; + soc_pcmcia_free_irqs(skt, &cd_irq, 1); + } } @@ -101,31 +98,32 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) { unsigned short cpr, csr; + struct device *scoop = scoop_devs[skt->nr].dev; - cpr = read_scoop_reg(&corgiscoop_device.dev, SCOOP_CPR); + cpr = read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR); - write_scoop_reg(&corgiscoop_device.dev, SCOOP_IRM, 0x00FF); - write_scoop_reg(&corgiscoop_device.dev, SCOOP_ISR, 0x0000); - write_scoop_reg(&corgiscoop_device.dev, SCOOP_IRM, 0x0000); - csr = read_scoop_reg(&corgiscoop_device.dev, SCOOP_CSR); + write_scoop_reg(scoop, SCOOP_IRM, 0x00FF); + write_scoop_reg(scoop, SCOOP_ISR, 0x0000); + write_scoop_reg(scoop, SCOOP_IRM, 0x0000); + csr = read_scoop_reg(scoop, SCOOP_CSR); if (csr & 0x0004) { /* card eject */ - write_scoop_reg(&corgiscoop_device.dev, SCOOP_CDR, 0x0000); - keep_vs = NO_KEEP_VS; + write_scoop_reg(scoop, SCOOP_CDR, 0x0000); + scoop_devs[skt->nr].keep_vs = NO_KEEP_VS; } - else if (!(keep_vs & NO_KEEP_VS)) { + else if (!(scoop_devs[skt->nr].keep_vs & NO_KEEP_VS)) { /* keep vs1,vs2 */ - write_scoop_reg(&corgiscoop_device.dev, SCOOP_CDR, 0x0000); - csr |= keep_vs; + write_scoop_reg(scoop, SCOOP_CDR, 0x0000); + csr |= scoop_devs[skt->nr].keep_vs; } else if (cpr & 0x0003) { /* power on */ - write_scoop_reg(&corgiscoop_device.dev, SCOOP_CDR, 0x0000); - keep_vs = (csr & 0x00C0); + write_scoop_reg(scoop, SCOOP_CDR, 0x0000); + scoop_devs[skt->nr].keep_vs = (csr & 0x00C0); } else { /* card detect */ - write_scoop_reg(&corgiscoop_device.dev, SCOOP_CDR, 0x0002); + write_scoop_reg(scoop, SCOOP_CDR, 0x0002); } state->detect = (csr & 0x0004) ? 0 : 1; @@ -147,6 +145,7 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) { unsigned long flags; + struct device *scoop = scoop_devs[skt->nr].dev; unsigned short cpr, ncpr, ccr, nccr, mcr, nmcr, imr, nimr; @@ -166,10 +165,10 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, local_irq_save(flags); - nmcr = (mcr = read_scoop_reg(&corgiscoop_device.dev, SCOOP_MCR)) & ~0x0010; - ncpr = (cpr = read_scoop_reg(&corgiscoop_device.dev, SCOOP_CPR)) & ~0x0083; - nccr = (ccr = read_scoop_reg(&corgiscoop_device.dev, SCOOP_CCR)) & ~0x0080; - nimr = (imr = read_scoop_reg(&corgiscoop_device.dev, SCOOP_IMR)) & ~0x003E; + nmcr = (mcr = read_scoop_reg(scoop, SCOOP_MCR)) & ~0x0010; + ncpr = (cpr = read_scoop_reg(scoop, SCOOP_CPR)) & ~0x0083; + nccr = (ccr = read_scoop_reg(scoop, SCOOP_CCR)) & ~0x0080; + nimr = (imr = read_scoop_reg(scoop, SCOOP_IMR)) & ~0x003E; ncpr |= (state->Vcc == 33) ? 0x0001 : (state->Vcc == 50) ? 0x0002 : 0; @@ -184,22 +183,22 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, ((skt->status&SS_WRPROT) ? 0x0008 : 0); if (!(ncpr & 0x0003)) { - keep_rd = 0; - } else if (!keep_rd) { + scoop_devs[skt->nr].keep_rd = 0; + } else if (!scoop_devs[skt->nr].keep_rd) { if (nccr & 0x0080) - keep_rd = 1; + scoop_devs[skt->nr].keep_rd = 1; else nccr |= 0x0080; } if (mcr != nmcr) - write_scoop_reg(&corgiscoop_device.dev, SCOOP_MCR, nmcr); + write_scoop_reg(scoop, SCOOP_MCR, nmcr); if (cpr != ncpr) - write_scoop_reg(&corgiscoop_device.dev, SCOOP_CPR, ncpr); + write_scoop_reg(scoop, SCOOP_CPR, ncpr); if (ccr != nccr) - write_scoop_reg(&corgiscoop_device.dev, SCOOP_CCR, nccr); + write_scoop_reg(scoop, SCOOP_CCR, nccr); if (imr != nimr) - write_scoop_reg(&corgiscoop_device.dev, SCOOP_IMR, nimr); + write_scoop_reg(scoop, SCOOP_IMR, nimr); local_irq_restore(flags); @@ -208,10 +207,18 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, static void sharpsl_pcmcia_socket_init(struct soc_pcmcia_socket *skt) { + sharpsl_pcmcia_init_reset(&scoop_devs[skt->nr]); + + /* Enable interrupt */ + write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_IMR, 0x00C0); + write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_MCR, 0x0101); + scoop_devs[skt->nr].keep_vs = NO_KEEP_VS; } static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) { + /* CF_BUS_OFF */ + sharpsl_pcmcia_init_reset(&scoop_devs[skt->nr]); } static struct pcmcia_low_level sharpsl_pcmcia_ops = { @@ -223,7 +230,7 @@ static struct pcmcia_low_level sharpsl_pcmcia_ops = { .socket_init = sharpsl_pcmcia_socket_init, .socket_suspend = sharpsl_pcmcia_socket_suspend, .first = 0, - .nr = 1, + .nr = 0, }; static struct platform_device *sharpsl_pcmcia_device; @@ -232,12 +239,15 @@ static int __init sharpsl_pcmcia_init(void) { int ret; + sharpsl_pcmcia_ops.nr=scoop_num; sharpsl_pcmcia_device = kmalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL); if (!sharpsl_pcmcia_device) return -ENOMEM; + memset(sharpsl_pcmcia_device, 0, sizeof(*sharpsl_pcmcia_device)); sharpsl_pcmcia_device->name = "pxa2xx-pcmcia"; sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops; + sharpsl_pcmcia_device->dev.parent=scoop_devs[0].dev; ret = platform_device_register(sharpsl_pcmcia_device); if (ret) diff --git a/include/asm-arm/hardware/scoop.h b/include/asm-arm/hardware/scoop.h index 7ea771ff6144..527404b5a8df 100644 --- a/include/asm-arm/hardware/scoop.h +++ b/include/asm-arm/hardware/scoop.h @@ -40,6 +40,19 @@ struct scoop_config { unsigned short io_dir; }; +/* Structure for linking scoop devices to PCMCIA sockets */ +struct scoop_pcmcia_dev { + struct device *dev; /* Pointer to this socket's scoop device */ + int irq; /* irq for socket */ + int cd_irq; + const char *cd_irq_str; + unsigned char keep_vs; + unsigned char keep_rd; +}; + +extern int scoop_num; +extern struct scoop_pcmcia_dev *scoop_devs; + void reset_scoop(struct device *dev); unsigned short set_scoop_gpio(struct device *dev, unsigned short bit); unsigned short reset_scoop_gpio(struct device *dev, unsigned short bit); -- cgit 1.4.1 From 2be863c959ea22ac9eb83e30f6cd92a8ae78bfdc Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 6 Sep 2005 23:13:17 +0100 Subject: [ARM] Fix missed initialisers/missing comma Fix the broken initialisers missed by the recent IRQ patch. Signed-off-by: Russell King --- arch/arm/mach-ixp2000/core.c | 2 +- arch/arm/mach-ixp4xx/common.c | 16 ++++++++-------- arch/arm/mach-omap1/irq.c | 8 ++++---- 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c index 781d10ae00b7..098c817a7fb8 100644 --- a/arch/arm/mach-ixp2000/core.c +++ b/arch/arm/mach-ixp2000/core.c @@ -382,7 +382,7 @@ static void ixp2000_GPIO_irq_unmask(unsigned int irq) static struct irqchip ixp2000_GPIO_irq_chip = { .ack = ixp2000_GPIO_irq_mask_ack, .mask = ixp2000_GPIO_irq_mask, - .unmask = ixp2000_GPIO_irq_unmask + .unmask = ixp2000_GPIO_irq_unmask, .set_type = ixp2000_GPIO_irq_type, }; diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index 0422e906cc9a..52ad11328e96 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -179,17 +179,17 @@ static void ixp4xx_irq_level_unmask(unsigned int irq) } static struct irqchip ixp4xx_irq_level_chip = { - .ack = ixp4xx_irq_mask, - .mask = ixp4xx_irq_mask, - .unmask = ixp4xx_irq_level_unmask, - .type = ixp4xx_set_irq_type + .ack = ixp4xx_irq_mask, + .mask = ixp4xx_irq_mask, + .unmask = ixp4xx_irq_level_unmask, + .set_type = ixp4xx_set_irq_type, }; static struct irqchip ixp4xx_irq_edge_chip = { - .ack = ixp4xx_irq_ack, - .mask = ixp4xx_irq_mask, - .unmask = ixp4xx_irq_unmask, - .type = ixp4xx_set_irq_type + .ack = ixp4xx_irq_ack, + .mask = ixp4xx_irq_mask, + .unmask = ixp4xx_irq_unmask, + .set_type = ixp4xx_set_irq_type, }; static void ixp4xx_config_irq(unsigned irq, enum ixp4xx_irq_type type) diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c index a11b6d807352..afd5d67e4ae7 100644 --- a/arch/arm/mach-omap1/irq.c +++ b/arch/arm/mach-omap1/irq.c @@ -165,10 +165,10 @@ static struct omap_irq_bank omap1610_irq_banks[] = { #endif static struct irqchip omap_irq_chip = { - .ack = omap_mask_ack_irq, - .mask = omap_mask_irq, - .unmask = omap_unmask_irq, - .wake = omap_wake_irq, + .ack = omap_mask_ack_irq, + .mask = omap_mask_irq, + .unmask = omap_unmask_irq, + .set_wake = omap_wake_irq, }; void __init omap_init_irq(void) -- cgit 1.4.1 From 7efb833d645d10258e32664404354d26cf6070e3 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 7 Sep 2005 11:49:23 +0100 Subject: [ARM] 2889/1: S3C2410 - Add machine Anubis Patch from Ben Dooks Add the Simtec Anubis to the list of supported machines in the arch/arm/mach-s3c2410 directory. This ensures the core peripherals are registered, the timer source is configured and the correct power-management is enabled. Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/mach-s3c2410/Kconfig | 7 + arch/arm/mach-s3c2410/Makefile | 1 + arch/arm/mach-s3c2410/mach-anubis.c | 270 +++++++++++++++++++++++++++++ arch/arm/mach-s3c2410/pm-simtec.c | 2 +- arch/arm/mach-s3c2410/time.c | 2 +- include/asm-arm/arch-s3c2410/anubis-cpld.h | 24 +++ include/asm-arm/arch-s3c2410/anubis-irq.h | 23 +++ include/asm-arm/arch-s3c2410/anubis-map.h | 46 +++++ 8 files changed, 373 insertions(+), 2 deletions(-) create mode 100644 arch/arm/mach-s3c2410/mach-anubis.c create mode 100644 include/asm-arm/arch-s3c2410/anubis-cpld.h create mode 100644 include/asm-arm/arch-s3c2410/anubis-irq.h create mode 100644 include/asm-arm/arch-s3c2410/anubis-map.h (limited to 'arch/arm') diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig index d4d03d0daaec..da818344f954 100644 --- a/arch/arm/mach-s3c2410/Kconfig +++ b/arch/arm/mach-s3c2410/Kconfig @@ -2,6 +2,13 @@ if ARCH_S3C2410 menu "S3C24XX Implementations" +config MACH_ANUBIS + bool "Simtec Electronics ANUBIS" + select CPU_S3C2440 + help + Say Y gere if you are using the Simtec Electronics ANUBIS + development system + config ARCH_BAST bool "Simtec Electronics BAST (EB2410ITX)" select CPU_S3C2410 diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile index 55ed7c7e57da..023c4f59a345 100644 --- a/arch/arm/mach-s3c2410/Makefile +++ b/arch/arm/mach-s3c2410/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_CPU_S3C2440) += s3c2440-clock.o # machine specific support +obj-$(CONFIG_MACH_ANUBIS) += mach-anubis.o obj-$(CONFIG_ARCH_BAST) += mach-bast.o usb-simtec.o obj-$(CONFIG_ARCH_H1940) += mach-h1940.o obj-$(CONFIG_MACH_N30) += mach-n30.o diff --git a/arch/arm/mach-s3c2410/mach-anubis.c b/arch/arm/mach-s3c2410/mach-anubis.c new file mode 100644 index 000000000000..f87aa0b669ad --- /dev/null +++ b/arch/arm/mach-s3c2410/mach-anubis.c @@ -0,0 +1,270 @@ +/* linux/arch/arm/mach-s3c2410/mach-anubis.c + * + * Copyright (c) 2003-2005 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Modifications: + * 02-May-2005 BJD Copied from mach-bast.c +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "clock.h" +#include "devs.h" +#include "cpu.h" + +#define COPYRIGHT ", (c) 2005 Simtec Electronics" + +static struct map_desc anubis_iodesc[] __initdata = { + /* ISA IO areas */ + + { (u32)S3C24XX_VA_ISA_BYTE, 0x0, SZ_16M, MT_DEVICE }, + { (u32)S3C24XX_VA_ISA_WORD, 0x0, SZ_16M, MT_DEVICE }, + + /* we could possibly compress the next set down into a set of smaller tables + * pagetables, but that would mean using an L2 section, and it still means + * we cannot actually feed the same register to an LDR due to 16K spacing + */ + + /* CPLD control registers */ + + { (u32)ANUBIS_VA_CTRL1, ANUBIS_PA_CTRL1, SZ_4K, MT_DEVICE }, + { (u32)ANUBIS_VA_CTRL2, ANUBIS_PA_CTRL2, SZ_4K, MT_DEVICE }, + + /* IDE drives */ + + { (u32)ANUBIS_IDEPRI, S3C2410_CS3, SZ_1M, MT_DEVICE }, + { (u32)ANUBIS_IDEPRIAUX, S3C2410_CS3+(1<<26), SZ_1M, MT_DEVICE }, + + { (u32)ANUBIS_IDESEC, S3C2410_CS4, SZ_1M, MT_DEVICE }, + { (u32)ANUBIS_IDESECAUX, S3C2410_CS4+(1<<26), SZ_1M, MT_DEVICE }, +}; + +#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK +#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB +#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE + +static struct s3c24xx_uart_clksrc anubis_serial_clocks[] = { + [0] = { + .name = "uclk", + .divisor = 1, + .min_baud = 0, + .max_baud = 0, + }, + [1] = { + .name = "pclk", + .divisor = 1, + .min_baud = 0, + .max_baud = 0. + } +}; + + +static struct s3c2410_uartcfg anubis_uartcfgs[] = { + [0] = { + .hwport = 0, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + .clocks = anubis_serial_clocks, + .clocks_size = ARRAY_SIZE(anubis_serial_clocks) + }, + [1] = { + .hwport = 2, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + .clocks = anubis_serial_clocks, + .clocks_size = ARRAY_SIZE(anubis_serial_clocks) + }, +}; + +/* NAND Flash on Anubis board */ + +static int external_map[] = { 2 }; +static int chip0_map[] = { 0 }; +static int chip1_map[] = { 1 }; + +struct mtd_partition anubis_default_nand_part[] = { + [0] = { + .name = "Boot Agent", + .size = SZ_16K, + .offset = 0 + }, + [1] = { + .name = "/boot", + .size = SZ_4M - SZ_16K, + .offset = SZ_16K, + }, + [2] = { + .name = "user1", + .offset = SZ_4M, + .size = SZ_32M - SZ_4M, + }, + [3] = { + .name = "user2", + .offset = SZ_32M, + .size = MTDPART_SIZ_FULL, + } +}; + +/* the Anubis has 3 selectable slots for nand-flash, the two + * on-board chip areas, as well as the external slot. + * + * Note, there is no current hot-plug support for the External + * socket. +*/ + +static struct s3c2410_nand_set anubis_nand_sets[] = { + [1] = { + .name = "External", + .nr_chips = 1, + .nr_map = external_map, + .nr_partitions = ARRAY_SIZE(anubis_default_nand_part), + .partitions = anubis_default_nand_part + }, + [0] = { + .name = "chip0", + .nr_chips = 1, + .nr_map = chip0_map, + .nr_partitions = ARRAY_SIZE(anubis_default_nand_part), + .partitions = anubis_default_nand_part + }, + [2] = { + .name = "chip1", + .nr_chips = 1, + .nr_map = chip1_map, + .nr_partitions = ARRAY_SIZE(anubis_default_nand_part), + .partitions = anubis_default_nand_part + }, +}; + +static void anubis_nand_select(struct s3c2410_nand_set *set, int slot) +{ + unsigned int tmp; + + slot = set->nr_map[slot] & 3; + + pr_debug("anubis_nand: selecting slot %d (set %p,%p)\n", + slot, set, set->nr_map); + + tmp = __raw_readb(ANUBIS_VA_CTRL1); + tmp &= ~ANUBIS_CTRL1_NANDSEL; + tmp |= slot; + + pr_debug("anubis_nand: ctrl1 now %02x\n", tmp); + + __raw_writeb(tmp, ANUBIS_VA_CTRL1); +} + +static struct s3c2410_platform_nand anubis_nand_info = { + .tacls = 25, + .twrph0 = 80, + .twrph1 = 80, + .nr_sets = ARRAY_SIZE(anubis_nand_sets), + .sets = anubis_nand_sets, + .select_chip = anubis_nand_select, +}; + + +/* Standard Anubis devices */ + +static struct platform_device *anubis_devices[] __initdata = { + &s3c_device_usb, + &s3c_device_wdt, + &s3c_device_adc, + &s3c_device_i2c, + &s3c_device_rtc, + &s3c_device_nand, +}; + +static struct clk *anubis_clocks[] = { + &s3c24xx_dclk0, + &s3c24xx_dclk1, + &s3c24xx_clkout0, + &s3c24xx_clkout1, + &s3c24xx_uclk, +}; + +static struct s3c24xx_board anubis_board __initdata = { + .devices = anubis_devices, + .devices_count = ARRAY_SIZE(anubis_devices), + .clocks = anubis_clocks, + .clocks_count = ARRAY_SIZE(anubis_clocks) +}; + +void __init anubis_map_io(void) +{ + /* initialise the clocks */ + + s3c24xx_dclk0.parent = NULL; + s3c24xx_dclk0.rate = 12*1000*1000; + + s3c24xx_dclk1.parent = NULL; + s3c24xx_dclk1.rate = 24*1000*1000; + + s3c24xx_clkout0.parent = &s3c24xx_dclk0; + s3c24xx_clkout1.parent = &s3c24xx_dclk1; + + s3c24xx_uclk.parent = &s3c24xx_clkout1; + + s3c_device_nand.dev.platform_data = &anubis_nand_info; + + s3c24xx_init_io(anubis_iodesc, ARRAY_SIZE(anubis_iodesc)); + s3c24xx_init_clocks(0); + s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs)); + s3c24xx_set_board(&anubis_board); + + /* ensure that the GPIO is setup */ + s3c2410_gpio_setpin(S3C2410_GPA0, 1); +} + +MACHINE_START(ANUBIS, "Simtec-Anubis") + /* Maintainer: Ben Dooks */ + .phys_ram = S3C2410_SDRAM_PA, + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, + .map_io = anubis_map_io, + .init_irq = s3c24xx_init_irq, + .timer = &s3c24xx_timer, +MACHINE_END diff --git a/arch/arm/mach-s3c2410/pm-simtec.c b/arch/arm/mach-s3c2410/pm-simtec.c index 2cb798832223..4c7ccef6c207 100644 --- a/arch/arm/mach-s3c2410/pm-simtec.c +++ b/arch/arm/mach-s3c2410/pm-simtec.c @@ -48,7 +48,7 @@ static __init int pm_simtec_init(void) /* check which machine we are running on */ - if (!machine_is_bast() && !machine_is_vr1000()) + if (!machine_is_bast() && !machine_is_vr1000() && !machine_is_anubis()) return 0; printk(KERN_INFO "Simtec Board Power Manangement" COPYRIGHT "\n"); diff --git a/arch/arm/mach-s3c2410/time.c b/arch/arm/mach-s3c2410/time.c index 765a3a9ae032..c0acfb2ad790 100644 --- a/arch/arm/mach-s3c2410/time.c +++ b/arch/arm/mach-s3c2410/time.c @@ -164,7 +164,7 @@ static void s3c2410_timer_setup (void) /* configure the system for whichever machine is in use */ - if (machine_is_bast() || machine_is_vr1000()) { + if (machine_is_bast() || machine_is_vr1000() || machine_is_anubis()) { /* timer is at 12MHz, scaler is 1 */ timer_usec_ticks = timer_mask_usec_ticks(1, 12000000); tcnt = 12000000 / HZ; diff --git a/include/asm-arm/arch-s3c2410/anubis-cpld.h b/include/asm-arm/arch-s3c2410/anubis-cpld.h new file mode 100644 index 000000000000..5675b1796b55 --- /dev/null +++ b/include/asm-arm/arch-s3c2410/anubis-cpld.h @@ -0,0 +1,24 @@ +/* linux/include/asm-arm/arch-s3c2410/anubis-cpld.h + * + * (c) 2005 Simtec Electronics + * http://www.simtec.co.uk/products/ + * Ben Dooks + * + * ANUBIS - CPLD control constants + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Changelog: + * +*/ + +#ifndef __ASM_ARCH_ANUBISCPLD_H +#define __ASM_ARCH_ANUBISCPLD_H + +/* CTRL2 - NAND WP control, IDE Reset assert/check */ + +#define ANUBIS_CTRL1_NANDSEL (0x3) + +#endif /* __ASM_ARCH_ANUBISCPLD_H */ diff --git a/include/asm-arm/arch-s3c2410/anubis-irq.h b/include/asm-arm/arch-s3c2410/anubis-irq.h new file mode 100644 index 000000000000..82f15dbd97e8 --- /dev/null +++ b/include/asm-arm/arch-s3c2410/anubis-irq.h @@ -0,0 +1,23 @@ +/* linux/include/asm-arm/arch-s3c2410/anubis-irq.h + * + * (c) 2005 Simtec Electronics + * http://www.simtec.co.uk/products/ + * Ben Dooks + * + * ANUBIS - IRQ Number definitions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Changelog: + */ + +#ifndef __ASM_ARCH_ANUBISIRQ_H +#define __ASM_ARCH_ANUBISIRQ_H + +#define IRQ_IDE0 IRQ_EINT2 +#define IRQ_IDE1 IRQ_EINT3 +#define IRQ_ASIX IRQ_EINT1 + +#endif /* __ASM_ARCH_ANUBISIRQ_H */ diff --git a/include/asm-arm/arch-s3c2410/anubis-map.h b/include/asm-arm/arch-s3c2410/anubis-map.h new file mode 100644 index 000000000000..97741d6e506a --- /dev/null +++ b/include/asm-arm/arch-s3c2410/anubis-map.h @@ -0,0 +1,46 @@ +/* linux/include/asm-arm/arch-s3c2410/anubis-map.h + * + * (c) 2005 Simtec Electronics + * http://www.simtec.co.uk/products/ + * Ben Dooks + * + * ANUBIS - Memory map definitions + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Changelog: +*/ + +/* needs arch/map.h including with this */ + +#ifndef __ASM_ARCH_ANUBISMAP_H +#define __ASM_ARCH_ANUBISMAP_H + +/* start peripherals off after the S3C2410 */ + +#define ANUBIS_IOADDR(x) (S3C2410_ADDR((x) + 0x02000000)) + +#define ANUBIS_PA_CPLD (S3C2410_CS1 | (1<<26)) + +/* we put the CPLD registers next, to get them out of the way */ + +#define ANUBIS_VA_CTRL1 ANUBIS_IOADDR(0x00000000) /* 0x01300000 */ +#define ANUBIS_PA_CTRL1 (ANUBIS_PA_CPLD) + +#define ANUBIS_VA_CTRL2 ANUBIS_IOADDR(0x00100000) /* 0x01400000 */ +#define ANUBIS_PA_CTRL2 (ANUBIS_PA_CPLD) + +#define ANUBIS_VA_CTRL3 ANUBIS_IOADDR(0x00200000) /* 0x01500000 */ +#define ANUBIS_PA_CTRL3 (ANUBIS_PA_CPLD) + +#define ANUBIS_VA_CTRL4 ANUBIS_IOADDR(0x00300000) /* 0x01600000 */ +#define ANUBIS_PA_CTRL4 (ANUBIS_PA_CPLD) + +#define ANUBIS_IDEPRI ANUBIS_IOADDR(0x01000000) +#define ANUBIS_IDEPRIAUX ANUBIS_IOADDR(0x01100000) +#define ANUBIS_IDESEC ANUBIS_IOADDR(0x01200000) +#define ANUBIS_IDESECAUX ANUBIS_IOADDR(0x01300000) + +#endif /* __ASM_ARCH_ANUBISMAP_H */ -- cgit 1.4.1 From 92105bb70634abacc08bbe12bf6f888fbd7dad38 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 7 Sep 2005 17:20:26 +0100 Subject: [ARM] 2887/1: OMAP 2/4: Update files common to omap1 and omap2, take 2 Patch from Tony Lindgren This patch syncs the mainline kernel with linux-omap tree. The highlights of the patch are: - Clock updates by Tuukka Tikkanen, Juha Yrjola, Daniel Petrini and Tony Lindgren - DMA fixes by Imre Deak, Juha Yrjola and Daniel Petrini - Add support to dual-mode hardware timers by Lauri Leukkunen - GPIO support for 24xx by Paul Mundt - GPIO wake-up support by Tony Lindgren - Better GPIO interrupt handler to not lose interrupts by Ralph Walden and Ladislav Michl - Power Management updates by Tuukka Tikkanen - Make Power Management code use new SRAM functions by Tony Lindgren Signed-off-by: Tony Lindgren Signed-off-by: Russell King --- arch/arm/plat-omap/Kconfig | 16 ++ arch/arm/plat-omap/Makefile | 4 +- arch/arm/plat-omap/clock.c | 39 +++- arch/arm/plat-omap/common.c | 7 +- arch/arm/plat-omap/dma.c | 25 ++- arch/arm/plat-omap/dmtimer.c | 260 +++++++++++++++++++++ arch/arm/plat-omap/gpio.c | 524 ++++++++++++++++++++++++++++++++++--------- arch/arm/plat-omap/mcbsp.c | 9 +- arch/arm/plat-omap/mux.c | 3 + arch/arm/plat-omap/ocpi.c | 1 + arch/arm/plat-omap/pm.c | 255 ++++++++++----------- arch/arm/plat-omap/sleep.S | 83 ++++--- arch/arm/plat-omap/sram-fn.S | 58 +++++ arch/arm/plat-omap/sram.c | 116 ++++++++++ arch/arm/plat-omap/sram.h | 21 ++ arch/arm/plat-omap/usb.c | 1 + 16 files changed, 1115 insertions(+), 307 deletions(-) create mode 100644 arch/arm/plat-omap/dmtimer.c create mode 100644 arch/arm/plat-omap/sram-fn.S create mode 100644 arch/arm/plat-omap/sram.c create mode 100644 arch/arm/plat-omap/sram.h (limited to 'arch/arm') diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index 345365852f8c..9693e9b4ffd1 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig @@ -91,6 +91,13 @@ config OMAP_32K_TIMER_HZ Kernel internal timer frequency should be a divisor of 32768, such as 64 or 128. +config OMAP_DM_TIMER + bool "Use dual-mode timer" + default n + depends on ARCH_OMAP16XX + help + Select this option if you want to use OMAP Dual-Mode timers. + choice prompt "Low-level debug console UART" depends on ARCH_OMAP @@ -107,6 +114,15 @@ config OMAP_LL_DEBUG_UART3 endchoice +config OMAP_SERIAL_WAKE + bool "Enable wake-up events for serial ports" + depends OMAP_MUX + default y + help + Select this option if you want to have your system wake up + to data on the serial RX line. This allows you to wake the + system from serial console. + endmenu endif diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile index 531e11af54d4..7e144f9cad1c 100644 --- a/arch/arm/plat-omap/Makefile +++ b/arch/arm/plat-omap/Makefile @@ -3,7 +3,7 @@ # # Common support -obj-y := common.o dma.o clock.o mux.o gpio.o mcbsp.o usb.o +obj-y := common.o sram.o sram-fn.o clock.o dma.o mux.o gpio.o mcbsp.o usb.o obj-m := obj-n := obj- := @@ -15,3 +15,5 @@ obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o obj-$(CONFIG_PM) += pm.o sleep.o obj-$(CONFIG_CPU_FREQ) += cpu-omap.o +obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o + diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c index 59d91b3262ba..52a58b2da288 100644 --- a/arch/arm/plat-omap/clock.c +++ b/arch/arm/plat-omap/clock.c @@ -21,6 +21,7 @@ #include #include "clock.h" +#include "sram.h" static LIST_HEAD(clocks); static DECLARE_MUTEX(clocks_sem); @@ -141,7 +142,7 @@ static struct clk arm_ck = { static struct clk armper_ck = { .name = "armper_ck", .parent = &ck_dpll1, - .flags = CLOCK_IN_OMAP730 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | RATE_CKCTL, .enable_reg = ARM_IDLECT2, .enable_bit = EN_PERCK, @@ -385,7 +386,8 @@ static struct clk uart2_ck = { .name = "uart2_ck", /* Direct from ULPD, no parent */ .rate = 12000000, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | ENABLE_REG_32BIT, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | ENABLE_REG_32BIT | + ALWAYS_ENABLED, .enable_reg = MOD_CONF_CTRL_0, .enable_bit = 30, /* Chooses between 12MHz and 48MHz */ .set_rate = &set_uart_rate, @@ -443,6 +445,15 @@ static struct clk usb_hhc_ck16xx = { .enable_bit = 8 /* UHOST_EN */, }; +static struct clk usb_dc_ck = { + .name = "usb_dc_ck", + /* Direct from ULPD, no parent */ + .rate = 48000000, + .flags = CLOCK_IN_OMAP16XX | RATE_FIXED, + .enable_reg = SOFT_REQ_REG, + .enable_bit = 4, +}; + static struct clk mclk_1510 = { .name = "mclk", /* Direct from ULPD, no parent. May be enabled by ext hardware. */ @@ -552,6 +563,7 @@ static struct clk * onchip_clks[] = { &uart3_16xx, &usb_clko, &usb_hhc_ck1510, &usb_hhc_ck16xx, + &usb_dc_ck, &mclk_1510, &mclk_16xx, &bclk_1510, &bclk_16xx, &mmc1_ck, @@ -946,14 +958,13 @@ static int select_table_rate(struct clk * clk, unsigned long rate) if (!ptr->rate) return -EINVAL; - if (!ptr->rate) - return -EINVAL; + /* + * In most cases we should not need to reprogram DPLL. + * Reprogramming the DPLL is tricky, it must be done from SRAM. + */ + omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val); - if (unlikely(ck_dpll1.rate == 0)) { - omap_writew(ptr->dpllctl_val, DPLL_CTL); - ck_dpll1.rate = ptr->pll_rate; - } - omap_writew(ptr->ckctl_val, ARM_CKCTL); + ck_dpll1.rate = ptr->pll_rate; propagate_rate(&ck_dpll1); return 0; } @@ -1224,9 +1235,11 @@ int __init clk_init(void) #endif /* Cache rates for clocks connected to ck_ref (not dpll1) */ propagate_rate(&ck_ref); - printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): %ld.%01ld/%ld/%ld MHz\n", + printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): " + "%ld.%01ld/%ld.%01ld/%ld.%01ld MHz\n", ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10, - ck_dpll1.rate, arm_ck.rate); + ck_dpll1.rate / 1000000, (ck_dpll1.rate / 100000) % 10, + arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10); #ifdef CONFIG_MACH_OMAP_PERSEUS2 /* Select slicer output as OMAP input clock */ @@ -1271,7 +1284,9 @@ static int __init omap_late_clk_reset(void) struct clk *p; __u32 regval32; - omap_writew(0, SOFT_REQ_REG); + /* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */ + regval32 = omap_readw(SOFT_REQ_REG) & (1 << 4); + omap_writew(regval32, SOFT_REQ_REG); omap_writew(0, SOFT_REQ_REG2); list_for_each_entry(p, &clocks, node) { diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c index ea967a8f6ce5..6cb20aea7f51 100644 --- a/arch/arm/plat-omap/common.c +++ b/arch/arm/plat-omap/common.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -35,11 +36,11 @@ #define NO_LENGTH_CHECK 0xffffffff -extern int omap_bootloader_tag_len; -extern u8 omap_bootloader_tag[]; +unsigned char omap_bootloader_tag[512]; +int omap_bootloader_tag_len; struct omap_board_config_kernel *omap_board_config; -int omap_board_config_size = 0; +int omap_board_config_size; static const void *get_config(u16 tag, size_t len, int skip, size_t *len_out) { diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index c0a5c2fa42bd..da7b65145658 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -425,7 +425,7 @@ static int dma_handle_ch(int ch) dma_chan[ch + 6].saved_csr = csr >> 7; csr &= 0x7f; } - if (!csr) + if ((csr & 0x3f) == 0) return 0; if (unlikely(dma_chan[ch].dev_id == -1)) { printk(KERN_WARNING "Spurious interrupt from DMA channel %d (CSR %04x)\n", @@ -890,11 +890,11 @@ void omap_enable_lcd_dma(void) w |= 1 << 8; omap_writew(w, OMAP1610_DMA_LCD_CTRL); + lcd_dma.active = 1; + w = omap_readw(OMAP1610_DMA_LCD_CCR); w |= 1 << 7; omap_writew(w, OMAP1610_DMA_LCD_CCR); - - lcd_dma.active = 1; } void omap_setup_lcd_dma(void) @@ -965,8 +965,8 @@ void omap_clear_dma(int lch) */ dma_addr_t omap_get_dma_src_pos(int lch) { - return (dma_addr_t) (OMAP_DMA_CSSA_L(lch) | - (OMAP_DMA_CSSA_U(lch) << 16)); + return (dma_addr_t) (omap_readw(OMAP_DMA_CSSA_L(lch)) | + (omap_readw(OMAP_DMA_CSSA_U(lch)) << 16)); } /* @@ -979,8 +979,18 @@ dma_addr_t omap_get_dma_src_pos(int lch) */ dma_addr_t omap_get_dma_dst_pos(int lch) { - return (dma_addr_t) (OMAP_DMA_CDSA_L(lch) | - (OMAP_DMA_CDSA_U(lch) << 16)); + return (dma_addr_t) (omap_readw(OMAP_DMA_CDSA_L(lch)) | + (omap_readw(OMAP_DMA_CDSA_U(lch)) << 16)); +} + +/* + * Returns current source transfer counting for the given DMA channel. + * Can be used to monitor the progress of a transfer inside a block. + * It must be called with disabled interrupts. + */ +int omap_get_dma_src_addr_counter(int lch) +{ + return (dma_addr_t) omap_readw(OMAP_DMA_CSAC(lch)); } int omap_dma_running(void) @@ -1076,6 +1086,7 @@ arch_initcall(omap_init_dma); EXPORT_SYMBOL(omap_get_dma_src_pos); EXPORT_SYMBOL(omap_get_dma_dst_pos); +EXPORT_SYMBOL(omap_get_dma_src_addr_counter); EXPORT_SYMBOL(omap_clear_dma); EXPORT_SYMBOL(omap_set_dma_priority); EXPORT_SYMBOL(omap_request_dma); diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c new file mode 100644 index 000000000000..a1468d7326eb --- /dev/null +++ b/arch/arm/plat-omap/dmtimer.c @@ -0,0 +1,260 @@ +/* + * linux/arch/arm/plat-omap/dmtimer.c + * + * OMAP Dual-Mode Timers + * + * Copyright (C) 2005 Nokia Corporation + * Author: Lauri Leukkunen + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define OMAP_TIMER_COUNT 8 + +#define OMAP_TIMER_ID_REG 0x00 +#define OMAP_TIMER_OCP_CFG_REG 0x10 +#define OMAP_TIMER_SYS_STAT_REG 0x14 +#define OMAP_TIMER_STAT_REG 0x18 +#define OMAP_TIMER_INT_EN_REG 0x1c +#define OMAP_TIMER_WAKEUP_EN_REG 0x20 +#define OMAP_TIMER_CTRL_REG 0x24 +#define OMAP_TIMER_COUNTER_REG 0x28 +#define OMAP_TIMER_LOAD_REG 0x2c +#define OMAP_TIMER_TRIGGER_REG 0x30 +#define OMAP_TIMER_WRITE_PEND_REG 0x34 +#define OMAP_TIMER_MATCH_REG 0x38 +#define OMAP_TIMER_CAPTURE_REG 0x3c +#define OMAP_TIMER_IF_CTRL_REG 0x40 + + +static struct dmtimer_info_struct { + struct list_head unused_timers; + struct list_head reserved_timers; +} dm_timer_info; + +static struct omap_dm_timer dm_timers[] = { + { .base=0xfffb1400, .irq=INT_1610_GPTIMER1 }, + { .base=0xfffb1c00, .irq=INT_1610_GPTIMER2 }, + { .base=0xfffb2400, .irq=INT_1610_GPTIMER3 }, + { .base=0xfffb2c00, .irq=INT_1610_GPTIMER4 }, + { .base=0xfffb3400, .irq=INT_1610_GPTIMER5 }, + { .base=0xfffb3c00, .irq=INT_1610_GPTIMER6 }, + { .base=0xfffb4400, .irq=INT_1610_GPTIMER7 }, + { .base=0xfffb4c00, .irq=INT_1610_GPTIMER8 }, + { .base=0x0 }, +}; + + +static spinlock_t dm_timer_lock; + + +inline void omap_dm_timer_write_reg(struct omap_dm_timer *timer, int reg, u32 value) +{ + omap_writel(value, timer->base + reg); + while (omap_dm_timer_read_reg(timer, OMAP_TIMER_WRITE_PEND_REG)) + ; +} + +u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, int reg) +{ + return omap_readl(timer->base + reg); +} + +int omap_dm_timers_active(void) +{ + struct omap_dm_timer *timer; + + for (timer = &dm_timers[0]; timer->base; ++timer) + if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) & + OMAP_TIMER_CTRL_ST) + return 1; + + return 0; +} + + +void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source) +{ + int n = (timer - dm_timers) << 1; + u32 l; + + l = omap_readl(MOD_CONF_CTRL_1) & ~(0x03 << n); + l |= source << n; + omap_writel(l, MOD_CONF_CTRL_1); +} + + +static void omap_dm_timer_reset(struct omap_dm_timer *timer) +{ + /* Reset and set posted mode */ + omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06); + omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_REG, 0x02); + + omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_ARMXOR); +} + + + +struct omap_dm_timer * omap_dm_timer_request(void) +{ + struct omap_dm_timer *timer = NULL; + unsigned long flags; + + spin_lock_irqsave(&dm_timer_lock, flags); + if (!list_empty(&dm_timer_info.unused_timers)) { + timer = (struct omap_dm_timer *) + dm_timer_info.unused_timers.next; + list_move_tail((struct list_head *)timer, + &dm_timer_info.reserved_timers); + } + spin_unlock_irqrestore(&dm_timer_lock, flags); + + return timer; +} + + +void omap_dm_timer_free(struct omap_dm_timer *timer) +{ + unsigned long flags; + + omap_dm_timer_reset(timer); + + spin_lock_irqsave(&dm_timer_lock, flags); + list_move_tail((struct list_head *)timer, &dm_timer_info.unused_timers); + spin_unlock_irqrestore(&dm_timer_lock, flags); +} + +void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, + unsigned int value) +{ + omap_dm_timer_write_reg(timer, OMAP_TIMER_INT_EN_REG, value); +} + +unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer) +{ + return omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG); +} + +void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value) +{ + omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG, value); +} + +void omap_dm_timer_enable_autoreload(struct omap_dm_timer *timer) +{ + u32 l; + l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); + l |= OMAP_TIMER_CTRL_AR; + omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); +} + +void omap_dm_timer_trigger(struct omap_dm_timer *timer) +{ + omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 1); +} + +void omap_dm_timer_set_trigger(struct omap_dm_timer *timer, unsigned int value) +{ + u32 l; + + l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); + l |= value & 0x3; + omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); +} + +void omap_dm_timer_start(struct omap_dm_timer *timer) +{ + u32 l; + + l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); + l |= OMAP_TIMER_CTRL_ST; + omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); +} + +void omap_dm_timer_stop(struct omap_dm_timer *timer) +{ + u32 l; + + l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); + l &= ~0x1; + omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); +} + +unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer) +{ + return omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG); +} + +void omap_dm_timer_reset_counter(struct omap_dm_timer *timer) +{ + omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, 0); +} + +void omap_dm_timer_set_load(struct omap_dm_timer *timer, unsigned int load) +{ + omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load); +} + +void omap_dm_timer_set_match(struct omap_dm_timer *timer, unsigned int match) +{ + omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match); +} + +void omap_dm_timer_enable_compare(struct omap_dm_timer *timer) +{ + u32 l; + + l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); + l |= OMAP_TIMER_CTRL_CE; + omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l); +} + + +static inline void __dm_timer_init(void) +{ + struct omap_dm_timer *timer; + + spin_lock_init(&dm_timer_lock); + INIT_LIST_HEAD(&dm_timer_info.unused_timers); + INIT_LIST_HEAD(&dm_timer_info.reserved_timers); + + timer = &dm_timers[0]; + while (timer->base) { + list_add_tail((struct list_head *)timer, &dm_timer_info.unused_timers); + omap_dm_timer_reset(timer); + timer++; + } +} + +static int __init omap_dm_timer_init(void) +{ + if (cpu_is_omap16xx()) + __dm_timer_init(); + return 0; +} + +arch_initcall(omap_dm_timer_init); diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index aa481ea3d702..55059a24ad41 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -3,7 +3,7 @@ * * Support functions for OMAP GPIO * - * Copyright (C) 2003 Nokia Corporation + * Copyright (C) 2003-2005 Nokia Corporation * Written by Juha Yrjölä * * This program is free software; you can redistribute it and/or modify @@ -17,8 +17,11 @@ #include #include #include +#include +#include #include +#include #include #include #include @@ -29,7 +32,7 @@ /* * OMAP1510 GPIO registers */ -#define OMAP1510_GPIO_BASE 0xfffce000 +#define OMAP1510_GPIO_BASE (void __iomem *)0xfffce000 #define OMAP1510_GPIO_DATA_INPUT 0x00 #define OMAP1510_GPIO_DATA_OUTPUT 0x04 #define OMAP1510_GPIO_DIR_CONTROL 0x08 @@ -43,34 +46,37 @@ /* * OMAP1610 specific GPIO registers */ -#define OMAP1610_GPIO1_BASE 0xfffbe400 -#define OMAP1610_GPIO2_BASE 0xfffbec00 -#define OMAP1610_GPIO3_BASE 0xfffbb400 -#define OMAP1610_GPIO4_BASE 0xfffbbc00 +#define OMAP1610_GPIO1_BASE (void __iomem *)0xfffbe400 +#define OMAP1610_GPIO2_BASE (void __iomem *)0xfffbec00 +#define OMAP1610_GPIO3_BASE (void __iomem *)0xfffbb400 +#define OMAP1610_GPIO4_BASE (void __iomem *)0xfffbbc00 #define OMAP1610_GPIO_REVISION 0x0000 #define OMAP1610_GPIO_SYSCONFIG 0x0010 #define OMAP1610_GPIO_SYSSTATUS 0x0014 #define OMAP1610_GPIO_IRQSTATUS1 0x0018 #define OMAP1610_GPIO_IRQENABLE1 0x001c +#define OMAP1610_GPIO_WAKEUPENABLE 0x0028 #define OMAP1610_GPIO_DATAIN 0x002c #define OMAP1610_GPIO_DATAOUT 0x0030 #define OMAP1610_GPIO_DIRECTION 0x0034 #define OMAP1610_GPIO_EDGE_CTRL1 0x0038 #define OMAP1610_GPIO_EDGE_CTRL2 0x003c #define OMAP1610_GPIO_CLEAR_IRQENABLE1 0x009c +#define OMAP1610_GPIO_CLEAR_WAKEUPENA 0x00a8 #define OMAP1610_GPIO_CLEAR_DATAOUT 0x00b0 #define OMAP1610_GPIO_SET_IRQENABLE1 0x00dc +#define OMAP1610_GPIO_SET_WAKEUPENA 0x00e8 #define OMAP1610_GPIO_SET_DATAOUT 0x00f0 /* * OMAP730 specific GPIO registers */ -#define OMAP730_GPIO1_BASE 0xfffbc000 -#define OMAP730_GPIO2_BASE 0xfffbc800 -#define OMAP730_GPIO3_BASE 0xfffbd000 -#define OMAP730_GPIO4_BASE 0xfffbd800 -#define OMAP730_GPIO5_BASE 0xfffbe000 -#define OMAP730_GPIO6_BASE 0xfffbe800 +#define OMAP730_GPIO1_BASE (void __iomem *)0xfffbc000 +#define OMAP730_GPIO2_BASE (void __iomem *)0xfffbc800 +#define OMAP730_GPIO3_BASE (void __iomem *)0xfffbd000 +#define OMAP730_GPIO4_BASE (void __iomem *)0xfffbd800 +#define OMAP730_GPIO5_BASE (void __iomem *)0xfffbe000 +#define OMAP730_GPIO6_BASE (void __iomem *)0xfffbe800 #define OMAP730_GPIO_DATA_INPUT 0x00 #define OMAP730_GPIO_DATA_OUTPUT 0x04 #define OMAP730_GPIO_DIR_CONTROL 0x08 @@ -78,14 +84,43 @@ #define OMAP730_GPIO_INT_MASK 0x10 #define OMAP730_GPIO_INT_STATUS 0x14 +/* + * omap24xx specific GPIO registers + */ +#define OMAP24XX_GPIO1_BASE (void __iomem *)0x48018000 +#define OMAP24XX_GPIO2_BASE (void __iomem *)0x4801a000 +#define OMAP24XX_GPIO3_BASE (void __iomem *)0x4801c000 +#define OMAP24XX_GPIO4_BASE (void __iomem *)0x4801e000 +#define OMAP24XX_GPIO_REVISION 0x0000 +#define OMAP24XX_GPIO_SYSCONFIG 0x0010 +#define OMAP24XX_GPIO_SYSSTATUS 0x0014 +#define OMAP24XX_GPIO_IRQSTATUS1 0x0018 +#define OMAP24XX_GPIO_IRQENABLE1 0x001c +#define OMAP24XX_GPIO_CTRL 0x0030 +#define OMAP24XX_GPIO_OE 0x0034 +#define OMAP24XX_GPIO_DATAIN 0x0038 +#define OMAP24XX_GPIO_DATAOUT 0x003c +#define OMAP24XX_GPIO_LEVELDETECT0 0x0040 +#define OMAP24XX_GPIO_LEVELDETECT1 0x0044 +#define OMAP24XX_GPIO_RISINGDETECT 0x0048 +#define OMAP24XX_GPIO_FALLINGDETECT 0x004c +#define OMAP24XX_GPIO_CLEARIRQENABLE1 0x0060 +#define OMAP24XX_GPIO_SETIRQENABLE1 0x0064 +#define OMAP24XX_GPIO_CLEARWKUENA 0x0080 +#define OMAP24XX_GPIO_SETWKUENA 0x0084 +#define OMAP24XX_GPIO_CLEARDATAOUT 0x0090 +#define OMAP24XX_GPIO_SETDATAOUT 0x0094 + #define OMAP_MPUIO_MASK (~OMAP_MAX_GPIO_LINES & 0xff) struct gpio_bank { - u32 base; + void __iomem *base; u16 irq; u16 virtual_irq_start; - u8 method; + int method; u32 reserved_map; + u32 suspend_wakeup; + u32 saved_wakeup; spinlock_t lock; }; @@ -93,8 +128,9 @@ struct gpio_bank { #define METHOD_GPIO_1510 1 #define METHOD_GPIO_1610 2 #define METHOD_GPIO_730 3 +#define METHOD_GPIO_24XX 4 -#if defined(CONFIG_ARCH_OMAP16XX) +#ifdef CONFIG_ARCH_OMAP16XX static struct gpio_bank gpio_bank_1610[5] = { { OMAP_MPUIO_BASE, INT_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO}, { OMAP1610_GPIO1_BASE, INT_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_1610 }, @@ -123,6 +159,15 @@ static struct gpio_bank gpio_bank_730[7] = { }; #endif +#ifdef CONFIG_ARCH_OMAP24XX +static struct gpio_bank gpio_bank_24xx[4] = { + { OMAP24XX_GPIO1_BASE, INT_24XX_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_24XX }, + { OMAP24XX_GPIO2_BASE, INT_24XX_GPIO_BANK2, IH_GPIO_BASE + 32, METHOD_GPIO_24XX }, + { OMAP24XX_GPIO3_BASE, INT_24XX_GPIO_BANK3, IH_GPIO_BASE + 64, METHOD_GPIO_24XX }, + { OMAP24XX_GPIO4_BASE, INT_24XX_GPIO_BANK4, IH_GPIO_BASE + 96, METHOD_GPIO_24XX }, +}; +#endif + static struct gpio_bank *gpio_bank; static int gpio_bank_count; @@ -149,14 +194,23 @@ static inline struct gpio_bank *get_gpio_bank(int gpio) return &gpio_bank[1 + (gpio >> 5)]; } #endif +#ifdef CONFIG_ARCH_OMAP24XX + if (cpu_is_omap24xx()) + return &gpio_bank[gpio >> 5]; +#endif } static inline int get_gpio_index(int gpio) { +#ifdef CONFIG_ARCH_OMAP730 if (cpu_is_omap730()) return gpio & 0x1f; - else - return gpio & 0x0f; +#endif +#ifdef CONFIG_ARCH_OMAP24XX + if (cpu_is_omap24xx()) + return gpio & 0x1f; +#endif + return gpio & 0x0f; } static inline int gpio_valid(int gpio) @@ -179,6 +233,10 @@ static inline int gpio_valid(int gpio) #ifdef CONFIG_ARCH_OMAP730 if (cpu_is_omap730() && gpio < 192) return 0; +#endif +#ifdef CONFIG_ARCH_OMAP24XX + if (cpu_is_omap24xx() && gpio < 128) + return 0; #endif return -1; } @@ -195,7 +253,7 @@ static int check_gpio(int gpio) static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input) { - u32 reg = bank->base; + void __iomem *reg = bank->base; u32 l; switch (bank->method) { @@ -211,6 +269,9 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input) case METHOD_GPIO_730: reg += OMAP730_GPIO_DIR_CONTROL; break; + case METHOD_GPIO_24XX: + reg += OMAP24XX_GPIO_OE; + break; } l = __raw_readl(reg); if (is_input) @@ -234,7 +295,7 @@ void omap_set_gpio_direction(int gpio, int is_input) static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) { - u32 reg = bank->base; + void __iomem *reg = bank->base; u32 l = 0; switch (bank->method) { @@ -269,6 +330,13 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) else l &= ~(1 << gpio); break; + case METHOD_GPIO_24XX: + if (enable) + reg += OMAP24XX_GPIO_SETDATAOUT; + else + reg += OMAP24XX_GPIO_CLEARDATAOUT; + l = 1 << gpio; + break; default: BUG(); return; @@ -291,7 +359,7 @@ void omap_set_gpio_dataout(int gpio, int enable) int omap_get_gpio_datain(int gpio) { struct gpio_bank *bank; - u32 reg; + void __iomem *reg; if (check_gpio(gpio) < 0) return -1; @@ -310,109 +378,132 @@ int omap_get_gpio_datain(int gpio) case METHOD_GPIO_730: reg += OMAP730_GPIO_DATA_INPUT; break; + case METHOD_GPIO_24XX: + reg += OMAP24XX_GPIO_DATAIN; + break; default: BUG(); return -1; } - return (__raw_readl(reg) & (1 << get_gpio_index(gpio))) != 0; + return (__raw_readl(reg) + & (1 << get_gpio_index(gpio))) != 0; } -static void _set_gpio_edge_ctrl(struct gpio_bank *bank, int gpio, int edge) +#define MOD_REG_BIT(reg, bit_mask, set) \ +do { \ + int l = __raw_readl(base + reg); \ + if (set) l |= bit_mask; \ + else l &= ~bit_mask; \ + __raw_writel(l, base + reg); \ +} while(0) + +static inline void set_24xx_gpio_triggering(void __iomem *base, int gpio, int trigger) { - u32 reg = bank->base; - u32 l; + u32 gpio_bit = 1 << gpio; + + MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit, + trigger & IRQT_LOW); + MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit, + trigger & IRQT_HIGH); + MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit, + trigger & IRQT_RISING); + MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit, + trigger & IRQT_FALLING); + /* FIXME: Possibly do 'set_irq_handler(j, do_level_IRQ)' if only level + * triggering requested. */ +} + +static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) +{ + void __iomem *reg = bank->base; + u32 l = 0; switch (bank->method) { case METHOD_MPUIO: reg += OMAP_MPUIO_GPIO_INT_EDGE; l = __raw_readl(reg); - if (edge == OMAP_GPIO_RISING_EDGE) + if (trigger == IRQT_RISING) l |= 1 << gpio; - else + else if (trigger == IRQT_FALLING) l &= ~(1 << gpio); - __raw_writel(l, reg); + else + goto bad; break; case METHOD_GPIO_1510: reg += OMAP1510_GPIO_INT_CONTROL; l = __raw_readl(reg); - if (edge == OMAP_GPIO_RISING_EDGE) + if (trigger == IRQT_RISING) l |= 1 << gpio; - else + else if (trigger == IRQT_FALLING) l &= ~(1 << gpio); - __raw_writel(l, reg); + else + goto bad; break; case METHOD_GPIO_1610: - edge &= 0x03; if (gpio & 0x08) reg += OMAP1610_GPIO_EDGE_CTRL2; else reg += OMAP1610_GPIO_EDGE_CTRL1; gpio &= 0x07; + /* We allow only edge triggering, i.e. two lowest bits */ + if (trigger & ~IRQT_BOTHEDGE) + BUG(); + /* NOTE: knows __IRQT_{FAL,RIS}EDGE match OMAP hardware */ + trigger &= 0x03; l = __raw_readl(reg); l &= ~(3 << (gpio << 1)); - l |= edge << (gpio << 1); - __raw_writel(l, reg); + l |= trigger << (gpio << 1); break; case METHOD_GPIO_730: reg += OMAP730_GPIO_INT_CONTROL; l = __raw_readl(reg); - if (edge == OMAP_GPIO_RISING_EDGE) + if (trigger == IRQT_RISING) l |= 1 << gpio; - else + else if (trigger == IRQT_FALLING) l &= ~(1 << gpio); - __raw_writel(l, reg); + else + goto bad; + break; + case METHOD_GPIO_24XX: + set_24xx_gpio_triggering(reg, gpio, trigger); break; default: BUG(); - return; + goto bad; } + __raw_writel(l, reg); + return 0; +bad: + return -EINVAL; } -void omap_set_gpio_edge_ctrl(int gpio, int edge) +static int gpio_irq_type(unsigned irq, unsigned type) { struct gpio_bank *bank; + unsigned gpio; + int retval; + + if (irq > IH_MPUIO_BASE) + gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE); + else + gpio = irq - IH_GPIO_BASE; if (check_gpio(gpio) < 0) - return; + return -EINVAL; + + if (type & (__IRQT_LOWLVL|__IRQT_HIGHLVL|IRQT_PROBE)) + return -EINVAL; + bank = get_gpio_bank(gpio); spin_lock(&bank->lock); - _set_gpio_edge_ctrl(bank, get_gpio_index(gpio), edge); + retval = _set_gpio_triggering(bank, get_gpio_index(gpio), type); spin_unlock(&bank->lock); -} - - -static int _get_gpio_edge_ctrl(struct gpio_bank *bank, int gpio) -{ - u32 reg = bank->base, l; - - switch (bank->method) { - case METHOD_MPUIO: - l = __raw_readl(reg + OMAP_MPUIO_GPIO_INT_EDGE); - return (l & (1 << gpio)) ? - OMAP_GPIO_RISING_EDGE : OMAP_GPIO_FALLING_EDGE; - case METHOD_GPIO_1510: - l = __raw_readl(reg + OMAP1510_GPIO_INT_CONTROL); - return (l & (1 << gpio)) ? - OMAP_GPIO_RISING_EDGE : OMAP_GPIO_FALLING_EDGE; - case METHOD_GPIO_1610: - if (gpio & 0x08) - reg += OMAP1610_GPIO_EDGE_CTRL2; - else - reg += OMAP1610_GPIO_EDGE_CTRL1; - return (__raw_readl(reg) >> ((gpio & 0x07) << 1)) & 0x03; - case METHOD_GPIO_730: - l = __raw_readl(reg + OMAP730_GPIO_INT_CONTROL); - return (l & (1 << gpio)) ? - OMAP_GPIO_RISING_EDGE : OMAP_GPIO_FALLING_EDGE; - default: - BUG(); - return -1; - } + return retval; } static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) { - u32 reg = bank->base; + void __iomem *reg = bank->base; switch (bank->method) { case METHOD_MPUIO: @@ -428,6 +519,9 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) case METHOD_GPIO_730: reg += OMAP730_GPIO_INT_STATUS; break; + case METHOD_GPIO_24XX: + reg += OMAP24XX_GPIO_IRQSTATUS1; + break; default: BUG(); return; @@ -442,7 +536,7 @@ static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio) static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enable) { - u32 reg = bank->base; + void __iomem *reg = bank->base; u32 l; switch (bank->method) { @@ -477,6 +571,13 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab else l |= gpio_mask; break; + case METHOD_GPIO_24XX: + if (enable) + reg += OMAP24XX_GPIO_SETIRQENABLE1; + else + reg += OMAP24XX_GPIO_CLEARIRQENABLE1; + l = gpio_mask; + break; default: BUG(); return; @@ -489,6 +590,50 @@ static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int ena _enable_gpio_irqbank(bank, 1 << get_gpio_index(gpio), enable); } +/* + * Note that ENAWAKEUP needs to be enabled in GPIO_SYSCONFIG register. + * 1510 does not seem to have a wake-up register. If JTAG is connected + * to the target, system will wake up always on GPIO events. While + * system is running all registered GPIO interrupts need to have wake-up + * enabled. When system is suspended, only selected GPIO interrupts need + * to have wake-up enabled. + */ +static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) +{ + switch (bank->method) { + case METHOD_GPIO_1610: + case METHOD_GPIO_24XX: + spin_lock(&bank->lock); + if (enable) + bank->suspend_wakeup |= (1 << gpio); + else + bank->suspend_wakeup &= ~(1 << gpio); + spin_unlock(&bank->lock); + return 0; + default: + printk(KERN_ERR "Can't enable GPIO wakeup for method %i\n", + bank->method); + return -EINVAL; + } +} + +/* Use disable_irq_wake() and enable_irq_wake() functions from drivers */ +static int gpio_wake_enable(unsigned int irq, unsigned int enable) +{ + unsigned int gpio = irq - IH_GPIO_BASE; + struct gpio_bank *bank; + int retval; + + if (check_gpio(gpio) < 0) + return -ENODEV; + bank = get_gpio_bank(gpio); + spin_lock(&bank->lock); + retval = _set_gpio_wakeup(bank, get_gpio_index(gpio), enable); + spin_unlock(&bank->lock); + + return retval; +} + int omap_request_gpio(int gpio) { struct gpio_bank *bank; @@ -505,14 +650,32 @@ int omap_request_gpio(int gpio) return -1; } bank->reserved_map |= (1 << get_gpio_index(gpio)); + + /* Set trigger to none. You need to enable the trigger after request_irq */ + _set_gpio_triggering(bank, get_gpio_index(gpio), IRQT_NOEDGE); + #ifdef CONFIG_ARCH_OMAP1510 if (bank->method == METHOD_GPIO_1510) { - u32 reg; + void __iomem *reg; - /* Claim the pin for the ARM */ + /* Claim the pin for MPU */ reg = bank->base + OMAP1510_GPIO_PIN_CONTROL; __raw_writel(__raw_readl(reg) | (1 << get_gpio_index(gpio)), reg); } +#endif +#ifdef CONFIG_ARCH_OMAP16XX + if (bank->method == METHOD_GPIO_1610) { + /* Enable wake-up during idle for dynamic tick */ + void __iomem *reg = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; + __raw_writel(1 << get_gpio_index(gpio), reg); + } +#endif +#ifdef CONFIG_ARCH_OMAP24XX + if (bank->method == METHOD_GPIO_24XX) { + /* Enable wake-up during idle for dynamic tick */ + void __iomem *reg = bank->base + OMAP24XX_GPIO_SETWKUENA; + __raw_writel(1 << get_gpio_index(gpio), reg); + } #endif spin_unlock(&bank->lock); @@ -533,6 +696,20 @@ void omap_free_gpio(int gpio) spin_unlock(&bank->lock); return; } +#ifdef CONFIG_ARCH_OMAP16XX + if (bank->method == METHOD_GPIO_1610) { + /* Disable wake-up during idle for dynamic tick */ + void __iomem *reg = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA; + __raw_writel(1 << get_gpio_index(gpio), reg); + } +#endif +#ifdef CONFIG_ARCH_OMAP24XX + if (bank->method == METHOD_GPIO_24XX) { + /* Disable wake-up during idle for dynamic tick */ + void __iomem *reg = bank->base + OMAP24XX_GPIO_CLEARWKUENA; + __raw_writel(1 << get_gpio_index(gpio), reg); + } +#endif bank->reserved_map &= ~(1 << get_gpio_index(gpio)); _set_gpio_direction(bank, get_gpio_index(gpio), 1); _set_gpio_irqenable(bank, gpio, 0); @@ -552,7 +729,7 @@ void omap_free_gpio(int gpio) static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) { - u32 isr_reg = 0; + void __iomem *isr_reg = NULL; u32 isr; unsigned int gpio_irq; struct gpio_bank *bank; @@ -574,24 +751,30 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc, if (bank->method == METHOD_GPIO_730) isr_reg = bank->base + OMAP730_GPIO_INT_STATUS; #endif +#ifdef CONFIG_ARCH_OMAP24XX + if (bank->method == METHOD_GPIO_24XX) + isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1; +#endif - isr = __raw_readl(isr_reg); - _enable_gpio_irqbank(bank, isr, 0); - _clear_gpio_irqbank(bank, isr); - _enable_gpio_irqbank(bank, isr, 1); - desc->chip->unmask(irq); - - if (unlikely(!isr)) - return; - - gpio_irq = bank->virtual_irq_start; - for (; isr != 0; isr >>= 1, gpio_irq++) { - struct irqdesc *d; - if (!(isr & 1)) - continue; - d = irq_desc + gpio_irq; - desc_handle_irq(gpio_irq, d, regs); - } + while(1) { + isr = __raw_readl(isr_reg); + _enable_gpio_irqbank(bank, isr, 0); + _clear_gpio_irqbank(bank, isr); + _enable_gpio_irqbank(bank, isr, 1); + desc->chip->unmask(irq); + + if (!isr) + break; + + gpio_irq = bank->virtual_irq_start; + for (; isr != 0; isr >>= 1, gpio_irq++) { + struct irqdesc *d; + if (!(isr & 1)) + continue; + d = irq_desc + gpio_irq; + desc_handle_irq(gpio_irq, d, regs); + } + } } static void gpio_ack_irq(unsigned int irq) @@ -613,14 +796,10 @@ static void gpio_mask_irq(unsigned int irq) static void gpio_unmask_irq(unsigned int irq) { unsigned int gpio = irq - IH_GPIO_BASE; + unsigned int gpio_idx = get_gpio_index(gpio); struct gpio_bank *bank = get_gpio_bank(gpio); - if (_get_gpio_edge_ctrl(bank, get_gpio_index(gpio)) == OMAP_GPIO_NO_EDGE) { - printk(KERN_ERR "OMAP GPIO %d: trying to enable GPIO IRQ while no edge is set\n", - gpio); - _set_gpio_edge_ctrl(bank, get_gpio_index(gpio), OMAP_GPIO_RISING_EDGE); - } - _set_gpio_irqenable(bank, gpio, 1); + _set_gpio_irqenable(bank, gpio_idx, 1); } static void mpuio_ack_irq(unsigned int irq) @@ -645,9 +824,11 @@ static void mpuio_unmask_irq(unsigned int irq) } static struct irqchip gpio_irq_chip = { - .ack = gpio_ack_irq, - .mask = gpio_mask_irq, - .unmask = gpio_unmask_irq, + .ack = gpio_ack_irq, + .mask = gpio_mask_irq, + .unmask = gpio_unmask_irq, + .set_type = gpio_irq_type, + .set_wake = gpio_wake_enable, }; static struct irqchip mpuio_irq_chip = { @@ -657,6 +838,7 @@ static struct irqchip mpuio_irq_chip = { }; static int initialized = 0; +static struct clk * gpio_ck = NULL; static int __init _omap_gpio_init(void) { @@ -665,6 +847,14 @@ static int __init _omap_gpio_init(void) initialized = 1; + if (cpu_is_omap1510()) { + gpio_ck = clk_get(NULL, "arm_gpio_ck"); + if (IS_ERR(gpio_ck)) + printk("Could not get arm_gpio_ck\n"); + else + clk_use(gpio_ck); + } + #ifdef CONFIG_ARCH_OMAP1510 if (cpu_is_omap1510()) { printk(KERN_INFO "OMAP1510 GPIO hardware\n"); @@ -674,7 +864,7 @@ static int __init _omap_gpio_init(void) #endif #if defined(CONFIG_ARCH_OMAP16XX) if (cpu_is_omap16xx()) { - int rev; + u32 rev; gpio_bank_count = 5; gpio_bank = gpio_bank_1610; @@ -689,6 +879,17 @@ static int __init _omap_gpio_init(void) gpio_bank_count = 7; gpio_bank = gpio_bank_730; } +#endif +#ifdef CONFIG_ARCH_OMAP24XX + if (cpu_is_omap24xx()) { + int rev; + + gpio_bank_count = 4; + gpio_bank = gpio_bank_24xx; + rev = omap_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION); + printk(KERN_INFO "OMAP24xx GPIO hardware version %d.%d\n", + (rev >> 4) & 0x0f, rev & 0x0f); + } #endif for (i = 0; i < gpio_bank_count; i++) { int j, gpio_count = 16; @@ -710,6 +911,7 @@ static int __init _omap_gpio_init(void) if (bank->method == METHOD_GPIO_1610) { __raw_writew(0x0000, bank->base + OMAP1610_GPIO_IRQENABLE1); __raw_writew(0xffff, bank->base + OMAP1610_GPIO_IRQSTATUS1); + __raw_writew(0x0014, bank->base + OMAP1610_GPIO_SYSCONFIG); } #endif #ifdef CONFIG_ARCH_OMAP730 @@ -719,6 +921,14 @@ static int __init _omap_gpio_init(void) gpio_count = 32; /* 730 has 32-bit GPIOs */ } +#endif +#ifdef CONFIG_ARCH_OMAP24XX + if (bank->method == METHOD_GPIO_24XX) { + __raw_writel(0x00000000, bank->base + OMAP24XX_GPIO_IRQENABLE1); + __raw_writel(0xffffffff, bank->base + OMAP24XX_GPIO_IRQSTATUS1); + + gpio_count = 32; + } #endif for (j = bank->virtual_irq_start; j < bank->virtual_irq_start + gpio_count; j++) { @@ -735,12 +945,97 @@ static int __init _omap_gpio_init(void) /* Enable system clock for GPIO module. * The CAM_CLK_CTRL *is* really the right place. */ - if (cpu_is_omap1610() || cpu_is_omap1710()) + if (cpu_is_omap16xx()) omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, ULPD_CAM_CLK_CTRL); return 0; } +#if defined (CONFIG_ARCH_OMAP16XX) || defined (CONFIG_ARCH_OMAP24XX) +static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg) +{ + int i; + + if (!cpu_is_omap24xx() && !cpu_is_omap16xx()) + return 0; + + for (i = 0; i < gpio_bank_count; i++) { + struct gpio_bank *bank = &gpio_bank[i]; + void __iomem *wake_status; + void __iomem *wake_clear; + void __iomem *wake_set; + + switch (bank->method) { + case METHOD_GPIO_1610: + wake_status = bank->base + OMAP1610_GPIO_WAKEUPENABLE; + wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA; + wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; + break; + case METHOD_GPIO_24XX: + wake_status = bank->base + OMAP24XX_GPIO_SETWKUENA; + wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA; + wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA; + break; + default: + continue; + } + + spin_lock(&bank->lock); + bank->saved_wakeup = __raw_readl(wake_status); + __raw_writel(0xffffffff, wake_clear); + __raw_writel(bank->suspend_wakeup, wake_set); + spin_unlock(&bank->lock); + } + + return 0; +} + +static int omap_gpio_resume(struct sys_device *dev) +{ + int i; + + if (!cpu_is_omap24xx() && !cpu_is_omap16xx()) + return 0; + + for (i = 0; i < gpio_bank_count; i++) { + struct gpio_bank *bank = &gpio_bank[i]; + void __iomem *wake_clear; + void __iomem *wake_set; + + switch (bank->method) { + case METHOD_GPIO_1610: + wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA; + wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; + break; + case METHOD_GPIO_24XX: + wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA; + wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; + break; + default: + continue; + } + + spin_lock(&bank->lock); + __raw_writel(0xffffffff, wake_clear); + __raw_writel(bank->saved_wakeup, wake_set); + spin_unlock(&bank->lock); + } + + return 0; +} + +static struct sysdev_class omap_gpio_sysclass = { + set_kset_name("gpio"), + .suspend = omap_gpio_suspend, + .resume = omap_gpio_resume, +}; + +static struct sys_device omap_gpio_device = { + .id = 0, + .cls = &omap_gpio_sysclass, +}; +#endif + /* * This may get called early from board specific init */ @@ -752,11 +1047,30 @@ int omap_gpio_init(void) return 0; } +static int __init omap_gpio_sysinit(void) +{ + int ret = 0; + + if (!initialized) + ret = _omap_gpio_init(); + +#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP24XX) + if (cpu_is_omap16xx() || cpu_is_omap24xx()) { + if (ret == 0) { + ret = sysdev_class_register(&omap_gpio_sysclass); + if (ret == 0) + ret = sysdev_register(&omap_gpio_device); + } + } +#endif + + return ret; +} + EXPORT_SYMBOL(omap_request_gpio); EXPORT_SYMBOL(omap_free_gpio); EXPORT_SYMBOL(omap_set_gpio_direction); EXPORT_SYMBOL(omap_set_gpio_dataout); EXPORT_SYMBOL(omap_get_gpio_datain); -EXPORT_SYMBOL(omap_set_gpio_edge_ctrl); -arch_initcall(omap_gpio_init); +arch_initcall(omap_gpio_sysinit); diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index 43567d5edddb..9c9b7df3faf6 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -187,9 +188,6 @@ static int omap_mcbsp_check(unsigned int id) return -1; } -#define EN_XORPCK 1 -#define DSP_RSTCT2 0xe1008014 - static void omap_mcbsp_dsp_request(void) { if (cpu_is_omap1510() || cpu_is_omap16xx()) { @@ -198,6 +196,11 @@ static void omap_mcbsp_dsp_request(void) /* enable 12MHz clock to mcbsp 1 & 3 */ clk_use(mcbsp_dspxor_ck); + + /* + * DSP external peripheral reset + * FIXME: This should be moved to dsp code + */ __raw_writew(__raw_readw(DSP_RSTCT2) | 1 | 1 << 1, DSP_RSTCT2); } diff --git a/arch/arm/plat-omap/mux.c b/arch/arm/plat-omap/mux.c index ea7b955b9c81..64482040f89e 100644 --- a/arch/arm/plat-omap/mux.c +++ b/arch/arm/plat-omap/mux.c @@ -48,6 +48,9 @@ omap_cfg_reg(const reg_cfg_t reg_cfg) pull_orig = 0, pull = 0; unsigned int mask, warn = 0; + if (cpu_is_omap7xx()) + return 0; + if (reg_cfg > ARRAY_SIZE(reg_cfg_table)) { printk(KERN_ERR "MUX: reg_cfg %d\n", reg_cfg); return -EINVAL; diff --git a/arch/arm/plat-omap/ocpi.c b/arch/arm/plat-omap/ocpi.c index 2ede2ee8cae4..1fb16f9edfd5 100644 --- a/arch/arm/plat-omap/ocpi.c +++ b/arch/arm/plat-omap/ocpi.c @@ -25,6 +25,7 @@ #include #include +#include #include #include #include diff --git a/arch/arm/plat-omap/pm.c b/arch/arm/plat-omap/pm.c index e6536b16c385..e15c6c1ddec9 100644 --- a/arch/arm/plat-omap/pm.c +++ b/arch/arm/plat-omap/pm.c @@ -39,24 +39,32 @@ #include #include #include +#include #include +#include #include -#include +#include -#include +#include +#include +#include #include #include -#include #include +#include #include "clock.h" +#include "sram.h" static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE]; static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE]; static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE]; static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE]; +static void (*omap_sram_idle)(void) = NULL; +static void (*omap_sram_suspend)(unsigned long r0, unsigned long r1) = NULL; + /* * Let's power down on idle, but only if we are really * idle, because once we start down the path of @@ -65,7 +73,6 @@ static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE]; */ void omap_pm_idle(void) { - int (*func_ptr)(void) = 0; unsigned int mask32 = 0; /* @@ -83,6 +90,13 @@ void omap_pm_idle(void) } mask32 = omap_readl(ARM_SYSST); + /* + * Prevent the ULPD from entering low power state by setting + * POWER_CTRL_REG:4 = 0 + */ + omap_writew(omap_readw(ULPD_POWER_CTRL) & + ~ULPD_DEEP_SLEEP_TRANSITION_EN, ULPD_POWER_CTRL); + /* * Since an interrupt may set up a timer, we don't want to * reprogram the hardware timer with interrupts enabled. @@ -92,18 +106,9 @@ void omap_pm_idle(void) if ((mask32 & DSP_IDLE) == 0) { __asm__ volatile ("mcr p15, 0, r0, c7, c0, 4"); - } else { - - if (cpu_is_omap1510()) { - func_ptr = (void *)(OMAP1510_SRAM_IDLE_SUSPEND); - } else if (cpu_is_omap1610() || cpu_is_omap1710()) { - func_ptr = (void *)(OMAP1610_SRAM_IDLE_SUSPEND); - } else if (cpu_is_omap5912()) { - func_ptr = (void *)(OMAP5912_SRAM_IDLE_SUSPEND); - } + } else + omap_sram_idle(); - func_ptr(); - } local_fiq_enable(); local_irq_enable(); } @@ -115,58 +120,55 @@ void omap_pm_idle(void) */ static void omap_pm_wakeup_setup(void) { - /* - * Enable ARM XOR clock and release peripheral from reset by - * writing 1 to PER_EN bit in ARM_RSTCT2, this is required - * for UART configuration to use UART2 to wake up. - */ - - omap_writel(omap_readl(ARM_IDLECT2) | ENABLE_XORCLK, ARM_IDLECT2); - omap_writel(omap_readl(ARM_RSTCT2) | PER_EN, ARM_RSTCT2); - omap_writew(MODEM_32K_EN, ULPD_CLOCK_CTRL); + u32 level1_wake = OMAP_IRQ_BIT(INT_IH2_IRQ); + u32 level2_wake = OMAP_IRQ_BIT(INT_UART2) | OMAP_IRQ_BIT(INT_KEYBOARD); /* - * Turn off all interrupts except L1-2nd level cascade, - * and the L2 wakeup interrupts: keypad and UART2. + * Turn off all interrupts except GPIO bank 1, L1-2nd level cascade, + * and the L2 wakeup interrupts: keypad and UART2. Note that the + * drivers must still separately call omap_set_gpio_wakeup() to + * wake up to a GPIO interrupt. */ + if (cpu_is_omap1510() || cpu_is_omap16xx()) + level1_wake |= OMAP_IRQ_BIT(INT_GPIO_BANK1); + else if (cpu_is_omap730()) + level1_wake |= OMAP_IRQ_BIT(INT_730_GPIO_BANK1); - omap_writel(~IRQ_LEVEL2, OMAP_IH1_MIR); + omap_writel(~level1_wake, OMAP_IH1_MIR); - if (cpu_is_omap1510()) { - omap_writel(~(IRQ_UART2 | IRQ_KEYBOARD), OMAP_IH2_MIR); - } + if (cpu_is_omap1510()) + omap_writel(~level2_wake, OMAP_IH2_MIR); + /* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */ if (cpu_is_omap16xx()) { - omap_writel(~(IRQ_UART2 | IRQ_KEYBOARD), OMAP_IH2_0_MIR); - - omap_writel(~0x0, OMAP_IH2_1_MIR); + omap_writel(~level2_wake, OMAP_IH2_0_MIR); + omap_writel(~OMAP_IRQ_BIT(INT_1610_WAKE_UP_REQ), OMAP_IH2_1_MIR); omap_writel(~0x0, OMAP_IH2_2_MIR); omap_writel(~0x0, OMAP_IH2_3_MIR); } - /* New IRQ agreement */ + /* New IRQ agreement, recalculate in cascade order */ + omap_writel(1, OMAP_IH2_CONTROL); omap_writel(1, OMAP_IH1_CONTROL); - - /* external PULL to down, bit 22 = 0 */ - omap_writel(omap_readl(PULL_DWN_CTRL_2) & ~(1<<22), PULL_DWN_CTRL_2); } void omap_pm_suspend(void) { - unsigned int mask32 = 0; unsigned long arg0 = 0, arg1 = 0; - int (*func_ptr)(unsigned short, unsigned short) = 0; - unsigned short save_dsp_idlect2; - printk("PM: OMAP%x is entering deep sleep now ...\n", system_rev); + printk("PM: OMAP%x is trying to enter deep sleep...\n", system_rev); + + omap_serial_wake_trigger(1); if (machine_is_omap_osk()) { /* Stop LED1 (D9) blink */ tps65010_set_led(LED1, OFF); } + omap_writew(0xffff, ULPD_SOFT_DISABLE_REQ_REG); + /* - * Step 1: turn off interrupts + * Step 1: turn off interrupts (FIXME: NOTE: already disabled) */ local_irq_disable(); @@ -207,6 +209,8 @@ void omap_pm_suspend(void) ARM_SAVE(ARM_CKCTL); ARM_SAVE(ARM_IDLECT1); ARM_SAVE(ARM_IDLECT2); + if (!(cpu_is_omap1510())) + ARM_SAVE(ARM_IDLECT3); ARM_SAVE(ARM_EWUPCT); ARM_SAVE(ARM_RSTCT1); ARM_SAVE(ARM_RSTCT2); @@ -214,42 +218,12 @@ void omap_pm_suspend(void) ULPD_SAVE(ULPD_CLOCK_CTRL); ULPD_SAVE(ULPD_STATUS_REQ); - /* - * Step 3: LOW_PWR signal enabling - * - * Allow the LOW_PWR signal to be visible on MPUIO5 ball. - */ - if (cpu_is_omap1510()) { - /* POWER_CTRL_REG = 0x1 (LOW_POWER is available) */ - omap_writew(omap_readw(ULPD_POWER_CTRL) | - OMAP1510_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL); - } else if (cpu_is_omap16xx()) { - /* POWER_CTRL_REG = 0x1 (LOW_POWER is available) */ - omap_writew(omap_readw(ULPD_POWER_CTRL) | - OMAP1610_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL); - } - - /* configure LOW_PWR pin */ - omap_cfg_reg(T20_1610_LOW_PWR); + /* (Step 3 removed - we now allow deep sleep by default) */ /* * Step 4: OMAP DSP Shutdown */ - /* Set DSP_RST = 1 and DSP_EN = 0, put DSP block into reset */ - omap_writel((omap_readl(ARM_RSTCT1) | DSP_RST) & ~DSP_ENABLE, - ARM_RSTCT1); - - /* Set DSP boot mode to DSP-IDLE, DSP_BOOT_MODE = 0x2 */ - omap_writel(DSP_IDLE_MODE, MPUI_DSP_BOOT_CONFIG); - - /* Set EN_DSPCK = 0, stop DSP block clock */ - omap_writel(omap_readl(ARM_CKCTL) & ~DSP_CLOCK_ENABLE, ARM_CKCTL); - - /* Stop any DSP domain clocks */ - omap_writel(omap_readl(ARM_IDLECT2) | (1< 0 (WDT clock) */ - mask32 |= (1< 1 (XORPCK clock) */ - mask32 &= ~(1< 0 (MPUPER_CK clock) */ - mask32 &= ~(1< 0 (LCDC clock) */ - mask32 &= ~(1< 0 (local bus clock) */ - mask32 |= (1< 1 (MPUI clock) */ - mask32 &= ~(1< 0 (MPU timer clock) */ - mask32 &= ~(1< 0 (DMAC clock) */ - mask32 &= ~(1< 0 (GPIO clock) */ - omap_writel(mask32, ARM_IDLECT2); - /* disable ARM watchdog */ omap_writel(0x00F5, OMAP_WDT_TIMER_MODE); omap_writel(0x00A0, OMAP_WDT_TIMER_MODE); @@ -295,47 +254,24 @@ void omap_pm_suspend(void) arg0 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT1]; arg1 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT2]; - if (cpu_is_omap1510()) { - func_ptr = (void *)(OMAP1510_SRAM_API_SUSPEND); - } else if (cpu_is_omap1610() || cpu_is_omap1710()) { - func_ptr = (void *)(OMAP1610_SRAM_API_SUSPEND); - } else if (cpu_is_omap5912()) { - func_ptr = (void *)(OMAP5912_SRAM_API_SUSPEND); - } - /* * Step 6c: ARM and Traffic controller shutdown * * Jump to assembly code. The processor will stay there * until wake up. */ - - func_ptr(arg0, arg1); + omap_sram_suspend(arg0, arg1); /* * If we are here, processor is woken up! */ - if (cpu_is_omap1510()) { - /* POWER_CTRL_REG = 0x0 (LOW_POWER is disabled) */ - omap_writew(omap_readw(ULPD_POWER_CTRL) & - ~OMAP1510_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL); - } else if (cpu_is_omap16xx()) { - /* POWER_CTRL_REG = 0x0 (LOW_POWER is disabled) */ - omap_writew(omap_readw(ULPD_POWER_CTRL) & - ~OMAP1610_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL); - } - - - /* Restore DSP clocks */ - omap_writel(omap_readl(ARM_IDLECT2) | (1< +#include +#include +#include +#include + + .text + +/* + * Reprograms ULPD and CKCTL. + */ +ENTRY(sram_reprogram_clock) + stmfd sp!, {r0 - r12, lr} @ save registers on stack + + mov r2, #IO_ADDRESS(DPLL_CTL) & 0xff000000 + orr r2, r2, #IO_ADDRESS(DPLL_CTL) & 0x00ff0000 + orr r2, r2, #IO_ADDRESS(DPLL_CTL) & 0x0000ff00 + + mov r3, #IO_ADDRESS(ARM_CKCTL) & 0xff000000 + orr r3, r3, #IO_ADDRESS(ARM_CKCTL) & 0x00ff0000 + orr r3, r3, #IO_ADDRESS(ARM_CKCTL) & 0x0000ff00 + + tst r0, #1 << 4 @ want lock mode? + beq newck @ nope + bic r0, r0, #1 << 4 @ else clear lock bit + strh r0, [r2] @ set dpll into bypass mode + orr r0, r0, #1 << 4 @ set lock bit again + +newck: + strh r1, [r3] @ write new ckctl value + strh r0, [r2] @ write new dpll value + + mov r4, #0x0700 @ let the clocks settle + orr r4, r4, #0x00ff +delay: sub r4, r4, #1 + cmp r4, #0 + bne delay + +lock: ldrh r4, [r2], #0 @ read back dpll value + tst r0, #1 << 4 @ want lock mode? + beq out @ nope + tst r4, #1 << 0 @ dpll rate locked? + beq lock @ try again + +out: + ldmfd sp!, {r0 - r12, pc} @ restore regs and return +ENTRY(sram_reprogram_clock_sz) + .word . - sram_reprogram_clock diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c new file mode 100644 index 000000000000..7719a4062e3a --- /dev/null +++ b/arch/arm/plat-omap/sram.c @@ -0,0 +1,116 @@ +/* + * linux/arch/arm/plat-omap/sram.c + * + * OMAP SRAM detection and management + * + * Copyright (C) 2005 Nokia Corporation + * Written by Tony Lindgren + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "sram.h" + +#define OMAP1_SRAM_BASE 0xd0000000 +#define OMAP1_SRAM_START 0x20000000 +#define SRAM_BOOTLOADER_SZ 0x80 + +static unsigned long omap_sram_base; +static unsigned long omap_sram_size; +static unsigned long omap_sram_ceil; + +/* + * The amount of SRAM depends on the core type: + * 730 = 200K, 1510 = 512K, 5912 = 256K, 1610 = 16K, 1710 = 16K + * Note that we cannot try to test for SRAM here because writes + * to secure SRAM will hang the system. Also the SRAM is not + * yet mapped at this point. + */ +void __init omap_detect_sram(void) +{ + omap_sram_base = OMAP1_SRAM_BASE; + + if (cpu_is_omap730()) + omap_sram_size = 0x32000; + else if (cpu_is_omap1510()) + omap_sram_size = 0x80000; + else if (cpu_is_omap1610() || cpu_is_omap1621() || cpu_is_omap1710()) + omap_sram_size = 0x4000; + else if (cpu_is_omap1611()) + omap_sram_size = 0x3e800; + else { + printk(KERN_ERR "Could not detect SRAM size\n"); + omap_sram_size = 0x4000; + } + + printk(KERN_INFO "SRAM size: 0x%lx\n", omap_sram_size); + omap_sram_ceil = omap_sram_base + omap_sram_size; +} + +static struct map_desc omap_sram_io_desc[] __initdata = { + { OMAP1_SRAM_BASE, OMAP1_SRAM_START, 0, MT_DEVICE } +}; + +/* + * In order to use last 2kB of SRAM on 1611b, we must round the size + * up to multiple of PAGE_SIZE. We cannot use ioremap for SRAM, as + * clock init needs SRAM early. + */ +void __init omap_map_sram(void) +{ + if (omap_sram_size == 0) + return; + + omap_sram_io_desc[0].length = (omap_sram_size + PAGE_SIZE-1)/PAGE_SIZE; + omap_sram_io_desc[0].length *= PAGE_SIZE; + iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc)); + + /* + * Looks like we need to preserve some bootloader code at the + * beginning of SRAM for jumping to flash for reboot to work... + */ + memset((void *)omap_sram_base + SRAM_BOOTLOADER_SZ, 0, + omap_sram_size - SRAM_BOOTLOADER_SZ); +} + +static void (*_omap_sram_reprogram_clock)(u32 dpllctl, u32 ckctl) = NULL; + +void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl) +{ + if (_omap_sram_reprogram_clock == NULL) + panic("Cannot use SRAM"); + + return _omap_sram_reprogram_clock(dpllctl, ckctl); +} + +void * omap_sram_push(void * start, unsigned long size) +{ + if (size > (omap_sram_ceil - (omap_sram_base + SRAM_BOOTLOADER_SZ))) { + printk(KERN_ERR "Not enough space in SRAM\n"); + return NULL; + } + omap_sram_ceil -= size; + omap_sram_ceil &= ~0x3; + memcpy((void *)omap_sram_ceil, start, size); + + return (void *)omap_sram_ceil; +} + +void __init omap_sram_init(void) +{ + omap_detect_sram(); + omap_map_sram(); + _omap_sram_reprogram_clock = omap_sram_push(sram_reprogram_clock, + sram_reprogram_clock_sz); +} diff --git a/arch/arm/plat-omap/sram.h b/arch/arm/plat-omap/sram.h new file mode 100644 index 000000000000..71984efa6ae8 --- /dev/null +++ b/arch/arm/plat-omap/sram.h @@ -0,0 +1,21 @@ +/* + * linux/arch/arm/plat-omap/sram.h + * + * Interface for functions that need to be run in internal SRAM + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ARCH_ARM_OMAP_SRAM_H +#define __ARCH_ARM_OMAP_SRAM_H + +extern void * omap_sram_push(void * start, unsigned long size); +extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl); + +/* Do not use these */ +extern void sram_reprogram_clock(u32 ckctl, u32 dpllctl); +extern unsigned long sram_reprogram_clock_sz; + +#endif diff --git a/arch/arm/plat-omap/usb.c b/arch/arm/plat-omap/usb.c index 25bc4a8dd763..98f1c76f8660 100644 --- a/arch/arm/plat-omap/usb.c +++ b/arch/arm/plat-omap/usb.c @@ -41,6 +41,7 @@ /* These routines should handle the standard chip-specific modes * for usb0/1/2 ports, covering basic mux and transceiver setup. + * Call omap_usb_init() once, from INIT_MACHINE(). * * Some board-*.c files will need to set up additional mux options, * like for suspend handling, vbus sensing, GPIOs, and the D+ pullup. -- cgit 1.4.1 From 7dfe508a821adf180beafa29761b4a303536d67b Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 7 Sep 2005 17:20:28 +0100 Subject: [ARM] 2880/1: OMAP 4/4: Update H2 defconfig Patch from Tony Lindgren This patch updates H2 defconfig Signed-off-by: Tony Lindgren Signed-off-by: Russell King --- arch/arm/configs/omap_h2_1610_defconfig | 290 ++++++++------------------------ 1 file changed, 72 insertions(+), 218 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/configs/omap_h2_1610_defconfig b/arch/arm/configs/omap_h2_1610_defconfig index 24955263b096..4198677cd394 100644 --- a/arch/arm/configs/omap_h2_1610_defconfig +++ b/arch/arm/configs/omap_h2_1610_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.13-rc2 -# Fri Jul 8 04:49:34 2005 +# Linux kernel version: 2.6.13 +# Mon Sep 5 18:07:12 2005 # CONFIG_ARM=y CONFIG_MMU=y @@ -102,9 +102,11 @@ CONFIG_OMAP_MUX_WARNINGS=y # CONFIG_OMAP_MPU_TIMER is not set CONFIG_OMAP_32K_TIMER=y CONFIG_OMAP_32K_TIMER_HZ=128 +# CONFIG_OMAP_DM_TIMER is not set CONFIG_OMAP_LL_DEBUG_UART1=y # CONFIG_OMAP_LL_DEBUG_UART2 is not set # CONFIG_OMAP_LL_DEBUG_UART3 is not set +CONFIG_OMAP_SERIAL_WAKE=y # # OMAP Core Type @@ -166,7 +168,6 @@ CONFIG_ISA_DMA_API=y # # Kernel Features # -# CONFIG_SMP is not set CONFIG_PREEMPT=y CONFIG_NO_IDLE_HZ=y # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set @@ -230,91 +231,82 @@ CONFIG_PM=y # CONFIG_APM is not set # -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set - -# -# Memory Technology Devices (MTD) +# Networking # -CONFIG_MTD=y -CONFIG_MTD_DEBUG=y -CONFIG_MTD_DEBUG_VERBOSE=3 -# CONFIG_MTD_CONCAT is not set -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -CONFIG_MTD_CMDLINE_PARTS=y -# CONFIG_MTD_AFS_PARTS is not set +CONFIG_NET=y # -# User Modules And Translation Layers +# Networking options # -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set # -# RAM/ROM/Flash chip drivers +# SCTP Configuration (EXPERIMENTAL) # -CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -CONFIG_MTD_CFI_INTELEXT=y -# CONFIG_MTD_CFI_AMDSTD is not set -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_XIP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set # -# Mapping drivers for chip access +# Network testing # -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_ARM_INTEGRATOR is not set -# CONFIG_MTD_EDB7312 is not set +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set # -# Self-contained MTD device drivers +# Device Drivers # -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLKMTD is not set -# CONFIG_MTD_BLOCK2MTD is not set # -# Disk-On-Chip Device Drivers +# Generic Driver Options # -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set # -# NAND Flash Device Drivers +# Memory Technology Devices (MTD) # -# CONFIG_MTD_NAND is not set +# CONFIG_MTD is not set # # Parallel port support @@ -403,72 +395,8 @@ CONFIG_SCSI_PROC_FS=y # # -# Networking support -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_IP_TCPDIAG=y -# CONFIG_IP_TCPDIAG_IPV6 is not set -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_BIC=y -# CONFIG_IPV6 is not set -# CONFIG_NETFILTER is not set - -# -# SCTP Configuration (EXPERIMENTAL) +# Network device support # -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set -# CONFIG_NET_CLS_ROUTE is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set @@ -518,6 +446,8 @@ CONFIG_SLIP_COMPRESSED=y # CONFIG_SLIP_MODE_SLIP6 is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set # # ISDN subsystem @@ -615,77 +545,15 @@ CONFIG_WATCHDOG_NOWAYOUT=y # # I2C support # -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y - -# -# I2C Algorithms -# -# CONFIG_I2C_ALGOBIT is not set -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALGOPCA is not set - -# -# I2C Hardware Bus support -# -# CONFIG_I2C_ISA is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_PCA_ISA is not set +# CONFIG_I2C is not set +# CONFIG_I2C_SENSOR is not set +CONFIG_ISP1301_OMAP=y # -# Hardware Sensors Chip support +# Hardware Monitoring support # -# CONFIG_I2C_SENSOR is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ASB100 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_FSCHER is not set -# CONFIG_SENSORS_FSCPOS is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set - -# -# Other I2C Chip support -# -# CONFIG_SENSORS_DS1337 is not set -# CONFIG_SENSORS_DS1374 is not set -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_RTC8564 is not set -CONFIG_ISP1301_OMAP=y -CONFIG_TPS65010=y -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set # # Misc devices @@ -756,15 +624,9 @@ CONFIG_SOUND=y # Open Sound System # CONFIG_SOUND_PRIME=y -# CONFIG_SOUND_BT878 is not set -# CONFIG_SOUND_FUSION is not set -# CONFIG_SOUND_CS4281 is not set -# CONFIG_SOUND_SONICVIBES is not set -# CONFIG_SOUND_TRIDENT is not set # CONFIG_SOUND_MSNDCLAS is not set # CONFIG_SOUND_MSNDPIN is not set # CONFIG_SOUND_OSS is not set -# CONFIG_SOUND_TVMIXER is not set # CONFIG_SOUND_AD1980 is not set # @@ -810,6 +672,7 @@ CONFIG_EXT2_FS=y # CONFIG_JBD is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set # # XFS support @@ -817,6 +680,7 @@ CONFIG_EXT2_FS=y # CONFIG_XFS_FS is not set # CONFIG_MINIX_FS is not set CONFIG_ROMFS_FS=y +CONFIG_INOTIFY=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set @@ -857,15 +721,6 @@ CONFIG_RAMFS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=2 -# CONFIG_JFFS2_FS_NAND is not set -# CONFIG_JFFS2_FS_NOR_ECC is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -CONFIG_JFFS2_ZLIB=y -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set CONFIG_CRAMFS=y # CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set @@ -1007,4 +862,3 @@ CONFIG_CRYPTO_DES=y CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -- cgit 1.4.1 From fd6480f27e38f86ddea78eb5b46db249dfd09f17 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Wed, 7 Sep 2005 17:24:35 +0100 Subject: [ARM] 2883/1: PXA Sharpsl: Add detection of new PXA based Zaurii machine types Patch from Richard Purdie Add machine detection routines for several new models of PXA based Zaurii (SL-C3000 - Spitz, SL-C1000 - Akita, SL-C3100 - Borzoi, SL-C6000 - Tosa). Sharp continue to use broken bootloaders in ROM. Signed-off-by: Richard Purdie Signed-off-by: Russell King --- arch/arm/boot/compressed/head-sharpsl.S | 111 ++++++++++++++++++++++++-------- 1 file changed, 85 insertions(+), 26 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/boot/compressed/head-sharpsl.S b/arch/arm/boot/compressed/head-sharpsl.S index d6bf8a2b090d..59ad69640d6b 100644 --- a/arch/arm/boot/compressed/head-sharpsl.S +++ b/arch/arm/boot/compressed/head-sharpsl.S @@ -7,7 +7,8 @@ * so we have to figure out the machine for ourselves... * * Support for Poodle, Corgi (SL-C700), Shepherd (SL-C750) - * and Husky (SL-C760). + * Husky (SL-C760), Tosa (SL-C6000), Spitz (SL-C3000), + * Akita (SL-C1000) and Borzoi (SL-C3100). * */ @@ -23,6 +24,22 @@ __SharpSL_start: +/* Check for TC6393 - if found we have a Tosa */ + ldr r7, .TOSAID + mov r1, #0x10000000 @ Base address of TC6393 chip + mov r6, #0x03 + ldrh r3, [r1, #8] @ Load TC6393XB Revison: This is 0x0003 + cmp r6, r3 + beq .SHARPEND @ Success -> tosa + +/* Check for pxa270 - if found, branch */ + mrc p15, 0, r4, c0, c0 @ Get Processor ID + and r4, r4, #0xffffff00 + ldr r3, .PXA270ID + cmp r4, r3 + beq .PXA270 + +/* Check for w100 - if not found we have a Poodle */ ldr r1, .W100ADDR @ Base address of w100 chip + regs offset mov r6, #0x31 @ Load Magic Init value @@ -30,7 +47,7 @@ __SharpSL_start: mov r5, #0x3000 .W100LOOP: subs r5, r5, #1 - bne .W100LOOP + bne .W100LOOP mov r6, #0x30 @ Load 2nd Magic Init value str r6, [r1, #0x280] @ to SCRATCH_UMSK @@ -40,45 +57,52 @@ __SharpSL_start: cmp r6, r3 bne .SHARPEND @ We have no w100 - Poodle - mrc p15, 0, r6, c0, c0 @ Get Processor ID - and r6, r6, #0xffffff00 +/* Check for pxa250 - if found we have a Corgi */ ldr r7, .CORGIID ldr r3, .PXA255ID - cmp r6, r3 + cmp r4, r3 blo .SHARPEND @ We have a PXA250 - Corgi - mov r1, #0x0c000000 @ Base address of NAND chip - ldrb r3, [r1, #24] @ Load FLASHCTL - bic r3, r3, #0x11 @ SET NCE - orr r3, r3, #0x0a @ SET CLR + FLWP - strb r3, [r1, #24] @ Save to FLASHCTL - mov r2, #0x90 @ Command "readid" - strb r2, [r1, #20] @ Save to FLASHIO - bic r3, r3, #2 @ CLR CLE - orr r3, r3, #4 @ SET ALE - strb r3, [r1, #24] @ Save to FLASHCTL - mov r2, #0 @ Address 0x00 - strb r2, [r1, #20] @ Save to FLASHIO - bic r3, r3, #4 @ CLR ALE - strb r3, [r1, #24] @ Save to FLASHCTL -.SHARP1: - ldrb r3, [r1, #24] @ Load FLASHCTL - tst r3, #32 @ Is chip ready? - beq .SHARP1 - ldrb r2, [r1, #20] @ NAND Manufacturer ID - ldrb r3, [r1, #20] @ NAND Chip ID +/* Check for 64MiB flash - if found we have a Shepherd */ + bl get_flash_ids ldr r7, .SHEPHERDID cmp r3, #0x76 @ 64MiB flash beq .SHARPEND @ We have Shepherd + +/* Must be a Husky */ ldr r7, .HUSKYID @ Must be Husky b .SHARPEND +.PXA270: +/* Check for 16MiB flash - if found we have Spitz */ + bl get_flash_ids + ldr r7, .SPITZID + cmp r3, #0x73 @ 16MiB flash + beq .SHARPEND @ We have Spitz + +/* Check for a second SCOOP chip - if found we have Borzoi */ + ldr r1, .SCOOP2ADDR + ldr r7, .BORZOIID + mov r6, #0x0140 + strh r6, [r1] + ldrh r6, [r1] + cmp r6, #0x0140 + beq .SHARPEND @ We have Borzoi + +/* Must be Akita */ + ldr r7, .AKITAID + b .SHARPEND @ We have Borzoi + .PXA255ID: .word 0x69052d00 @ PXA255 Processor ID +.PXA270ID: + .word 0x69054100 @ PXA270 Processor ID .W100ID: .word 0x57411002 @ w100 Chip ID .W100ADDR: .word 0x08010000 @ w100 Chip ID Reg Address +.SCOOP2ADDR: + .word 0x08800040 .POODLEID: .word MACH_TYPE_POODLE .CORGIID: @@ -87,6 +111,41 @@ __SharpSL_start: .word MACH_TYPE_SHEPHERD .HUSKYID: .word MACH_TYPE_HUSKY -.SHARPEND: +.TOSAID: + .word MACH_TYPE_TOSA +.SPITZID: + .word MACH_TYPE_SPITZ +.AKITAID: + .word MACH_TYPE_AKITA +.BORZOIID: + .word MACH_TYPE_BORZOI +/* + * Return: r2 - NAND Manufacturer ID + * r3 - NAND Chip ID + * Corrupts: r1 + */ +get_flash_ids: + mov r1, #0x0c000000 @ Base address of NAND chip + ldrb r3, [r1, #24] @ Load FLASHCTL + bic r3, r3, #0x11 @ SET NCE + orr r3, r3, #0x0a @ SET CLR + FLWP + strb r3, [r1, #24] @ Save to FLASHCTL + mov r2, #0x90 @ Command "readid" + strb r2, [r1, #20] @ Save to FLASHIO + bic r3, r3, #2 @ CLR CLE + orr r3, r3, #4 @ SET ALE + strb r3, [r1, #24] @ Save to FLASHCTL + mov r2, #0 @ Address 0x00 + strb r2, [r1, #20] @ Save to FLASHIO + bic r3, r3, #4 @ CLR ALE + strb r3, [r1, #24] @ Save to FLASHCTL +.fids1: + ldrb r3, [r1, #24] @ Load FLASHCTL + tst r3, #32 @ Is chip ready? + beq .fids1 + ldrb r2, [r1, #20] @ NAND Manufacturer ID + ldrb r3, [r1, #20] @ NAND Chip ID + mov pc, lr +.SHARPEND: -- cgit 1.4.1 From 7691d931aa55409ae3339d541ec0b87ab0a2adae Mon Sep 17 00:00:00 2001 From: Adam Brooks Date: Wed, 7 Sep 2005 17:24:36 +0100 Subject: [ARM] 2871/1: Fixes an issue with gettimeofday not working correctly on Intel IOP3xx processors Patch from Adam Brooks The current gettimeofday implementation for the IOP3xx processors reads the contents of the timer interrupt register and does math on the value to figure out exactly what time it is. To do this it multiplies the contents of the timer register with a large constant. The result is then divided by a large constant. Unfortunately the result of the first multiplication is often too large for the register to hold. The solution is to combine the two large constants to a single smaller constant at compile time. Then the timer value can be divided by single smaller constant without any overflow issues. Signed-off-by: Adam Brooks Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- arch/arm/mach-iop3xx/iop321-time.c | 2 +- arch/arm/mach-iop3xx/iop331-time.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-iop3xx/iop321-time.c b/arch/arm/mach-iop3xx/iop321-time.c index d53af1669502..0039793b694a 100644 --- a/arch/arm/mach-iop3xx/iop321-time.c +++ b/arch/arm/mach-iop3xx/iop321-time.c @@ -60,7 +60,7 @@ static unsigned long iop321_gettimeoffset(void) /* * Now convert them to usec. */ - usec = (unsigned long)(elapsed * (tick_nsec / 1000)) / LATCH; + usec = (unsigned long)(elapsed / (CLOCK_TICK_RATE/1000000)); return usec; } diff --git a/arch/arm/mach-iop3xx/iop331-time.c b/arch/arm/mach-iop3xx/iop331-time.c index 1a6d9d661e4b..8eddfac7e2b0 100644 --- a/arch/arm/mach-iop3xx/iop331-time.c +++ b/arch/arm/mach-iop3xx/iop331-time.c @@ -58,7 +58,7 @@ static unsigned long iop331_gettimeoffset(void) /* * Now convert them to usec. */ - usec = (unsigned long)(elapsed * (tick_nsec / 1000)) / LATCH; + usec = (unsigned long)(elapsed / (CLOCK_TICK_RATE/1000000)); return usec; } -- cgit 1.4.1 From bafa49cc1b800df4748b29e2b038ff029d7c8747 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 7 Sep 2005 17:24:48 +0100 Subject: [ARM] 2884/1: BAST - fix PC104 IRQ routing Patch from Ben Dooks This has been broken for a while now, so fix the problems with the code, test and bring up to date. This also makes the code conditional on an Kconfig option Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/mach-s3c2410/Kconfig | 8 +++++ arch/arm/mach-s3c2410/Makefile | 4 +++ arch/arm/mach-s3c2410/bast-irq.c | 77 ++++++++++++++++++++++++++++++---------- 3 files changed, 71 insertions(+), 18 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig index da818344f954..06807c6ee68a 100644 --- a/arch/arm/mach-s3c2410/Kconfig +++ b/arch/arm/mach-s3c2410/Kconfig @@ -18,6 +18,14 @@ config ARCH_BAST Product page: . +config BAST_PC104_IRQ + bool "BAST PC104 IRQ support" + depends on ARCH_BAST + default y + help + Say Y here to enable the PC104 IRQ routing on the + Simtec BAST (EB2410ITX) + config ARCH_H1940 bool "IPAQ H1940" select CPU_S3C2410 diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile index 023c4f59a345..b4f1e051c768 100644 --- a/arch/arm/mach-s3c2410/Makefile +++ b/arch/arm/mach-s3c2410/Makefile @@ -26,6 +26,10 @@ obj-$(CONFIG_CPU_S3C2440) += s3c2440.o s3c2440-dsc.o obj-$(CONFIG_CPU_S3C2440) += s3c2440-irq.o obj-$(CONFIG_CPU_S3C2440) += s3c2440-clock.o +# bast extras + +obj-$(CONFIG_BAST_PC104_IRQ) += bast-irq.o + # machine specific support obj-$(CONFIG_MACH_ANUBIS) += mach-anubis.o diff --git a/arch/arm/mach-s3c2410/bast-irq.c b/arch/arm/mach-s3c2410/bast-irq.c index 49914709fa09..fbbeb0553006 100644 --- a/arch/arm/mach-s3c2410/bast-irq.c +++ b/arch/arm/mach-s3c2410/bast-irq.c @@ -1,6 +1,6 @@ /* linux/arch/arm/mach-s3c2410/bast-irq.c * - * Copyright (c) 2004 Simtec Electronics + * Copyright (c) 2003,2005 Simtec Electronics * Ben Dooks * * http://www.simtec.co.uk/products/EB2410ITX/ @@ -21,7 +21,8 @@ * * Modifications: * 08-Jan-2003 BJD Moved from central IRQ code - */ + * 21-Aug-2005 BJD Fixed missing code and compile errors +*/ #include @@ -30,12 +31,19 @@ #include #include +#include + #include #include #include #include -#include + +#include +#include +#include + +#include "irq.h" #if 0 #include @@ -79,15 +87,15 @@ bast_pc104_mask(unsigned int irqno) temp = __raw_readb(BAST_VA_PC104_IRQMASK); temp &= ~bast_pc104_irqmasks[irqno]; __raw_writeb(temp, BAST_VA_PC104_IRQMASK); - - if (temp == 0) - bast_extint_mask(IRQ_ISA); } static void -bast_pc104_ack(unsigned int irqno) +bast_pc104_maskack(unsigned int irqno) { - bast_extint_ack(IRQ_ISA); + struct irqdesc *desc = irq_desc + IRQ_ISA; + + bast_pc104_mask(irqno); + desc->chip->ack(IRQ_ISA); } static void @@ -98,14 +106,12 @@ bast_pc104_unmask(unsigned int irqno) temp = __raw_readb(BAST_VA_PC104_IRQMASK); temp |= bast_pc104_irqmasks[irqno]; __raw_writeb(temp, BAST_VA_PC104_IRQMASK); - - bast_extint_unmask(IRQ_ISA); } -static struct bast_pc104_chip = { +static struct irqchip bast_pc104_chip = { .mask = bast_pc104_mask, .unmask = bast_pc104_unmask, - .ack = bast_pc104_ack + .ack = bast_pc104_maskack }; static void @@ -119,14 +125,49 @@ bast_irq_pc104_demux(unsigned int irq, stat = __raw_readb(BAST_VA_PC104_IRQREQ) & 0xf; - for (i = 0; i < 4 && stat != 0; i++) { - if (stat & 1) { - irqno = bast_pc104_irqs[i]; - desc = irq_desc + irqno; + if (unlikely(stat == 0)) { + /* ack if we get an irq with nothing (ie, startup) */ + + desc = irq_desc + IRQ_ISA; + desc->chip->ack(IRQ_ISA); + } else { + /* handle the IRQ */ + + for (i = 0; stat != 0; i++, stat >>= 1) { + if (stat & 1) { + irqno = bast_pc104_irqs[i]; - desc_handle_irq(irqno, desc, regs); + desc_handle_irq(irqno, irq_desc + irqno, regs); + } } + } +} - stat >>= 1; +static __init int bast_irq_init(void) +{ + unsigned int i; + + if (machine_is_bast()) { + printk(KERN_INFO "BAST PC104 IRQ routing, (c) 2005 Simtec Electronics\n"); + + /* zap all the IRQs */ + + __raw_writeb(0x0, BAST_VA_PC104_IRQMASK); + + set_irq_chained_handler(IRQ_ISA, bast_irq_pc104_demux); + + /* reigster our IRQs */ + + for (i = 0; i < 4; i++) { + unsigned int irqno = bast_pc104_irqs[i]; + + set_irq_chip(irqno, &bast_pc104_chip); + set_irq_handler(irqno, do_level_IRQ); + set_irq_flags(irqno, IRQF_VALID); + } } + + return 0; } + +arch_initcall(bast_irq_init); -- cgit 1.4.1 From b149ee2233edf08fb59b11e879a2c5941929bcb8 Mon Sep 17 00:00:00 2001 From: john stultz Date: Tue, 6 Sep 2005 15:17:46 -0700 Subject: [PATCH] NTP: ntp-helper functions This patch cleans up a commonly repeated set of changes to the NTP state variables by adding two helper inline functions: ntp_clear(): Clears the ntp state variables ntp_synced(): Returns 1 if the system is synced with a time server. This was compile tested for alpha, arm, i386, x86-64, ppc64, s390, sparc, sparc64. Signed-off-by: John Stultz Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/alpha/kernel/time.c | 7 ++----- arch/arm/kernel/time.c | 7 ++----- arch/arm26/kernel/time.c | 7 ++----- arch/cris/arch-v10/kernel/time.c | 2 +- arch/cris/kernel/time.c | 5 +---- arch/frv/kernel/time.c | 7 ++----- arch/h8300/kernel/time.c | 5 +---- arch/i386/kernel/time.c | 7 ++----- arch/m32r/kernel/time.c | 7 ++----- arch/m68k/kernel/time.c | 5 +---- arch/m68knommu/kernel/time.c | 7 ++----- arch/mips/kernel/sysirix.c | 5 +---- arch/mips/kernel/time.c | 7 ++----- arch/mips/sgi-ip27/ip27-timer.c | 2 +- arch/parisc/kernel/time.c | 5 +---- arch/ppc/kernel/time.c | 7 ++----- arch/ppc64/kernel/time.c | 7 ++----- arch/s390/kernel/time.c | 5 +---- arch/sh/kernel/time.c | 7 ++----- arch/sh64/kernel/time.c | 7 ++----- arch/sparc/kernel/pcic.c | 5 +---- arch/sparc/kernel/time.c | 7 ++----- arch/sparc64/kernel/time.c | 2 +- arch/v850/kernel/time.c | 7 ++----- arch/x86_64/kernel/time.c | 7 ++----- arch/xtensa/kernel/time.c | 7 ++----- include/linux/timex.h | 23 +++++++++++++++++++++++ 27 files changed, 65 insertions(+), 111 deletions(-) (limited to 'arch/arm') diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c index 8226c5cd788c..67be50b7d80a 100644 --- a/arch/alpha/kernel/time.c +++ b/arch/alpha/kernel/time.c @@ -149,7 +149,7 @@ irqreturn_t timer_interrupt(int irq, void *dev, struct pt_regs * regs) * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be * called as close as possible to 500 ms before the new second starts. */ - if ((time_status & STA_UNSYNC) == 0 + if (ntp_synced() && xtime.tv_sec > state.last_rtc_update + 660 && xtime.tv_nsec >= 500000 - ((unsigned) TICK_SIZE) / 2 && xtime.tv_nsec <= 500000 + ((unsigned) TICK_SIZE) / 2) { @@ -502,10 +502,7 @@ do_settimeofday(struct timespec *tv) set_normalized_timespec(&xtime, sec, nsec); set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; + ntp_clear(); write_sequnlock_irq(&xtime_lock); clock_was_set(); diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index 8880482dcbff..69449a818dcc 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c @@ -102,7 +102,7 @@ static unsigned long next_rtc_update; */ static inline void do_set_rtc(void) { - if (time_status & STA_UNSYNC || set_rtc == NULL) + if (!ntp_synced() || set_rtc == NULL) return; if (next_rtc_update && @@ -292,10 +292,7 @@ int do_settimeofday(struct timespec *tv) set_normalized_timespec(&xtime, sec, nsec); set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; + ntp_clear(); write_sequnlock_irq(&xtime_lock); clock_was_set(); return 0; diff --git a/arch/arm26/kernel/time.c b/arch/arm26/kernel/time.c index 549a6b2e177e..e66aedd02fad 100644 --- a/arch/arm26/kernel/time.c +++ b/arch/arm26/kernel/time.c @@ -114,7 +114,7 @@ static unsigned long next_rtc_update; */ static inline void do_set_rtc(void) { - if (time_status & STA_UNSYNC || set_rtc == NULL) + if (!ntp_synced() || set_rtc == NULL) return; //FIXME - timespec.tv_sec is a time_t not unsigned long @@ -189,10 +189,7 @@ int do_settimeofday(struct timespec *tv) xtime.tv_sec = tv->tv_sec; xtime.tv_nsec = tv->tv_nsec; - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; + ntp_clear(); write_sequnlock_irq(&xtime_lock); clock_was_set(); return 0; diff --git a/arch/cris/arch-v10/kernel/time.c b/arch/cris/arch-v10/kernel/time.c index 6b7b4e0802e3..dc3dfe9b4a1a 100644 --- a/arch/cris/arch-v10/kernel/time.c +++ b/arch/cris/arch-v10/kernel/time.c @@ -240,7 +240,7 @@ timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) * The division here is not time critical since it will run once in * 11 minutes */ - if ((time_status & STA_UNSYNC) == 0 && + if (ntp_synced() && xtime.tv_sec > last_rtc_update + 660 && (xtime.tv_nsec / 1000) >= 500000 - (tick_nsec / 1000) / 2 && (xtime.tv_nsec / 1000) <= 500000 + (tick_nsec / 1000) / 2) { diff --git a/arch/cris/kernel/time.c b/arch/cris/kernel/time.c index fa2d4323da25..a2d99b4aedcd 100644 --- a/arch/cris/kernel/time.c +++ b/arch/cris/kernel/time.c @@ -114,10 +114,7 @@ int do_settimeofday(struct timespec *tv) set_normalized_timespec(&xtime, sec, nsec); set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; + ntp_clear(); write_sequnlock_irq(&xtime_lock); clock_was_set(); return 0; diff --git a/arch/frv/kernel/time.c b/arch/frv/kernel/time.c index 075db6644694..8d6558b00e44 100644 --- a/arch/frv/kernel/time.c +++ b/arch/frv/kernel/time.c @@ -85,7 +85,7 @@ static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs * regs) * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be * called as close as possible to 500 ms before the new second starts. */ - if ((time_status & STA_UNSYNC) == 0 && + if (ntp_synced() && xtime.tv_sec > last_rtc_update + 660 && (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 && (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2 @@ -216,10 +216,7 @@ int do_settimeofday(struct timespec *tv) set_normalized_timespec(&xtime, sec, nsec); set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; + ntp_clear(); write_sequnlock_irq(&xtime_lock); clock_was_set(); return 0; diff --git a/arch/h8300/kernel/time.c b/arch/h8300/kernel/time.c index 8a600218334d..af8c5d2057dd 100644 --- a/arch/h8300/kernel/time.c +++ b/arch/h8300/kernel/time.c @@ -116,10 +116,7 @@ int do_settimeofday(struct timespec *tv) xtime.tv_sec = tv->tv_sec; xtime.tv_nsec = tv->tv_nsec; - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; + ntp_clear(); write_sequnlock_irq(&xtime_lock); clock_was_set(); return 0; diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c index 9b94d84a6c3b..eefea7c55008 100644 --- a/arch/i386/kernel/time.c +++ b/arch/i386/kernel/time.c @@ -194,10 +194,7 @@ int do_settimeofday(struct timespec *tv) set_normalized_timespec(&xtime, sec, nsec); set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; + ntp_clear(); write_sequnlock_irq(&xtime_lock); clock_was_set(); return 0; @@ -347,7 +344,7 @@ static void sync_cmos_clock(unsigned long dummy) * This code is run on a timer. If the clock is set, that timer * may not expire at the correct time. Thus, we adjust... */ - if ((time_status & STA_UNSYNC) != 0) + if (!ntp_synced()) /* * Not synced, exit, do not restart a timer (if one is * running, let it run out). diff --git a/arch/m32r/kernel/time.c b/arch/m32r/kernel/time.c index 8a2b77bc5749..539c562cd54d 100644 --- a/arch/m32r/kernel/time.c +++ b/arch/m32r/kernel/time.c @@ -171,10 +171,7 @@ int do_settimeofday(struct timespec *tv) set_normalized_timespec(&xtime, sec, nsec); set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; + ntp_clear(); write_sequnlock_irq(&xtime_lock); clock_was_set(); @@ -221,7 +218,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) * called as close as possible to 500 ms before the new second starts. */ write_seqlock(&xtime_lock); - if ((time_status & STA_UNSYNC) == 0 + if (ntp_synced() && xtime.tv_sec > last_rtc_update + 660 && (xtime.tv_nsec / 1000) >= 500000 - ((unsigned)TICK_SIZE) / 2 && (xtime.tv_nsec / 1000) <= 500000 + ((unsigned)TICK_SIZE) / 2) diff --git a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c index e47e19588525..4ec95e3cb874 100644 --- a/arch/m68k/kernel/time.c +++ b/arch/m68k/kernel/time.c @@ -166,10 +166,7 @@ int do_settimeofday(struct timespec *tv) set_normalized_timespec(&xtime, sec, nsec); set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; + ntp_clear(); write_sequnlock_irq(&xtime_lock); clock_was_set(); return 0; diff --git a/arch/m68knommu/kernel/time.c b/arch/m68knommu/kernel/time.c index 5c3ca671627c..b17c1ecba966 100644 --- a/arch/m68knommu/kernel/time.c +++ b/arch/m68knommu/kernel/time.c @@ -68,7 +68,7 @@ static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs * regs) * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be * called as close as possible to 500 ms before the new second starts. */ - if ((time_status & STA_UNSYNC) == 0 && + if (ntp_synced() && xtime.tv_sec > last_rtc_update + 660 && (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 && (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) { @@ -178,10 +178,7 @@ int do_settimeofday(struct timespec *tv) set_normalized_timespec(&xtime, sec, nsec); set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; + ntp_clear(); write_sequnlock_irq(&xtime_lock); clock_was_set(); return 0; diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c index f3bf0e43b8bb..b46595462717 100644 --- a/arch/mips/kernel/sysirix.c +++ b/arch/mips/kernel/sysirix.c @@ -632,10 +632,7 @@ asmlinkage int irix_stime(int value) write_seqlock_irq(&xtime_lock); xtime.tv_sec = value; xtime.tv_nsec = 0; - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; + ntp_clear(); write_sequnlock_irq(&xtime_lock); return 0; diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index 648c82292ed6..0dd0df7a3b04 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -223,10 +223,7 @@ int do_settimeofday(struct timespec *tv) set_normalized_timespec(&xtime, sec, nsec); set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; + ntp_clear(); write_sequnlock_irq(&xtime_lock); clock_was_set(); @@ -442,7 +439,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) * called as close as possible to 500 ms before the new second starts. */ write_seqlock(&xtime_lock); - if ((time_status & STA_UNSYNC) == 0 && + if (ntp_synced() && xtime.tv_sec > last_rtc_update + 660 && (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 && (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) { diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c index 8c1b96fffa76..cddf1cedf007 100644 --- a/arch/mips/sgi-ip27/ip27-timer.c +++ b/arch/mips/sgi-ip27/ip27-timer.c @@ -118,7 +118,7 @@ again: * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be * called as close as possible to when a second starts. */ - if ((time_status & STA_UNSYNC) == 0 && + if (ntp_synced() && xtime.tv_sec > last_rtc_update + 660 && (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 && (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) { diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index 6cf7407344ba..7ff67f8e9f8c 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c @@ -188,10 +188,7 @@ do_settimeofday (struct timespec *tv) set_normalized_timespec(&xtime, sec, nsec); set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; + ntp_clear(); } write_sequnlock_irq(&xtime_lock); clock_was_set(); diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c index bf4ddca5e853..a3c5281a5d2d 100644 --- a/arch/ppc/kernel/time.c +++ b/arch/ppc/kernel/time.c @@ -169,7 +169,7 @@ void timer_interrupt(struct pt_regs * regs) * We should have an rtc call that only sets the minutes and * seconds like on Intel to avoid problems with non UTC clocks. */ - if ( ppc_md.set_rtc_time && (time_status & STA_UNSYNC) == 0 && + if ( ppc_md.set_rtc_time && ntp_synced() && xtime.tv_sec - last_rtc_update >= 659 && abs((xtime.tv_nsec / 1000) - (1000000-1000000/HZ)) < 500000/HZ && jiffies - wall_jiffies == 1) { @@ -271,10 +271,7 @@ int do_settimeofday(struct timespec *tv) */ last_rtc_update = new_sec - 658; - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; + ntp_clear(); write_sequnlock_irqrestore(&xtime_lock, flags); clock_was_set(); return 0; diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c index 91ef95ccda4f..9939c206afa4 100644 --- a/arch/ppc64/kernel/time.c +++ b/arch/ppc64/kernel/time.c @@ -128,7 +128,7 @@ static __inline__ void timer_check_rtc(void) * We should have an rtc call that only sets the minutes and * seconds like on Intel to avoid problems with non UTC clocks. */ - if ( (time_status & STA_UNSYNC) == 0 && + if (ntp_synced() && xtime.tv_sec - last_rtc_update >= 659 && abs((xtime.tv_nsec/1000) - (1000000-1000000/HZ)) < 500000/HZ && jiffies - wall_jiffies == 1) { @@ -435,10 +435,7 @@ int do_settimeofday(struct timespec *tv) */ last_rtc_update = new_sec - 658; - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; + ntp_clear(); delta_xsec = mulhdu( (tb_last_stamp-do_gtod.varp->tb_orig_stamp), do_gtod.varp->tb_to_xs ); diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 8ca485676780..2fd75da15495 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -139,10 +139,7 @@ int do_settimeofday(struct timespec *tv) set_normalized_timespec(&xtime, sec, nsec); set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; + ntp_clear(); write_sequnlock_irq(&xtime_lock); clock_was_set(); return 0; diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c index d5f5aedde0a3..02ca69918d7c 100644 --- a/arch/sh/kernel/time.c +++ b/arch/sh/kernel/time.c @@ -215,10 +215,7 @@ int do_settimeofday(struct timespec *tv) set_normalized_timespec(&xtime, sec, nsec); set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; + ntp_clear(); write_sequnlock_irq(&xtime_lock); clock_was_set(); @@ -252,7 +249,7 @@ static inline void do_timer_interrupt(int irq, struct pt_regs *regs) * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be * called as close as possible to 500 ms before the new second starts. */ - if ((time_status & STA_UNSYNC) == 0 && + if (ntp_synced() && xtime.tv_sec > last_rtc_update + 660 && (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 && (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) { diff --git a/arch/sh64/kernel/time.c b/arch/sh64/kernel/time.c index 926c6fc0619c..f4a62a10053c 100644 --- a/arch/sh64/kernel/time.c +++ b/arch/sh64/kernel/time.c @@ -247,10 +247,7 @@ int do_settimeofday(struct timespec *tv) set_normalized_timespec(&xtime, sec, nsec); set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; + ntp_clear(); write_sequnlock_irq(&xtime_lock); clock_was_set(); @@ -328,7 +325,7 @@ static inline void do_timer_interrupt(int irq, struct pt_regs *regs) * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be * called as close as possible to 500 ms before the new second starts. */ - if ((time_status & STA_UNSYNC) == 0 && + if (ntp_synced() && xtime.tv_sec > last_rtc_update + 660 && (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 && (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) { diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index 597d3ff6ad68..36a40697b8d6 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c @@ -840,10 +840,7 @@ static int pci_do_settimeofday(struct timespec *tv) xtime.tv_sec = tv->tv_sec; xtime.tv_nsec = tv->tv_nsec; - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; + ntp_clear(); return 0; } diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c index 3b759aefc170..bc015e980341 100644 --- a/arch/sparc/kernel/time.c +++ b/arch/sparc/kernel/time.c @@ -139,7 +139,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) /* Determine when to update the Mostek clock. */ - if ((time_status & STA_UNSYNC) == 0 && + if (ntp_synced() && xtime.tv_sec > last_rtc_update + 660 && (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 && (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) { @@ -554,10 +554,7 @@ static int sbus_do_settimeofday(struct timespec *tv) set_normalized_timespec(&xtime, sec, nsec); set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; + ntp_clear(); return 0; } diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index 362b9c26871b..3f08a32f51a1 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c @@ -449,7 +449,7 @@ static inline void timer_check_rtc(void) static long last_rtc_update; /* Determine when to update the Mostek clock. */ - if ((time_status & STA_UNSYNC) == 0 && + if (ntp_synced() && xtime.tv_sec > last_rtc_update + 660 && (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 && (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) { diff --git a/arch/v850/kernel/time.c b/arch/v850/kernel/time.c index f722a268238a..ea3fd8844ff0 100644 --- a/arch/v850/kernel/time.c +++ b/arch/v850/kernel/time.c @@ -66,7 +66,7 @@ static irqreturn_t timer_interrupt (int irq, void *dummy, struct pt_regs *regs) * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be * called as close as possible to 500 ms before the new second starts. */ - if ((time_status & STA_UNSYNC) == 0 && + if (ntp_synced() && xtime.tv_sec > last_rtc_update + 660 && (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 && (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) { @@ -169,10 +169,7 @@ int do_settimeofday(struct timespec *tv) xtime.tv_sec = tv->tv_sec; xtime.tv_nsec = tv->tv_nsec; - time_adjust = 0; /* stop active adjtime () */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; + ntp_clear(); write_sequnlock_irq (&xtime_lock); clock_was_set(); diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c index 2b5d9da912a2..7b6abe058253 100644 --- a/arch/x86_64/kernel/time.c +++ b/arch/x86_64/kernel/time.c @@ -176,10 +176,7 @@ int do_settimeofday(struct timespec *tv) set_normalized_timespec(&xtime, sec, nsec); set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; + ntp_clear(); write_sequnlock_irq(&xtime_lock); clock_was_set(); @@ -471,7 +468,7 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) * off) isn't likely to go away much sooner anyway. */ - if ((~time_status & STA_UNSYNC) && xtime.tv_sec > rtc_update && + if (ntp_synced() && xtime.tv_sec > rtc_update && abs(xtime.tv_nsec - 500000000) <= tick_nsec / 2) { set_rtc_mmss(xtime.tv_sec); rtc_update = xtime.tv_sec + 660; diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c index e07287db5a40..1ac7d5ce7456 100644 --- a/arch/xtensa/kernel/time.c +++ b/arch/xtensa/kernel/time.c @@ -122,10 +122,7 @@ int do_settimeofday(struct timespec *tv) set_normalized_timespec(&xtime, sec, nsec); set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; + ntp_clear(); write_sequnlock_irq(&xtime_lock); return 0; } @@ -184,7 +181,7 @@ again: next += CCOUNT_PER_JIFFY; do_timer (regs); /* Linux handler in kernel/timer.c */ - if ((time_status & STA_UNSYNC) == 0 && + if (ntp_synced() && xtime.tv_sec - last_rtc_update >= 659 && abs((xtime.tv_nsec/1000)-(1000000-1000000/HZ))<5000000/HZ && jiffies - wall_jiffies == 1) { diff --git a/include/linux/timex.h b/include/linux/timex.h index 74fdd07d3792..7e050a2cc35b 100644 --- a/include/linux/timex.h +++ b/include/linux/timex.h @@ -260,6 +260,29 @@ extern long pps_calcnt; /* calibration intervals */ extern long pps_errcnt; /* calibration errors */ extern long pps_stbcnt; /* stability limit exceeded */ +/** + * ntp_clear - Clears the NTP state variables + * + * Must be called while holding a write on the xtime_lock + */ +static inline void ntp_clear(void) +{ + time_adjust = 0; /* stop active adjtime() */ + time_status |= STA_UNSYNC; + time_maxerror = NTP_PHASE_LIMIT; + time_esterror = NTP_PHASE_LIMIT; +} + +/** + * ntp_synced - Returns 1 if the NTP status is not UNSYNC + * + */ +static inline int ntp_synced(void) +{ + return !(time_status & STA_UNSYNC); +} + + #ifdef CONFIG_TIME_INTERPOLATION #define TIME_SOURCE_CPU 0 -- cgit 1.4.1 From 41b1bce80b43f7c6a6c64006b2abe3a8d52ab120 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Tue, 6 Sep 2005 15:19:05 -0700 Subject: [PATCH] w100fb: Update corgi platform code to match new driver This patch moves the platform specific Sharp SL-C7x0 LCD code from the w100fb driver into a more appropriate place and updates the Corgi code to match the new w100fb driver. It also updates the corgi touchscreen code to match the new simplified interface available from w100fb. Signed-off-by: Richard Purdie Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm/mach-pxa/Makefile | 2 +- arch/arm/mach-pxa/corgi.c | 35 +--- arch/arm/mach-pxa/corgi_lcd.c | 396 +++++++++++++++++++++++++++++++++++ drivers/input/touchscreen/corgi_ts.c | 28 +-- include/asm-arm/arch-pxa/corgi.h | 8 +- 5 files changed, 408 insertions(+), 61 deletions(-) create mode 100644 arch/arm/mach-pxa/corgi_lcd.c (limited to 'arch/arm') diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index efc2f657184e..33dae99ec2d8 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -11,7 +11,7 @@ obj-$(CONFIG_PXA27x) += pxa27x.o obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o obj-$(CONFIG_ARCH_PXA_IDP) += idp.o -obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o ssp.o +obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o ssp.o obj-$(CONFIG_MACH_POODLE) += poodle.o # Support for blinky lights diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index 06ea730e8675..453be2948533 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -39,7 +39,6 @@ #include #include -#include