From 29c140b623ce2c55131c6d1c26a2f3e455723b81 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 3 Feb 2012 19:03:31 +0000 Subject: ARM: sa1111: fix memory request/grant setup on PM events We weren't re-enabling the memory request/grant signals on resume, causing DMA devices on the sa1111 to fail. Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/common/sa1111.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 61691cdbdcf2..c7bed309b3aa 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -87,7 +87,8 @@ #define IRQ_S0_BVD1_STSCHG (53) #define IRQ_S1_BVD1_STSCHG (54) -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 @@ -926,6 +927,10 @@ static int sa1111_suspend(struct platform_device *dev, pm_message_t state) spin_unlock_irqrestore(&sachip->lock, flags); +#ifdef CONFIG_ARCH_SA1100 + sa1110_mb_disable(); +#endif + return 0; } @@ -966,6 +971,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! -- cgit v1.2.1 From a22db0f38243f68957c89b1b9689a2064507bed6 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 3 Feb 2012 19:05:13 +0000 Subject: ARM: sa1111: fix PWM state on suspend We should not write to the SA1111 registers after setting the SLEEP bit. Moreover, the manual says that the PWM registers should be disabled before we enter sleep. So, move the clearing of these registers earlier in the suspend sequence. Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/common/sa1111.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index c7bed309b3aa..f0d9faadcc3f 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -905,6 +905,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); @@ -920,8 +923,6 @@ 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); -- cgit v1.2.1 From 4d5d11285c78691efb17148dfc3d56642bee6204 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 14 Jan 2012 16:09:22 +0000 Subject: ARM: sa1111: add sa1111 core driver .owner initializer Add an initializer for the struct device_driver .owner member. Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/common/sa1111.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index f0d9faadcc3f..957f6e3c4280 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -1064,6 +1064,7 @@ static struct platform_driver sa1111_device_driver = { .resume = sa1111_resume, .driver = { .name = "sa1111", + .owner = THIS_MODULE, }, }; -- cgit v1.2.1 From 1ebcd7654e4e391a36945c937c125995c737c446 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 26 Jan 2012 11:19:48 +0000 Subject: ARM: sa1111: add .owner initializer to sa1111 driver structures Add a .owner initializer to the sa1111 driver structures to allow allow the modules to be associated with their driver structures. Acked-by: Nicolas Pitre Signed-off-by: Russell King --- drivers/input/serio/sa1111ps2.c | 1 + drivers/usb/host/ohci-sa1111.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c index 44fc8b4bcd81..40ec545fbd40 100644 --- a/drivers/input/serio/sa1111ps2.c +++ b/drivers/input/serio/sa1111ps2.c @@ -330,6 +330,7 @@ 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/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c index 4bde4f9821ba..7d2aa62ea613 100644 --- a/drivers/usb/host/ohci-sa1111.c +++ b/drivers/usb/host/ohci-sa1111.c @@ -262,6 +262,7 @@ static int ohci_hcd_sa1111_drv_remove(struct sa1111_dev *dev) static struct sa1111_driver ohci_hcd_sa1111_driver = { .drv = { .name = "sa1111-ohci", + .owner = THIS_MODULE, }, .devid = SA1111_DEVID_USB, .probe = ohci_hcd_sa1111_drv_probe, -- cgit v1.2.1 From f03ecaa0aa3a3b74b9b9e8341cf7919516c902d5 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 16 Jan 2012 00:09:22 +0000 Subject: ARM: sa1111: finish "allow cascaded IRQs to be used by platforms" Commit 19851c58e680 (sa1111: allow cascaded IRQs to be used by platforms) moved the IRQ definitions to the .c file, and added an irq_base member to the private data structure. The inerrupt demultiplexer uses irq_base, but the interrupt setup code does not. Also, although the commit adds a private data structure to pass this data, it isn't even referenced, resulting in irq_base being zero. We also copied the IRQ numbers from the device info array into the actual devices, resulting in wrong interrupt numbers passed to the sub-devices. The net effect of this is that we always overwrite IRQs 0-54, even if they are allocated elsewhere in the system. Add the code necessary to setup the private irq_base, and use it in the IRQ setup code. Make the SA-1111 probe fail with -EINVAL if there is no platform data provided. Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/common/sa1111.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 957f6e3c4280..d3a8f5e26487 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -438,7 +438,7 @@ static struct irq_chip sa1111_high_chip = { static void sa1111_setup_irq(struct sa1111 *sachip) { void __iomem *irqbase = sachip->base + SA1111_INTC; - unsigned int irq; + unsigned i, irq; /* * We're guaranteed that this region hasn't been taken. @@ -464,14 +464,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); @@ -625,6 +627,7 @@ 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); @@ -645,7 +648,9 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent, 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)); + + for (i = 0; i < ARRAY_SIZE(info->irq); i++) + dev->irq[i] = sachip->irq_base + info->irq[i]; ret = request_resource(parent, &dev->res); if (ret) { @@ -699,16 +704,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; @@ -730,6 +740,7 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) sachip->phys = mem->start; sachip->irq = irq; + sachip->irq_base = pd->irq_base; /* * Map the whole region. This also maps the -- cgit v1.2.1 From 36d312130228504a223de44739c807b0353248c1 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 24 Jan 2012 21:25:20 +0000 Subject: ARM: sa1111: implement support for sparse IRQs Implement the necessary allocation/freeing functionality to support sparse IRQs with the SA-1111 device. On non-sparse IRQ platforms, this allows us to dynamically allocate from within the available IRQ number space. Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/common/sa1111.c | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index d3a8f5e26487..b64a3360c8c2 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -16,6 +16,7 @@ */ #include #include +#include #include #include #include @@ -28,9 +29,8 @@ #include #include -#include -#include #include +#include #include #include @@ -86,6 +86,7 @@ #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); @@ -435,16 +436,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 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); @@ -486,6 +499,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; } /* @@ -740,7 +758,6 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) sachip->phys = mem->start; sachip->irq = irq; - sachip->irq_base = pd->irq_base; /* * Map the whole region. This also maps the @@ -771,6 +788,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; @@ -801,13 +828,6 @@ __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; @@ -858,6 +878,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); } -- cgit v1.2.1 From 6bd72f0562142ddae26a052cfc4e578ad6953d06 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 26 Jan 2012 11:01:18 +0000 Subject: ARM: sa1111: add shutdown hook to sa1111_driver structure Add a shutdown hook to the sa1111_driver structure to allow drivers to be notified of system reboots and shutdowns. Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/common/sa1111.c | 9 +++++++++ arch/arm/include/asm/hardware/sa1111.h | 1 + 2 files changed, 10 insertions(+) diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index b64a3360c8c2..b0f93628dcd7 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -1348,6 +1348,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); @@ -1377,6 +1385,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); diff --git a/arch/arm/include/asm/hardware/sa1111.h b/arch/arm/include/asm/hardware/sa1111.h index 92ed254c175b..29e320f6f85f 100644 --- a/arch/arm/include/asm/hardware/sa1111.h +++ b/arch/arm/include/asm/hardware/sa1111.h @@ -548,6 +548,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) -- cgit v1.2.1 From ae99ddbc976572194e8a68cb9ca1e27805ce30c7 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 26 Jan 2012 13:25:47 +0000 Subject: ARM: sa1111: add platform enable/disable functions Add platform hooks to be called when individual sa1111 devices are enabled and disabled. This will allow us to move some platform specifics out of the individual drivers. Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/common/sa1111.c | 22 +++++++++++++++++----- arch/arm/include/asm/hardware/sa1111.h | 8 ++++++-- drivers/input/serio/sa1111ps2.c | 6 +++++- drivers/pcmcia/sa1111_generic.c | 11 +++++++++-- drivers/usb/host/ohci-sa1111.c | 19 ++++++++++++++----- 5 files changed, 51 insertions(+), 15 deletions(-) diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index b0f93628dcd7..1366e82e6707 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -106,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 @@ -756,6 +757,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; @@ -1282,16 +1284,23 @@ 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; - 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); + 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); @@ -1309,6 +1318,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); diff --git a/arch/arm/include/asm/hardware/sa1111.h b/arch/arm/include/asm/hardware/sa1111.h index 29e320f6f85f..d54d781021c8 100644 --- a/arch/arm/include/asm/hardware/sa1111.h +++ b/arch/arm/include/asm/hardware/sa1111.h @@ -556,9 +556,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 *); @@ -581,6 +582,9 @@ 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 */ + void *data; + int (*enable)(void *, unsigned); + void (*disable)(void *, unsigned); }; #endif /* _ASM_ARCH_SA1111 */ diff --git a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c index 40ec545fbd40..ad7d23b5c6fe 100644 --- a/drivers/input/serio/sa1111ps2.c +++ b/drivers/input/serio/sa1111ps2.c @@ -124,13 +124,16 @@ static int ps2_open(struct serio *io) struct ps2if *ps2if = io->port_data; int ret; - sa1111_enable_device(ps2if->dev); + ret = sa1111_enable_device(ps2if->dev); + if (ret) + return ret; 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; } @@ -140,6 +143,7 @@ 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; } diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c index 27f2fe3b7fb4..0735c3e6a8b0 100644 --- a/drivers/pcmcia/sa1111_generic.c +++ b/drivers/pcmcia/sa1111_generic.c @@ -163,12 +163,18 @@ 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))) + if (!request_mem_region(dev->res.start, 512, SA1111_DRIVER_NAME(dev))) { + sa1111_disable_device(dev); return -EBUSY; + } base = dev->mapbase; @@ -212,6 +218,7 @@ 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/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c index 7d2aa62ea613..f61f4f90529e 100644 --- a/drivers/usb/host/ohci-sa1111.c +++ b/drivers/usb/host/ohci-sa1111.c @@ -27,9 +27,10 @@ extern int usb_disabled(void); /*-------------------------------------------------------------------------*/ -static void sa1111_start_hc(struct sa1111_dev *dev) +static int sa1111_start_hc(struct sa1111_dev *dev) { unsigned int usb_rst = 0; + int ret; printk(KERN_DEBUG "%s: starting SA-1111 OHCI USB Controller\n", __FILE__); @@ -57,9 +58,13 @@ static void sa1111_start_hc(struct sa1111_dev *dev) * Now, carefully enable the USB clock, and take * the USB host controller out of reset. */ - sa1111_enable_device(dev); - udelay(11); - sa1111_writel(usb_rst, dev->mapbase + SA1111_USB_RESET); + ret = sa1111_enable_device(dev); + if (ret == 0) { + udelay(11); + sa1111_writel(usb_rst, dev->mapbase + SA1111_USB_RESET); + } + + return ret; } static void sa1111_stop_hc(struct sa1111_dev *dev) @@ -140,7 +145,10 @@ int usb_hcd_sa1111_probe (const struct hc_driver *driver, } hcd->regs = dev->mapbase; - sa1111_start_hc(dev); + ret = sa1111_start_hc(dev); + if (ret) + goto err2; + ohci_hcd_init(hcd_to_ohci(hcd)); retval = usb_add_hcd(hcd, dev->irq[1], 0); @@ -148,6 +156,7 @@ int usb_hcd_sa1111_probe (const struct hc_driver *driver, return retval; sa1111_stop_hc(dev); + err2: release_mem_region(hcd->rsrc_start, hcd->rsrc_len); err1: usb_put_hcd(hcd); -- cgit v1.2.1 From 3259701cc2969ae16a0018d7e3a89f327fa23a6e Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 26 Jan 2012 13:28:35 +0000 Subject: ARM: sa11x0: badge4: move board specific ohci initialization to badge4.c Move the handling of the 5v supply into badge4.c, removing this board specific detail from the sa1111 ohci driver. Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/mach-sa1100/badge4.c | 15 +++++++++++++++ drivers/usb/host/ohci-sa1111.c | 14 -------------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c index b07a2c024cb7..d84924993bad 100644 --- a/arch/arm/mach-sa1100/badge4.c +++ b/arch/arm/mach-sa1100/badge4.c @@ -51,8 +51,23 @@ static struct resource sa1111_resources[] = { }, }; +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, + .enable = badge4_sa1111_enable, + .disable = badge4_sa1111_disable, }; static u64 sa1111_dmamask = 0xffffffffUL; diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c index f61f4f90529e..48300080433c 100644 --- a/drivers/usb/host/ohci-sa1111.c +++ b/drivers/usb/host/ohci-sa1111.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #ifndef CONFIG_SA1111 @@ -35,12 +34,6 @@ static int sa1111_start_hc(struct sa1111_dev *dev) printk(KERN_DEBUG "%s: starting SA-1111 OHCI USB Controller\n", __FILE__); -#ifdef CONFIG_SA1100_BADGE4 - if (machine_is_badge4()) { - badge4_set_5V(BADGE4_5V_USB, 1); - } -#endif - if (machine_is_xp860() || machine_has_neponset() || machine_is_pfs168() || @@ -84,13 +77,6 @@ static void sa1111_stop_hc(struct sa1111_dev *dev) * 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 } -- cgit v1.2.1 From e5c0fc4185c551c270868dcb6573604db2bc3171 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 25 Jan 2012 10:42:52 +0000 Subject: ARM: sa1111: change devid to be a bitmask Change the sa1111 device id to be a bitmask. This allows us to specify the actual device, while allowing a single driver to bind to both PS2 devices. Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/common/sa1111.c | 12 ++++++------ arch/arm/include/asm/hardware/sa1111.h | 20 +++++++++++--------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 1366e82e6707..4bdf1bb283dc 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -158,7 +158,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 @@ -167,7 +167,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 @@ -835,12 +835,12 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) has_devs = ~0; if (machine_is_assabet() || machine_is_jornada720() || machine_is_badge4()) - has_devs &= ~(1 << 4); + has_devs &= ~SA1111_DEVID_PS2_MSE; else - has_devs &= ~(1 << 1); + has_devs &= ~SA1111_DEVID_SAC; 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; @@ -1335,7 +1335,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) diff --git a/arch/arm/include/asm/hardware/sa1111.h b/arch/arm/include/asm/hardware/sa1111.h index d54d781021c8..37ad29d482f4 100644 --- a/arch/arm/include/asm/hardware/sa1111.h +++ b/arch/arm/include/asm/hardware/sa1111.h @@ -516,15 +516,17 @@ 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; -- cgit v1.2.1 From 07be45f57ebe037977c8033a008e9012617b1915 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 26 Jan 2012 13:34:21 +0000 Subject: ARM: sa1111: provide a generic way to prevent devices from registering Some platforms don't want certain devices to be registered, because, eg, the interface is not wired. Provide a way for platforms to prevent various devices from being registered via a devid bitmask in the platform data. Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/common/sa1111.c | 7 ++----- arch/arm/include/asm/hardware/sa1111.h | 1 + arch/arm/mach-pxa/lubbock.c | 1 + arch/arm/mach-sa1100/badge4.c | 1 + arch/arm/mach-sa1100/jornada720.c | 1 + arch/arm/mach-sa1100/neponset.c | 1 + 6 files changed, 7 insertions(+), 5 deletions(-) diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 4bdf1bb283dc..17694cf64aa6 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -833,11 +833,8 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq) g_sa1111 = sachip; has_devs = ~0; - if (machine_is_assabet() || machine_is_jornada720() || - machine_is_badge4()) - has_devs &= ~SA1111_DEVID_PS2_MSE; - else - has_devs &= ~SA1111_DEVID_SAC; + if (pd) + has_devs &= ~pd->disable_devs; for (i = 0; i < ARRAY_SIZE(sa1111_devices); i++) if (sa1111_devices[i].devid & has_devs) diff --git a/arch/arm/include/asm/hardware/sa1111.h b/arch/arm/include/asm/hardware/sa1111.h index 37ad29d482f4..74afe20fffff 100644 --- a/arch/arm/include/asm/hardware/sa1111.h +++ b/arch/arm/include/asm/hardware/sa1111.h @@ -584,6 +584,7 @@ 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); diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index 6ebd276aebeb..6bb3f47b1f14 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -223,6 +223,7 @@ 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/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c index d84924993bad..8fb80f02c2a9 100644 --- a/arch/arm/mach-sa1100/badge4.c +++ b/arch/arm/mach-sa1100/badge4.c @@ -66,6 +66,7 @@ static void badge4_sa1111_disable(void *data, unsigned devid) 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, }; diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c index ee121d6f0480..dcd6d026aa68 100644 --- a/arch/arm/mach-sa1100/jornada720.c +++ b/arch/arm/mach-sa1100/jornada720.c @@ -211,6 +211,7 @@ static struct resource sa1111_resources[] = { static struct sa1111_platform_data sa1111_info = { .irq_base = IRQ_BOARD_END, + .disable_devs = SA1111_DEVID_PS2_MSE, }; static u64 sa1111_dmamask = 0xffffffffUL; diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c index b4fa53a1427e..b40a7192f09f 100644 --- a/arch/arm/mach-sa1100/neponset.c +++ b/arch/arm/mach-sa1100/neponset.c @@ -242,6 +242,7 @@ static struct resource sa1111_resources[] = { static struct sa1111_platform_data sa1111_info = { .irq_base = IRQ_BOARD_END, + .disable_devs = SA1111_DEVID_PS2_MSE, }; static u64 sa1111_dmamask = 0xffffffffUL; -- cgit v1.2.1 From 6995f5b007c6b774e7d0c7528ced171145c03a09 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 16 Jan 2012 14:28:25 +0000 Subject: ARM: sa1111: delete unused physical GPIO register definitions Get rid of the unused GPIO register definitions - we access GPIO registers through the base + offset method, and having the phys address definitions is unnecessary duplication. Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/include/asm/hardware/sa1111.h | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/arch/arm/include/asm/hardware/sa1111.h b/arch/arm/include/asm/hardware/sa1111.h index 74afe20fffff..5ba2e13ed2b6 100644 --- a/arch/arm/include/asm/hardware/sa1111.h +++ b/arch/arm/include/asm/hardware/sa1111.h @@ -327,22 +327,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) -- cgit v1.2.1 From 4f8d9cae15b5b5c89ec17c8168215aa06a5c9b2c Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 16 Jan 2012 11:29:43 +0000 Subject: ARM: sa1111: move PS/2 interface register definitions to sa1111p2.c Move the PS/2 interface register definitions into the driver, rather than keeping them in a common location. Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/include/asm/hardware/sa1111.h | 39 +------------------------ drivers/input/serio/sa1111ps2.c | 52 +++++++++++++++++++++++----------- 2 files changed, 37 insertions(+), 54 deletions(-) diff --git a/arch/arm/include/asm/hardware/sa1111.h b/arch/arm/include/asm/hardware/sa1111.h index 5ba2e13ed2b6..dc15bf8ff39d 100644 --- a/arch/arm/include/asm/hardware/sa1111.h +++ b/arch/arm/include/asm/hardware/sa1111.h @@ -409,47 +409,10 @@ #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 * diff --git a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c index ad7d23b5c6fe..5ebabe3fc845 100644 --- a/drivers/input/serio/sa1111ps2.c +++ b/drivers/input/serio/sa1111ps2.c @@ -24,6 +24,26 @@ #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; @@ -45,22 +65,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 + SA1111_PS2STAT); + status = sa1111_readl(ps2if->base + PS2STAT); while (status & PS2STAT_RXF) { if (status & PS2STAT_STP) - sa1111_writel(PS2STAT_STP, ps2if->base + SA1111_PS2STAT); + sa1111_writel(PS2STAT_STP, ps2if->base + PS2STAT); flag = (status & PS2STAT_STP ? SERIO_FRAME : 0) | (status & PS2STAT_RXP ? 0 : SERIO_PARITY); - scancode = sa1111_readl(ps2if->base + SA1111_PS2DATA) & 0xff; + scancode = sa1111_readl(ps2if->base + PS2DATA) & 0xff; if (hweight8(scancode) & 1) flag ^= SERIO_PARITY; serio_interrupt(ps2if->io, scancode, flag); - status = sa1111_readl(ps2if->base + SA1111_PS2STAT); + status = sa1111_readl(ps2if->base + PS2STAT); } return IRQ_HANDLED; @@ -75,12 +95,12 @@ static irqreturn_t ps2_txint(int irq, void *dev_id) unsigned int status; spin_lock(&ps2if->lock); - status = sa1111_readl(ps2if->base + SA1111_PS2STAT); + status = sa1111_readl(ps2if->base + PS2STAT); if (ps2if->head == ps2if->tail) { disable_irq_nosync(irq); /* done */ } else if (status & PS2STAT_TXE) { - sa1111_writel(ps2if->buf[ps2if->tail], ps2if->base + SA1111_PS2DATA); + sa1111_writel(ps2if->buf[ps2if->tail], ps2if->base + PS2DATA); ps2if->tail = (ps2if->tail + 1) & (sizeof(ps2if->buf) - 1); } spin_unlock(&ps2if->lock); @@ -103,8 +123,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 + SA1111_PS2STAT) & PS2STAT_TXE) { - sa1111_writel(val, ps2if->base + SA1111_PS2DATA); + if (sa1111_readl(ps2if->base + PS2STAT) & PS2STAT_TXE) { + sa1111_writel(val, ps2if->base + PS2DATA); } else { if (ps2if->head == ps2if->tail) enable_irq(ps2if->dev->irq[1]); @@ -151,7 +171,7 @@ static int ps2_open(struct serio *io) enable_irq_wake(ps2if->dev->irq[0]); - sa1111_writel(PS2CR_ENA, ps2if->base + SA1111_PS2CR); + sa1111_writel(PS2CR_ENA, ps2if->base + PS2CR); return 0; } @@ -159,7 +179,7 @@ static void ps2_close(struct serio *io) { struct ps2if *ps2if = io->port_data; - sa1111_writel(0, ps2if->base + SA1111_PS2CR); + sa1111_writel(0, ps2if->base + PS2CR); disable_irq_wake(ps2if->dev->irq[0]); @@ -179,7 +199,7 @@ static void __devinit ps2_clear_input(struct ps2if *ps2if) int maxread = 100; while (maxread--) { - if ((sa1111_readl(ps2if->base + SA1111_PS2DATA) & 0xff) == 0xff) + if ((sa1111_readl(ps2if->base + PS2DATA) & 0xff) == 0xff) break; } } @@ -189,11 +209,11 @@ static unsigned int __devinit ps2_test_one(struct ps2if *ps2if, { unsigned int val; - sa1111_writel(PS2CR_ENA | mask, ps2if->base + SA1111_PS2CR); + sa1111_writel(PS2CR_ENA | mask, ps2if->base + PS2CR); udelay(2); - val = sa1111_readl(ps2if->base + SA1111_PS2STAT); + val = sa1111_readl(ps2if->base + PS2STAT); return val & (PS2STAT_KBC | PS2STAT_KBD); } @@ -224,7 +244,7 @@ static int __devinit ps2_test(struct ps2if *ps2if) ret = -ENODEV; } - sa1111_writel(0, ps2if->base + SA1111_PS2CR); + sa1111_writel(0, ps2if->base + PS2CR); return ret; } @@ -278,8 +298,8 @@ static int __devinit ps2_probe(struct sa1111_dev *dev) sa1111_enable_device(ps2if->dev); /* Incoming clock is 8MHz */ - sa1111_writel(0, ps2if->base + SA1111_PS2CLKDIV); - sa1111_writel(127, ps2if->base + SA1111_PS2PRECNT); + sa1111_writel(0, ps2if->base + PS2CLKDIV); + sa1111_writel(127, ps2if->base + PS2PRECNT); /* * Flush any pending input. -- cgit v1.2.1 From ea8c00ac18198763bceb7ca53d26df4aa8d3c414 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 16 Jan 2012 11:32:09 +0000 Subject: ARM: sa1111: move PCMCIA interface register definitions to sa1111_generic.c Move the PCMCIA interface register definitions into the driver, rather than keeping them in a common place. Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/include/asm/hardware/sa1111.h | 45 ++-------------------------------- drivers/pcmcia/sa1111_generic.c | 44 +++++++++++++++++++++++++++++---- 2 files changed, 41 insertions(+), 48 deletions(-) diff --git a/arch/arm/include/asm/hardware/sa1111.h b/arch/arm/include/asm/hardware/sa1111.h index dc15bf8ff39d..29e3e5673883 100644 --- a/arch/arm/include/asm/hardware/sa1111.h +++ b/arch/arm/include/asm/hardware/sa1111.h @@ -413,50 +413,9 @@ #define SA1111_KBD 0x0a00 #define SA1111_MSE 0x0c00 -/* - * PCMCIA Interface - * - * Registers - * PCSR Status Register - * PCCR Control Register - * PCSSR Sleep State Register - */ +/* PCMCIA Interface */ +#define SA1111_PCMCIA 0x1600 -#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) diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c index 0735c3e6a8b0..33568e18998b 100644 --- a/drivers/pcmcia/sa1111_generic.c +++ b/drivers/pcmcia/sa1111_generic.c @@ -22,6 +22,40 @@ #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) @@ -49,7 +83,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 + SA1111_PCSR); + unsigned long status = sa1111_readl(s->dev->mapbase + PCSR); switch (skt->nr) { case 0: @@ -105,10 +139,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 + SA1111_PCCR); + val = sa1111_readl(s->dev->mapbase + PCCR); val &= ~pccr_skt_mask; val |= pccr_set_mask & pccr_skt_mask; - sa1111_writel(val, s->dev->mapbase + SA1111_PCCR); + sa1111_writel(val, s->dev->mapbase + PCCR); local_irq_restore(flags); return 0; @@ -187,8 +221,8 @@ static int pcmcia_probe(struct sa1111_dev *dev) /* * Initialise the suspend state. */ - sa1111_writel(PCSSR_S0_SLEEP | PCSSR_S1_SLEEP, base + SA1111_PCSSR); - sa1111_writel(PCCR_S0_FLT | PCCR_S1_FLT, base + SA1111_PCCR); + sa1111_writel(PCSSR_S0_SLEEP | PCSSR_S1_SLEEP, base + PCSSR); + sa1111_writel(PCCR_S0_FLT | PCCR_S1_FLT, base + PCCR); #ifdef CONFIG_SA1100_BADGE4 pcmcia_badge4_init(&dev->dev); -- cgit v1.2.1 From 2213536d78a2ed96e870396b06ee53f4a54a1e42 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 16 Jan 2012 11:37:03 +0000 Subject: ARM: sa1111: move USB interface register definitions to ohci-sa1111.c Move the USB interface register definitions into the driver, rather than keeping them in a common place. Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/include/asm/hardware/sa1111.h | 26 +------------------------- drivers/usb/host/ohci-sa1111.c | 29 ++++++++++++++++++++++++----- 2 files changed, 25 insertions(+), 30 deletions(-) diff --git a/arch/arm/include/asm/hardware/sa1111.h b/arch/arm/include/asm/hardware/sa1111.h index 29e3e5673883..7c2bbc7f0be1 100644 --- a/arch/arm/include/asm/hardware/sa1111.h +++ b/arch/arm/include/asm/hardware/sa1111.h @@ -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 * diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c index 48300080433c..585e53eabff6 100644 --- a/drivers/usb/host/ohci-sa1111.c +++ b/drivers/usb/host/ohci-sa1111.c @@ -22,6 +22,25 @@ #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); /*-------------------------------------------------------------------------*/ @@ -45,7 +64,7 @@ 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 + SA1111_USB_RESET); + dev->mapbase + USB_RESET); /* * Now, carefully enable the USB clock, and take @@ -54,7 +73,7 @@ static int sa1111_start_hc(struct sa1111_dev *dev) ret = sa1111_enable_device(dev); if (ret == 0) { udelay(11); - sa1111_writel(usb_rst, dev->mapbase + SA1111_USB_RESET); + sa1111_writel(usb_rst, dev->mapbase + USB_RESET); } return ret; @@ -69,9 +88,9 @@ static void sa1111_stop_hc(struct sa1111_dev *dev) /* * Put the USB host controller into reset. */ - usb_rst = sa1111_readl(dev->mapbase + SA1111_USB_RESET); + usb_rst = sa1111_readl(dev->mapbase + USB_RESET); sa1111_writel(usb_rst | USB_RESET_FORCEIFRESET | USB_RESET_FORCEHCRESET, - dev->mapbase + SA1111_USB_RESET); + dev->mapbase + USB_RESET); /* * Stop the USB clock. @@ -85,7 +104,7 @@ static void sa1111_stop_hc(struct sa1111_dev *dev) #if 0 static void dump_hci_status(struct usb_hcd *hcd, const char *label) { - unsigned long status = sa1111_readl(hcd->regs + SA1111_USB_STATUS); + unsigned long status = sa1111_readl(hcd->regs + USB_STATUS); dbg ("%s USB_STATUS = { %s%s%s%s%s}", label, ((status & USB_STATUS_IRQHCIRMTWKUP) ? "IRQHCIRMTWKUP " : ""), -- cgit v1.2.1 From 09a2ba2fa0eba3da747db860ac1c8c0956665316 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 29 Jan 2012 09:31:31 +0000 Subject: ARM: sa1111: register sa1111 devices with dmabounce in bus notifier Use the bus notifier to register sa1111 devices with dmabounce, rather than after the device has been registered, potentially racing with driver binding. Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/common/sa1111.c | 129 +++++++++++++++++++++++++++-------------------- 1 file changed, 74 insertions(+), 55 deletions(-) diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 17694cf64aa6..7b4351b28a5e 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -603,36 +603,6 @@ 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); @@ -660,7 +630,6 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent, 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); @@ -671,6 +640,16 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent, for (i = 0; i < ARRAY_SIZE(info->irq); i++) dev->irq[i] = sachip->irq_base + info->irq[i]; + /* + * If the parent device has a DMA mask associated with it, + * propagate it down to the children. + */ + 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) { printk("SA1111: failed to allocate resource for %s\n", @@ -680,36 +659,12 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent, goto out; } - 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 (sachip->dev->dma_mask) { - dev->dma_mask = *sachip->dev->dma_mask; - dev->dev.dma_mask = &dev->dma_mask; - - 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 -out: return ret; } @@ -1411,9 +1366,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; @@ -1422,6 +1438,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); } -- cgit v1.2.1 From 21d1c7702e74337717a1133fe8665f6591768581 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 29 Jan 2012 10:22:49 +0000 Subject: ARM: sa1111: only setup DMA for DMA capable devices It's pointless registering the PS/2 interfaces with the dmabounce code when there's no DMA support for these in hardware, so only setup the DMA masks for two subdevices which support DMA - the OHCI and SAC. Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/common/sa1111.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 7b4351b28a5e..d78499f84bd1 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -121,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]; }; @@ -129,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, @@ -142,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, @@ -641,10 +644,10 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent, dev->irq[i] = sachip->irq_base + info->irq[i]; /* - * 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; -- cgit v1.2.1 From 924e1d4910a1f7d53f949a92a5d7793e572bb21d Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 29 Jan 2012 10:20:00 +0000 Subject: ARM: sa1111: cleanup sub-device registration and unregistration Move the releasing of resources out of the release function - this allows a cleaner and more conventional arrangement of the registration failure paths and a saner unregistration process for these devices. Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/common/sa1111.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index d78499f84bd1..8d86338a54ca 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -610,7 +610,6 @@ static void sa1111_dev_release(struct device *_dev) { struct sa1111_dev *dev = SA1111_DEV(_dev); - release_resource(&dev->res); kfree(dev); } @@ -625,9 +624,10 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent, 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; @@ -657,17 +657,19 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent, if (ret) { printk("SA1111: failed to allocate resource for %s\n", dev->res.name); - dev_set_name(&dev->dev, NULL); - kfree(dev); - goto out; + goto err_resource; } - ret = device_register(&dev->dev); - if (ret) { - release_resource(&dev->res); - kfree(dev); - } + 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; } @@ -813,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; } -- cgit v1.2.1 From 22eeaff367ac85a09643b2b8a5af064ec8773f63 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 29 Jan 2012 10:28:09 +0000 Subject: ARM: sa1111: use dev_err() rather than printk() Use dev_err() to report device specific errors rather than printk(). Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/common/sa1111.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 8d86338a54ca..9173d112ea01 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -655,7 +655,7 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent, ret = request_resource(parent, &dev->res); if (ret) { - printk("SA1111: failed to allocate resource for %s\n", + dev_err(sachip->dev, "failed to allocate resource for %s\n", dev->res.name); goto err_resource; } -- cgit v1.2.1 From 876c1f27852ff1e45e1164da15847d3b25600160 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 29 Jan 2012 10:37:36 +0000 Subject: ARM: sa11x0: don't static map sa1111 The sa1111 support will ioremap() the device; there is no need for platforms to setup a static mapping for this. Remove the static mapping for this device from badge4, jornada720 and neponset. Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/mach-sa1100/badge4.c | 5 ----- arch/arm/mach-sa1100/jornada720.c | 5 ----- arch/arm/mach-sa1100/neponset.c | 5 ----- 3 files changed, 15 deletions(-) diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c index 8fb80f02c2a9..645ffa1ddc7c 100644 --- a/arch/arm/mach-sa1100/badge4.c +++ b/arch/arm/mach-sa1100/badge4.c @@ -285,11 +285,6 @@ 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/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c index dcd6d026aa68..5d2ceb40dac9 100644 --- a/arch/arm/mach-sa1100/jornada720.c +++ b/arch/arm/mach-sa1100/jornada720.c @@ -285,11 +285,6 @@ 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 } }; diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c index b40a7192f09f..290afedde749 100644 --- a/arch/arm/mach-sa1100/neponset.c +++ b/arch/arm/mach-sa1100/neponset.c @@ -333,11 +333,6 @@ static struct map_desc neponset_io_desc[] __initdata = { .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 } }; -- cgit v1.2.1 From 9cb0f819eb88f573703e9a73d9883febcfcfa1c3 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 26 Jan 2012 10:37:46 +0000 Subject: USB: sa1111: sparse and checkpatch cleanups Clean up the ohci-sa1111 driver formatting to be more compliant with current standards, and add 'static' to various function definitions to avoid sparse complaints about undeclared functions. Remove the unnecessary local declaration of 'usb_disabled', which can be found instead in linux/usb.h. Acked-by: Greg Kroah-Hartman Signed-off-by: Russell King --- drivers/usb/host/ohci-sa1111.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c index 585e53eabff6..50ebeb310fda 100644 --- a/drivers/usb/host/ohci-sa1111.c +++ b/drivers/usb/host/ohci-sa1111.c @@ -41,8 +41,6 @@ #define USB_STATUS_NHCIMFCLR (1 << 10) #define USB_STATUS_USBPWRSENSE (1 << 11) -extern int usb_disabled(void); - /*-------------------------------------------------------------------------*/ static int sa1111_start_hc(struct sa1111_dev *dev) @@ -82,6 +80,7 @@ static int sa1111_start_hc(struct sa1111_dev *dev) static void sa1111_stop_hc(struct sa1111_dev *dev) { unsigned int usb_rst; + printk(KERN_DEBUG "%s: stopping SA-1111 OHCI USB Controller\n", __FILE__); @@ -106,7 +105,7 @@ 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, + 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 "), @@ -131,15 +130,16 @@ static void dump_hci_status(struct usb_hcd *hcd, const char *label) * * Store this function in the HCD's struct pci_driver as probe(). */ -int usb_hcd_sa1111_probe (const struct hc_driver *driver, - struct sa1111_dev *dev) +static int usb_hcd_sa1111_probe(const struct hc_driver *driver, + struct sa1111_dev *dev) { struct usb_hcd *hcd; int retval; - hcd = usb_create_hcd (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); @@ -148,6 +148,7 @@ int usb_hcd_sa1111_probe (const struct hc_driver *driver, retval = -EBUSY; goto err1; } + hcd->regs = dev->mapbase; ret = sa1111_start_hc(dev); @@ -180,9 +181,8 @@ int usb_hcd_sa1111_probe (const struct hc_driver *driver, * 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. - * */ -void usb_hcd_sa1111_remove (struct usb_hcd *hcd, struct sa1111_dev *dev) +static void usb_hcd_sa1111_remove(struct usb_hcd *hcd, struct sa1111_dev *dev) { usb_remove_hcd(hcd); sa1111_stop_hc(dev); @@ -192,18 +192,19 @@ void usb_hcd_sa1111_remove (struct usb_hcd *hcd, struct sa1111_dev *dev) /*-------------------------------------------------------------------------*/ -static int __devinit -ohci_sa1111_start (struct usb_hcd *hcd) +static int __devinit ohci_sa1111_start(struct usb_hcd *hcd) { - struct ohci_hcd *ohci = hcd_to_ohci (hcd); - int ret; + struct ohci_hcd *ohci = hcd_to_ohci(hcd); + int ret; - if ((ret = ohci_init(ohci)) < 0) + ret = ohci_init(ohci); + if (ret < 0) return ret; - if ((ret = ohci_run (ohci)) < 0) { - err ("can't start %s", hcd->self.bus_name); - ohci_stop (hcd); + ret = ohci_run(ohci); + if (ret < 0) { + err("can't start %s", hcd->self.bus_name); + ohci_stop(hcd); return ret; } return 0; -- cgit v1.2.1 From 3f878dbcd6ca4bbdbac0a1380d25161a7ba610ab Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 26 Jan 2012 10:39:57 +0000 Subject: USB: sa1111: get rid of nasty printk(KERN_DEBUG "%s: ...", __FILE__) Use dev_dbg() instead, it's more friendly. Acked-by: Greg Kroah-Hartman Signed-off-by: Russell King --- drivers/usb/host/ohci-sa1111.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c index 50ebeb310fda..e797f18acb33 100644 --- a/drivers/usb/host/ohci-sa1111.c +++ b/drivers/usb/host/ohci-sa1111.c @@ -48,8 +48,7 @@ static int sa1111_start_hc(struct sa1111_dev *dev) unsigned int usb_rst = 0; int ret; - printk(KERN_DEBUG "%s: starting SA-1111 OHCI USB Controller\n", - __FILE__); + dev_dbg(&dev->dev, "starting SA-1111 OHCI USB Controller\n"); if (machine_is_xp860() || machine_has_neponset() || @@ -81,8 +80,7 @@ static void sa1111_stop_hc(struct sa1111_dev *dev) { unsigned int usb_rst; - printk(KERN_DEBUG "%s: stopping SA-1111 OHCI USB Controller\n", - __FILE__); + dev_dbg(&dev->dev, "stopping SA-1111 OHCI USB Controller\n"); /* * Put the USB host controller into reset. -- cgit v1.2.1 From 132db99ae2c6f6a586fc932507fcf4484d90c8fa Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 26 Jan 2012 10:52:34 +0000 Subject: USB: sa1111: reorganize ohci-sa1111.c Combine usb_hcd_sa1111_probe() and ohci_hcd_sa1111_drv_probe(), doing the same for the remove methods. Move sa1111_start_hc and sa1111_stop_hc to be located next to these the probe/release functions, as they're only called from them. Get rid of the /*----*/ breaker lines. Acked-by: Greg Kroah-Hartman Signed-off-by: Russell King --- drivers/usb/host/ohci-sa1111.c | 227 +++++++++++++++++------------------------ 1 file changed, 93 insertions(+), 134 deletions(-) diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c index e797f18acb33..83f3a40db538 100644 --- a/drivers/usb/host/ohci-sa1111.c +++ b/drivers/usb/host/ohci-sa1111.c @@ -41,7 +41,78 @@ #define USB_STATUS_NHCIMFCLR (1 << 10) #define USB_STATUS_USBPWRSENSE (1 << 11) -/*-------------------------------------------------------------------------*/ +#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 __devinit ohci_sa1111_start(struct usb_hcd *hcd) +{ + struct ohci_hcd *ohci = hcd_to_ohci(hcd); + int ret; + + ret = ohci_init(ohci); + if (ret < 0) + return ret; + + ret = ohci_run(ohci); + if (ret < 0) { + err("can't start %s", hcd->self.bus_name); + ohci_stop(hcd); + return ret; + } + return 0; +} + +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 sa1111_start_hc(struct sa1111_dev *dev) { @@ -95,46 +166,21 @@ static void sa1111_stop_hc(struct sa1111_dev *dev) sa1111_disable_device(dev); } - -/*-------------------------------------------------------------------------*/ - -#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 - -/*-------------------------------------------------------------------------*/ - -/* configure so an HC device and id are always provided */ -/* always called with process context; sleeping is OK */ - - /** - * usb_hcd_sa1111_probe - initialize SA-1111-based HCDs - * Context: !in_interrupt() + * ohci_hcd_sa1111_probe - initialize SA-1111-based HCDs * * Allocates basic resources for this USB host controller, and - * 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(). + * then invokes the start() method for the HCD associated with it. */ -static int usb_hcd_sa1111_probe(const struct hc_driver *driver, - struct sa1111_dev *dev) +static int ohci_hcd_sa1111_probe(struct sa1111_dev *dev) { struct usb_hcd *hcd; - int retval; + int ret; + + if (usb_disabled()) + return -ENODEV; - hcd = usb_create_hcd(driver, &dev->dev, "sa1111"); + hcd = usb_create_hcd(&ohci_sa1111_hc_driver, &dev->dev, "sa1111"); if (!hcd) return -ENOMEM; @@ -143,7 +189,7 @@ static int usb_hcd_sa1111_probe(const struct hc_driver *driver, if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { dbg("request_mem_region failed"); - retval = -EBUSY; + ret = -EBUSY; goto err1; } @@ -155,120 +201,34 @@ static int usb_hcd_sa1111_probe(const struct hc_driver *driver, ohci_hcd_init(hcd_to_ohci(hcd)); - retval = usb_add_hcd(hcd, dev->irq[1], 0); - if (retval == 0) - return retval; + ret = usb_add_hcd(hcd, dev->irq[1], 0); + if (ret == 0) + return ret; sa1111_stop_hc(dev); err2: release_mem_region(hcd->rsrc_start, hcd->rsrc_len); err1: usb_put_hcd(hcd); - return retval; + return ret; } - -/* may be called without controller electrically present */ -/* may be called with controller, bus, and devices active */ - /** - * usb_hcd_sa1111_remove - shutdown processing for SA-1111-based HCDs + * ohci_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 void usb_hcd_sa1111_remove(struct usb_hcd *hcd, struct sa1111_dev *dev) +static int ohci_hcd_sa1111_remove(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; - - ret = ohci_init(ohci); - if (ret < 0) - return ret; - - ret = ohci_run(ohci); - if (ret < 0) { - err("can't start %s", hcd->self.bus_name); - ohci_stop(hcd); - return ret; - } - return 0; -} - -/*-------------------------------------------------------------------------*/ - -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); - - usb_hcd_sa1111_remove(hcd, dev); return 0; } @@ -278,7 +238,6 @@ static struct sa1111_driver ohci_hcd_sa1111_driver = { .owner = THIS_MODULE, }, .devid = SA1111_DEVID_USB, - .probe = ohci_hcd_sa1111_drv_probe, - .remove = ohci_hcd_sa1111_drv_remove, + .probe = ohci_hcd_sa1111_probe, + .remove = ohci_hcd_sa1111_remove, }; - -- cgit v1.2.1 From 846a70487e2a0e5045c6a428a0969d3e0490b359 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 26 Jan 2012 11:10:20 +0000 Subject: USB: sa1111: add OHCI shutdown methods Add OHCI shutdown methods to cleanly shutdown the OHCI controller on system shutdowns and reboots. This avoids the controller continuing to run should be soft-reboot the platform, potentially scribbling over system memory. Acked-by: Greg Kroah-Hartman Signed-off-by: Russell King --- drivers/usb/host/ohci-sa1111.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c index 83f3a40db538..95c3f0fb48d3 100644 --- a/drivers/usb/host/ohci-sa1111.c +++ b/drivers/usb/host/ohci-sa1111.c @@ -89,6 +89,7 @@ static const struct hc_driver ohci_sa1111_hc_driver = { */ .start = ohci_sa1111_start, .stop = ohci_stop, + .shutdown = ohci_shutdown, /* * managing i/o requests and associated device resources @@ -232,6 +233,16 @@ static int ohci_hcd_sa1111_remove(struct sa1111_dev *dev) return 0; } +static void ohci_hcd_sa1111_shutdown(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); + } +} + static struct sa1111_driver ohci_hcd_sa1111_driver = { .drv = { .name = "sa1111-ohci", @@ -240,4 +251,5 @@ static struct sa1111_driver ohci_hcd_sa1111_driver = { .devid = SA1111_DEVID_USB, .probe = ohci_hcd_sa1111_probe, .remove = ohci_hcd_sa1111_remove, + .shutdown = ohci_hcd_sa1111_shutdown, }; -- cgit v1.2.1 From 81e6ca3eb74d6bdbab181dd2db378f49f76f0d97 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 26 Jan 2012 11:45:27 +0000 Subject: USB: sa1111: add hcd .reset method Add the .reset method to the HCD, and update the .start method accordingly for this change. Acked-by: Greg Kroah-Hartman Signed-off-by: Russell King --- drivers/usb/host/ohci-sa1111.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c index 95c3f0fb48d3..e1004fb37bd9 100644 --- a/drivers/usb/host/ohci-sa1111.c +++ b/drivers/usb/host/ohci-sa1111.c @@ -55,22 +55,25 @@ static void dump_hci_status(struct usb_hcd *hcd, const char *label) } #endif +static int ohci_sa1111_reset(struct usb_hcd *hcd) +{ + struct ohci_hcd *ohci = hcd_to_ohci(hcd); + + ohci_hcd_init(ohci); + return ohci_init(ohci); +} + static int __devinit ohci_sa1111_start(struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci(hcd); int ret; - ret = ohci_init(ohci); - if (ret < 0) - return ret; - ret = ohci_run(ohci); if (ret < 0) { - err("can't start %s", hcd->self.bus_name); + ohci_err(ohci, "can't start\n"); ohci_stop(hcd); - return ret; } - return 0; + return ret; } static const struct hc_driver ohci_sa1111_hc_driver = { @@ -87,6 +90,7 @@ static const struct hc_driver ohci_sa1111_hc_driver = { /* * basic lifecycle operations */ + .reset = ohci_sa1111_reset, .start = ohci_sa1111_start, .stop = ohci_stop, .shutdown = ohci_shutdown, @@ -200,8 +204,6 @@ static int ohci_hcd_sa1111_probe(struct sa1111_dev *dev) if (ret) goto err2; - ohci_hcd_init(hcd_to_ohci(hcd)); - ret = usb_add_hcd(hcd, dev->irq[1], 0); if (ret == 0) return ret; -- cgit v1.2.1