Hi,
there are some HTC devices (hx4700, n560, artemis, athena) that have one
or more memory mapped EGPIO registers with output pins only.
The following patch makes the htc-egpio probe just not register the irq
handler instead of failing if there is no base_irq given.
regards
Philipp
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;
}
Received on Mon Nov 12 2007 - 17:23:02 EST
This archive was generated by hypermail 2.2.0 : Mon Nov 12 2007 - 17:23:16 EST