aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>2006-05-01 21:54:50 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-06-19 17:13:22 -0400
commit7430e34c70106a9576fc61d77604d164b187a1b7 (patch)
tree4b9eeaaa3702c9be216f820e8eeaf11f93610d2c /drivers/pci
parent2433ee2654f0ac86f7886e5a8d01bee7f3c7c6db (diff)
[PATCH] acpi_pcihp: Fix programming _HPP values
This patch fixes the problem that hotplug parameters are not programed when PCI cards are hot-added by ACPIPHP, SHPCHP and PCIEHP driver. The pci_dev structure being hot-added is not bound to ACPI handle, so we need to trace PCI bus tree to find ACPI handle. Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> Cc: Kristen 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/acpi_pcihp.c34
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c3
-rw-r--r--drivers/pci/hotplug/pci_hotplug.h2
-rw-r--r--drivers/pci/hotplug/pciehp.h2
-rw-r--r--drivers/pci/hotplug/shpchp.h2
5 files changed, 29 insertions, 14 deletions
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c
index 64cb30d7fc9a..9395fec73423 100644
--- a/drivers/pci/hotplug/acpi_pcihp.c
+++ b/drivers/pci/hotplug/acpi_pcihp.c
@@ -145,14 +145,27 @@ EXPORT_SYMBOL_GPL(acpi_run_oshp);
145 145
146/* acpi_get_hp_params_from_firmware 146/* acpi_get_hp_params_from_firmware
147 * 147 *
148 * @dev - the pci_dev of the newly added device 148 * @bus - the pci_bus of the bus on which the device is newly added
149 * @hpp - allocated by the caller 149 * @hpp - allocated by the caller
150 */ 150 */
151acpi_status acpi_get_hp_params_from_firmware(struct pci_dev *dev, 151acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus,
152 struct hotplug_params *hpp) 152 struct hotplug_params *hpp)
153{ 153{
154 acpi_status status = AE_NOT_FOUND; 154 acpi_status status = AE_NOT_FOUND;
155 struct pci_dev *pdev = dev; 155 acpi_handle handle, phandle;
156 struct pci_bus *pbus = bus;
157 struct pci_dev *pdev;
158
159 do {
160 pdev = pbus->self;
161 if (!pdev) {
162 handle = acpi_get_pci_rootbridge_handle(
163 pci_domain_nr(pbus), pbus->number);
164 break;
165 }
166 handle = DEVICE_ACPI_HANDLE(&(pdev->dev));
167 pbus = pbus->parent;
168 } while (!handle);
156 169
157 /* 170 /*
158 * _HPP settings apply to all child buses, until another _HPP is 171 * _HPP settings apply to all child buses, until another _HPP is
@@ -160,15 +173,16 @@ acpi_status acpi_get_hp_params_from_firmware(struct pci_dev *dev,
160 * look for it in the parent device scope since that would apply to 173 * look for it in the parent device scope since that would apply to
161 * this pci dev. If we don't find any _HPP, use hardcoded defaults 174 * this pci dev. If we don't find any _HPP, use hardcoded defaults
162 */ 175 */
163 while (pdev && (ACPI_FAILURE(status))) { 176 while (handle) {
164 acpi_handle handle = DEVICE_ACPI_HANDLE(&(pdev->dev));
165 if (!handle)
166 break;
167 status = acpi_run_hpp(handle, hpp); 177 status = acpi_run_hpp(handle, hpp);
168 if (!(pdev->bus->parent)) 178 if (ACPI_SUCCESS(status))
179 break;
180 if (acpi_root_bridge(handle))
181 break;
182 status = acpi_get_parent(handle, &phandle);
183 if (ACPI_FAILURE(status))
169 break; 184 break;
170 /* Check if a parent object supports _HPP */ 185 handle = phandle;
171 pdev = pdev->bus->parent->self;
172 } 186 }
173 return status; 187 return status;
174} 188}
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 2a83e6bdab6a..4b0988e93806 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -286,7 +286,7 @@ static void decode_hpp(struct acpiphp_bridge *bridge)
286{ 286{
287 acpi_status status; 287 acpi_status status;
288 288
289 status = acpi_get_hp_params_from_firmware(bridge->pci_dev, &bridge->hpp); 289 status = acpi_get_hp_params_from_firmware(bridge->pci_bus, &bridge->hpp);
290 if (ACPI_FAILURE(status)) { 290 if (ACPI_FAILURE(status)) {
291 /* use default numbers */ 291 /* use default numbers */
292 bridge->hpp.cache_line_size = 0x10; 292 bridge->hpp.cache_line_size = 0x10;
@@ -1250,6 +1250,7 @@ static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus)
1250 1250
1251 memset(&bridge, 0, sizeof(bridge)); 1251 memset(&bridge, 0, sizeof(bridge));
1252 bridge.handle = handle; 1252 bridge.handle = handle;
1253 bridge.pci_bus = bus;
1253 bridge.pci_dev = bus->self; 1254 bridge.pci_dev = bus->self;
1254 decode_hpp(&bridge); 1255 decode_hpp(&bridge);
1255 list_for_each_entry(dev, &bus->devices, bus_list) 1256 list_for_each_entry(dev, &bus->devices, bus_list)
diff --git a/drivers/pci/hotplug/pci_hotplug.h b/drivers/pci/hotplug/pci_hotplug.h
index eb0d01d47236..6913ace70e9b 100644
--- a/drivers/pci/hotplug/pci_hotplug.h
+++ b/drivers/pci/hotplug/pci_hotplug.h
@@ -188,7 +188,7 @@ struct hotplug_params {
188#include <acpi/acpi_bus.h> 188#include <acpi/acpi_bus.h>
189#include <acpi/actypes.h> 189#include <acpi/actypes.h>
190extern acpi_status acpi_run_oshp(acpi_handle handle); 190extern acpi_status acpi_run_oshp(acpi_handle handle);
191extern acpi_status acpi_get_hp_params_from_firmware(struct pci_dev *dev, 191extern acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus,
192 struct hotplug_params *hpp); 192 struct hotplug_params *hpp);
193int acpi_root_bridge(acpi_handle handle); 193int acpi_root_bridge(acpi_handle handle);
194#endif 194#endif
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 92c1f0f1e1ad..ce89f5815861 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -284,7 +284,7 @@ struct hpc_ops {
284static inline int pciehp_get_hp_params_from_firmware(struct pci_dev *dev, 284static inline int pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
285 struct hotplug_params *hpp) 285 struct hotplug_params *hpp)
286{ 286{
287 if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev, hpp))) 287 if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev->bus, hpp)))
288 return -ENODEV; 288 return -ENODEV;
289 return 0; 289 return 0;
290} 290}
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
index 5c70f43908c4..b70fddbce934 100644
--- a/drivers/pci/hotplug/shpchp.h
+++ b/drivers/pci/hotplug/shpchp.h
@@ -196,7 +196,7 @@ extern void queue_pushbutton_work(void *data);
196static inline int get_hp_params_from_firmware(struct pci_dev *dev, 196static inline int get_hp_params_from_firmware(struct pci_dev *dev,
197 struct hotplug_params *hpp) 197 struct hotplug_params *hpp)
198{ 198{
199 if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev, hpp))) 199 if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev->bus, hpp)))
200 return -ENODEV; 200 return -ENODEV;
201 return 0; 201 return 0;
202} 202}