Index: kernel26/drivers/mfd/htc-egpio.c =================================================================== --- kernel26.orig/drivers/mfd/htc-egpio.c 2007-11-12 21:40:22.000000000 +0100 +++ kernel26/drivers/mfd/htc-egpio.c 2007-11-12 21:40:24.000000000 +0100 @@ -226,9 +226,8 @@ /* Find chained irq */ ret = -EINVAL; res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res) - goto fail; - ei->chainedirq = res->start; + if (res) + ei->chainedirq = res->start; /* Map egpio chip into virtual address space. */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -255,29 +254,32 @@ for (i = 0; i < pdata->nr_pins; i++) setup_pin(ei, &pdata->pins[i]); - /* Setup irq handlers */ - ei->ackWrite = 0xFFFF; - if (pdata->invertAcks) - ei->ackWrite = 0; - for (irq = ei->irqStart; irq < ei->irqStart+MAX_EGPIO_IRQS; irq++) { - set_irq_chip(irq, &egpio_muxed_chip); - set_irq_chip_data(irq, ei); - set_irq_handler(irq, handle_simple_irq); - set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + if (ei->chainedirq) { + /* Setup irq handlers */ + ei->ackWrite = 0xFFFF; + if (pdata->invertAcks) + ei->ackWrite = 0; + for (irq = ei->irqStart; irq < ei->irqStart+MAX_EGPIO_IRQS; irq++) { + set_irq_chip(irq, &egpio_muxed_chip); + set_irq_chip_data(irq, ei); + set_irq_handler(irq, handle_simple_irq); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } + set_irq_type(ei->chainedirq, IRQT_RISING); + set_irq_data(ei->chainedirq, ei); + set_irq_chained_handler(ei->chainedirq, egpio_handler); + ackirqs(ei); + + device_init_wakeup(&pdev->dev, 1); } - set_irq_type(ei->chainedirq, IRQT_RISING); - set_irq_data(ei->chainedirq, ei); - set_irq_chained_handler(ei->chainedirq, egpio_handler); - ackirqs(ei); /* Setup initial output pin values. */ for (i = 0; i<=ei->maxRegs; i++) if (i != ei->ackRegister) writew(ei->cached_values[i], &ei->addrBase[i << ei->bus_shift]); - device_init_wakeup(&pdev->dev, 1); - return 0; + fail: printk(KERN_NOTICE "EGPIO failed to setup\n"); kfree(ei); @@ -288,18 +290,18 @@ { struct egpio_info *ei = platform_get_drvdata(pdev); unsigned int irq; - for (irq = ei->irqStart; irq < ei->irqStart+MAX_EGPIO_IRQS; irq++) { - set_irq_chip(irq, NULL); - set_irq_handler(irq, NULL); - set_irq_flags(irq, 0); + if (ei->chainedirq) { + for (irq = ei->irqStart; irq < ei->irqStart+MAX_EGPIO_IRQS; irq++) { + set_irq_chip(irq, NULL); + set_irq_handler(irq, NULL); + set_irq_flags(irq, 0); + } + set_irq_chained_handler(ei->chainedirq, NULL); + device_init_wakeup(&pdev->dev, 0); } - set_irq_chained_handler(ei->chainedirq, NULL); - iounmap(ei->addrBase); kfree(ei); - device_init_wakeup(&pdev->dev, 0); - return 0; } @@ -308,7 +310,7 @@ { struct egpio_info *ei = platform_get_drvdata(pdev); - if (device_may_wakeup(&pdev->dev)) + if (ei->chainedirq && device_may_wakeup(&pdev->dev)) enable_irq_wake(ei->chainedirq); return 0; } @@ -317,7 +319,7 @@ { struct egpio_info *ei = platform_get_drvdata(pdev); - if (device_may_wakeup(&pdev->dev)) + if (ei->chainedirq && device_may_wakeup(&pdev->dev)) disable_irq_wake(ei->chainedirq); return 0; }