diff options
Diffstat (limited to 'arch/ppc64')
41 files changed, 502 insertions, 876 deletions
diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig index 5cb343883e4d..0f1fa289744e 100644 --- a/arch/ppc64/Kconfig +++ b/arch/ppc64/Kconfig | |||
@@ -323,7 +323,7 @@ config EISA | |||
323 | bool | 323 | bool |
324 | 324 | ||
325 | config PCI | 325 | config PCI |
326 | bool | 326 | bool "support for PCI devices" if (EMBEDDED && PPC_ISERIES) |
327 | default y | 327 | default y |
328 | help | 328 | help |
329 | Find out whether your system includes a PCI bus. PCI is the name of | 329 | Find out whether your system includes a PCI bus. PCI is the name of |
diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile index 691f3008e698..33c752ceca4b 100644 --- a/arch/ppc64/Makefile +++ b/arch/ppc64/Makefile | |||
@@ -35,9 +35,9 @@ CROSS32AS := $(AS) -a32 | |||
35 | CROSS32LD := $(LD) -m elf32ppc | 35 | CROSS32LD := $(LD) -m elf32ppc |
36 | CROSS32OBJCOPY := $(OBJCOPY) | 36 | CROSS32OBJCOPY := $(OBJCOPY) |
37 | endif | 37 | endif |
38 | AS := $(AS) -a64 | 38 | override AS += -a64 |
39 | LD := $(LD) -m elf64ppc | 39 | override LD += -m elf64ppc |
40 | CC := $(CC) -m64 | 40 | override CC += -m64 |
41 | endif | 41 | endif |
42 | 42 | ||
43 | export CROSS32CC CROSS32AS CROSS32LD CROSS32OBJCOPY | 43 | export CROSS32CC CROSS32AS CROSS32LD CROSS32OBJCOPY |
diff --git a/arch/ppc64/kernel/HvLpEvent.c b/arch/ppc64/kernel/HvLpEvent.c index f8f19637f73f..90032b138902 100644 --- a/arch/ppc64/kernel/HvLpEvent.c +++ b/arch/ppc64/kernel/HvLpEvent.c | |||
@@ -12,7 +12,7 @@ | |||
12 | #include <asm/system.h> | 12 | #include <asm/system.h> |
13 | #include <asm/iSeries/HvLpEvent.h> | 13 | #include <asm/iSeries/HvLpEvent.h> |
14 | #include <asm/iSeries/HvCallEvent.h> | 14 | #include <asm/iSeries/HvCallEvent.h> |
15 | #include <asm/iSeries/LparData.h> | 15 | #include <asm/iSeries/ItLpNaca.h> |
16 | 16 | ||
17 | /* Array of LpEvent handler functions */ | 17 | /* Array of LpEvent handler functions */ |
18 | LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes]; | 18 | LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes]; |
diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index c923a815760e..cdea00d7707f 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <asm/iSeries/ItLpQueue.h> | 16 | #include <asm/iSeries/ItLpQueue.h> |
17 | #include <asm/iSeries/HvLpEvent.h> | 17 | #include <asm/iSeries/HvLpEvent.h> |
18 | #include <asm/iSeries/HvCallEvent.h> | 18 | #include <asm/iSeries/HvCallEvent.h> |
19 | #include <asm/iSeries/LparData.h> | ||
20 | 19 | ||
21 | static __inline__ int set_inUse( struct ItLpQueue * lpQueue ) | 20 | static __inline__ int set_inUse( struct ItLpQueue * lpQueue ) |
22 | { | 21 | { |
diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 96d90b0c5119..b5e167cf1a05 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile | |||
@@ -16,14 +16,13 @@ obj-y += vdso32/ vdso64/ | |||
16 | 16 | ||
17 | obj-$(CONFIG_PPC_OF) += of_device.o | 17 | obj-$(CONFIG_PPC_OF) += of_device.o |
18 | 18 | ||
19 | pci-obj-$(CONFIG_PPC_ISERIES) += iSeries_pci.o iSeries_pci_reset.o | 19 | pci-obj-$(CONFIG_PPC_ISERIES) += iSeries_pci.o iSeries_irq.o \ |
20 | iSeries_VpdInfo.o | ||
20 | pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o | 21 | pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o |
21 | 22 | ||
22 | obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y) | 23 | obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y) |
23 | 24 | ||
24 | obj-$(CONFIG_PPC_ISERIES) += iSeries_irq.o \ | 25 | obj-$(CONFIG_PPC_ISERIES) += HvCall.o HvLpConfig.o LparData.o \ |
25 | iSeries_VpdInfo.o XmPciLpEvent.o \ | ||
26 | HvCall.o HvLpConfig.o LparData.o \ | ||
27 | iSeries_setup.o ItLpQueue.o hvCall.o \ | 26 | iSeries_setup.o ItLpQueue.o hvCall.o \ |
28 | mf.o HvLpEvent.o iSeries_proc.o iSeries_htab.o \ | 27 | mf.o HvLpEvent.o iSeries_proc.o iSeries_htab.o \ |
29 | iSeries_iommu.o | 28 | iSeries_iommu.o |
diff --git a/arch/ppc64/kernel/XmPciLpEvent.c b/arch/ppc64/kernel/XmPciLpEvent.c deleted file mode 100644 index 809c9bc6678b..000000000000 --- a/arch/ppc64/kernel/XmPciLpEvent.c +++ /dev/null | |||
@@ -1,190 +0,0 @@ | |||
1 | /* | ||
2 | * File XmPciLpEvent.h created by Wayne Holm on Mon Jan 15 2001. | ||
3 | * | ||
4 | * This module handles PCI interrupt events sent by the iSeries Hypervisor. | ||
5 | */ | ||
6 | |||
7 | #include <linux/config.h> | ||
8 | #include <linux/pci.h> | ||
9 | #include <linux/init.h> | ||
10 | #include <linux/threads.h> | ||
11 | #include <linux/smp.h> | ||
12 | #include <linux/param.h> | ||
13 | #include <linux/string.h> | ||
14 | #include <linux/bootmem.h> | ||
15 | #include <linux/ide.h> | ||
16 | |||
17 | #include <asm/iSeries/HvTypes.h> | ||
18 | #include <asm/iSeries/HvLpEvent.h> | ||
19 | #include <asm/iSeries/HvCallPci.h> | ||
20 | #include <asm/iSeries/XmPciLpEvent.h> | ||
21 | #include <asm/ppcdebug.h> | ||
22 | |||
23 | static long Pci_Interrupt_Count; | ||
24 | static long Pci_Event_Count; | ||
25 | |||
26 | enum XmPciLpEvent_Subtype { | ||
27 | XmPciLpEvent_BusCreated = 0, // PHB has been created | ||
28 | XmPciLpEvent_BusError = 1, // PHB has failed | ||
29 | XmPciLpEvent_BusFailed = 2, // Msg to Secondary, Primary failed bus | ||
30 | XmPciLpEvent_NodeFailed = 4, // Multi-adapter bridge has failed | ||
31 | XmPciLpEvent_NodeRecovered = 5, // Multi-adapter bridge has recovered | ||
32 | XmPciLpEvent_BusRecovered = 12, // PHB has been recovered | ||
33 | XmPciLpEvent_UnQuiesceBus = 18, // Secondary bus unqiescing | ||
34 | XmPciLpEvent_BridgeError = 21, // Bridge Error | ||
35 | XmPciLpEvent_SlotInterrupt = 22 // Slot interrupt | ||
36 | }; | ||
37 | |||
38 | struct XmPciLpEvent_BusInterrupt { | ||
39 | HvBusNumber busNumber; | ||
40 | HvSubBusNumber subBusNumber; | ||
41 | }; | ||
42 | |||
43 | struct XmPciLpEvent_NodeInterrupt { | ||
44 | HvBusNumber busNumber; | ||
45 | HvSubBusNumber subBusNumber; | ||
46 | HvAgentId deviceId; | ||
47 | }; | ||
48 | |||
49 | struct XmPciLpEvent { | ||
50 | struct HvLpEvent hvLpEvent; | ||
51 | |||
52 | union { | ||
53 | u64 alignData; // Align on an 8-byte boundary | ||
54 | |||
55 | struct { | ||
56 | u32 fisr; | ||
57 | HvBusNumber busNumber; | ||
58 | HvSubBusNumber subBusNumber; | ||
59 | HvAgentId deviceId; | ||
60 | } slotInterrupt; | ||
61 | |||
62 | struct XmPciLpEvent_BusInterrupt busFailed; | ||
63 | struct XmPciLpEvent_BusInterrupt busRecovered; | ||
64 | struct XmPciLpEvent_BusInterrupt busCreated; | ||
65 | |||
66 | struct XmPciLpEvent_NodeInterrupt nodeFailed; | ||
67 | struct XmPciLpEvent_NodeInterrupt nodeRecovered; | ||
68 | |||
69 | } eventData; | ||
70 | |||
71 | }; | ||
72 | |||
73 | static void intReceived(struct XmPciLpEvent *eventParm, | ||
74 | struct pt_regs *regsParm); | ||
75 | |||
76 | static void XmPciLpEvent_handler(struct HvLpEvent *eventParm, | ||
77 | struct pt_regs *regsParm) | ||
78 | { | ||
79 | #ifdef CONFIG_PCI | ||
80 | #if 0 | ||
81 | PPCDBG(PPCDBG_BUSWALK, "XmPciLpEvent_handler, type 0x%x\n", | ||
82 | eventParm->xType); | ||
83 | #endif | ||
84 | ++Pci_Event_Count; | ||
85 | |||
86 | if (eventParm && (eventParm->xType == HvLpEvent_Type_PciIo)) { | ||
87 | switch (eventParm->xFlags.xFunction) { | ||
88 | case HvLpEvent_Function_Int: | ||
89 | intReceived((struct XmPciLpEvent *)eventParm, regsParm); | ||
90 | break; | ||
91 | case HvLpEvent_Function_Ack: | ||
92 | printk(KERN_ERR | ||
93 | "XmPciLpEvent.c: unexpected ack received\n"); | ||
94 | break; | ||
95 | default: | ||
96 | printk(KERN_ERR | ||
97 | "XmPciLpEvent.c: unexpected event function %d\n", | ||
98 | (int)eventParm->xFlags.xFunction); | ||
99 | break; | ||
100 | } | ||
101 | } else if (eventParm) | ||
102 | printk(KERN_ERR | ||
103 | "XmPciLpEvent.c: Unrecognized PCI event type 0x%x\n", | ||
104 | (int)eventParm->xType); | ||
105 | else | ||
106 | printk(KERN_ERR "XmPciLpEvent.c: NULL event received\n"); | ||
107 | #endif | ||
108 | } | ||
109 | |||
110 | static void intReceived(struct XmPciLpEvent *eventParm, | ||
111 | struct pt_regs *regsParm) | ||
112 | { | ||
113 | int irq; | ||
114 | |||
115 | ++Pci_Interrupt_Count; | ||
116 | #if 0 | ||
117 | PPCDBG(PPCDBG_BUSWALK, "PCI: XmPciLpEvent.c: intReceived\n"); | ||
118 | #endif | ||
119 | |||
120 | switch (eventParm->hvLpEvent.xSubtype) { | ||
121 | case XmPciLpEvent_SlotInterrupt: | ||
122 | irq = eventParm->hvLpEvent.xCorrelationToken; | ||
123 | /* Dispatch the interrupt handlers for this irq */ | ||
124 | ppc_irq_dispatch_handler(regsParm, irq); | ||
125 | HvCallPci_eoi(eventParm->eventData.slotInterrupt.busNumber, | ||
126 | eventParm->eventData.slotInterrupt.subBusNumber, | ||
127 | eventParm->eventData.slotInterrupt.deviceId); | ||
128 | break; | ||
129 | /* Ignore error recovery events for now */ | ||
130 | case XmPciLpEvent_BusCreated: | ||
131 | printk(KERN_INFO "XmPciLpEvent.c: system bus %d created\n", | ||
132 | eventParm->eventData.busCreated.busNumber); | ||
133 | break; | ||
134 | case XmPciLpEvent_BusError: | ||
135 | case XmPciLpEvent_BusFailed: | ||
136 | printk(KERN_INFO "XmPciLpEvent.c: system bus %d failed\n", | ||
137 | eventParm->eventData.busFailed.busNumber); | ||
138 | break; | ||
139 | case XmPciLpEvent_BusRecovered: | ||
140 | case XmPciLpEvent_UnQuiesceBus: | ||
141 | printk(KERN_INFO "XmPciLpEvent.c: system bus %d recovered\n", | ||
142 | eventParm->eventData.busRecovered.busNumber); | ||
143 | break; | ||
144 | case XmPciLpEvent_NodeFailed: | ||
145 | case XmPciLpEvent_BridgeError: | ||
146 | printk(KERN_INFO | ||
147 | "XmPciLpEvent.c: multi-adapter bridge %d/%d/%d failed\n", | ||
148 | eventParm->eventData.nodeFailed.busNumber, | ||
149 | eventParm->eventData.nodeFailed.subBusNumber, | ||
150 | eventParm->eventData.nodeFailed.deviceId); | ||
151 | break; | ||
152 | case XmPciLpEvent_NodeRecovered: | ||
153 | printk(KERN_INFO | ||
154 | "XmPciLpEvent.c: multi-adapter bridge %d/%d/%d recovered\n", | ||
155 | eventParm->eventData.nodeRecovered.busNumber, | ||
156 | eventParm->eventData.nodeRecovered.subBusNumber, | ||
157 | eventParm->eventData.nodeRecovered.deviceId); | ||
158 | break; | ||
159 | default: | ||
160 | printk(KERN_ERR | ||
161 | "XmPciLpEvent.c: unrecognized event subtype 0x%x\n", | ||
162 | eventParm->hvLpEvent.xSubtype); | ||
163 | break; | ||
164 | } | ||
165 | } | ||
166 | |||
167 | |||
168 | /* This should be called sometime prior to buswalk (init_IRQ would be good) */ | ||
169 | int XmPciLpEvent_init() | ||
170 | { | ||
171 | int xRc; | ||
172 | |||
173 | PPCDBG(PPCDBG_BUSWALK, | ||
174 | "XmPciLpEvent_init, Register Event type 0x%04X\n", | ||
175 | HvLpEvent_Type_PciIo); | ||
176 | |||
177 | xRc = HvLpEvent_registerHandler(HvLpEvent_Type_PciIo, | ||
178 | &XmPciLpEvent_handler); | ||
179 | if (xRc == 0) { | ||
180 | xRc = HvLpEvent_openPath(HvLpEvent_Type_PciIo, 0); | ||
181 | if (xRc != 0) | ||
182 | printk(KERN_ERR | ||
183 | "XmPciLpEvent.c: open event path failed with rc 0x%x\n", | ||
184 | xRc); | ||
185 | } else | ||
186 | printk(KERN_ERR | ||
187 | "XmPciLpEvent.c: register handler failed with rc 0x%x\n", | ||
188 | xRc); | ||
189 | return xRc; | ||
190 | } | ||
diff --git a/arch/ppc64/kernel/asm-offsets.c b/arch/ppc64/kernel/asm-offsets.c index 0094ac79a18c..abb9e5b5da03 100644 --- a/arch/ppc64/kernel/asm-offsets.c +++ b/arch/ppc64/kernel/asm-offsets.c | |||
@@ -31,7 +31,6 @@ | |||
31 | 31 | ||
32 | #include <asm/paca.h> | 32 | #include <asm/paca.h> |
33 | #include <asm/lppaca.h> | 33 | #include <asm/lppaca.h> |
34 | #include <asm/iSeries/ItLpQueue.h> | ||
35 | #include <asm/iSeries/HvLpEvent.h> | 34 | #include <asm/iSeries/HvLpEvent.h> |
36 | #include <asm/rtas.h> | 35 | #include <asm/rtas.h> |
37 | #include <asm/cputable.h> | 36 | #include <asm/cputable.h> |
diff --git a/arch/ppc64/kernel/dma.c b/arch/ppc64/kernel/dma.c index ce714c927134..4da8e31b2b61 100644 --- a/arch/ppc64/kernel/dma.c +++ b/arch/ppc64/kernel/dma.c | |||
@@ -15,8 +15,10 @@ | |||
15 | 15 | ||
16 | static struct dma_mapping_ops *get_dma_ops(struct device *dev) | 16 | static struct dma_mapping_ops *get_dma_ops(struct device *dev) |
17 | { | 17 | { |
18 | #ifdef CONFIG_PCI | ||
18 | if (dev->bus == &pci_bus_type) | 19 | if (dev->bus == &pci_bus_type) |
19 | return &pci_dma_ops; | 20 | return &pci_dma_ops; |
21 | #endif | ||
20 | #ifdef CONFIG_IBMVIO | 22 | #ifdef CONFIG_IBMVIO |
21 | if (dev->bus == &vio_bus_type) | 23 | if (dev->bus == &vio_bus_type) |
22 | return &vio_dma_ops; | 24 | return &vio_dma_ops; |
@@ -37,8 +39,10 @@ EXPORT_SYMBOL(dma_supported); | |||
37 | 39 | ||
38 | int dma_set_mask(struct device *dev, u64 dma_mask) | 40 | int dma_set_mask(struct device *dev, u64 dma_mask) |
39 | { | 41 | { |
42 | #ifdef CONFIG_PCI | ||
40 | if (dev->bus == &pci_bus_type) | 43 | if (dev->bus == &pci_bus_type) |
41 | return pci_set_dma_mask(to_pci_dev(dev), dma_mask); | 44 | return pci_set_dma_mask(to_pci_dev(dev), dma_mask); |
45 | #endif | ||
42 | #ifdef CONFIG_IBMVIO | 46 | #ifdef CONFIG_IBMVIO |
43 | if (dev->bus == &vio_bus_type) | 47 | if (dev->bus == &vio_bus_type) |
44 | return -EIO; | 48 | return -EIO; |
diff --git a/arch/ppc64/kernel/eeh.c b/arch/ppc64/kernel/eeh.c index d63d41f3eecf..af5272fedadf 100644 --- a/arch/ppc64/kernel/eeh.c +++ b/arch/ppc64/kernel/eeh.c | |||
@@ -505,7 +505,7 @@ static inline unsigned long eeh_token_to_phys(unsigned long token) | |||
505 | pte_t *ptep; | 505 | pte_t *ptep; |
506 | unsigned long pa; | 506 | unsigned long pa; |
507 | 507 | ||
508 | ptep = find_linux_pte(ioremap_mm.pgd, token); | 508 | ptep = find_linux_pte(init_mm.pgd, token); |
509 | if (!ptep) | 509 | if (!ptep) |
510 | return token; | 510 | return token; |
511 | pa = pte_pfn(*ptep) << PAGE_SHIFT; | 511 | pa = pte_pfn(*ptep) << PAGE_SHIFT; |
diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S index 346dbf606b5d..02c8f4e3e4bc 100644 --- a/arch/ppc64/kernel/head.S +++ b/arch/ppc64/kernel/head.S | |||
@@ -2121,10 +2121,6 @@ empty_zero_page: | |||
2121 | swapper_pg_dir: | 2121 | swapper_pg_dir: |
2122 | .space 4096 | 2122 | .space 4096 |
2123 | 2123 | ||
2124 | .globl ioremap_dir | ||
2125 | ioremap_dir: | ||
2126 | .space 4096 | ||
2127 | |||
2128 | #ifdef CONFIG_SMP | 2124 | #ifdef CONFIG_SMP |
2129 | /* 1 page segment table per cpu (max 48, cpu0 allocated at STAB0_PHYS_ADDR) */ | 2125 | /* 1 page segment table per cpu (max 48, cpu0 allocated at STAB0_PHYS_ADDR) */ |
2130 | .globl stab_array | 2126 | .globl stab_array |
diff --git a/arch/ppc64/kernel/iSeries_VpdInfo.c b/arch/ppc64/kernel/iSeries_VpdInfo.c index a6f0ff2d0239..d11c732daf81 100644 --- a/arch/ppc64/kernel/iSeries_VpdInfo.c +++ b/arch/ppc64/kernel/iSeries_VpdInfo.c | |||
@@ -1,31 +1,31 @@ | |||
1 | /************************************************************************/ | 1 | /* |
2 | /* File iSeries_vpdInfo.c created by Allan Trautman on Fri Feb 2 2001. */ | 2 | * File iSeries_vpdInfo.c created by Allan Trautman on Fri Feb 2 2001. |
3 | /************************************************************************/ | 3 | * |
4 | /* This code gets the card location of the hardware */ | 4 | * This code gets the card location of the hardware |
5 | /* Copyright (C) 20yy <Allan H Trautman> <IBM Corp> */ | 5 | * Copyright (C) 2001 <Allan H Trautman> <IBM Corp> |
6 | /* */ | 6 | * Copyright (C) 2005 Stephen Rothwel, IBM Corp |
7 | /* This program is free software; you can redistribute it and/or modify */ | 7 | * |
8 | /* it under the terms of the GNU General Public License as published by */ | 8 | * This program is free software; you can redistribute it and/or modify |
9 | /* the Free Software Foundation; either version 2 of the License, or */ | 9 | * it under the terms of the GNU General Public License as published by |
10 | /* (at your option) any later version. */ | 10 | * the Free Software Foundation; either version 2 of the License, or |
11 | /* */ | 11 | * (at your option) any later version. |
12 | /* This program is distributed in the hope that it will be useful, */ | 12 | * |
13 | /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ | 13 | * This program is distributed in the hope that it will be useful, |
14 | /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | /* GNU General Public License for more details. */ | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | /* */ | 16 | * GNU General Public License for more details. |
17 | /* You should have received a copy of the GNU General Public License */ | 17 | * |
18 | /* along with this program; if not, write to the: */ | 18 | * You should have received a copy of the GNU General Public License |
19 | /* Free Software Foundation, Inc., */ | 19 | * along with this program; if not, write to the: |
20 | /* 59 Temple Place, Suite 330, */ | 20 | * Free Software Foundation, Inc., |
21 | /* Boston, MA 02111-1307 USA */ | 21 | * 59 Temple Place, Suite 330, |
22 | /************************************************************************/ | 22 | * Boston, MA 02111-1307 USA |
23 | /* Change Activity: */ | 23 | * |
24 | /* Created, Feb 2, 2001 */ | 24 | * Change Activity: |
25 | /* Ported to ppc64, August 20, 2001 */ | 25 | * Created, Feb 2, 2001 |
26 | /* End Change Activity */ | 26 | * Ported to ppc64, August 20, 2001 |
27 | /************************************************************************/ | 27 | * End Change Activity |
28 | #include <linux/config.h> | 28 | */ |
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/pci.h> | 31 | #include <linux/pci.h> |
@@ -34,30 +34,25 @@ | |||
34 | 34 | ||
35 | #include <asm/iSeries/HvCallPci.h> | 35 | #include <asm/iSeries/HvCallPci.h> |
36 | #include <asm/iSeries/HvTypes.h> | 36 | #include <asm/iSeries/HvTypes.h> |
37 | #include <asm/iSeries/mf.h> | ||
38 | #include <asm/iSeries/LparData.h> | ||
39 | #include <asm/iSeries/iSeries_pci.h> | 37 | #include <asm/iSeries/iSeries_pci.h> |
40 | #include "pci.h" | ||
41 | 38 | ||
42 | /* | 39 | /* |
43 | * Size of Bus VPD data | 40 | * Size of Bus VPD data |
44 | */ | 41 | */ |
45 | #define BUS_VPDSIZE 1024 | 42 | #define BUS_VPDSIZE 1024 |
43 | |||
46 | /* | 44 | /* |
47 | * Bus Vpd Tags | 45 | * Bus Vpd Tags |
48 | */ | 46 | */ |
49 | #define VpdEndOfDataTag 0x78 | ||
50 | #define VpdEndOfAreaTag 0x79 | 47 | #define VpdEndOfAreaTag 0x79 |
51 | #define VpdIdStringTag 0x82 | 48 | #define VpdIdStringTag 0x82 |
52 | #define VpdVendorAreaTag 0x84 | 49 | #define VpdVendorAreaTag 0x84 |
50 | |||
53 | /* | 51 | /* |
54 | * Mfg Area Tags | 52 | * Mfg Area Tags |
55 | */ | 53 | */ |
56 | #define VpdFruFlag 0x4647 // "FG" | ||
57 | #define VpdFruFrameId 0x4649 // "FI" | 54 | #define VpdFruFrameId 0x4649 // "FI" |
58 | #define VpdSlotMapFormat 0x4D46 // "MF" | 55 | #define VpdSlotMapFormat 0x4D46 // "MF" |
59 | #define VpdAsmPartNumber 0x504E // "PN" | ||
60 | #define VpdFruSerial 0x534E // "SN" | ||
61 | #define VpdSlotMap 0x534D // "SM" | 56 | #define VpdSlotMap 0x534D // "SM" |
62 | 57 | ||
63 | /* | 58 | /* |
@@ -79,74 +74,33 @@ struct SlotMapStruct { | |||
79 | char CardLocation[3]; | 74 | char CardLocation[3]; |
80 | char Parms[8]; | 75 | char Parms[8]; |
81 | char Reserved[2]; | 76 | char Reserved[2]; |
82 | }; | 77 | }; |
83 | typedef struct SlotMapStruct SlotMap; | 78 | typedef struct SlotMapStruct SlotMap; |
84 | #define SLOT_ENTRY_SIZE 16 | 79 | #define SLOT_ENTRY_SIZE 16 |
85 | 80 | ||
86 | /* | 81 | /* |
87 | * Formats the device information. | ||
88 | * - Pass in pci_dev* pointer to the device. | ||
89 | * - Pass in buffer to place the data. Danger here is the buffer must | ||
90 | * be as big as the client says it is. Should be at least 128 bytes. | ||
91 | * Return will the length of the string data put in the buffer. | ||
92 | * Format: | ||
93 | * PCI: Bus 0, Device 26, Vendor 0x12AE Frame 1, Card C10 Ethernet | ||
94 | * controller | ||
95 | */ | ||
96 | int iSeries_Device_Information(struct pci_dev *PciDev, char *buffer, | ||
97 | int BufferSize) | ||
98 | { | ||
99 | struct iSeries_Device_Node *DevNode = | ||
100 | (struct iSeries_Device_Node *)PciDev->sysdata; | ||
101 | int len; | ||
102 | |||
103 | if (DevNode == NULL) | ||
104 | return sprintf(buffer, | ||
105 | "PCI: iSeries_Device_Information DevNode is NULL"); | ||
106 | |||
107 | if (BufferSize < 128) | ||
108 | return 0; | ||
109 | |||
110 | len = sprintf(buffer, "PCI: Bus%3d, Device%3d, Vendor %04X ", | ||
111 | ISERIES_BUS(DevNode), PCI_SLOT(PciDev->devfn), | ||
112 | PciDev->vendor); | ||
113 | len += sprintf(buffer + len, "Frame%3d, Card %4s ", | ||
114 | DevNode->FrameId, DevNode->CardLocation); | ||
115 | #ifdef CONFIG_PCI | ||
116 | if (pci_class_name(PciDev->class >> 8) == 0) | ||
117 | len += sprintf(buffer + len, "0x%04X ", | ||
118 | (int)(PciDev->class >> 8)); | ||
119 | else | ||
120 | len += sprintf(buffer + len, "%s", | ||
121 | pci_class_name(PciDev->class >> 8)); | ||
122 | #endif | ||
123 | return len; | ||
124 | } | ||
125 | |||
126 | /* | ||
127 | * Parse the Slot Area | 82 | * Parse the Slot Area |
128 | */ | 83 | */ |
129 | void iSeries_Parse_SlotArea(SlotMap *MapPtr, int MapLen, | 84 | static void __init iSeries_Parse_SlotArea(SlotMap *MapPtr, int MapLen, |
130 | struct iSeries_Device_Node *DevNode) | 85 | HvAgentId agent, u8 *PhbId, char card[4]) |
131 | { | 86 | { |
132 | int SlotMapLen = MapLen; | 87 | int SlotMapLen = MapLen; |
133 | SlotMap *SlotMapPtr = MapPtr; | 88 | SlotMap *SlotMapPtr = MapPtr; |
134 | 89 | ||
135 | /* | 90 | /* |
136 | * Parse Slot label until we find the one requrested | 91 | * Parse Slot label until we find the one requested |
137 | */ | 92 | */ |
138 | while (SlotMapLen > 0) { | 93 | while (SlotMapLen > 0) { |
139 | if (SlotMapPtr->AgentId == DevNode->AgentId ) { | 94 | if (SlotMapPtr->AgentId == agent) { |
140 | /* | 95 | /* |
141 | * If Phb wasn't found, grab the entry first one found. | 96 | * If Phb wasn't found, grab the entry first one found. |
142 | */ | 97 | */ |
143 | if (DevNode->PhbId == 0xff) | 98 | if (*PhbId == 0xff) |
144 | DevNode->PhbId = SlotMapPtr->PhbId; | 99 | *PhbId = SlotMapPtr->PhbId; |
145 | /* Found it, extract the data. */ | 100 | /* Found it, extract the data. */ |
146 | if (SlotMapPtr->PhbId == DevNode->PhbId ) { | 101 | if (SlotMapPtr->PhbId == *PhbId) { |
147 | memcpy(&DevNode->CardLocation, | 102 | memcpy(card, &SlotMapPtr->CardLocation, 3); |
148 | &SlotMapPtr->CardLocation, 3); | 103 | card[3] = 0; |
149 | DevNode->CardLocation[3] = 0; | ||
150 | break; | 104 | break; |
151 | } | 105 | } |
152 | } | 106 | } |
@@ -159,8 +113,9 @@ void iSeries_Parse_SlotArea(SlotMap *MapPtr, int MapLen, | |||
159 | /* | 113 | /* |
160 | * Parse the Mfg Area | 114 | * Parse the Mfg Area |
161 | */ | 115 | */ |
162 | static void iSeries_Parse_MfgArea(u8 *AreaData, int AreaLen, | 116 | static void __init iSeries_Parse_MfgArea(u8 *AreaData, int AreaLen, |
163 | struct iSeries_Device_Node *DevNode) | 117 | HvAgentId agent, u8 *PhbId, |
118 | u8 *frame, char card[4]) | ||
164 | { | 119 | { |
165 | MfgArea *MfgAreaPtr = (MfgArea *)AreaData; | 120 | MfgArea *MfgAreaPtr = (MfgArea *)AreaData; |
166 | int MfgAreaLen = AreaLen; | 121 | int MfgAreaLen = AreaLen; |
@@ -171,7 +126,7 @@ static void iSeries_Parse_MfgArea(u8 *AreaData, int AreaLen, | |||
171 | int MfgTagLen = MfgAreaPtr->TagLength; | 126 | int MfgTagLen = MfgAreaPtr->TagLength; |
172 | /* Frame ID (FI 4649020310 ) */ | 127 | /* Frame ID (FI 4649020310 ) */ |
173 | if (MfgAreaPtr->Tag == VpdFruFrameId) /* FI */ | 128 | if (MfgAreaPtr->Tag == VpdFruFrameId) /* FI */ |
174 | DevNode->FrameId = MfgAreaPtr->AreaData1; | 129 | *frame = MfgAreaPtr->AreaData1; |
175 | /* Slot Map Format (MF 4D46020004 ) */ | 130 | /* Slot Map Format (MF 4D46020004 ) */ |
176 | else if (MfgAreaPtr->Tag == VpdSlotMapFormat) /* MF */ | 131 | else if (MfgAreaPtr->Tag == VpdSlotMapFormat) /* MF */ |
177 | SlotMapFmt = (MfgAreaPtr->AreaData1 * 256) | 132 | SlotMapFmt = (MfgAreaPtr->AreaData1 * 256) |
@@ -183,10 +138,11 @@ static void iSeries_Parse_MfgArea(u8 *AreaData, int AreaLen, | |||
183 | if (SlotMapFmt == 0x1004) | 138 | if (SlotMapFmt == 0x1004) |
184 | SlotMapPtr = (SlotMap *)((char *)MfgAreaPtr | 139 | SlotMapPtr = (SlotMap *)((char *)MfgAreaPtr |
185 | + MFG_ENTRY_SIZE + 1); | 140 | + MFG_ENTRY_SIZE + 1); |
186 | else | 141 | else |
187 | SlotMapPtr = (SlotMap *)((char *)MfgAreaPtr | 142 | SlotMapPtr = (SlotMap *)((char *)MfgAreaPtr |
188 | + MFG_ENTRY_SIZE); | 143 | + MFG_ENTRY_SIZE); |
189 | iSeries_Parse_SlotArea(SlotMapPtr, MfgTagLen, DevNode); | 144 | iSeries_Parse_SlotArea(SlotMapPtr, MfgTagLen, |
145 | agent, PhbId, card); | ||
190 | } | 146 | } |
191 | /* | 147 | /* |
192 | * Point to the next Mfg Area | 148 | * Point to the next Mfg Area |
@@ -194,19 +150,19 @@ static void iSeries_Parse_MfgArea(u8 *AreaData, int AreaLen, | |||
194 | */ | 150 | */ |
195 | MfgAreaPtr = (MfgArea *)((char *)MfgAreaPtr + MfgTagLen | 151 | MfgAreaPtr = (MfgArea *)((char *)MfgAreaPtr + MfgTagLen |
196 | + MFG_ENTRY_SIZE); | 152 | + MFG_ENTRY_SIZE); |
197 | MfgAreaLen -= (MfgTagLen + MFG_ENTRY_SIZE); | 153 | MfgAreaLen -= (MfgTagLen + MFG_ENTRY_SIZE); |
198 | } | 154 | } |
199 | } | 155 | } |
200 | 156 | ||
201 | /* | 157 | /* |
202 | * Look for "BUS".. Data is not Null terminated. | 158 | * Look for "BUS".. Data is not Null terminated. |
203 | * PHBID of 0xFF indicates PHB was not found in VPD Data. | 159 | * PHBID of 0xFF indicates PHB was not found in VPD Data. |
204 | */ | 160 | */ |
205 | static int iSeries_Parse_PhbId(u8 *AreaPtr, int AreaLength) | 161 | static int __init iSeries_Parse_PhbId(u8 *AreaPtr, int AreaLength) |
206 | { | 162 | { |
207 | u8 *PhbPtr = AreaPtr; | 163 | u8 *PhbPtr = AreaPtr; |
208 | int DataLen = AreaLength; | 164 | int DataLen = AreaLength; |
209 | char PhbId = 0xFF; | 165 | char PhbId = 0xFF; |
210 | 166 | ||
211 | while (DataLen > 0) { | 167 | while (DataLen > 0) { |
212 | if ((*PhbPtr == 'B') && (*(PhbPtr + 1) == 'U') | 168 | if ((*PhbPtr == 'B') && (*(PhbPtr + 1) == 'U') |
@@ -216,7 +172,7 @@ static int iSeries_Parse_PhbId(u8 *AreaPtr, int AreaLength) | |||
216 | ++PhbPtr; | 172 | ++PhbPtr; |
217 | PhbId = (*PhbPtr & 0x0F); | 173 | PhbId = (*PhbPtr & 0x0F); |
218 | break; | 174 | break; |
219 | } | 175 | } |
220 | ++PhbPtr; | 176 | ++PhbPtr; |
221 | --DataLen; | 177 | --DataLen; |
222 | } | 178 | } |
@@ -226,52 +182,90 @@ static int iSeries_Parse_PhbId(u8 *AreaPtr, int AreaLength) | |||
226 | /* | 182 | /* |
227 | * Parse out the VPD Areas | 183 | * Parse out the VPD Areas |
228 | */ | 184 | */ |
229 | static void iSeries_Parse_Vpd(u8 *VpdData, int VpdDataLen, | 185 | static void __init iSeries_Parse_Vpd(u8 *VpdData, int VpdDataLen, |
230 | struct iSeries_Device_Node *DevNode) | 186 | HvAgentId agent, u8 *frame, char card[4]) |
231 | { | 187 | { |
232 | u8 *TagPtr = VpdData; | 188 | u8 *TagPtr = VpdData; |
233 | int DataLen = VpdDataLen - 3; | 189 | int DataLen = VpdDataLen - 3; |
190 | u8 PhbId; | ||
234 | 191 | ||
235 | while ((*TagPtr != VpdEndOfAreaTag) && (DataLen > 0)) { | 192 | while ((*TagPtr != VpdEndOfAreaTag) && (DataLen > 0)) { |
236 | int AreaLen = *(TagPtr + 1) + (*(TagPtr + 2) * 256); | 193 | int AreaLen = *(TagPtr + 1) + (*(TagPtr + 2) * 256); |
237 | u8 *AreaData = TagPtr + 3; | 194 | u8 *AreaData = TagPtr + 3; |
238 | 195 | ||
239 | if (*TagPtr == VpdIdStringTag) | 196 | if (*TagPtr == VpdIdStringTag) |
240 | DevNode->PhbId = iSeries_Parse_PhbId(AreaData, AreaLen); | 197 | PhbId = iSeries_Parse_PhbId(AreaData, AreaLen); |
241 | else if (*TagPtr == VpdVendorAreaTag) | 198 | else if (*TagPtr == VpdVendorAreaTag) |
242 | iSeries_Parse_MfgArea(AreaData, AreaLen, DevNode); | 199 | iSeries_Parse_MfgArea(AreaData, AreaLen, |
200 | agent, &PhbId, frame, card); | ||
243 | /* Point to next Area. */ | 201 | /* Point to next Area. */ |
244 | TagPtr = AreaData + AreaLen; | 202 | TagPtr = AreaData + AreaLen; |
245 | DataLen -= AreaLen; | 203 | DataLen -= AreaLen; |
246 | } | 204 | } |
247 | } | 205 | } |
248 | 206 | ||
249 | void iSeries_Get_Location_Code(struct iSeries_Device_Node *DevNode) | 207 | static void __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent, |
208 | u8 *frame, char card[4]) | ||
250 | { | 209 | { |
251 | int BusVpdLen = 0; | 210 | int BusVpdLen = 0; |
252 | u8 *BusVpdPtr = (u8 *)kmalloc(BUS_VPDSIZE, GFP_KERNEL); | 211 | u8 *BusVpdPtr = kmalloc(BUS_VPDSIZE, GFP_KERNEL); |
253 | 212 | ||
254 | if (BusVpdPtr == NULL) { | 213 | if (BusVpdPtr == NULL) { |
255 | printk("PCI: Bus VPD Buffer allocation failure.\n"); | 214 | printk("PCI: Bus VPD Buffer allocation failure.\n"); |
256 | return; | 215 | return; |
257 | } | 216 | } |
258 | BusVpdLen = HvCallPci_getBusVpd(ISERIES_BUS(DevNode), | 217 | BusVpdLen = HvCallPci_getBusVpd(bus, ISERIES_HV_ADDR(BusVpdPtr), |
259 | ISERIES_HV_ADDR(BusVpdPtr), | ||
260 | BUS_VPDSIZE); | 218 | BUS_VPDSIZE); |
261 | if (BusVpdLen == 0) { | 219 | if (BusVpdLen == 0) { |
262 | kfree(BusVpdPtr); | ||
263 | printk("PCI: Bus VPD Buffer zero length.\n"); | 220 | printk("PCI: Bus VPD Buffer zero length.\n"); |
264 | return; | 221 | goto out_free; |
265 | } | 222 | } |
266 | /* printk("PCI: BusVpdPtr: %p, %d\n",BusVpdPtr, BusVpdLen); */ | 223 | /* printk("PCI: BusVpdPtr: %p, %d\n",BusVpdPtr, BusVpdLen); */ |
267 | /* Make sure this is what I think it is */ | 224 | /* Make sure this is what I think it is */ |
268 | if (*BusVpdPtr != VpdIdStringTag) { /* 0x82 */ | 225 | if (*BusVpdPtr != VpdIdStringTag) { /* 0x82 */ |
269 | printk("PCI: Bus VPD Buffer missing starting tag.\n"); | 226 | printk("PCI: Bus VPD Buffer missing starting tag.\n"); |
270 | kfree(BusVpdPtr); | 227 | goto out_free; |
271 | return; | ||
272 | } | 228 | } |
273 | iSeries_Parse_Vpd(BusVpdPtr,BusVpdLen, DevNode); | 229 | iSeries_Parse_Vpd(BusVpdPtr, BusVpdLen, agent, frame, card); |
274 | sprintf(DevNode->Location, "Frame%3d, Card %-4s", DevNode->FrameId, | 230 | out_free: |
275 | DevNode->CardLocation); | ||
276 | kfree(BusVpdPtr); | 231 | kfree(BusVpdPtr); |
277 | } | 232 | } |
233 | |||
234 | /* | ||
235 | * Prints the device information. | ||
236 | * - Pass in pci_dev* pointer to the device. | ||
237 | * - Pass in the device count | ||
238 | * | ||
239 | * Format: | ||
240 | * PCI: Bus 0, Device 26, Vendor 0x12AE Frame 1, Card C10 Ethernet | ||
241 | * controller | ||
242 | */ | ||
243 | void __init iSeries_Device_Information(struct pci_dev *PciDev, int count) | ||
244 | { | ||
245 | struct iSeries_Device_Node *DevNode = PciDev->sysdata; | ||
246 | u16 bus; | ||
247 | u8 frame; | ||
248 | char card[4]; | ||
249 | HvSubBusNumber subbus; | ||
250 | HvAgentId agent; | ||
251 | |||
252 | if (DevNode == NULL) { | ||
253 | printk("%d. PCI: iSeries_Device_Information DevNode is NULL\n", | ||
254 | count); | ||
255 | return; | ||
256 | } | ||
257 | |||
258 | bus = ISERIES_BUS(DevNode); | ||
259 | subbus = ISERIES_SUBBUS(DevNode); | ||
260 | agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus), | ||
261 | ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus)); | ||
262 | iSeries_Get_Location_Code(bus, agent, &frame, card); | ||
263 | |||
264 | printk("%d. PCI: Bus%3d, Device%3d, Vendor %04X Frame%3d, Card %4s ", | ||
265 | count, bus, PCI_SLOT(PciDev->devfn), PciDev->vendor, | ||
266 | frame, card); | ||
267 | if (pci_class_name(PciDev->class >> 8) == 0) | ||
268 | printk("0x%04X\n", (int)(PciDev->class >> 8)); | ||
269 | else | ||
270 | printk("%s\n", pci_class_name(PciDev->class >> 8)); | ||
271 | } | ||
diff --git a/arch/ppc64/kernel/iSeries_iommu.c b/arch/ppc64/kernel/iSeries_iommu.c index 4e1a47c8a802..f8ff1bb054dc 100644 --- a/arch/ppc64/kernel/iSeries_iommu.c +++ b/arch/ppc64/kernel/iSeries_iommu.c | |||
@@ -83,7 +83,7 @@ static void tce_free_iSeries(struct iommu_table *tbl, long index, long npages) | |||
83 | } | 83 | } |
84 | } | 84 | } |
85 | 85 | ||
86 | 86 | #ifdef CONFIG_PCI | |
87 | /* | 87 | /* |
88 | * This function compares the known tables to find an iommu_table | 88 | * This function compares the known tables to find an iommu_table |
89 | * that has already been built for hardware TCEs. | 89 | * that has already been built for hardware TCEs. |
@@ -159,6 +159,7 @@ void iommu_devnode_init_iSeries(struct iSeries_Device_Node *dn) | |||
159 | else | 159 | else |
160 | kfree(tbl); | 160 | kfree(tbl); |
161 | } | 161 | } |
162 | #endif | ||
162 | 163 | ||
163 | static void iommu_dev_setup_iSeries(struct pci_dev *dev) { } | 164 | static void iommu_dev_setup_iSeries(struct pci_dev *dev) { } |
164 | static void iommu_bus_setup_iSeries(struct pci_bus *bus) { } | 165 | static void iommu_bus_setup_iSeries(struct pci_bus *bus) { } |
diff --git a/arch/ppc64/kernel/iSeries_irq.c b/arch/ppc64/kernel/iSeries_irq.c index f831d259dbb7..77376c1bd611 100644 --- a/arch/ppc64/kernel/iSeries_irq.c +++ b/arch/ppc64/kernel/iSeries_irq.c | |||
@@ -1,27 +1,29 @@ | |||
1 | /************************************************************************/ | 1 | /* |
2 | /* This module supports the iSeries PCI bus interrupt handling */ | 2 | * This module supports the iSeries PCI bus interrupt handling |
3 | /* Copyright (C) 20yy <Robert L Holtorf> <IBM Corp> */ | 3 | * Copyright (C) 20yy <Robert L Holtorf> <IBM Corp> |
4 | /* */ | 4 | * Copyright (C) 2004-2005 IBM Corporation |
5 | /* This program is free software; you can redistribute it and/or modify */ | 5 | * |
6 | /* it under the terms of the GNU General Public License as published by */ | 6 | * This program is free software; you can redistribute it and/or modify |
7 | /* the Free Software Foundation; either version 2 of the License, or */ | 7 | * it under the terms of the GNU General Public License as published by |
8 | /* (at your option) any later version. */ | 8 | * the Free Software Foundation; either version 2 of the License, or |
9 | /* */ | 9 | * (at your option) any later version. |
10 | /* This program is distributed in the hope that it will be useful, */ | 10 | * |
11 | /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ | 11 | * This program is distributed in the hope that it will be useful, |
12 | /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | /* GNU General Public License for more details. */ | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | /* */ | 14 | * GNU General Public License for more details. |
15 | /* You should have received a copy of the GNU General Public License */ | 15 | * |
16 | /* along with this program; if not, write to the: */ | 16 | * You should have received a copy of the GNU General Public License |
17 | /* Free Software Foundation, Inc., */ | 17 | * along with this program; if not, write to the: |
18 | /* 59 Temple Place, Suite 330, */ | 18 | * Free Software Foundation, Inc., |
19 | /* Boston, MA 02111-1307 USA */ | 19 | * 59 Temple Place, Suite 330, |
20 | /************************************************************************/ | 20 | * Boston, MA 02111-1307 USA |
21 | /* Change Activity: */ | 21 | * |
22 | /* Created, December 13, 2000 by Wayne Holm */ | 22 | * Change Activity: |
23 | /* End Change Activity */ | 23 | * Created, December 13, 2000 by Wayne Holm |
24 | /************************************************************************/ | 24 | * End Change Activity |
25 | */ | ||
26 | #include <linux/config.h> | ||
25 | #include <linux/pci.h> | 27 | #include <linux/pci.h> |
26 | #include <linux/init.h> | 28 | #include <linux/init.h> |
27 | #include <linux/threads.h> | 29 | #include <linux/threads.h> |
@@ -30,30 +32,15 @@ | |||
30 | #include <linux/string.h> | 32 | #include <linux/string.h> |
31 | #include <linux/bootmem.h> | 33 | #include <linux/bootmem.h> |
32 | #include <linux/ide.h> | 34 | #include <linux/ide.h> |
33 | |||
34 | #include <linux/irq.h> | 35 | #include <linux/irq.h> |
35 | #include <linux/spinlock.h> | 36 | #include <linux/spinlock.h> |
36 | #include <asm/ppcdebug.h> | ||
37 | 37 | ||
38 | #include <asm/ppcdebug.h> | ||
39 | #include <asm/iSeries/HvTypes.h> | ||
40 | #include <asm/iSeries/HvLpEvent.h> | ||
38 | #include <asm/iSeries/HvCallPci.h> | 41 | #include <asm/iSeries/HvCallPci.h> |
39 | #include <asm/iSeries/HvCallXm.h> | 42 | #include <asm/iSeries/HvCallXm.h> |
40 | #include <asm/iSeries/iSeries_irq.h> | 43 | #include <asm/iSeries/iSeries_irq.h> |
41 | #include <asm/iSeries/XmPciLpEvent.h> | ||
42 | |||
43 | static unsigned int iSeries_startup_IRQ(unsigned int irq); | ||
44 | static void iSeries_shutdown_IRQ(unsigned int irq); | ||
45 | static void iSeries_enable_IRQ(unsigned int irq); | ||
46 | static void iSeries_disable_IRQ(unsigned int irq); | ||
47 | static void iSeries_end_IRQ(unsigned int irq); | ||
48 | |||
49 | static hw_irq_controller iSeries_IRQ_handler = { | ||
50 | .typename = "iSeries irq controller", | ||
51 | .startup = iSeries_startup_IRQ, | ||
52 | .shutdown = iSeries_shutdown_IRQ, | ||
53 | .enable = iSeries_enable_IRQ, | ||
54 | .disable = iSeries_disable_IRQ, | ||
55 | .end = iSeries_end_IRQ | ||
56 | }; | ||
57 | 44 | ||
58 | /* This maps virtual irq numbers to real irqs */ | 45 | /* This maps virtual irq numbers to real irqs */ |
59 | unsigned int virt_irq_to_real_map[NR_IRQS]; | 46 | unsigned int virt_irq_to_real_map[NR_IRQS]; |
@@ -62,37 +49,187 @@ unsigned int virt_irq_to_real_map[NR_IRQS]; | |||
62 | /* Note: the pcnet32 driver assumes irq numbers < 2 aren't valid. :( */ | 49 | /* Note: the pcnet32 driver assumes irq numbers < 2 aren't valid. :( */ |
63 | static int next_virtual_irq = 2; | 50 | static int next_virtual_irq = 2; |
64 | 51 | ||
65 | /* This is called by init_IRQ. set in ppc_md.init_IRQ by iSeries_setup.c */ | 52 | static long Pci_Interrupt_Count; |
66 | void __init iSeries_init_IRQ(void) | 53 | static long Pci_Event_Count; |
54 | |||
55 | enum XmPciLpEvent_Subtype { | ||
56 | XmPciLpEvent_BusCreated = 0, // PHB has been created | ||
57 | XmPciLpEvent_BusError = 1, // PHB has failed | ||
58 | XmPciLpEvent_BusFailed = 2, // Msg to Secondary, Primary failed bus | ||
59 | XmPciLpEvent_NodeFailed = 4, // Multi-adapter bridge has failed | ||
60 | XmPciLpEvent_NodeRecovered = 5, // Multi-adapter bridge has recovered | ||
61 | XmPciLpEvent_BusRecovered = 12, // PHB has been recovered | ||
62 | XmPciLpEvent_UnQuiesceBus = 18, // Secondary bus unqiescing | ||
63 | XmPciLpEvent_BridgeError = 21, // Bridge Error | ||
64 | XmPciLpEvent_SlotInterrupt = 22 // Slot interrupt | ||
65 | }; | ||
66 | |||
67 | struct XmPciLpEvent_BusInterrupt { | ||
68 | HvBusNumber busNumber; | ||
69 | HvSubBusNumber subBusNumber; | ||
70 | }; | ||
71 | |||
72 | struct XmPciLpEvent_NodeInterrupt { | ||
73 | HvBusNumber busNumber; | ||
74 | HvSubBusNumber subBusNumber; | ||
75 | HvAgentId deviceId; | ||
76 | }; | ||
77 | |||
78 | struct XmPciLpEvent { | ||
79 | struct HvLpEvent hvLpEvent; | ||
80 | |||
81 | union { | ||
82 | u64 alignData; // Align on an 8-byte boundary | ||
83 | |||
84 | struct { | ||
85 | u32 fisr; | ||
86 | HvBusNumber busNumber; | ||
87 | HvSubBusNumber subBusNumber; | ||
88 | HvAgentId deviceId; | ||
89 | } slotInterrupt; | ||
90 | |||
91 | struct XmPciLpEvent_BusInterrupt busFailed; | ||
92 | struct XmPciLpEvent_BusInterrupt busRecovered; | ||
93 | struct XmPciLpEvent_BusInterrupt busCreated; | ||
94 | |||
95 | struct XmPciLpEvent_NodeInterrupt nodeFailed; | ||
96 | struct XmPciLpEvent_NodeInterrupt nodeRecovered; | ||
97 | |||
98 | } eventData; | ||
99 | |||
100 | }; | ||
101 | |||
102 | static void intReceived(struct XmPciLpEvent *eventParm, | ||
103 | struct pt_regs *regsParm) | ||
67 | { | 104 | { |
68 | /* Register PCI event handler and open an event path */ | 105 | int irq; |
69 | XmPciLpEvent_init(); | 106 | |
107 | ++Pci_Interrupt_Count; | ||
108 | |||
109 | switch (eventParm->hvLpEvent.xSubtype) { | ||
110 | case XmPciLpEvent_SlotInterrupt: | ||
111 | irq = eventParm->hvLpEvent.xCorrelationToken; | ||
112 | /* Dispatch the interrupt handlers for this irq */ | ||
113 | ppc_irq_dispatch_handler(regsParm, irq); | ||
114 | HvCallPci_eoi(eventParm->eventData.slotInterrupt.busNumber, | ||
115 | eventParm->eventData.slotInterrupt.subBusNumber, | ||
116 | eventParm->eventData.slotInterrupt.deviceId); | ||
117 | break; | ||
118 | /* Ignore error recovery events for now */ | ||
119 | case XmPciLpEvent_BusCreated: | ||
120 | printk(KERN_INFO "intReceived: system bus %d created\n", | ||
121 | eventParm->eventData.busCreated.busNumber); | ||
122 | break; | ||
123 | case XmPciLpEvent_BusError: | ||
124 | case XmPciLpEvent_BusFailed: | ||
125 | printk(KERN_INFO "intReceived: system bus %d failed\n", | ||
126 | eventParm->eventData.busFailed.busNumber); | ||
127 | break; | ||
128 | case XmPciLpEvent_BusRecovered: | ||
129 | case XmPciLpEvent_UnQuiesceBus: | ||
130 | printk(KERN_INFO "intReceived: system bus %d recovered\n", | ||
131 | eventParm->eventData.busRecovered.busNumber); | ||
132 | break; | ||
133 | case XmPciLpEvent_NodeFailed: | ||
134 | case XmPciLpEvent_BridgeError: | ||
135 | printk(KERN_INFO | ||
136 | "intReceived: multi-adapter bridge %d/%d/%d failed\n", | ||
137 | eventParm->eventData.nodeFailed.busNumber, | ||
138 | eventParm->eventData.nodeFailed.subBusNumber, | ||
139 | eventParm->eventData.nodeFailed.deviceId); | ||
140 | break; | ||
141 | case XmPciLpEvent_NodeRecovered: | ||
142 | printk(KERN_INFO | ||
143 | "intReceived: multi-adapter bridge %d/%d/%d recovered\n", | ||
144 | eventParm->eventData.nodeRecovered.busNumber, | ||
145 | eventParm->eventData.nodeRecovered.subBusNumber, | ||
146 | eventParm->eventData.nodeRecovered.deviceId); | ||
147 | break; | ||
148 | default: | ||
149 | printk(KERN_ERR | ||
150 | "intReceived: unrecognized event subtype 0x%x\n", | ||
151 | eventParm->hvLpEvent.xSubtype); | ||
152 | break; | ||
153 | } | ||
154 | } | ||
155 | |||
156 | static void XmPciLpEvent_handler(struct HvLpEvent *eventParm, | ||
157 | struct pt_regs *regsParm) | ||
158 | { | ||
159 | #ifdef CONFIG_PCI | ||
160 | ++Pci_Event_Count; | ||
161 | |||
162 | if (eventParm && (eventParm->xType == HvLpEvent_Type_PciIo)) { | ||
163 | switch (eventParm->xFlags.xFunction) { | ||
164 | case HvLpEvent_Function_Int: | ||
165 | intReceived((struct XmPciLpEvent *)eventParm, regsParm); | ||
166 | break; | ||
167 | case HvLpEvent_Function_Ack: | ||
168 | printk(KERN_ERR | ||
169 | "XmPciLpEvent_handler: unexpected ack received\n"); | ||
170 | break; | ||
171 | default: | ||
172 | printk(KERN_ERR | ||
173 | "XmPciLpEvent_handler: unexpected event function %d\n", | ||
174 | (int)eventParm->xFlags.xFunction); | ||
175 | break; | ||
176 | } | ||
177 | } else if (eventParm) | ||
178 | printk(KERN_ERR | ||
179 | "XmPciLpEvent_handler: Unrecognized PCI event type 0x%x\n", | ||
180 | (int)eventParm->xType); | ||
181 | else | ||
182 | printk(KERN_ERR "XmPciLpEvent_handler: NULL event received\n"); | ||
183 | #endif | ||
70 | } | 184 | } |
71 | 185 | ||
72 | /* | 186 | /* |
73 | * This is called out of iSeries_scan_slot to allocate an IRQ for an EADS slot | 187 | * This is called by init_IRQ. set in ppc_md.init_IRQ by iSeries_setup.c |
74 | * It calculates the irq value for the slot. | 188 | * It must be called before the bus walk. |
75 | * Note that subBusNumber is always 0 (at the moment at least). | ||
76 | */ | 189 | */ |
77 | int __init iSeries_allocate_IRQ(HvBusNumber busNumber, | 190 | void __init iSeries_init_IRQ(void) |
78 | HvSubBusNumber subBusNumber, HvAgentId deviceId) | ||
79 | { | 191 | { |
80 | unsigned int realirq, virtirq; | 192 | /* Register PCI event handler and open an event path */ |
81 | u8 idsel = (deviceId >> 4); | 193 | int xRc; |
82 | u8 function = deviceId & 7; | ||
83 | |||
84 | virtirq = next_virtual_irq++; | ||
85 | realirq = ((busNumber - 1) << 6) + ((idsel - 1) << 3) + function; | ||
86 | virt_irq_to_real_map[virtirq] = realirq; | ||
87 | 194 | ||
88 | irq_desc[virtirq].handler = &iSeries_IRQ_handler; | 195 | xRc = HvLpEvent_registerHandler(HvLpEvent_Type_PciIo, |
89 | return virtirq; | 196 | &XmPciLpEvent_handler); |
197 | if (xRc == 0) { | ||
198 | xRc = HvLpEvent_openPath(HvLpEvent_Type_PciIo, 0); | ||
199 | if (xRc != 0) | ||
200 | printk(KERN_ERR "iSeries_init_IRQ: open event path " | ||
201 | "failed with rc 0x%x\n", xRc); | ||
202 | } else | ||
203 | printk(KERN_ERR "iSeries_init_IRQ: register handler " | ||
204 | "failed with rc 0x%x\n", xRc); | ||
90 | } | 205 | } |
91 | 206 | ||
92 | #define REAL_IRQ_TO_BUS(irq) ((((irq) >> 6) & 0xff) + 1) | 207 | #define REAL_IRQ_TO_BUS(irq) ((((irq) >> 6) & 0xff) + 1) |
93 | #define REAL_IRQ_TO_IDSEL(irq) ((((irq) >> 3) & 7) + 1) | 208 | #define REAL_IRQ_TO_IDSEL(irq) ((((irq) >> 3) & 7) + 1) |
94 | #define REAL_IRQ_TO_FUNC(irq) ((irq) & 7) | 209 | #define REAL_IRQ_TO_FUNC(irq) ((irq) & 7) |
95 | 210 | ||
211 | /* | ||
212 | * This will be called by device drivers (via enable_IRQ) | ||
213 | * to enable INTA in the bridge interrupt status register. | ||
214 | */ | ||
215 | static void iSeries_enable_IRQ(unsigned int irq) | ||
216 | { | ||
217 | u32 bus, deviceId, function, mask; | ||
218 | const u32 subBus = 0; | ||
219 | unsigned int rirq = virt_irq_to_real_map[irq]; | ||
220 | |||
221 | /* The IRQ has already been locked by the caller */ | ||
222 | bus = REAL_IRQ_TO_BUS(rirq); | ||
223 | function = REAL_IRQ_TO_FUNC(rirq); | ||
224 | deviceId = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function; | ||
225 | |||
226 | /* Unmask secondary INTA */ | ||
227 | mask = 0x80000000; | ||
228 | HvCallPci_unmaskInterrupts(bus, subBus, deviceId, mask); | ||
229 | PPCDBG(PPCDBG_BUSWALK, "iSeries_enable_IRQ 0x%02X.%02X.%02X 0x%04X\n", | ||
230 | bus, subBus, deviceId, irq); | ||
231 | } | ||
232 | |||
96 | /* This is called by iSeries_activate_IRQs */ | 233 | /* This is called by iSeries_activate_IRQs */ |
97 | static unsigned int iSeries_startup_IRQ(unsigned int irq) | 234 | static unsigned int iSeries_startup_IRQ(unsigned int irq) |
98 | { | 235 | { |
@@ -131,7 +268,7 @@ void __init iSeries_activate_IRQs() | |||
131 | desc->handler->startup(irq); | 268 | desc->handler->startup(irq); |
132 | spin_unlock_irqrestore(&desc->lock, flags); | 269 | spin_unlock_irqrestore(&desc->lock, flags); |
133 | } | 270 | } |
134 | } | 271 | } |
135 | } | 272 | } |
136 | 273 | ||
137 | /* this is not called anywhere currently */ | 274 | /* this is not called anywhere currently */ |
@@ -173,29 +310,7 @@ static void iSeries_disable_IRQ(unsigned int irq) | |||
173 | mask = 0x80000000; | 310 | mask = 0x80000000; |
174 | HvCallPci_maskInterrupts(bus, subBus, deviceId, mask); | 311 | HvCallPci_maskInterrupts(bus, subBus, deviceId, mask); |
175 | PPCDBG(PPCDBG_BUSWALK, "iSeries_disable_IRQ 0x%02X.%02X.%02X 0x%04X\n", | 312 | PPCDBG(PPCDBG_BUSWALK, "iSeries_disable_IRQ 0x%02X.%02X.%02X 0x%04X\n", |
176 | bus, subBus, deviceId, irq); | 313 | bus, subBus, deviceId, irq); |
177 | } | ||
178 | |||
179 | /* | ||
180 | * This will be called by device drivers (via enable_IRQ) | ||
181 | * to enable INTA in the bridge interrupt status register. | ||
182 | */ | ||
183 | static void iSeries_enable_IRQ(unsigned int irq) | ||
184 | { | ||
185 | u32 bus, deviceId, function, mask; | ||
186 | const u32 subBus = 0; | ||
187 | unsigned int rirq = virt_irq_to_real_map[irq]; | ||
188 | |||
189 | /* The IRQ has already been locked by the caller */ | ||
190 | bus = REAL_IRQ_TO_BUS(rirq); | ||
191 | function = REAL_IRQ_TO_FUNC(rirq); | ||
192 | deviceId = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function; | ||
193 | |||
194 | /* Unmask secondary INTA */ | ||
195 | mask = 0x80000000; | ||
196 | HvCallPci_unmaskInterrupts(bus, subBus, deviceId, mask); | ||
197 | PPCDBG(PPCDBG_BUSWALK, "iSeries_enable_IRQ 0x%02X.%02X.%02X 0x%04X\n", | ||
198 | bus, subBus, deviceId, irq); | ||
199 | } | 314 | } |
200 | 315 | ||
201 | /* | 316 | /* |
@@ -207,3 +322,32 @@ static void iSeries_enable_IRQ(unsigned int irq) | |||
207 | static void iSeries_end_IRQ(unsigned int irq) | 322 | static void iSeries_end_IRQ(unsigned int irq) |
208 | { | 323 | { |
209 | } | 324 | } |
325 | |||
326 | static hw_irq_controller iSeries_IRQ_handler = { | ||
327 | .typename = "iSeries irq controller", | ||
328 | .startup = iSeries_startup_IRQ, | ||
329 | .shutdown = iSeries_shutdown_IRQ, | ||
330 | .enable = iSeries_enable_IRQ, | ||
331 | .disable = iSeries_disable_IRQ, | ||
332 | .end = iSeries_end_IRQ | ||
333 | }; | ||
334 | |||
335 | /* | ||
336 | * This is called out of iSeries_scan_slot to allocate an IRQ for an EADS slot | ||
337 | * It calculates the irq value for the slot. | ||
338 | * Note that subBusNumber is always 0 (at the moment at least). | ||
339 | */ | ||
340 | int __init iSeries_allocate_IRQ(HvBusNumber busNumber, | ||
341 | HvSubBusNumber subBusNumber, HvAgentId deviceId) | ||
342 | { | ||
343 | unsigned int realirq, virtirq; | ||
344 | u8 idsel = (deviceId >> 4); | ||
345 | u8 function = deviceId & 7; | ||
346 | |||
347 | virtirq = next_virtual_irq++; | ||
348 | realirq = ((busNumber - 1) << 6) + ((idsel - 1) << 3) + function; | ||
349 | virt_irq_to_real_map[virtirq] = realirq; | ||
350 | |||
351 | irq_desc[virtirq].handler = &iSeries_IRQ_handler; | ||
352 | return virtirq; | ||
353 | } | ||
diff --git a/arch/ppc64/kernel/iSeries_pci.c b/arch/ppc64/kernel/iSeries_pci.c index bd4c2554f1a0..356e4fd9a94f 100644 --- a/arch/ppc64/kernel/iSeries_pci.c +++ b/arch/ppc64/kernel/iSeries_pci.c | |||
@@ -38,9 +38,7 @@ | |||
38 | #include <asm/iommu.h> | 38 | #include <asm/iommu.h> |
39 | 39 | ||
40 | #include <asm/iSeries/HvCallPci.h> | 40 | #include <asm/iSeries/HvCallPci.h> |
41 | #include <asm/iSeries/HvCallSm.h> | ||
42 | #include <asm/iSeries/HvCallXm.h> | 41 | #include <asm/iSeries/HvCallXm.h> |
43 | #include <asm/iSeries/LparData.h> | ||
44 | #include <asm/iSeries/iSeries_irq.h> | 42 | #include <asm/iSeries/iSeries_irq.h> |
45 | #include <asm/iSeries/iSeries_pci.h> | 43 | #include <asm/iSeries/iSeries_pci.h> |
46 | #include <asm/iSeries/mf.h> | 44 | #include <asm/iSeries/mf.h> |
@@ -225,10 +223,7 @@ static struct iSeries_Device_Node *build_device_node(HvBusNumber Bus, | |||
225 | node->DsaAddr.Dsa.busNumber = Bus; | 223 | node->DsaAddr.Dsa.busNumber = Bus; |
226 | node->DsaAddr.Dsa.subBusNumber = SubBus; | 224 | node->DsaAddr.Dsa.subBusNumber = SubBus; |
227 | node->DsaAddr.Dsa.deviceId = 0x10; | 225 | node->DsaAddr.Dsa.deviceId = 0x10; |
228 | node->AgentId = AgentId; | ||
229 | node->DevFn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId), Function); | 226 | node->DevFn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId), Function); |
230 | node->IoRetry = 0; | ||
231 | iSeries_Get_Location_Code(node); | ||
232 | return node; | 227 | return node; |
233 | } | 228 | } |
234 | 229 | ||
@@ -302,7 +297,6 @@ void __init iSeries_pci_final_fixup(void) | |||
302 | { | 297 | { |
303 | struct pci_dev *pdev = NULL; | 298 | struct pci_dev *pdev = NULL; |
304 | struct iSeries_Device_Node *node; | 299 | struct iSeries_Device_Node *node; |
305 | char Buffer[256]; | ||
306 | int DeviceCount = 0; | 300 | int DeviceCount = 0; |
307 | 301 | ||
308 | PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup Entry.\n"); | 302 | PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup Entry.\n"); |
@@ -324,9 +318,7 @@ void __init iSeries_pci_final_fixup(void) | |||
324 | "pdev 0x%p <==> DevNode 0x%p\n", | 318 | "pdev 0x%p <==> DevNode 0x%p\n", |
325 | pdev, node); | 319 | pdev, node); |
326 | allocate_device_bars(pdev); | 320 | allocate_device_bars(pdev); |
327 | iSeries_Device_Information(pdev, Buffer, | 321 | iSeries_Device_Information(pdev, DeviceCount); |
328 | sizeof(Buffer)); | ||
329 | printk("%d. %s\n", DeviceCount, Buffer); | ||
330 | iommu_devnode_init_iSeries(node); | 322 | iommu_devnode_init_iSeries(node); |
331 | } else | 323 | } else |
332 | printk("PCI: Device Tree not found for 0x%016lX\n", | 324 | printk("PCI: Device Tree not found for 0x%016lX\n", |
@@ -499,7 +491,6 @@ static int scan_bridge_slot(HvBusNumber Bus, | |||
499 | 491 | ||
500 | ++DeviceCount; | 492 | ++DeviceCount; |
501 | node = build_device_node(Bus, SubBus, EADsIdSel, Function); | 493 | node = build_device_node(Bus, SubBus, EADsIdSel, Function); |
502 | node->Vendor = VendorId; | ||
503 | node->Irq = Irq; | 494 | node->Irq = Irq; |
504 | node->LogicalSlot = BridgeInfo->logicalSlotNumber; | 495 | node->LogicalSlot = BridgeInfo->logicalSlotNumber; |
505 | 496 | ||
@@ -661,38 +652,34 @@ static struct pci_ops iSeries_pci_ops = { | |||
661 | * Check Return Code | 652 | * Check Return Code |
662 | * -> On Failure, print and log information. | 653 | * -> On Failure, print and log information. |
663 | * Increment Retry Count, if exceeds max, panic partition. | 654 | * Increment Retry Count, if exceeds max, panic partition. |
664 | * -> If in retry, print and log success | ||
665 | * | 655 | * |
666 | * PCI: Device 23.90 ReadL I/O Error( 0): 0x1234 | 656 | * PCI: Device 23.90 ReadL I/O Error( 0): 0x1234 |
667 | * PCI: Device 23.90 ReadL Retry( 1) | 657 | * PCI: Device 23.90 ReadL Retry( 1) |
668 | * PCI: Device 23.90 ReadL Retry Successful(1) | 658 | * PCI: Device 23.90 ReadL Retry Successful(1) |
669 | */ | 659 | */ |
670 | static int CheckReturnCode(char *TextHdr, struct iSeries_Device_Node *DevNode, | 660 | static int CheckReturnCode(char *TextHdr, struct iSeries_Device_Node *DevNode, |
671 | u64 ret) | 661 | int *retry, u64 ret) |
672 | { | 662 | { |
673 | if (ret != 0) { | 663 | if (ret != 0) { |
674 | ++Pci_Error_Count; | 664 | ++Pci_Error_Count; |
675 | ++DevNode->IoRetry; | 665 | (*retry)++; |
676 | printk("PCI: %s: Device 0x%04X:%02X I/O Error(%2d): 0x%04X\n", | 666 | printk("PCI: %s: Device 0x%04X:%02X I/O Error(%2d): 0x%04X\n", |
677 | TextHdr, DevNode->DsaAddr.Dsa.busNumber, DevNode->DevFn, | 667 | TextHdr, DevNode->DsaAddr.Dsa.busNumber, DevNode->DevFn, |
678 | DevNode->IoRetry, (int)ret); | 668 | *retry, (int)ret); |
679 | /* | 669 | /* |
680 | * Bump the retry and check for retry count exceeded. | 670 | * Bump the retry and check for retry count exceeded. |
681 | * If, Exceeded, panic the system. | 671 | * If, Exceeded, panic the system. |
682 | */ | 672 | */ |
683 | if ((DevNode->IoRetry > Pci_Retry_Max) && | 673 | if (((*retry) > Pci_Retry_Max) && |
684 | (Pci_Error_Flag > 0)) { | 674 | (Pci_Error_Flag > 0)) { |
685 | mf_display_src(0xB6000103); | 675 | mf_display_src(0xB6000103); |
686 | panic_timeout = 0; | 676 | panic_timeout = 0; |
687 | panic("PCI: Hardware I/O Error, SRC B6000103, " | 677 | panic("PCI: Hardware I/O Error, SRC B6000103, " |
688 | "Automatic Reboot Disabled.\n"); | 678 | "Automatic Reboot Disabled.\n"); |
689 | } | 679 | } |
690 | return -1; /* Retry Try */ | 680 | return -1; /* Retry Try */ |
691 | } | 681 | } |
692 | /* If retry was in progress, log success and rest retry count */ | 682 | return 0; |
693 | if (DevNode->IoRetry > 0) | ||
694 | DevNode->IoRetry = 0; | ||
695 | return 0; | ||
696 | } | 683 | } |
697 | 684 | ||
698 | /* | 685 | /* |
@@ -738,6 +725,7 @@ u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress) | |||
738 | { | 725 | { |
739 | u64 BarOffset; | 726 | u64 BarOffset; |
740 | u64 dsa; | 727 | u64 dsa; |
728 | int retry = 0; | ||
741 | struct HvCallPci_LoadReturn ret; | 729 | struct HvCallPci_LoadReturn ret; |
742 | struct iSeries_Device_Node *DevNode = | 730 | struct iSeries_Device_Node *DevNode = |
743 | xlate_iomm_address(IoAddress, &dsa, &BarOffset); | 731 | xlate_iomm_address(IoAddress, &dsa, &BarOffset); |
@@ -757,7 +745,7 @@ u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress) | |||
757 | do { | 745 | do { |
758 | ++Pci_Io_Read_Count; | 746 | ++Pci_Io_Read_Count; |
759 | HvCall3Ret16(HvCallPciBarLoad8, &ret, dsa, BarOffset, 0); | 747 | HvCall3Ret16(HvCallPciBarLoad8, &ret, dsa, BarOffset, 0); |
760 | } while (CheckReturnCode("RDB", DevNode, ret.rc) != 0); | 748 | } while (CheckReturnCode("RDB", DevNode, &retry, ret.rc) != 0); |
761 | 749 | ||
762 | return (u8)ret.value; | 750 | return (u8)ret.value; |
763 | } | 751 | } |
@@ -767,6 +755,7 @@ u16 iSeries_Read_Word(const volatile void __iomem *IoAddress) | |||
767 | { | 755 | { |
768 | u64 BarOffset; | 756 | u64 BarOffset; |
769 | u64 dsa; | 757 | u64 dsa; |
758 | int retry = 0; | ||
770 | struct HvCallPci_LoadReturn ret; | 759 | struct HvCallPci_LoadReturn ret; |
771 | struct iSeries_Device_Node *DevNode = | 760 | struct iSeries_Device_Node *DevNode = |
772 | xlate_iomm_address(IoAddress, &dsa, &BarOffset); | 761 | xlate_iomm_address(IoAddress, &dsa, &BarOffset); |
@@ -787,7 +776,7 @@ u16 iSeries_Read_Word(const volatile void __iomem *IoAddress) | |||
787 | ++Pci_Io_Read_Count; | 776 | ++Pci_Io_Read_Count; |
788 | HvCall3Ret16(HvCallPciBarLoad16, &ret, dsa, | 777 | HvCall3Ret16(HvCallPciBarLoad16, &ret, dsa, |
789 | BarOffset, 0); | 778 | BarOffset, 0); |
790 | } while (CheckReturnCode("RDW", DevNode, ret.rc) != 0); | 779 | } while (CheckReturnCode("RDW", DevNode, &retry, ret.rc) != 0); |
791 | 780 | ||
792 | return swab16((u16)ret.value); | 781 | return swab16((u16)ret.value); |
793 | } | 782 | } |
@@ -797,6 +786,7 @@ u32 iSeries_Read_Long(const volatile void __iomem *IoAddress) | |||
797 | { | 786 | { |
798 | u64 BarOffset; | 787 | u64 BarOffset; |
799 | u64 dsa; | 788 | u64 dsa; |
789 | int retry = 0; | ||
800 | struct HvCallPci_LoadReturn ret; | 790 | struct HvCallPci_LoadReturn ret; |
801 | struct iSeries_Device_Node *DevNode = | 791 | struct iSeries_Device_Node *DevNode = |
802 | xlate_iomm_address(IoAddress, &dsa, &BarOffset); | 792 | xlate_iomm_address(IoAddress, &dsa, &BarOffset); |
@@ -817,7 +807,7 @@ u32 iSeries_Read_Long(const volatile void __iomem *IoAddress) | |||
817 | ++Pci_Io_Read_Count; | 807 | ++Pci_Io_Read_Count; |
818 | HvCall3Ret16(HvCallPciBarLoad32, &ret, dsa, | 808 | HvCall3Ret16(HvCallPciBarLoad32, &ret, dsa, |
819 | BarOffset, 0); | 809 | BarOffset, 0); |
820 | } while (CheckReturnCode("RDL", DevNode, ret.rc) != 0); | 810 | } while (CheckReturnCode("RDL", DevNode, &retry, ret.rc) != 0); |
821 | 811 | ||
822 | return swab32((u32)ret.value); | 812 | return swab32((u32)ret.value); |
823 | } | 813 | } |
@@ -834,6 +824,7 @@ void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress) | |||
834 | { | 824 | { |
835 | u64 BarOffset; | 825 | u64 BarOffset; |
836 | u64 dsa; | 826 | u64 dsa; |
827 | int retry = 0; | ||
837 | u64 rc; | 828 | u64 rc; |
838 | struct iSeries_Device_Node *DevNode = | 829 | struct iSeries_Device_Node *DevNode = |
839 | xlate_iomm_address(IoAddress, &dsa, &BarOffset); | 830 | xlate_iomm_address(IoAddress, &dsa, &BarOffset); |
@@ -853,7 +844,7 @@ void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress) | |||
853 | do { | 844 | do { |
854 | ++Pci_Io_Write_Count; | 845 | ++Pci_Io_Write_Count; |
855 | rc = HvCall4(HvCallPciBarStore8, dsa, BarOffset, data, 0); | 846 | rc = HvCall4(HvCallPciBarStore8, dsa, BarOffset, data, 0); |
856 | } while (CheckReturnCode("WWB", DevNode, rc) != 0); | 847 | } while (CheckReturnCode("WWB", DevNode, &retry, rc) != 0); |
857 | } | 848 | } |
858 | EXPORT_SYMBOL(iSeries_Write_Byte); | 849 | EXPORT_SYMBOL(iSeries_Write_Byte); |
859 | 850 | ||
@@ -861,6 +852,7 @@ void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress) | |||
861 | { | 852 | { |
862 | u64 BarOffset; | 853 | u64 BarOffset; |
863 | u64 dsa; | 854 | u64 dsa; |
855 | int retry = 0; | ||
864 | u64 rc; | 856 | u64 rc; |
865 | struct iSeries_Device_Node *DevNode = | 857 | struct iSeries_Device_Node *DevNode = |
866 | xlate_iomm_address(IoAddress, &dsa, &BarOffset); | 858 | xlate_iomm_address(IoAddress, &dsa, &BarOffset); |
@@ -880,7 +872,7 @@ void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress) | |||
880 | do { | 872 | do { |
881 | ++Pci_Io_Write_Count; | 873 | ++Pci_Io_Write_Count; |
882 | rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, swab16(data), 0); | 874 | rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, swab16(data), 0); |
883 | } while (CheckReturnCode("WWW", DevNode, rc) != 0); | 875 | } while (CheckReturnCode("WWW", DevNode, &retry, rc) != 0); |
884 | } | 876 | } |
885 | EXPORT_SYMBOL(iSeries_Write_Word); | 877 | EXPORT_SYMBOL(iSeries_Write_Word); |
886 | 878 | ||
@@ -888,6 +880,7 @@ void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress) | |||
888 | { | 880 | { |
889 | u64 BarOffset; | 881 | u64 BarOffset; |
890 | u64 dsa; | 882 | u64 dsa; |
883 | int retry = 0; | ||
891 | u64 rc; | 884 | u64 rc; |
892 | struct iSeries_Device_Node *DevNode = | 885 | struct iSeries_Device_Node *DevNode = |
893 | xlate_iomm_address(IoAddress, &dsa, &BarOffset); | 886 | xlate_iomm_address(IoAddress, &dsa, &BarOffset); |
@@ -907,6 +900,6 @@ void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress) | |||
907 | do { | 900 | do { |
908 | ++Pci_Io_Write_Count; | 901 | ++Pci_Io_Write_Count; |
909 | rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, swab32(data), 0); | 902 | rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, swab32(data), 0); |
910 | } while (CheckReturnCode("WWL", DevNode, rc) != 0); | 903 | } while (CheckReturnCode("WWL", DevNode, &retry, rc) != 0); |
911 | } | 904 | } |
912 | EXPORT_SYMBOL(iSeries_Write_Long); | 905 | EXPORT_SYMBOL(iSeries_Write_Long); |
diff --git a/arch/ppc64/kernel/iSeries_pci_reset.c b/arch/ppc64/kernel/iSeries_pci_reset.c deleted file mode 100644 index 0f785e4584f7..000000000000 --- a/arch/ppc64/kernel/iSeries_pci_reset.c +++ /dev/null | |||
@@ -1,104 +0,0 @@ | |||
1 | #define PCIFR(...) | ||
2 | /************************************************************************/ | ||
3 | /* File iSeries_pci_reset.c created by Allan Trautman on Mar 21 2001. */ | ||
4 | /************************************************************************/ | ||
5 | /* This code supports the pci interface on the IBM iSeries systems. */ | ||
6 | /* Copyright (C) 20yy <Allan H Trautman> <IBM Corp> */ | ||
7 | /* */ | ||
8 | /* This program is free software; you can redistribute it and/or modify */ | ||
9 | /* it under the terms of the GNU General Public License as published by */ | ||
10 | /* the Free Software Foundation; either version 2 of the License, or */ | ||
11 | /* (at your option) any later version. */ | ||
12 | /* */ | ||
13 | /* This program is distributed in the hope that it will be useful, */ | ||
14 | /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ | ||
15 | /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ | ||
16 | /* GNU General Public License for more details. */ | ||
17 | /* */ | ||
18 | /* You should have received a copy of the GNU General Public License */ | ||
19 | /* along with this program; if not, write to the: */ | ||
20 | /* Free Software Foundation, Inc., */ | ||
21 | /* 59 Temple Place, Suite 330, */ | ||
22 | /* Boston, MA 02111-1307 USA */ | ||
23 | /************************************************************************/ | ||
24 | /* Change Activity: */ | ||
25 | /* Created, March 20, 2001 */ | ||
26 | /* April 30, 2001, Added return codes on functions. */ | ||
27 | /* September 10, 2001, Ported to ppc64. */ | ||
28 | /* End Change Activity */ | ||
29 | /************************************************************************/ | ||
30 | #include <linux/kernel.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/module.h> | ||
33 | #include <linux/pci.h> | ||
34 | #include <linux/irq.h> | ||
35 | #include <linux/delay.h> | ||
36 | |||
37 | #include <asm/io.h> | ||
38 | #include <asm/iSeries/HvCallPci.h> | ||
39 | #include <asm/iSeries/HvTypes.h> | ||
40 | #include <asm/iSeries/mf.h> | ||
41 | #include <asm/pci.h> | ||
42 | |||
43 | #include <asm/iSeries/iSeries_pci.h> | ||
44 | #include "pci.h" | ||
45 | |||
46 | /* | ||
47 | * Interface to toggle the reset line | ||
48 | * Time is in .1 seconds, need for seconds. | ||
49 | */ | ||
50 | int iSeries_Device_ToggleReset(struct pci_dev *PciDev, int AssertTime, | ||
51 | int DelayTime) | ||
52 | { | ||
53 | unsigned int AssertDelay, WaitDelay; | ||
54 | struct iSeries_Device_Node *DeviceNode = | ||
55 | (struct iSeries_Device_Node *)PciDev->sysdata; | ||
56 | |||
57 | if (DeviceNode == NULL) { | ||
58 | printk("PCI: Pci Reset Failed, Device Node not found for pci_dev %p\n", | ||
59 | PciDev); | ||
60 | return -1; | ||
61 | } | ||
62 | /* | ||
63 | * Set defaults, Assert is .5 second, Wait is 3 seconds. | ||
64 | */ | ||
65 | if (AssertTime == 0) | ||
66 | AssertDelay = 500; | ||
67 | else | ||
68 | AssertDelay = AssertTime * 100; | ||
69 | |||
70 | if (DelayTime == 0) | ||
71 | WaitDelay = 3000; | ||
72 | else | ||
73 | WaitDelay = DelayTime * 100; | ||
74 | |||
75 | /* | ||
76 | * Assert reset | ||
77 | */ | ||
78 | DeviceNode->ReturnCode = HvCallPci_setSlotReset(ISERIES_BUS(DeviceNode), | ||
79 | 0x00, DeviceNode->AgentId, 1); | ||
80 | if (DeviceNode->ReturnCode == 0) { | ||
81 | msleep(AssertDelay); /* Sleep for the time */ | ||
82 | DeviceNode->ReturnCode = | ||
83 | HvCallPci_setSlotReset(ISERIES_BUS(DeviceNode), | ||
84 | 0x00, DeviceNode->AgentId, 0); | ||
85 | |||
86 | /* | ||
87 | * Wait for device to reset | ||
88 | */ | ||
89 | msleep(WaitDelay); | ||
90 | } | ||
91 | if (DeviceNode->ReturnCode == 0) | ||
92 | PCIFR("Slot 0x%04X.%02 Reset\n", ISERIES_BUS(DeviceNode), | ||
93 | DeviceNode->AgentId); | ||
94 | else { | ||
95 | printk("PCI: Slot 0x%04X.%02X Reset Failed, RCode: %04X\n", | ||
96 | ISERIES_BUS(DeviceNode), DeviceNode->AgentId, | ||
97 | DeviceNode->ReturnCode); | ||
98 | PCIFR("Slot 0x%04X.%02X Reset Failed, RCode: %04X\n", | ||
99 | ISERIES_BUS(DeviceNode), DeviceNode->AgentId, | ||
100 | DeviceNode->ReturnCode); | ||
101 | } | ||
102 | return DeviceNode->ReturnCode; | ||
103 | } | ||
104 | EXPORT_SYMBOL(iSeries_Device_ToggleReset); | ||
diff --git a/arch/ppc64/kernel/iSeries_proc.c b/arch/ppc64/kernel/iSeries_proc.c index 0cc58ddf48de..356bd9931fcc 100644 --- a/arch/ppc64/kernel/iSeries_proc.c +++ b/arch/ppc64/kernel/iSeries_proc.c | |||
@@ -28,8 +28,7 @@ | |||
28 | #include <asm/iSeries/ItLpQueue.h> | 28 | #include <asm/iSeries/ItLpQueue.h> |
29 | #include <asm/iSeries/HvCallXm.h> | 29 | #include <asm/iSeries/HvCallXm.h> |
30 | #include <asm/iSeries/IoHriMainStore.h> | 30 | #include <asm/iSeries/IoHriMainStore.h> |
31 | #include <asm/iSeries/LparData.h> | 31 | #include <asm/iSeries/IoHriProcessorVpd.h> |
32 | #include <asm/iSeries/iSeries_proc.h> | ||
33 | 32 | ||
34 | static int __init iseries_proc_create(void) | 33 | static int __init iseries_proc_create(void) |
35 | { | 34 | { |
diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c index 6d06eb550a3f..b31962436fe3 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/ppc64/kernel/iSeries_setup.c | |||
@@ -47,7 +47,7 @@ | |||
47 | #include <asm/paca.h> | 47 | #include <asm/paca.h> |
48 | #include <asm/cache.h> | 48 | #include <asm/cache.h> |
49 | #include <asm/sections.h> | 49 | #include <asm/sections.h> |
50 | #include <asm/iSeries/LparData.h> | 50 | #include <asm/abs_addr.h> |
51 | #include <asm/iSeries/HvCallHpt.h> | 51 | #include <asm/iSeries/HvCallHpt.h> |
52 | #include <asm/iSeries/HvLpConfig.h> | 52 | #include <asm/iSeries/HvLpConfig.h> |
53 | #include <asm/iSeries/HvCallEvent.h> | 53 | #include <asm/iSeries/HvCallEvent.h> |
@@ -55,10 +55,12 @@ | |||
55 | #include <asm/iSeries/HvCallXm.h> | 55 | #include <asm/iSeries/HvCallXm.h> |
56 | #include <asm/iSeries/ItLpQueue.h> | 56 | #include <asm/iSeries/ItLpQueue.h> |
57 | #include <asm/iSeries/IoHriMainStore.h> | 57 | #include <asm/iSeries/IoHriMainStore.h> |
58 | #include <asm/iSeries/iSeries_proc.h> | ||
59 | #include <asm/iSeries/mf.h> | 58 | #include <asm/iSeries/mf.h> |
60 | #include <asm/iSeries/HvLpEvent.h> | 59 | #include <asm/iSeries/HvLpEvent.h> |
61 | #include <asm/iSeries/iSeries_irq.h> | 60 | #include <asm/iSeries/iSeries_irq.h> |
61 | #include <asm/iSeries/IoHriProcessorVpd.h> | ||
62 | #include <asm/iSeries/ItVpdAreas.h> | ||
63 | #include <asm/iSeries/LparMap.h> | ||
62 | 64 | ||
63 | extern void hvlog(char *fmt, ...); | 65 | extern void hvlog(char *fmt, ...); |
64 | 66 | ||
@@ -74,7 +76,11 @@ extern void ppcdbg_initialize(void); | |||
74 | static void build_iSeries_Memory_Map(void); | 76 | static void build_iSeries_Memory_Map(void); |
75 | static void setup_iSeries_cache_sizes(void); | 77 | static void setup_iSeries_cache_sizes(void); |
76 | static void iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr); | 78 | static void iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr); |
79 | #ifdef CONFIG_PCI | ||
77 | extern void iSeries_pci_final_fixup(void); | 80 | extern void iSeries_pci_final_fixup(void); |
81 | #else | ||
82 | static void iSeries_pci_final_fixup(void) { } | ||
83 | #endif | ||
78 | 84 | ||
79 | /* Global Variables */ | 85 | /* Global Variables */ |
80 | static unsigned long procFreqHz; | 86 | static unsigned long procFreqHz; |
@@ -874,6 +880,10 @@ static int set_spread_lpevents(char *str) | |||
874 | } | 880 | } |
875 | __setup("spread_lpevents=", set_spread_lpevents); | 881 | __setup("spread_lpevents=", set_spread_lpevents); |
876 | 882 | ||
883 | #ifndef CONFIG_PCI | ||
884 | void __init iSeries_init_IRQ(void) { } | ||
885 | #endif | ||
886 | |||
877 | void __init iSeries_early_setup(void) | 887 | void __init iSeries_early_setup(void) |
878 | { | 888 | { |
879 | iSeries_fixup_klimit(); | 889 | iSeries_fixup_klimit(); |
diff --git a/arch/ppc64/kernel/iSeries_smp.c b/arch/ppc64/kernel/iSeries_smp.c index ba1f084d5462..f74386e31638 100644 --- a/arch/ppc64/kernel/iSeries_smp.c +++ b/arch/ppc64/kernel/iSeries_smp.c | |||
@@ -38,9 +38,7 @@ | |||
38 | #include <asm/io.h> | 38 | #include <asm/io.h> |
39 | #include <asm/smp.h> | 39 | #include <asm/smp.h> |
40 | #include <asm/paca.h> | 40 | #include <asm/paca.h> |
41 | #include <asm/iSeries/LparData.h> | ||
42 | #include <asm/iSeries/HvCall.h> | 41 | #include <asm/iSeries/HvCall.h> |
43 | #include <asm/iSeries/HvCallCfg.h> | ||
44 | #include <asm/time.h> | 42 | #include <asm/time.h> |
45 | #include <asm/ppcdebug.h> | 43 | #include <asm/ppcdebug.h> |
46 | #include <asm/machdep.h> | 44 | #include <asm/machdep.h> |
diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c index f24ce2b87200..bdf13b4dc1c8 100644 --- a/arch/ppc64/kernel/idle.c +++ b/arch/ppc64/kernel/idle.c | |||
@@ -42,6 +42,11 @@ static int (*idle_loop)(void); | |||
42 | static unsigned long maxYieldTime = 0; | 42 | static unsigned long maxYieldTime = 0; |
43 | static unsigned long minYieldTime = 0xffffffffffffffffUL; | 43 | static unsigned long minYieldTime = 0xffffffffffffffffUL; |
44 | 44 | ||
45 | static inline void process_iSeries_events(void) | ||
46 | { | ||
47 | asm volatile ("li 0,0x5555; sc" : : : "r0", "r3"); | ||
48 | } | ||
49 | |||
45 | static void yield_shared_processor(void) | 50 | static void yield_shared_processor(void) |
46 | { | 51 | { |
47 | unsigned long tb; | 52 | unsigned long tb; |
@@ -292,7 +297,7 @@ static int native_idle(void) | |||
292 | if (need_resched()) | 297 | if (need_resched()) |
293 | schedule(); | 298 | schedule(); |
294 | 299 | ||
295 | if (cpu_is_offline(_smp_processor_id()) && | 300 | if (cpu_is_offline(raw_smp_processor_id()) && |
296 | system_state == SYSTEM_RUNNING) | 301 | system_state == SYSTEM_RUNNING) |
297 | cpu_die(); | 302 | cpu_die(); |
298 | } | 303 | } |
diff --git a/arch/ppc64/kernel/iommu.c b/arch/ppc64/kernel/iommu.c index 344164681d2c..8316426ccaf6 100644 --- a/arch/ppc64/kernel/iommu.c +++ b/arch/ppc64/kernel/iommu.c | |||
@@ -423,6 +423,9 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl) | |||
423 | tbl->it_largehint = tbl->it_halfpoint; | 423 | tbl->it_largehint = tbl->it_halfpoint; |
424 | spin_lock_init(&tbl->it_lock); | 424 | spin_lock_init(&tbl->it_lock); |
425 | 425 | ||
426 | /* Clear the hardware table in case firmware left allocations in it */ | ||
427 | ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size); | ||
428 | |||
426 | if (!welcomed) { | 429 | if (!welcomed) { |
427 | printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n", | 430 | printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n", |
428 | novmerge ? "disabled" : "enabled"); | 431 | novmerge ? "disabled" : "enabled"); |
diff --git a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c index 4fd7f203c1e3..d860467b8f09 100644 --- a/arch/ppc64/kernel/irq.c +++ b/arch/ppc64/kernel/irq.c | |||
@@ -52,7 +52,7 @@ | |||
52 | #include <asm/cache.h> | 52 | #include <asm/cache.h> |
53 | #include <asm/prom.h> | 53 | #include <asm/prom.h> |
54 | #include <asm/ptrace.h> | 54 | #include <asm/ptrace.h> |
55 | #include <asm/iSeries/LparData.h> | 55 | #include <asm/iSeries/ItLpQueue.h> |
56 | #include <asm/machdep.h> | 56 | #include <asm/machdep.h> |
57 | #include <asm/paca.h> | 57 | #include <asm/paca.h> |
58 | 58 | ||
diff --git a/arch/ppc64/kernel/lparcfg.c b/arch/ppc64/kernel/lparcfg.c index a8fd32df848b..387923fcf9b0 100644 --- a/arch/ppc64/kernel/lparcfg.c +++ b/arch/ppc64/kernel/lparcfg.c | |||
@@ -28,12 +28,12 @@ | |||
28 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
29 | #include <asm/iSeries/HvLpConfig.h> | 29 | #include <asm/iSeries/HvLpConfig.h> |
30 | #include <asm/lppaca.h> | 30 | #include <asm/lppaca.h> |
31 | #include <asm/iSeries/LparData.h> | ||
32 | #include <asm/hvcall.h> | 31 | #include <asm/hvcall.h> |
33 | #include <asm/cputable.h> | 32 | #include <asm/cputable.h> |
34 | #include <asm/rtas.h> | 33 | #include <asm/rtas.h> |
35 | #include <asm/system.h> | 34 | #include <asm/system.h> |
36 | #include <asm/time.h> | 35 | #include <asm/time.h> |
36 | #include <asm/iSeries/ItExtVpdPanel.h> | ||
37 | 37 | ||
38 | #define MODULE_VERS "1.6" | 38 | #define MODULE_VERS "1.6" |
39 | #define MODULE_NAME "lparcfg" | 39 | #define MODULE_NAME "lparcfg" |
diff --git a/arch/ppc64/kernel/mf.c b/arch/ppc64/kernel/mf.c index 5aca7e8005a8..d98bebf7042f 100644 --- a/arch/ppc64/kernel/mf.c +++ b/arch/ppc64/kernel/mf.c | |||
@@ -40,7 +40,6 @@ | |||
40 | #include <asm/iSeries/vio.h> | 40 | #include <asm/iSeries/vio.h> |
41 | #include <asm/iSeries/mf.h> | 41 | #include <asm/iSeries/mf.h> |
42 | #include <asm/iSeries/HvLpConfig.h> | 42 | #include <asm/iSeries/HvLpConfig.h> |
43 | #include <asm/iSeries/ItSpCommArea.h> | ||
44 | #include <asm/iSeries/ItLpQueue.h> | 43 | #include <asm/iSeries/ItLpQueue.h> |
45 | 44 | ||
46 | /* | 45 | /* |
diff --git a/arch/ppc64/kernel/of_device.c b/arch/ppc64/kernel/of_device.c index f4c825a69fa0..66bd5ab7c25a 100644 --- a/arch/ppc64/kernel/of_device.c +++ b/arch/ppc64/kernel/of_device.c | |||
@@ -161,7 +161,7 @@ void of_unregister_driver(struct of_platform_driver *drv) | |||
161 | } | 161 | } |
162 | 162 | ||
163 | 163 | ||
164 | static ssize_t dev_show_devspec(struct device *dev, char *buf) | 164 | static ssize_t dev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf) |
165 | { | 165 | { |
166 | struct of_device *ofdev; | 166 | struct of_device *ofdev; |
167 | 167 | ||
diff --git a/arch/ppc64/kernel/pSeries_smp.c b/arch/ppc64/kernel/pSeries_smp.c index fbad349ec58c..4203bd020c82 100644 --- a/arch/ppc64/kernel/pSeries_smp.c +++ b/arch/ppc64/kernel/pSeries_smp.c | |||
@@ -375,7 +375,7 @@ static int smp_pSeries_cpu_bootable(unsigned int nr) | |||
375 | * cpus are assumed to be secondary threads. | 375 | * cpus are assumed to be secondary threads. |
376 | */ | 376 | */ |
377 | if (system_state < SYSTEM_RUNNING && | 377 | if (system_state < SYSTEM_RUNNING && |
378 | cur_cpu_spec->cpu_features & CPU_FTR_SMT && | 378 | cpu_has_feature(CPU_FTR_SMT) && |
379 | !smt_enabled_at_boot && nr % 2 != 0) | 379 | !smt_enabled_at_boot && nr % 2 != 0) |
380 | return 0; | 380 | return 0; |
381 | 381 | ||
@@ -419,8 +419,8 @@ void __init smp_init_pSeries(void) | |||
419 | #endif | 419 | #endif |
420 | 420 | ||
421 | /* Mark threads which are still spinning in hold loops. */ | 421 | /* Mark threads which are still spinning in hold loops. */ |
422 | if (cur_cpu_spec->cpu_features & CPU_FTR_SMT) | 422 | if (cpu_has_feature(CPU_FTR_SMT)) { |
423 | for_each_present_cpu(i) { | 423 | for_each_present_cpu(i) { |
424 | if (i % 2 == 0) | 424 | if (i % 2 == 0) |
425 | /* | 425 | /* |
426 | * Even-numbered logical cpus correspond to | 426 | * Even-numbered logical cpus correspond to |
@@ -428,8 +428,9 @@ void __init smp_init_pSeries(void) | |||
428 | */ | 428 | */ |
429 | cpu_set(i, of_spin_map); | 429 | cpu_set(i, of_spin_map); |
430 | } | 430 | } |
431 | else | 431 | } else { |
432 | of_spin_map = cpu_present_map; | 432 | of_spin_map = cpu_present_map; |
433 | } | ||
433 | 434 | ||
434 | cpu_clear(boot_cpuid, of_spin_map); | 435 | cpu_clear(boot_cpuid, of_spin_map); |
435 | 436 | ||
diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c index d786d4b6af0b..2bf0513f3eca 100644 --- a/arch/ppc64/kernel/pci.c +++ b/arch/ppc64/kernel/pci.c | |||
@@ -507,7 +507,7 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | |||
507 | } | 507 | } |
508 | 508 | ||
509 | #ifdef CONFIG_PPC_MULTIPLATFORM | 509 | #ifdef CONFIG_PPC_MULTIPLATFORM |
510 | static ssize_t pci_show_devspec(struct device *dev, char *buf) | 510 | static ssize_t pci_show_devspec(struct device *dev, struct device_attribute *attr, char *buf) |
511 | { | 511 | { |
512 | struct pci_dev *pdev; | 512 | struct pci_dev *pdev; |
513 | struct device_node *np; | 513 | struct device_node *np; |
diff --git a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c index cdfecbeb331f..aba89554d89d 100644 --- a/arch/ppc64/kernel/process.c +++ b/arch/ppc64/kernel/process.c | |||
@@ -58,14 +58,6 @@ struct task_struct *last_task_used_math = NULL; | |||
58 | struct task_struct *last_task_used_altivec = NULL; | 58 | struct task_struct *last_task_used_altivec = NULL; |
59 | #endif | 59 | #endif |
60 | 60 | ||
61 | struct mm_struct ioremap_mm = { | ||
62 | .pgd = ioremap_dir, | ||
63 | .mm_users = ATOMIC_INIT(2), | ||
64 | .mm_count = ATOMIC_INIT(1), | ||
65 | .cpu_vm_mask = CPU_MASK_ALL, | ||
66 | .page_table_lock = SPIN_LOCK_UNLOCKED, | ||
67 | }; | ||
68 | |||
69 | /* | 61 | /* |
70 | * Make sure the floating-point register state in the | 62 | * Make sure the floating-point register state in the |
71 | * the thread_struct is up to date for task tsk. | 63 | * the thread_struct is up to date for task tsk. |
diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c index eb6538b58008..47727a6f7346 100644 --- a/arch/ppc64/kernel/prom.c +++ b/arch/ppc64/kernel/prom.c | |||
@@ -884,6 +884,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node, | |||
884 | { | 884 | { |
885 | char *type = get_flat_dt_prop(node, "device_type", NULL); | 885 | char *type = get_flat_dt_prop(node, "device_type", NULL); |
886 | u32 *prop; | 886 | u32 *prop; |
887 | unsigned long size; | ||
887 | 888 | ||
888 | /* We are scanning "cpu" nodes only */ | 889 | /* We are scanning "cpu" nodes only */ |
889 | if (type == NULL || strcmp(type, "cpu") != 0) | 890 | if (type == NULL || strcmp(type, "cpu") != 0) |
@@ -929,6 +930,17 @@ static int __init early_init_dt_scan_cpus(unsigned long node, | |||
929 | cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC; | 930 | cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC; |
930 | } | 931 | } |
931 | 932 | ||
933 | /* | ||
934 | * Check for an SMT capable CPU and set the CPU feature. We do | ||
935 | * this by looking at the size of the ibm,ppc-interrupt-server#s | ||
936 | * property | ||
937 | */ | ||
938 | prop = (u32 *)get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s", | ||
939 | &size); | ||
940 | cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT; | ||
941 | if (prop && ((size / sizeof(u32)) > 1)) | ||
942 | cur_cpu_spec->cpu_features |= CPU_FTR_SMT; | ||
943 | |||
932 | return 0; | 944 | return 0; |
933 | } | 945 | } |
934 | 946 | ||
diff --git a/arch/ppc64/kernel/ras.c b/arch/ppc64/kernel/ras.c index 1c4c796b212b..3c00f7bfc1b5 100644 --- a/arch/ppc64/kernel/ras.c +++ b/arch/ppc64/kernel/ras.c | |||
@@ -47,7 +47,6 @@ | |||
47 | #include <asm/cache.h> | 47 | #include <asm/cache.h> |
48 | #include <asm/prom.h> | 48 | #include <asm/prom.h> |
49 | #include <asm/ptrace.h> | 49 | #include <asm/ptrace.h> |
50 | #include <asm/iSeries/LparData.h> | ||
51 | #include <asm/machdep.h> | 50 | #include <asm/machdep.h> |
52 | #include <asm/rtas.h> | 51 | #include <asm/rtas.h> |
53 | #include <asm/ppcdebug.h> | 52 | #include <asm/ppcdebug.h> |
diff --git a/arch/ppc64/kernel/rtasd.c b/arch/ppc64/kernel/rtasd.c index ff65dc33320e..b0c3b829fe47 100644 --- a/arch/ppc64/kernel/rtasd.c +++ b/arch/ppc64/kernel/rtasd.c | |||
@@ -440,7 +440,7 @@ static int rtasd(void *unused) | |||
440 | goto error; | 440 | goto error; |
441 | } | 441 | } |
442 | 442 | ||
443 | printk(KERN_ERR "RTAS daemon started\n"); | 443 | printk(KERN_INFO "RTAS daemon started\n"); |
444 | 444 | ||
445 | DEBUG("will sleep for %d jiffies\n", (HZ*60/rtas_event_scan_rate) / 2); | 445 | DEBUG("will sleep for %d jiffies\n", (HZ*60/rtas_event_scan_rate) / 2); |
446 | 446 | ||
@@ -485,7 +485,7 @@ static int __init rtas_init(void) | |||
485 | /* No RTAS, only warn if we are on a pSeries box */ | 485 | /* No RTAS, only warn if we are on a pSeries box */ |
486 | if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) { | 486 | if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) { |
487 | if (systemcfg->platform & PLATFORM_PSERIES) | 487 | if (systemcfg->platform & PLATFORM_PSERIES) |
488 | printk(KERN_ERR "rtasd: no event-scan on system\n"); | 488 | printk(KERN_INFO "rtasd: no event-scan on system\n"); |
489 | return 1; | 489 | return 1; |
490 | } | 490 | } |
491 | 491 | ||
diff --git a/arch/ppc64/kernel/rtc.c b/arch/ppc64/kernel/rtc.c index 67989055a9fe..de02aedbe080 100644 --- a/arch/ppc64/kernel/rtc.c +++ b/arch/ppc64/kernel/rtc.c | |||
@@ -42,10 +42,8 @@ | |||
42 | #include <asm/time.h> | 42 | #include <asm/time.h> |
43 | #include <asm/rtas.h> | 43 | #include <asm/rtas.h> |
44 | 44 | ||
45 | #include <asm/iSeries/LparData.h> | ||
46 | #include <asm/iSeries/mf.h> | 45 | #include <asm/iSeries/mf.h> |
47 | #include <asm/machdep.h> | 46 | #include <asm/machdep.h> |
48 | #include <asm/iSeries/ItSpCommArea.h> | ||
49 | 47 | ||
50 | extern int piranha_simulator; | 48 | extern int piranha_simulator; |
51 | 49 | ||
diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c index dce198d39328..8e439a817642 100644 --- a/arch/ppc64/kernel/setup.c +++ b/arch/ppc64/kernel/setup.c | |||
@@ -41,7 +41,6 @@ | |||
41 | #include <asm/smp.h> | 41 | #include <asm/smp.h> |
42 | #include <asm/elf.h> | 42 | #include <asm/elf.h> |
43 | #include <asm/machdep.h> | 43 | #include <asm/machdep.h> |
44 | #include <asm/iSeries/LparData.h> | ||
45 | #include <asm/paca.h> | 44 | #include <asm/paca.h> |
46 | #include <asm/ppcdebug.h> | 45 | #include <asm/ppcdebug.h> |
47 | #include <asm/time.h> | 46 | #include <asm/time.h> |
@@ -57,6 +56,8 @@ | |||
57 | #include <asm/cache.h> | 56 | #include <asm/cache.h> |
58 | #include <asm/page.h> | 57 | #include <asm/page.h> |
59 | #include <asm/mmu.h> | 58 | #include <asm/mmu.h> |
59 | #include <asm/lmb.h> | ||
60 | #include <asm/iSeries/ItLpNaca.h> | ||
60 | 61 | ||
61 | #ifdef DEBUG | 62 | #ifdef DEBUG |
62 | #define DBG(fmt...) udbg_printf(fmt) | 63 | #define DBG(fmt...) udbg_printf(fmt) |
diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c index 9c8e317c598d..118436e8085a 100644 --- a/arch/ppc64/kernel/sys_ppc32.c +++ b/arch/ppc64/kernel/sys_ppc32.c | |||
@@ -741,6 +741,7 @@ asmlinkage int sys32_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubu | |||
741 | 741 | ||
742 | asmlinkage int sys32_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn) | 742 | asmlinkage int sys32_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn) |
743 | { | 743 | { |
744 | #ifdef CONFIG_PCI | ||
744 | struct pci_controller* hose; | 745 | struct pci_controller* hose; |
745 | struct list_head *ln; | 746 | struct list_head *ln; |
746 | struct pci_bus *bus = NULL; | 747 | struct pci_bus *bus = NULL; |
@@ -786,7 +787,7 @@ asmlinkage int sys32_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn) | |||
786 | case IOBASE_ISA_MEM: | 787 | case IOBASE_ISA_MEM: |
787 | return -EINVAL; | 788 | return -EINVAL; |
788 | } | 789 | } |
789 | 790 | #endif /* CONFIG_PCI */ | |
790 | return -EOPNOTSUPP; | 791 | return -EOPNOTSUPP; |
791 | } | 792 | } |
792 | 793 | ||
diff --git a/arch/ppc64/kernel/vio.c b/arch/ppc64/kernel/vio.c index cdd830cb2768..0c0ba71ac0e8 100644 --- a/arch/ppc64/kernel/vio.c +++ b/arch/ppc64/kernel/vio.c | |||
@@ -41,20 +41,25 @@ static const struct vio_device_id *vio_match_device( | |||
41 | static struct iommu_table *vio_build_iommu_table(struct vio_dev *); | 41 | static struct iommu_table *vio_build_iommu_table(struct vio_dev *); |
42 | static int vio_num_address_cells; | 42 | static int vio_num_address_cells; |
43 | #endif | 43 | #endif |
44 | static struct vio_dev *vio_bus_device; /* fake "parent" device */ | ||
45 | |||
46 | #ifdef CONFIG_PPC_ISERIES | 44 | #ifdef CONFIG_PPC_ISERIES |
47 | static struct vio_dev *__init vio_register_device_iseries(char *type, | ||
48 | uint32_t unit_num); | ||
49 | |||
50 | static struct iommu_table veth_iommu_table; | 45 | static struct iommu_table veth_iommu_table; |
51 | static struct iommu_table vio_iommu_table; | 46 | static struct iommu_table vio_iommu_table; |
52 | 47 | #endif | |
53 | static struct vio_dev _vio_dev = { | 48 | static struct vio_dev vio_bus_device = { /* fake "parent" device */ |
49 | .name = vio_bus_device.dev.bus_id, | ||
50 | .type = "", | ||
51 | #ifdef CONFIG_PPC_ISERIES | ||
54 | .iommu_table = &vio_iommu_table, | 52 | .iommu_table = &vio_iommu_table, |
55 | .dev.bus = &vio_bus_type | 53 | #endif |
54 | .dev.bus_id = "vio", | ||
55 | .dev.bus = &vio_bus_type, | ||
56 | }; | 56 | }; |
57 | struct device *iSeries_vio_dev = &_vio_dev.dev; | 57 | |
58 | #ifdef CONFIG_PPC_ISERIES | ||
59 | static struct vio_dev *__init vio_register_device_iseries(char *type, | ||
60 | uint32_t unit_num); | ||
61 | |||
62 | struct device *iSeries_vio_dev = &vio_bus_device.dev; | ||
58 | EXPORT_SYMBOL(iSeries_vio_dev); | 63 | EXPORT_SYMBOL(iSeries_vio_dev); |
59 | 64 | ||
60 | #define device_is_compatible(a, b) 1 | 65 | #define device_is_compatible(a, b) 1 |
@@ -260,18 +265,10 @@ static int __init vio_bus_init(void) | |||
260 | } | 265 | } |
261 | 266 | ||
262 | /* the fake parent of all vio devices, just to give us a nice directory */ | 267 | /* the fake parent of all vio devices, just to give us a nice directory */ |
263 | vio_bus_device = kmalloc(sizeof(struct vio_dev), GFP_KERNEL); | 268 | err = device_register(&vio_bus_device.dev); |
264 | if (!vio_bus_device) { | ||
265 | return 1; | ||
266 | } | ||
267 | memset(vio_bus_device, 0, sizeof(struct vio_dev)); | ||
268 | strcpy(vio_bus_device->dev.bus_id, "vio"); | ||
269 | |||
270 | err = device_register(&vio_bus_device->dev); | ||
271 | if (err) { | 269 | if (err) { |
272 | printk(KERN_WARNING "%s: device_register returned %i\n", __FUNCTION__, | 270 | printk(KERN_WARNING "%s: device_register returned %i\n", __FUNCTION__, |
273 | err); | 271 | err); |
274 | kfree(vio_bus_device); | ||
275 | return err; | 272 | return err; |
276 | } | 273 | } |
277 | 274 | ||
@@ -300,7 +297,7 @@ static void __devinit vio_dev_release(struct device *dev) | |||
300 | } | 297 | } |
301 | 298 | ||
302 | #ifdef CONFIG_PPC_PSERIES | 299 | #ifdef CONFIG_PPC_PSERIES |
303 | static ssize_t viodev_show_devspec(struct device *dev, char *buf) | 300 | static ssize_t viodev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf) |
304 | { | 301 | { |
305 | struct device_node *of_node = dev->platform_data; | 302 | struct device_node *of_node = dev->platform_data; |
306 | 303 | ||
@@ -309,7 +306,7 @@ static ssize_t viodev_show_devspec(struct device *dev, char *buf) | |||
309 | DEVICE_ATTR(devspec, S_IRUSR | S_IRGRP | S_IROTH, viodev_show_devspec, NULL); | 306 | DEVICE_ATTR(devspec, S_IRUSR | S_IRGRP | S_IROTH, viodev_show_devspec, NULL); |
310 | #endif | 307 | #endif |
311 | 308 | ||
312 | static ssize_t viodev_show_name(struct device *dev, char *buf) | 309 | static ssize_t viodev_show_name(struct device *dev, struct device_attribute *attr, char *buf) |
313 | { | 310 | { |
314 | return sprintf(buf, "%s\n", to_vio_dev(dev)->name); | 311 | return sprintf(buf, "%s\n", to_vio_dev(dev)->name); |
315 | } | 312 | } |
@@ -326,7 +323,7 @@ static struct vio_dev * __devinit vio_register_device_common( | |||
326 | viodev->unit_address = unit_address; | 323 | viodev->unit_address = unit_address; |
327 | viodev->iommu_table = iommu_table; | 324 | viodev->iommu_table = iommu_table; |
328 | /* init generic 'struct device' fields: */ | 325 | /* init generic 'struct device' fields: */ |
329 | viodev->dev.parent = &vio_bus_device->dev; | 326 | viodev->dev.parent = &vio_bus_device.dev; |
330 | viodev->dev.bus = &vio_bus_type; | 327 | viodev->dev.bus = &vio_bus_type; |
331 | viodev->dev.release = vio_dev_release; | 328 | viodev->dev.release = vio_dev_release; |
332 | 329 | ||
@@ -636,5 +633,3 @@ struct bus_type vio_bus_type = { | |||
636 | .name = "vio", | 633 | .name = "vio", |
637 | .match = vio_bus_match, | 634 | .match = vio_bus_match, |
638 | }; | 635 | }; |
639 | |||
640 | EXPORT_SYMBOL(vio_bus_type); | ||
diff --git a/arch/ppc64/kernel/viopath.c b/arch/ppc64/kernel/viopath.c index 2ed8ee075680..2a6c4f01c45e 100644 --- a/arch/ppc64/kernel/viopath.c +++ b/arch/ppc64/kernel/viopath.c | |||
@@ -43,12 +43,10 @@ | |||
43 | #include <asm/system.h> | 43 | #include <asm/system.h> |
44 | #include <asm/uaccess.h> | 44 | #include <asm/uaccess.h> |
45 | #include <asm/iSeries/HvTypes.h> | 45 | #include <asm/iSeries/HvTypes.h> |
46 | #include <asm/iSeries/LparData.h> | 46 | #include <asm/iSeries/ItExtVpdPanel.h> |
47 | #include <asm/iSeries/HvLpEvent.h> | 47 | #include <asm/iSeries/HvLpEvent.h> |
48 | #include <asm/iSeries/HvLpConfig.h> | 48 | #include <asm/iSeries/HvLpConfig.h> |
49 | #include <asm/iSeries/HvCallCfg.h> | ||
50 | #include <asm/iSeries/mf.h> | 49 | #include <asm/iSeries/mf.h> |
51 | #include <asm/iSeries/iSeries_proc.h> | ||
52 | #include <asm/iSeries/vio.h> | 50 | #include <asm/iSeries/vio.h> |
53 | 51 | ||
54 | /* Status of the path to each other partition in the system. | 52 | /* Status of the path to each other partition in the system. |
@@ -365,7 +363,7 @@ void vio_set_hostlp(void) | |||
365 | * while we're active | 363 | * while we're active |
366 | */ | 364 | */ |
367 | viopath_ourLp = HvLpConfig_getLpIndex(); | 365 | viopath_ourLp = HvLpConfig_getLpIndex(); |
368 | viopath_hostLp = HvCallCfg_getHostingLpIndex(viopath_ourLp); | 366 | viopath_hostLp = HvLpConfig_getHostingLpIndex(viopath_ourLp); |
369 | 367 | ||
370 | if (viopath_hostLp != HvLpIndexInvalid) | 368 | if (viopath_hostLp != HvLpIndexInvalid) |
371 | vio_setHandler(viomajorsubtype_config, handleConfig); | 369 | vio_setHandler(viomajorsubtype_config, handleConfig); |
@@ -487,7 +485,7 @@ int viopath_open(HvLpIndex remoteLp, int subtype, int numReq) | |||
487 | unsigned long flags; | 485 | unsigned long flags; |
488 | int tempNumAllocated; | 486 | int tempNumAllocated; |
489 | 487 | ||
490 | if ((remoteLp >= HvMaxArchitectedLps) || (remoteLp == HvLpIndexInvalid)) | 488 | if ((remoteLp >= HVMAXARCHITECTEDLPS) || (remoteLp == HvLpIndexInvalid)) |
491 | return -EINVAL; | 489 | return -EINVAL; |
492 | 490 | ||
493 | subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT; | 491 | subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT; |
@@ -558,7 +556,7 @@ int viopath_close(HvLpIndex remoteLp, int subtype, int numReq) | |||
558 | int numOpen; | 556 | int numOpen; |
559 | struct alloc_parms parms; | 557 | struct alloc_parms parms; |
560 | 558 | ||
561 | if ((remoteLp >= HvMaxArchitectedLps) || (remoteLp == HvLpIndexInvalid)) | 559 | if ((remoteLp >= HVMAXARCHITECTEDLPS) || (remoteLp == HvLpIndexInvalid)) |
562 | return -EINVAL; | 560 | return -EINVAL; |
563 | 561 | ||
564 | subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT; | 562 | subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT; |
diff --git a/arch/ppc64/lib/Makefile b/arch/ppc64/lib/Makefile index bf7b5bbfc04e..76fbfa9f706f 100644 --- a/arch/ppc64/lib/Makefile +++ b/arch/ppc64/lib/Makefile | |||
@@ -12,7 +12,7 @@ lib-$(CONFIG_SMP) += locks.o | |||
12 | 12 | ||
13 | # e2a provides EBCDIC to ASCII conversions. | 13 | # e2a provides EBCDIC to ASCII conversions. |
14 | ifdef CONFIG_PPC_ISERIES | 14 | ifdef CONFIG_PPC_ISERIES |
15 | obj-$(CONFIG_PCI) += e2a.o | 15 | obj-y += e2a.o |
16 | endif | 16 | endif |
17 | 17 | ||
18 | lib-$(CONFIG_DEBUG_KERNEL) += sstep.o | 18 | lib-$(CONFIG_DEBUG_KERNEL) += sstep.o |
diff --git a/arch/ppc64/mm/hash_utils.c b/arch/ppc64/mm/hash_utils.c index 0a0f97008d02..1647b1c6f28e 100644 --- a/arch/ppc64/mm/hash_utils.c +++ b/arch/ppc64/mm/hash_utils.c | |||
@@ -195,7 +195,7 @@ void __init htab_initialize(void) | |||
195 | memset((void *)table, 0, htab_size_bytes); | 195 | memset((void *)table, 0, htab_size_bytes); |
196 | } | 196 | } |
197 | 197 | ||
198 | mode_rw = _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX; | 198 | mode_rw = _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX; |
199 | 199 | ||
200 | /* On U3 based machines, we need to reserve the DART area and | 200 | /* On U3 based machines, we need to reserve the DART area and |
201 | * _NOT_ map it to avoid cache paradoxes as it's remapped non | 201 | * _NOT_ map it to avoid cache paradoxes as it's remapped non |
@@ -310,10 +310,6 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) | |||
310 | 310 | ||
311 | vsid = get_vsid(mm->context.id, ea); | 311 | vsid = get_vsid(mm->context.id, ea); |
312 | break; | 312 | break; |
313 | case IO_REGION_ID: | ||
314 | mm = &ioremap_mm; | ||
315 | vsid = get_kernel_vsid(ea); | ||
316 | break; | ||
317 | case VMALLOC_REGION_ID: | 313 | case VMALLOC_REGION_ID: |
318 | mm = &init_mm; | 314 | mm = &init_mm; |
319 | vsid = get_kernel_vsid(ea); | 315 | vsid = get_kernel_vsid(ea); |
diff --git a/arch/ppc64/mm/hugetlbpage.c b/arch/ppc64/mm/hugetlbpage.c index d3bf86a5c1ad..fdcfe97c75c1 100644 --- a/arch/ppc64/mm/hugetlbpage.c +++ b/arch/ppc64/mm/hugetlbpage.c | |||
@@ -121,7 +121,7 @@ static pte_t *hugepte_alloc(struct mm_struct *mm, pud_t *dir, unsigned long addr | |||
121 | return hugepte_offset(dir, addr); | 121 | return hugepte_offset(dir, addr); |
122 | } | 122 | } |
123 | 123 | ||
124 | static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) | 124 | pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) |
125 | { | 125 | { |
126 | pud_t *pud; | 126 | pud_t *pud; |
127 | 127 | ||
@@ -134,7 +134,7 @@ static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) | |||
134 | return hugepte_offset(pud, addr); | 134 | return hugepte_offset(pud, addr); |
135 | } | 135 | } |
136 | 136 | ||
137 | static pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) | 137 | pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) |
138 | { | 138 | { |
139 | pud_t *pud; | 139 | pud_t *pud; |
140 | 140 | ||
@@ -147,25 +147,6 @@ static pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) | |||
147 | return hugepte_alloc(mm, pud, addr); | 147 | return hugepte_alloc(mm, pud, addr); |
148 | } | 148 | } |
149 | 149 | ||
150 | static void set_huge_pte(struct mm_struct *mm, struct vm_area_struct *vma, | ||
151 | unsigned long addr, struct page *page, | ||
152 | pte_t *ptep, int write_access) | ||
153 | { | ||
154 | pte_t entry; | ||
155 | |||
156 | add_mm_counter(mm, rss, HPAGE_SIZE / PAGE_SIZE); | ||
157 | if (write_access) { | ||
158 | entry = | ||
159 | pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot))); | ||
160 | } else { | ||
161 | entry = pte_wrprotect(mk_pte(page, vma->vm_page_prot)); | ||
162 | } | ||
163 | entry = pte_mkyoung(entry); | ||
164 | entry = pte_mkhuge(entry); | ||
165 | |||
166 | set_pte_at(mm, addr, ptep, entry); | ||
167 | } | ||
168 | |||
169 | /* | 150 | /* |
170 | * This function checks for proper alignment of input addr and len parameters. | 151 | * This function checks for proper alignment of input addr and len parameters. |
171 | */ | 152 | */ |
@@ -259,80 +240,6 @@ int prepare_hugepage_range(unsigned long addr, unsigned long len) | |||
259 | return -EINVAL; | 240 | return -EINVAL; |
260 | } | 241 | } |
261 | 242 | ||
262 | int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, | ||
263 | struct vm_area_struct *vma) | ||
264 | { | ||
265 | pte_t *src_pte, *dst_pte, entry; | ||
266 | struct page *ptepage; | ||
267 | unsigned long addr = vma->vm_start; | ||
268 | unsigned long end = vma->vm_end; | ||
269 | int err = -ENOMEM; | ||
270 | |||
271 | while (addr < end) { | ||
272 | dst_pte = huge_pte_alloc(dst, addr); | ||
273 | if (!dst_pte) | ||
274 | goto out; | ||
275 | |||
276 | src_pte = huge_pte_offset(src, addr); | ||
277 | entry = *src_pte; | ||
278 | |||
279 | ptepage = pte_page(entry); | ||
280 | get_page(ptepage); | ||
281 | add_mm_counter(dst, rss, HPAGE_SIZE / PAGE_SIZE); | ||
282 | set_pte_at(dst, addr, dst_pte, entry); | ||
283 | |||
284 | addr += HPAGE_SIZE; | ||
285 | } | ||
286 | |||
287 | err = 0; | ||
288 | out: | ||
289 | return err; | ||
290 | } | ||
291 | |||
292 | int | ||
293 | follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma, | ||
294 | struct page **pages, struct vm_area_struct **vmas, | ||
295 | unsigned long *position, int *length, int i) | ||
296 | { | ||
297 | unsigned long vpfn, vaddr = *position; | ||
298 | int remainder = *length; | ||
299 | |||
300 | WARN_ON(!is_vm_hugetlb_page(vma)); | ||
301 | |||
302 | vpfn = vaddr/PAGE_SIZE; | ||
303 | while (vaddr < vma->vm_end && remainder) { | ||
304 | if (pages) { | ||
305 | pte_t *pte; | ||
306 | struct page *page; | ||
307 | |||
308 | pte = huge_pte_offset(mm, vaddr); | ||
309 | |||
310 | /* hugetlb should be locked, and hence, prefaulted */ | ||
311 | WARN_ON(!pte || pte_none(*pte)); | ||
312 | |||
313 | page = &pte_page(*pte)[vpfn % (HPAGE_SIZE/PAGE_SIZE)]; | ||
314 | |||
315 | WARN_ON(!PageCompound(page)); | ||
316 | |||
317 | get_page(page); | ||
318 | pages[i] = page; | ||
319 | } | ||
320 | |||
321 | if (vmas) | ||
322 | vmas[i] = vma; | ||
323 | |||
324 | vaddr += PAGE_SIZE; | ||
325 | ++vpfn; | ||
326 | --remainder; | ||
327 | ++i; | ||
328 | } | ||
329 | |||
330 | *length = remainder; | ||
331 | *position = vaddr; | ||
332 | |||
333 | return i; | ||
334 | } | ||
335 | |||
336 | struct page * | 243 | struct page * |
337 | follow_huge_addr(struct mm_struct *mm, unsigned long address, int write) | 244 | follow_huge_addr(struct mm_struct *mm, unsigned long address, int write) |
338 | { | 245 | { |
@@ -363,89 +270,6 @@ follow_huge_pmd(struct mm_struct *mm, unsigned long address, | |||
363 | return NULL; | 270 | return NULL; |
364 | } | 271 | } |
365 | 272 | ||
366 | void unmap_hugepage_range(struct vm_area_struct *vma, | ||
367 | unsigned long start, unsigned long end) | ||
368 | { | ||
369 | struct mm_struct *mm = vma->vm_mm; | ||
370 | unsigned long addr; | ||
371 | pte_t *ptep; | ||
372 | struct page *page; | ||
373 | |||
374 | WARN_ON(!is_vm_hugetlb_page(vma)); | ||
375 | BUG_ON((start % HPAGE_SIZE) != 0); | ||
376 | BUG_ON((end % HPAGE_SIZE) != 0); | ||
377 | |||
378 | for (addr = start; addr < end; addr += HPAGE_SIZE) { | ||
379 | pte_t pte; | ||
380 | |||
381 | ptep = huge_pte_offset(mm, addr); | ||
382 | if (!ptep || pte_none(*ptep)) | ||
383 | continue; | ||
384 | |||
385 | pte = *ptep; | ||
386 | page = pte_page(pte); | ||
387 | pte_clear(mm, addr, ptep); | ||
388 | |||
389 | put_page(page); | ||
390 | } | ||
391 | add_mm_counter(mm, rss, -((end - start) >> PAGE_SHIFT)); | ||
392 | flush_tlb_pending(); | ||
393 | } | ||
394 | |||
395 | int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma) | ||
396 | { | ||
397 | struct mm_struct *mm = current->mm; | ||
398 | unsigned long addr; | ||
399 | int ret = 0; | ||
400 | |||
401 | WARN_ON(!is_vm_hugetlb_page(vma)); | ||
402 | BUG_ON((vma->vm_start % HPAGE_SIZE) != 0); | ||
403 | BUG_ON((vma->vm_end % HPAGE_SIZE) != 0); | ||
404 | |||
405 | spin_lock(&mm->page_table_lock); | ||
406 | for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) { | ||
407 | unsigned long idx; | ||
408 | pte_t *pte = huge_pte_alloc(mm, addr); | ||
409 | struct page *page; | ||
410 | |||
411 | if (!pte) { | ||
412 | ret = -ENOMEM; | ||
413 | goto out; | ||
414 | } | ||
415 | if (! pte_none(*pte)) | ||
416 | continue; | ||
417 | |||
418 | idx = ((addr - vma->vm_start) >> HPAGE_SHIFT) | ||
419 | + (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT)); | ||
420 | page = find_get_page(mapping, idx); | ||
421 | if (!page) { | ||
422 | /* charge the fs quota first */ | ||
423 | if (hugetlb_get_quota(mapping)) { | ||
424 | ret = -ENOMEM; | ||
425 | goto out; | ||
426 | } | ||
427 | page = alloc_huge_page(); | ||
428 | if (!page) { | ||
429 | hugetlb_put_quota(mapping); | ||
430 | ret = -ENOMEM; | ||
431 | goto out; | ||
432 | } | ||
433 | ret = add_to_page_cache(page, mapping, idx, GFP_ATOMIC); | ||
434 | if (! ret) { | ||
435 | unlock_page(page); | ||
436 | } else { | ||
437 | hugetlb_put_quota(mapping); | ||
438 | free_huge_page(page); | ||
439 | goto out; | ||
440 | } | ||
441 | } | ||
442 | set_huge_pte(mm, vma, addr, page, pte, vma->vm_flags & VM_WRITE); | ||
443 | } | ||
444 | out: | ||
445 | spin_unlock(&mm->page_table_lock); | ||
446 | return ret; | ||
447 | } | ||
448 | |||
449 | /* Because we have an exclusive hugepage region which lies within the | 273 | /* Because we have an exclusive hugepage region which lies within the |
450 | * normal user address space, we have to take special measures to make | 274 | * normal user address space, we have to take special measures to make |
451 | * non-huge mmap()s evade the hugepage reserved regions. */ | 275 | * non-huge mmap()s evade the hugepage reserved regions. */ |
@@ -468,7 +292,12 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, | |||
468 | && !is_hugepage_only_range(mm, addr,len)) | 292 | && !is_hugepage_only_range(mm, addr,len)) |
469 | return addr; | 293 | return addr; |
470 | } | 294 | } |
471 | start_addr = addr = mm->free_area_cache; | 295 | if (len > mm->cached_hole_size) { |
296 | start_addr = addr = mm->free_area_cache; | ||
297 | } else { | ||
298 | start_addr = addr = TASK_UNMAPPED_BASE; | ||
299 | mm->cached_hole_size = 0; | ||
300 | } | ||
472 | 301 | ||
473 | full_search: | 302 | full_search: |
474 | vma = find_vma(mm, addr); | 303 | vma = find_vma(mm, addr); |
@@ -492,6 +321,8 @@ full_search: | |||
492 | mm->free_area_cache = addr + len; | 321 | mm->free_area_cache = addr + len; |
493 | return addr; | 322 | return addr; |
494 | } | 323 | } |
324 | if (addr + mm->cached_hole_size < vma->vm_start) | ||
325 | mm->cached_hole_size = vma->vm_start - addr; | ||
495 | addr = vma->vm_end; | 326 | addr = vma->vm_end; |
496 | vma = vma->vm_next; | 327 | vma = vma->vm_next; |
497 | } | 328 | } |
@@ -499,6 +330,7 @@ full_search: | |||
499 | /* Make sure we didn't miss any holes */ | 330 | /* Make sure we didn't miss any holes */ |
500 | if (start_addr != TASK_UNMAPPED_BASE) { | 331 | if (start_addr != TASK_UNMAPPED_BASE) { |
501 | start_addr = addr = TASK_UNMAPPED_BASE; | 332 | start_addr = addr = TASK_UNMAPPED_BASE; |
333 | mm->cached_hole_size = 0; | ||
502 | goto full_search; | 334 | goto full_search; |
503 | } | 335 | } |
504 | return -ENOMEM; | 336 | return -ENOMEM; |
@@ -520,6 +352,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, | |||
520 | struct vm_area_struct *vma, *prev_vma; | 352 | struct vm_area_struct *vma, *prev_vma; |
521 | struct mm_struct *mm = current->mm; | 353 | struct mm_struct *mm = current->mm; |
522 | unsigned long base = mm->mmap_base, addr = addr0; | 354 | unsigned long base = mm->mmap_base, addr = addr0; |
355 | unsigned long largest_hole = mm->cached_hole_size; | ||
523 | int first_time = 1; | 356 | int first_time = 1; |
524 | 357 | ||
525 | /* requested length too big for entire address space */ | 358 | /* requested length too big for entire address space */ |
@@ -540,6 +373,10 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, | |||
540 | return addr; | 373 | return addr; |
541 | } | 374 | } |
542 | 375 | ||
376 | if (len <= largest_hole) { | ||
377 | largest_hole = 0; | ||
378 | mm->free_area_cache = base; | ||
379 | } | ||
543 | try_again: | 380 | try_again: |
544 | /* make sure it can fit in the remaining address space */ | 381 | /* make sure it can fit in the remaining address space */ |
545 | if (mm->free_area_cache < len) | 382 | if (mm->free_area_cache < len) |
@@ -568,13 +405,21 @@ hugepage_recheck: | |||
568 | * vma->vm_start, use it: | 405 | * vma->vm_start, use it: |
569 | */ | 406 | */ |
570 | if (addr+len <= vma->vm_start && | 407 | if (addr+len <= vma->vm_start && |
571 | (!prev_vma || (addr >= prev_vma->vm_end))) | 408 | (!prev_vma || (addr >= prev_vma->vm_end))) { |
572 | /* remember the address as a hint for next time */ | 409 | /* remember the address as a hint for next time */ |
573 | return (mm->free_area_cache = addr); | 410 | mm->cached_hole_size = largest_hole; |
574 | else | 411 | return (mm->free_area_cache = addr); |
412 | } else { | ||
575 | /* pull free_area_cache down to the first hole */ | 413 | /* pull free_area_cache down to the first hole */ |
576 | if (mm->free_area_cache == vma->vm_end) | 414 | if (mm->free_area_cache == vma->vm_end) { |
577 | mm->free_area_cache = vma->vm_start; | 415 | mm->free_area_cache = vma->vm_start; |
416 | mm->cached_hole_size = largest_hole; | ||
417 | } | ||
418 | } | ||
419 | |||
420 | /* remember the largest hole we saw so far */ | ||
421 | if (addr + largest_hole < vma->vm_start) | ||
422 | largest_hole = vma->vm_start - addr; | ||
578 | 423 | ||
579 | /* try just below the current vma->vm_start */ | 424 | /* try just below the current vma->vm_start */ |
580 | addr = vma->vm_start-len; | 425 | addr = vma->vm_start-len; |
@@ -587,6 +432,7 @@ fail: | |||
587 | */ | 432 | */ |
588 | if (first_time) { | 433 | if (first_time) { |
589 | mm->free_area_cache = base; | 434 | mm->free_area_cache = base; |
435 | largest_hole = 0; | ||
590 | first_time = 0; | 436 | first_time = 0; |
591 | goto try_again; | 437 | goto try_again; |
592 | } | 438 | } |
@@ -597,11 +443,13 @@ fail: | |||
597 | * allocations. | 443 | * allocations. |
598 | */ | 444 | */ |
599 | mm->free_area_cache = TASK_UNMAPPED_BASE; | 445 | mm->free_area_cache = TASK_UNMAPPED_BASE; |
446 | mm->cached_hole_size = ~0UL; | ||
600 | addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags); | 447 | addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags); |
601 | /* | 448 | /* |
602 | * Restore the topdown base: | 449 | * Restore the topdown base: |
603 | */ | 450 | */ |
604 | mm->free_area_cache = base; | 451 | mm->free_area_cache = base; |
452 | mm->cached_hole_size = ~0UL; | ||
605 | 453 | ||
606 | return addr; | 454 | return addr; |
607 | } | 455 | } |
diff --git a/arch/ppc64/mm/imalloc.c b/arch/ppc64/mm/imalloc.c index cb8727f3267a..b6e75b891ac0 100644 --- a/arch/ppc64/mm/imalloc.c +++ b/arch/ppc64/mm/imalloc.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <asm/pgtable.h> | 15 | #include <asm/pgtable.h> |
16 | #include <asm/semaphore.h> | 16 | #include <asm/semaphore.h> |
17 | #include <asm/imalloc.h> | 17 | #include <asm/imalloc.h> |
18 | #include <asm/cacheflush.h> | ||
18 | 19 | ||
19 | static DECLARE_MUTEX(imlist_sem); | 20 | static DECLARE_MUTEX(imlist_sem); |
20 | struct vm_struct * imlist = NULL; | 21 | struct vm_struct * imlist = NULL; |
@@ -285,29 +286,32 @@ struct vm_struct * im_get_area(unsigned long v_addr, unsigned long size, | |||
285 | return area; | 286 | return area; |
286 | } | 287 | } |
287 | 288 | ||
288 | unsigned long im_free(void * addr) | 289 | void im_free(void * addr) |
289 | { | 290 | { |
290 | struct vm_struct **p, *tmp; | 291 | struct vm_struct **p, *tmp; |
291 | unsigned long ret_size = 0; | ||
292 | 292 | ||
293 | if (!addr) | 293 | if (!addr) |
294 | return ret_size; | 294 | return; |
295 | if ((PAGE_SIZE-1) & (unsigned long) addr) { | 295 | if ((unsigned long) addr & ~PAGE_MASK) { |
296 | printk(KERN_ERR "Trying to %s bad address (%p)\n", __FUNCTION__, addr); | 296 | printk(KERN_ERR "Trying to %s bad address (%p)\n", __FUNCTION__, addr); |
297 | return ret_size; | 297 | return; |
298 | } | 298 | } |
299 | down(&imlist_sem); | 299 | down(&imlist_sem); |
300 | for (p = &imlist ; (tmp = *p) ; p = &tmp->next) { | 300 | for (p = &imlist ; (tmp = *p) ; p = &tmp->next) { |
301 | if (tmp->addr == addr) { | 301 | if (tmp->addr == addr) { |
302 | ret_size = tmp->size; | ||
303 | *p = tmp->next; | 302 | *p = tmp->next; |
303 | |||
304 | /* XXX: do we need the lock? */ | ||
305 | spin_lock(&init_mm.page_table_lock); | ||
306 | unmap_vm_area(tmp); | ||
307 | spin_unlock(&init_mm.page_table_lock); | ||
308 | |||
304 | kfree(tmp); | 309 | kfree(tmp); |
305 | up(&imlist_sem); | 310 | up(&imlist_sem); |
306 | return ret_size; | 311 | return; |
307 | } | 312 | } |
308 | } | 313 | } |
309 | up(&imlist_sem); | 314 | up(&imlist_sem); |
310 | printk(KERN_ERR "Trying to %s nonexistent area (%p)\n", __FUNCTION__, | 315 | printk(KERN_ERR "Trying to %s nonexistent area (%p)\n", __FUNCTION__, |
311 | addr); | 316 | addr); |
312 | return ret_size; | ||
313 | } | 317 | } |
diff --git a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c index 4b42aff74d73..6fa1e6490b57 100644 --- a/arch/ppc64/mm/init.c +++ b/arch/ppc64/mm/init.c | |||
@@ -73,9 +73,6 @@ static unsigned long phbs_io_bot = PHBS_IO_BASE; | |||
73 | extern pgd_t swapper_pg_dir[]; | 73 | extern pgd_t swapper_pg_dir[]; |
74 | extern struct task_struct *current_set[NR_CPUS]; | 74 | extern struct task_struct *current_set[NR_CPUS]; |
75 | 75 | ||
76 | extern pgd_t ioremap_dir[]; | ||
77 | pgd_t * ioremap_pgd = (pgd_t *)&ioremap_dir; | ||
78 | |||
79 | unsigned long klimit = (unsigned long)_end; | 76 | unsigned long klimit = (unsigned long)_end; |
80 | 77 | ||
81 | unsigned long _SDR1=0; | 78 | unsigned long _SDR1=0; |
@@ -137,69 +134,6 @@ void iounmap(volatile void __iomem *addr) | |||
137 | 134 | ||
138 | #else | 135 | #else |
139 | 136 | ||
140 | static void unmap_im_area_pte(pmd_t *pmd, unsigned long addr, | ||
141 | unsigned long end) | ||
142 | { | ||
143 | pte_t *pte; | ||
144 | |||
145 | pte = pte_offset_kernel(pmd, addr); | ||
146 | do { | ||
147 | pte_t ptent = ptep_get_and_clear(&ioremap_mm, addr, pte); | ||
148 | WARN_ON(!pte_none(ptent) && !pte_present(ptent)); | ||
149 | } while (pte++, addr += PAGE_SIZE, addr != end); | ||
150 | } | ||
151 | |||
152 | static inline void unmap_im_area_pmd(pud_t *pud, unsigned long addr, | ||
153 | unsigned long end) | ||
154 | { | ||
155 | pmd_t *pmd; | ||
156 | unsigned long next; | ||
157 | |||
158 | pmd = pmd_offset(pud, addr); | ||
159 | do { | ||
160 | next = pmd_addr_end(addr, end); | ||
161 | if (pmd_none_or_clear_bad(pmd)) | ||
162 | continue; | ||
163 | unmap_im_area_pte(pmd, addr, next); | ||
164 | } while (pmd++, addr = next, addr != end); | ||
165 | } | ||
166 | |||
167 | static inline void unmap_im_area_pud(pgd_t *pgd, unsigned long addr, | ||
168 | unsigned long end) | ||
169 | { | ||
170 | pud_t *pud; | ||
171 | unsigned long next; | ||
172 | |||
173 | pud = pud_offset(pgd, addr); | ||
174 | do { | ||
175 | next = pud_addr_end(addr, end); | ||
176 | if (pud_none_or_clear_bad(pud)) | ||
177 | continue; | ||
178 | unmap_im_area_pmd(pud, addr, next); | ||
179 | } while (pud++, addr = next, addr != end); | ||
180 | } | ||
181 | |||
182 | static void unmap_im_area(unsigned long addr, unsigned long end) | ||
183 | { | ||
184 | struct mm_struct *mm = &ioremap_mm; | ||
185 | unsigned long next; | ||
186 | pgd_t *pgd; | ||
187 | |||
188 | spin_lock(&mm->page_table_lock); | ||
189 | |||
190 | pgd = pgd_offset_i(addr); | ||
191 | flush_cache_vunmap(addr, end); | ||
192 | do { | ||
193 | next = pgd_addr_end(addr, end); | ||
194 | if (pgd_none_or_clear_bad(pgd)) | ||
195 | continue; | ||
196 | unmap_im_area_pud(pgd, addr, next); | ||
197 | } while (pgd++, addr = next, addr != end); | ||
198 | flush_tlb_kernel_range(start, end); | ||
199 | |||
200 | spin_unlock(&mm->page_table_lock); | ||
201 | } | ||
202 | |||
203 | /* | 137 | /* |
204 | * map_io_page currently only called by __ioremap | 138 | * map_io_page currently only called by __ioremap |
205 | * map_io_page adds an entry to the ioremap page table | 139 | * map_io_page adds an entry to the ioremap page table |
@@ -214,21 +148,21 @@ static int map_io_page(unsigned long ea, unsigned long pa, int flags) | |||
214 | unsigned long vsid; | 148 | unsigned long vsid; |
215 | 149 | ||
216 | if (mem_init_done) { | 150 | if (mem_init_done) { |
217 | spin_lock(&ioremap_mm.page_table_lock); | 151 | spin_lock(&init_mm.page_table_lock); |
218 | pgdp = pgd_offset_i(ea); | 152 | pgdp = pgd_offset_k(ea); |
219 | pudp = pud_alloc(&ioremap_mm, pgdp, ea); | 153 | pudp = pud_alloc(&init_mm, pgdp, ea); |
220 | if (!pudp) | 154 | if (!pudp) |
221 | return -ENOMEM; | 155 | return -ENOMEM; |
222 | pmdp = pmd_alloc(&ioremap_mm, pudp, ea); | 156 | pmdp = pmd_alloc(&init_mm, pudp, ea); |
223 | if (!pmdp) | 157 | if (!pmdp) |
224 | return -ENOMEM; | 158 | return -ENOMEM; |
225 | ptep = pte_alloc_kernel(&ioremap_mm, pmdp, ea); | 159 | ptep = pte_alloc_kernel(&init_mm, pmdp, ea); |
226 | if (!ptep) | 160 | if (!ptep) |
227 | return -ENOMEM; | 161 | return -ENOMEM; |
228 | pa = abs_to_phys(pa); | 162 | pa = abs_to_phys(pa); |
229 | set_pte_at(&ioremap_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT, | 163 | set_pte_at(&init_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT, |
230 | __pgprot(flags))); | 164 | __pgprot(flags))); |
231 | spin_unlock(&ioremap_mm.page_table_lock); | 165 | spin_unlock(&init_mm.page_table_lock); |
232 | } else { | 166 | } else { |
233 | unsigned long va, vpn, hash, hpteg; | 167 | unsigned long va, vpn, hash, hpteg; |
234 | 168 | ||
@@ -267,13 +201,9 @@ static void __iomem * __ioremap_com(unsigned long addr, unsigned long pa, | |||
267 | 201 | ||
268 | for (i = 0; i < size; i += PAGE_SIZE) | 202 | for (i = 0; i < size; i += PAGE_SIZE) |
269 | if (map_io_page(ea+i, pa+i, flags)) | 203 | if (map_io_page(ea+i, pa+i, flags)) |
270 | goto failure; | 204 | return NULL; |
271 | 205 | ||
272 | return (void __iomem *) (ea + (addr & ~PAGE_MASK)); | 206 | return (void __iomem *) (ea + (addr & ~PAGE_MASK)); |
273 | failure: | ||
274 | if (mem_init_done) | ||
275 | unmap_im_area(ea, ea + size); | ||
276 | return NULL; | ||
277 | } | 207 | } |
278 | 208 | ||
279 | 209 | ||
@@ -381,19 +311,14 @@ int __ioremap_explicit(unsigned long pa, unsigned long ea, | |||
381 | */ | 311 | */ |
382 | void iounmap(volatile void __iomem *token) | 312 | void iounmap(volatile void __iomem *token) |
383 | { | 313 | { |
384 | unsigned long address, size; | ||
385 | void *addr; | 314 | void *addr; |
386 | 315 | ||
387 | if (!mem_init_done) | 316 | if (!mem_init_done) |
388 | return; | 317 | return; |
389 | 318 | ||
390 | addr = (void *) ((unsigned long __force) token & PAGE_MASK); | 319 | addr = (void *) ((unsigned long __force) token & PAGE_MASK); |
391 | |||
392 | if ((size = im_free(addr)) == 0) | ||
393 | return; | ||
394 | 320 | ||
395 | address = (unsigned long)addr; | 321 | im_free(addr); |
396 | unmap_im_area(address, address + size); | ||
397 | } | 322 | } |
398 | 323 | ||
399 | static int iounmap_subset_regions(unsigned long addr, unsigned long size) | 324 | static int iounmap_subset_regions(unsigned long addr, unsigned long size) |
diff --git a/arch/ppc64/xmon/xmon.c b/arch/ppc64/xmon/xmon.c index 3c0ccb2623ae..7f6e13a4b71e 100644 --- a/arch/ppc64/xmon/xmon.c +++ b/arch/ppc64/xmon/xmon.c | |||
@@ -2247,7 +2247,14 @@ scanhex(unsigned long *vp) | |||
2247 | tmpstr[i] = c; | 2247 | tmpstr[i] = c; |
2248 | } | 2248 | } |
2249 | tmpstr[i++] = 0; | 2249 | tmpstr[i++] = 0; |
2250 | *vp = kallsyms_lookup_name(tmpstr); | 2250 | *vp = 0; |
2251 | if (setjmp(bus_error_jmp) == 0) { | ||
2252 | catch_memory_errors = 1; | ||
2253 | sync(); | ||
2254 | *vp = kallsyms_lookup_name(tmpstr); | ||
2255 | sync(); | ||
2256 | } | ||
2257 | catch_memory_errors = 0; | ||
2251 | if (!(*vp)) { | 2258 | if (!(*vp)) { |
2252 | printf("unknown symbol '%s'\n", tmpstr); | 2259 | printf("unknown symbol '%s'\n", tmpstr); |
2253 | return 0; | 2260 | return 0; |