aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorMarc Zyngier <maz@misterjones.org>2008-08-18 07:08:42 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2008-10-17 17:40:52 -0400
commit27140219373327f2291da5d74a78db0105b15060 (patch)
tree1cbb0eab32d9b847b0f030982429045ff0e8f041 /drivers/usb
parent7dbcbe88b1495f778f56c742391e49f580dc101a (diff)
USB: Let some USB host controllers get IRQ flags from resource
[This version fixes a thinko in the r8a66597 driver] This patch let a few discrete USB host controllers drivers (isp116x-hcd, r8a66597-hcd and sl811-hcd) obtain IRQ flags from their IORESOURCE_IRQ resource if configured as such, much like it's been done for the smc91x driver. It spares people writing support for specific boards the burden to configure the interrupt controller independantly, and keeps all IRQ related information in a single resource. HCD that are integrally part of a SoC have been left aside, as there is probably no "wiring" options... Tested on an Xscale PXA-255 based platform with isp116x-hcd. Signed-off-by: Marc Zyngier <marc.zyngier@altran.com> Cc: David Brownell <david-b@pacbell.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/host/isp116x-hcd.c13
-rw-r--r--drivers/usb/host/r8a66597-hcd.c41
-rw-r--r--drivers/usb/host/sl811-hcd.c15
3 files changed, 52 insertions, 17 deletions
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
index ce1ca0ba0515..4dda31b26892 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -1562,11 +1562,12 @@ static int __devinit isp116x_probe(struct platform_device *pdev)
1562{ 1562{
1563 struct usb_hcd *hcd; 1563 struct usb_hcd *hcd;
1564 struct isp116x *isp116x; 1564 struct isp116x *isp116x;
1565 struct resource *addr, *data; 1565 struct resource *addr, *data, *ires;
1566 void __iomem *addr_reg; 1566 void __iomem *addr_reg;
1567 void __iomem *data_reg; 1567 void __iomem *data_reg;
1568 int irq; 1568 int irq;
1569 int ret = 0; 1569 int ret = 0;
1570 unsigned long irqflags;
1570 1571
1571 if (pdev->num_resources < 3) { 1572 if (pdev->num_resources < 3) {
1572 ret = -ENODEV; 1573 ret = -ENODEV;
@@ -1575,12 +1576,16 @@ static int __devinit isp116x_probe(struct platform_device *pdev)
1575 1576
1576 data = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1577 data = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1577 addr = platform_get_resource(pdev, IORESOURCE_MEM, 1); 1578 addr = platform_get_resource(pdev, IORESOURCE_MEM, 1);
1578 irq = platform_get_irq(pdev, 0); 1579 ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1579 if (!addr || !data || irq < 0) { 1580
1581 if (!addr || !data || !ires) {
1580 ret = -ENODEV; 1582 ret = -ENODEV;
1581 goto err1; 1583 goto err1;
1582 } 1584 }
1583 1585
1586 irq = ires->start;
1587 irqflags = ires->flags & IRQF_TRIGGER_MASK;
1588
1584 if (pdev->dev.dma_mask) { 1589 if (pdev->dev.dma_mask) {
1585 DBG("DMA not supported\n"); 1590 DBG("DMA not supported\n");
1586 ret = -EINVAL; 1591 ret = -EINVAL;
@@ -1634,7 +1639,7 @@ static int __devinit isp116x_probe(struct platform_device *pdev)
1634 goto err6; 1639 goto err6;
1635 } 1640 }
1636 1641
1637 ret = usb_add_hcd(hcd, irq, IRQF_DISABLED); 1642 ret = usb_add_hcd(hcd, irq, irqflags | IRQF_DISABLED);
1638 if (ret) 1643 if (ret)
1639 goto err6; 1644 goto err6;
1640 1645
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index ea7126f99cab..3a45ad275b41 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -66,7 +66,7 @@ static unsigned short endian;
66module_param(endian, ushort, 0644); 66module_param(endian, ushort, 0644);
67MODULE_PARM_DESC(endian, "data endian: big=256, little=0 (default=0)"); 67MODULE_PARM_DESC(endian, "data endian: big=256, little=0 (default=0)");
68 68
69static unsigned short irq_sense = INTL; 69static unsigned short irq_sense = 0xff;
70module_param(irq_sense, ushort, 0644); 70module_param(irq_sense, ushort, 0644);
71MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=32, falling edge=0 " 71MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=32, falling edge=0 "
72 "(default=32)"); 72 "(default=32)");
@@ -2263,7 +2263,7 @@ static int __init_or_module r8a66597_remove(struct platform_device *pdev)
2263#define resource_len(r) (((r)->end - (r)->start) + 1) 2263#define resource_len(r) (((r)->end - (r)->start) + 1)
2264static int __init r8a66597_probe(struct platform_device *pdev) 2264static int __init r8a66597_probe(struct platform_device *pdev)
2265{ 2265{
2266 struct resource *res = NULL; 2266 struct resource *res = NULL, *ires;
2267 int irq = -1; 2267 int irq = -1;
2268 void __iomem *reg = NULL; 2268 void __iomem *reg = NULL;
2269 struct usb_hcd *hcd = NULL; 2269 struct usb_hcd *hcd = NULL;
@@ -2286,13 +2286,16 @@ static int __init r8a66597_probe(struct platform_device *pdev)
2286 goto clean_up; 2286 goto clean_up;
2287 } 2287 }
2288 2288
2289 irq = platform_get_irq(pdev, 0); 2289 ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
2290 if (irq < 0) { 2290 if (!ires) {
2291 ret = -ENODEV; 2291 ret = -ENODEV;
2292 err("platform_get_irq error."); 2292 err("platform_get_resource IORESOURCE_IRQ error.");
2293 goto clean_up; 2293 goto clean_up;
2294 } 2294 }
2295 2295
2296 irq = ires->start;
2297 irq_trigger = ires->flags & IRQF_TRIGGER_MASK;
2298
2296 reg = ioremap(res->start, resource_len(res)); 2299 reg = ioremap(res->start, resource_len(res));
2297 if (reg == NULL) { 2300 if (reg == NULL) {
2298 ret = -ENOMEM; 2301 ret = -ENOMEM;
@@ -2329,10 +2332,30 @@ static int __init r8a66597_probe(struct platform_device *pdev)
2329 INIT_LIST_HEAD(&r8a66597->child_device); 2332 INIT_LIST_HEAD(&r8a66597->child_device);
2330 2333
2331 hcd->rsrc_start = res->start; 2334 hcd->rsrc_start = res->start;
2332 if (irq_sense == INTL) 2335
2333 irq_trigger = IRQF_TRIGGER_LOW; 2336 /* irq_sense setting on cmdline takes precedence over resource
2334 else 2337 * settings, so the introduction of irqflags in IRQ resourse
2335 irq_trigger = IRQF_TRIGGER_FALLING; 2338 * won't disturb existing setups */
2339 switch (irq_sense) {
2340 case INTL:
2341 irq_trigger = IRQF_TRIGGER_LOW;
2342 break;
2343 case 0:
2344 irq_trigger = IRQF_TRIGGER_FALLING;
2345 break;
2346 case 0xff:
2347 if (irq_trigger)
2348 irq_sense = (irq_trigger & IRQF_TRIGGER_LOW) ?
2349 INTL : 0;
2350 else {
2351 irq_sense = INTL;
2352 irq_trigger = IRQF_TRIGGER_LOW;
2353 }
2354 break;
2355 default:
2356 err("Unknown irq_sense value.");
2357 }
2358
2336 ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | irq_trigger); 2359 ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | irq_trigger);
2337 if (ret != 0) { 2360 if (ret != 0) {
2338 err("Failed to add hcd"); 2361 err("Failed to add hcd");
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
index 8a74bbb57d08..e106e9d48d4a 100644
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -1620,22 +1620,26 @@ sl811h_probe(struct platform_device *dev)
1620{ 1620{
1621 struct usb_hcd *hcd; 1621 struct usb_hcd *hcd;
1622 struct sl811 *sl811; 1622 struct sl811 *sl811;
1623 struct resource *addr, *data; 1623 struct resource *addr, *data, *ires;
1624 int irq; 1624 int irq;
1625 void __iomem *addr_reg; 1625 void __iomem *addr_reg;
1626 void __iomem *data_reg; 1626 void __iomem *data_reg;
1627 int retval; 1627 int retval;
1628 u8 tmp, ioaddr = 0; 1628 u8 tmp, ioaddr = 0;
1629 unsigned long irqflags;
1629 1630
1630 /* basic sanity checks first. board-specific init logic should 1631 /* basic sanity checks first. board-specific init logic should
1631 * have initialized these three resources and probably board 1632 * have initialized these three resources and probably board
1632 * specific platform_data. we don't probe for IRQs, and do only 1633 * specific platform_data. we don't probe for IRQs, and do only
1633 * minimal sanity checking. 1634 * minimal sanity checking.
1634 */ 1635 */
1635 irq = platform_get_irq(dev, 0); 1636 ires = platform_get_resource(dev, IORESOURCE_IRQ, 0);
1636 if (dev->num_resources < 3 || irq < 0) 1637 if (dev->num_resources < 3 || !ires)
1637 return -ENODEV; 1638 return -ENODEV;
1638 1639
1640 irq = ires->start;
1641 irqflags = ires->flags & IRQF_TRIGGER_MASK;
1642
1639 /* refuse to confuse usbcore */ 1643 /* refuse to confuse usbcore */
1640 if (dev->dev.dma_mask) { 1644 if (dev->dev.dma_mask) {
1641 DBG("no we won't dma\n"); 1645 DBG("no we won't dma\n");
@@ -1717,8 +1721,11 @@ sl811h_probe(struct platform_device *dev)
1717 * triggers (e.g. most ARM CPUs). Initial driver stress testing 1721 * triggers (e.g. most ARM CPUs). Initial driver stress testing
1718 * was on a system with single edge triggering, so most sorts of 1722 * was on a system with single edge triggering, so most sorts of
1719 * triggering arrangement should work. 1723 * triggering arrangement should work.
1724 *
1725 * Use resource IRQ flags if set by platform device setup.
1720 */ 1726 */
1721 retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); 1727 irqflags |= IRQF_SHARED;
1728 retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | irqflags);
1722 if (retval != 0) 1729 if (retval != 0)
1723 goto err6; 1730 goto err6;
1724 1731