Loading arch/arm/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -759,6 +759,7 @@ config ARCH_SA1100 select ARCH_REQUIRE_GPIOLIB select HAVE_IDE select NEED_MACH_MEMORY_H select SPARSE_IRQ help Support for StrongARM 11x0 based boards. Loading arch/arm/common/sa1111.c +185 −96 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ */ #include <linux/module.h> #include <linux/init.h> #include <linux/irq.h> #include <linux/kernel.h> #include <linux/delay.h> #include <linux/errno.h> Loading @@ -28,9 +29,8 @@ #include <linux/io.h> #include <mach/hardware.h> #include <asm/mach-types.h> #include <asm/irq.h> #include <asm/mach/irq.h> #include <asm/mach-types.h> #include <asm/sizes.h> #include <asm/hardware/sa1111.h> Loading Loading @@ -86,8 +86,10 @@ #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 __init sa1110_mb_enable(void); extern void sa1110_mb_enable(void); extern void sa1110_mb_disable(void); /* * We keep the following data for the overall SA1111. Note that the Loading @@ -104,6 +106,7 @@ 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 Loading @@ -118,6 +121,7 @@ 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]; }; Loading @@ -126,6 +130,7 @@ static struct sa1111_dev_info sa1111_devices[] = { { .offset = SA1111_USB, .skpcr_mask = SKPCR_UCLKEN, .dma = true, .devid = SA1111_DEVID_USB, .irq = { IRQ_USBPWR, Loading @@ -139,6 +144,7 @@ static struct sa1111_dev_info sa1111_devices[] = { { .offset = 0x0600, .skpcr_mask = SKPCR_I2SCLKEN | SKPCR_L3CLKEN, .dma = true, .devid = SA1111_DEVID_SAC, .irq = { AUDXMTDMADONEA, Loading @@ -155,7 +161,7 @@ static struct sa1111_dev_info sa1111_devices[] = { { .offset = SA1111_KBD, .skpcr_mask = SKPCR_PTCLKEN, .devid = SA1111_DEVID_PS2, .devid = SA1111_DEVID_PS2_KBD, .irq = { IRQ_TPRXINT, IRQ_TPTXINT Loading @@ -164,7 +170,7 @@ static struct sa1111_dev_info sa1111_devices[] = { { .offset = SA1111_MSE, .skpcr_mask = SKPCR_PMCLKEN, .devid = SA1111_DEVID_PS2, .devid = SA1111_DEVID_PS2_MSE, .irq = { IRQ_MSRXINT, IRQ_MSTXINT Loading Loading @@ -434,16 +440,28 @@ static struct irq_chip sa1111_high_chip = { .irq_set_wake = sa1111_wake_highirq, }; static void sa1111_setup_irq(struct sa1111 *sachip) static int sa1111_setup_irq(struct sa1111 *sachip, unsigned irq_base) { void __iomem *irqbase = sachip->base + SA1111_INTC; unsigned int irq; unsigned i, irq; int ret; /* * 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); Loading @@ -463,14 +481,16 @@ static void sa1111_setup_irq(struct sa1111 *sachip) sa1111_writel(~0, irqbase + SA1111_INTSTATCLR0); sa1111_writel(~0, irqbase + SA1111_INTSTATCLR1); for (irq = IRQ_GPAIN0; irq <= SSPROR; irq++) { for (i = IRQ_GPAIN0; i <= SSPROR; i++) { irq = sachip->irq_base + i; 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 (irq = AUDXMTDMADONEA; irq <= IRQ_S1_BVD1_STSCHG; irq++) { for (i = AUDXMTDMADONEA; i <= IRQ_S1_BVD1_STSCHG; i++) { irq = sachip->irq_base + i; irq_set_chip_and_handler(irq, &sa1111_high_chip, handle_edge_irq); irq_set_chip_data(irq, sachip); Loading @@ -483,6 +503,11 @@ static void sa1111_setup_irq(struct sa1111 *sachip) 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; } /* Loading Loading @@ -581,41 +606,10 @@ 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); } Loading @@ -624,67 +618,58 @@ 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 out; goto err_alloc; } 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, * propagate it down to the children. * If the parent device has a DMA mask associated with it, and * this child supports DMA, propagate it down to the children. */ if (sachip->dev->dma_mask) { if (info->dma && 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; } if (dev->dma_mask != 0xffffffffUL) { ret = dmabounce_register_dev(&dev->dev, 1024, 4096, sa1111_needs_bounce); ret = request_resource(parent, &dev->res); if (ret) { dev_err(&dev->dev, "SA1111: Failed to register" " with dmabounce\n"); device_unregister(&dev->dev); } } dev_err(sachip->dev, "failed to allocate resource for %s\n", dev->res.name); goto err_resource; } #endif out: 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: return ret; } Loading @@ -698,16 +683,21 @@ out: * 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; Loading @@ -727,6 +717,7 @@ __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; Loading Loading @@ -759,6 +750,16 @@ __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; Loading Loading @@ -789,24 +790,14 @@ __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 (machine_is_assabet() || machine_is_jornada720() || machine_is_badge4()) has_devs &= ~(1 << 4); else has_devs &= ~(1 << 1); if (pd) has_devs &= ~pd->disable_devs; for (i = 0; i < ARRAY_SIZE(sa1111_devices); i++) if (has_devs & (1 << i)) if (sa1111_devices[i].devid & has_devs) sa1111_init_one_child(sachip, mem, &sa1111_devices[i]); return 0; Loading @@ -824,7 +815,10 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) static int sa1111_remove_one(struct device *dev, void *data) { device_unregister(dev); struct sa1111_dev *sadev = SA1111_DEV(dev); device_del(&sadev->dev); release_resource(&sadev->res); put_device(&sadev->dev); return 0; } Loading @@ -846,6 +840,7 @@ 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); } Loading Loading @@ -904,6 +899,9 @@ 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); Loading @@ -919,13 +917,15 @@ 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; } Loading Loading @@ -966,6 +966,11 @@ 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! Loading Loading @@ -1053,6 +1058,7 @@ static struct platform_driver sa1111_device_driver = { .resume = sa1111_resume, .driver = { .name = "sa1111", .owner = THIS_MODULE, }, }; Loading Loading @@ -1238,17 +1244,24 @@ EXPORT_SYMBOL(sa1111_set_sleep_io); * sa1111_enable_device - enable an on-chip SA1111 function block * @sadev: SA1111 function block device to enable */ void sa1111_enable_device(struct sa1111_dev *sadev) int 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; } EXPORT_SYMBOL(sa1111_enable_device); /** Loading @@ -1265,6 +1278,9 @@ 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); Loading @@ -1279,7 +1295,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) Loading @@ -1304,6 +1320,14 @@ 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); Loading Loading @@ -1333,6 +1357,7 @@ 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); Loading @@ -1349,9 +1374,70 @@ 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; Loading @@ -1360,6 +1446,9 @@ 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); } Loading arch/arm/include/asm/hardware/sa1111.h +23 −133 Original line number Diff line number Diff line Loading @@ -132,33 +132,9 @@ #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 * Loading Loading @@ -327,22 +303,6 @@ * 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) Loading Loading @@ -425,106 +385,30 @@ #define SA1111_WAKEPOL0 0x0034 #define SA1111_WAKEPOL1 0x0038 /* * 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 */ /* PS/2 Trackpad and Mouse Interfaces */ #define SA1111_KBD 0x0a00 #define SA1111_MSE 0x0c00 /* * 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 */ /* PCMCIA Interface */ #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 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 #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) struct sa1111_dev { struct device dev; Loading @@ -548,6 +432,7 @@ 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) Loading @@ -555,9 +440,10 @@ struct sa1111_driver { #define SA1111_DRIVER_NAME(_sadev) ((_sadev)->dev.driver->name) /* * These frob the SKPCR register. * These frob the SKPCR register, and call platform specific * enable/disable functions. */ void sa1111_enable_device(struct sa1111_dev *); int sa1111_enable_device(struct sa1111_dev *); void sa1111_disable_device(struct sa1111_dev *); unsigned int sa1111_pll_clock(struct sa1111_dev *); Loading @@ -580,6 +466,10 @@ 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 */ arch/arm/mach-ebsa110/core.c +5 −8 Original line number Diff line number Diff line Loading @@ -30,10 +30,7 @@ #include <asm/mach/time.h> #define IRQ_MASK 0xfe000000 /* read */ #define IRQ_MSET 0xfe000000 /* write */ #define IRQ_STAT 0xff000000 /* read */ #define IRQ_MCLR 0xff000000 /* write */ #include "core.h" static void ebsa110_mask_irq(struct irq_data *d) { Loading Loading @@ -79,22 +76,22 @@ static struct map_desc ebsa110_io_desc[] __initdata = { { /* IRQ_STAT/IRQ_MCLR */ .virtual = IRQ_STAT, .pfn = __phys_to_pfn(TRICK4_PHYS), .length = PGDIR_SIZE, .length = TRICK4_SIZE, .type = MT_DEVICE }, { /* IRQ_MASK/IRQ_MSET */ .virtual = IRQ_MASK, .pfn = __phys_to_pfn(TRICK3_PHYS), .length = PGDIR_SIZE, .length = TRICK3_SIZE, .type = MT_DEVICE }, { /* SOFT_BASE */ .virtual = SOFT_BASE, .pfn = __phys_to_pfn(TRICK1_PHYS), .length = PGDIR_SIZE, .length = TRICK1_SIZE, .type = MT_DEVICE }, { /* PIT_BASE */ .virtual = PIT_BASE, .pfn = __phys_to_pfn(TRICK0_PHYS), .length = PGDIR_SIZE, .length = TRICK0_SIZE, .type = MT_DEVICE }, Loading arch/arm/mach-ebsa110/core.h 0 → 100644 +41 −0 Original line number Diff line number Diff line /* * Copyright (C) 1996-2000 Russell King. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This file contains the core hardware definitions of the EBSA-110. */ #ifndef CORE_H #define CORE_H /* Physical addresses/sizes */ #define ISAMEM_PHYS 0xe0000000 #define ISAMEM_SIZE 0x10000000 #define ISAIO_PHYS 0xf0000000 #define ISAIO_SIZE PGDIR_SIZE #define TRICK0_PHYS 0xf2000000 #define TRICK0_SIZE PGDIR_SIZE #define TRICK1_PHYS 0xf2400000 #define TRICK1_SIZE PGDIR_SIZE #define TRICK2_PHYS 0xf2800000 #define TRICK3_PHYS 0xf2c00000 #define TRICK3_SIZE PGDIR_SIZE #define TRICK4_PHYS 0xf3000000 #define TRICK4_SIZE PGDIR_SIZE #define TRICK5_PHYS 0xf3400000 #define TRICK6_PHYS 0xf3800000 #define TRICK7_PHYS 0xf3c00000 /* Virtual addresses */ #define PIT_BASE 0xfc000000 /* trick 0 */ #define SOFT_BASE 0xfd000000 /* trick 1 */ #define IRQ_MASK 0xfe000000 /* trick 3 - read */ #define IRQ_MSET 0xfe000000 /* trick 3 - write */ #define IRQ_STAT 0xff000000 /* trick 4 - read */ #define IRQ_MCLR 0xff000000 /* trick 4 - write */ #endif Loading
arch/arm/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -759,6 +759,7 @@ config ARCH_SA1100 select ARCH_REQUIRE_GPIOLIB select HAVE_IDE select NEED_MACH_MEMORY_H select SPARSE_IRQ help Support for StrongARM 11x0 based boards. Loading
arch/arm/common/sa1111.c +185 −96 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ */ #include <linux/module.h> #include <linux/init.h> #include <linux/irq.h> #include <linux/kernel.h> #include <linux/delay.h> #include <linux/errno.h> Loading @@ -28,9 +29,8 @@ #include <linux/io.h> #include <mach/hardware.h> #include <asm/mach-types.h> #include <asm/irq.h> #include <asm/mach/irq.h> #include <asm/mach-types.h> #include <asm/sizes.h> #include <asm/hardware/sa1111.h> Loading Loading @@ -86,8 +86,10 @@ #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 __init sa1110_mb_enable(void); extern void sa1110_mb_enable(void); extern void sa1110_mb_disable(void); /* * We keep the following data for the overall SA1111. Note that the Loading @@ -104,6 +106,7 @@ 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 Loading @@ -118,6 +121,7 @@ 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]; }; Loading @@ -126,6 +130,7 @@ static struct sa1111_dev_info sa1111_devices[] = { { .offset = SA1111_USB, .skpcr_mask = SKPCR_UCLKEN, .dma = true, .devid = SA1111_DEVID_USB, .irq = { IRQ_USBPWR, Loading @@ -139,6 +144,7 @@ static struct sa1111_dev_info sa1111_devices[] = { { .offset = 0x0600, .skpcr_mask = SKPCR_I2SCLKEN | SKPCR_L3CLKEN, .dma = true, .devid = SA1111_DEVID_SAC, .irq = { AUDXMTDMADONEA, Loading @@ -155,7 +161,7 @@ static struct sa1111_dev_info sa1111_devices[] = { { .offset = SA1111_KBD, .skpcr_mask = SKPCR_PTCLKEN, .devid = SA1111_DEVID_PS2, .devid = SA1111_DEVID_PS2_KBD, .irq = { IRQ_TPRXINT, IRQ_TPTXINT Loading @@ -164,7 +170,7 @@ static struct sa1111_dev_info sa1111_devices[] = { { .offset = SA1111_MSE, .skpcr_mask = SKPCR_PMCLKEN, .devid = SA1111_DEVID_PS2, .devid = SA1111_DEVID_PS2_MSE, .irq = { IRQ_MSRXINT, IRQ_MSTXINT Loading Loading @@ -434,16 +440,28 @@ static struct irq_chip sa1111_high_chip = { .irq_set_wake = sa1111_wake_highirq, }; static void sa1111_setup_irq(struct sa1111 *sachip) static int sa1111_setup_irq(struct sa1111 *sachip, unsigned irq_base) { void __iomem *irqbase = sachip->base + SA1111_INTC; unsigned int irq; unsigned i, irq; int ret; /* * 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); Loading @@ -463,14 +481,16 @@ static void sa1111_setup_irq(struct sa1111 *sachip) sa1111_writel(~0, irqbase + SA1111_INTSTATCLR0); sa1111_writel(~0, irqbase + SA1111_INTSTATCLR1); for (irq = IRQ_GPAIN0; irq <= SSPROR; irq++) { for (i = IRQ_GPAIN0; i <= SSPROR; i++) { irq = sachip->irq_base + i; 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 (irq = AUDXMTDMADONEA; irq <= IRQ_S1_BVD1_STSCHG; irq++) { for (i = AUDXMTDMADONEA; i <= IRQ_S1_BVD1_STSCHG; i++) { irq = sachip->irq_base + i; irq_set_chip_and_handler(irq, &sa1111_high_chip, handle_edge_irq); irq_set_chip_data(irq, sachip); Loading @@ -483,6 +503,11 @@ static void sa1111_setup_irq(struct sa1111 *sachip) 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; } /* Loading Loading @@ -581,41 +606,10 @@ 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); } Loading @@ -624,67 +618,58 @@ 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 out; goto err_alloc; } 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, * propagate it down to the children. * If the parent device has a DMA mask associated with it, and * this child supports DMA, propagate it down to the children. */ if (sachip->dev->dma_mask) { if (info->dma && 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; } if (dev->dma_mask != 0xffffffffUL) { ret = dmabounce_register_dev(&dev->dev, 1024, 4096, sa1111_needs_bounce); ret = request_resource(parent, &dev->res); if (ret) { dev_err(&dev->dev, "SA1111: Failed to register" " with dmabounce\n"); device_unregister(&dev->dev); } } dev_err(sachip->dev, "failed to allocate resource for %s\n", dev->res.name); goto err_resource; } #endif out: 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: return ret; } Loading @@ -698,16 +683,21 @@ out: * 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; Loading @@ -727,6 +717,7 @@ __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; Loading Loading @@ -759,6 +750,16 @@ __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; Loading Loading @@ -789,24 +790,14 @@ __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 (machine_is_assabet() || machine_is_jornada720() || machine_is_badge4()) has_devs &= ~(1 << 4); else has_devs &= ~(1 << 1); if (pd) has_devs &= ~pd->disable_devs; for (i = 0; i < ARRAY_SIZE(sa1111_devices); i++) if (has_devs & (1 << i)) if (sa1111_devices[i].devid & has_devs) sa1111_init_one_child(sachip, mem, &sa1111_devices[i]); return 0; Loading @@ -824,7 +815,10 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) static int sa1111_remove_one(struct device *dev, void *data) { device_unregister(dev); struct sa1111_dev *sadev = SA1111_DEV(dev); device_del(&sadev->dev); release_resource(&sadev->res); put_device(&sadev->dev); return 0; } Loading @@ -846,6 +840,7 @@ 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); } Loading Loading @@ -904,6 +899,9 @@ 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); Loading @@ -919,13 +917,15 @@ 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; } Loading Loading @@ -966,6 +966,11 @@ 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! Loading Loading @@ -1053,6 +1058,7 @@ static struct platform_driver sa1111_device_driver = { .resume = sa1111_resume, .driver = { .name = "sa1111", .owner = THIS_MODULE, }, }; Loading Loading @@ -1238,17 +1244,24 @@ EXPORT_SYMBOL(sa1111_set_sleep_io); * sa1111_enable_device - enable an on-chip SA1111 function block * @sadev: SA1111 function block device to enable */ void sa1111_enable_device(struct sa1111_dev *sadev) int 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; } EXPORT_SYMBOL(sa1111_enable_device); /** Loading @@ -1265,6 +1278,9 @@ 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); Loading @@ -1279,7 +1295,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) Loading @@ -1304,6 +1320,14 @@ 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); Loading Loading @@ -1333,6 +1357,7 @@ 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); Loading @@ -1349,9 +1374,70 @@ 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; Loading @@ -1360,6 +1446,9 @@ 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); } Loading
arch/arm/include/asm/hardware/sa1111.h +23 −133 Original line number Diff line number Diff line Loading @@ -132,33 +132,9 @@ #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 * Loading Loading @@ -327,22 +303,6 @@ * 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) Loading Loading @@ -425,106 +385,30 @@ #define SA1111_WAKEPOL0 0x0034 #define SA1111_WAKEPOL1 0x0038 /* * 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 */ /* PS/2 Trackpad and Mouse Interfaces */ #define SA1111_KBD 0x0a00 #define SA1111_MSE 0x0c00 /* * 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 */ /* PCMCIA Interface */ #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 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 #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) struct sa1111_dev { struct device dev; Loading @@ -548,6 +432,7 @@ 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) Loading @@ -555,9 +440,10 @@ struct sa1111_driver { #define SA1111_DRIVER_NAME(_sadev) ((_sadev)->dev.driver->name) /* * These frob the SKPCR register. * These frob the SKPCR register, and call platform specific * enable/disable functions. */ void sa1111_enable_device(struct sa1111_dev *); int sa1111_enable_device(struct sa1111_dev *); void sa1111_disable_device(struct sa1111_dev *); unsigned int sa1111_pll_clock(struct sa1111_dev *); Loading @@ -580,6 +466,10 @@ 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 */
arch/arm/mach-ebsa110/core.c +5 −8 Original line number Diff line number Diff line Loading @@ -30,10 +30,7 @@ #include <asm/mach/time.h> #define IRQ_MASK 0xfe000000 /* read */ #define IRQ_MSET 0xfe000000 /* write */ #define IRQ_STAT 0xff000000 /* read */ #define IRQ_MCLR 0xff000000 /* write */ #include "core.h" static void ebsa110_mask_irq(struct irq_data *d) { Loading Loading @@ -79,22 +76,22 @@ static struct map_desc ebsa110_io_desc[] __initdata = { { /* IRQ_STAT/IRQ_MCLR */ .virtual = IRQ_STAT, .pfn = __phys_to_pfn(TRICK4_PHYS), .length = PGDIR_SIZE, .length = TRICK4_SIZE, .type = MT_DEVICE }, { /* IRQ_MASK/IRQ_MSET */ .virtual = IRQ_MASK, .pfn = __phys_to_pfn(TRICK3_PHYS), .length = PGDIR_SIZE, .length = TRICK3_SIZE, .type = MT_DEVICE }, { /* SOFT_BASE */ .virtual = SOFT_BASE, .pfn = __phys_to_pfn(TRICK1_PHYS), .length = PGDIR_SIZE, .length = TRICK1_SIZE, .type = MT_DEVICE }, { /* PIT_BASE */ .virtual = PIT_BASE, .pfn = __phys_to_pfn(TRICK0_PHYS), .length = PGDIR_SIZE, .length = TRICK0_SIZE, .type = MT_DEVICE }, Loading
arch/arm/mach-ebsa110/core.h 0 → 100644 +41 −0 Original line number Diff line number Diff line /* * Copyright (C) 1996-2000 Russell King. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This file contains the core hardware definitions of the EBSA-110. */ #ifndef CORE_H #define CORE_H /* Physical addresses/sizes */ #define ISAMEM_PHYS 0xe0000000 #define ISAMEM_SIZE 0x10000000 #define ISAIO_PHYS 0xf0000000 #define ISAIO_SIZE PGDIR_SIZE #define TRICK0_PHYS 0xf2000000 #define TRICK0_SIZE PGDIR_SIZE #define TRICK1_PHYS 0xf2400000 #define TRICK1_SIZE PGDIR_SIZE #define TRICK2_PHYS 0xf2800000 #define TRICK3_PHYS 0xf2c00000 #define TRICK3_SIZE PGDIR_SIZE #define TRICK4_PHYS 0xf3000000 #define TRICK4_SIZE PGDIR_SIZE #define TRICK5_PHYS 0xf3400000 #define TRICK6_PHYS 0xf3800000 #define TRICK7_PHYS 0xf3c00000 /* Virtual addresses */ #define PIT_BASE 0xfc000000 /* trick 0 */ #define SOFT_BASE 0xfd000000 /* trick 1 */ #define IRQ_MASK 0xfe000000 /* trick 3 - read */ #define IRQ_MSET 0xfe000000 /* trick 3 - write */ #define IRQ_STAT 0xff000000 /* trick 4 - read */ #define IRQ_MCLR 0xff000000 /* trick 4 - write */ #endif