aboutsummaryrefslogtreecommitdiff
path: root/arch/powerpc/platforms
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r--arch/powerpc/platforms/cell/interrupt.c4
-rw-r--r--arch/powerpc/platforms/cell/spider-pic.c70
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c6
-rw-r--r--arch/powerpc/platforms/iseries/irq.c4
-rw-r--r--arch/powerpc/platforms/maple/setup.c17
-rw-r--r--arch/powerpc/platforms/powermac/backlight.c85
-rw-r--r--arch/powerpc/platforms/powermac/cpufreq_64.c14
-rw-r--r--arch/powerpc/platforms/powermac/pci.c13
-rw-r--r--arch/powerpc/platforms/powermac/pic.c8
-rw-r--r--arch/powerpc/platforms/pseries/ras.c3
-rw-r--r--arch/powerpc/platforms/pseries/setup.c6
-rw-r--r--arch/powerpc/platforms/pseries/xics.c34
12 files changed, 173 insertions, 91 deletions
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index b26b496f654..7813a58e0db 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -159,7 +159,7 @@ static void iic_request_ipi(int ipi, const char *name)
if (iic_hosts[node] == NULL)
continue;
virq = irq_create_mapping(iic_hosts[node],
- iic_ipi_to_irq(ipi), 0);
+ iic_ipi_to_irq(ipi));
if (virq == NO_IRQ) {
printk(KERN_ERR
"iic: failed to map IPI %s on node %d\n",
@@ -197,7 +197,7 @@ static int iic_host_match(struct irq_host *h, struct device_node *node)
}
static int iic_host_map(struct irq_host *h, unsigned int virq,
- irq_hw_number_t hw, unsigned int flags)
+ irq_hw_number_t hw)
{
if (hw < IIC_IRQ_IPI0)
set_irq_chip_and_handler(virq, &iic_chip, handle_fasteoi_irq);
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index ab4c252a4d9..742a03282b4 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -85,9 +85,6 @@ static void spider_unmask_irq(unsigned int virq)
struct spider_pic *pic = spider_virq_to_pic(virq);
void __iomem *cfg = spider_get_irq_config(pic, irq_map[virq].hwirq);
- /* We use no locking as we should be covered by the descriptor lock
- * for access to invidual source configuration registers
- */
out_be32(cfg, in_be32(cfg) | 0x30000000u);
}
@@ -96,9 +93,6 @@ static void spider_mask_irq(unsigned int virq)
struct spider_pic *pic = spider_virq_to_pic(virq);
void __iomem *cfg = spider_get_irq_config(pic, irq_map[virq].hwirq);
- /* We use no locking as we should be covered by the descriptor lock
- * for access to invidual source configuration registers
- */
out_be32(cfg, in_be32(cfg) & ~0x30000000u);
}
@@ -120,26 +114,14 @@ static void spider_ack_irq(unsigned int virq)
out_be32(pic->regs + TIR_EDC, 0x100 | (src & 0xf));
}
-static struct irq_chip spider_pic = {
- .typename = " SPIDER ",
- .unmask = spider_unmask_irq,
- .mask = spider_mask_irq,
- .ack = spider_ack_irq,
-};
-
-static int spider_host_match(struct irq_host *h, struct device_node *node)
-{
- struct spider_pic *pic = h->host_data;
- return node == pic->of_node;
-}
-
-static int spider_host_map(struct irq_host *h, unsigned int virq,
- irq_hw_number_t hw, unsigned int flags)
+static int spider_set_irq_type(unsigned int virq, unsigned int type)
{
- unsigned int sense = flags & IRQ_TYPE_SENSE_MASK;
- struct spider_pic *pic = h->host_data;
+ unsigned int sense = type & IRQ_TYPE_SENSE_MASK;
+ struct spider_pic *pic = spider_virq_to_pic(virq);
+ unsigned int hw = irq_map[virq].hwirq;
void __iomem *cfg = spider_get_irq_config(pic, hw);
- int level = 0;
+ struct irq_desc *desc = get_irq_desc(virq);
+ u32 old_mask;
u32 ic;
/* Note that only level high is supported for most interrupts */
@@ -157,29 +139,57 @@ static int spider_host_map(struct irq_host *h, unsigned int virq,
break;
case IRQ_TYPE_LEVEL_LOW:
ic = 0x0;
- level = 1;
break;
case IRQ_TYPE_LEVEL_HIGH:
case IRQ_TYPE_NONE:
ic = 0x1;
- level = 1;
break;
default:
return -EINVAL;
}
+ /* Update irq_desc */
+ desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
+ desc->status |= type & IRQ_TYPE_SENSE_MASK;
+ if (type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
+ desc->status |= IRQ_LEVEL;
+
/* Configure the source. One gross hack that was there before and
* that I've kept around is the priority to the BE which I set to
* be the same as the interrupt source number. I don't know wether
* that's supposed to make any kind of sense however, we'll have to
* decide that, but for now, I'm not changing the behaviour.
*/
- out_be32(cfg, (ic << 24) | (0x7 << 16) | (pic->node_id << 4) | 0xe);
+ old_mask = in_be32(cfg) & 0x30000000u;
+ out_be32(cfg, old_mask | (ic << 24) | (0x7 << 16) |
+ (pic->node_id << 4) | 0xe);
out_be32(cfg + 4, (0x2 << 16) | (hw & 0xff));
- if (level)
- get_irq_desc(virq)->status |= IRQ_LEVEL;
+ return 0;
+}
+
+static struct irq_chip spider_pic = {
+ .typename = " SPIDER ",
+ .unmask = spider_unmask_irq,
+ .mask = spider_mask_irq,
+ .ack = spider_ack_irq,
+ .set_type = spider_set_irq_type,
+};
+
+static int spider_host_match(struct irq_host *h, struct device_node *node)
+{
+ struct spider_pic *pic = h->host_data;
+ return node == pic->of_node;
+}
+
+static int spider_host_map(struct irq_host *h, unsigned int virq,
+ irq_hw_number_t hw)
+{
set_irq_chip_and_handler(virq, &spider_pic, handle_level_irq);
+
+ /* Set default irq type */
+ set_irq_type(virq, IRQ_TYPE_NONE);
+
return 0;
}
@@ -283,7 +293,7 @@ static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic)
if (iic_host == NULL)
return NO_IRQ;
/* Manufacture an IIC interrupt number of class 2 */
- virq = irq_create_mapping(iic_host, 0x20 | unit, 0);
+ virq = irq_create_mapping(iic_host, 0x20 | unit);
if (virq == NO_IRQ)
printk(KERN_ERR "spider_pic: failed to map cascade !");
return virq;
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index 86d55675e1d..3bd36d46ab4 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -583,9 +583,9 @@ static int __init spu_map_interrupts(struct spu *spu, struct device_node *np)
spu->isrc = isrc = tmp[0];
/* Now map interrupts of all 3 classes */
- spu->irqs[0] = irq_create_mapping(host, 0x00 | isrc, 0);
- spu->irqs[1] = irq_create_mapping(host, 0x10 | isrc, 0);
- spu->irqs[2] = irq_create_mapping(host, 0x20 | isrc, 0);
+ spu->irqs[0] = irq_create_mapping(host, 0x00 | isrc);
+ spu->irqs[1] = irq_create_mapping(host, 0x10 | isrc);
+ spu->irqs[2] = irq_create_mapping(host, 0x20 | isrc);
/* Right now, we only fail if class 2 failed */
return spu->irqs[2] == NO_IRQ ? -EINVAL : 0;
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
index 2275e64f315..e32446877e7 100644
--- a/arch/powerpc/platforms/iseries/irq.c
+++ b/arch/powerpc/platforms/iseries/irq.c
@@ -300,7 +300,7 @@ int __init iSeries_allocate_IRQ(HvBusNumber bus,
realirq = (((((sub_bus << 8) + (bus - 1)) << 3) + (idsel - 1)) << 3)
+ function;
- return irq_create_mapping(NULL, realirq, IRQ_TYPE_NONE);
+ return irq_create_mapping(NULL, realirq);
}
#endif /* CONFIG_PCI */
@@ -341,7 +341,7 @@ unsigned int iSeries_get_irq(struct pt_regs *regs)
}
static int iseries_irq_host_map(struct irq_host *h, unsigned int virq,
- irq_hw_number_t hw, unsigned int flags)
+ irq_hw_number_t hw)
{
set_irq_chip_and_handler(virq, &iseries_pic, handle_fasteoi_irq);
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c
index ecc764a3ff3..fe6b9bff61b 100644
--- a/arch/powerpc/platforms/maple/setup.c
+++ b/arch/powerpc/platforms/maple/setup.c
@@ -215,10 +215,17 @@ static void __init maple_init_IRQ(void)
* in Maple device-tree where the type of the controller is
* open-pic and not interrupt-controller
*/
- for_each_node_by_type(np, "open-pic") {
- mpic_node = np;
- break;
- }
+
+ for_each_node_by_type(np, "interrupt-controller")
+ if (device_is_compatible(np, "open-pic")) {
+ mpic_node = np;
+ break;
+ }
+ if (mpic_node == NULL)
+ for_each_node_by_type(np, "open-pic") {
+ mpic_node = np;
+ break;
+ }
if (mpic_node == NULL) {
printk(KERN_ERR
"Failed to locate the MPIC interrupt controller\n");
@@ -245,6 +252,8 @@ static void __init maple_init_IRQ(void)
/* XXX Maple specific bits */
flags |= MPIC_BROKEN_U3 | MPIC_WANTS_RESET;
+ /* All U3/U4 are big-endian, older SLOF firmware doesn't encode this */
+ flags |= MPIC_BIG_ENDIAN;
/* Setup the openpic driver. More device-tree junks, we hard code no
* ISUs for now. I'll have to revisit some stuffs with the folks doing
diff --git a/arch/powerpc/platforms/powermac/backlight.c b/arch/powerpc/platforms/powermac/backlight.c
index 205b4a39286..afa593a8544 100644
--- a/arch/powerpc/platforms/powermac/backlight.c
+++ b/arch/powerpc/platforms/powermac/backlight.c
@@ -10,11 +10,33 @@
#include <linux/kernel.h>
#include <linux/fb.h>
#include <linux/backlight.h>
+#include <linux/adb.h>
+#include <linux/pmu.h>
+#include <asm/atomic.h>
#include <asm/prom.h>
#include <asm/backlight.h>
#define OLD_BACKLIGHT_MAX 15
+static void pmac_backlight_key_worker(void *data);
+static void pmac_backlight_set_legacy_worker(void *data);
+
+static DECLARE_WORK(pmac_backlight_key_work, pmac_backlight_key_worker, NULL);
+static DECLARE_WORK(pmac_backlight_set_legacy_work, pmac_backlight_set_legacy_worker, NULL);
+
+/* Although these variables are used in interrupt context, it makes no sense to
+ * protect them. No user is able to produce enough key events per second and
+ * notice the errors that might happen.
+ */
+static int pmac_backlight_key_queued;
+static int pmac_backlight_set_legacy_queued;
+
+/* The via-pmu code allows the backlight to be grabbed, in which case the
+ * in-kernel control of the brightness needs to be disabled. This should
+ * only be used by really old PowerBooks.
+ */
+static atomic_t kernel_backlight_disabled = ATOMIC_INIT(0);
+
/* Protect the pmac_backlight variable */
DEFINE_MUTEX(pmac_backlight_mutex);
@@ -72,8 +94,11 @@ int pmac_backlight_curve_lookup(struct fb_info *info, int value)
return level;
}
-static void pmac_backlight_key(int direction)
+static void pmac_backlight_key_worker(void *data)
{
+ if (atomic_read(&kernel_backlight_disabled))
+ return;
+
mutex_lock(&pmac_backlight_mutex);
if (pmac_backlight) {
struct backlight_properties *props;
@@ -83,7 +108,8 @@ static void pmac_backlight_key(int direction)
props = pmac_backlight->props;
brightness = props->brightness +
- ((direction?-1:1) * (props->max_brightness / 15));
+ ((pmac_backlight_key_queued?-1:1) *
+ (props->max_brightness / 15));
if (brightness < 0)
brightness = 0;
@@ -98,17 +124,20 @@ static void pmac_backlight_key(int direction)
mutex_unlock(&pmac_backlight_mutex);
}
-void pmac_backlight_key_up()
+/* This function is called in interrupt context */
+void pmac_backlight_key(int direction)
{
- pmac_backlight_key(0);
+ if (atomic_read(&kernel_backlight_disabled))
+ return;
+
+ /* we can receive multiple interrupts here, but the scheduled work
+ * will run only once, with the last value
+ */
+ pmac_backlight_key_queued = direction;
+ schedule_work(&pmac_backlight_key_work);
}
-void pmac_backlight_key_down()
-{
- pmac_backlight_key(1);
-}
-
-int pmac_backlight_set_legacy_brightness(int brightness)
+static int __pmac_backlight_set_legacy_brightness(int brightness)
{
int error = -ENXIO;
@@ -137,6 +166,28 @@ int pmac_backlight_set_legacy_brightness(int brightness)
return error;
}
+static void pmac_backlight_set_legacy_worker(void *data)
+{
+ if (atomic_read(&kernel_backlight_disabled))
+ return;
+
+ __pmac_backlight_set_legacy_brightness(pmac_backlight_set_legacy_queued);
+}
+
+/* This function is called in interrupt context */
+void pmac_backlight_set_legacy_brightness_pmu(int brightness) {
+ if (atomic_read(&kernel_backlight_disabled))
+ return;
+
+ pmac_backlight_set_legacy_queued = brightness;
+ schedule_work(&pmac_backlight_set_legacy_work);
+}
+
+int pmac_backlight_set_legacy_brightness(int brightness)
+{
+ return __pmac_backlight_set_legacy_brightness(brightness);
+}
+
int pmac_backlight_get_legacy_brightness()
{
int result = -ENXIO;
@@ -158,3 +209,17 @@ int pmac_backlight_get_legacy_brightness()
return result;
}
+
+void pmac_backlight_disable()
+{
+ atomic_inc(&kernel_backlight_disabled);
+}
+
+void pmac_backlight_enable()
+{
+ atomic_dec(&kernel_backlight_disabled);
+}
+
+EXPORT_SYMBOL_GPL(pmac_backlight);
+EXPORT_SYMBOL_GPL(pmac_backlight_mutex);
+EXPORT_SYMBOL_GPL(pmac_has_backlight_type);
diff --git a/arch/powerpc/platforms/powermac/cpufreq_64.c b/arch/powerpc/platforms/powermac/cpufreq_64.c
index c364c89adb4..167cd3ce8a1 100644
--- a/arch/powerpc/platforms/powermac/cpufreq_64.c
+++ b/arch/powerpc/platforms/powermac/cpufreq_64.c
@@ -87,9 +87,9 @@ static int (*g5_query_freq)(void);
static DEFINE_MUTEX(g5_switch_mutex);
-#ifdef CONFIG_PPC_SMU
+#ifdef CONFIG_PMAC_SMU
-static const u32 *g5_pmode_data;
+static u32 *g5_pmode_data;
static int g5_pmode_max;
static struct smu_sdbp_fvt *g5_fvt_table; /* table of op. points */
@@ -216,7 +216,7 @@ static void g5_dummy_switch_volt(int speed_mode)
{
}
-#endif /* CONFIG_PPC_SMU */
+#endif /* CONFIG_PMAC_SMU */
/*
* Platform function based voltage switching for PowerMac7,2 & 7,3
@@ -383,7 +383,7 @@ static struct cpufreq_driver g5_cpufreq_driver = {
};
-#ifdef CONFIG_PPC_SMU
+#ifdef CONFIG_PMAC_SMU
static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
{
@@ -535,7 +535,7 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
return rc;
}
-#endif /* CONFIG_PPC_SMU */
+#endif /* CONFIG_PMAC_SMU */
static int __init g5_pm72_cpufreq_init(struct device_node *cpus)
@@ -731,10 +731,10 @@ static int __init g5_cpufreq_init(void)
machine_is_compatible("PowerMac7,3") ||
machine_is_compatible("RackMac3,1"))
rc = g5_pm72_cpufreq_init(cpus);
-#ifdef CONFIG_PPC_SMU
+#ifdef CONFIG_PMAC_SMU
else
rc = g5_neo2_cpufreq_init(cpus);
-#endif /* CONFIG_PPC_SMU */
+#endif /* CONFIG_PMAC_SMU */
of_node_put(cpus);
return rc;
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index 787ffd999bc..9923adc5248 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -16,6 +16,7 @@
#include <linux/string.h>
#include <linux/init.h>
#include <linux/bootmem.h>
+#include <linux/irq.h>
#include <asm/sections.h>
#include <asm/io.h>
@@ -24,10 +25,7 @@
#include <asm/machdep.h>
#include <asm/pmac_feature.h>
#include <asm/grackle.h>
-#ifdef CONFIG_PPC64
-//#include <asm/iommu.h>
#include <asm/ppc-pci.h>
-#endif
#undef DEBUG
@@ -46,7 +44,6 @@ static int has_uninorth;
static struct pci_controller *u3_agp;
static struct pci_controller *u4_pcie;
static struct pci_controller *u3_ht;
-#define has_second_ohare 0
#else
static int has_second_ohare;
#endif /* CONFIG_PPC64 */
@@ -996,6 +993,7 @@ void __init pmac_pcibios_fixup(void)
/* Read interrupt from the device-tree */
pci_read_irq_line(dev);
+#ifdef CONFIG_PPC32
/* Fixup interrupt for the modem/ethernet combo controller.
* on machines with a second ohare chip.
* The number in the device tree (27) is bogus (correct for
@@ -1005,8 +1003,11 @@ void __init pmac_pcibios_fixup(void)
*/
if (has_second_ohare &&
dev->vendor == PCI_VENDOR_ID_DEC &&
- dev->device == PCI_DEVICE_ID_DEC_TULIP_PLUS)
- dev->irq = irq_create_mapping(NULL, 60, 0);
+ dev->device == PCI_DEVICE_ID_DEC_TULIP_PLUS) {
+ dev->irq = irq_create_mapping(NULL, 60);
+ set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW);
+ }
+#endif /* CONFIG_PPC32 */
}
}
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 3d328bc1f7e..060789e31c6 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -291,7 +291,7 @@ static int pmac_pic_host_match(struct irq_host *h, struct device_node *node)
}
static int pmac_pic_host_map(struct irq_host *h, unsigned int virq,
- irq_hw_number_t hw, unsigned int flags)
+ irq_hw_number_t hw)
{
struct irq_desc *desc = get_irq_desc(virq);
int level;
@@ -318,6 +318,7 @@ static int pmac_pic_host_xlate(struct irq_host *h, struct device_node *ct,
unsigned int *out_flags)
{
+ *out_flags = IRQ_TYPE_NONE;
*out_hwirq = *intspec;
return 0;
}
@@ -434,7 +435,7 @@ static void __init pmac_pic_probe_oldstyle(void)
printk(KERN_INFO "irq: System has %d possible interrupts\n", max_irqs);
#ifdef CONFIG_XMON
- setup_irq(irq_create_mapping(NULL, 20, 0), &xmon_action);
+ setup_irq(irq_create_mapping(NULL, 20), &xmon_action);
#endif
}
#endif /* CONFIG_PPC32 */
@@ -579,9 +580,10 @@ void __init pmac_pic_init(void)
flags |= OF_IMAP_OLDWORLD_MAC;
if (get_property(of_chosen, "linux,bootx", NULL) != NULL)
flags |= OF_IMAP_NO_PHANDLE;
- of_irq_map_init(flags);
#endif /* CONFIG_PPC_32 */
+ of_irq_map_init(flags);
+
/* We first try to detect Apple's new Core99 chipset, since mac-io
* is quite different on those machines and contains an IBM MPIC2.
*/
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
index 0e6339ee45a..903115d67fd 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -93,8 +93,7 @@ static void request_ras_irqs(struct device_node *np,
for (i = 0; i < opicplen; i++) {
if (count > 15)
break;
- virqs[count] = irq_create_mapping(NULL, *(opicprop++),
- IRQ_TYPE_NONE);
+ virqs[count] = irq_create_mapping(NULL, *(opicprop++));
if (virqs[count] == NO_IRQ)
printk(KERN_ERR "Unable to allocate interrupt "
"number for %s\n", np->full_name);
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 927e0a423b8..de214d86ff4 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -501,7 +501,8 @@ static void pseries_dedicated_idle_sleep(void)
}
/*
- * Cede if the other thread is not idle, so that it can
+ * If not SMT, cede processor. If CPU is running SMT
+ * cede if the other thread is not idle, so that it can
* go single-threaded. If the other thread is idle,
* we ask the hypervisor if it has pending work it
* wants to do and cede if it does. Otherwise we keep
@@ -514,7 +515,8 @@ static void pseries_dedicated_idle_sleep(void)
* very low priority. The cede enables interrupts, which
* doesn't matter here.
*/
- if (!lppaca[cpu ^ 1].idle || poll_pending() == H_PENDING)
+ if (!cpu_has_feature(CPU_FTR_SMT) || !lppaca[cpu ^ 1].idle
+ || poll_pending() == H_PENDING)
cede_processor();
out:
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 75642104944..1eab4688be1 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -502,16 +502,9 @@ static int xics_host_match(struct irq_host *h, struct device_node *node)
}
static int xics_host_map_direct(struct irq_host *h, unsigned int virq,
- irq_hw_number_t hw, unsigned int flags)
+ irq_hw_number_t hw)
{
- unsigned int sense = flags & IRQ_TYPE_SENSE_MASK;
-
- pr_debug("xics: map_direct virq %d, hwirq 0x%lx, flags: 0x%x\n",
- virq, hw, flags);
-
- if (sense && sense != IRQ_TYPE_LEVEL_LOW)
- printk(KERN_WARNING "xics: using unsupported sense 0x%x"
- " for irq %d (h: 0x%lx)\n", flags, virq, hw);
+ pr_debug("xics: map_direct virq %d, hwirq 0x%lx\n", virq, hw);
get_irq_desc(virq)->status |= IRQ_LEVEL;
set_irq_chip_and_handler(virq, &xics_pic_direct, handle_fasteoi_irq);
@@ -519,16 +512,9 @@ static int xics_host_map_direct(struct irq_host *h, unsigned int virq,
}
static int xics_host_map_lpar(struct irq_host *h, unsigned int virq,
- irq_hw_number_t hw, unsigned int flags)
+ irq_hw_number_t hw)
{
- unsigned int sense = flags & IRQ_TYPE_SENSE_MASK;
-
- pr_debug("xics: map_lpar virq %d, hwirq 0x%lx, flags: 0x%x\n",
- virq, hw, flags);
-
- if (sense && sense != IRQ_TYPE_LEVEL_LOW)
- printk(KERN_WARNING "xics: using unsupported sense 0x%x"
- " for irq %d (h: 0x%lx)\n", flags, virq, hw);
+ pr_debug("xics: map_direct virq %d, hwirq 0x%lx\n", virq, hw);
get_irq_desc(virq)->status |= IRQ_LEVEL;
set_irq_chip_and_handler(virq, &xics_pic_lpar, handle_fasteoi_irq);
@@ -757,7 +743,7 @@ void xics_request_IPIs(void)
{
unsigned int ipi;
- ipi = irq_create_mapping(xics_host, XICS_IPI, 0);
+ ipi = irq_create_mapping(xics_host, XICS_IPI);
BUG_ON(ipi == NO_IRQ);
/*
@@ -783,6 +769,14 @@ void xics_teardown_cpu(int secondary)
xics_set_cpu_priority(cpu, 0);
/*
+ * Clear IPI
+ */
+ if (firmware_has_feature(FW_FEATURE_LPAR))
+ lpar_qirr_info(cpu, 0xff);
+ else
+ direct_qirr_info(cpu, 0xff);
+
+ /*
* we need to EOI the IPI if we got here from kexec down IPI
*
* probably need to check all the other interrupts too
@@ -795,7 +789,7 @@ void xics_teardown_cpu(int secondary)
return;
desc = get_irq_desc(ipi);
if (desc->chip && desc->chip->eoi)
- desc->chip->eoi(XICS_IPI);
+ desc->chip->eoi(ipi);
/*
* Some machines need to have at least one cpu in the GIQ,