aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorKristen Accardi <kristen.c.accardi@intel.com>2006-03-03 13:16:05 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-03-23 17:35:17 -0500
commit783c49fc506d9afe4784390b556fa25ede5d6d1f (patch)
tree8090c2251193211129816254f16f10cbb33ed20c /drivers/pci
parentf5afe8064f3087bead8fea7e32547c2a3ada5fd0 (diff)
[PATCH] PCI Hotplug: add common acpi functions to core
shpchprm_acpi.c and pciehprm_acpi.c are nearly identical. In addition, there are functions in both these files that are also in acpiphp_glue.c. This patch will remove duplicate functions from shpchp, pciehp, and acpiphp and move this functionality to pci_hotplug, as it is not hardware specific. Get rid of shpchprm* and pciehprm* files since they are no longer needed. shpchprm_nonacpi.c and pciehprm_nonacpi.c are identical, as well as shpchprm_legacy.c and can be replaced with a macro. This patch also changes acpiphp to use the common hpp code. Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/hotplug/Makefile17
-rw-r--r--drivers/pci/hotplug/acpi_pcihp.c (renamed from drivers/pci/hotplug/pciehprm_acpi.c)206
-rw-r--r--drivers/pci/hotplug/acpiphp.h15
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c91
-rw-r--r--drivers/pci/hotplug/pci_hotplug.h17
-rw-r--r--drivers/pci/hotplug/pciehp.h24
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c74
-rw-r--r--drivers/pci/hotplug/pciehprm_nonacpi.c47
-rw-r--r--drivers/pci/hotplug/shpchp.h30
-rw-r--r--drivers/pci/hotplug/shpchp_core.c17
-rw-r--r--drivers/pci/hotplug/shpchp_pci.c10
-rw-r--r--drivers/pci/hotplug/shpchprm_acpi.c186
-rw-r--r--drivers/pci/hotplug/shpchprm_legacy.c54
-rw-r--r--drivers/pci/hotplug/shpchprm_nonacpi.c57
14 files changed, 254 insertions, 591 deletions
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile
index 1c0ed377ed91..421cfffb1756 100644
--- a/drivers/pci/hotplug/Makefile
+++ b/drivers/pci/hotplug/Makefile
@@ -22,6 +22,9 @@ ifdef CONFIG_HOTPLUG_PCI_CPCI
22pci_hotplug-objs += cpci_hotplug_core.o \ 22pci_hotplug-objs += cpci_hotplug_core.o \
23 cpci_hotplug_pci.o 23 cpci_hotplug_pci.o
24endif 24endif
25ifdef CONFIG_ACPI
26pci_hotplug-objs += acpi_pcihp.o
27endif
25 28
26cpqphp-objs := cpqphp_core.o \ 29cpqphp-objs := cpqphp_core.o \
27 cpqphp_ctrl.o \ 30 cpqphp_ctrl.o \
@@ -51,23 +54,9 @@ pciehp-objs := pciehp_core.o \
51 pciehp_ctrl.o \ 54 pciehp_ctrl.o \
52 pciehp_pci.o \ 55 pciehp_pci.o \
53 pciehp_hpc.o 56 pciehp_hpc.o
54ifdef CONFIG_ACPI
55 pciehp-objs += pciehprm_acpi.o
56else
57 pciehp-objs += pciehprm_nonacpi.o
58endif
59 57
60shpchp-objs := shpchp_core.o \ 58shpchp-objs := shpchp_core.o \
61 shpchp_ctrl.o \ 59 shpchp_ctrl.o \
62 shpchp_pci.o \ 60 shpchp_pci.o \
63 shpchp_sysfs.o \ 61 shpchp_sysfs.o \
64 shpchp_hpc.o 62 shpchp_hpc.o
65ifdef CONFIG_ACPI
66 shpchp-objs += shpchprm_acpi.o
67else
68 ifdef CONFIG_HOTPLUG_PCI_SHPC_PHPRM_LEGACY
69 shpchp-objs += shpchprm_legacy.o
70 else
71 shpchp-objs += shpchprm_nonacpi.o
72 endif
73endif
diff --git a/drivers/pci/hotplug/pciehprm_acpi.c b/drivers/pci/hotplug/acpi_pcihp.c
index 2bdb30f68bf8..0f7135317542 100644
--- a/drivers/pci/hotplug/pciehprm_acpi.c
+++ b/drivers/pci/hotplug/acpi_pcihp.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * PCIEHPRM ACPI: PHP Resource Manager for ACPI platform 2 * Common ACPI functions for hot plug platforms
3 * 3 *
4 * Copyright (C) 2003-2004 Intel Corporation 4 * Copyright (C) 2006 Intel Corporation
5 * 5 *
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
@@ -28,30 +28,37 @@
28#include <linux/kernel.h> 28#include <linux/kernel.h>
29#include <linux/types.h> 29#include <linux/types.h>
30#include <linux/pci.h> 30#include <linux/pci.h>
31#include <linux/acpi.h> 31#include <acpi/acpi.h>
32#include <linux/pci-acpi.h>
33#include <acpi/acpi_bus.h> 32#include <acpi/acpi_bus.h>
34#include <acpi/actypes.h> 33#include <acpi/actypes.h>
35#include "pciehp.h" 34#include "pci_hotplug.h"
36 35
37#define METHOD_NAME__SUN "_SUN" 36#define METHOD_NAME__SUN "_SUN"
38#define METHOD_NAME__HPP "_HPP" 37#define METHOD_NAME__HPP "_HPP"
39#define METHOD_NAME_OSHP "OSHP" 38#define METHOD_NAME_OSHP "OSHP"
40 39
41static u8 * acpi_path_name( acpi_handle handle) 40/* acpi_path_name
41 *
42 * @handle - the acpi_handle of the object who's name you want.
43 *
44 * Caller must free buffer.
45 */
46u8 * acpi_path_name(acpi_handle handle)
42{ 47{
43 acpi_status status; 48 acpi_status status;
44 static u8 path_name[ACPI_PATHNAME_MAX]; 49 struct acpi_buffer ret_buf = {ACPI_ALLOCATE_BUFFER, NULL};
45 struct acpi_buffer ret_buf = { ACPI_PATHNAME_MAX, path_name }; 50 union acpi_object *obj;
46 51
47 memset(path_name, 0, sizeof (path_name));
48 status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &ret_buf); 52 status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &ret_buf);
49 53 if (ACPI_FAILURE(status)) {
50 if (ACPI_FAILURE(status))
51 return NULL; 54 return NULL;
52 else 55 }
53 return path_name; 56 obj = ret_buf.pointer;
57 return obj->string.pointer;
54} 58}
59EXPORT_SYMBOL_GPL(acpi_path_name);
60
61
55 62
56static acpi_status 63static acpi_status
57acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp) 64acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
@@ -69,8 +76,9 @@ acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
69 case AE_BUFFER_OVERFLOW: 76 case AE_BUFFER_OVERFLOW:
70 ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL); 77 ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL);
71 if (!ret_buf.pointer) { 78 if (!ret_buf.pointer) {
72 err ("%s:%s alloc for _HPP fail\n", __FUNCTION__, 79 printk(KERN_ERR "%s:%s alloc for _HPP fail\n",
73 path_name); 80 __FUNCTION__, path_name);
81 acpi_os_free(path_name);
74 return AE_NO_MEMORY; 82 return AE_NO_MEMORY;
75 } 83 }
76 status = acpi_evaluate_object(handle, METHOD_NAME__HPP, 84 status = acpi_evaluate_object(handle, METHOD_NAME__HPP,
@@ -79,15 +87,16 @@ acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
79 break; 87 break;
80 default: 88 default:
81 if (ACPI_FAILURE(status)) { 89 if (ACPI_FAILURE(status)) {
82 dbg("%s:%s _HPP fail=0x%x\n", __FUNCTION__, 90 pr_debug("%s:%s _HPP fail=0x%x\n", __FUNCTION__,
83 path_name, status); 91 path_name, status);
92 acpi_os_free(path_name);
84 return status; 93 return status;
85 } 94 }
86 } 95 }
87 96
88 ext_obj = (union acpi_object *) ret_buf.pointer; 97 ext_obj = (union acpi_object *) ret_buf.pointer;
89 if (ext_obj->type != ACPI_TYPE_PACKAGE) { 98 if (ext_obj->type != ACPI_TYPE_PACKAGE) {
90 err ("%s:%s _HPP obj not a package\n", __FUNCTION__, 99 printk(KERN_ERR "%s:%s _HPP obj not a package\n", __FUNCTION__,
91 path_name); 100 path_name);
92 status = AE_ERROR; 101 status = AE_ERROR;
93 goto free_and_return; 102 goto free_and_return;
@@ -102,8 +111,8 @@ acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
102 nui[i] = (u8)ext_obj->integer.value; 111 nui[i] = (u8)ext_obj->integer.value;
103 break; 112 break;
104 default: 113 default:
105 err ("%s:%s _HPP obj type incorrect\n", __FUNCTION__, 114 printk(KERN_ERR "%s:%s _HPP obj type incorrect\n",
106 path_name); 115 __FUNCTION__, path_name);
107 status = AE_ERROR; 116 status = AE_ERROR;
108 goto free_and_return; 117 goto free_and_return;
109 } 118 }
@@ -114,33 +123,79 @@ acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
114 hpp->enable_serr = nui[2]; 123 hpp->enable_serr = nui[2];
115 hpp->enable_perr = nui[3]; 124 hpp->enable_perr = nui[3];
116 125
117 dbg(" _HPP: cache_line_size=0x%x\n", hpp->cache_line_size); 126 pr_debug(" _HPP: cache_line_size=0x%x\n", hpp->cache_line_size);
118 dbg(" _HPP: latency timer =0x%x\n", hpp->latency_timer); 127 pr_debug(" _HPP: latency timer =0x%x\n", hpp->latency_timer);
119 dbg(" _HPP: enable SERR =0x%x\n", hpp->enable_serr); 128 pr_debug(" _HPP: enable SERR =0x%x\n", hpp->enable_serr);
120 dbg(" _HPP: enable PERR =0x%x\n", hpp->enable_perr); 129 pr_debug(" _HPP: enable PERR =0x%x\n", hpp->enable_perr);
121 130
122free_and_return: 131free_and_return:
132 acpi_os_free(path_name);
123 kfree(ret_buf.pointer); 133 kfree(ret_buf.pointer);
124 return status; 134 return status;
125} 135}
126 136
127static acpi_status acpi_run_oshp(acpi_handle handle) 137
138
139/* acpi_run_oshp - get control of hotplug from the firmware
140 *
141 * @handle - the handle of the hotplug controller.
142 */
143acpi_status acpi_run_oshp(acpi_handle handle)
128{ 144{
129 acpi_status status; 145 acpi_status status;
130 u8 *path_name = acpi_path_name(handle); 146 u8 *path_name = acpi_path_name(handle);
131 147
132 /* run OSHP */ 148 /* run OSHP */
133 status = acpi_evaluate_object(handle, METHOD_NAME_OSHP, NULL, NULL); 149 status = acpi_evaluate_object(handle, METHOD_NAME_OSHP, NULL, NULL);
134 if (ACPI_FAILURE(status)) { 150 if (ACPI_FAILURE(status))
135 dbg("%s:%s OSHP fails=0x%x\n", __FUNCTION__, path_name, 151 printk(KERN_ERR "%s:%s OSHP fails=0x%x\n", __FUNCTION__,
136 status); 152 path_name, status);
137 } else { 153 else
138 dbg("%s:%s OSHP passes\n", __FUNCTION__, path_name); 154 pr_debug("%s:%s OSHP passes\n", __FUNCTION__, path_name);
155 acpi_os_free(path_name);
156 return status;
157}
158EXPORT_SYMBOL_GPL(acpi_run_oshp);
159
160
161
162/* acpi_get_hp_params_from_firmware
163 *
164 * @dev - the pci_dev of the newly added device
165 * @hpp - allocated by the caller
166 */
167acpi_status acpi_get_hp_params_from_firmware(struct pci_dev *dev,
168 struct hotplug_params *hpp)
169{
170 acpi_status status = AE_NOT_FOUND;
171 struct pci_dev *pdev = dev;
172
173 /*
174 * _HPP settings apply to all child buses, until another _HPP is
175 * encountered. If we don't find an _HPP for the input pci dev,
176 * look for it in the parent device scope since that would apply to
177 * this pci dev. If we don't find any _HPP, use hardcoded defaults
178 */
179 while (pdev && (ACPI_FAILURE(status))) {
180 acpi_handle handle = DEVICE_ACPI_HANDLE(&(pdev->dev));
181 if (!handle)
182 break;
183 status = acpi_run_hpp(handle, hpp);
184 if (!(pdev->bus->parent))
185 break;
186 /* Check if a parent object supports _HPP */
187 pdev = pdev->bus->parent->self;
139 } 188 }
140 return status; 189 return status;
141} 190}
191EXPORT_SYMBOL_GPL(acpi_get_hp_params_from_firmware);
192
142 193
143static int is_root_bridge(acpi_handle handle) 194/* acpi_root_bridge - check to see if this acpi object is a root bridge
195 *
196 * @handle - the acpi object in question.
197 */
198int acpi_root_bridge(acpi_handle handle)
144{ 199{
145 acpi_status status; 200 acpi_status status;
146 struct acpi_device_info *info; 201 struct acpi_device_info *info;
@@ -165,93 +220,8 @@ static int is_root_bridge(acpi_handle handle)
165 } 220 }
166 } 221 }
167 } 222 }
223 acpi_os_free(buffer.pointer);
168 } 224 }
169 return 0; 225 return 0;
170} 226}
171 227EXPORT_SYMBOL_GPL(acpi_root_bridge);
172int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev)
173{
174 acpi_status status;
175 acpi_handle chandle, handle = DEVICE_ACPI_HANDLE(&(dev->dev));
176 struct pci_dev *pdev = dev;
177 struct pci_bus *parent;
178 u8 *path_name;
179
180 /*
181 * Per PCI firmware specification, we should run the ACPI _OSC
182 * method to get control of hotplug hardware before using it.
183 * If an _OSC is missing, we look for an OSHP to do the same thing.
184 * To handle different BIOS behavior, we look for _OSC and OSHP
185 * within the scope of the hotplug controller and its parents, upto
186 * the host bridge under which this controller exists.
187 */
188 while (!handle) {
189 /*
190 * This hotplug controller was not listed in the ACPI name
191 * space at all. Try to get acpi handle of parent pci bus.
192 */
193 if (!pdev || !pdev->bus->parent)
194 break;
195 parent = pdev->bus->parent;
196 dbg("Could not find %s in acpi namespace, trying parent\n",
197 pci_name(pdev));
198 if (!parent->self)
199 /* Parent must be a host bridge */
200 handle = acpi_get_pci_rootbridge_handle(
201 pci_domain_nr(parent),
202 parent->number);
203 else
204 handle = DEVICE_ACPI_HANDLE(
205 &(parent->self->dev));
206 pdev = parent->self;
207 }
208
209 while (handle) {
210 path_name = acpi_path_name(handle);
211 dbg("Trying to get hotplug control for %s \n", path_name);
212 status = pci_osc_control_set(handle,
213 OSC_PCI_EXPRESS_NATIVE_HP_CONTROL);
214 if (status == AE_NOT_FOUND)
215 status = acpi_run_oshp(handle);
216 if (ACPI_SUCCESS(status)) {
217 dbg("Gained control for hotplug HW for pci %s (%s)\n",
218 pci_name(dev), path_name);
219 return 0;
220 }
221 if (is_root_bridge(handle))
222 break;
223 chandle = handle;
224 status = acpi_get_parent(chandle, &handle);
225 if (ACPI_FAILURE(status))
226 break;
227 }
228
229 err("Cannot get control of hotplug hardware for pci %s\n",
230 pci_name(dev));
231 return -1;
232}
233
234void pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
235 struct hotplug_params *hpp)
236{
237 acpi_status status = AE_NOT_FOUND;
238 struct pci_dev *pdev = dev;
239
240 /*
241 * _HPP settings apply to all child buses, until another _HPP is
242 * encountered. If we don't find an _HPP for the input pci dev,
243 * look for it in the parent device scope since that would apply to
244 * this pci dev. If we don't find any _HPP, use hardcoded defaults
245 */
246 while (pdev && (ACPI_FAILURE(status))) {
247 acpi_handle handle = DEVICE_ACPI_HANDLE(&(pdev->dev));
248 if (!handle)
249 break;
250 status = acpi_run_hpp(handle, hpp);
251 if (!(pdev->bus->parent))
252 break;
253 /* Check if a parent object supports _HPP */
254 pdev = pdev->bus->parent->self;
255 }
256}
257
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h
index de9df80ffb50..467ac70a46ff 100644
--- a/drivers/pci/hotplug/acpiphp.h
+++ b/drivers/pci/hotplug/acpiphp.h
@@ -64,19 +64,6 @@ struct slot {
64 struct acpiphp_slot *acpi_slot; 64 struct acpiphp_slot *acpi_slot;
65}; 65};
66 66
67/**
68 * struct hpp_param - ACPI 2.0 _HPP Hot Plug Parameters
69 * @cache_line_size in DWORD
70 * @latency_timer in PCI clock
71 * @enable_SERR 0 or 1
72 * @enable_PERR 0 or 1
73 */
74struct hpp_param {
75 u8 cache_line_size;
76 u8 latency_timer;
77 u8 enable_SERR;
78 u8 enable_PERR;
79};
80 67
81 68
82/** 69/**
@@ -100,7 +87,7 @@ struct acpiphp_bridge {
100 struct pci_dev *pci_dev; 87 struct pci_dev *pci_dev;
101 88
102 /* ACPI 2.0 _HPP parameters */ 89 /* ACPI 2.0 _HPP parameters */
103 struct hpp_param hpp; 90 struct hotplug_params hpp;
104 91
105 spinlock_t res_lock; 92 spinlock_t res_lock;
106}; 93};
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index c7e6387983df..053ee843863c 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -285,57 +285,19 @@ static int detect_ejectable_slots(acpi_handle *bridge_handle)
285static void decode_hpp(struct acpiphp_bridge *bridge) 285static void decode_hpp(struct acpiphp_bridge *bridge)
286{ 286{
287 acpi_status status; 287 acpi_status status;
288 struct acpi_buffer buffer = { .length = ACPI_ALLOCATE_BUFFER,
289 .pointer = NULL};
290 union acpi_object *package;
291 int i;
292
293 /* default numbers */
294 bridge->hpp.cache_line_size = 0x10;
295 bridge->hpp.latency_timer = 0x40;
296 bridge->hpp.enable_SERR = 0;
297 bridge->hpp.enable_PERR = 0;
298
299 status = acpi_evaluate_object(bridge->handle, "_HPP", NULL, &buffer);
300 288
289 status = acpi_get_hp_params_from_firmware(bridge->pci_dev, &bridge->hpp);
301 if (ACPI_FAILURE(status)) { 290 if (ACPI_FAILURE(status)) {
302 dbg("_HPP evaluation failed\n"); 291 /* use default numbers */
303 return; 292 bridge->hpp.cache_line_size = 0x10;
304 } 293 bridge->hpp.latency_timer = 0x40;
305 294 bridge->hpp.enable_serr = 0;
306 package = (union acpi_object *) buffer.pointer; 295 bridge->hpp.enable_perr = 0;
307
308 if (!package || package->type != ACPI_TYPE_PACKAGE ||
309 package->package.count != 4 || !package->package.elements) {
310 err("invalid _HPP object; ignoring\n");
311 goto err_exit;
312 } 296 }
313
314 for (i = 0; i < 4; i++) {
315 if (package->package.elements[i].type != ACPI_TYPE_INTEGER) {
316 err("invalid _HPP parameter type; ignoring\n");
317 goto err_exit;
318 }
319 }
320
321 bridge->hpp.cache_line_size = package->package.elements[0].integer.value;
322 bridge->hpp.latency_timer = package->package.elements[1].integer.value;
323 bridge->hpp.enable_SERR = package->package.elements[2].integer.value;
324 bridge->hpp.enable_PERR = package->package.elements[3].integer.value;
325
326 dbg("_HPP parameter = (%02x, %02x, %02x, %02x)\n",
327 bridge->hpp.cache_line_size,
328 bridge->hpp.latency_timer,
329 bridge->hpp.enable_SERR,
330 bridge->hpp.enable_PERR);
331
332 bridge->flags |= BRIDGE_HAS_HPP;
333
334 err_exit:
335 kfree(buffer.pointer);
336} 297}
337 298
338 299
300
339/* initialize miscellaneous stuff for both root and PCI-to-PCI bridge */ 301/* initialize miscellaneous stuff for both root and PCI-to-PCI bridge */
340static void init_bridge_misc(struct acpiphp_bridge *bridge) 302static void init_bridge_misc(struct acpiphp_bridge *bridge)
341{ 303{
@@ -1154,11 +1116,11 @@ static void program_hpp(struct pci_dev *dev, struct acpiphp_bridge *bridge)
1154 pci_write_config_byte(dev, PCI_LATENCY_TIMER, 1116 pci_write_config_byte(dev, PCI_LATENCY_TIMER,
1155 bridge->hpp.latency_timer); 1117 bridge->hpp.latency_timer);
1156 pci_read_config_word(dev, PCI_COMMAND, &pci_cmd); 1118 pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
1157 if (bridge->hpp.enable_SERR) 1119 if (bridge->hpp.enable_serr)
1158 pci_cmd |= PCI_COMMAND_SERR; 1120 pci_cmd |= PCI_COMMAND_SERR;
1159 else 1121 else
1160 pci_cmd &= ~PCI_COMMAND_SERR; 1122 pci_cmd &= ~PCI_COMMAND_SERR;
1161 if (bridge->hpp.enable_PERR) 1123 if (bridge->hpp.enable_perr)
1162 pci_cmd |= PCI_COMMAND_PARITY; 1124 pci_cmd |= PCI_COMMAND_PARITY;
1163 else 1125 else
1164 pci_cmd &= ~PCI_COMMAND_PARITY; 1126 pci_cmd &= ~PCI_COMMAND_PARITY;
@@ -1169,11 +1131,11 @@ static void program_hpp(struct pci_dev *dev, struct acpiphp_bridge *bridge)
1169 pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 1131 pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,
1170 bridge->hpp.latency_timer); 1132 bridge->hpp.latency_timer);
1171 pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl); 1133 pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
1172 if (bridge->hpp.enable_SERR) 1134 if (bridge->hpp.enable_serr)
1173 pci_bctl |= PCI_BRIDGE_CTL_SERR; 1135 pci_bctl |= PCI_BRIDGE_CTL_SERR;
1174 else 1136 else
1175 pci_bctl &= ~PCI_BRIDGE_CTL_SERR; 1137 pci_bctl &= ~PCI_BRIDGE_CTL_SERR;
1176 if (bridge->hpp.enable_PERR) 1138 if (bridge->hpp.enable_perr)
1177 pci_bctl |= PCI_BRIDGE_CTL_PARITY; 1139 pci_bctl |= PCI_BRIDGE_CTL_PARITY;
1178 else 1140 else
1179 pci_bctl &= ~PCI_BRIDGE_CTL_PARITY; 1141 pci_bctl &= ~PCI_BRIDGE_CTL_PARITY;
@@ -1193,6 +1155,7 @@ static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus)
1193 1155
1194 memset(&bridge, 0, sizeof(bridge)); 1156 memset(&bridge, 0, sizeof(bridge));
1195 bridge.handle = handle; 1157 bridge.handle = handle;
1158 bridge.pci_dev = bus->self;
1196 decode_hpp(&bridge); 1159 decode_hpp(&bridge);
1197 list_for_each_entry(dev, &bus->devices, bus_list) 1160 list_for_each_entry(dev, &bus->devices, bus_list)
1198 program_hpp(dev, &bridge); 1161 program_hpp(dev, &bridge);
@@ -1409,41 +1372,13 @@ void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context)
1409 } 1372 }
1410} 1373}
1411 1374
1412static int is_root_bridge(acpi_handle handle)
1413{
1414 acpi_status status;
1415 struct acpi_device_info *info;
1416 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
1417 int i;
1418
1419 status = acpi_get_object_info(handle, &buffer);
1420 if (ACPI_SUCCESS(status)) {
1421 info = buffer.pointer;
1422 if ((info->valid & ACPI_VALID_HID) &&
1423 !strcmp(PCI_ROOT_HID_STRING,
1424 info->hardware_id.value)) {
1425 acpi_os_free(buffer.pointer);
1426 return 1;
1427 }
1428 if (info->valid & ACPI_VALID_CID) {
1429 for (i=0; i < info->compatibility_id.count; i++) {
1430 if (!strcmp(PCI_ROOT_HID_STRING,
1431 info->compatibility_id.id[i].value)) {
1432 acpi_os_free(buffer.pointer);
1433 return 1;
1434 }
1435 }
1436 }
1437 }
1438 return 0;
1439}
1440 1375
1441static acpi_status 1376static acpi_status
1442find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) 1377find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
1443{ 1378{
1444 int *count = (int *)context; 1379 int *count = (int *)context;
1445 1380
1446 if (is_root_bridge(handle)) { 1381 if (acpi_root_bridge(handle)) {
1447 acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, 1382 acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
1448 handle_hotplug_event_bridge, NULL); 1383 handle_hotplug_event_bridge, NULL);
1449 (*count)++; 1384 (*count)++;
diff --git a/drivers/pci/hotplug/pci_hotplug.h b/drivers/pci/hotplug/pci_hotplug.h
index 88d44f7fef29..e476ed033384 100644
--- a/drivers/pci/hotplug/pci_hotplug.h
+++ b/drivers/pci/hotplug/pci_hotplug.h
@@ -176,5 +176,22 @@ extern int pci_hp_change_slot_info (struct hotplug_slot *slot,
176 struct hotplug_slot_info *info); 176 struct hotplug_slot_info *info);
177extern struct subsystem pci_hotplug_slots_subsys; 177extern struct subsystem pci_hotplug_slots_subsys;
178 178
179struct hotplug_params {
180 u8 cache_line_size;
181 u8 latency_timer;
182 u8 enable_serr;
183 u8 enable_perr;
184};
185
186#ifdef CONFIG_ACPI
187#include <acpi/acpi.h>
188#include <acpi/acpi_bus.h>
189#include <acpi/actypes.h>
190extern acpi_status acpi_run_oshp(acpi_handle handle);
191extern acpi_status acpi_get_hp_params_from_firmware(struct pci_dev *dev,
192 struct hotplug_params *hpp);
193extern u8 * acpi_path_name(acpi_handle handle);
194int acpi_root_bridge(acpi_handle handle);
195#endif
179#endif 196#endif
180 197
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index e0adf4bc89e8..92c1f0f1e1ad 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -50,12 +50,6 @@ extern int pciehp_force;
50#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg) 50#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
51#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg) 51#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
52 52
53struct hotplug_params {
54 u8 cache_line_size;
55 u8 latency_timer;
56 u8 enable_serr;
57 u8 enable_perr;
58};
59 53
60struct slot { 54struct slot {
61 struct slot *next; 55 struct slot *next;
@@ -192,9 +186,6 @@ extern u8 pciehp_handle_power_fault (u8 hp_slot, void *inst_id);
192/* pci functions */ 186/* pci functions */
193extern int pciehp_configure_device (struct slot *p_slot); 187extern int pciehp_configure_device (struct slot *p_slot);
194extern int pciehp_unconfigure_device (struct slot *p_slot); 188extern int pciehp_unconfigure_device (struct slot *p_slot);
195extern int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev);
196extern void pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
197 struct hotplug_params *hpp);
198 189
199 190
200 191
@@ -286,4 +277,19 @@ struct hpc_ops {
286 int (*check_lnk_status) (struct controller *ctrl); 277 int (*check_lnk_status) (struct controller *ctrl);
287}; 278};
288 279
280
281#ifdef CONFIG_ACPI
282#define pciehp_get_hp_hw_control_from_firmware(dev) \
283 pciehp_acpi_get_hp_hw_control_from_firmware(dev)
284static inline int pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
285 struct hotplug_params *hpp)
286{
287 if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev, hpp)))
288 return -ENODEV;
289 return 0;
290}
291#else
292#define pciehp_get_hp_hw_control_from_firmware(dev) 0
293#define pciehp_get_hp_params_from_firmware(dev, hpp) (-ENODEV)
294#endif /* CONFIG_ACPI */
289#endif /* _PCIEHP_H */ 295#endif /* _PCIEHP_H */
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 2427b0862cbf..22dcd12e4c1c 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -38,7 +38,10 @@
38 38
39#include "../pci.h" 39#include "../pci.h"
40#include "pciehp.h" 40#include "pciehp.h"
41 41#include <acpi/acpi.h>
42#include <acpi/acpi_bus.h>
43#include <acpi/actypes.h>
44#include <linux/pci-acpi.h>
42#ifdef DEBUG 45#ifdef DEBUG
43#define DBG_K_TRACE_ENTRY ((unsigned int)0x00000001) /* On function entry */ 46#define DBG_K_TRACE_ENTRY ((unsigned int)0x00000001) /* On function entry */
44#define DBG_K_TRACE_EXIT ((unsigned int)0x00000002) /* On function exit */ 47#define DBG_K_TRACE_EXIT ((unsigned int)0x00000002) /* On function exit */
@@ -1236,6 +1239,75 @@ static struct hpc_ops pciehp_hpc_ops = {
1236 .check_lnk_status = hpc_check_lnk_status, 1239 .check_lnk_status = hpc_check_lnk_status,
1237}; 1240};
1238 1241
1242#ifdef CONFIG_ACPI
1243int pciehp_acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev)
1244{
1245 acpi_status status;
1246 acpi_handle chandle, handle = DEVICE_ACPI_HANDLE(&(dev->dev));
1247 struct pci_dev *pdev = dev;
1248 struct pci_bus *parent;
1249 u8 *path_name = NULL;
1250
1251 /*
1252 * Per PCI firmware specification, we should run the ACPI _OSC
1253 * method to get control of hotplug hardware before using it.
1254 * If an _OSC is missing, we look for an OSHP to do the same thing.
1255 * To handle different BIOS behavior, we look for _OSC and OSHP
1256 * within the scope of the hotplug controller and its parents, upto
1257 * the host bridge under which this controller exists.
1258 */
1259 while (!handle) {
1260 /*
1261 * This hotplug controller was not listed in the ACPI name
1262 * space at all. Try to get acpi handle of parent pci bus.
1263 */
1264 if (!pdev || !pdev->bus->parent)
1265 break;
1266 parent = pdev->bus->parent;
1267 dbg("Could not find %s in acpi namespace, trying parent\n",
1268 pci_name(pdev));
1269 if (!parent->self)
1270 /* Parent must be a host bridge */
1271 handle = acpi_get_pci_rootbridge_handle(
1272 pci_domain_nr(parent),
1273 parent->number);
1274 else
1275 handle = DEVICE_ACPI_HANDLE(
1276 &(parent->self->dev));
1277 pdev = parent->self;
1278 }
1279
1280 while (handle) {
1281 path_name = acpi_path_name(handle);
1282 dbg("Trying to get hotplug control for %s \n", path_name);
1283 status = pci_osc_control_set(handle,
1284 OSC_PCI_EXPRESS_NATIVE_HP_CONTROL);
1285 if (status == AE_NOT_FOUND)
1286 status = acpi_run_oshp(handle);
1287 if (ACPI_SUCCESS(status)) {
1288 dbg("Gained control for hotplug HW for pci %s (%s)\n",
1289 pci_name(dev), path_name);
1290 acpi_os_free(path_name);
1291 return 0;
1292 }
1293 if (acpi_root_bridge(handle))
1294 break;
1295 chandle = handle;
1296 status = acpi_get_parent(chandle, &handle);
1297 if (ACPI_FAILURE(status))
1298 break;
1299 }
1300
1301 err("Cannot get control of hotplug hardware for pci %s\n",
1302 pci_name(dev));
1303 if (path_name)
1304 acpi_os_free(path_name);
1305 return -1;
1306}
1307#endif
1308
1309
1310
1239int pcie_init(struct controller * ctrl, struct pcie_device *dev) 1311int pcie_init(struct controller * ctrl, struct pcie_device *dev)
1240{ 1312{
1241 struct php_ctlr_state_s *php_ctlr, *p; 1313 struct php_ctlr_state_s *php_ctlr, *p;
diff --git a/drivers/pci/hotplug/pciehprm_nonacpi.c b/drivers/pci/hotplug/pciehprm_nonacpi.c
deleted file mode 100644
index 29180dfe8493..000000000000
--- a/drivers/pci/hotplug/pciehprm_nonacpi.c
+++ /dev/null
@@ -1,47 +0,0 @@
1/*
2 * PCIEHPRM NONACPI: PHP Resource Manager for Non-ACPI/Legacy platform
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2003-2004 Intel Corporation
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
27 *
28 */
29
30#include <linux/module.h>
31#include <linux/kernel.h>
32#include <linux/types.h>
33#include <linux/sched.h>
34#include <linux/pci.h>
35#include <linux/slab.h>
36#include "pciehp.h"
37
38void pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
39 struct hotplug_params *hpp)
40{
41 return;
42}
43
44int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev)
45{
46 return 0;
47}
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
index f10f1ba877af..5c70f43908c4 100644
--- a/drivers/pci/hotplug/shpchp.h
+++ b/drivers/pci/hotplug/shpchp.h
@@ -106,12 +106,6 @@ struct controller {
106 volatile int cmd_busy; 106 volatile int cmd_busy;
107}; 107};
108 108
109struct hotplug_params {
110 u8 cache_line_size;
111 u8 latency_timer;
112 u8 enable_serr;
113 u8 enable_perr;
114};
115 109
116/* Define AMD SHPC ID */ 110/* Define AMD SHPC ID */
117#define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450 111#define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450
@@ -193,15 +187,29 @@ extern u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id);
193extern int shpchp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num); 187extern int shpchp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num);
194extern int shpchp_configure_device(struct slot *p_slot); 188extern int shpchp_configure_device(struct slot *p_slot);
195extern int shpchp_unconfigure_device(struct slot *p_slot); 189extern int shpchp_unconfigure_device(struct slot *p_slot);
196extern void get_hp_hw_control_from_firmware(struct pci_dev *dev);
197extern void get_hp_params_from_firmware(struct pci_dev *dev,
198 struct hotplug_params *hpp);
199extern int shpchprm_get_physical_slot_number(struct controller *ctrl,
200 u32 *sun, u8 busnum, u8 devnum);
201extern void shpchp_remove_ctrl_files(struct controller *ctrl); 190extern void shpchp_remove_ctrl_files(struct controller *ctrl);
202extern void cleanup_slots(struct controller *ctrl); 191extern void cleanup_slots(struct controller *ctrl);
203extern void queue_pushbutton_work(void *data); 192extern void queue_pushbutton_work(void *data);
204 193
194
195#ifdef CONFIG_ACPI
196static inline int get_hp_params_from_firmware(struct pci_dev *dev,
197 struct hotplug_params *hpp)
198{
199 if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev, hpp)))
200 return -ENODEV;
201 return 0;
202}
203#define get_hp_hw_control_from_firmware(pdev) \
204 do { \
205 if (DEVICE_ACPI_HANDLE(&(pdev->dev))) \
206 acpi_run_oshp(DEVICE_ACPI_HANDLE(&(pdev->dev))); \
207 } while (0)
208#else
209#define get_hp_params_from_firmware(dev, hpp) (-ENODEV)
210#define get_hp_hw_control_from_firmware(dev) do { } while (0)
211#endif
212
205struct ctrl_reg { 213struct ctrl_reg {
206 volatile u32 base_offset; 214 volatile u32 base_offset;
207 volatile u32 slot_avail1; 215 volatile u32 slot_avail1;
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c
index 0e83c5fbc9df..3be4d492ccc2 100644
--- a/drivers/pci/hotplug/shpchp_core.c
+++ b/drivers/pci/hotplug/shpchp_core.c
@@ -104,6 +104,23 @@ static void make_slot_name(struct slot *slot)
104 slot->bus, slot->number); 104 slot->bus, slot->number);
105} 105}
106 106
107
108
109
110static int
111shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun,
112 u8 busnum, u8 devnum)
113{
114 int offset = devnum - ctrl->slot_device_offset;
115
116 dbg("%s: ctrl->slot_num_inc %d, offset %d\n", __FUNCTION__,
117 ctrl->slot_num_inc, offset);
118 *sun = (u8) (ctrl->first_slot + ctrl->slot_num_inc *offset);
119 return 0;
120}
121
122
123
107static int init_slots(struct controller *ctrl) 124static int init_slots(struct controller *ctrl)
108{ 125{
109 struct slot *slot; 126 struct slot *slot;
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c
index 19e1a5e1e30b..257adc233996 100644
--- a/drivers/pci/hotplug/shpchp_pci.c
+++ b/drivers/pci/hotplug/shpchp_pci.c
@@ -38,7 +38,7 @@ static void program_fw_provided_values(struct pci_dev *dev)
38{ 38{
39 u16 pci_cmd, pci_bctl; 39 u16 pci_cmd, pci_bctl;
40 struct pci_dev *cdev; 40 struct pci_dev *cdev;
41 struct hotplug_params hpp = {0x8, 0x40, 0, 0}; /* defaults */ 41 struct hotplug_params hpp;
42 42
43 /* Program hpp values for this device */ 43 /* Program hpp values for this device */
44 if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL || 44 if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL ||
@@ -46,7 +46,13 @@ static void program_fw_provided_values(struct pci_dev *dev)
46 (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI))) 46 (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
47 return; 47 return;
48 48
49 get_hp_params_from_firmware(dev, &hpp); 49 /* use default values if we can't get them from firmware */
50 if (get_hp_params_from_firmware(dev, &hpp)) {
51 hpp.cache_line_size = 8;
52 hpp.latency_timer = 0x40;
53 hpp.enable_serr = 0;
54 hpp.enable_perr = 0;
55 }
50 56
51 pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, hpp.cache_line_size); 57 pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, hpp.cache_line_size);
52 pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp.latency_timer); 58 pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp.latency_timer);
diff --git a/drivers/pci/hotplug/shpchprm_acpi.c b/drivers/pci/hotplug/shpchprm_acpi.c
deleted file mode 100644
index 17145e52223a..000000000000
--- a/drivers/pci/hotplug/shpchprm_acpi.c
+++ /dev/null
@@ -1,186 +0,0 @@
1/*
2 * SHPCHPRM ACPI: PHP Resource Manager for ACPI platform
3 *
4 * Copyright (C) 2003-2004 Intel Corporation
5 *
6 * All rights reserved.
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 (at
11 * your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
16 * NON INFRINGEMENT. See the GNU General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 * Send feedback to <kristen.c.accardi@intel.com>
24 *
25 */
26
27#include <linux/module.h>
28#include <linux/kernel.h>
29#include <linux/types.h>
30#include <linux/pci.h>
31#include <acpi/acpi.h>
32#include <acpi/acpi_bus.h>
33#include <acpi/actypes.h>
34#include "shpchp.h"
35
36#define METHOD_NAME__SUN "_SUN"
37#define METHOD_NAME__HPP "_HPP"
38#define METHOD_NAME_OSHP "OSHP"
39
40static u8 * acpi_path_name( acpi_handle handle)
41{
42 acpi_status status;
43 static u8 path_name[ACPI_PATHNAME_MAX];
44 struct acpi_buffer ret_buf = { ACPI_PATHNAME_MAX, path_name };
45
46 memset(path_name, 0, sizeof (path_name));
47 status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &ret_buf);
48
49 if (ACPI_FAILURE(status))
50 return NULL;
51 else
52 return path_name;
53}
54
55static acpi_status
56acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
57{
58 acpi_status status;
59 u8 nui[4];
60 struct acpi_buffer ret_buf = { 0, NULL};
61 union acpi_object *ext_obj, *package;
62 u8 *path_name = acpi_path_name(handle);
63 int i, len = 0;
64
65 /* get _hpp */
66 status = acpi_evaluate_object(handle, METHOD_NAME__HPP, NULL, &ret_buf);
67 switch (status) {
68 case AE_BUFFER_OVERFLOW:
69 ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL);
70 if (!ret_buf.pointer) {
71 err ("%s:%s alloc for _HPP fail\n", __FUNCTION__,
72 path_name);
73 return AE_NO_MEMORY;
74 }
75 status = acpi_evaluate_object(handle, METHOD_NAME__HPP,
76 NULL, &ret_buf);
77 if (ACPI_SUCCESS(status))
78 break;
79 default:
80 if (ACPI_FAILURE(status)) {
81 dbg("%s:%s _HPP fail=0x%x\n", __FUNCTION__,
82 path_name, status);
83 return status;
84 }
85 }
86
87 ext_obj = (union acpi_object *) ret_buf.pointer;
88 if (ext_obj->type != ACPI_TYPE_PACKAGE) {
89 err ("%s:%s _HPP obj not a package\n", __FUNCTION__,
90 path_name);
91 status = AE_ERROR;
92 goto free_and_return;
93 }
94
95 len = ext_obj->package.count;
96 package = (union acpi_object *) ret_buf.pointer;
97 for ( i = 0; (i < len) || (i < 4); i++) {
98 ext_obj = (union acpi_object *) &package->package.elements[i];
99 switch (ext_obj->type) {
100 case ACPI_TYPE_INTEGER:
101 nui[i] = (u8)ext_obj->integer.value;
102 break;
103 default:
104 err ("%s:%s _HPP obj type incorrect\n", __FUNCTION__,
105 path_name);
106 status = AE_ERROR;
107 goto free_and_return;
108 }
109 }
110
111 hpp->cache_line_size = nui[0];
112 hpp->latency_timer = nui[1];
113 hpp->enable_serr = nui[2];
114 hpp->enable_perr = nui[3];
115
116 dbg(" _HPP: cache_line_size=0x%x\n", hpp->cache_line_size);
117 dbg(" _HPP: latency timer =0x%x\n", hpp->latency_timer);
118 dbg(" _HPP: enable SERR =0x%x\n", hpp->enable_serr);
119 dbg(" _HPP: enable PERR =0x%x\n", hpp->enable_perr);
120
121free_and_return:
122 kfree(ret_buf.pointer);
123 return status;
124}
125
126static void acpi_run_oshp(acpi_handle handle)
127{
128 acpi_status status;
129 u8 *path_name = acpi_path_name(handle);
130
131 /* run OSHP */
132 status = acpi_evaluate_object(handle, METHOD_NAME_OSHP, NULL, NULL);
133 if (ACPI_FAILURE(status)) {
134 err("%s:%s OSHP fails=0x%x\n", __FUNCTION__, path_name,
135 status);
136 } else {
137 dbg("%s:%s OSHP passes\n", __FUNCTION__, path_name);
138 }
139}
140
141int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
142{
143 int offset = devnum - ctrl->slot_device_offset;
144
145 dbg("%s: ctrl->slot_num_inc %d, offset %d\n", __FUNCTION__, ctrl->slot_num_inc, offset);
146 *sun = (u8) (ctrl->first_slot + ctrl->slot_num_inc *offset);
147 return 0;
148}
149
150void get_hp_hw_control_from_firmware(struct pci_dev *dev)
151{
152 /*
153 * OSHP is an optional ACPI firmware control method. If present,
154 * we need to run it to inform BIOS that we will control SHPC
155 * hardware from now on.
156 */
157 acpi_handle handle = DEVICE_ACPI_HANDLE(&(dev->dev));
158 if (!handle)
159 return;
160 acpi_run_oshp(handle);
161}
162
163void get_hp_params_from_firmware(struct pci_dev *dev,
164 struct hotplug_params *hpp)
165{
166 acpi_status status = AE_NOT_FOUND;
167 struct pci_dev *pdev = dev;
168
169 /*
170 * _HPP settings apply to all child buses, until another _HPP is
171 * encountered. If we don't find an _HPP for the input pci dev,
172 * look for it in the parent device scope since that would apply to
173 * this pci dev. If we don't find any _HPP, use hardcoded defaults
174 */
175 while (pdev && (ACPI_FAILURE(status))) {
176 acpi_handle handle = DEVICE_ACPI_HANDLE(&(pdev->dev));
177 if (!handle)
178 break;
179 status = acpi_run_hpp(handle, hpp);
180 if (!(pdev->bus->parent))
181 break;
182 /* Check if a parent object supports _HPP */
183 pdev = pdev->bus->parent->self;
184 }
185}
186
diff --git a/drivers/pci/hotplug/shpchprm_legacy.c b/drivers/pci/hotplug/shpchprm_legacy.c
deleted file mode 100644
index ed6c1254bf6f..000000000000
--- a/drivers/pci/hotplug/shpchprm_legacy.c
+++ /dev/null
@@ -1,54 +0,0 @@
1/*
2 * SHPCHPRM Legacy: PHP Resource Manager for Non-ACPI/Legacy platform
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2003-2004 Intel Corporation
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <greg@kroah.com>,<kristen.c.accardi@intel.com>
27 *
28 */
29
30#include <linux/module.h>
31#include <linux/kernel.h>
32#include <linux/types.h>
33#include <linux/pci.h>
34#include "shpchp.h"
35
36int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
37{
38 int offset = devnum - ctrl->slot_device_offset;
39
40 *sun = (u8) (ctrl->first_slot + ctrl->slot_num_inc * offset);
41 return 0;
42}
43
44void get_hp_params_from_firmware(struct pci_dev *dev,
45 struct hotplug_params *hpp)
46{
47 return;
48}
49
50void get_hp_hw_control_from_firmware(struct pci_dev *dev)
51{
52 return;
53}
54
diff --git a/drivers/pci/hotplug/shpchprm_nonacpi.c b/drivers/pci/hotplug/shpchprm_nonacpi.c
deleted file mode 100644
index c6b40998eeb3..000000000000
--- a/drivers/pci/hotplug/shpchprm_nonacpi.c
+++ /dev/null
@@ -1,57 +0,0 @@
1/*
2 * SHPCHPRM NONACPI: PHP Resource Manager for Non-ACPI/Legacy platform
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2003-2004 Intel Corporation
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
27 *
28 */
29
30#include <linux/config.h>
31#include <linux/module.h>
32#include <linux/kernel.h>
33#include <linux/types.h>
34#include <linux/pci.h>
35#include <linux/slab.h>
36
37#include "shpchp.h"
38
39int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
40{
41 int offset = devnum - ctrl->slot_device_offset;
42
43 dbg("%s: ctrl->slot_num_inc %d, offset %d\n", __FUNCTION__, ctrl->slot_num_inc, offset);
44 *sun = (u8) (ctrl->first_slot + ctrl->slot_num_inc * offset);
45 return 0;
46}
47
48void get_hp_params_from_firmware(struct pci_dev *dev,
49 struct hotplug_params *hpp)
50{
51 return;
52}
53
54void get_hp_hw_control_from_firmware(struct pci_dev *dev)
55{
56 return;
57}