summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/sparc/kernel/irq_64.c29
-rw-r--r--drivers/net/sunhme.c2
-rw-r--r--drivers/sbus/char/bbc_i2c.c2
-rw-r--r--drivers/sbus/char/jsflash.c3
4 files changed, 20 insertions, 16 deletions
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c
index e289376198eb..1c378d8e90c5 100644
--- a/arch/sparc/kernel/irq_64.c
+++ b/arch/sparc/kernel/irq_64.c
@@ -323,17 +323,25 @@ static void sun4u_set_affinity(unsigned int virt_irq,
sun4u_irq_enable(virt_irq);
}
+/* Don't do anything. The desc->status check for IRQ_DISABLED in
+ * handler_irq() will skip the handler call and that will leave the
+ * interrupt in the sent state. The next ->enable() call will hit the
+ * ICLR register to reset the state machine.
+ *
+ * This scheme is necessary, instead of clearing the Valid bit in the
+ * IMAP register, to handle the case of IMAP registers being shared by
+ * multiple INOs (and thus ICLR registers). Since we use a different
+ * virtual IRQ for each shared IMAP instance, the generic code thinks
+ * there is only one user so it prematurely calls ->disable() on
+ * free_irq().
+ *
+ * We have to provide an explicit ->disable() method instead of using
+ * NULL to get the default. The reason is that if the generic code
+ * sees that, it also hooks up a default ->shutdown method which
+ * invokes ->mask() which we do not want. See irq_chip_set_defaults().
+ */
static void sun4u_irq_disable(unsigned int virt_irq)
{
- struct irq_handler_data *data = get_irq_chip_data(virt_irq);
-
- if (likely(data)) {
- unsigned long imap = data->imap;
- unsigned long tmp = upa_readq(imap);
-
- tmp &= ~IMAP_VALID;
- upa_writeq(tmp, imap);
- }
}
static void sun4u_irq_eoi(unsigned int virt_irq)
@@ -746,7 +754,8 @@ void handler_irq(int irq, struct pt_regs *regs)
desc = irq_desc + virt_irq;
- desc->handle_irq(virt_irq, desc);
+ if (!(desc->status & IRQ_DISABLED))
+ desc->handle_irq(virt_irq, desc);
bucket_pa = next_pa;
}
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index d4fb4acdbebd..4e9bd380a5c2 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -2649,8 +2649,6 @@ static int __devinit happy_meal_sbus_probe_one(struct of_device *op, int is_qfe)
int err = -ENODEV;
sbus_dp = to_of_device(op->dev.parent)->node;
- if (is_qfe)
- sbus_dp = to_of_device(op->dev.parent->parent)->node;
/* We can match PCI devices too, do not accept those here. */
if (strcmp(sbus_dp->name, "sbus"))
diff --git a/drivers/sbus/char/bbc_i2c.c b/drivers/sbus/char/bbc_i2c.c
index f08e169ba1b5..7e30e5f6e032 100644
--- a/drivers/sbus/char/bbc_i2c.c
+++ b/drivers/sbus/char/bbc_i2c.c
@@ -129,7 +129,7 @@ static int wait_for_pin(struct bbc_i2c_bus *bp, u8 *status)
bp->waiting = 1;
add_wait_queue(&bp->wq, &wait);
while (limit-- > 0) {
- unsigned long val;
+ long val;
val = wait_event_interruptible_timeout(
bp->wq,
diff --git a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c
index a9a9893a5f95..e6d1fc8c54f1 100644
--- a/drivers/sbus/char/jsflash.c
+++ b/drivers/sbus/char/jsflash.c
@@ -38,9 +38,6 @@
#include <linux/string.h>
#include <linux/genhd.h>
#include <linux/blkdev.h>
-
-#define MAJOR_NR JSFD_MAJOR
-
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/io.h>