aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/pseries
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/pseries')
-rw-r--r--arch/powerpc/platforms/pseries/Makefile1
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c5
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c25
-rw-r--r--arch/powerpc/platforms/pseries/pci_dlpar.c2
-rw-r--r--arch/powerpc/platforms/pseries/phyp_dump.c507
-rw-r--r--arch/powerpc/platforms/pseries/pseries.h2
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c12
-rw-r--r--arch/powerpc/platforms/pseries/scanlog.c37
-rw-r--r--arch/powerpc/platforms/pseries/setup.c105
-rw-r--r--arch/powerpc/platforms/pseries/xics.c87
-rw-r--r--arch/powerpc/platforms/pseries/xics.h3
11 files changed, 628 insertions, 158 deletions
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index 992ba6753cf2..bdae04bb7a01 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -18,3 +18,4 @@ obj-$(CONFIG_HOTPLUG_CPU) += hotplug-cpu.o
18obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o 18obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o
19obj-$(CONFIG_HVCS) += hvcserver.o 19obj-$(CONFIG_HVCS) += hvcserver.o
20obj-$(CONFIG_HCALL_STATS) += hvCall_inst.o 20obj-$(CONFIG_HCALL_STATS) += hvCall_inst.o
21obj-$(CONFIG_PHYP_DUMP) += phyp_dump.o
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 9eb539ee5f9a..550b2f7d2cc1 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -945,7 +945,6 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
945 unsigned int rets[3]; 945 unsigned int rets[3];
946 struct eeh_early_enable_info *info = data; 946 struct eeh_early_enable_info *info = data;
947 int ret; 947 int ret;
948 const char *status = of_get_property(dn, "status", NULL);
949 const u32 *class_code = of_get_property(dn, "class-code", NULL); 948 const u32 *class_code = of_get_property(dn, "class-code", NULL);
950 const u32 *vendor_id = of_get_property(dn, "vendor-id", NULL); 949 const u32 *vendor_id = of_get_property(dn, "vendor-id", NULL);
951 const u32 *device_id = of_get_property(dn, "device-id", NULL); 950 const u32 *device_id = of_get_property(dn, "device-id", NULL);
@@ -959,8 +958,8 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
959 pdn->eeh_freeze_count = 0; 958 pdn->eeh_freeze_count = 0;
960 pdn->eeh_false_positives = 0; 959 pdn->eeh_false_positives = 0;
961 960
962 if (status && strncmp(status, "ok", 2) != 0) 961 if (!of_device_is_available(dn))
963 return NULL; /* ignore devices with bad status */ 962 return NULL;
964 963
965 /* Ignore bad nodes. */ 964 /* Ignore bad nodes. */
966 if (!class_code || !vendor_id || !device_id) 965 if (!class_code || !vendor_id || !device_id)
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 9a455d46379d..9235c469449e 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -40,6 +40,7 @@
40#include <asm/smp.h> 40#include <asm/smp.h>
41 41
42#include "plpar_wrappers.h" 42#include "plpar_wrappers.h"
43#include "pseries.h"
43 44
44#ifdef DEBUG_LOW 45#ifdef DEBUG_LOW
45#define DBG_LOW(fmt...) do { udbg_printf(fmt); } while(0) 46#define DBG_LOW(fmt...) do { udbg_printf(fmt); } while(0)
@@ -203,7 +204,6 @@ void __init find_udbg_vterm(void)
203 struct device_node *stdout_node; 204 struct device_node *stdout_node;
204 const u32 *termno; 205 const u32 *termno;
205 const char *name; 206 const char *name;
206 int add_console;
207 207
208 /* find the boot console from /chosen/stdout */ 208 /* find the boot console from /chosen/stdout */
209 if (!of_chosen) 209 if (!of_chosen)
@@ -219,8 +219,6 @@ void __init find_udbg_vterm(void)
219 printk(KERN_WARNING "stdout node missing 'name' property!\n"); 219 printk(KERN_WARNING "stdout node missing 'name' property!\n");
220 goto out; 220 goto out;
221 } 221 }
222 /* The user has requested a console so this is already set up. */
223 add_console = !strstr(cmd_line, "console=");
224 222
225 /* Check if it's a virtual terminal */ 223 /* Check if it's a virtual terminal */
226 if (strncmp(name, "vty", 3) != 0) 224 if (strncmp(name, "vty", 3) != 0)
@@ -234,15 +232,13 @@ void __init find_udbg_vterm(void)
234 udbg_putc = udbg_putcLP; 232 udbg_putc = udbg_putcLP;
235 udbg_getc = udbg_getcLP; 233 udbg_getc = udbg_getcLP;
236 udbg_getc_poll = udbg_getc_pollLP; 234 udbg_getc_poll = udbg_getc_pollLP;
237 if (add_console) 235 add_preferred_console("hvc", termno[0] & 0xff, NULL);
238 add_preferred_console("hvc", termno[0] & 0xff, NULL);
239 } else if (of_device_is_compatible(stdout_node, "hvterm-protocol")) { 236 } else if (of_device_is_compatible(stdout_node, "hvterm-protocol")) {
240 vtermno = termno[0]; 237 vtermno = termno[0];
241 udbg_putc = udbg_hvsi_putc; 238 udbg_putc = udbg_hvsi_putc;
242 udbg_getc = udbg_hvsi_getc; 239 udbg_getc = udbg_hvsi_getc;
243 udbg_getc_poll = udbg_hvsi_getc_poll; 240 udbg_getc_poll = udbg_hvsi_getc_poll;
244 if (add_console) 241 add_preferred_console("hvsi", termno[0] & 0xff, NULL);
245 add_preferred_console("hvsi", termno[0] & 0xff, NULL);
246 } 242 }
247out: 243out:
248 of_node_put(stdout_node); 244 of_node_put(stdout_node);
@@ -520,6 +516,20 @@ static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
520 BUG_ON(lpar_rc != H_SUCCESS); 516 BUG_ON(lpar_rc != H_SUCCESS);
521} 517}
522 518
519static void pSeries_lpar_hpte_removebolted(unsigned long ea,
520 int psize, int ssize)
521{
522 unsigned long slot, vsid, va;
523
524 vsid = get_kernel_vsid(ea, ssize);
525 va = hpt_va(ea, vsid, ssize);
526
527 slot = pSeries_lpar_hpte_find(va, psize, ssize);
528 BUG_ON(slot == -1);
529
530 pSeries_lpar_hpte_invalidate(slot, va, psize, ssize, 0);
531}
532
523/* Flag bits for H_BULK_REMOVE */ 533/* Flag bits for H_BULK_REMOVE */
524#define HBR_REQUEST 0x4000000000000000UL 534#define HBR_REQUEST 0x4000000000000000UL
525#define HBR_RESPONSE 0x8000000000000000UL 535#define HBR_RESPONSE 0x8000000000000000UL
@@ -597,6 +607,7 @@ void __init hpte_init_lpar(void)
597 ppc_md.hpte_updateboltedpp = pSeries_lpar_hpte_updateboltedpp; 607 ppc_md.hpte_updateboltedpp = pSeries_lpar_hpte_updateboltedpp;
598 ppc_md.hpte_insert = pSeries_lpar_hpte_insert; 608 ppc_md.hpte_insert = pSeries_lpar_hpte_insert;
599 ppc_md.hpte_remove = pSeries_lpar_hpte_remove; 609 ppc_md.hpte_remove = pSeries_lpar_hpte_remove;
610 ppc_md.hpte_removebolted = pSeries_lpar_hpte_removebolted;
600 ppc_md.flush_hash_range = pSeries_lpar_flush_hash_range; 611 ppc_md.flush_hash_range = pSeries_lpar_flush_hash_range;
601 ppc_md.hpte_clear_all = pSeries_lpar_hptab_clear; 612 ppc_md.hpte_clear_all = pSeries_lpar_hptab_clear;
602} 613}
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c
index 5a5a19e40bb4..0d7229cde0e9 100644
--- a/arch/powerpc/platforms/pseries/pci_dlpar.c
+++ b/arch/powerpc/platforms/pseries/pci_dlpar.c
@@ -123,7 +123,7 @@ pcibios_pci_config_bridge(struct pci_dev *dev)
123 /* Add to children of PCI bridge dev->bus */ 123 /* Add to children of PCI bridge dev->bus */
124 child_bus = pci_add_new_bus(dev->bus, dev, sec_busno); 124 child_bus = pci_add_new_bus(dev->bus, dev, sec_busno);
125 if (!child_bus) { 125 if (!child_bus) {
126 printk (KERN_ERR "%s: could not add second bus\n", __FUNCTION__); 126 printk (KERN_ERR "%s: could not add second bus\n", __func__);
127 return -EIO; 127 return -EIO;
128 } 128 }
129 sprintf(child_bus->name, "PCI Bus #%02x", child_bus->number); 129 sprintf(child_bus->name, "PCI Bus #%02x", child_bus->number);
diff --git a/arch/powerpc/platforms/pseries/phyp_dump.c b/arch/powerpc/platforms/pseries/phyp_dump.c
new file mode 100644
index 000000000000..edbc012c2ebc
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/phyp_dump.c
@@ -0,0 +1,507 @@
1/*
2 * Hypervisor-assisted dump
3 *
4 * Linas Vepstas, Manish Ahuja 2008
5 * Copyright 2008 IBM Corp.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 *
12 */
13
14#include <linux/init.h>
15#include <linux/kobject.h>
16#include <linux/mm.h>
17#include <linux/of.h>
18#include <linux/pfn.h>
19#include <linux/swap.h>
20#include <linux/sysfs.h>
21
22#include <asm/page.h>
23#include <asm/phyp_dump.h>
24#include <asm/machdep.h>
25#include <asm/prom.h>
26#include <asm/rtas.h>
27
28/* Variables, used to communicate data between early boot and late boot */
29static struct phyp_dump phyp_dump_vars;
30struct phyp_dump *phyp_dump_info = &phyp_dump_vars;
31
32static int ibm_configure_kernel_dump;
33/* ------------------------------------------------- */
34/* RTAS interfaces to declare the dump regions */
35
36struct dump_section {
37 u32 dump_flags;
38 u16 source_type;
39 u16 error_flags;
40 u64 source_address;
41 u64 source_length;
42 u64 length_copied;
43 u64 destination_address;
44};
45
46struct phyp_dump_header {
47 u32 version;
48 u16 num_of_sections;
49 u16 status;
50
51 u32 first_offset_section;
52 u32 dump_disk_section;
53 u64 block_num_dd;
54 u64 num_of_blocks_dd;
55 u32 offset_dd;
56 u32 maxtime_to_auto;
57 /* No dump disk path string used */
58
59 struct dump_section cpu_data;
60 struct dump_section hpte_data;
61 struct dump_section kernel_data;
62};
63
64/* The dump header *must be* in low memory, so .bss it */
65static struct phyp_dump_header phdr;
66
67#define NUM_DUMP_SECTIONS 3
68#define DUMP_HEADER_VERSION 0x1
69#define DUMP_REQUEST_FLAG 0x1
70#define DUMP_SOURCE_CPU 0x0001
71#define DUMP_SOURCE_HPTE 0x0002
72#define DUMP_SOURCE_RMO 0x0011
73#define DUMP_ERROR_FLAG 0x2000
74#define DUMP_TRIGGERED 0x4000
75#define DUMP_PERFORMED 0x8000
76
77
78/**
79 * init_dump_header() - initialize the header declaring a dump
80 * Returns: length of dump save area.
81 *
82 * When the hypervisor saves crashed state, it needs to put
83 * it somewhere. The dump header tells the hypervisor where
84 * the data can be saved.
85 */
86static unsigned long init_dump_header(struct phyp_dump_header *ph)
87{
88 unsigned long addr_offset = 0;
89
90 /* Set up the dump header */
91 ph->version = DUMP_HEADER_VERSION;
92 ph->num_of_sections = NUM_DUMP_SECTIONS;
93 ph->status = 0;
94
95 ph->first_offset_section =
96 (u32)offsetof(struct phyp_dump_header, cpu_data);
97 ph->dump_disk_section = 0;
98 ph->block_num_dd = 0;
99 ph->num_of_blocks_dd = 0;
100 ph->offset_dd = 0;
101
102 ph->maxtime_to_auto = 0; /* disabled */
103
104 /* The first two sections are mandatory */
105 ph->cpu_data.dump_flags = DUMP_REQUEST_FLAG;
106 ph->cpu_data.source_type = DUMP_SOURCE_CPU;
107 ph->cpu_data.source_address = 0;
108 ph->cpu_data.source_length = phyp_dump_info->cpu_state_size;
109 ph->cpu_data.destination_address = addr_offset;
110 addr_offset += phyp_dump_info->cpu_state_size;
111
112 ph->hpte_data.dump_flags = DUMP_REQUEST_FLAG;
113 ph->hpte_data.source_type = DUMP_SOURCE_HPTE;
114 ph->hpte_data.source_address = 0;
115 ph->hpte_data.source_length = phyp_dump_info->hpte_region_size;
116 ph->hpte_data.destination_address = addr_offset;
117 addr_offset += phyp_dump_info->hpte_region_size;
118
119 /* This section describes the low kernel region */
120 ph->kernel_data.dump_flags = DUMP_REQUEST_FLAG;
121 ph->kernel_data.source_type = DUMP_SOURCE_RMO;
122 ph->kernel_data.source_address = PHYP_DUMP_RMR_START;
123 ph->kernel_data.source_length = PHYP_DUMP_RMR_END;
124 ph->kernel_data.destination_address = addr_offset;
125 addr_offset += ph->kernel_data.source_length;
126
127 return addr_offset;
128}
129
130static void print_dump_header(const struct phyp_dump_header *ph)
131{
132#ifdef DEBUG
133 printk(KERN_INFO "dump header:\n");
134 /* setup some ph->sections required */
135 printk(KERN_INFO "version = %d\n", ph->version);
136 printk(KERN_INFO "Sections = %d\n", ph->num_of_sections);
137 printk(KERN_INFO "Status = 0x%x\n", ph->status);
138
139 /* No ph->disk, so all should be set to 0 */
140 printk(KERN_INFO "Offset to first section 0x%x\n",
141 ph->first_offset_section);
142 printk(KERN_INFO "dump disk sections should be zero\n");
143 printk(KERN_INFO "dump disk section = %d\n", ph->dump_disk_section);
144 printk(KERN_INFO "block num = %ld\n", ph->block_num_dd);
145 printk(KERN_INFO "number of blocks = %ld\n", ph->num_of_blocks_dd);
146 printk(KERN_INFO "dump disk offset = %d\n", ph->offset_dd);
147 printk(KERN_INFO "Max auto time= %d\n", ph->maxtime_to_auto);
148
149 /*set cpu state and hpte states as well scratch pad area */
150 printk(KERN_INFO " CPU AREA \n");
151 printk(KERN_INFO "cpu dump_flags =%d\n", ph->cpu_data.dump_flags);
152 printk(KERN_INFO "cpu source_type =%d\n", ph->cpu_data.source_type);
153 printk(KERN_INFO "cpu error_flags =%d\n", ph->cpu_data.error_flags);
154 printk(KERN_INFO "cpu source_address =%lx\n",
155 ph->cpu_data.source_address);
156 printk(KERN_INFO "cpu source_length =%lx\n",
157 ph->cpu_data.source_length);
158 printk(KERN_INFO "cpu length_copied =%lx\n",
159 ph->cpu_data.length_copied);
160
161 printk(KERN_INFO " HPTE AREA \n");
162 printk(KERN_INFO "HPTE dump_flags =%d\n", ph->hpte_data.dump_flags);
163 printk(KERN_INFO "HPTE source_type =%d\n", ph->hpte_data.source_type);
164 printk(KERN_INFO "HPTE error_flags =%d\n", ph->hpte_data.error_flags);
165 printk(KERN_INFO "HPTE source_address =%lx\n",
166 ph->hpte_data.source_address);
167 printk(KERN_INFO "HPTE source_length =%lx\n",
168 ph->hpte_data.source_length);
169 printk(KERN_INFO "HPTE length_copied =%lx\n",
170 ph->hpte_data.length_copied);
171
172 printk(KERN_INFO " SRSD AREA \n");
173 printk(KERN_INFO "SRSD dump_flags =%d\n", ph->kernel_data.dump_flags);
174 printk(KERN_INFO "SRSD source_type =%d\n", ph->kernel_data.source_type);
175 printk(KERN_INFO "SRSD error_flags =%d\n", ph->kernel_data.error_flags);
176 printk(KERN_INFO "SRSD source_address =%lx\n",
177 ph->kernel_data.source_address);
178 printk(KERN_INFO "SRSD source_length =%lx\n",
179 ph->kernel_data.source_length);
180 printk(KERN_INFO "SRSD length_copied =%lx\n",
181 ph->kernel_data.length_copied);
182#endif
183}
184
185static ssize_t show_phyp_dump_active(struct kobject *kobj,
186 struct kobj_attribute *attr, char *buf)
187{
188
189 /* create filesystem entry so kdump is phyp-dump aware */
190 return sprintf(buf, "%lx\n", phyp_dump_info->phyp_dump_at_boot);
191}
192
193static struct kobj_attribute pdl = __ATTR(phyp_dump_active, 0600,
194 show_phyp_dump_active,
195 NULL);
196
197static void register_dump_area(struct phyp_dump_header *ph, unsigned long addr)
198{
199 int rc;
200
201 /* Add addr value if not initialized before */
202 if (ph->cpu_data.destination_address == 0) {
203 ph->cpu_data.destination_address += addr;
204 ph->hpte_data.destination_address += addr;
205 ph->kernel_data.destination_address += addr;
206 }
207
208 /* ToDo Invalidate kdump and free memory range. */
209
210 do {
211 rc = rtas_call(ibm_configure_kernel_dump, 3, 1, NULL,
212 1, ph, sizeof(struct phyp_dump_header));
213 } while (rtas_busy_delay(rc));
214
215 if (rc) {
216 printk(KERN_ERR "phyp-dump: unexpected error (%d) on "
217 "register\n", rc);
218 print_dump_header(ph);
219 return;
220 }
221
222 rc = sysfs_create_file(kernel_kobj, &pdl.attr);
223 if (rc)
224 printk(KERN_ERR "phyp-dump: unable to create sysfs"
225 " file (%d)\n", rc);
226}
227
228static
229void invalidate_last_dump(struct phyp_dump_header *ph, unsigned long addr)
230{
231 int rc;
232
233 /* Add addr value if not initialized before */
234 if (ph->cpu_data.destination_address == 0) {
235 ph->cpu_data.destination_address += addr;
236 ph->hpte_data.destination_address += addr;
237 ph->kernel_data.destination_address += addr;
238 }
239
240 do {
241 rc = rtas_call(ibm_configure_kernel_dump, 3, 1, NULL,
242 2, ph, sizeof(struct phyp_dump_header));
243 } while (rtas_busy_delay(rc));
244
245 if (rc) {
246 printk(KERN_ERR "phyp-dump: unexpected error (%d) "
247 "on invalidate\n", rc);
248 print_dump_header(ph);
249 }
250}
251
252/* ------------------------------------------------- */
253/**
254 * release_memory_range -- release memory previously lmb_reserved
255 * @start_pfn: starting physical frame number
256 * @nr_pages: number of pages to free.
257 *
258 * This routine will release memory that had been previously
259 * lmb_reserved in early boot. The released memory becomes
260 * available for genreal use.
261 */
262static void release_memory_range(unsigned long start_pfn,
263 unsigned long nr_pages)
264{
265 struct page *rpage;
266 unsigned long end_pfn;
267 long i;
268
269 end_pfn = start_pfn + nr_pages;
270
271 for (i = start_pfn; i <= end_pfn; i++) {
272 rpage = pfn_to_page(i);
273 if (PageReserved(rpage)) {
274 ClearPageReserved(rpage);
275 init_page_count(rpage);
276 __free_page(rpage);
277 totalram_pages++;
278 }
279 }
280}
281
282/**
283 * track_freed_range -- Counts the range being freed.
284 * Once the counter goes to zero, it re-registers dump for
285 * future use.
286 */
287static void
288track_freed_range(unsigned long addr, unsigned long length)
289{
290 static unsigned long scratch_area_size, reserved_area_size;
291
292 if (addr < phyp_dump_info->init_reserve_start)
293 return;
294
295 if ((addr >= phyp_dump_info->init_reserve_start) &&
296 (addr <= phyp_dump_info->init_reserve_start +
297 phyp_dump_info->init_reserve_size))
298 reserved_area_size += length;
299
300 if ((addr >= phyp_dump_info->reserved_scratch_addr) &&
301 (addr <= phyp_dump_info->reserved_scratch_addr +
302 phyp_dump_info->reserved_scratch_size))
303 scratch_area_size += length;
304
305 if ((reserved_area_size == phyp_dump_info->init_reserve_size) &&
306 (scratch_area_size == phyp_dump_info->reserved_scratch_size)) {
307
308 invalidate_last_dump(&phdr,
309 phyp_dump_info->reserved_scratch_addr);
310 register_dump_area(&phdr,
311 phyp_dump_info->reserved_scratch_addr);
312 }
313}
314
315/* ------------------------------------------------- */
316/**
317 * sysfs_release_region -- sysfs interface to release memory range.
318 *
319 * Usage:
320 * "echo <start addr> <length> > /sys/kernel/release_region"
321 *
322 * Example:
323 * "echo 0x40000000 0x10000000 > /sys/kernel/release_region"
324 *
325 * will release 256MB starting at 1GB.
326 */
327static ssize_t store_release_region(struct kobject *kobj,
328 struct kobj_attribute *attr,
329 const char *buf, size_t count)
330{
331 unsigned long start_addr, length, end_addr;
332 unsigned long start_pfn, nr_pages;
333 ssize_t ret;
334
335 ret = sscanf(buf, "%lx %lx", &start_addr, &length);
336 if (ret != 2)
337 return -EINVAL;
338
339 track_freed_range(start_addr, length);
340
341 /* Range-check - don't free any reserved memory that
342 * wasn't reserved for phyp-dump */
343 if (start_addr < phyp_dump_info->init_reserve_start)
344 start_addr = phyp_dump_info->init_reserve_start;
345
346 end_addr = phyp_dump_info->init_reserve_start +
347 phyp_dump_info->init_reserve_size;
348 if (start_addr+length > end_addr)
349 length = end_addr - start_addr;
350
351 /* Release the region of memory assed in by user */
352 start_pfn = PFN_DOWN(start_addr);
353 nr_pages = PFN_DOWN(length);
354 release_memory_range(start_pfn, nr_pages);
355
356 return count;
357}
358
359static ssize_t show_release_region(struct kobject *kobj,
360 struct kobj_attribute *attr, char *buf)
361{
362 u64 second_addr_range;
363
364 /* total reserved size - start of scratch area */
365 second_addr_range = phyp_dump_info->init_reserve_size -
366 phyp_dump_info->reserved_scratch_size;
367 return sprintf(buf, "CPU:0x%lx-0x%lx: HPTE:0x%lx-0x%lx:"
368 " DUMP:0x%lx-0x%lx, 0x%lx-0x%lx:\n",
369 phdr.cpu_data.destination_address,
370 phdr.cpu_data.length_copied,
371 phdr.hpte_data.destination_address,
372 phdr.hpte_data.length_copied,
373 phdr.kernel_data.destination_address,
374 phdr.kernel_data.length_copied,
375 phyp_dump_info->init_reserve_start,
376 second_addr_range);
377}
378
379static struct kobj_attribute rr = __ATTR(release_region, 0600,
380 show_release_region,
381 store_release_region);
382
383static int __init phyp_dump_setup(void)
384{
385 struct device_node *rtas;
386 const struct phyp_dump_header *dump_header = NULL;
387 unsigned long dump_area_start;
388 unsigned long dump_area_length;
389 int header_len = 0;
390 int rc;
391
392 /* If no memory was reserved in early boot, there is nothing to do */
393 if (phyp_dump_info->init_reserve_size == 0)
394 return 0;
395
396 /* Return if phyp dump not supported */
397 if (!phyp_dump_info->phyp_dump_configured)
398 return -ENOSYS;
399
400 /* Is there dump data waiting for us? If there isn't,
401 * then register a new dump area, and release all of
402 * the rest of the reserved ram.
403 *
404 * The /rtas/ibm,kernel-dump rtas node is present only
405 * if there is dump data waiting for us.
406 */
407 rtas = of_find_node_by_path("/rtas");
408 if (rtas) {
409 dump_header = of_get_property(rtas, "ibm,kernel-dump",
410 &header_len);
411 of_node_put(rtas);
412 }
413
414 print_dump_header(dump_header);
415 dump_area_length = init_dump_header(&phdr);
416 /* align down */
417 dump_area_start = phyp_dump_info->init_reserve_start & PAGE_MASK;
418
419 if (dump_header == NULL) {
420 register_dump_area(&phdr, dump_area_start);
421 return 0;
422 }
423
424 /* re-register the dump area, if old dump was invalid */
425 if ((dump_header) && (dump_header->status & DUMP_ERROR_FLAG)) {
426 invalidate_last_dump(&phdr, dump_area_start);
427 register_dump_area(&phdr, dump_area_start);
428 return 0;
429 }
430
431 if (dump_header) {
432 phyp_dump_info->reserved_scratch_addr =
433 dump_header->cpu_data.destination_address;
434 phyp_dump_info->reserved_scratch_size =
435 dump_header->cpu_data.source_length +
436 dump_header->hpte_data.source_length +
437 dump_header->kernel_data.source_length;
438 }
439
440 /* Should we create a dump_subsys, analogous to s390/ipl.c ? */
441 rc = sysfs_create_file(kernel_kobj, &rr.attr);
442 if (rc)
443 printk(KERN_ERR "phyp-dump: unable to create sysfs file (%d)\n",
444 rc);
445
446 /* ToDo: re-register the dump area, for next time. */
447 return 0;
448}
449machine_subsys_initcall(pseries, phyp_dump_setup);
450
451int __init early_init_dt_scan_phyp_dump(unsigned long node,
452 const char *uname, int depth, void *data)
453{
454 const unsigned int *sizes;
455
456 phyp_dump_info->phyp_dump_configured = 0;
457 phyp_dump_info->phyp_dump_is_active = 0;
458
459 if (depth != 1 || strcmp(uname, "rtas") != 0)
460 return 0;
461
462 if (of_get_flat_dt_prop(node, "ibm,configure-kernel-dump", NULL))
463 phyp_dump_info->phyp_dump_configured++;
464
465 if (of_get_flat_dt_prop(node, "ibm,dump-kernel", NULL))
466 phyp_dump_info->phyp_dump_is_active++;
467
468 sizes = of_get_flat_dt_prop(node, "ibm,configure-kernel-dump-sizes",
469 NULL);
470 if (!sizes)
471 return 0;
472
473 if (sizes[0] == 1)
474 phyp_dump_info->cpu_state_size = *((unsigned long *)&sizes[1]);
475
476 if (sizes[3] == 2)
477 phyp_dump_info->hpte_region_size =
478 *((unsigned long *)&sizes[4]);
479 return 1;
480}
481
482/* Look for phyp_dump= cmdline option */
483static int __init early_phyp_dump_enabled(char *p)
484{
485 phyp_dump_info->phyp_dump_at_boot = 1;
486
487 if (!p)
488 return 0;
489
490 if (strncmp(p, "1", 1) == 0)
491 phyp_dump_info->phyp_dump_at_boot = 1;
492 else if (strncmp(p, "0", 1) == 0)
493 phyp_dump_info->phyp_dump_at_boot = 0;
494
495 return 0;
496}
497early_param("phyp_dump", early_phyp_dump_enabled);
498
499/* Look for phyp_dump_reserve_size= cmdline option */
500static int __init early_phyp_dump_reserve_size(char *p)
501{
502 if (p)
503 phyp_dump_info->reserve_bootvar = memparse(p, &p);
504
505 return 0;
506}
507early_param("phyp_dump_reserve_size", early_phyp_dump_reserve_size);
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
index 61136d019554..9e17c0d2a0c8 100644
--- a/arch/powerpc/platforms/pseries/pseries.h
+++ b/arch/powerpc/platforms/pseries/pseries.h
@@ -38,4 +38,6 @@ extern void pSeries_final_fixup(void);
38/* Poweron flag used for enabling auto ups restart */ 38/* Poweron flag used for enabling auto ups restart */
39extern unsigned long rtas_poweron_auto; 39extern unsigned long rtas_poweron_auto;
40 40
41extern void find_udbg_vterm(void);
42
41#endif /* _PSERIES_PSERIES_H */ 43#endif /* _PSERIES_PSERIES_H */
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index 2800fced8c7c..ac75c10de278 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -222,14 +222,14 @@ static char * parse_next_property(char *buf, char *end, char **name, int *length
222 tmp = strchr(buf, ' '); 222 tmp = strchr(buf, ' ');
223 if (!tmp) { 223 if (!tmp) {
224 printk(KERN_ERR "property parse failed in %s at line %d\n", 224 printk(KERN_ERR "property parse failed in %s at line %d\n",
225 __FUNCTION__, __LINE__); 225 __func__, __LINE__);
226 return NULL; 226 return NULL;
227 } 227 }
228 *tmp = '\0'; 228 *tmp = '\0';
229 229
230 if (++tmp >= end) { 230 if (++tmp >= end) {
231 printk(KERN_ERR "property parse failed in %s at line %d\n", 231 printk(KERN_ERR "property parse failed in %s at line %d\n",
232 __FUNCTION__, __LINE__); 232 __func__, __LINE__);
233 return NULL; 233 return NULL;
234 } 234 }
235 235
@@ -238,12 +238,12 @@ static char * parse_next_property(char *buf, char *end, char **name, int *length
238 *length = simple_strtoul(tmp, &tmp, 10); 238 *length = simple_strtoul(tmp, &tmp, 10);
239 if (*length == -1) { 239 if (*length == -1) {
240 printk(KERN_ERR "property parse failed in %s at line %d\n", 240 printk(KERN_ERR "property parse failed in %s at line %d\n",
241 __FUNCTION__, __LINE__); 241 __func__, __LINE__);
242 return NULL; 242 return NULL;
243 } 243 }
244 if (*tmp != ' ' || ++tmp >= end) { 244 if (*tmp != ' ' || ++tmp >= end) {
245 printk(KERN_ERR "property parse failed in %s at line %d\n", 245 printk(KERN_ERR "property parse failed in %s at line %d\n",
246 __FUNCTION__, __LINE__); 246 __func__, __LINE__);
247 return NULL; 247 return NULL;
248 } 248 }
249 249
@@ -252,12 +252,12 @@ static char * parse_next_property(char *buf, char *end, char **name, int *length
252 tmp += *length; 252 tmp += *length;
253 if (tmp > end) { 253 if (tmp > end) {
254 printk(KERN_ERR "property parse failed in %s at line %d\n", 254 printk(KERN_ERR "property parse failed in %s at line %d\n",
255 __FUNCTION__, __LINE__); 255 __func__, __LINE__);
256 return NULL; 256 return NULL;
257 } 257 }
258 else if (tmp < end && *tmp != ' ' && *tmp != '\0') { 258 else if (tmp < end && *tmp != ' ' && *tmp != '\0') {
259 printk(KERN_ERR "property parse failed in %s at line %d\n", 259 printk(KERN_ERR "property parse failed in %s at line %d\n",
260 __FUNCTION__, __LINE__); 260 __func__, __LINE__);
261 return NULL; 261 return NULL;
262 } 262 }
263 tmp++; 263 tmp++;
diff --git a/arch/powerpc/platforms/pseries/scanlog.c b/arch/powerpc/platforms/pseries/scanlog.c
index 8e1ef168e2dd..e5b0ea870164 100644
--- a/arch/powerpc/platforms/pseries/scanlog.c
+++ b/arch/powerpc/platforms/pseries/scanlog.c
@@ -195,31 +195,30 @@ const struct file_operations scanlog_fops = {
195static int __init scanlog_init(void) 195static int __init scanlog_init(void)
196{ 196{
197 struct proc_dir_entry *ent; 197 struct proc_dir_entry *ent;
198 void *data;
199 int err = -ENOMEM;
198 200
199 ibm_scan_log_dump = rtas_token("ibm,scan-log-dump"); 201 ibm_scan_log_dump = rtas_token("ibm,scan-log-dump");
200 if (ibm_scan_log_dump == RTAS_UNKNOWN_SERVICE) { 202 if (ibm_scan_log_dump == RTAS_UNKNOWN_SERVICE)
201 printk(KERN_ERR "scan-log-dump not implemented on this system\n"); 203 return -ENODEV;
202 return -EIO;
203 }
204 204
205 ent = create_proc_entry("ppc64/rtas/scan-log-dump", S_IRUSR, NULL); 205 /* Ideally we could allocate a buffer < 4G */
206 if (ent) { 206 data = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL);
207 ent->proc_fops = &scanlog_fops; 207 if (!data)
208 /* Ideally we could allocate a buffer < 4G */ 208 goto err;
209 ent->data = kmalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL); 209
210 if (!ent->data) { 210 ent = proc_create("ppc64/rtas/scan-log-dump", S_IRUSR, NULL,
211 printk(KERN_ERR "Failed to allocate a buffer\n"); 211 &scanlog_fops);
212 remove_proc_entry("scan-log-dump", ent->parent); 212 if (!ent)
213 return -ENOMEM; 213 goto err;
214 } 214
215 ((unsigned int *)ent->data)[0] = 0; 215 ent->data = data;
216 } else {
217 printk(KERN_ERR "Failed to create ppc64/scan-log-dump proc entry\n");
218 return -EIO;
219 }
220 proc_ppc64_scan_log_dump = ent; 216 proc_ppc64_scan_log_dump = ent;
221 217
222 return 0; 218 return 0;
219err:
220 kfree(data);
221 return err;
223} 222}
224 223
225static void __exit scanlog_cleanup(void) 224static void __exit scanlog_cleanup(void)
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index fdb9b1c8f977..f66aa9c3b135 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -76,9 +76,6 @@
76#define DBG(fmt...) 76#define DBG(fmt...)
77#endif 77#endif
78 78
79/* move those away to a .h */
80extern void find_udbg_vterm(void);
81
82int fwnmi_active; /* TRUE if an FWNMI handler is present */ 79int fwnmi_active; /* TRUE if an FWNMI handler is present */
83 80
84static void pseries_shared_idle_sleep(void); 81static void pseries_shared_idle_sleep(void);
@@ -127,14 +124,60 @@ void pseries_8259_cascade(unsigned int irq, struct irq_desc *desc)
127 desc->chip->eoi(irq); 124 desc->chip->eoi(irq);
128} 125}
129 126
130static void __init pseries_mpic_init_IRQ(void) 127static void __init pseries_setup_i8259_cascade(void)
131{ 128{
132 struct device_node *np, *old, *cascade = NULL; 129 struct device_node *np, *old, *found = NULL;
133 const unsigned int *addrp; 130 unsigned int cascade;
131 const u32 *addrp;
134 unsigned long intack = 0; 132 unsigned long intack = 0;
133 int naddr;
134
135 for_each_node_by_type(np, "interrupt-controller") {
136 if (of_device_is_compatible(np, "chrp,iic")) {
137 found = np;
138 break;
139 }
140 }
141
142 if (found == NULL) {
143 printk(KERN_DEBUG "pic: no ISA interrupt controller\n");
144 return;
145 }
146
147 cascade = irq_of_parse_and_map(found, 0);
148 if (cascade == NO_IRQ) {
149 printk(KERN_ERR "pic: failed to map cascade interrupt");
150 return;
151 }
152 pr_debug("pic: cascade mapped to irq %d\n", cascade);
153
154 for (old = of_node_get(found); old != NULL ; old = np) {
155 np = of_get_parent(old);
156 of_node_put(old);
157 if (np == NULL)
158 break;
159 if (strcmp(np->name, "pci") != 0)
160 continue;
161 addrp = of_get_property(np, "8259-interrupt-acknowledge", NULL);
162 if (addrp == NULL)
163 continue;
164 naddr = of_n_addr_cells(np);
165 intack = addrp[naddr-1];
166 if (naddr > 1)
167 intack |= ((unsigned long)addrp[naddr-2]) << 32;
168 }
169 if (intack)
170 printk(KERN_DEBUG "pic: PCI 8259 intack at 0x%016lx\n", intack);
171 i8259_init(found, intack);
172 of_node_put(found);
173 set_irq_chained_handler(cascade, pseries_8259_cascade);
174}
175
176static void __init pseries_mpic_init_IRQ(void)
177{
178 struct device_node *np;
135 const unsigned int *opprop; 179 const unsigned int *opprop;
136 unsigned long openpic_addr = 0; 180 unsigned long openpic_addr = 0;
137 unsigned int cascade_irq;
138 int naddr, n, i, opplen; 181 int naddr, n, i, opplen;
139 struct mpic *mpic; 182 struct mpic *mpic;
140 183
@@ -167,43 +210,13 @@ static void __init pseries_mpic_init_IRQ(void)
167 mpic_init(mpic); 210 mpic_init(mpic);
168 211
169 /* Look for cascade */ 212 /* Look for cascade */
170 for_each_node_by_type(np, "interrupt-controller") 213 pseries_setup_i8259_cascade();
171 if (of_device_is_compatible(np, "chrp,iic")) { 214}
172 cascade = np;
173 break;
174 }
175 if (cascade == NULL)
176 return;
177
178 cascade_irq = irq_of_parse_and_map(cascade, 0);
179 if (cascade_irq == NO_IRQ) {
180 printk(KERN_ERR "mpic: failed to map cascade interrupt");
181 return;
182 }
183 215
184 /* Check ACK type */ 216static void __init pseries_xics_init_IRQ(void)
185 for (old = of_node_get(cascade); old != NULL ; old = np) { 217{
186 np = of_get_parent(old); 218 xics_init_IRQ();
187 of_node_put(old); 219 pseries_setup_i8259_cascade();
188 if (np == NULL)
189 break;
190 if (strcmp(np->name, "pci") != 0)
191 continue;
192 addrp = of_get_property(np, "8259-interrupt-acknowledge",
193 NULL);
194 if (addrp == NULL)
195 continue;
196 naddr = of_n_addr_cells(np);
197 intack = addrp[naddr-1];
198 if (naddr > 1)
199 intack |= ((unsigned long)addrp[naddr-2]) << 32;
200 }
201 if (intack)
202 printk(KERN_DEBUG "mpic: PCI 8259 intack at 0x%016lx\n",
203 intack);
204 i8259_init(cascade, intack);
205 of_node_put(cascade);
206 set_irq_chained_handler(cascade_irq, pseries_8259_cascade);
207} 220}
208 221
209static void pseries_lpar_enable_pmcs(void) 222static void pseries_lpar_enable_pmcs(void)
@@ -235,7 +248,7 @@ static void __init pseries_discover_pic(void)
235 smp_init_pseries_mpic(); 248 smp_init_pseries_mpic();
236 return; 249 return;
237 } else if (strstr(typep, "ppc-xicp")) { 250 } else if (strstr(typep, "ppc-xicp")) {
238 ppc_md.init_IRQ = xics_init_IRQ; 251 ppc_md.init_IRQ = pseries_xics_init_IRQ;
239 setup_kexec_cpu_down_xics(); 252 setup_kexec_cpu_down_xics();
240 smp_init_pseries_xics(); 253 smp_init_pseries_xics();
241 return; 254 return;
@@ -393,6 +406,7 @@ static void pseries_dedicated_idle_sleep(void)
393{ 406{
394 unsigned int cpu = smp_processor_id(); 407 unsigned int cpu = smp_processor_id();
395 unsigned long start_snooze; 408 unsigned long start_snooze;
409 unsigned long in_purr, out_purr;
396 410
397 /* 411 /*
398 * Indicate to the HV that we are idle. Now would be 412 * Indicate to the HV that we are idle. Now would be
@@ -400,6 +414,7 @@ static void pseries_dedicated_idle_sleep(void)
400 */ 414 */
401 get_lppaca()->idle = 1; 415 get_lppaca()->idle = 1;
402 get_lppaca()->donate_dedicated_cpu = 1; 416 get_lppaca()->donate_dedicated_cpu = 1;
417 in_purr = mfspr(SPRN_PURR);
403 418
404 /* 419 /*
405 * We come in with interrupts disabled, and need_resched() 420 * We come in with interrupts disabled, and need_resched()
@@ -432,6 +447,8 @@ static void pseries_dedicated_idle_sleep(void)
432 447
433out: 448out:
434 HMT_medium(); 449 HMT_medium();
450 out_purr = mfspr(SPRN_PURR);
451 get_lppaca()->wait_state_cycles += out_purr - in_purr;
435 get_lppaca()->donate_dedicated_cpu = 0; 452 get_lppaca()->donate_dedicated_cpu = 0;
436 get_lppaca()->idle = 0; 453 get_lppaca()->idle = 0;
437} 454}
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index a977f200db89..43df53c30aa0 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -516,6 +516,8 @@ static struct irq_chip xics_pic_lpar = {
516 .set_affinity = xics_set_affinity 516 .set_affinity = xics_set_affinity
517}; 517};
518 518
519/* Points to the irq_chip we're actually using */
520static struct irq_chip *xics_irq_chip;
519 521
520static int xics_host_match(struct irq_host *h, struct device_node *node) 522static int xics_host_match(struct irq_host *h, struct device_node *node)
521{ 523{
@@ -526,23 +528,13 @@ static int xics_host_match(struct irq_host *h, struct device_node *node)
526 return !of_device_is_compatible(node, "chrp,iic"); 528 return !of_device_is_compatible(node, "chrp,iic");
527} 529}
528 530
529static int xics_host_map_direct(struct irq_host *h, unsigned int virq, 531static int xics_host_map(struct irq_host *h, unsigned int virq,
530 irq_hw_number_t hw) 532 irq_hw_number_t hw)
531{ 533{
532 pr_debug("xics: map_direct virq %d, hwirq 0x%lx\n", virq, hw); 534 pr_debug("xics: map virq %d, hwirq 0x%lx\n", virq, hw);
533 535
534 get_irq_desc(virq)->status |= IRQ_LEVEL; 536 get_irq_desc(virq)->status |= IRQ_LEVEL;
535 set_irq_chip_and_handler(virq, &xics_pic_direct, handle_fasteoi_irq); 537 set_irq_chip_and_handler(virq, xics_irq_chip, handle_fasteoi_irq);
536 return 0;
537}
538
539static int xics_host_map_lpar(struct irq_host *h, unsigned int virq,
540 irq_hw_number_t hw)
541{
542 pr_debug("xics: map_direct virq %d, hwirq 0x%lx\n", virq, hw);
543
544 get_irq_desc(virq)->status |= IRQ_LEVEL;
545 set_irq_chip_and_handler(virq, &xics_pic_lpar, handle_fasteoi_irq);
546 return 0; 538 return 0;
547} 539}
548 540
@@ -561,27 +553,20 @@ static int xics_host_xlate(struct irq_host *h, struct device_node *ct,
561 return 0; 553 return 0;
562} 554}
563 555
564static struct irq_host_ops xics_host_direct_ops = { 556static struct irq_host_ops xics_host_ops = {
565 .match = xics_host_match, 557 .match = xics_host_match,
566 .map = xics_host_map_direct, 558 .map = xics_host_map,
567 .xlate = xics_host_xlate,
568};
569
570static struct irq_host_ops xics_host_lpar_ops = {
571 .match = xics_host_match,
572 .map = xics_host_map_lpar,
573 .xlate = xics_host_xlate, 559 .xlate = xics_host_xlate,
574}; 560};
575 561
576static void __init xics_init_host(void) 562static void __init xics_init_host(void)
577{ 563{
578 struct irq_host_ops *ops;
579
580 if (firmware_has_feature(FW_FEATURE_LPAR)) 564 if (firmware_has_feature(FW_FEATURE_LPAR))
581 ops = &xics_host_lpar_ops; 565 xics_irq_chip = &xics_pic_lpar;
582 else 566 else
583 ops = &xics_host_direct_ops; 567 xics_irq_chip = &xics_pic_direct;
584 xics_host = irq_alloc_host(NULL, IRQ_HOST_MAP_TREE, 0, ops, 568
569 xics_host = irq_alloc_host(NULL, IRQ_HOST_MAP_TREE, 0, &xics_host_ops,
585 XICS_IRQ_SPURIOUS); 570 XICS_IRQ_SPURIOUS);
586 BUG_ON(xics_host == NULL); 571 BUG_ON(xics_host == NULL);
587 irq_set_default_host(xics_host); 572 irq_set_default_host(xics_host);
@@ -655,52 +640,6 @@ static void __init xics_init_one_node(struct device_node *np,
655 } 640 }
656} 641}
657 642
658
659static void __init xics_setup_8259_cascade(void)
660{
661 struct device_node *np, *old, *found = NULL;
662 int cascade, naddr;
663 const u32 *addrp;
664 unsigned long intack = 0;
665
666 for_each_node_by_type(np, "interrupt-controller")
667 if (of_device_is_compatible(np, "chrp,iic")) {
668 found = np;
669 break;
670 }
671 if (found == NULL) {
672 printk(KERN_DEBUG "xics: no ISA interrupt controller\n");
673 return;
674 }
675 cascade = irq_of_parse_and_map(found, 0);
676 if (cascade == NO_IRQ) {
677 printk(KERN_ERR "xics: failed to map cascade interrupt");
678 return;
679 }
680 pr_debug("xics: cascade mapped to irq %d\n", cascade);
681
682 for (old = of_node_get(found); old != NULL ; old = np) {
683 np = of_get_parent(old);
684 of_node_put(old);
685 if (np == NULL)
686 break;
687 if (strcmp(np->name, "pci") != 0)
688 continue;
689 addrp = of_get_property(np, "8259-interrupt-acknowledge", NULL);
690 if (addrp == NULL)
691 continue;
692 naddr = of_n_addr_cells(np);
693 intack = addrp[naddr-1];
694 if (naddr > 1)
695 intack |= ((unsigned long)addrp[naddr-2]) << 32;
696 }
697 if (intack)
698 printk(KERN_DEBUG "xics: PCI 8259 intack at 0x%016lx\n", intack);
699 i8259_init(found, intack);
700 of_node_put(found);
701 set_irq_chained_handler(cascade, pseries_8259_cascade);
702}
703
704void __init xics_init_IRQ(void) 643void __init xics_init_IRQ(void)
705{ 644{
706 struct device_node *np; 645 struct device_node *np;
@@ -733,8 +672,6 @@ void __init xics_init_IRQ(void)
733 672
734 xics_setup_cpu(); 673 xics_setup_cpu();
735 674
736 xics_setup_8259_cascade();
737
738 ppc64_boot_msg(0x21, "XICS Done"); 675 ppc64_boot_msg(0x21, "XICS Done");
739} 676}
740 677
diff --git a/arch/powerpc/platforms/pseries/xics.h b/arch/powerpc/platforms/pseries/xics.h
index c26bcff47b6d..1c5321ae8f2f 100644
--- a/arch/powerpc/platforms/pseries/xics.h
+++ b/arch/powerpc/platforms/pseries/xics.h
@@ -28,7 +28,4 @@ struct xics_ipi_struct {
28 28
29extern struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned; 29extern struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned;
30 30
31struct irq_desc;
32extern void pseries_8259_cascade(unsigned int irq, struct irq_desc *desc);
33
34#endif /* _POWERPC_KERNEL_XICS_H */ 31#endif /* _POWERPC_KERNEL_XICS_H */