From 4ae9b105430a56f739764bdaefb90f256e1a25c4 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 5 Jul 2008 13:06:19 -0700 Subject: [PATCH] --- yaml --- r: 98732 b: refs/heads/master c: fbe0825752dc34b505777fd59cde4a6ce832eb16 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/ata/ahci.c | 16 +++++++++++++--- trunk/mm/mempolicy.c | 6 +++++- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/[refs] b/[refs] index 0136f09bd9a9..9a1ae072f4c2 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 2b54ed9467697b0ce2d60d89e5e4253c9e322c26 +refs/heads/master: fbe0825752dc34b505777fd59cde4a6ce832eb16 diff --git a/trunk/drivers/ata/ahci.c b/trunk/drivers/ata/ahci.c index 061817a3a0e5..5e6468a7ca4b 100644 --- a/trunk/drivers/ata/ahci.c +++ b/trunk/drivers/ata/ahci.c @@ -1777,7 +1777,7 @@ static irqreturn_t ahci_interrupt(int irq, void *dev_instance) struct ahci_host_priv *hpriv; unsigned int i, handled = 0; void __iomem *mmio; - u32 irq_stat; + u32 irq_stat, irq_masked; VPRINTK("ENTER\n"); @@ -1786,16 +1786,17 @@ static irqreturn_t ahci_interrupt(int irq, void *dev_instance) /* sigh. 0xffffffff is a valid return from h/w */ irq_stat = readl(mmio + HOST_IRQ_STAT); - irq_stat &= hpriv->port_map; if (!irq_stat) return IRQ_NONE; + irq_masked = irq_stat & hpriv->port_map; + spin_lock(&host->lock); for (i = 0; i < host->n_ports; i++) { struct ata_port *ap; - if (!(irq_stat & (1 << i))) + if (!(irq_masked & (1 << i))) continue; ap = host->ports[i]; @@ -1812,6 +1813,15 @@ static irqreturn_t ahci_interrupt(int irq, void *dev_instance) handled = 1; } + /* HOST_IRQ_STAT behaves as level triggered latch meaning that + * it should be cleared after all the port events are cleared; + * otherwise, it will raise a spurious interrupt after each + * valid one. Please read section 10.6.2 of ahci 1.1 for more + * information. + * + * Also, use the unmasked value to clear interrupt as spurious + * pending event on a dummy port might cause screaming IRQ. + */ writel(irq_stat, mmio + HOST_IRQ_STAT); spin_unlock(&host->lock); diff --git a/trunk/mm/mempolicy.c b/trunk/mm/mempolicy.c index a37a5034f63d..c94e58b192c3 100644 --- a/trunk/mm/mempolicy.c +++ b/trunk/mm/mempolicy.c @@ -729,7 +729,11 @@ static long do_get_mempolicy(int *policy, nodemask_t *nmask, } else { *policy = pol == &default_policy ? MPOL_DEFAULT : pol->mode; - *policy |= pol->flags; + /* + * Internal mempolicy flags must be masked off before exposing + * the policy to userspace. + */ + *policy |= (pol->flags & MPOL_MODE_FLAGS); } if (vma) {