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/common/locomo.c') diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c index 41f12658c8b..30ab1c3e1d4 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 v1.2.3-70-g09d2 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/common/locomo.c') diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c index 30ab1c3e1d4..51f430cc2fb 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 6540db69133..dceb826bd21 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 58b3bd00083..3284118f356 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 b21016070ea..e1c43b331d6 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 96aa3af70d8..5110e2e65dd 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 593b6a2a30e..4b3199319e6 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 45d22dd5583..eeb8a6d4a39 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 569f328c479..2be5c03ab87 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 594b4c4d5b1..781d10ae00b 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 a43369ad876..63ba0191aa6 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 43447dad165..7a510992128 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 beda7c2602f..578a52461fd 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 7c08f6c2e1d..c12a7833562 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 6cf35f67446..539b596005f 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 6309853b59b..923f6eb774c 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 827b7b5a5be..85fdb5b1470 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 5e5bbe893cb..49914709fa0 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 67138797866..66d8c068e94 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 7cb9912242a..278d0044c85 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 cc349bc1b7c..c131a5201b5 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 1405383463e..fc061641b7b 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 f01c0f8a2bb..3c8862fde51 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 1c85b4e536c..aa481ea3d70 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 bc9763db1d3..0ce6ca588d8 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 v1.2.3-70-g09d2 From b38d950d3aedf90c8b15b3c7c799b5eb53c47c45 Mon Sep 17 00:00:00 2001 From: John Lenz Date: Thu, 8 Sep 2005 14:41:54 +0100 Subject: [ARM] Add suspend/resume support to locomo.c This adds low-level suspend/resume support to locomo.c. Signed-off-by: Pavel Machek Signed-off-by: Russell King --- arch/arm/common/locomo.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) (limited to 'arch/arm/common/locomo.c') diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c index 51f430cc2fb..2786f7c34b3 100644 --- a/arch/arm/common/locomo.c +++ b/arch/arm/common/locomo.c @@ -541,6 +541,103 @@ locomo_init_one_child(struct locomo *lchip, struct locomo_dev_info *info) return ret; } +#ifdef CONFIG_PM + +struct locomo_save_data { + u16 LCM_GPO; + u16 LCM_SPICT; + u16 LCM_GPE; + u16 LCM_ASD; + u16 LCM_SPIMD; +}; + +static int locomo_suspend(struct device *dev, u32 pm_message_t, u32 level) +{ + struct locomo *lchip = dev_get_drvdata(dev); + struct locomo_save_data *save; + unsigned long flags; + + if (level != SUSPEND_DISABLE) + return 0; + + save = kmalloc(sizeof(struct locomo_save_data), GFP_KERNEL); + if (!save) + return -ENOMEM; + + dev->power.saved_state = (void *) save; + + spin_lock_irqsave(&lchip->lock, flags); + + save->LCM_GPO = locomo_readl(lchip->base + LOCOMO_GPO); /* GPIO */ + locomo_writel(0x00, lchip->base + LOCOMO_GPO); + save->LCM_SPICT = locomo_readl(lchip->base + LOCOMO_SPICT); /* SPI */ + locomo_writel(0x40, lchip->base + LOCOMO_SPICT); + save->LCM_GPE = locomo_readl(lchip->base + LOCOMO_GPE); /* GPIO */ + locomo_writel(0x00, lchip->base + LOCOMO_GPE); + save->LCM_ASD = locomo_readl(lchip->base + LOCOMO_ASD); /* ADSTART */ + locomo_writel(0x00, lchip->base + LOCOMO_ASD); + save->LCM_SPIMD = locomo_readl(lchip->base + LOCOMO_SPIMD); /* SPI */ + locomo_writel(0x3C14, lchip->base + LOCOMO_SPIMD); + + locomo_writel(0x00, lchip->base + LOCOMO_PAIF); + locomo_writel(0x00, lchip->base + LOCOMO_DAC); + locomo_writel(0x00, lchip->base + LOCOMO_BACKLIGHT + LOCOMO_TC); + + if ( (locomo_readl(lchip->base + LOCOMO_LED + LOCOMO_LPT0) & 0x88) && (locomo_readl(lchip->base + LOCOMO_LED + LOCOMO_LPT1) & 0x88) ) + locomo_writel(0x00, lchip->base + LOCOMO_C32K); /* CLK32 off */ + else + /* 18MHz already enabled, so no wait */ + locomo_writel(0xc1, lchip->base + LOCOMO_C32K); /* CLK32 on */ + + locomo_writel(0x00, lchip->base + LOCOMO_TADC); /* 18MHz clock off*/ + locomo_writel(0x00, lchip->base + LOCOMO_AUDIO + LOCOMO_ACC); /* 22MHz/24MHz clock off */ + locomo_writel(0x00, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS); /* FL */ + + spin_unlock_irqrestore(&lchip->lock, flags); + + return 0; +} + +static int locomo_resume(struct device *dev, u32 level) +{ + struct locomo *lchip = dev_get_drvdata(dev); + struct locomo_save_data *save; + unsigned long r; + unsigned long flags; + + if (level != RESUME_ENABLE) + return 0; + + save = (struct locomo_save_data *) dev->power.saved_state; + if (!save) + return 0; + + spin_lock_irqsave(&lchip->lock, flags); + + locomo_writel(save->LCM_GPO, lchip->base + LOCOMO_GPO); + locomo_writel(save->LCM_SPICT, lchip->base + LOCOMO_SPICT); + locomo_writel(save->LCM_GPE, lchip->base + LOCOMO_GPE); + locomo_writel(save->LCM_ASD, lchip->base + LOCOMO_ASD); + locomo_writel(save->LCM_SPIMD, lchip->base + LOCOMO_SPIMD); + + locomo_writel(0x00, lchip->base + LOCOMO_C32K); + locomo_writel(0x90, lchip->base + LOCOMO_TADC); + + locomo_writel(0, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KSC); + r = locomo_readl(lchip->base + LOCOMO_KEYBOARD + LOCOMO_KIC); + r &= 0xFEFF; + locomo_writel(r, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KIC); + locomo_writel(0x1, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KCMD); + + spin_unlock_irqrestore(&lchip->lock, flags); + + dev->power.saved_state = NULL; + kfree(save); + + return 0; +} +#endif + /** * locomo_probe - probe for a single LoCoMo chip. * @phys_addr: physical address of device. @@ -707,6 +804,10 @@ static struct device_driver locomo_device_driver = { .bus = &platform_bus_type, .probe = locomo_probe, .remove = locomo_remove, +#ifdef CONFIG_PM + .suspend = locomo_suspend, + .resume = locomo_resume, +#endif }; /* -- cgit v1.2.3-70-g09d2