From 0e39864afb0deeb2b1ef8aebe942d456a853b129 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 8 Jan 2012 12:04:05 +0000 Subject: [PATCH] --- yaml --- r: 296314 b: refs/heads/master c: 15877e9c8a12ced38ac31d8bf4f93f3634fbea3f h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/arm/common/sa1111.c | 281 +++------ trunk/arch/arm/include/asm/hardware/sa1111.h | 156 ++++- trunk/arch/arm/mach-pxa/lubbock.c | 1 - trunk/arch/arm/mach-sa1100/assabet.c | 54 +- trunk/arch/arm/mach-sa1100/badge4.c | 40 +- trunk/arch/arm/mach-sa1100/cerf.c | 13 +- trunk/arch/arm/mach-sa1100/collie.c | 24 +- trunk/arch/arm/mach-sa1100/generic.c | 97 +++- trunk/arch/arm/mach-sa1100/h3xxx.c | 13 +- trunk/arch/arm/mach-sa1100/hackkit.c | 7 +- .../arch/arm/mach-sa1100/include/mach/irqs.h | 8 + .../arm/mach-sa1100/include/mach/neponset.h | 52 +- trunk/arch/arm/mach-sa1100/irq.c | 7 +- trunk/arch/arm/mach-sa1100/jornada720.c | 39 +- trunk/arch/arm/mach-sa1100/nanoengine.c | 11 +- trunk/arch/arm/mach-sa1100/neponset.c | 545 ++++++++---------- trunk/arch/arm/mach-sa1100/pci-nanoengine.c | 8 +- trunk/arch/arm/mach-sa1100/pleb.c | 24 +- trunk/arch/arm/mach-sa1100/shannon.c | 7 +- trunk/arch/arm/mach-sa1100/simpad.c | 11 +- trunk/arch/arm/mach-sa1100/sleep.S | 37 +- trunk/drivers/input/serio/sa1111ps2.c | 59 +- trunk/drivers/net/ethernet/smsc/smc91x.c | 2 +- trunk/drivers/net/irda/sa1100_ir.c | 2 +- trunk/drivers/pcmcia/sa1100_neponset.c | 7 +- trunk/drivers/pcmcia/sa1111_generic.c | 55 +- trunk/drivers/usb/host/ohci-sa1111.c | 297 +++++----- 28 files changed, 972 insertions(+), 887 deletions(-) diff --git a/[refs] b/[refs] index d9bb6db622bd..eedc9082e7b6 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 374da9da22ebaad0524c77905b5e89ae4619bef3 +refs/heads/master: 15877e9c8a12ced38ac31d8bf4f93f3634fbea3f diff --git a/trunk/arch/arm/common/sa1111.c b/trunk/arch/arm/common/sa1111.c index 9173d112ea01..61691cdbdcf2 100644 --- a/trunk/arch/arm/common/sa1111.c +++ b/trunk/arch/arm/common/sa1111.c @@ -16,7 +16,6 @@ */ #include #include -#include #include #include #include @@ -29,8 +28,9 @@ #include #include -#include #include +#include +#include #include #include @@ -86,10 +86,8 @@ #define IRQ_S1_CD_VALID (52) #define IRQ_S0_BVD1_STSCHG (53) #define IRQ_S1_BVD1_STSCHG (54) -#define SA1111_IRQ_NR (55) -extern void sa1110_mb_enable(void); -extern void sa1110_mb_disable(void); +extern void __init sa1110_mb_enable(void); /* * We keep the following data for the overall SA1111. Note that the @@ -106,7 +104,6 @@ struct sa1111 { int irq_base; /* base for cascaded on-chip IRQs */ spinlock_t lock; void __iomem *base; - struct sa1111_platform_data *pdata; #ifdef CONFIG_PM void *saved_state; #endif @@ -121,7 +118,6 @@ static struct sa1111 *g_sa1111; struct sa1111_dev_info { unsigned long offset; unsigned long skpcr_mask; - bool dma; unsigned int devid; unsigned int irq[6]; }; @@ -130,7 +126,6 @@ static struct sa1111_dev_info sa1111_devices[] = { { .offset = SA1111_USB, .skpcr_mask = SKPCR_UCLKEN, - .dma = true, .devid = SA1111_DEVID_USB, .irq = { IRQ_USBPWR, @@ -144,7 +139,6 @@ static struct sa1111_dev_info sa1111_devices[] = { { .offset = 0x0600, .skpcr_mask = SKPCR_I2SCLKEN | SKPCR_L3CLKEN, - .dma = true, .devid = SA1111_DEVID_SAC, .irq = { AUDXMTDMADONEA, @@ -161,7 +155,7 @@ static struct sa1111_dev_info sa1111_devices[] = { { .offset = SA1111_KBD, .skpcr_mask = SKPCR_PTCLKEN, - .devid = SA1111_DEVID_PS2_KBD, + .devid = SA1111_DEVID_PS2, .irq = { IRQ_TPRXINT, IRQ_TPTXINT @@ -170,7 +164,7 @@ static struct sa1111_dev_info sa1111_devices[] = { { .offset = SA1111_MSE, .skpcr_mask = SKPCR_PMCLKEN, - .devid = SA1111_DEVID_PS2_MSE, + .devid = SA1111_DEVID_PS2, .irq = { IRQ_MSRXINT, IRQ_MSTXINT @@ -440,28 +434,16 @@ static struct irq_chip sa1111_high_chip = { .irq_set_wake = sa1111_wake_highirq, }; -static int sa1111_setup_irq(struct sa1111 *sachip, unsigned irq_base) +static void sa1111_setup_irq(struct sa1111 *sachip) { void __iomem *irqbase = sachip->base + SA1111_INTC; - unsigned i, irq; - int ret; + unsigned int irq; /* * We're guaranteed that this region hasn't been taken. */ request_mem_region(sachip->phys + SA1111_INTC, 512, "irq"); - ret = irq_alloc_descs(-1, irq_base, SA1111_IRQ_NR, -1); - if (ret <= 0) { - dev_err(sachip->dev, "unable to allocate %u irqs: %d\n", - SA1111_IRQ_NR, ret); - if (ret == 0) - ret = -EINVAL; - return ret; - } - - sachip->irq_base = ret; - /* disable all IRQs */ sa1111_writel(0, irqbase + SA1111_INTEN0); sa1111_writel(0, irqbase + SA1111_INTEN1); @@ -481,16 +463,14 @@ static int sa1111_setup_irq(struct sa1111 *sachip, unsigned irq_base) sa1111_writel(~0, irqbase + SA1111_INTSTATCLR0); sa1111_writel(~0, irqbase + SA1111_INTSTATCLR1); - for (i = IRQ_GPAIN0; i <= SSPROR; i++) { - irq = sachip->irq_base + i; + for (irq = IRQ_GPAIN0; irq <= SSPROR; irq++) { irq_set_chip_and_handler(irq, &sa1111_low_chip, handle_edge_irq); irq_set_chip_data(irq, sachip); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } - for (i = AUDXMTDMADONEA; i <= IRQ_S1_BVD1_STSCHG; i++) { - irq = sachip->irq_base + i; + for (irq = AUDXMTDMADONEA; irq <= IRQ_S1_BVD1_STSCHG; irq++) { irq_set_chip_and_handler(irq, &sa1111_high_chip, handle_edge_irq); irq_set_chip_data(irq, sachip); @@ -503,11 +483,6 @@ static int sa1111_setup_irq(struct sa1111 *sachip, unsigned irq_base) irq_set_irq_type(sachip->irq, IRQ_TYPE_EDGE_RISING); irq_set_handler_data(sachip->irq, sachip); irq_set_chained_handler(sachip->irq, sa1111_irq_handler); - - dev_info(sachip->dev, "Providing IRQ%u-%u\n", - sachip->irq_base, sachip->irq_base + SA1111_IRQ_NR - 1); - - return 0; } /* @@ -606,10 +581,41 @@ sa1111_configure_smc(struct sa1111 *sachip, int sdram, unsigned int drac, } #endif +#ifdef CONFIG_DMABOUNCE +/* + * According to the "Intel StrongARM SA-1111 Microprocessor Companion + * Chip Specification Update" (June 2000), erratum #7, there is a + * significant bug in the SA1111 SDRAM shared memory controller. If + * an access to a region of memory above 1MB relative to the bank base, + * it is important that address bit 10 _NOT_ be asserted. Depending + * on the configuration of the RAM, bit 10 may correspond to one + * of several different (processor-relative) address bits. + * + * This routine only identifies whether or not a given DMA address + * is susceptible to the bug. + * + * This should only get called for sa1111_device types due to the + * way we configure our device dma_masks. + */ +static int sa1111_needs_bounce(struct device *dev, dma_addr_t addr, size_t size) +{ + /* + * Section 4.6 of the "Intel StrongARM SA-1111 Development Module + * User's Guide" mentions that jumpers R51 and R52 control the + * target of SA-1111 DMA (either SDRAM bank 0 on Assabet, or + * SDRAM bank 1 on Neponset). The default configuration selects + * Assabet, so any address in bank 1 is necessarily invalid. + */ + return (machine_is_assabet() || machine_is_pfs168()) && + (addr >= 0xc8000000 || (addr + size) >= 0xc8000000); +} +#endif + static void sa1111_dev_release(struct device *_dev) { struct sa1111_dev *dev = SA1111_DEV(_dev); + release_resource(&dev->res); kfree(dev); } @@ -618,58 +624,67 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent, struct sa1111_dev_info *info) { struct sa1111_dev *dev; - unsigned i; int ret; dev = kzalloc(sizeof(struct sa1111_dev), GFP_KERNEL); if (!dev) { ret = -ENOMEM; - goto err_alloc; + goto out; } - device_initialize(&dev->dev); dev_set_name(&dev->dev, "%4.4lx", info->offset); dev->devid = info->devid; dev->dev.parent = sachip->dev; dev->dev.bus = &sa1111_bus_type; dev->dev.release = sa1111_dev_release; + dev->dev.coherent_dma_mask = sachip->dev->coherent_dma_mask; dev->res.start = sachip->phys + info->offset; dev->res.end = dev->res.start + 511; dev->res.name = dev_name(&dev->dev); dev->res.flags = IORESOURCE_MEM; dev->mapbase = sachip->base + info->offset; dev->skpcr_mask = info->skpcr_mask; + memmove(dev->irq, info->irq, sizeof(dev->irq)); + + ret = request_resource(parent, &dev->res); + if (ret) { + printk("SA1111: failed to allocate resource for %s\n", + dev->res.name); + dev_set_name(&dev->dev, NULL); + kfree(dev); + goto out; + } + - for (i = 0; i < ARRAY_SIZE(info->irq); i++) - dev->irq[i] = sachip->irq_base + info->irq[i]; + ret = device_register(&dev->dev); + if (ret) { + release_resource(&dev->res); + kfree(dev); + goto out; + } +#ifdef CONFIG_DMABOUNCE /* - * If the parent device has a DMA mask associated with it, and - * this child supports DMA, propagate it down to the children. + * If the parent device has a DMA mask associated with it, + * propagate it down to the children. */ - if (info->dma && sachip->dev->dma_mask) { + if (sachip->dev->dma_mask) { dev->dma_mask = *sachip->dev->dma_mask; dev->dev.dma_mask = &dev->dma_mask; - dev->dev.coherent_dma_mask = sachip->dev->coherent_dma_mask; - } - ret = request_resource(parent, &dev->res); - if (ret) { - dev_err(sachip->dev, "failed to allocate resource for %s\n", - dev->res.name); - goto err_resource; + if (dev->dma_mask != 0xffffffffUL) { + ret = dmabounce_register_dev(&dev->dev, 1024, 4096, + sa1111_needs_bounce); + if (ret) { + dev_err(&dev->dev, "SA1111: Failed to register" + " with dmabounce\n"); + device_unregister(&dev->dev); + } + } } +#endif - ret = device_add(&dev->dev); - if (ret) - goto err_add; - return 0; - - err_add: - release_resource(&dev->res); - err_resource: - put_device(&dev->dev); - err_alloc: +out: return ret; } @@ -683,21 +698,16 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent, * Returns: * %-ENODEV device not found. * %-EBUSY physical address already marked in-use. - * %-EINVAL no platform data passed * %0 successful. */ static int __devinit __sa1111_probe(struct device *me, struct resource *mem, int irq) { - struct sa1111_platform_data *pd = me->platform_data; struct sa1111 *sachip; unsigned long id; unsigned int has_devs; int i, ret = -ENODEV; - if (!pd) - return -EINVAL; - sachip = kzalloc(sizeof(struct sa1111), GFP_KERNEL); if (!sachip) return -ENOMEM; @@ -717,7 +727,6 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) sachip->dev = me; dev_set_drvdata(sachip->dev, sachip); - sachip->pdata = pd; sachip->phys = mem->start; sachip->irq = irq; @@ -750,16 +759,6 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) */ sa1111_wake(sachip); - /* - * The interrupt controller must be initialised before any - * other device to ensure that the interrupts are available. - */ - if (sachip->irq != NO_IRQ) { - ret = sa1111_setup_irq(sachip, pd->irq_base); - if (ret) - goto err_unmap; - } - #ifdef CONFIG_ARCH_SA1100 { unsigned int val; @@ -790,14 +789,24 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) } #endif + /* + * The interrupt controller must be initialised before any + * other device to ensure that the interrupts are available. + */ + if (sachip->irq != NO_IRQ) + sa1111_setup_irq(sachip); + g_sa1111 = sachip; has_devs = ~0; - if (pd) - has_devs &= ~pd->disable_devs; + if (machine_is_assabet() || machine_is_jornada720() || + machine_is_badge4()) + has_devs &= ~(1 << 4); + else + has_devs &= ~(1 << 1); for (i = 0; i < ARRAY_SIZE(sa1111_devices); i++) - if (sa1111_devices[i].devid & has_devs) + if (has_devs & (1 << i)) sa1111_init_one_child(sachip, mem, &sa1111_devices[i]); return 0; @@ -815,10 +824,7 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) static int sa1111_remove_one(struct device *dev, void *data) { - struct sa1111_dev *sadev = SA1111_DEV(dev); - device_del(&sadev->dev); - release_resource(&sadev->res); - put_device(&sadev->dev); + device_unregister(dev); return 0; } @@ -840,7 +846,6 @@ static void __sa1111_remove(struct sa1111 *sachip) if (sachip->irq != NO_IRQ) { irq_set_chained_handler(sachip->irq, NULL); irq_set_handler_data(sachip->irq, NULL); - irq_free_descs(sachip->irq_base, SA1111_IRQ_NR); release_mem_region(sachip->phys + SA1111_INTC, 512); } @@ -899,9 +904,6 @@ static int sa1111_suspend(struct platform_device *dev, pm_message_t state) save->skpwm0 = sa1111_readl(base + SA1111_SKPWM0); save->skpwm1 = sa1111_readl(base + SA1111_SKPWM1); - sa1111_writel(0, sachip->base + SA1111_SKPWM0); - sa1111_writel(0, sachip->base + SA1111_SKPWM1); - base = sachip->base + SA1111_INTC; save->intpol0 = sa1111_readl(base + SA1111_INTPOL0); save->intpol1 = sa1111_readl(base + SA1111_INTPOL1); @@ -917,15 +919,13 @@ static int sa1111_suspend(struct platform_device *dev, pm_message_t state) */ val = sa1111_readl(sachip->base + SA1111_SKCR); sa1111_writel(val | SKCR_SLEEP, sachip->base + SA1111_SKCR); + sa1111_writel(0, sachip->base + SA1111_SKPWM0); + sa1111_writel(0, sachip->base + SA1111_SKPWM1); clk_disable(sachip->clk); spin_unlock_irqrestore(&sachip->lock, flags); -#ifdef CONFIG_ARCH_SA1100 - sa1110_mb_disable(); -#endif - return 0; } @@ -966,11 +966,6 @@ static int sa1111_resume(struct platform_device *dev) */ sa1111_wake(sachip); -#ifdef CONFIG_ARCH_SA1100 - /* Enable the memory bus request/grant signals */ - sa1110_mb_enable(); -#endif - /* * Only lock for write ops. Also, sa1111_wake must be called with * released spinlock! @@ -1058,7 +1053,6 @@ static struct platform_driver sa1111_device_driver = { .resume = sa1111_resume, .driver = { .name = "sa1111", - .owner = THIS_MODULE, }, }; @@ -1244,23 +1238,16 @@ EXPORT_SYMBOL(sa1111_set_sleep_io); * sa1111_enable_device - enable an on-chip SA1111 function block * @sadev: SA1111 function block device to enable */ -int sa1111_enable_device(struct sa1111_dev *sadev) +void sa1111_enable_device(struct sa1111_dev *sadev) { struct sa1111 *sachip = sa1111_chip_driver(sadev); unsigned long flags; unsigned int val; - int ret = 0; - - if (sachip->pdata && sachip->pdata->enable) - ret = sachip->pdata->enable(sachip->pdata->data, sadev->devid); - if (ret == 0) { - spin_lock_irqsave(&sachip->lock, flags); - val = sa1111_readl(sachip->base + SA1111_SKPCR); - sa1111_writel(val | sadev->skpcr_mask, sachip->base + SA1111_SKPCR); - spin_unlock_irqrestore(&sachip->lock, flags); - } - return ret; + spin_lock_irqsave(&sachip->lock, flags); + val = sa1111_readl(sachip->base + SA1111_SKPCR); + sa1111_writel(val | sadev->skpcr_mask, sachip->base + SA1111_SKPCR); + spin_unlock_irqrestore(&sachip->lock, flags); } EXPORT_SYMBOL(sa1111_enable_device); @@ -1278,9 +1265,6 @@ void sa1111_disable_device(struct sa1111_dev *sadev) val = sa1111_readl(sachip->base + SA1111_SKPCR); sa1111_writel(val & ~sadev->skpcr_mask, sachip->base + SA1111_SKPCR); spin_unlock_irqrestore(&sachip->lock, flags); - - if (sachip->pdata && sachip->pdata->disable) - sachip->pdata->disable(sachip->pdata->data, sadev->devid); } EXPORT_SYMBOL(sa1111_disable_device); @@ -1295,7 +1279,7 @@ static int sa1111_match(struct device *_dev, struct device_driver *_drv) struct sa1111_dev *dev = SA1111_DEV(_dev); struct sa1111_driver *drv = SA1111_DRV(_drv); - return dev->devid & drv->devid; + return dev->devid == drv->devid; } static int sa1111_bus_suspend(struct device *dev, pm_message_t state) @@ -1320,14 +1304,6 @@ static int sa1111_bus_resume(struct device *dev) return ret; } -static void sa1111_bus_shutdown(struct device *dev) -{ - struct sa1111_driver *drv = SA1111_DRV(dev->driver); - - if (drv && drv->shutdown) - drv->shutdown(SA1111_DEV(dev)); -} - static int sa1111_bus_probe(struct device *dev) { struct sa1111_dev *sadev = SA1111_DEV(dev); @@ -1357,7 +1333,6 @@ struct bus_type sa1111_bus_type = { .remove = sa1111_bus_remove, .suspend = sa1111_bus_suspend, .resume = sa1111_bus_resume, - .shutdown = sa1111_bus_shutdown, }; EXPORT_SYMBOL(sa1111_bus_type); @@ -1374,70 +1349,9 @@ void sa1111_driver_unregister(struct sa1111_driver *driver) } EXPORT_SYMBOL(sa1111_driver_unregister); -#ifdef CONFIG_DMABOUNCE -/* - * According to the "Intel StrongARM SA-1111 Microprocessor Companion - * Chip Specification Update" (June 2000), erratum #7, there is a - * significant bug in the SA1111 SDRAM shared memory controller. If - * an access to a region of memory above 1MB relative to the bank base, - * it is important that address bit 10 _NOT_ be asserted. Depending - * on the configuration of the RAM, bit 10 may correspond to one - * of several different (processor-relative) address bits. - * - * This routine only identifies whether or not a given DMA address - * is susceptible to the bug. - * - * This should only get called for sa1111_device types due to the - * way we configure our device dma_masks. - */ -static int sa1111_needs_bounce(struct device *dev, dma_addr_t addr, size_t size) -{ - /* - * Section 4.6 of the "Intel StrongARM SA-1111 Development Module - * User's Guide" mentions that jumpers R51 and R52 control the - * target of SA-1111 DMA (either SDRAM bank 0 on Assabet, or - * SDRAM bank 1 on Neponset). The default configuration selects - * Assabet, so any address in bank 1 is necessarily invalid. - */ - return (machine_is_assabet() || machine_is_pfs168()) && - (addr >= 0xc8000000 || (addr + size) >= 0xc8000000); -} - -static int sa1111_notifier_call(struct notifier_block *n, unsigned long action, - void *data) -{ - struct sa1111_dev *dev = SA1111_DEV(data); - - switch (action) { - case BUS_NOTIFY_ADD_DEVICE: - if (dev->dev.dma_mask && dev->dma_mask < 0xffffffffUL) { - int ret = dmabounce_register_dev(&dev->dev, 1024, 4096, - sa1111_needs_bounce); - if (ret) - dev_err(&dev->dev, "failed to register with dmabounce: %d\n", ret); - } - break; - - case BUS_NOTIFY_DEL_DEVICE: - if (dev->dev.dma_mask && dev->dma_mask < 0xffffffffUL) - dmabounce_unregister_dev(&dev->dev); - break; - } - return NOTIFY_OK; -} - -static struct notifier_block sa1111_bus_notifier = { - .notifier_call = sa1111_notifier_call, -}; -#endif - static int __init sa1111_init(void) { int ret = bus_register(&sa1111_bus_type); -#ifdef CONFIG_DMABOUNCE - if (ret == 0) - bus_register_notifier(&sa1111_bus_type, &sa1111_bus_notifier); -#endif if (ret == 0) platform_driver_register(&sa1111_device_driver); return ret; @@ -1446,9 +1360,6 @@ static int __init sa1111_init(void) static void __exit sa1111_exit(void) { platform_driver_unregister(&sa1111_device_driver); -#ifdef CONFIG_DMABOUNCE - bus_unregister_notifier(&sa1111_bus_type, &sa1111_bus_notifier); -#endif bus_unregister(&sa1111_bus_type); } diff --git a/trunk/arch/arm/include/asm/hardware/sa1111.h b/trunk/arch/arm/include/asm/hardware/sa1111.h index 7c2bbc7f0be1..92ed254c175b 100644 --- a/trunk/arch/arm/include/asm/hardware/sa1111.h +++ b/trunk/arch/arm/include/asm/hardware/sa1111.h @@ -132,9 +132,33 @@ #define SKPCR_DCLKEN (1<<7) #define SKPCR_PWMCLKEN (1<<8) -/* USB Host controller */ +/* + * USB Host controller + */ #define SA1111_USB 0x0400 +/* + * Offsets from SA1111_USB_BASE + */ +#define SA1111_USB_STATUS 0x0118 +#define SA1111_USB_RESET 0x011c +#define SA1111_USB_IRQTEST 0x0120 + +#define USB_RESET_FORCEIFRESET (1 << 0) +#define USB_RESET_FORCEHCRESET (1 << 1) +#define USB_RESET_CLKGENRESET (1 << 2) +#define USB_RESET_SIMSCALEDOWN (1 << 3) +#define USB_RESET_USBINTTEST (1 << 4) +#define USB_RESET_SLEEPSTBYEN (1 << 5) +#define USB_RESET_PWRSENSELOW (1 << 6) +#define USB_RESET_PWRCTRLLOW (1 << 7) + +#define USB_STATUS_IRQHCIRMTWKUP (1 << 7) +#define USB_STATUS_IRQHCIBUFFACC (1 << 8) +#define USB_STATUS_NIRQHCIM (1 << 9) +#define USB_STATUS_NHCIMFCLR (1 << 10) +#define USB_STATUS_USBPWRSENSE (1 << 11) + /* * Serial Audio Controller * @@ -303,6 +327,22 @@ * PC_SSR GPIO Block C Sleep State */ +#define _PA_DDR _SA1111( 0x1000 ) +#define _PA_DRR _SA1111( 0x1004 ) +#define _PA_DWR _SA1111( 0x1004 ) +#define _PA_SDR _SA1111( 0x1008 ) +#define _PA_SSR _SA1111( 0x100c ) +#define _PB_DDR _SA1111( 0x1010 ) +#define _PB_DRR _SA1111( 0x1014 ) +#define _PB_DWR _SA1111( 0x1014 ) +#define _PB_SDR _SA1111( 0x1018 ) +#define _PB_SSR _SA1111( 0x101c ) +#define _PC_DDR _SA1111( 0x1020 ) +#define _PC_DRR _SA1111( 0x1024 ) +#define _PC_DWR _SA1111( 0x1024 ) +#define _PC_SDR _SA1111( 0x1028 ) +#define _PC_SSR _SA1111( 0x102c ) + #define SA1111_GPIO 0x1000 #define SA1111_GPIO_PADDR (0x000) @@ -385,30 +425,106 @@ #define SA1111_WAKEPOL0 0x0034 #define SA1111_WAKEPOL1 0x0038 -/* PS/2 Trackpad and Mouse Interfaces */ +/* + * PS/2 Trackpad and Mouse Interfaces + * + * Registers + * PS2CR Control Register + * PS2STAT Status Register + * PS2DATA Transmit/Receive Data register + * PS2CLKDIV Clock Division Register + * PS2PRECNT Clock Precount Register + * PS2TEST1 Test register 1 + * PS2TEST2 Test register 2 + * PS2TEST3 Test register 3 + * PS2TEST4 Test register 4 + */ + #define SA1111_KBD 0x0a00 #define SA1111_MSE 0x0c00 -/* PCMCIA Interface */ -#define SA1111_PCMCIA 0x1600 +/* + * These are offsets from the above bases. + */ +#define SA1111_PS2CR 0x0000 +#define SA1111_PS2STAT 0x0004 +#define SA1111_PS2DATA 0x0008 +#define SA1111_PS2CLKDIV 0x000c +#define SA1111_PS2PRECNT 0x0010 + +#define PS2CR_ENA 0x08 +#define PS2CR_FKD 0x02 +#define PS2CR_FKC 0x01 + +#define PS2STAT_STP 0x0100 +#define PS2STAT_TXE 0x0080 +#define PS2STAT_TXB 0x0040 +#define PS2STAT_RXF 0x0020 +#define PS2STAT_RXB 0x0010 +#define PS2STAT_ENA 0x0008 +#define PS2STAT_RXP 0x0004 +#define PS2STAT_KBD 0x0002 +#define PS2STAT_KBC 0x0001 +/* + * PCMCIA Interface + * + * Registers + * PCSR Status Register + * PCCR Control Register + * PCSSR Sleep State Register + */ + +#define SA1111_PCMCIA 0x1600 + +/* + * These are offsets from the above base. + */ +#define SA1111_PCCR 0x0000 +#define SA1111_PCSSR 0x0004 +#define SA1111_PCSR 0x0008 + +#define PCSR_S0_READY (1<<0) +#define PCSR_S1_READY (1<<1) +#define PCSR_S0_DETECT (1<<2) +#define PCSR_S1_DETECT (1<<3) +#define PCSR_S0_VS1 (1<<4) +#define PCSR_S0_VS2 (1<<5) +#define PCSR_S1_VS1 (1<<6) +#define PCSR_S1_VS2 (1<<7) +#define PCSR_S0_WP (1<<8) +#define PCSR_S1_WP (1<<9) +#define PCSR_S0_BVD1 (1<<10) +#define PCSR_S0_BVD2 (1<<11) +#define PCSR_S1_BVD1 (1<<12) +#define PCSR_S1_BVD2 (1<<13) + +#define PCCR_S0_RST (1<<0) +#define PCCR_S1_RST (1<<1) +#define PCCR_S0_FLT (1<<2) +#define PCCR_S1_FLT (1<<3) +#define PCCR_S0_PWAITEN (1<<4) +#define PCCR_S1_PWAITEN (1<<5) +#define PCCR_S0_PSE (1<<6) +#define PCCR_S1_PSE (1<<7) + +#define PCSSR_S0_SLEEP (1<<0) +#define PCSSR_S1_SLEEP (1<<1) extern struct bus_type sa1111_bus_type; -#define SA1111_DEVID_SBI (1 << 0) -#define SA1111_DEVID_SK (1 << 1) -#define SA1111_DEVID_USB (1 << 2) -#define SA1111_DEVID_SAC (1 << 3) -#define SA1111_DEVID_SSP (1 << 4) -#define SA1111_DEVID_PS2 (3 << 5) -#define SA1111_DEVID_PS2_KBD (1 << 5) -#define SA1111_DEVID_PS2_MSE (1 << 6) -#define SA1111_DEVID_GPIO (1 << 7) -#define SA1111_DEVID_INT (1 << 8) -#define SA1111_DEVID_PCMCIA (1 << 9) +#define SA1111_DEVID_SBI 0 +#define SA1111_DEVID_SK 1 +#define SA1111_DEVID_USB 2 +#define SA1111_DEVID_SAC 3 +#define SA1111_DEVID_SSP 4 +#define SA1111_DEVID_PS2 5 +#define SA1111_DEVID_GPIO 6 +#define SA1111_DEVID_INT 7 +#define SA1111_DEVID_PCMCIA 8 struct sa1111_dev { struct device dev; @@ -432,7 +548,6 @@ struct sa1111_driver { int (*remove)(struct sa1111_dev *); int (*suspend)(struct sa1111_dev *, pm_message_t); int (*resume)(struct sa1111_dev *); - void (*shutdown)(struct sa1111_dev *); }; #define SA1111_DRV(_d) container_of((_d), struct sa1111_driver, drv) @@ -440,10 +555,9 @@ struct sa1111_driver { #define SA1111_DRIVER_NAME(_sadev) ((_sadev)->dev.driver->name) /* - * These frob the SKPCR register, and call platform specific - * enable/disable functions. + * These frob the SKPCR register. */ -int sa1111_enable_device(struct sa1111_dev *); +void sa1111_enable_device(struct sa1111_dev *); void sa1111_disable_device(struct sa1111_dev *); unsigned int sa1111_pll_clock(struct sa1111_dev *); @@ -466,10 +580,6 @@ void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned i struct sa1111_platform_data { int irq_base; /* base for cascaded on-chip IRQs */ - unsigned disable_devs; - void *data; - int (*enable)(void *, unsigned); - void (*disable)(void *, unsigned); }; #endif /* _ASM_ARCH_SA1111 */ diff --git a/trunk/arch/arm/mach-pxa/lubbock.c b/trunk/arch/arm/mach-pxa/lubbock.c index 6bb3f47b1f14..6ebd276aebeb 100644 --- a/trunk/arch/arm/mach-pxa/lubbock.c +++ b/trunk/arch/arm/mach-pxa/lubbock.c @@ -223,7 +223,6 @@ static struct resource sa1111_resources[] = { static struct sa1111_platform_data sa1111_info = { .irq_base = LUBBOCK_SA1111_IRQ_BASE, - .disable_devs = SA1111_DEVID_SAC, }; static struct platform_device sa1111_device = { diff --git a/trunk/arch/arm/mach-sa1100/assabet.c b/trunk/arch/arm/mach-sa1100/assabet.c index e2d411a8d4ce..0c4b76ab4d8e 100644 --- a/trunk/arch/arm/mach-sa1100/assabet.c +++ b/trunk/arch/arm/mach-sa1100/assabet.c @@ -40,13 +40,13 @@ #include "generic.h" #define ASSABET_BCR_DB1110 \ - (ASSABET_BCR_SPK_OFF | \ + (ASSABET_BCR_SPK_OFF | ASSABET_BCR_QMUTE | \ ASSABET_BCR_LED_GREEN | ASSABET_BCR_LED_RED | \ ASSABET_BCR_RS232EN | ASSABET_BCR_LCD_12RGB | \ ASSABET_BCR_IRDA_MD0) #define ASSABET_BCR_DB1111 \ - (ASSABET_BCR_SPK_OFF | \ + (ASSABET_BCR_SPK_OFF | ASSABET_BCR_QMUTE | \ ASSABET_BCR_LED_GREEN | ASSABET_BCR_LED_RED | \ ASSABET_BCR_RS232EN | ASSABET_BCR_LCD_12RGB | \ ASSABET_BCR_CF_BUS_OFF | ASSABET_BCR_STEREO_LB | \ @@ -152,8 +152,15 @@ static struct flash_platform_data assabet_flash_data = { }; static struct resource assabet_flash_resources[] = { - DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M), - DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_32M), + { + .start = SA1100_CS0_PHYS, + .end = SA1100_CS0_PHYS + SZ_32M - 1, + .flags = IORESOURCE_MEM, + }, { + .start = SA1100_CS1_PHYS, + .end = SA1100_CS1_PHYS + SZ_32M - 1, + .flags = IORESOURCE_MEM, + } }; @@ -197,22 +204,13 @@ static struct mcp_plat_data assabet_mcp_data = { .sclk_rate = 11981000, }; -#ifdef CONFIG_ASSABET_NEPONSET -static struct resource neponset_resources[] = { - DEFINE_RES_MEM(0x10000000, 0x08000000), - DEFINE_RES_MEM(0x18000000, 0x04000000), - DEFINE_RES_MEM(0x40000000, SZ_8K), - DEFINE_RES_IRQ(IRQ_GPIO25), -}; -#endif - static void __init assabet_init(void) { /* * Ensure that the power supply is in "high power" mode. */ - GPSR = GPIO_GPIO16; GPDR |= GPIO_GPIO16; + GPSR = GPIO_GPIO16; /* * Ensure that these pins are set as outputs and are driving @@ -220,16 +218,8 @@ static void __init assabet_init(void) * the WS latch in the CPLD, and we don't float causing * excessive power drain. --rmk */ - GPCR = GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM; GPDR |= GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM; - - /* - * Also set GPIO27 as an output; this is used to clock UART3 - * via the FPGA and as otherwise has no pullups or pulldowns, - * so stop it floating. - */ - GPCR = GPIO_GPIO27; - GPDR |= GPIO_GPIO27; + GPCR = GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM; /* * Set up registers for sleep mode. @@ -256,9 +246,6 @@ static void __init assabet_init(void) #ifndef CONFIG_ASSABET_NEPONSET printk( "Warning: Neponset detected but full support " "hasn't been configured in the kernel\n" ); -#else - platform_device_register_simple("neponset", 0, - neponset_resources, ARRAY_SIZE(neponset_resources)); #endif } @@ -425,8 +412,21 @@ static void __init assabet_map_io(void) */ Ser1SDCR0 |= SDCR0_SUS; - if (!machine_has_neponset()) + if (machine_has_neponset()) { +#ifdef CONFIG_ASSABET_NEPONSET + extern void neponset_map_io(void); + + /* + * We map Neponset registers even if it isn't present since + * many drivers will try to probe their stuff (and fail). + * This is still more friendly than a kernel paging request + * crash. + */ + neponset_map_io(); +#endif + } else { sa1100_register_uart_fns(&assabet_port_fns); + } /* * When Neponset is attached, the first UART should be diff --git a/trunk/arch/arm/mach-sa1100/badge4.c b/trunk/arch/arm/mach-sa1100/badge4.c index 5839c9d8bb92..b07a2c024cb7 100644 --- a/trunk/arch/arm/mach-sa1100/badge4.c +++ b/trunk/arch/arm/mach-sa1100/badge4.c @@ -39,28 +39,20 @@ #include "generic.h" static struct resource sa1111_resources[] = { - [0] = DEFINE_RES_MEM(BADGE4_SA1111_BASE, 0x2000), - [1] = DEFINE_RES_IRQ(BADGE4_IRQ_GPIO_SA1111), + [0] = { + .start = BADGE4_SA1111_BASE, + .end = BADGE4_SA1111_BASE + 0x00001fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = BADGE4_IRQ_GPIO_SA1111, + .end = BADGE4_IRQ_GPIO_SA1111, + .flags = IORESOURCE_IRQ, + }, }; -static int badge4_sa1111_enable(void *data, unsigned devid) -{ - if (devid == SA1111_DEVID_USB) - badge4_set_5V(BADGE4_5V_USB, 1); - return 0; -} - -static void badge4_sa1111_disable(void *data, unsigned devid) -{ - if (devid == SA1111_DEVID_USB) - badge4_set_5V(BADGE4_5V_USB, 0); -} - static struct sa1111_platform_data sa1111_info = { .irq_base = IRQ_BOARD_END, - .disable_devs = SA1111_DEVID_PS2_MSE, - .enable = badge4_sa1111_enable, - .disable = badge4_sa1111_disable, }; static u64 sa1111_dmamask = 0xffffffffUL; @@ -129,8 +121,11 @@ static struct flash_platform_data badge4_flash_data = { .nr_parts = ARRAY_SIZE(badge4_partitions), }; -static struct resource badge4_flash_resource = - DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_64M); +static struct resource badge4_flash_resource = { + .start = SA1100_CS0_PHYS, + .end = SA1100_CS0_PHYS + SZ_64M - 1, + .flags = IORESOURCE_MEM, +}; static int five_v_on __initdata = 0; @@ -274,6 +269,11 @@ static struct map_desc badge4_io_desc[] __initdata = { .pfn = __phys_to_pfn(0x10000000), .length = 0x00100000, .type = MT_DEVICE + }, { /* SA-1111 */ + .virtual = 0xf4000000, + .pfn = __phys_to_pfn(0x48000000), + .length = 0x00100000, + .type = MT_DEVICE } }; diff --git a/trunk/arch/arm/mach-sa1100/cerf.c b/trunk/arch/arm/mach-sa1100/cerf.c index c2f9ba3a9578..11bb6d0b9be3 100644 --- a/trunk/arch/arm/mach-sa1100/cerf.c +++ b/trunk/arch/arm/mach-sa1100/cerf.c @@ -33,7 +33,11 @@ #include "generic.h" static struct resource cerfuart2_resources[] = { - [0] = DEFINE_RES_MEM(0x80030000, SZ_64K), + [0] = { + .start = 0x80030000, + .end = 0x8003ffff, + .flags = IORESOURCE_MEM, + }, }; static struct platform_device cerfuart2_device = { @@ -83,8 +87,11 @@ static struct flash_platform_data cerf_flash_data = { .nr_parts = ARRAY_SIZE(cerf_partitions), }; -static struct resource cerf_flash_resource = - DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M); +static struct resource cerf_flash_resource = { + .start = SA1100_CS0_PHYS, + .end = SA1100_CS0_PHYS + SZ_32M - 1, + .flags = IORESOURCE_MEM, +}; static void __init cerf_init_irq(void) { diff --git a/trunk/arch/arm/mach-sa1100/collie.c b/trunk/arch/arm/mach-sa1100/collie.c index dbe5cf719f7e..fd5652118ed1 100644 --- a/trunk/arch/arm/mach-sa1100/collie.c +++ b/trunk/arch/arm/mach-sa1100/collie.c @@ -48,7 +48,11 @@ #include "generic.h" static struct resource collie_scoop_resources[] = { - [0] = DEFINE_RES_MEM(0x40800000, SZ_4K), + [0] = { + .start = 0x40800000, + .end = 0x40800fff, + .flags = IORESOURCE_MEM, + }, }; static struct scoop_config collie_scoop_setup = { @@ -217,8 +221,16 @@ device_initcall(collie_uart_init); static struct resource locomo_resources[] = { - [0] = DEFINE_RES_MEM(0x40000000, SZ_8K), - [1] = DEFINE_RES_IRQ(IRQ_GPIO25), + [0] = { + .start = 0x40000000, + .end = 0x40001fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_GPIO25, + .end = IRQ_GPIO25, + .flags = IORESOURCE_IRQ, + }, }; static struct locomo_platform_data locomo_info = { @@ -291,7 +303,11 @@ static struct flash_platform_data collie_flash_data = { }; static struct resource collie_flash_resources[] = { - DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M), + { + .start = SA1100_CS0_PHYS, + .end = SA1100_CS0_PHYS + SZ_32M - 1, + .flags = IORESOURCE_MEM, + } }; static void __init collie_init(void) diff --git a/trunk/arch/arm/mach-sa1100/generic.c b/trunk/arch/arm/mach-sa1100/generic.c index 2b33b4597468..bb10ee2cb89f 100644 --- a/trunk/arch/arm/mach-sa1100/generic.c +++ b/trunk/arch/arm/mach-sa1100/generic.c @@ -149,8 +149,16 @@ static void sa11x0_register_device(struct platform_device *dev, void *data) static struct resource sa11x0udc_resources[] = { - [0] = DEFINE_RES_MEM(__PREG(Ser0UDCCR), SZ_64K), - [1] = DEFINE_RES_IRQ(IRQ_Ser0UDC), + [0] = { + .start = __PREG(Ser0UDCCR), + .end = __PREG(Ser0UDCCR) + 0xffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_Ser0UDC, + .end = IRQ_Ser0UDC, + .flags = IORESOURCE_IRQ, + }, }; static u64 sa11x0udc_dma_mask = 0xffffffffUL; @@ -167,8 +175,16 @@ static struct platform_device sa11x0udc_device = { }; static struct resource sa11x0uart1_resources[] = { - [0] = DEFINE_RES_MEM(__PREG(Ser1UTCR0), SZ_64K), - [1] = DEFINE_RES_IRQ(IRQ_Ser1UART), + [0] = { + .start = __PREG(Ser1UTCR0), + .end = __PREG(Ser1UTCR0) + 0xffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_Ser1UART, + .end = IRQ_Ser1UART, + .flags = IORESOURCE_IRQ, + }, }; static struct platform_device sa11x0uart1_device = { @@ -179,8 +195,16 @@ static struct platform_device sa11x0uart1_device = { }; static struct resource sa11x0uart3_resources[] = { - [0] = DEFINE_RES_MEM(__PREG(Ser3UTCR0), SZ_64K), - [1] = DEFINE_RES_IRQ(IRQ_Ser3UART), + [0] = { + .start = __PREG(Ser3UTCR0), + .end = __PREG(Ser3UTCR0) + 0xffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_Ser3UART, + .end = IRQ_Ser3UART, + .flags = IORESOURCE_IRQ, + }, }; static struct platform_device sa11x0uart3_device = { @@ -191,8 +215,16 @@ static struct platform_device sa11x0uart3_device = { }; static struct resource sa11x0mcp_resources[] = { - [0] = DEFINE_RES_MEM(__PREG(Ser4MCCR0), SZ_64K), - [1] = DEFINE_RES_IRQ(IRQ_Ser4MCP), + [0] = { + .start = __PREG(Ser4MCCR0), + .end = __PREG(Ser4MCCR0) + 0xffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_Ser4MCP, + .end = IRQ_Ser4MCP, + .flags = IORESOURCE_IRQ, + }, }; static u64 sa11x0mcp_dma_mask = 0xffffffffUL; @@ -214,8 +246,16 @@ void sa11x0_register_mcp(struct mcp_plat_data *data) } static struct resource sa11x0ssp_resources[] = { - [0] = DEFINE_RES_MEM(0x80070000, SZ_64K), - [1] = DEFINE_RES_IRQ(IRQ_Ser4SSP), + [0] = { + .start = 0x80070000, + .end = 0x8007ffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_Ser4SSP, + .end = IRQ_Ser4SSP, + .flags = IORESOURCE_IRQ, + }, }; static u64 sa11x0ssp_dma_mask = 0xffffffffUL; @@ -232,8 +272,16 @@ static struct platform_device sa11x0ssp_device = { }; static struct resource sa11x0fb_resources[] = { - [0] = DEFINE_RES_MEM(0xb0100000, SZ_64K), - [1] = DEFINE_RES_IRQ(IRQ_LCD), + [0] = { + .start = 0xb0100000, + .end = 0xb010ffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_LCD, + .end = IRQ_LCD, + .flags = IORESOURCE_IRQ, + }, }; static struct platform_device sa11x0fb_device = { @@ -266,10 +314,23 @@ void sa11x0_register_mtd(struct flash_platform_data *flash, } static struct resource sa11x0ir_resources[] = { - DEFINE_RES_MEM(__PREG(Ser2UTCR0), 0x24), - DEFINE_RES_MEM(__PREG(Ser2HSCR0), 0x1c), - DEFINE_RES_MEM(__PREG(Ser2HSCR2), 0x04), - DEFINE_RES_IRQ(IRQ_Ser2ICP), + { + .start = __PREG(Ser2UTCR0), + .end = __PREG(Ser2UTCR0) + 0x24 - 1, + .flags = IORESOURCE_MEM, + }, { + .start = __PREG(Ser2HSCR0), + .end = __PREG(Ser2HSCR0) + 0x1c - 1, + .flags = IORESOURCE_MEM, + }, { + .start = __PREG(Ser2HSCR2), + .end = __PREG(Ser2HSCR2) + 0x04 - 1, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_Ser2ICP, + .end = IRQ_Ser2ICP, + .flags = IORESOURCE_IRQ, + } }; static struct platform_device sa11x0ir_device = { @@ -367,7 +428,7 @@ void __init sa1100_map_io(void) * the MBGNT signal false to ensure the SA1111 doesn't own the * SDRAM bus. */ -void sa1110_mb_disable(void) +void __init sa1110_mb_disable(void) { unsigned long flags; @@ -386,7 +447,7 @@ void sa1110_mb_disable(void) * If the system is going to use the SA-1111 DMA engines, set up * the memory bus request/grant pins. */ -void sa1110_mb_enable(void) +void __devinit sa1110_mb_enable(void) { unsigned long flags; diff --git a/trunk/arch/arm/mach-sa1100/h3xxx.c b/trunk/arch/arm/mach-sa1100/h3xxx.c index 63150e1ffe9e..b0784c974c2d 100644 --- a/trunk/arch/arm/mach-sa1100/h3xxx.c +++ b/trunk/arch/arm/mach-sa1100/h3xxx.c @@ -109,8 +109,11 @@ static struct flash_platform_data h3xxx_flash_data = { .nr_parts = ARRAY_SIZE(h3xxx_partitions), }; -static struct resource h3xxx_flash_resource = - DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M); +static struct resource h3xxx_flash_resource = { + .start = SA1100_CS0_PHYS, + .end = SA1100_CS0_PHYS + SZ_32M - 1, + .flags = IORESOURCE_MEM, +}; /* @@ -183,7 +186,11 @@ static struct sa1100_port_fns h3xxx_port_fns __initdata = { */ static struct resource egpio_resources[] = { - [0] = DEFINE_RES_MEM(H3600_EGPIO_PHYS, 0x4), + [0] = { + .start = H3600_EGPIO_PHYS, + .end = H3600_EGPIO_PHYS + 0x4 - 1, + .flags = IORESOURCE_MEM, + }, }; static struct htc_egpio_chip egpio_chips[] = { diff --git a/trunk/arch/arm/mach-sa1100/hackkit.c b/trunk/arch/arm/mach-sa1100/hackkit.c index 37d381ad5464..c01bb36db940 100644 --- a/trunk/arch/arm/mach-sa1100/hackkit.c +++ b/trunk/arch/arm/mach-sa1100/hackkit.c @@ -179,8 +179,11 @@ static struct flash_platform_data hackkit_flash_data = { .nr_parts = ARRAY_SIZE(hackkit_partitions), }; -static struct resource hackkit_flash_resource = - DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M); +static struct resource hackkit_flash_resource = { + .start = SA1100_CS0_PHYS, + .end = SA1100_CS0_PHYS + SZ_32M, + .flags = IORESOURCE_MEM, +}; static void __init hackkit_init(void) { diff --git a/trunk/arch/arm/mach-sa1100/include/mach/irqs.h b/trunk/arch/arm/mach-sa1100/include/mach/irqs.h index 9e07634a4670..d18f21abef80 100644 --- a/trunk/arch/arm/mach-sa1100/include/mach/irqs.h +++ b/trunk/arch/arm/mach-sa1100/include/mach/irqs.h @@ -82,3 +82,11 @@ #else #define NR_IRQS (IRQ_BOARD_START) #endif + +/* + * Board specific IRQs. Define them here. + * Do not surround them with ifdefs. + */ +#define IRQ_NEPONSET_SMC9196 (IRQ_BOARD_START + 0) +#define IRQ_NEPONSET_USAR (IRQ_BOARD_START + 1) +#define IRQ_NEPONSET_SA1111 (IRQ_BOARD_START + 2) diff --git a/trunk/arch/arm/mach-sa1100/include/mach/neponset.h b/trunk/arch/arm/mach-sa1100/include/mach/neponset.h index 5516a52a329d..ffe2bc45eed0 100644 --- a/trunk/arch/arm/mach-sa1100/include/mach/neponset.h +++ b/trunk/arch/arm/mach-sa1100/include/mach/neponset.h @@ -15,6 +15,54 @@ /* * Neponset definitions: */ + +#define NEPONSET_CPLD_BASE (0x10000000) +#define Nep_p2v( x ) ((x) - NEPONSET_CPLD_BASE + 0xf3000000) +#define Nep_v2p( x ) ((x) - 0xf3000000 + NEPONSET_CPLD_BASE) + +#define _IRR 0x10000024 /* Interrupt Reason Register */ +#define _AUD_CTL 0x100000c0 /* Audio controls (RW) */ +#define _MDM_CTL_0 0x100000b0 /* Modem control 0 (RW) */ +#define _MDM_CTL_1 0x100000b4 /* Modem control 1 (RW) */ +#define _NCR_0 0x100000a0 /* Control Register (RW) */ +#define _KP_X_OUT 0x10000090 /* Keypad row write (RW) */ +#define _KP_Y_IN 0x10000080 /* Keypad column read (RO) */ +#define _SWPK 0x10000020 /* Switch pack (RO) */ +#define _WHOAMI 0x10000000 /* System ID Register (RO) */ + +#define _LEDS 0x10000010 /* LEDs [31:0] (WO) */ + +#define IRR (*((volatile u_char *) Nep_p2v(_IRR))) +#define AUD_CTL (*((volatile u_char *) Nep_p2v(_AUD_CTL))) +#define MDM_CTL_0 (*((volatile u_char *) Nep_p2v(_MDM_CTL_0))) +#define MDM_CTL_1 (*((volatile u_char *) Nep_p2v(_MDM_CTL_1))) +#define NCR_0 (*((volatile u_char *) Nep_p2v(_NCR_0))) +#define KP_X_OUT (*((volatile u_char *) Nep_p2v(_KP_X_OUT))) +#define KP_Y_IN (*((volatile u_char *) Nep_p2v(_KP_Y_IN))) +#define SWPK (*((volatile u_char *) Nep_p2v(_SWPK))) +#define WHOAMI (*((volatile u_char *) Nep_p2v(_WHOAMI))) + +#define LEDS (*((volatile Word *) Nep_p2v(_LEDS))) + +#define IRR_ETHERNET (1<<0) +#define IRR_USAR (1<<1) +#define IRR_SA1111 (1<<2) + +#define AUD_SEL_1341 (1<<0) +#define AUD_MUTE_1341 (1<<1) + +#define MDM_CTL0_RTS1 (1 << 0) +#define MDM_CTL0_DTR1 (1 << 1) +#define MDM_CTL0_RTS2 (1 << 2) +#define MDM_CTL0_DTR2 (1 << 3) + +#define MDM_CTL1_CTS1 (1 << 0) +#define MDM_CTL1_DSR1 (1 << 1) +#define MDM_CTL1_DCD1 (1 << 2) +#define MDM_CTL1_CTS2 (1 << 3) +#define MDM_CTL1_DSR2 (1 << 4) +#define MDM_CTL1_DCD2 (1 << 5) + #define NCR_GP01_OFF (1<<0) #define NCR_TP_PWR_EN (1<<1) #define NCR_MS_PWR_EN (1<<2) @@ -23,8 +71,4 @@ #define NCR_A0VPP (1<<5) #define NCR_A1VPP (1<<6) -void neponset_ncr_frob(unsigned int, unsigned int); -#define neponset_ncr_set(v) neponset_ncr_frob(0, v) -#define neponset_ncr_clear(v) neponset_ncr_frob(v, 0) - #endif diff --git a/trunk/arch/arm/mach-sa1100/irq.c b/trunk/arch/arm/mach-sa1100/irq.c index 5d12a305f53e..dfbf824a69fa 100644 --- a/trunk/arch/arm/mach-sa1100/irq.c +++ b/trunk/arch/arm/mach-sa1100/irq.c @@ -221,8 +221,11 @@ static struct irq_chip sa1100_normal_chip = { .irq_set_wake = sa1100_set_wake, }; -static struct resource irq_resource = - DEFINE_RES_MEM_NAMED(0x90050000, SZ_64K, "irqs"); +static struct resource irq_resource = { + .name = "irqs", + .start = 0x90050000, + .end = 0x9005ffff, +}; static struct sa1100irq_state { unsigned int saved; diff --git a/trunk/arch/arm/mach-sa1100/jornada720.c b/trunk/arch/arm/mach-sa1100/jornada720.c index 8be8130baf63..ee121d6f0480 100644 --- a/trunk/arch/arm/mach-sa1100/jornada720.c +++ b/trunk/arch/arm/mach-sa1100/jornada720.c @@ -46,7 +46,7 @@ /* memory space (line 52 of HP's doc) */ #define SA1111REGSTART 0x40000000 -#define SA1111REGLEN 0x00002000 +#define SA1111REGLEN 0x00001fff #define EPSONREGSTART 0x48000000 #define EPSONREGLEN 0x00100000 #define EPSONFBSTART 0x48200000 @@ -174,8 +174,16 @@ static struct s1d13xxxfb_pdata s1d13xxxfb_data = { }; static struct resource s1d13xxxfb_resources[] = { - [0] = DEFINE_RES_MEM(EPSONFBSTART, EPSONFBLEN), - [1] = DEFINE_RES_MEM(EPSONREGSTART, EPSONREGLEN), + [0] = { + .start = EPSONFBSTART, + .end = EPSONFBSTART + EPSONFBLEN, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = EPSONREGSTART, + .end = EPSONREGSTART + EPSONREGLEN, + .flags = IORESOURCE_MEM, + } }; static struct platform_device s1d13xxxfb_device = { @@ -189,13 +197,20 @@ static struct platform_device s1d13xxxfb_device = { }; static struct resource sa1111_resources[] = { - [0] = DEFINE_RES_MEM(SA1111REGSTART, SA1111REGLEN), - [1] = DEFINE_RES_IRQ(IRQ_GPIO1), + [0] = { + .start = SA1111REGSTART, + .end = SA1111REGSTART + SA1111REGLEN, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_GPIO1, + .end = IRQ_GPIO1, + .flags = IORESOURCE_IRQ, + }, }; static struct sa1111_platform_data sa1111_info = { .irq_base = IRQ_BOARD_END, - .disable_devs = SA1111_DEVID_PS2_MSE, }; static u64 sa1111_dmamask = 0xffffffffUL; @@ -269,6 +284,11 @@ static struct map_desc jornada720_io_desc[] __initdata = { .pfn = __phys_to_pfn(EPSONFBSTART), .length = EPSONFBLEN, .type = MT_DEVICE + }, { /* SA-1111 */ + .virtual = 0xf4000000, + .pfn = __phys_to_pfn(SA1111REGSTART), + .length = SA1111REGLEN, + .type = MT_DEVICE } }; @@ -332,8 +352,11 @@ static struct flash_platform_data jornada720_flash_data = { .nr_parts = ARRAY_SIZE(jornada720_partitions), }; -static struct resource jornada720_flash_resource = - DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M); +static struct resource jornada720_flash_resource = { + .start = SA1100_CS0_PHYS, + .end = SA1100_CS0_PHYS + SZ_32M - 1, + .flags = IORESOURCE_MEM, +}; static void __init jornada720_mach_init(void) { diff --git a/trunk/arch/arm/mach-sa1100/nanoengine.c b/trunk/arch/arm/mach-sa1100/nanoengine.c index 3923911000de..85f6ee672225 100644 --- a/trunk/arch/arm/mach-sa1100/nanoengine.c +++ b/trunk/arch/arm/mach-sa1100/nanoengine.c @@ -58,8 +58,15 @@ static struct flash_platform_data nanoengine_flash_data = { }; static struct resource nanoengine_flash_resources[] = { - DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M), - DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_32M), + { + .start = SA1100_CS0_PHYS, + .end = SA1100_CS0_PHYS + SZ_32M - 1, + .flags = IORESOURCE_MEM, + }, { + .start = SA1100_CS1_PHYS, + .end = SA1100_CS1_PHYS + SZ_32M - 1, + .flags = IORESOURCE_MEM, + } }; static struct map_desc nanoengine_io_desc[] __initdata = { diff --git a/trunk/arch/arm/mach-sa1100/neponset.c b/trunk/arch/arm/mach-sa1100/neponset.c index 3297aa22cd77..b4fa53a1427e 100644 --- a/trunk/arch/arm/mach-sa1100/neponset.c +++ b/trunk/arch/arm/mach-sa1100/neponset.c @@ -1,103 +1,89 @@ /* * linux/arch/arm/mach-sa1100/neponset.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 +/* + * Install handler for Neponset IRQ. Note that we have to loop here + * since the ETHERNET and USAR IRQs are level based, and we need to + * ensure that the IRQ signal is deasserted before returning. This + * is rather unfortunate. + */ +static void +neponset_irq_handler(unsigned int irq, struct irq_desc *desc) +{ + unsigned int irr; -#define NEP_IRQ_SMC91X 0 -#define NEP_IRQ_USAR 1 -#define NEP_IRQ_SA1111 2 -#define NEP_IRQ_NR 3 - -#define WHOAMI 0x00 -#define LEDS 0x10 -#define SWPK 0x20 -#define IRR 0x24 -#define KP_Y_IN 0x80 -#define KP_X_OUT 0x90 -#define NCR_0 0xa0 -#define MDM_CTL_0 0xb0 -#define MDM_CTL_1 0xb4 -#define AUD_CTL 0xc0 - -#define IRR_ETHERNET (1 << 0) -#define IRR_USAR (1 << 1) -#define IRR_SA1111 (1 << 2) - -#define MDM_CTL0_RTS1 (1 << 0) -#define MDM_CTL0_DTR1 (1 << 1) -#define MDM_CTL0_RTS2 (1 << 2) -#define MDM_CTL0_DTR2 (1 << 3) - -#define MDM_CTL1_CTS1 (1 << 0) -#define MDM_CTL1_DSR1 (1 << 1) -#define MDM_CTL1_DCD1 (1 << 2) -#define MDM_CTL1_CTS2 (1 << 3) -#define MDM_CTL1_DSR2 (1 << 4) -#define MDM_CTL1_DCD2 (1 << 5) - -#define AUD_SEL_1341 (1 << 0) -#define AUD_MUTE_1341 (1 << 1) + while (1) { + /* + * Acknowledge the parent IRQ. + */ + desc->irq_data.chip->irq_ack(&desc->irq_data); -extern void sa1110_mb_disable(void); + /* + * Read the interrupt reason register. Let's have all + * active IRQ bits high. Note: there is a typo in the + * Neponset user's guide for the SA1111 IRR level. + */ + irr = IRR ^ (IRR_ETHERNET | IRR_USAR); -struct neponset_drvdata { - void __iomem *base; - struct platform_device *sa1111; - struct platform_device *smc91x; - unsigned irq_base; -#ifdef CONFIG_PM_SLEEP - u32 ncr0; - u32 mdm_ctl_0; -#endif -}; + if ((irr & (IRR_ETHERNET | IRR_USAR | IRR_SA1111)) == 0) + break; + + /* + * Since there is no individual mask, we have to + * mask the parent IRQ. This is safe, since we'll + * recheck the register for any pending IRQs. + */ + if (irr & (IRR_ETHERNET | IRR_USAR)) { + desc->irq_data.chip->irq_mask(&desc->irq_data); -static void __iomem *nep_base; + /* + * Ack the interrupt now to prevent re-entering + * this neponset handler. Again, this is safe + * since we'll check the IRR register prior to + * leaving. + */ + desc->irq_data.chip->irq_ack(&desc->irq_data); -void neponset_ncr_frob(unsigned int mask, unsigned int val) -{ - void __iomem *base = nep_base; - - if (base) { - unsigned long flags; - unsigned v; - - local_irq_save(flags); - v = readb_relaxed(base + NCR_0); - writeb_relaxed((v & ~mask) | val, base + NCR_0); - local_irq_restore(flags); - } else { - WARN(1, "nep_base unset\n"); + if (irr & IRR_ETHERNET) { + generic_handle_irq(IRQ_NEPONSET_SMC9196); + } + + if (irr & IRR_USAR) { + generic_handle_irq(IRQ_NEPONSET_USAR); + } + + desc->irq_data.chip->irq_unmask(&desc->irq_data); + } + + if (irr & IRR_SA1111) { + generic_handle_irq(IRQ_NEPONSET_SA1111); + } } } static void neponset_set_mctrl(struct uart_port *port, u_int mctrl) { - void __iomem *base = nep_base; - u_int mdm_ctl0; - - if (!base) - return; + u_int mdm_ctl0 = MDM_CTL_0; - mdm_ctl0 = readb_relaxed(base + MDM_CTL_0); if (port->mapbase == _Ser1UTCR0) { if (mctrl & TIOCM_RTS) mdm_ctl0 &= ~MDM_CTL0_RTS2; @@ -120,19 +106,14 @@ static void neponset_set_mctrl(struct uart_port *port, u_int mctrl) mdm_ctl0 |= MDM_CTL0_DTR1; } - writeb_relaxed(mdm_ctl0, base + MDM_CTL_0); + MDM_CTL_0 = mdm_ctl0; } static u_int neponset_get_mctrl(struct uart_port *port) { - void __iomem *base = nep_base; u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR; - u_int mdm_ctl1; + u_int mdm_ctl1 = MDM_CTL_1; - if (!base) - return ret; - - mdm_ctl1 = readb_relaxed(base + MDM_CTL_1); if (port->mapbase == _Ser1UTCR0) { if (mdm_ctl1 & MDM_CTL1_DCD2) ret &= ~TIOCM_CD; @@ -157,279 +138,209 @@ static struct sa1100_port_fns neponset_port_fns __devinitdata = { .get_mctrl = neponset_get_mctrl, }; -/* - * Install handler for Neponset IRQ. Note that we have to loop here - * since the ETHERNET and USAR IRQs are level based, and we need to - * ensure that the IRQ signal is deasserted before returning. This - * is rather unfortunate. - */ -static void neponset_irq_handler(unsigned int irq, struct irq_desc *desc) +static int __devinit neponset_probe(struct platform_device *dev) { - struct neponset_drvdata *d = irq_desc_get_handler_data(desc); - unsigned int irr; + sa1100_register_uart_fns(&neponset_port_fns); - while (1) { - /* - * Acknowledge the parent IRQ. - */ - desc->irq_data.chip->irq_ack(&desc->irq_data); + /* + * Install handler for GPIO25. + */ + irq_set_irq_type(IRQ_GPIO25, IRQ_TYPE_EDGE_RISING); + irq_set_chained_handler(IRQ_GPIO25, neponset_irq_handler); - /* - * Read the interrupt reason register. Let's have all - * active IRQ bits high. Note: there is a typo in the - * Neponset user's guide for the SA1111 IRR level. - */ - irr = readb_relaxed(d->base + IRR); - irr ^= IRR_ETHERNET | IRR_USAR; + /* + * We would set IRQ_GPIO25 to be a wake-up IRQ, but + * unfortunately something on the Neponset activates + * this IRQ on sleep (ethernet?) + */ +#if 0 + enable_irq_wake(IRQ_GPIO25); +#endif - if ((irr & (IRR_ETHERNET | IRR_USAR | IRR_SA1111)) == 0) - break; + /* + * Setup other Neponset IRQs. SA1111 will be done by the + * generic SA1111 code. + */ + irq_set_handler(IRQ_NEPONSET_SMC9196, handle_simple_irq); + set_irq_flags(IRQ_NEPONSET_SMC9196, IRQF_VALID | IRQF_PROBE); + irq_set_handler(IRQ_NEPONSET_USAR, handle_simple_irq); + set_irq_flags(IRQ_NEPONSET_USAR, IRQF_VALID | IRQF_PROBE); - /* - * Since there is no individual mask, we have to - * mask the parent IRQ. This is safe, since we'll - * recheck the register for any pending IRQs. - */ - if (irr & (IRR_ETHERNET | IRR_USAR)) { - desc->irq_data.chip->irq_mask(&desc->irq_data); + /* + * Disable GPIO 0/1 drivers so the buttons work on the module. + */ + NCR_0 = NCR_GP01_OFF; - /* - * Ack the interrupt now to prevent re-entering - * this neponset handler. Again, this is safe - * since we'll check the IRR register prior to - * leaving. - */ - desc->irq_data.chip->irq_ack(&desc->irq_data); + return 0; +} - if (irr & IRR_ETHERNET) - generic_handle_irq(d->irq_base + NEP_IRQ_SMC91X); +#ifdef CONFIG_PM - if (irr & IRR_USAR) - generic_handle_irq(d->irq_base + NEP_IRQ_USAR); +/* + * LDM power management. + */ +static unsigned int neponset_saved_state; - desc->irq_data.chip->irq_unmask(&desc->irq_data); - } +static int neponset_suspend(struct platform_device *dev, pm_message_t state) +{ + /* + * Save state. + */ + neponset_saved_state = NCR_0; - if (irr & IRR_SA1111) - generic_handle_irq(d->irq_base + NEP_IRQ_SA1111); - } + return 0; } -/* Yes, we really do not have any kind of masking or unmasking */ -static void nochip_noop(struct irq_data *irq) +static int neponset_resume(struct platform_device *dev) { + NCR_0 = neponset_saved_state; + + return 0; } -static struct irq_chip nochip = { - .name = "neponset", - .irq_ack = nochip_noop, - .irq_mask = nochip_noop, - .irq_unmask = nochip_noop, +#else +#define neponset_suspend NULL +#define neponset_resume NULL +#endif + +static struct platform_driver neponset_device_driver = { + .probe = neponset_probe, + .suspend = neponset_suspend, + .resume = neponset_resume, + .driver = { + .name = "neponset", + }, +}; + +static struct resource neponset_resources[] = { + [0] = { + .start = 0x10000000, + .end = 0x17ffffff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device neponset_device = { + .name = "neponset", + .id = 0, + .num_resources = ARRAY_SIZE(neponset_resources), + .resource = neponset_resources, +}; + +static struct resource sa1111_resources[] = { + [0] = { + .start = 0x40000000, + .end = 0x40001fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_NEPONSET_SA1111, + .end = IRQ_NEPONSET_SA1111, + .flags = IORESOURCE_IRQ, + }, }; static struct sa1111_platform_data sa1111_info = { .irq_base = IRQ_BOARD_END, - .disable_devs = SA1111_DEVID_PS2_MSE, }; -static int __devinit neponset_probe(struct platform_device *dev) -{ - struct neponset_drvdata *d; - struct resource *nep_res, *sa1111_res, *smc91x_res; - struct resource sa1111_resources[] = { - DEFINE_RES_MEM(0x40000000, SZ_8K), - { .flags = IORESOURCE_IRQ }, - }; - struct platform_device_info sa1111_devinfo = { - .parent = &dev->dev, - .name = "sa1111", - .id = 0, - .res = sa1111_resources, - .num_res = ARRAY_SIZE(sa1111_resources), - .data = &sa1111_info, - .size_data = sizeof(sa1111_info), - .dma_mask = 0xffffffffUL, - }; - struct resource smc91x_resources[] = { - DEFINE_RES_MEM_NAMED(SA1100_CS3_PHYS, - 0x02000000, "smc91x-regs"), - DEFINE_RES_MEM_NAMED(SA1100_CS3_PHYS + 0x02000000, - 0x02000000, "smc91x-attrib"), - { .flags = IORESOURCE_IRQ }, - }; - struct platform_device_info smc91x_devinfo = { - .parent = &dev->dev, - .name = "smc91x", - .id = 0, - .res = smc91x_resources, - .num_res = ARRAY_SIZE(smc91x_resources), - }; - int ret, irq; - - if (nep_base) - return -EBUSY; - - irq = ret = platform_get_irq(dev, 0); - if (ret < 0) - goto err_alloc; - - nep_res = platform_get_resource(dev, IORESOURCE_MEM, 0); - smc91x_res = platform_get_resource(dev, IORESOURCE_MEM, 1); - sa1111_res = platform_get_resource(dev, IORESOURCE_MEM, 2); - if (!nep_res || !smc91x_res || !sa1111_res) { - ret = -ENXIO; - goto err_alloc; - } - - d = kzalloc(sizeof(*d), GFP_KERNEL); - if (!d) { - ret = -ENOMEM; - goto err_alloc; - } +static u64 sa1111_dmamask = 0xffffffffUL; - d->base = ioremap(nep_res->start, SZ_4K); - if (!d->base) { - ret = -ENOMEM; - goto err_ioremap; - } +static struct platform_device sa1111_device = { + .name = "sa1111", + .id = 0, + .dev = { + .dma_mask = &sa1111_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = &sa1111_info, + }, + .num_resources = ARRAY_SIZE(sa1111_resources), + .resource = sa1111_resources, +}; - if (readb_relaxed(d->base + WHOAMI) != 0x11) { - dev_warn(&dev->dev, "Neponset board detected, but wrong ID: %02x\n", - readb_relaxed(d->base + WHOAMI)); - ret = -ENODEV; - goto err_id; - } +static struct resource smc91x_resources[] = { + [0] = { + .name = "smc91x-regs", + .start = SA1100_CS3_PHYS, + .end = SA1100_CS3_PHYS + 0x01ffffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_NEPONSET_SMC9196, + .end = IRQ_NEPONSET_SMC9196, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .name = "smc91x-attrib", + .start = SA1100_CS3_PHYS + 0x02000000, + .end = SA1100_CS3_PHYS + 0x03ffffff, + .flags = IORESOURCE_MEM, + }, +}; - ret = irq_alloc_descs(-1, IRQ_BOARD_START, NEP_IRQ_NR, -1); - if (ret <= 0) { - dev_err(&dev->dev, "unable to allocate %u irqs: %d\n", - NEP_IRQ_NR, ret); - if (ret == 0) - ret = -ENOMEM; - goto err_irq_alloc; - } +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; - d->irq_base = ret; +static struct platform_device *devices[] __initdata = { + &neponset_device, + &sa1111_device, + &smc91x_device, +}; - irq_set_chip_and_handler(d->irq_base + NEP_IRQ_SMC91X, &nochip, - handle_simple_irq); - set_irq_flags(d->irq_base + NEP_IRQ_SMC91X, IRQF_VALID | IRQF_PROBE); - irq_set_chip_and_handler(d->irq_base + NEP_IRQ_USAR, &nochip, - handle_simple_irq); - set_irq_flags(d->irq_base + NEP_IRQ_USAR, IRQF_VALID | IRQF_PROBE); - irq_set_chip(d->irq_base + NEP_IRQ_SA1111, &nochip); +extern void sa1110_mb_disable(void); - irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING); - irq_set_handler_data(irq, d); - irq_set_chained_handler(irq, neponset_irq_handler); +static int __init neponset_init(void) +{ + platform_driver_register(&neponset_device_driver); /* - * We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately - * something on the Neponset activates this IRQ on sleep (eth?) + * The Neponset is only present on the Assabet machine type. */ -#if 0 - enable_irq_wake(irq); -#endif + if (!machine_is_assabet()) + return -ENODEV; - dev_info(&dev->dev, "Neponset daughter board, providing IRQ%u-%u\n", - d->irq_base, d->irq_base + NEP_IRQ_NR - 1); - nep_base = d->base; - - sa1100_register_uart_fns(&neponset_port_fns); - - /* Ensure that the memory bus request/grant signals are setup */ + /* + * Ensure that the memory bus request/grant signals are setup, + * and the grant is held in its inactive state, whether or not + * we actually have a Neponset attached. + */ sa1110_mb_disable(); - /* Disable GPIO 0/1 drivers so the buttons work on the Assabet */ - writeb_relaxed(NCR_GP01_OFF, d->base + NCR_0); - - sa1111_resources[0].parent = sa1111_res; - sa1111_resources[1].start = d->irq_base + NEP_IRQ_SA1111; - sa1111_resources[1].end = d->irq_base + NEP_IRQ_SA1111; - d->sa1111 = platform_device_register_full(&sa1111_devinfo); - - smc91x_resources[0].parent = smc91x_res; - smc91x_resources[1].parent = smc91x_res; - smc91x_resources[2].start = d->irq_base + NEP_IRQ_SMC91X; - smc91x_resources[2].end = d->irq_base + NEP_IRQ_SMC91X; - d->smc91x = platform_device_register_full(&smc91x_devinfo); - - platform_set_drvdata(dev, d); - - return 0; - - err_irq_alloc: - err_id: - iounmap(d->base); - err_ioremap: - kfree(d); - err_alloc: - return ret; -} - -static int __devexit neponset_remove(struct platform_device *dev) -{ - struct neponset_drvdata *d = platform_get_drvdata(dev); - int irq = platform_get_irq(dev, 0); - - if (!IS_ERR(d->sa1111)) - platform_device_unregister(d->sa1111); - if (!IS_ERR(d->smc91x)) - platform_device_unregister(d->smc91x); - irq_set_chained_handler(irq, NULL); - irq_free_descs(d->irq_base, NEP_IRQ_NR); - nep_base = NULL; - iounmap(d->base); - kfree(d); - - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int neponset_suspend(struct device *dev) -{ - struct neponset_drvdata *d = dev_get_drvdata(dev); - - d->ncr0 = readb_relaxed(d->base + NCR_0); - d->mdm_ctl_0 = readb_relaxed(d->base + MDM_CTL_0); - - return 0; -} - -static int neponset_resume(struct device *dev) -{ - struct neponset_drvdata *d = dev_get_drvdata(dev); + if (!machine_has_neponset()) { + printk(KERN_DEBUG "Neponset expansion board not present\n"); + return -ENODEV; + } - writeb_relaxed(d->ncr0, d->base + NCR_0); - writeb_relaxed(d->mdm_ctl_0, d->base + MDM_CTL_0); + if (WHOAMI != 0x11) { + printk(KERN_WARNING "Neponset board detected, but " + "wrong ID: %02x\n", WHOAMI); + return -ENODEV; + } - return 0; + return platform_add_devices(devices, ARRAY_SIZE(devices)); } -static const struct dev_pm_ops neponset_pm_ops = { - .suspend_noirq = neponset_suspend, - .resume_noirq = neponset_resume, - .freeze_noirq = neponset_suspend, - .restore_noirq = neponset_resume, -}; -#define PM_OPS &neponset_pm_ops -#else -#define PM_OPS NULL -#endif +subsys_initcall(neponset_init); -static struct platform_driver neponset_device_driver = { - .probe = neponset_probe, - .remove = __devexit_p(neponset_remove), - .driver = { - .name = "neponset", - .owner = THIS_MODULE, - .pm = PM_OPS, - }, +static struct map_desc neponset_io_desc[] __initdata = { + { /* System Registers */ + .virtual = 0xf3000000, + .pfn = __phys_to_pfn(0x10000000), + .length = SZ_1M, + .type = MT_DEVICE + }, { /* SA-1111 */ + .virtual = 0xf4000000, + .pfn = __phys_to_pfn(0x40000000), + .length = SZ_1M, + .type = MT_DEVICE + } }; -static int __init neponset_init(void) +void __init neponset_map_io(void) { - return platform_driver_register(&neponset_device_driver); + iotable_init(neponset_io_desc, ARRAY_SIZE(neponset_io_desc)); } - -subsys_initcall(neponset_init); diff --git a/trunk/arch/arm/mach-sa1100/pci-nanoengine.c b/trunk/arch/arm/mach-sa1100/pci-nanoengine.c index 41bb018b3103..0d01ca788922 100644 --- a/trunk/arch/arm/mach-sa1100/pci-nanoengine.c +++ b/trunk/arch/arm/mach-sa1100/pci-nanoengine.c @@ -135,8 +135,12 @@ struct pci_bus * __init pci_nanoengine_scan_bus(int nr, struct pci_sys_data *sys &sys->resources); } -static struct resource pci_io_ports = - DEFINE_RES_IO_NAMED(0x400, 0x400, "PCI IO"); +static struct resource pci_io_ports = { + .name = "PCI IO", + .start = 0x400, + .end = 0x7FF, + .flags = IORESOURCE_IO, +}; static struct resource pci_non_prefetchable_memory = { .name = "PCI non-prefetchable", diff --git a/trunk/arch/arm/mach-sa1100/pleb.c b/trunk/arch/arm/mach-sa1100/pleb.c index ca5d33b6041a..9307df053533 100644 --- a/trunk/arch/arm/mach-sa1100/pleb.c +++ b/trunk/arch/arm/mach-sa1100/pleb.c @@ -37,9 +37,17 @@ #define IRQ_GPIO_ETH0_IRQ IRQ_GPIO21 static struct resource smc91x_resources[] = { - [0] = DEFINE_RES_MEM(PLEB_ETH0_P, 0x04000000), + [0] = { + .start = PLEB_ETH0_P, + .end = PLEB_ETH0_P | 0x03ffffff, + .flags = IORESOURCE_MEM, + }, #if 0 /* Autoprobe instead, to get rising/falling edge characteristic right */ - [1] = DEFINE_RES_IRQ(IRQ_GPIO_ETH0_IRQ), + [1] = { + .start = IRQ_GPIO_ETH0_IRQ, + .end = IRQ_GPIO_ETH0_IRQ, + .flags = IORESOURCE_IRQ, + }, #endif }; @@ -62,8 +70,16 @@ static struct platform_device *devices[] __initdata = { * the two SA1100 lowest chip select outputs. */ static struct resource pleb_flash_resources[] = { - [0] = DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_8M), - [1] = DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_8M), + [0] = { + .start = SA1100_CS0_PHYS, + .end = SA1100_CS0_PHYS + SZ_8M - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = SA1100_CS1_PHYS, + .end = SA1100_CS1_PHYS + SZ_8M - 1, + .flags = IORESOURCE_MEM, + } }; diff --git a/trunk/arch/arm/mach-sa1100/shannon.c b/trunk/arch/arm/mach-sa1100/shannon.c index 5fd615649847..318b2b766a0b 100644 --- a/trunk/arch/arm/mach-sa1100/shannon.c +++ b/trunk/arch/arm/mach-sa1100/shannon.c @@ -46,8 +46,11 @@ static struct flash_platform_data shannon_flash_data = { .nr_parts = ARRAY_SIZE(shannon_partitions), }; -static struct resource shannon_flash_resource = - DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_4M); +static struct resource shannon_flash_resource = { + .start = SA1100_CS0_PHYS, + .end = SA1100_CS0_PHYS + SZ_4M - 1, + .flags = IORESOURCE_MEM, +}; static struct mcp_plat_data shannon_mcp_data = { .mccr0 = MCCR0_ADM, diff --git a/trunk/arch/arm/mach-sa1100/simpad.c b/trunk/arch/arm/mach-sa1100/simpad.c index cdb9d197c092..e17c04d6e324 100644 --- a/trunk/arch/arm/mach-sa1100/simpad.c +++ b/trunk/arch/arm/mach-sa1100/simpad.c @@ -176,8 +176,15 @@ static struct flash_platform_data simpad_flash_data = { static struct resource simpad_flash_resources [] = { - DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_16M), - DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_16M), + { + .start = SA1100_CS0_PHYS, + .end = SA1100_CS0_PHYS + SZ_16M -1, + .flags = IORESOURCE_MEM, + }, { + .start = SA1100_CS1_PHYS, + .end = SA1100_CS1_PHYS + SZ_16M -1, + .flags = IORESOURCE_MEM, + } }; static struct mcp_plat_data simpad_mcp_data = { diff --git a/trunk/arch/arm/mach-sa1100/sleep.S b/trunk/arch/arm/mach-sa1100/sleep.S index 30cc6721665b..e8223315b442 100644 --- a/trunk/arch/arm/mach-sa1100/sleep.S +++ b/trunk/arch/arm/mach-sa1100/sleep.S @@ -26,36 +26,27 @@ * * Causes sa11x0 to enter sleep state * - * Must be aligned to a cacheline. */ - .balign 32 + ENTRY(sa1100_finish_suspend) @ disable clock switching mcr p15, 0, r1, c15, c2, 2 - ldr r6, =MDREFR - ldr r4, [r6] - orr r4, r4, #MDREFR_K1DB2 - ldr r5, =PPCR - - @ Pre-load __udelay into the I-cache - mov r0, #1 - bl __udelay - mov r0, r0 - - @ The following must all exist in a single cache line to - @ avoid accessing memory until this sequence is complete, - @ otherwise we occasionally hang. - - @ Adjust memory timing before lowering CPU clock - str r4, [r6] + @ Adjust memory timing before lowering CPU clock + @ Clock speed adjustment without changing memory timing makes + @ CPU hang in some cases + ldr r0, =MDREFR + ldr r1, [r0] + orr r1, r1, #MDREFR_K1DB2 + str r1, [r0] @ delay 90us and set CPU PLL to lowest speed @ fixes resume problem on high speed SA1110 mov r0, #90 bl __udelay + ldr r0, =PPCR mov r1, #0 - str r1, [r5] + str r1, [r0] mov r0, #90 bl __udelay @@ -94,10 +85,12 @@ ENTRY(sa1100_finish_suspend) bic r5, r5, #FMsk(MSC_RT) bic r5, r5, #FMsk(MSC_RT)<<16 + ldr r6, =MDREFR + ldr r7, [r6] - bic r7, r7, #0x0000FF00 - bic r7, r7, #0x000000F0 - orr r8, r7, #MDREFR_SLFRSH +bic r7, r7, #0x0000FF00 +bic r7, r7, #0x000000F0 +orr r8, r7, #MDREFR_SLFRSH ldr r9, =MDCNFG ldr r10, [r9] diff --git a/trunk/drivers/input/serio/sa1111ps2.c b/trunk/drivers/input/serio/sa1111ps2.c index 5ebabe3fc845..44fc8b4bcd81 100644 --- a/trunk/drivers/input/serio/sa1111ps2.c +++ b/trunk/drivers/input/serio/sa1111ps2.c @@ -24,26 +24,6 @@ #include -#define PS2CR 0x0000 -#define PS2STAT 0x0004 -#define PS2DATA 0x0008 -#define PS2CLKDIV 0x000c -#define PS2PRECNT 0x0010 - -#define PS2CR_ENA 0x08 -#define PS2CR_FKD 0x02 -#define PS2CR_FKC 0x01 - -#define PS2STAT_STP 0x0100 -#define PS2STAT_TXE 0x0080 -#define PS2STAT_TXB 0x0040 -#define PS2STAT_RXF 0x0020 -#define PS2STAT_RXB 0x0010 -#define PS2STAT_ENA 0x0008 -#define PS2STAT_RXP 0x0004 -#define PS2STAT_KBD 0x0002 -#define PS2STAT_KBC 0x0001 - struct ps2if { struct serio *io; struct sa1111_dev *dev; @@ -65,22 +45,22 @@ static irqreturn_t ps2_rxint(int irq, void *dev_id) struct ps2if *ps2if = dev_id; unsigned int scancode, flag, status; - status = sa1111_readl(ps2if->base + PS2STAT); + status = sa1111_readl(ps2if->base + SA1111_PS2STAT); while (status & PS2STAT_RXF) { if (status & PS2STAT_STP) - sa1111_writel(PS2STAT_STP, ps2if->base + PS2STAT); + sa1111_writel(PS2STAT_STP, ps2if->base + SA1111_PS2STAT); flag = (status & PS2STAT_STP ? SERIO_FRAME : 0) | (status & PS2STAT_RXP ? 0 : SERIO_PARITY); - scancode = sa1111_readl(ps2if->base + PS2DATA) & 0xff; + scancode = sa1111_readl(ps2if->base + SA1111_PS2DATA) & 0xff; if (hweight8(scancode) & 1) flag ^= SERIO_PARITY; serio_interrupt(ps2if->io, scancode, flag); - status = sa1111_readl(ps2if->base + PS2STAT); + status = sa1111_readl(ps2if->base + SA1111_PS2STAT); } return IRQ_HANDLED; @@ -95,12 +75,12 @@ static irqreturn_t ps2_txint(int irq, void *dev_id) unsigned int status; spin_lock(&ps2if->lock); - status = sa1111_readl(ps2if->base + PS2STAT); + status = sa1111_readl(ps2if->base + SA1111_PS2STAT); if (ps2if->head == ps2if->tail) { disable_irq_nosync(irq); /* done */ } else if (status & PS2STAT_TXE) { - sa1111_writel(ps2if->buf[ps2if->tail], ps2if->base + PS2DATA); + sa1111_writel(ps2if->buf[ps2if->tail], ps2if->base + SA1111_PS2DATA); ps2if->tail = (ps2if->tail + 1) & (sizeof(ps2if->buf) - 1); } spin_unlock(&ps2if->lock); @@ -123,8 +103,8 @@ static int ps2_write(struct serio *io, unsigned char val) /* * If the TX register is empty, we can go straight out. */ - if (sa1111_readl(ps2if->base + PS2STAT) & PS2STAT_TXE) { - sa1111_writel(val, ps2if->base + PS2DATA); + if (sa1111_readl(ps2if->base + SA1111_PS2STAT) & PS2STAT_TXE) { + sa1111_writel(val, ps2if->base + SA1111_PS2DATA); } else { if (ps2if->head == ps2if->tail) enable_irq(ps2if->dev->irq[1]); @@ -144,16 +124,13 @@ static int ps2_open(struct serio *io) struct ps2if *ps2if = io->port_data; int ret; - ret = sa1111_enable_device(ps2if->dev); - if (ret) - return ret; + sa1111_enable_device(ps2if->dev); ret = request_irq(ps2if->dev->irq[0], ps2_rxint, 0, SA1111_DRIVER_NAME(ps2if->dev), ps2if); if (ret) { printk(KERN_ERR "sa1111ps2: could not allocate IRQ%d: %d\n", ps2if->dev->irq[0], ret); - sa1111_disable_device(ps2if->dev); return ret; } @@ -163,7 +140,6 @@ static int ps2_open(struct serio *io) printk(KERN_ERR "sa1111ps2: could not allocate IRQ%d: %d\n", ps2if->dev->irq[1], ret); free_irq(ps2if->dev->irq[0], ps2if); - sa1111_disable_device(ps2if->dev); return ret; } @@ -171,7 +147,7 @@ static int ps2_open(struct serio *io) enable_irq_wake(ps2if->dev->irq[0]); - sa1111_writel(PS2CR_ENA, ps2if->base + PS2CR); + sa1111_writel(PS2CR_ENA, ps2if->base + SA1111_PS2CR); return 0; } @@ -179,7 +155,7 @@ static void ps2_close(struct serio *io) { struct ps2if *ps2if = io->port_data; - sa1111_writel(0, ps2if->base + PS2CR); + sa1111_writel(0, ps2if->base + SA1111_PS2CR); disable_irq_wake(ps2if->dev->irq[0]); @@ -199,7 +175,7 @@ static void __devinit ps2_clear_input(struct ps2if *ps2if) int maxread = 100; while (maxread--) { - if ((sa1111_readl(ps2if->base + PS2DATA) & 0xff) == 0xff) + if ((sa1111_readl(ps2if->base + SA1111_PS2DATA) & 0xff) == 0xff) break; } } @@ -209,11 +185,11 @@ static unsigned int __devinit ps2_test_one(struct ps2if *ps2if, { unsigned int val; - sa1111_writel(PS2CR_ENA | mask, ps2if->base + PS2CR); + sa1111_writel(PS2CR_ENA | mask, ps2if->base + SA1111_PS2CR); udelay(2); - val = sa1111_readl(ps2if->base + PS2STAT); + val = sa1111_readl(ps2if->base + SA1111_PS2STAT); return val & (PS2STAT_KBC | PS2STAT_KBD); } @@ -244,7 +220,7 @@ static int __devinit ps2_test(struct ps2if *ps2if) ret = -ENODEV; } - sa1111_writel(0, ps2if->base + PS2CR); + sa1111_writel(0, ps2if->base + SA1111_PS2CR); return ret; } @@ -298,8 +274,8 @@ static int __devinit ps2_probe(struct sa1111_dev *dev) sa1111_enable_device(ps2if->dev); /* Incoming clock is 8MHz */ - sa1111_writel(0, ps2if->base + PS2CLKDIV); - sa1111_writel(127, ps2if->base + PS2PRECNT); + sa1111_writel(0, ps2if->base + SA1111_PS2CLKDIV); + sa1111_writel(127, ps2if->base + SA1111_PS2PRECNT); /* * Flush any pending input. @@ -354,7 +330,6 @@ static int __devexit ps2_remove(struct sa1111_dev *dev) static struct sa1111_driver ps2_driver = { .drv = { .name = "sa1111-ps2", - .owner = THIS_MODULE, }, .devid = SA1111_DEVID_PS2, .probe = ps2_probe, diff --git a/trunk/drivers/net/ethernet/smsc/smc91x.c b/trunk/drivers/net/ethernet/smsc/smc91x.c index 0dba0501b712..64ad3ed74495 100644 --- a/trunk/drivers/net/ethernet/smsc/smc91x.c +++ b/trunk/drivers/net/ethernet/smsc/smc91x.c @@ -2281,7 +2281,7 @@ static int __devinit smc_drv_probe(struct platform_device *pdev) if (ret) goto out_release_io; #if defined(CONFIG_SA1100_ASSABET) - neponset_ncr_set(NCR_ENET_OSC_EN); + NCR_0 |= NCR_ENET_OSC_EN; #endif platform_set_drvdata(pdev, ndev); ret = smc_enable_device(pdev); diff --git a/trunk/drivers/net/irda/sa1100_ir.c b/trunk/drivers/net/irda/sa1100_ir.c index da2705061a60..751f2a9f283b 100644 --- a/trunk/drivers/net/irda/sa1100_ir.c +++ b/trunk/drivers/net/irda/sa1100_ir.c @@ -15,7 +15,7 @@ * This driver takes one kernel command line parameter, sa1100ir=, with * the following options: * max_rate:baudrate - set the maximum baud rate - * power_leve:level - set the transmitter power level + * power_level:level - set the transmitter power level * tx_lpm:0|1 - set transmit low power mode */ #include diff --git a/trunk/drivers/pcmcia/sa1100_neponset.c b/trunk/drivers/pcmcia/sa1100_neponset.c index 4300a7fb3edb..c95639b5f2a0 100644 --- a/trunk/drivers/pcmcia/sa1100_neponset.c +++ b/trunk/drivers/pcmcia/sa1100_neponset.c @@ -94,7 +94,12 @@ neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_sta ret = sa1111_pcmcia_configure_socket(skt, state); if (ret == 0) { - neponset_ncr_frob(ncr_mask, ncr_set); + unsigned long flags; + + local_irq_save(flags); + NCR_0 = (NCR_0 & ~ncr_mask) | ncr_set; + + local_irq_restore(flags); sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set); } diff --git a/trunk/drivers/pcmcia/sa1111_generic.c b/trunk/drivers/pcmcia/sa1111_generic.c index 33568e18998b..27f2fe3b7fb4 100644 --- a/trunk/drivers/pcmcia/sa1111_generic.c +++ b/trunk/drivers/pcmcia/sa1111_generic.c @@ -22,40 +22,6 @@ #include "sa1111_generic.h" -/* - * These are offsets from the above base. - */ -#define PCCR 0x0000 -#define PCSSR 0x0004 -#define PCSR 0x0008 - -#define PCSR_S0_READY (1<<0) -#define PCSR_S1_READY (1<<1) -#define PCSR_S0_DETECT (1<<2) -#define PCSR_S1_DETECT (1<<3) -#define PCSR_S0_VS1 (1<<4) -#define PCSR_S0_VS2 (1<<5) -#define PCSR_S1_VS1 (1<<6) -#define PCSR_S1_VS2 (1<<7) -#define PCSR_S0_WP (1<<8) -#define PCSR_S1_WP (1<<9) -#define PCSR_S0_BVD1 (1<<10) -#define PCSR_S0_BVD2 (1<<11) -#define PCSR_S1_BVD1 (1<<12) -#define PCSR_S1_BVD2 (1<<13) - -#define PCCR_S0_RST (1<<0) -#define PCCR_S1_RST (1<<1) -#define PCCR_S0_FLT (1<<2) -#define PCCR_S1_FLT (1<<3) -#define PCCR_S0_PWAITEN (1<<4) -#define PCCR_S1_PWAITEN (1<<5) -#define PCCR_S0_PSE (1<<6) -#define PCCR_S1_PSE (1<<7) - -#define PCSSR_S0_SLEEP (1<<0) -#define PCSSR_S1_SLEEP (1<<1) - #define IDX_IRQ_S0_READY_NINT (0) #define IDX_IRQ_S0_CD_VALID (1) #define IDX_IRQ_S0_BVD1_STSCHG (2) @@ -83,7 +49,7 @@ static void sa1111_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) { struct sa1111_pcmcia_socket *s = to_skt(skt); - unsigned long status = sa1111_readl(s->dev->mapbase + PCSR); + unsigned long status = sa1111_readl(s->dev->mapbase + SA1111_PCSR); switch (skt->nr) { case 0: @@ -139,10 +105,10 @@ int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s pccr_set_mask |= PCCR_S0_FLT|PCCR_S1_FLT; local_irq_save(flags); - val = sa1111_readl(s->dev->mapbase + PCCR); + val = sa1111_readl(s->dev->mapbase + SA1111_PCCR); val &= ~pccr_skt_mask; val |= pccr_set_mask & pccr_skt_mask; - sa1111_writel(val, s->dev->mapbase + PCCR); + sa1111_writel(val, s->dev->mapbase + SA1111_PCCR); local_irq_restore(flags); return 0; @@ -197,18 +163,12 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops, static int pcmcia_probe(struct sa1111_dev *dev) { void __iomem *base; - int ret; - - ret = sa1111_enable_device(dev); - if (ret) - return ret; dev_set_drvdata(&dev->dev, NULL); - if (!request_mem_region(dev->res.start, 512, SA1111_DRIVER_NAME(dev))) { - sa1111_disable_device(dev); + if (!request_mem_region(dev->res.start, 512, + SA1111_DRIVER_NAME(dev))) return -EBUSY; - } base = dev->mapbase; @@ -221,8 +181,8 @@ static int pcmcia_probe(struct sa1111_dev *dev) /* * Initialise the suspend state. */ - sa1111_writel(PCSSR_S0_SLEEP | PCSSR_S1_SLEEP, base + PCSSR); - sa1111_writel(PCCR_S0_FLT | PCCR_S1_FLT, base + PCCR); + sa1111_writel(PCSSR_S0_SLEEP | PCSSR_S1_SLEEP, base + SA1111_PCSSR); + sa1111_writel(PCCR_S0_FLT | PCCR_S1_FLT, base + SA1111_PCCR); #ifdef CONFIG_SA1100_BADGE4 pcmcia_badge4_init(&dev->dev); @@ -252,7 +212,6 @@ static int __devexit pcmcia_remove(struct sa1111_dev *dev) } release_mem_region(dev->res.start, 512); - sa1111_disable_device(dev); return 0; } diff --git a/trunk/drivers/usb/host/ohci-sa1111.c b/trunk/drivers/usb/host/ohci-sa1111.c index e1004fb37bd9..4bde4f9821ba 100644 --- a/trunk/drivers/usb/host/ohci-sa1111.c +++ b/trunk/drivers/usb/host/ohci-sa1111.c @@ -16,115 +16,29 @@ #include #include #include +#include #include #ifndef CONFIG_SA1111 #error "This file is SA-1111 bus glue. CONFIG_SA1111 must be defined." #endif -#define USB_STATUS 0x0118 -#define USB_RESET 0x011c -#define USB_IRQTEST 0x0120 - -#define USB_RESET_FORCEIFRESET (1 << 0) -#define USB_RESET_FORCEHCRESET (1 << 1) -#define USB_RESET_CLKGENRESET (1 << 2) -#define USB_RESET_SIMSCALEDOWN (1 << 3) -#define USB_RESET_USBINTTEST (1 << 4) -#define USB_RESET_SLEEPSTBYEN (1 << 5) -#define USB_RESET_PWRSENSELOW (1 << 6) -#define USB_RESET_PWRCTRLLOW (1 << 7) - -#define USB_STATUS_IRQHCIRMTWKUP (1 << 7) -#define USB_STATUS_IRQHCIBUFFACC (1 << 8) -#define USB_STATUS_NIRQHCIM (1 << 9) -#define USB_STATUS_NHCIMFCLR (1 << 10) -#define USB_STATUS_USBPWRSENSE (1 << 11) +extern int usb_disabled(void); -#if 0 -static void dump_hci_status(struct usb_hcd *hcd, const char *label) -{ - unsigned long status = sa1111_readl(hcd->regs + USB_STATUS); - - dbg("%s USB_STATUS = { %s%s%s%s%s}", label, - ((status & USB_STATUS_IRQHCIRMTWKUP) ? "IRQHCIRMTWKUP " : ""), - ((status & USB_STATUS_IRQHCIBUFFACC) ? "IRQHCIBUFFACC " : ""), - ((status & USB_STATUS_NIRQHCIM) ? "" : "IRQHCIM "), - ((status & USB_STATUS_NHCIMFCLR) ? "" : "HCIMFCLR "), - ((status & USB_STATUS_USBPWRSENSE) ? "USBPWRSENSE " : "")); -} -#endif +/*-------------------------------------------------------------------------*/ -static int ohci_sa1111_reset(struct usb_hcd *hcd) +static void sa1111_start_hc(struct sa1111_dev *dev) { - struct ohci_hcd *ohci = hcd_to_ohci(hcd); - - ohci_hcd_init(ohci); - return ohci_init(ohci); -} + unsigned int usb_rst = 0; -static int __devinit ohci_sa1111_start(struct usb_hcd *hcd) -{ - struct ohci_hcd *ohci = hcd_to_ohci(hcd); - int ret; + printk(KERN_DEBUG "%s: starting SA-1111 OHCI USB Controller\n", + __FILE__); - ret = ohci_run(ohci); - if (ret < 0) { - ohci_err(ohci, "can't start\n"); - ohci_stop(hcd); +#ifdef CONFIG_SA1100_BADGE4 + if (machine_is_badge4()) { + badge4_set_5V(BADGE4_5V_USB, 1); } - return ret; -} - -static const struct hc_driver ohci_sa1111_hc_driver = { - .description = hcd_name, - .product_desc = "SA-1111 OHCI", - .hcd_priv_size = sizeof(struct ohci_hcd), - - /* - * generic hardware linkage - */ - .irq = ohci_irq, - .flags = HCD_USB11 | HCD_MEMORY, - - /* - * basic lifecycle operations - */ - .reset = ohci_sa1111_reset, - .start = ohci_sa1111_start, - .stop = ohci_stop, - .shutdown = ohci_shutdown, - - /* - * managing i/o requests and associated device resources - */ - .urb_enqueue = ohci_urb_enqueue, - .urb_dequeue = ohci_urb_dequeue, - .endpoint_disable = ohci_endpoint_disable, - - /* - * scheduling support - */ - .get_frame_number = ohci_get_frame, - - /* - * root hub support - */ - .hub_status_data = ohci_hub_status_data, - .hub_control = ohci_hub_control, -#ifdef CONFIG_PM - .bus_suspend = ohci_bus_suspend, - .bus_resume = ohci_bus_resume, #endif - .start_port_reset = ohci_start_port_reset, -}; - -static int sa1111_start_hc(struct sa1111_dev *dev) -{ - unsigned int usb_rst = 0; - int ret; - - dev_dbg(&dev->dev, "starting SA-1111 OHCI USB Controller\n"); if (machine_is_xp860() || machine_has_neponset() || @@ -137,121 +51,220 @@ static int sa1111_start_hc(struct sa1111_dev *dev) * host controller in reset. */ sa1111_writel(usb_rst | USB_RESET_FORCEIFRESET | USB_RESET_FORCEHCRESET, - dev->mapbase + USB_RESET); + dev->mapbase + SA1111_USB_RESET); /* * Now, carefully enable the USB clock, and take * the USB host controller out of reset. */ - ret = sa1111_enable_device(dev); - if (ret == 0) { - udelay(11); - sa1111_writel(usb_rst, dev->mapbase + USB_RESET); - } - - return ret; + sa1111_enable_device(dev); + udelay(11); + sa1111_writel(usb_rst, dev->mapbase + SA1111_USB_RESET); } static void sa1111_stop_hc(struct sa1111_dev *dev) { unsigned int usb_rst; - - dev_dbg(&dev->dev, "stopping SA-1111 OHCI USB Controller\n"); + printk(KERN_DEBUG "%s: stopping SA-1111 OHCI USB Controller\n", + __FILE__); /* * Put the USB host controller into reset. */ - usb_rst = sa1111_readl(dev->mapbase + USB_RESET); + usb_rst = sa1111_readl(dev->mapbase + SA1111_USB_RESET); sa1111_writel(usb_rst | USB_RESET_FORCEIFRESET | USB_RESET_FORCEHCRESET, - dev->mapbase + USB_RESET); + dev->mapbase + SA1111_USB_RESET); /* * Stop the USB clock. */ sa1111_disable_device(dev); + +#ifdef CONFIG_SA1100_BADGE4 + if (machine_is_badge4()) { + /* Disable power to the USB bus */ + badge4_set_5V(BADGE4_5V_USB, 0); + } +#endif +} + + +/*-------------------------------------------------------------------------*/ + +#if 0 +static void dump_hci_status(struct usb_hcd *hcd, const char *label) +{ + unsigned long status = sa1111_readl(hcd->regs + SA1111_USB_STATUS); + + dbg ("%s USB_STATUS = { %s%s%s%s%s}", label, + ((status & USB_STATUS_IRQHCIRMTWKUP) ? "IRQHCIRMTWKUP " : ""), + ((status & USB_STATUS_IRQHCIBUFFACC) ? "IRQHCIBUFFACC " : ""), + ((status & USB_STATUS_NIRQHCIM) ? "" : "IRQHCIM "), + ((status & USB_STATUS_NHCIMFCLR) ? "" : "HCIMFCLR "), + ((status & USB_STATUS_USBPWRSENSE) ? "USBPWRSENSE " : "")); } +#endif + +/*-------------------------------------------------------------------------*/ + +/* configure so an HC device and id are always provided */ +/* always called with process context; sleeping is OK */ + /** - * ohci_hcd_sa1111_probe - initialize SA-1111-based HCDs + * usb_hcd_sa1111_probe - initialize SA-1111-based HCDs + * Context: !in_interrupt() * * Allocates basic resources for this USB host controller, and - * then invokes the start() method for the HCD associated with it. + * then invokes the start() method for the HCD associated with it + * through the hotplug entry's driver_data. + * + * Store this function in the HCD's struct pci_driver as probe(). */ -static int ohci_hcd_sa1111_probe(struct sa1111_dev *dev) +int usb_hcd_sa1111_probe (const struct hc_driver *driver, + struct sa1111_dev *dev) { struct usb_hcd *hcd; - int ret; + int retval; - if (usb_disabled()) - return -ENODEV; - - hcd = usb_create_hcd(&ohci_sa1111_hc_driver, &dev->dev, "sa1111"); + hcd = usb_create_hcd (driver, &dev->dev, "sa1111"); if (!hcd) return -ENOMEM; - hcd->rsrc_start = dev->res.start; hcd->rsrc_len = resource_size(&dev->res); if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { dbg("request_mem_region failed"); - ret = -EBUSY; + retval = -EBUSY; goto err1; } - hcd->regs = dev->mapbase; - ret = sa1111_start_hc(dev); - if (ret) - goto err2; + sa1111_start_hc(dev); + ohci_hcd_init(hcd_to_ohci(hcd)); - ret = usb_add_hcd(hcd, dev->irq[1], 0); - if (ret == 0) - return ret; + retval = usb_add_hcd(hcd, dev->irq[1], 0); + if (retval == 0) + return retval; sa1111_stop_hc(dev); - err2: release_mem_region(hcd->rsrc_start, hcd->rsrc_len); err1: usb_put_hcd(hcd); - return ret; + return retval; } + +/* may be called without controller electrically present */ +/* may be called with controller, bus, and devices active */ + /** - * ohci_hcd_sa1111_remove - shutdown processing for SA-1111-based HCDs + * usb_hcd_sa1111_remove - shutdown processing for SA-1111-based HCDs * @dev: USB Host Controller being removed + * Context: !in_interrupt() + * + * Reverses the effect of usb_hcd_sa1111_probe(), first invoking + * the HCD's stop() method. It is always called from a thread + * context, normally "rmmod", "apmd", or something similar. * - * Reverses the effect of ohci_hcd_sa1111_probe(), first invoking - * the HCD's stop() method. */ -static int ohci_hcd_sa1111_remove(struct sa1111_dev *dev) +void usb_hcd_sa1111_remove (struct usb_hcd *hcd, struct sa1111_dev *dev) { - struct usb_hcd *hcd = sa1111_get_drvdata(dev); - usb_remove_hcd(hcd); sa1111_stop_hc(dev); release_mem_region(hcd->rsrc_start, hcd->rsrc_len); usb_put_hcd(hcd); +} + +/*-------------------------------------------------------------------------*/ +static int __devinit +ohci_sa1111_start (struct usb_hcd *hcd) +{ + struct ohci_hcd *ohci = hcd_to_ohci (hcd); + int ret; + + if ((ret = ohci_init(ohci)) < 0) + return ret; + + if ((ret = ohci_run (ohci)) < 0) { + err ("can't start %s", hcd->self.bus_name); + ohci_stop (hcd); + return ret; + } return 0; } -static void ohci_hcd_sa1111_shutdown(struct sa1111_dev *dev) +/*-------------------------------------------------------------------------*/ + +static const struct hc_driver ohci_sa1111_hc_driver = { + .description = hcd_name, + .product_desc = "SA-1111 OHCI", + .hcd_priv_size = sizeof(struct ohci_hcd), + + /* + * generic hardware linkage + */ + .irq = ohci_irq, + .flags = HCD_USB11 | HCD_MEMORY, + + /* + * basic lifecycle operations + */ + .start = ohci_sa1111_start, + .stop = ohci_stop, + + /* + * managing i/o requests and associated device resources + */ + .urb_enqueue = ohci_urb_enqueue, + .urb_dequeue = ohci_urb_dequeue, + .endpoint_disable = ohci_endpoint_disable, + + /* + * scheduling support + */ + .get_frame_number = ohci_get_frame, + + /* + * root hub support + */ + .hub_status_data = ohci_hub_status_data, + .hub_control = ohci_hub_control, +#ifdef CONFIG_PM + .bus_suspend = ohci_bus_suspend, + .bus_resume = ohci_bus_resume, +#endif + .start_port_reset = ohci_start_port_reset, +}; + +/*-------------------------------------------------------------------------*/ + +static int ohci_hcd_sa1111_drv_probe(struct sa1111_dev *dev) +{ + int ret; + + if (usb_disabled()) + return -ENODEV; + + ret = usb_hcd_sa1111_probe(&ohci_sa1111_hc_driver, dev); + return ret; +} + +static int ohci_hcd_sa1111_drv_remove(struct sa1111_dev *dev) { struct usb_hcd *hcd = sa1111_get_drvdata(dev); - if (test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { - hcd->driver->shutdown(hcd); - sa1111_stop_hc(dev); - } + usb_hcd_sa1111_remove(hcd, dev); + return 0; } static struct sa1111_driver ohci_hcd_sa1111_driver = { .drv = { .name = "sa1111-ohci", - .owner = THIS_MODULE, }, .devid = SA1111_DEVID_USB, - .probe = ohci_hcd_sa1111_probe, - .remove = ohci_hcd_sa1111_remove, - .shutdown = ohci_hcd_sa1111_shutdown, + .probe = ohci_hcd_sa1111_drv_probe, + .remove = ohci_hcd_sa1111_drv_remove, }; +