aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2006-07-31 20:37:25 -0400
committerPaul Mackerras <paulus@samba.org>2006-07-31 20:37:25 -0400
commit57cad8084e0837e0f2c97da789ec9b3f36809be9 (patch)
treee9c790afb4286f78cb08d9664f58baa7e876fe55 /arch/powerpc/platforms
parentcb18bd40030c879cd93fef02fd579f74dbab473d (diff)
parent49b1e3ea19b1c95c2f012b8331ffb3b169e4c042 (diff)
Merge branch 'merge'
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 b26b496f6548..7813a58e0db4 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)
159 if (iic_hosts[node] == NULL) 159 if (iic_hosts[node] == NULL)
160 continue; 160 continue;
161 virq = irq_create_mapping(iic_hosts[node], 161 virq = irq_create_mapping(iic_hosts[node],
162 iic_ipi_to_irq(ipi), 0); 162 iic_ipi_to_irq(ipi));
163 if (virq == NO_IRQ) { 163 if (virq == NO_IRQ) {
164 printk(KERN_ERR 164 printk(KERN_ERR
165 "iic: failed to map IPI %s on node %d\n", 165 "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)
197} 197}
198 198
199static int iic_host_map(struct irq_host *h, unsigned int virq, 199static int iic_host_map(struct irq_host *h, unsigned int virq,
200 irq_hw_number_t hw, unsigned int flags) 200 irq_hw_number_t hw)
201{ 201{
202 if (hw < IIC_IRQ_IPI0) 202 if (hw < IIC_IRQ_IPI0)
203 set_irq_chip_and_handler(virq, &iic_chip, handle_fasteoi_irq); 203 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 ab4c252a4d9b..742a03282b44 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)
85 struct spider_pic *pic = spider_virq_to_pic(virq); 85 struct spider_pic *pic = spider_virq_to_pic(virq);
86 void __iomem *cfg = spider_get_irq_config(pic, irq_map[virq].hwirq); 86 void __iomem *cfg = spider_get_irq_config(pic, irq_map[virq].hwirq);
87 87
88 /* We use no locking as we should be covered by the descriptor lock
89 * for access to invidual source configuration registers
90 */
91 out_be32(cfg, in_be32(cfg) | 0x30000000u); 88 out_be32(cfg, in_be32(cfg) | 0x30000000u);
92} 89}
93 90
@@ -96,9 +93,6 @@ static void spider_mask_irq(unsigned int virq)
96 struct spider_pic *pic = spider_virq_to_pic(virq); 93 struct spider_pic *pic = spider_virq_to_pic(virq);
97 void __iomem *cfg = spider_get_irq_config(pic, irq_map[virq].hwirq); 94 void __iomem *cfg = spider_get_irq_config(pic, irq_map[virq].hwirq);
98 95
99 /* We use no locking as we should be covered by the descriptor lock
100 * for access to invidual source configuration registers
101 */
102 out_be32(cfg, in_be32(cfg) & ~0x30000000u); 96 out_be32(cfg, in_be32(cfg) & ~0x30000000u);
103} 97}
104 98
@@ -120,26 +114,14 @@ static void spider_ack_irq(unsigned int virq)
120 out_be32(pic->regs + TIR_EDC, 0x100 | (src & 0xf)); 114 out_be32(pic->regs + TIR_EDC, 0x100 | (src & 0xf));
121} 115}
122 116
123static struct irq_chip spider_pic = { 117static int spider_set_irq_type(unsigned int virq, unsigned int type)
124 .typename = " SPIDER ",
125 .unmask = spider_unmask_irq,
126 .mask = spider_mask_irq,
127 .ack = spider_ack_irq,
128};
129
130static int spider_host_match(struct irq_host *h, struct device_node *node)
131{
132 struct spider_pic *pic = h->host_data;
133 return node == pic->of_node;
134}
135
136static int spider_host_map(struct irq_host *h, unsigned int virq,
137 irq_hw_number_t hw, unsigned int flags)
138{ 118{
139 unsigned int sense = flags & IRQ_TYPE_SENSE_MASK; 119 unsigned int sense = type & IRQ_TYPE_SENSE_MASK;
140 struct spider_pic *pic = h->host_data; 120 struct spider_pic *pic = spider_virq_to_pic(virq);
121 unsigned int hw = irq_map[virq].hwirq;
141 void __iomem *cfg = spider_get_irq_config(pic, hw); 122 void __iomem *cfg = spider_get_irq_config(pic, hw);
142 int level = 0; 123 struct irq_desc *desc = get_irq_desc(virq);
124 u32 old_mask;
143 u32 ic; 125 u32 ic;
144 126
145 /* Note that only level high is supported for most interrupts */ 127 /* 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,
157 break; 139 break;
158 case IRQ_TYPE_LEVEL_LOW: 140 case IRQ_TYPE_LEVEL_LOW:
159 ic = 0x0; 141 ic = 0x0;
160 level = 1;
161 break; 142 break;
162 case IRQ_TYPE_LEVEL_HIGH: 143 case IRQ_TYPE_LEVEL_HIGH:
163 case IRQ_TYPE_NONE: 144 case IRQ_TYPE_NONE:
164 ic = 0x1; 145 ic = 0x1;
165 level = 1;
166 break; 146 break;
167 default: 147 default:
168 return -EINVAL; 148 return -EINVAL;
169 } 149 }
170 150
151 /* Update irq_desc */
152 desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
153 desc->status |= type & IRQ_TYPE_SENSE_MASK;
154 if (type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
155 desc->status |= IRQ_LEVEL;
156
171 /* Configure the source. One gross hack that was there before and 157 /* Configure the source. One gross hack that was there before and
172 * that I've kept around is the priority to the BE which I set to 158 * that I've kept around is the priority to the BE which I set to
173 * be the same as the interrupt source number. I don't know wether 159 * be the same as the interrupt source number. I don't know wether
174 * that's supposed to make any kind of sense however, we'll have to 160 * that's supposed to make any kind of sense however, we'll have to
175 * decide that, but for now, I'm not changing the behaviour. 161 * decide that, but for now, I'm not changing the behaviour.
176 */ 162 */
177 out_be32(cfg, (ic << 24) | (0x7 << 16) | (pic->node_id << 4) | 0xe); 163 old_mask = in_be32(cfg) & 0x30000000u;
164 out_be32(cfg, old_mask | (ic << 24) | (0x7 << 16) |
165 (pic->node_id << 4) | 0xe);
178 out_be32(cfg + 4, (0x2 << 16) | (hw & 0xff)); 166 out_be32(cfg + 4, (0x2 << 16) | (hw & 0xff));
179 167
180 if (level) 168 return 0;
181 get_irq_desc(virq)->status |= IRQ_LEVEL; 169}
170
171static struct irq_chip spider_pic = {
172 .typename = " SPIDER ",
173 .unmask = spider_unmask_irq,
174 .mask = spider_mask_irq,
175 .ack = spider_ack_irq,
176 .set_type = spider_set_irq_type,
177};
178
179static int spider_host_match(struct irq_host *h, struct device_node *node)
180{
181 struct spider_pic *pic = h->host_data;
182 return node == pic->of_node;
183}
184
185static int spider_host_map(struct irq_host *h, unsigned int virq,
186 irq_hw_number_t hw)
187{
182 set_irq_chip_and_handler(virq, &spider_pic, handle_level_irq); 188 set_irq_chip_and_handler(virq, &spider_pic, handle_level_irq);
189
190 /* Set default irq type */
191 set_irq_type(virq, IRQ_TYPE_NONE);
192
183 return 0; 193 return 0;
184} 194}
185 195
@@ -283,7 +293,7 @@ static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic)
283 if (iic_host == NULL) 293 if (iic_host == NULL)
284 return NO_IRQ; 294 return NO_IRQ;
285 /* Manufacture an IIC interrupt number of class 2 */ 295 /* Manufacture an IIC interrupt number of class 2 */
286 virq = irq_create_mapping(iic_host, 0x20 | unit, 0); 296 virq = irq_create_mapping(iic_host, 0x20 | unit);
287 if (virq == NO_IRQ) 297 if (virq == NO_IRQ)
288 printk(KERN_ERR "spider_pic: failed to map cascade !"); 298 printk(KERN_ERR "spider_pic: failed to map cascade !");
289 return virq; 299 return virq;
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index 86d55675e1d2..3bd36d46ab4a 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)
583 spu->isrc = isrc = tmp[0]; 583 spu->isrc = isrc = tmp[0];
584 584
585 /* Now map interrupts of all 3 classes */ 585 /* Now map interrupts of all 3 classes */
586 spu->irqs[0] = irq_create_mapping(host, 0x00 | isrc, 0); 586 spu->irqs[0] = irq_create_mapping(host, 0x00 | isrc);
587 spu->irqs[1] = irq_create_mapping(host, 0x10 | isrc, 0); 587 spu->irqs[1] = irq_create_mapping(host, 0x10 | isrc);
588 spu->irqs[2] = irq_create_mapping(host, 0x20 | isrc, 0); 588 spu->irqs[2] = irq_create_mapping(host, 0x20 | isrc);
589 589
590 /* Right now, we only fail if class 2 failed */ 590 /* Right now, we only fail if class 2 failed */
591 return spu->irqs[2] == NO_IRQ ? -EINVAL : 0; 591 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 2275e64f3152..e32446877e78 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,
300 realirq = (((((sub_bus << 8) + (bus - 1)) << 3) + (idsel - 1)) << 3) 300 realirq = (((((sub_bus << 8) + (bus - 1)) << 3) + (idsel - 1)) << 3)
301 + function; 301 + function;
302 302
303 return irq_create_mapping(NULL, realirq, IRQ_TYPE_NONE); 303 return irq_create_mapping(NULL, realirq);
304} 304}
305 305
306#endif /* CONFIG_PCI */ 306#endif /* CONFIG_PCI */
@@ -341,7 +341,7 @@ unsigned int iSeries_get_irq(struct pt_regs *regs)
341} 341}
342 342
343static int iseries_irq_host_map(struct irq_host *h, unsigned int virq, 343static int iseries_irq_host_map(struct irq_host *h, unsigned int virq,
344 irq_hw_number_t hw, unsigned int flags) 344 irq_hw_number_t hw)
345{ 345{
346 set_irq_chip_and_handler(virq, &iseries_pic, handle_fasteoi_irq); 346 set_irq_chip_and_handler(virq, &iseries_pic, handle_fasteoi_irq);
347 347
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c
index ecc764a3ff3a..fe6b9bff61b9 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)
215 * in Maple device-tree where the type of the controller is 215 * in Maple device-tree where the type of the controller is
216 * open-pic and not interrupt-controller 216 * open-pic and not interrupt-controller
217 */ 217 */
218 for_each_node_by_type(np, "open-pic") { 218
219 mpic_node = np; 219 for_each_node_by_type(np, "interrupt-controller")
220 break; 220 if (device_is_compatible(np, "open-pic")) {
221 } 221 mpic_node = np;
222 break;
223 }
224 if (mpic_node == NULL)
225 for_each_node_by_type(np, "open-pic") {
226 mpic_node = np;
227 break;
228 }
222 if (mpic_node == NULL) { 229 if (mpic_node == NULL) {
223 printk(KERN_ERR 230 printk(KERN_ERR
224 "Failed to locate the MPIC interrupt controller\n"); 231 "Failed to locate the MPIC interrupt controller\n");
@@ -245,6 +252,8 @@ static void __init maple_init_IRQ(void)
245 252
246 /* XXX Maple specific bits */ 253 /* XXX Maple specific bits */
247 flags |= MPIC_BROKEN_U3 | MPIC_WANTS_RESET; 254 flags |= MPIC_BROKEN_U3 | MPIC_WANTS_RESET;
255 /* All U3/U4 are big-endian, older SLOF firmware doesn't encode this */
256 flags |= MPIC_BIG_ENDIAN;
248 257
249 /* Setup the openpic driver. More device-tree junks, we hard code no 258 /* Setup the openpic driver. More device-tree junks, we hard code no
250 * ISUs for now. I'll have to revisit some stuffs with the folks doing 259 * 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 205b4a392862..afa593a8544a 100644
--- a/arch/powerpc/platforms/powermac/backlight.c
+++ b/arch/powerpc/platforms/powermac/backlight.c
@@ -10,11 +10,33 @@
10#include <linux/kernel.h> 10#include <linux/kernel.h>
11#include <linux/fb.h> 11#include <linux/fb.h>
12#include <linux/backlight.h> 12#include <linux/backlight.h>
13#include <linux/adb.h>
14#include <linux/pmu.h>
15#include <asm/atomic.h>
13#include <asm/prom.h> 16#include <asm/prom.h>
14#include <asm/backlight.h> 17#include <asm/backlight.h>
15 18
16#define OLD_BACKLIGHT_MAX 15 19#define OLD_BACKLIGHT_MAX 15
17 20
21static void pmac_backlight_key_worker(void *data);
22static void pmac_backlight_set_legacy_worker(void *data);
23
24static DECLARE_WORK(pmac_backlight_key_work, pmac_backlight_key_worker, NULL);
25static DECLARE_WORK(pmac_backlight_set_legacy_work, pmac_backlight_set_legacy_worker, NULL);
26
27/* Although these variables are used in interrupt context, it makes no sense to
28 * protect them. No user is able to produce enough key events per second and
29 * notice the errors that might happen.
30 */
31static int pmac_backlight_key_queued;
32static int pmac_backlight_set_legacy_queued;
33
34/* The via-pmu code allows the backlight to be grabbed, in which case the
35 * in-kernel control of the brightness needs to be disabled. This should
36 * only be used by really old PowerBooks.
37 */
38static atomic_t kernel_backlight_disabled = ATOMIC_INIT(0);
39
18/* Protect the pmac_backlight variable */ 40/* Protect the pmac_backlight variable */
19DEFINE_MUTEX(pmac_backlight_mutex); 41DEFINE_MUTEX(pmac_backlight_mutex);
20 42
@@ -72,8 +94,11 @@ int pmac_backlight_curve_lookup(struct fb_info *info, int value)
72 return level; 94 return level;
73} 95}
74 96
75static void pmac_backlight_key(int direction) 97static void pmac_backlight_key_worker(void *data)
76{ 98{
99 if (atomic_read(&kernel_backlight_disabled))
100 return;
101
77 mutex_lock(&pmac_backlight_mutex); 102 mutex_lock(&pmac_backlight_mutex);
78 if (pmac_backlight) { 103 if (pmac_backlight) {
79 struct backlight_properties *props; 104 struct backlight_properties *props;
@@ -83,7 +108,8 @@ static void pmac_backlight_key(int direction)
83 props = pmac_backlight->props; 108 props = pmac_backlight->props;
84 109
85 brightness = props->brightness + 110 brightness = props->brightness +
86 ((direction?-1:1) * (props->max_brightness / 15)); 111 ((pmac_backlight_key_queued?-1:1) *
112 (props->max_brightness / 15));
87 113
88 if (brightness < 0) 114 if (brightness < 0)
89 brightness = 0; 115 brightness = 0;
@@ -98,17 +124,20 @@ static void pmac_backlight_key(int direction)
98 mutex_unlock(&pmac_backlight_mutex); 124 mutex_unlock(&pmac_backlight_mutex);
99} 125}
100 126
101void pmac_backlight_key_up() 127/* This function is called in interrupt context */
128void pmac_backlight_key(int direction)
102{ 129{
103 pmac_backlight_key(0); 130 if (atomic_read(&kernel_backlight_disabled))
131 return;
132
133 /* we can receive multiple interrupts here, but the scheduled work
134 * will run only once, with the last value
135 */
136 pmac_backlight_key_queued = direction;
137 schedule_work(&pmac_backlight_key_work);
104} 138}
105 139
106void pmac_backlight_key_down() 140static int __pmac_backlight_set_legacy_brightness(int brightness)
107{
108 pmac_backlight_key(1);
109}
110
111int pmac_backlight_set_legacy_brightness(int brightness)
112{ 141{
113 int error = -ENXIO; 142 int error = -ENXIO;
114 143
@@ -137,6 +166,28 @@ int pmac_backlight_set_legacy_brightness(int brightness)
137 return error; 166 return error;
138} 167}
139 168
169static void pmac_backlight_set_legacy_worker(void *data)
170{
171 if (atomic_read(&kernel_backlight_disabled))
172 return;
173
174 __pmac_backlight_set_legacy_brightness(pmac_backlight_set_legacy_queued);
175}
176
177/* This function is called in interrupt context */
178void pmac_backlight_set_legacy_brightness_pmu(int brightness) {
179 if (atomic_read(&kernel_backlight_disabled))
180 return;
181
182 pmac_backlight_set_legacy_queued = brightness;
183 schedule_work(&pmac_backlight_set_legacy_work);
184}
185
186int pmac_backlight_set_legacy_brightness(int brightness)
187{
188 return __pmac_backlight_set_legacy_brightness(brightness);
189}
190
140int pmac_backlight_get_legacy_brightness() 191int pmac_backlight_get_legacy_brightness()
141{ 192{
142 int result = -ENXIO; 193 int result = -ENXIO;
@@ -158,3 +209,17 @@ int pmac_backlight_get_legacy_brightness()
158 209
159 return result; 210 return result;
160} 211}
212
213void pmac_backlight_disable()
214{
215 atomic_inc(&kernel_backlight_disabled);
216}
217
218void pmac_backlight_enable()
219{
220 atomic_dec(&kernel_backlight_disabled);
221}
222
223EXPORT_SYMBOL_GPL(pmac_backlight);
224EXPORT_SYMBOL_GPL(pmac_backlight_mutex);
225EXPORT_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 c364c89adb4e..167cd3ce8a13 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);
87static DEFINE_MUTEX(g5_switch_mutex); 87static DEFINE_MUTEX(g5_switch_mutex);
88 88
89 89
90#ifdef CONFIG_PPC_SMU 90#ifdef CONFIG_PMAC_SMU
91 91
92static const u32 *g5_pmode_data; 92static u32 *g5_pmode_data;
93static int g5_pmode_max; 93static int g5_pmode_max;
94 94
95static struct smu_sdbp_fvt *g5_fvt_table; /* table of op. points */ 95static struct smu_sdbp_fvt *g5_fvt_table; /* table of op. points */
@@ -216,7 +216,7 @@ static void g5_dummy_switch_volt(int speed_mode)
216{ 216{
217} 217}
218 218
219#endif /* CONFIG_PPC_SMU */ 219#endif /* CONFIG_PMAC_SMU */
220 220
221/* 221/*
222 * Platform function based voltage switching for PowerMac7,2 & 7,3 222 * Platform function based voltage switching for PowerMac7,2 & 7,3
@@ -383,7 +383,7 @@ static struct cpufreq_driver g5_cpufreq_driver = {
383}; 383};
384 384
385 385
386#ifdef CONFIG_PPC_SMU 386#ifdef CONFIG_PMAC_SMU
387 387
388static int __init g5_neo2_cpufreq_init(struct device_node *cpus) 388static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
389{ 389{
@@ -535,7 +535,7 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
535 return rc; 535 return rc;
536} 536}
537 537
538#endif /* CONFIG_PPC_SMU */ 538#endif /* CONFIG_PMAC_SMU */
539 539
540 540
541static int __init g5_pm72_cpufreq_init(struct device_node *cpus) 541static int __init g5_pm72_cpufreq_init(struct device_node *cpus)
@@ -731,10 +731,10 @@ static int __init g5_cpufreq_init(void)
731 machine_is_compatible("PowerMac7,3") || 731 machine_is_compatible("PowerMac7,3") ||
732 machine_is_compatible("RackMac3,1")) 732 machine_is_compatible("RackMac3,1"))
733 rc = g5_pm72_cpufreq_init(cpus); 733 rc = g5_pm72_cpufreq_init(cpus);
734#ifdef CONFIG_PPC_SMU 734#ifdef CONFIG_PMAC_SMU
735 else 735 else
736 rc = g5_neo2_cpufreq_init(cpus); 736 rc = g5_neo2_cpufreq_init(cpus);
737#endif /* CONFIG_PPC_SMU */ 737#endif /* CONFIG_PMAC_SMU */
738 738
739 of_node_put(cpus); 739 of_node_put(cpus);
740 return rc; 740 return rc;
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index 787ffd999bc2..9923adc5248e 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -16,6 +16,7 @@
16#include <linux/string.h> 16#include <linux/string.h>
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/bootmem.h> 18#include <linux/bootmem.h>
19#include <linux/irq.h>
19 20
20#include <asm/sections.h> 21#include <asm/sections.h>
21#include <asm/io.h> 22#include <asm/io.h>
@@ -24,10 +25,7 @@
24#include <asm/machdep.h> 25#include <asm/machdep.h>
25#include <asm/pmac_feature.h> 26#include <asm/pmac_feature.h>
26#include <asm/grackle.h> 27#include <asm/grackle.h>
27#ifdef CONFIG_PPC64
28//#include <asm/iommu.h>
29#include <asm/ppc-pci.h> 28#include <asm/ppc-pci.h>
30#endif
31 29
32#undef DEBUG 30#undef DEBUG
33 31
@@ -46,7 +44,6 @@ static int has_uninorth;
46static struct pci_controller *u3_agp; 44static struct pci_controller *u3_agp;
47static struct pci_controller *u4_pcie; 45static struct pci_controller *u4_pcie;
48static struct pci_controller *u3_ht; 46static struct pci_controller *u3_ht;
49#define has_second_ohare 0
50#else 47#else
51static int has_second_ohare; 48static int has_second_ohare;
52#endif /* CONFIG_PPC64 */ 49#endif /* CONFIG_PPC64 */
@@ -996,6 +993,7 @@ void __init pmac_pcibios_fixup(void)
996 /* Read interrupt from the device-tree */ 993 /* Read interrupt from the device-tree */
997 pci_read_irq_line(dev); 994 pci_read_irq_line(dev);
998 995
996#ifdef CONFIG_PPC32
999 /* Fixup interrupt for the modem/ethernet combo controller. 997 /* Fixup interrupt for the modem/ethernet combo controller.
1000 * on machines with a second ohare chip. 998 * on machines with a second ohare chip.
1001 * The number in the device tree (27) is bogus (correct for 999 * The number in the device tree (27) is bogus (correct for
@@ -1005,8 +1003,11 @@ void __init pmac_pcibios_fixup(void)
1005 */ 1003 */
1006 if (has_second_ohare && 1004 if (has_second_ohare &&
1007 dev->vendor == PCI_VENDOR_ID_DEC && 1005 dev->vendor == PCI_VENDOR_ID_DEC &&
1008 dev->device == PCI_DEVICE_ID_DEC_TULIP_PLUS) 1006 dev->device == PCI_DEVICE_ID_DEC_TULIP_PLUS) {
1009 dev->irq = irq_create_mapping(NULL, 60, 0); 1007 dev->irq = irq_create_mapping(NULL, 60);
1008 set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW);
1009 }
1010#endif /* CONFIG_PPC32 */
1010 } 1011 }
1011} 1012}
1012 1013
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 3d328bc1f7e0..060789e31c67 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)
291} 291}
292 292
293static int pmac_pic_host_map(struct irq_host *h, unsigned int virq, 293static int pmac_pic_host_map(struct irq_host *h, unsigned int virq,
294 irq_hw_number_t hw, unsigned int flags) 294 irq_hw_number_t hw)
295{ 295{
296 struct irq_desc *desc = get_irq_desc(virq); 296 struct irq_desc *desc = get_irq_desc(virq);
297 int level; 297 int level;
@@ -318,6 +318,7 @@ static int pmac_pic_host_xlate(struct irq_host *h, struct device_node *ct,
318 unsigned int *out_flags) 318 unsigned int *out_flags)
319 319
320{ 320{
321 *out_flags = IRQ_TYPE_NONE;
321 *out_hwirq = *intspec; 322 *out_hwirq = *intspec;
322 return 0; 323 return 0;
323} 324}
@@ -434,7 +435,7 @@ static void __init pmac_pic_probe_oldstyle(void)
434 435
435 printk(KERN_INFO "irq: System has %d possible interrupts\n", max_irqs); 436 printk(KERN_INFO "irq: System has %d possible interrupts\n", max_irqs);
436#ifdef CONFIG_XMON 437#ifdef CONFIG_XMON
437 setup_irq(irq_create_mapping(NULL, 20, 0), &xmon_action); 438 setup_irq(irq_create_mapping(NULL, 20), &xmon_action);
438#endif 439#endif
439} 440}
440#endif /* CONFIG_PPC32 */ 441#endif /* CONFIG_PPC32 */
@@ -579,9 +580,10 @@ void __init pmac_pic_init(void)
579 flags |= OF_IMAP_OLDWORLD_MAC; 580 flags |= OF_IMAP_OLDWORLD_MAC;
580 if (get_property(of_chosen, "linux,bootx", NULL) != NULL) 581 if (get_property(of_chosen, "linux,bootx", NULL) != NULL)
581 flags |= OF_IMAP_NO_PHANDLE; 582 flags |= OF_IMAP_NO_PHANDLE;
582 of_irq_map_init(flags);
583#endif /* CONFIG_PPC_32 */ 583#endif /* CONFIG_PPC_32 */
584 584
585 of_irq_map_init(flags);
586
585 /* We first try to detect Apple's new Core99 chipset, since mac-io 587 /* We first try to detect Apple's new Core99 chipset, since mac-io
586 * is quite different on those machines and contains an IBM MPIC2. 588 * is quite different on those machines and contains an IBM MPIC2.
587 */ 589 */
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
index 0e6339ee45a1..903115d67fdc 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,
93 for (i = 0; i < opicplen; i++) { 93 for (i = 0; i < opicplen; i++) {
94 if (count > 15) 94 if (count > 15)
95 break; 95 break;
96 virqs[count] = irq_create_mapping(NULL, *(opicprop++), 96 virqs[count] = irq_create_mapping(NULL, *(opicprop++));
97 IRQ_TYPE_NONE);
98 if (virqs[count] == NO_IRQ) 97 if (virqs[count] == NO_IRQ)
99 printk(KERN_ERR "Unable to allocate interrupt " 98 printk(KERN_ERR "Unable to allocate interrupt "
100 "number for %s\n", np->full_name); 99 "number for %s\n", np->full_name);
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 927e0a423b87..de214d86ff44 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)
501 } 501 }
502 502
503 /* 503 /*
504 * Cede if the other thread is not idle, so that it can 504 * If not SMT, cede processor. If CPU is running SMT
505 * cede if the other thread is not idle, so that it can
505 * go single-threaded. If the other thread is idle, 506 * go single-threaded. If the other thread is idle,
506 * we ask the hypervisor if it has pending work it 507 * we ask the hypervisor if it has pending work it
507 * wants to do and cede if it does. Otherwise we keep 508 * wants to do and cede if it does. Otherwise we keep
@@ -514,7 +515,8 @@ static void pseries_dedicated_idle_sleep(void)
514 * very low priority. The cede enables interrupts, which 515 * very low priority. The cede enables interrupts, which
515 * doesn't matter here. 516 * doesn't matter here.
516 */ 517 */
517 if (!lppaca[cpu ^ 1].idle || poll_pending() == H_PENDING) 518 if (!cpu_has_feature(CPU_FTR_SMT) || !lppaca[cpu ^ 1].idle
519 || poll_pending() == H_PENDING)
518 cede_processor(); 520 cede_processor();
519 521
520out: 522out:
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 756421049441..1eab4688be17 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)
502} 502}
503 503
504static int xics_host_map_direct(struct irq_host *h, unsigned int virq, 504static int xics_host_map_direct(struct irq_host *h, unsigned int virq,
505 irq_hw_number_t hw, unsigned int flags) 505 irq_hw_number_t hw)
506{ 506{
507 unsigned int sense = flags & IRQ_TYPE_SENSE_MASK; 507 pr_debug("xics: map_direct virq %d, hwirq 0x%lx\n", virq, hw);
508
509 pr_debug("xics: map_direct virq %d, hwirq 0x%lx, flags: 0x%x\n",
510 virq, hw, flags);
511
512 if (sense && sense != IRQ_TYPE_LEVEL_LOW)
513 printk(KERN_WARNING "xics: using unsupported sense 0x%x"
514 " for irq %d (h: 0x%lx)\n", flags, virq, hw);
515 508
516 get_irq_desc(virq)->status |= IRQ_LEVEL; 509 get_irq_desc(virq)->status |= IRQ_LEVEL;
517 set_irq_chip_and_handler(virq, &xics_pic_direct, handle_fasteoi_irq); 510 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,
519} 512}
520 513
521static int xics_host_map_lpar(struct irq_host *h, unsigned int virq, 514static int xics_host_map_lpar(struct irq_host *h, unsigned int virq,
522 irq_hw_number_t hw, unsigned int flags) 515 irq_hw_number_t hw)
523{ 516{
524 unsigned int sense = flags & IRQ_TYPE_SENSE_MASK; 517 pr_debug("xics: map_direct virq %d, hwirq 0x%lx\n", virq, hw);
525
526 pr_debug("xics: map_lpar virq %d, hwirq 0x%lx, flags: 0x%x\n",
527 virq, hw, flags);
528
529 if (sense && sense != IRQ_TYPE_LEVEL_LOW)
530 printk(KERN_WARNING "xics: using unsupported sense 0x%x"
531 " for irq %d (h: 0x%lx)\n", flags, virq, hw);
532 518
533 get_irq_desc(virq)->status |= IRQ_LEVEL; 519 get_irq_desc(virq)->status |= IRQ_LEVEL;
534 set_irq_chip_and_handler(virq, &xics_pic_lpar, handle_fasteoi_irq); 520 set_irq_chip_and_handler(virq, &xics_pic_lpar, handle_fasteoi_irq);
@@ -757,7 +743,7 @@ void xics_request_IPIs(void)
757{ 743{
758 unsigned int ipi; 744 unsigned int ipi;
759 745
760 ipi = irq_create_mapping(xics_host, XICS_IPI, 0); 746 ipi = irq_create_mapping(xics_host, XICS_IPI);
761 BUG_ON(ipi == NO_IRQ); 747 BUG_ON(ipi == NO_IRQ);
762 748
763 /* 749 /*
@@ -783,6 +769,14 @@ void xics_teardown_cpu(int secondary)
783 xics_set_cpu_priority(cpu, 0); 769 xics_set_cpu_priority(cpu, 0);
784 770
785 /* 771 /*
772 * Clear IPI
773 */
774 if (firmware_has_feature(FW_FEATURE_LPAR))
775 lpar_qirr_info(cpu, 0xff);
776 else
777 direct_qirr_info(cpu, 0xff);
778
779 /*
786 * we need to EOI the IPI if we got here from kexec down IPI 780 * we need to EOI the IPI if we got here from kexec down IPI
787 * 781 *
788 * probably need to check all the other interrupts too 782 * probably need to check all the other interrupts too
@@ -795,7 +789,7 @@ void xics_teardown_cpu(int secondary)
795 return; 789 return;
796 desc = get_irq_desc(ipi); 790 desc = get_irq_desc(ipi);
797 if (desc->chip && desc->chip->eoi) 791 if (desc->chip && desc->chip->eoi)
798 desc->chip->eoi(XICS_IPI); 792 desc->chip->eoi(ipi);
799 793
800 /* 794 /*
801 * Some machines need to have at least one cpu in the GIQ, 795 * Some machines need to have at least one cpu in the GIQ,