aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-06-21 14:23:13 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-21 14:23:13 -0400
commit789e7dc8ee6cfb7928208b077d0799d81196e9bb (patch)
treecfaa3da3f3f919379d673819db9a27de355695dd /drivers/pci
parent28e4b224955cbe30275b2a7842e729023a4f4b03 (diff)
parent9c64f9774805ba5d5ad4129899bdd822f61874e9 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6: (30 commits) [PATCH] PCI Hotplug: Fix recovery path from errors during pcie_init() [PATCH] PCI Hotplug: fake NULL pointer dereferences in IBM Hot Plug Controller Driver [PATCH] shpchp: Cleanup improper info messages [PATCH] shpchp: Remove Unused hpc_evelnt_lock [PATCH] shpchp: Cleanup interrupt polling timer [PATCH] shpchp: Cleanup SHPC commands [PATCH] shpchp: Cleanup interrupt handler [PATCH] shpchp: Remove unnecessary hpc_ctlr_handle check [PATCH] pciehp: Implement get_address callback [PATCH] pciehp: Add missing pci_dev_put [PATCH] pciehp: Replace pci_find_slot() with pci_get_slot() [PATCH] SGI Hotplug: Incorrect power status [PATCH] shpchp: Create shpchpd at controller probe time [PATCH] shpchp: Mask Global SERR and Intr at controller release time [PATCH] SHPC: Fix SHPC Contoller SERR-INT Register bits access [PATCH] SHPC: Fix SHPC Logical Slot Register bits access [PATCH] SHPC: Cleanup SHPC Logical Slot Register bits access [PATCH] SHPC: Cleanup SHPC Logical Slot Register access [PATCH] SHPC: Cleanup SHPC register access [PATCH] pciehp: Fix programming hotplug parameters ...
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/hotplug/acpi_pcihp.c257
-rw-r--r--drivers/pci/hotplug/acpiphp.h5
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c242
-rw-r--r--drivers/pci/hotplug/ibmphp_core.c12
-rw-r--r--drivers/pci/hotplug/pci_hotplug.h50
-rw-r--r--drivers/pci/hotplug/pciehp.h2
-rw-r--r--drivers/pci/hotplug/pciehp_core.c14
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c32
-rw-r--r--drivers/pci/hotplug/pciehp_pci.c152
-rw-r--r--drivers/pci/hotplug/sgi_hotplug.c46
-rw-r--r--drivers/pci/hotplug/shpchp.h8
-rw-r--r--drivers/pci/hotplug/shpchp_core.c8
-rw-r--r--drivers/pci/hotplug/shpchp_ctrl.c32
-rw-r--r--drivers/pci/hotplug/shpchp_hpc.c861
-rw-r--r--drivers/pci/hotplug/shpchp_pci.c31
15 files changed, 1091 insertions, 661 deletions
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c
index 39af9c325f35..51cb9f817c22 100644
--- a/drivers/pci/hotplug/acpi_pcihp.c
+++ b/drivers/pci/hotplug/acpi_pcihp.c
@@ -25,6 +25,7 @@
25 */ 25 */
26 26
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/moduleparam.h>
28#include <linux/kernel.h> 29#include <linux/kernel.h>
29#include <linux/types.h> 30#include <linux/types.h>
30#include <linux/pci.h> 31#include <linux/pci.h>
@@ -33,10 +34,184 @@
33#include <acpi/actypes.h> 34#include <acpi/actypes.h>
34#include "pci_hotplug.h" 35#include "pci_hotplug.h"
35 36
37#define MY_NAME "acpi_pcihp"
38
39#define dbg(fmt, arg...) do { if (debug_acpi) printk(KERN_DEBUG "%s: %s: " fmt , MY_NAME , __FUNCTION__ , ## arg); } while (0)
40#define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
41#define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
42#define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
43
36#define METHOD_NAME__SUN "_SUN" 44#define METHOD_NAME__SUN "_SUN"
37#define METHOD_NAME__HPP "_HPP" 45#define METHOD_NAME__HPP "_HPP"
38#define METHOD_NAME_OSHP "OSHP" 46#define METHOD_NAME_OSHP "OSHP"
39 47
48static int debug_acpi;
49
50static acpi_status
51decode_type0_hpx_record(union acpi_object *record, struct hotplug_params *hpx)
52{
53 int i;
54 union acpi_object *fields = record->package.elements;
55 u32 revision = fields[1].integer.value;
56
57 switch (revision) {
58 case 1:
59 if (record->package.count != 6)
60 return AE_ERROR;
61 for (i = 2; i < 6; i++)
62 if (fields[i].type != ACPI_TYPE_INTEGER)
63 return AE_ERROR;
64 hpx->t0 = &hpx->type0_data;
65 hpx->t0->revision = revision;
66 hpx->t0->cache_line_size = fields[2].integer.value;
67 hpx->t0->latency_timer = fields[3].integer.value;
68 hpx->t0->enable_serr = fields[4].integer.value;
69 hpx->t0->enable_perr = fields[5].integer.value;
70 break;
71 default:
72 printk(KERN_WARNING
73 "%s: Type 0 Revision %d record not supported\n",
74 __FUNCTION__, revision);
75 return AE_ERROR;
76 }
77 return AE_OK;
78}
79
80static acpi_status
81decode_type1_hpx_record(union acpi_object *record, struct hotplug_params *hpx)
82{
83 int i;
84 union acpi_object *fields = record->package.elements;
85 u32 revision = fields[1].integer.value;
86
87 switch (revision) {
88 case 1:
89 if (record->package.count != 5)
90 return AE_ERROR;
91 for (i = 2; i < 5; i++)
92 if (fields[i].type != ACPI_TYPE_INTEGER)
93 return AE_ERROR;
94 hpx->t1 = &hpx->type1_data;
95 hpx->t1->revision = revision;
96 hpx->t1->max_mem_read = fields[2].integer.value;
97 hpx->t1->avg_max_split = fields[3].integer.value;
98 hpx->t1->tot_max_split = fields[4].integer.value;
99 break;
100 default:
101 printk(KERN_WARNING
102 "%s: Type 1 Revision %d record not supported\n",
103 __FUNCTION__, revision);
104 return AE_ERROR;
105 }
106 return AE_OK;
107}
108
109static acpi_status
110decode_type2_hpx_record(union acpi_object *record, struct hotplug_params *hpx)
111{
112 int i;
113 union acpi_object *fields = record->package.elements;
114 u32 revision = fields[1].integer.value;
115
116 switch (revision) {
117 case 1:
118 if (record->package.count != 18)
119 return AE_ERROR;
120 for (i = 2; i < 18; i++)
121 if (fields[i].type != ACPI_TYPE_INTEGER)
122 return AE_ERROR;
123 hpx->t2 = &hpx->type2_data;
124 hpx->t2->revision = revision;
125 hpx->t2->unc_err_mask_and = fields[2].integer.value;
126 hpx->t2->unc_err_mask_or = fields[3].integer.value;
127 hpx->t2->unc_err_sever_and = fields[4].integer.value;
128 hpx->t2->unc_err_sever_or = fields[5].integer.value;
129 hpx->t2->cor_err_mask_and = fields[6].integer.value;
130 hpx->t2->cor_err_mask_or = fields[7].integer.value;
131 hpx->t2->adv_err_cap_and = fields[8].integer.value;
132 hpx->t2->adv_err_cap_or = fields[9].integer.value;
133 hpx->t2->pci_exp_devctl_and = fields[10].integer.value;
134 hpx->t2->pci_exp_devctl_or = fields[11].integer.value;
135 hpx->t2->pci_exp_lnkctl_and = fields[12].integer.value;
136 hpx->t2->pci_exp_lnkctl_or = fields[13].integer.value;
137 hpx->t2->sec_unc_err_sever_and = fields[14].integer.value;
138 hpx->t2->sec_unc_err_sever_or = fields[15].integer.value;
139 hpx->t2->sec_unc_err_mask_and = fields[16].integer.value;
140 hpx->t2->sec_unc_err_mask_or = fields[17].integer.value;
141 break;
142 default:
143 printk(KERN_WARNING
144 "%s: Type 2 Revision %d record not supported\n",
145 __FUNCTION__, revision);
146 return AE_ERROR;
147 }
148 return AE_OK;
149}
150
151static acpi_status
152acpi_run_hpx(acpi_handle handle, struct hotplug_params *hpx)
153{
154 acpi_status status;
155 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
156 union acpi_object *package, *record, *fields;
157 u32 type;
158 int i;
159
160 /* Clear the return buffer with zeros */
161 memset(hpx, 0, sizeof(struct hotplug_params));
162
163 status = acpi_evaluate_object(handle, "_HPX", NULL, &buffer);
164 if (ACPI_FAILURE(status))
165 return status;
166
167 package = (union acpi_object *)buffer.pointer;
168 if (package->type != ACPI_TYPE_PACKAGE) {
169 status = AE_ERROR;
170 goto exit;
171 }
172
173 for (i = 0; i < package->package.count; i++) {
174 record = &package->package.elements[i];
175 if (record->type != ACPI_TYPE_PACKAGE) {
176 status = AE_ERROR;
177 goto exit;
178 }
179
180 fields = record->package.elements;
181 if (fields[0].type != ACPI_TYPE_INTEGER ||
182 fields[1].type != ACPI_TYPE_INTEGER) {
183 status = AE_ERROR;
184 goto exit;
185 }
186
187 type = fields[0].integer.value;
188 switch (type) {
189 case 0:
190 status = decode_type0_hpx_record(record, hpx);
191 if (ACPI_FAILURE(status))
192 goto exit;
193 break;
194 case 1:
195 status = decode_type1_hpx_record(record, hpx);
196 if (ACPI_FAILURE(status))
197 goto exit;
198 break;
199 case 2:
200 status = decode_type2_hpx_record(record, hpx);
201 if (ACPI_FAILURE(status))
202 goto exit;
203 break;
204 default:
205 printk(KERN_ERR "%s: Type %d record not supported\n",
206 __FUNCTION__, type);
207 status = AE_ERROR;
208 goto exit;
209 }
210 }
211 exit:
212 kfree(buffer.pointer);
213 return status;
214}
40 215
41static acpi_status 216static acpi_status
42acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp) 217acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
@@ -50,6 +225,9 @@ acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
50 225
51 acpi_get_name(handle, ACPI_FULL_PATHNAME, &string); 226 acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
52 227
228 /* Clear the return buffer with zeros */
229 memset(hpp, 0, sizeof(struct hotplug_params));
230
53 /* get _hpp */ 231 /* get _hpp */
54 status = acpi_evaluate_object(handle, METHOD_NAME__HPP, NULL, &ret_buf); 232 status = acpi_evaluate_object(handle, METHOD_NAME__HPP, NULL, &ret_buf);
55 switch (status) { 233 switch (status) {
@@ -58,7 +236,7 @@ acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
58 if (!ret_buf.pointer) { 236 if (!ret_buf.pointer) {
59 printk(KERN_ERR "%s:%s alloc for _HPP fail\n", 237 printk(KERN_ERR "%s:%s alloc for _HPP fail\n",
60 __FUNCTION__, (char *)string.pointer); 238 __FUNCTION__, (char *)string.pointer);
61 acpi_os_free(string.pointer); 239 kfree(string.pointer);
62 return AE_NO_MEMORY; 240 return AE_NO_MEMORY;
63 } 241 }
64 status = acpi_evaluate_object(handle, METHOD_NAME__HPP, 242 status = acpi_evaluate_object(handle, METHOD_NAME__HPP,
@@ -69,7 +247,7 @@ acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
69 if (ACPI_FAILURE(status)) { 247 if (ACPI_FAILURE(status)) {
70 pr_debug("%s:%s _HPP fail=0x%x\n", __FUNCTION__, 248 pr_debug("%s:%s _HPP fail=0x%x\n", __FUNCTION__,
71 (char *)string.pointer, status); 249 (char *)string.pointer, status);
72 acpi_os_free(string.pointer); 250 kfree(string.pointer);
73 return status; 251 return status;
74 } 252 }
75 } 253 }
@@ -98,19 +276,20 @@ acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
98 } 276 }
99 } 277 }
100 278
101 hpp->cache_line_size = nui[0]; 279 hpp->t0 = &hpp->type0_data;
102 hpp->latency_timer = nui[1]; 280 hpp->t0->cache_line_size = nui[0];
103 hpp->enable_serr = nui[2]; 281 hpp->t0->latency_timer = nui[1];
104 hpp->enable_perr = nui[3]; 282 hpp->t0->enable_serr = nui[2];
283 hpp->t0->enable_perr = nui[3];
105 284
106 pr_debug(" _HPP: cache_line_size=0x%x\n", hpp->cache_line_size); 285 pr_debug(" _HPP: cache_line_size=0x%x\n", hpp->t0->cache_line_size);
107 pr_debug(" _HPP: latency timer =0x%x\n", hpp->latency_timer); 286 pr_debug(" _HPP: latency timer =0x%x\n", hpp->t0->latency_timer);
108 pr_debug(" _HPP: enable SERR =0x%x\n", hpp->enable_serr); 287 pr_debug(" _HPP: enable SERR =0x%x\n", hpp->t0->enable_serr);
109 pr_debug(" _HPP: enable PERR =0x%x\n", hpp->enable_perr); 288 pr_debug(" _HPP: enable PERR =0x%x\n", hpp->t0->enable_perr);
110 289
111free_and_return: 290free_and_return:
112 acpi_os_free(string.pointer); 291 kfree(string.pointer);
113 acpi_os_free(ret_buf.pointer); 292 kfree(ret_buf.pointer);
114 return status; 293 return status;
115} 294}
116 295
@@ -130,13 +309,17 @@ acpi_status acpi_run_oshp(acpi_handle handle)
130 /* run OSHP */ 309 /* run OSHP */
131 status = acpi_evaluate_object(handle, METHOD_NAME_OSHP, NULL, NULL); 310 status = acpi_evaluate_object(handle, METHOD_NAME_OSHP, NULL, NULL);
132 if (ACPI_FAILURE(status)) 311 if (ACPI_FAILURE(status))
133 printk(KERN_ERR "%s:%s OSHP fails=0x%x\n", __FUNCTION__, 312 if (status != AE_NOT_FOUND)
134 (char *)string.pointer, status); 313 printk(KERN_ERR "%s:%s OSHP fails=0x%x\n",
314 __FUNCTION__, (char *)string.pointer, status);
315 else
316 dbg("%s:%s OSHP not found\n",
317 __FUNCTION__, (char *)string.pointer);
135 else 318 else
136 pr_debug("%s:%s OSHP passes\n", __FUNCTION__, 319 pr_debug("%s:%s OSHP passes\n", __FUNCTION__,
137 (char *)string.pointer); 320 (char *)string.pointer);
138 321
139 acpi_os_free(string.pointer); 322 kfree(string.pointer);
140 return status; 323 return status;
141} 324}
142EXPORT_SYMBOL_GPL(acpi_run_oshp); 325EXPORT_SYMBOL_GPL(acpi_run_oshp);
@@ -145,14 +328,27 @@ EXPORT_SYMBOL_GPL(acpi_run_oshp);
145 328
146/* acpi_get_hp_params_from_firmware 329/* acpi_get_hp_params_from_firmware
147 * 330 *
148 * @dev - the pci_dev of the newly added device 331 * @bus - the pci_bus of the bus on which the device is newly added
149 * @hpp - allocated by the caller 332 * @hpp - allocated by the caller
150 */ 333 */
151acpi_status acpi_get_hp_params_from_firmware(struct pci_dev *dev, 334acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus,
152 struct hotplug_params *hpp) 335 struct hotplug_params *hpp)
153{ 336{
154 acpi_status status = AE_NOT_FOUND; 337 acpi_status status = AE_NOT_FOUND;
155 struct pci_dev *pdev = dev; 338 acpi_handle handle, phandle;
339 struct pci_bus *pbus = bus;
340 struct pci_dev *pdev;
341
342 do {
343 pdev = pbus->self;
344 if (!pdev) {
345 handle = acpi_get_pci_rootbridge_handle(
346 pci_domain_nr(pbus), pbus->number);
347 break;
348 }
349 handle = DEVICE_ACPI_HANDLE(&(pdev->dev));
350 pbus = pbus->parent;
351 } while (!handle);
156 352
157 /* 353 /*
158 * _HPP settings apply to all child buses, until another _HPP is 354 * _HPP settings apply to all child buses, until another _HPP is
@@ -160,15 +356,19 @@ 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 356 * 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 357 * this pci dev. If we don't find any _HPP, use hardcoded defaults
162 */ 358 */
163 while (pdev && (ACPI_FAILURE(status))) { 359 while (handle) {
164 acpi_handle handle = DEVICE_ACPI_HANDLE(&(pdev->dev)); 360 status = acpi_run_hpx(handle, hpp);
165 if (!handle) 361 if (ACPI_SUCCESS(status))
166 break; 362 break;
167 status = acpi_run_hpp(handle, hpp); 363 status = acpi_run_hpp(handle, hpp);
168 if (!(pdev->bus->parent)) 364 if (ACPI_SUCCESS(status))
169 break; 365 break;
170 /* Check if a parent object supports _HPP */ 366 if (acpi_root_bridge(handle))
171 pdev = pdev->bus->parent->self; 367 break;
368 status = acpi_get_parent(handle, &phandle);
369 if (ACPI_FAILURE(status))
370 break;
371 handle = phandle;
172 } 372 }
173 return status; 373 return status;
174} 374}
@@ -192,20 +392,23 @@ int acpi_root_bridge(acpi_handle handle)
192 if ((info->valid & ACPI_VALID_HID) && 392 if ((info->valid & ACPI_VALID_HID) &&
193 !strcmp(PCI_ROOT_HID_STRING, 393 !strcmp(PCI_ROOT_HID_STRING,
194 info->hardware_id.value)) { 394 info->hardware_id.value)) {
195 acpi_os_free(buffer.pointer); 395 kfree(buffer.pointer);
196 return 1; 396 return 1;
197 } 397 }
198 if (info->valid & ACPI_VALID_CID) { 398 if (info->valid & ACPI_VALID_CID) {
199 for (i=0; i < info->compatibility_id.count; i++) { 399 for (i=0; i < info->compatibility_id.count; i++) {
200 if (!strcmp(PCI_ROOT_HID_STRING, 400 if (!strcmp(PCI_ROOT_HID_STRING,
201 info->compatibility_id.id[i].value)) { 401 info->compatibility_id.id[i].value)) {
202 acpi_os_free(buffer.pointer); 402 kfree(buffer.pointer);
203 return 1; 403 return 1;
204 } 404 }
205 } 405 }
206 } 406 }
207 acpi_os_free(buffer.pointer); 407 kfree(buffer.pointer);
208 } 408 }
209 return 0; 409 return 0;
210} 410}
211EXPORT_SYMBOL_GPL(acpi_root_bridge); 411EXPORT_SYMBOL_GPL(acpi_root_bridge);
412
413module_param(debug_acpi, bool, 0644);
414MODULE_PARM_DESC(debug_acpi, "Debugging mode for ACPI enabled or not");
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h
index 467ac70a46ff..17a93f890dba 100644
--- a/drivers/pci/hotplug/acpiphp.h
+++ b/drivers/pci/hotplug/acpiphp.h
@@ -75,6 +75,10 @@ struct acpiphp_bridge {
75 struct list_head list; 75 struct list_head list;
76 acpi_handle handle; 76 acpi_handle handle;
77 struct acpiphp_slot *slots; 77 struct acpiphp_slot *slots;
78
79 /* Ejectable PCI-to-PCI bridge (PCI bridge and PCI function) */
80 struct acpiphp_func *func;
81
78 int type; 82 int type;
79 int nr_slots; 83 int nr_slots;
80 84
@@ -122,6 +126,7 @@ struct acpiphp_slot {
122 */ 126 */
123struct acpiphp_func { 127struct acpiphp_func {
124 struct acpiphp_slot *slot; /* parent */ 128 struct acpiphp_slot *slot; /* parent */
129 struct acpiphp_bridge *bridge; /* Ejectable PCI-to-PCI bridge */
125 130
126 struct list_head sibling; 131 struct list_head sibling;
127 struct pci_dev *pci_dev; 132 struct pci_dev *pci_dev;
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 053ee843863c..d370f999782e 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -286,13 +286,19 @@ 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 !bridge->hpp.t0 || (bridge->hpp.t0->revision > 1)) {
291 /* use default numbers */ 292 /* use default numbers */
292 bridge->hpp.cache_line_size = 0x10; 293 printk(KERN_WARNING
293 bridge->hpp.latency_timer = 0x40; 294 "%s: Could not get hotplug parameters. Use defaults\n",
294 bridge->hpp.enable_serr = 0; 295 __FUNCTION__);
295 bridge->hpp.enable_perr = 0; 296 bridge->hpp.t0 = &bridge->hpp.type0_data;
297 bridge->hpp.t0->revision = 0;
298 bridge->hpp.t0->cache_line_size = 0x10;
299 bridge->hpp.t0->latency_timer = 0x40;
300 bridge->hpp.t0->enable_serr = 0;
301 bridge->hpp.t0->enable_perr = 0;
296 } 302 }
297} 303}
298 304
@@ -319,6 +325,13 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge)
319 325
320 /* install notify handler */ 326 /* install notify handler */
321 if (bridge->type != BRIDGE_TYPE_HOST) { 327 if (bridge->type != BRIDGE_TYPE_HOST) {
328 if ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func) {
329 status = acpi_remove_notify_handler(bridge->func->handle,
330 ACPI_SYSTEM_NOTIFY,
331 handle_hotplug_event_func);
332 if (ACPI_FAILURE(status))
333 err("failed to remove notify handler\n");
334 }
322 status = acpi_install_notify_handler(bridge->handle, 335 status = acpi_install_notify_handler(bridge->handle,
323 ACPI_SYSTEM_NOTIFY, 336 ACPI_SYSTEM_NOTIFY,
324 handle_hotplug_event_bridge, 337 handle_hotplug_event_bridge,
@@ -331,6 +344,66 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge)
331} 344}
332 345
333 346
347/* find acpiphp_func from acpiphp_bridge */
348static struct acpiphp_func *acpiphp_bridge_handle_to_function(acpi_handle handle)
349{
350 struct list_head *node, *l;
351 struct acpiphp_bridge *bridge;
352 struct acpiphp_slot *slot;
353 struct acpiphp_func *func;
354
355 list_for_each(node, &bridge_list) {
356 bridge = list_entry(node, struct acpiphp_bridge, list);
357 for (slot = bridge->slots; slot; slot = slot->next) {
358 list_for_each(l, &slot->funcs) {
359 func = list_entry(l, struct acpiphp_func,
360 sibling);
361 if (func->handle == handle)
362 return func;
363 }
364 }
365 }
366
367 return NULL;
368}
369
370
371static inline void config_p2p_bridge_flags(struct acpiphp_bridge *bridge)
372{
373 acpi_handle dummy_handle;
374
375 if (ACPI_SUCCESS(acpi_get_handle(bridge->handle,
376 "_STA", &dummy_handle)))
377 bridge->flags |= BRIDGE_HAS_STA;
378
379 if (ACPI_SUCCESS(acpi_get_handle(bridge->handle,
380 "_EJ0", &dummy_handle)))
381 bridge->flags |= BRIDGE_HAS_EJ0;
382
383 if (ACPI_SUCCESS(acpi_get_handle(bridge->handle,
384 "_PS0", &dummy_handle)))
385 bridge->flags |= BRIDGE_HAS_PS0;
386
387 if (ACPI_SUCCESS(acpi_get_handle(bridge->handle,
388 "_PS3", &dummy_handle)))
389 bridge->flags |= BRIDGE_HAS_PS3;
390
391 /* is this ejectable p2p bridge? */
392 if (bridge->flags & BRIDGE_HAS_EJ0) {
393 struct acpiphp_func *func;
394
395 dbg("found ejectable p2p bridge\n");
396
397 /* make link between PCI bridge and PCI function */
398 func = acpiphp_bridge_handle_to_function(bridge->handle);
399 if (!func)
400 return;
401 bridge->func = func;
402 func->bridge = bridge;
403 }
404}
405
406
334/* allocate and initialize host bridge data structure */ 407/* allocate and initialize host bridge data structure */
335static void add_host_bridge(acpi_handle *handle, struct pci_bus *pci_bus) 408static void add_host_bridge(acpi_handle *handle, struct pci_bus *pci_bus)
336{ 409{
@@ -364,6 +437,7 @@ static void add_p2p_bridge(acpi_handle *handle, struct pci_dev *pci_dev)
364 437
365 bridge->type = BRIDGE_TYPE_P2P; 438 bridge->type = BRIDGE_TYPE_P2P;
366 bridge->handle = handle; 439 bridge->handle = handle;
440 config_p2p_bridge_flags(bridge);
367 441
368 bridge->pci_dev = pci_dev_get(pci_dev); 442 bridge->pci_dev = pci_dev_get(pci_dev);
369 bridge->pci_bus = pci_dev->subordinate; 443 bridge->pci_bus = pci_dev->subordinate;
@@ -423,7 +497,7 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
423 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, 497 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
424 find_p2p_bridge, dev->subordinate, NULL); 498 find_p2p_bridge, dev->subordinate, NULL);
425 if (ACPI_FAILURE(status)) 499 if (ACPI_FAILURE(status))
426 warn("find_p2p_bridge faied (error code = 0x%x)\n", status); 500 warn("find_p2p_bridge failed (error code = 0x%x)\n", status);
427 501
428 out: 502 out:
429 pci_dev_put(dev); 503 pci_dev_put(dev);
@@ -478,7 +552,6 @@ static int add_bridge(acpi_handle handle)
478 if (detect_ejectable_slots(handle) > 0) { 552 if (detect_ejectable_slots(handle) > 0) {
479 dbg("found PCI host-bus bridge with hot-pluggable slots\n"); 553 dbg("found PCI host-bus bridge with hot-pluggable slots\n");
480 add_host_bridge(handle, pci_bus); 554 add_host_bridge(handle, pci_bus);
481 return 0;
482 } 555 }
483 556
484 /* search P2P bridges under this host bridge */ 557 /* search P2P bridges under this host bridge */
@@ -486,7 +559,7 @@ static int add_bridge(acpi_handle handle)
486 find_p2p_bridge, pci_bus, NULL); 559 find_p2p_bridge, pci_bus, NULL);
487 560
488 if (ACPI_FAILURE(status)) 561 if (ACPI_FAILURE(status))
489 warn("find_p2p_bridge faied (error code = 0x%x)\n",status); 562 warn("find_p2p_bridge failed (error code = 0x%x)\n", status);
490 563
491 return 0; 564 return 0;
492} 565}
@@ -516,6 +589,16 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge)
516 if (ACPI_FAILURE(status)) 589 if (ACPI_FAILURE(status))
517 err("failed to remove notify handler\n"); 590 err("failed to remove notify handler\n");
518 591
592 if ((bridge->type != BRIDGE_TYPE_HOST) &&
593 ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func)) {
594 status = acpi_install_notify_handler(bridge->func->handle,
595 ACPI_SYSTEM_NOTIFY,
596 handle_hotplug_event_func,
597 bridge->func);
598 if (ACPI_FAILURE(status))
599 err("failed to install interrupt notify handler\n");
600 }
601
519 slot = bridge->slots; 602 slot = bridge->slots;
520 while (slot) { 603 while (slot) {
521 struct acpiphp_slot *next = slot->next; 604 struct acpiphp_slot *next = slot->next;
@@ -549,6 +632,11 @@ cleanup_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
549{ 632{
550 struct acpiphp_bridge *bridge; 633 struct acpiphp_bridge *bridge;
551 634
635 /* cleanup p2p bridges under this P2P bridge
636 in a depth-first manner */
637 acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
638 cleanup_p2p_bridge, NULL, NULL);
639
552 if (!(bridge = acpiphp_handle_to_bridge(handle))) 640 if (!(bridge = acpiphp_handle_to_bridge(handle)))
553 return AE_OK; 641 return AE_OK;
554 cleanup_bridge(bridge); 642 cleanup_bridge(bridge);
@@ -559,15 +647,14 @@ static void remove_bridge(acpi_handle handle)
559{ 647{
560 struct acpiphp_bridge *bridge; 648 struct acpiphp_bridge *bridge;
561 649
650 /* cleanup p2p bridges under this host bridge
651 in a depth-first manner */
652 acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
653 (u32)1, cleanup_p2p_bridge, NULL, NULL);
654
562 bridge = acpiphp_handle_to_bridge(handle); 655 bridge = acpiphp_handle_to_bridge(handle);
563 if (bridge) { 656 if (bridge)
564 cleanup_bridge(bridge); 657 cleanup_bridge(bridge);
565 } else {
566 /* clean-up p2p bridges under this host bridge */
567 acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
568 ACPI_UINT32_MAX, cleanup_p2p_bridge,
569 NULL, NULL);
570 }
571} 658}
572 659
573static struct pci_dev * get_apic_pci_info(acpi_handle handle) 660static struct pci_dev * get_apic_pci_info(acpi_handle handle)
@@ -634,7 +721,7 @@ static int get_gsi_base(acpi_handle handle, u32 *gsi_base)
634 break; 721 break;
635 } 722 }
636 out: 723 out:
637 acpi_os_free(buffer.pointer); 724 kfree(buffer.pointer);
638 return result; 725 return result;
639} 726}
640 727
@@ -797,36 +884,6 @@ static unsigned char acpiphp_max_busnr(struct pci_bus *bus)
797} 884}
798 885
799 886
800
801/**
802 * get_func - get a pointer to acpiphp_func given a slot, device
803 * @slot: slot to search
804 * @dev: pci_dev struct to match.
805 *
806 * This function will increase the reference count of pci_dev,
807 * so callers should call pci_dev_put when complete.
808 *
809 */
810static struct acpiphp_func *
811get_func(struct acpiphp_slot *slot, struct pci_dev *dev)
812{
813 struct acpiphp_func *func = NULL;
814 struct pci_bus *bus = slot->bridge->pci_bus;
815 struct pci_dev *pdev;
816
817 list_for_each_entry(func, &slot->funcs, sibling) {
818 pdev = pci_get_slot(bus, PCI_DEVFN(slot->device,
819 func->function));
820 if (pdev) {
821 if (pdev == dev)
822 break;
823 pci_dev_put(pdev);
824 }
825 }
826 return func;
827}
828
829
830/** 887/**
831 * acpiphp_bus_add - add a new bus to acpi subsystem 888 * acpiphp_bus_add - add a new bus to acpi subsystem
832 * @func: acpiphp_func of the bridge 889 * @func: acpiphp_func of the bridge
@@ -872,6 +929,28 @@ acpiphp_bus_add_out:
872} 929}
873 930
874 931
932/**
933 * acpiphp_bus_trim - trim a bus from acpi subsystem
934 * @handle: handle to acpi namespace
935 *
936 */
937int acpiphp_bus_trim(acpi_handle handle)
938{
939 struct acpi_device *device;
940 int retval;
941
942 retval = acpi_bus_get_device(handle, &device);
943 if (retval) {
944 dbg("acpi_device not found\n");
945 return retval;
946 }
947
948 retval = acpi_bus_trim(device, 1);
949 if (retval)
950 err("cannot remove from acpi list\n");
951
952 return retval;
953}
875 954
876/** 955/**
877 * enable_device - enable, configure a slot 956 * enable_device - enable, configure a slot
@@ -889,6 +968,7 @@ static int enable_device(struct acpiphp_slot *slot)
889 struct acpiphp_func *func; 968 struct acpiphp_func *func;
890 int retval = 0; 969 int retval = 0;
891 int num, max, pass; 970 int num, max, pass;
971 acpi_status status;
892 972
893 if (slot->flags & SLOT_ENABLED) 973 if (slot->flags & SLOT_ENABLED)
894 goto err_exit; 974 goto err_exit;
@@ -918,19 +998,17 @@ static int enable_device(struct acpiphp_slot *slot)
918 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || 998 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
919 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { 999 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
920 max = pci_scan_bridge(bus, dev, max, pass); 1000 max = pci_scan_bridge(bus, dev, max, pass);
921 if (pass && dev->subordinate) { 1001 if (pass && dev->subordinate)
922 pci_bus_size_bridges(dev->subordinate); 1002 pci_bus_size_bridges(dev->subordinate);
923 func = get_func(slot, dev);
924 if (func) {
925 acpiphp_bus_add(func);
926 /* side effect of get_func */
927 pci_dev_put(dev);
928 }
929 }
930 } 1003 }
931 } 1004 }
932 } 1005 }
933 1006
1007 list_for_each (l, &slot->funcs) {
1008 func = list_entry(l, struct acpiphp_func, sibling);
1009 acpiphp_bus_add(func);
1010 }
1011
934 pci_bus_assign_resources(bus); 1012 pci_bus_assign_resources(bus);
935 acpiphp_sanitize_bus(bus); 1013 acpiphp_sanitize_bus(bus);
936 pci_enable_bridges(bus); 1014 pci_enable_bridges(bus);
@@ -943,6 +1021,17 @@ static int enable_device(struct acpiphp_slot *slot)
943 func = list_entry(l, struct acpiphp_func, sibling); 1021 func = list_entry(l, struct acpiphp_func, sibling);
944 func->pci_dev = pci_get_slot(bus, PCI_DEVFN(slot->device, 1022 func->pci_dev = pci_get_slot(bus, PCI_DEVFN(slot->device,
945 func->function)); 1023 func->function));
1024 if (!func->pci_dev)
1025 continue;
1026
1027 if (func->pci_dev->hdr_type != PCI_HEADER_TYPE_BRIDGE &&
1028 func->pci_dev->hdr_type != PCI_HEADER_TYPE_CARDBUS)
1029 continue;
1030
1031 status = find_p2p_bridge(func->handle, (u32)1, bus, NULL);
1032 if (ACPI_FAILURE(status))
1033 warn("find_p2p_bridge failed (error code = 0x%x)\n",
1034 status);
946 } 1035 }
947 1036
948 slot->flags |= SLOT_ENABLED; 1037 slot->flags |= SLOT_ENABLED;
@@ -967,6 +1056,18 @@ static int disable_device(struct acpiphp_slot *slot)
967 1056
968 list_for_each (l, &slot->funcs) { 1057 list_for_each (l, &slot->funcs) {
969 func = list_entry(l, struct acpiphp_func, sibling); 1058 func = list_entry(l, struct acpiphp_func, sibling);
1059
1060 if (func->bridge) {
1061 /* cleanup p2p bridges under this P2P bridge */
1062 cleanup_p2p_bridge(func->bridge->handle,
1063 (u32)1, NULL, NULL);
1064 func->bridge = NULL;
1065 }
1066
1067 acpiphp_bus_trim(func->handle);
1068 /* try to remove anyway.
1069 * acpiphp_bus_add might have been failed */
1070
970 if (!func->pci_dev) 1071 if (!func->pci_dev)
971 continue; 1072 continue;
972 1073
@@ -1111,16 +1212,17 @@ static void program_hpp(struct pci_dev *dev, struct acpiphp_bridge *bridge)
1111 (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && 1212 (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
1112 (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI))) 1213 (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
1113 return; 1214 return;
1215
1114 pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 1216 pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
1115 bridge->hpp.cache_line_size); 1217 bridge->hpp.t0->cache_line_size);
1116 pci_write_config_byte(dev, PCI_LATENCY_TIMER, 1218 pci_write_config_byte(dev, PCI_LATENCY_TIMER,
1117 bridge->hpp.latency_timer); 1219 bridge->hpp.t0->latency_timer);
1118 pci_read_config_word(dev, PCI_COMMAND, &pci_cmd); 1220 pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
1119 if (bridge->hpp.enable_serr) 1221 if (bridge->hpp.t0->enable_serr)
1120 pci_cmd |= PCI_COMMAND_SERR; 1222 pci_cmd |= PCI_COMMAND_SERR;
1121 else 1223 else
1122 pci_cmd &= ~PCI_COMMAND_SERR; 1224 pci_cmd &= ~PCI_COMMAND_SERR;
1123 if (bridge->hpp.enable_perr) 1225 if (bridge->hpp.t0->enable_perr)
1124 pci_cmd |= PCI_COMMAND_PARITY; 1226 pci_cmd |= PCI_COMMAND_PARITY;
1125 else 1227 else
1126 pci_cmd &= ~PCI_COMMAND_PARITY; 1228 pci_cmd &= ~PCI_COMMAND_PARITY;
@@ -1129,13 +1231,13 @@ static void program_hpp(struct pci_dev *dev, struct acpiphp_bridge *bridge)
1129 /* Program bridge control value and child devices */ 1231 /* Program bridge control value and child devices */
1130 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { 1232 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
1131 pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 1233 pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,
1132 bridge->hpp.latency_timer); 1234 bridge->hpp.t0->latency_timer);
1133 pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl); 1235 pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
1134 if (bridge->hpp.enable_serr) 1236 if (bridge->hpp.t0->enable_serr)
1135 pci_bctl |= PCI_BRIDGE_CTL_SERR; 1237 pci_bctl |= PCI_BRIDGE_CTL_SERR;
1136 else 1238 else
1137 pci_bctl &= ~PCI_BRIDGE_CTL_SERR; 1239 pci_bctl &= ~PCI_BRIDGE_CTL_SERR;
1138 if (bridge->hpp.enable_perr) 1240 if (bridge->hpp.t0->enable_perr)
1139 pci_bctl |= PCI_BRIDGE_CTL_PARITY; 1241 pci_bctl |= PCI_BRIDGE_CTL_PARITY;
1140 else 1242 else
1141 pci_bctl &= ~PCI_BRIDGE_CTL_PARITY; 1243 pci_bctl &= ~PCI_BRIDGE_CTL_PARITY;
@@ -1155,6 +1257,7 @@ static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus)
1155 1257
1156 memset(&bridge, 0, sizeof(bridge)); 1258 memset(&bridge, 0, sizeof(bridge));
1157 bridge.handle = handle; 1259 bridge.handle = handle;
1260 bridge.pci_bus = bus;
1158 bridge.pci_dev = bus->self; 1261 bridge.pci_dev = bus->self;
1159 decode_hpp(&bridge); 1262 decode_hpp(&bridge);
1160 list_for_each_entry(dev, &bus->devices, bus_list) 1263 list_for_each_entry(dev, &bus->devices, bus_list)
@@ -1297,6 +1400,13 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont
1297 case ACPI_NOTIFY_EJECT_REQUEST: 1400 case ACPI_NOTIFY_EJECT_REQUEST:
1298 /* request device eject */ 1401 /* request device eject */
1299 dbg("%s: Device eject notify on %s\n", __FUNCTION__, objname); 1402 dbg("%s: Device eject notify on %s\n", __FUNCTION__, objname);
1403 if ((bridge->type != BRIDGE_TYPE_HOST) &&
1404 (bridge->flags & BRIDGE_HAS_EJ0)) {
1405 struct acpiphp_slot *slot;
1406 slot = bridge->func->slot;
1407 if (!acpiphp_disable_slot(slot))
1408 acpiphp_eject_slot(slot);
1409 }
1300 break; 1410 break;
1301 1411
1302 case ACPI_NOTIFY_FREQUENCY_MISMATCH: 1412 case ACPI_NOTIFY_FREQUENCY_MISMATCH:
@@ -1490,9 +1600,15 @@ int acpiphp_enable_slot(struct acpiphp_slot *slot)
1490 if (retval) 1600 if (retval)
1491 goto err_exit; 1601 goto err_exit;
1492 1602
1493 if (get_slot_status(slot) == ACPI_STA_ALL) 1603 if (get_slot_status(slot) == ACPI_STA_ALL) {
1494 /* configure all functions */ 1604 /* configure all functions */
1495 retval = enable_device(slot); 1605 retval = enable_device(slot);
1606 if (retval)
1607 power_off_slot(slot);
1608 } else {
1609 dbg("%s: Slot status is not ACPI_STA_ALL\n", __FUNCTION__);
1610 power_off_slot(slot);
1611 }
1496 1612
1497 err_exit: 1613 err_exit:
1498 mutex_unlock(&slot->crit_sect); 1614 mutex_unlock(&slot->crit_sect);
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c
index e13d5b87241a..59392946c2bd 100644
--- a/drivers/pci/hotplug/ibmphp_core.c
+++ b/drivers/pci/hotplug/ibmphp_core.c
@@ -285,7 +285,7 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value)
285 (ulong) hotplug_slot, (ulong) value); 285 (ulong) hotplug_slot, (ulong) value);
286 286
287 ibmphp_lock_operations(); 287 ibmphp_lock_operations();
288 if (hotplug_slot && value) { 288 if (hotplug_slot) {
289 pslot = hotplug_slot->private; 289 pslot = hotplug_slot->private;
290 if (pslot) { 290 if (pslot) {
291 memcpy(&myslot, pslot, sizeof(struct slot)); 291 memcpy(&myslot, pslot, sizeof(struct slot));
@@ -315,7 +315,7 @@ static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 * value)
315 debug("get_latch_status - Entry hotplug_slot[%lx] pvalue[%lx]\n", 315 debug("get_latch_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
316 (ulong) hotplug_slot, (ulong) value); 316 (ulong) hotplug_slot, (ulong) value);
317 ibmphp_lock_operations(); 317 ibmphp_lock_operations();
318 if (hotplug_slot && value) { 318 if (hotplug_slot) {
319 pslot = hotplug_slot->private; 319 pslot = hotplug_slot->private;
320 if (pslot) { 320 if (pslot) {
321 memcpy(&myslot, pslot, sizeof(struct slot)); 321 memcpy(&myslot, pslot, sizeof(struct slot));
@@ -342,7 +342,7 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 * value)
342 debug("get_power_status - Entry hotplug_slot[%lx] pvalue[%lx]\n", 342 debug("get_power_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
343 (ulong) hotplug_slot, (ulong) value); 343 (ulong) hotplug_slot, (ulong) value);
344 ibmphp_lock_operations(); 344 ibmphp_lock_operations();
345 if (hotplug_slot && value) { 345 if (hotplug_slot) {
346 pslot = hotplug_slot->private; 346 pslot = hotplug_slot->private;
347 if (pslot) { 347 if (pslot) {
348 memcpy(&myslot, pslot, sizeof(struct slot)); 348 memcpy(&myslot, pslot, sizeof(struct slot));
@@ -369,7 +369,7 @@ static int get_adapter_present(struct hotplug_slot *hotplug_slot, u8 * value)
369 debug("get_adapter_status - Entry hotplug_slot[%lx] pvalue[%lx]\n", 369 debug("get_adapter_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
370 (ulong) hotplug_slot, (ulong) value); 370 (ulong) hotplug_slot, (ulong) value);
371 ibmphp_lock_operations(); 371 ibmphp_lock_operations();
372 if (hotplug_slot && value) { 372 if (hotplug_slot) {
373 pslot = hotplug_slot->private; 373 pslot = hotplug_slot->private;
374 if (pslot) { 374 if (pslot) {
375 memcpy(&myslot, pslot, sizeof(struct slot)); 375 memcpy(&myslot, pslot, sizeof(struct slot));
@@ -401,7 +401,7 @@ static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe
401 401
402 ibmphp_lock_operations(); 402 ibmphp_lock_operations();
403 403
404 if (hotplug_slot && value) { 404 if (hotplug_slot) {
405 pslot = hotplug_slot->private; 405 pslot = hotplug_slot->private;
406 if (pslot) { 406 if (pslot) {
407 rc = 0; 407 rc = 0;
@@ -441,7 +441,7 @@ static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe
441 441
442 ibmphp_lock_operations(); 442 ibmphp_lock_operations();
443 443
444 if (hotplug_slot && value) { 444 if (hotplug_slot) {
445 pslot = hotplug_slot->private; 445 pslot = hotplug_slot->private;
446 if (pslot) { 446 if (pslot) {
447 rc = get_cur_bus_info(&pslot); 447 rc = get_cur_bus_info(&pslot);
diff --git a/drivers/pci/hotplug/pci_hotplug.h b/drivers/pci/hotplug/pci_hotplug.h
index eb0d01d47236..e929b7c11429 100644
--- a/drivers/pci/hotplug/pci_hotplug.h
+++ b/drivers/pci/hotplug/pci_hotplug.h
@@ -176,11 +176,51 @@ 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
179/* PCI Setting Record (Type 0) */
180struct hpp_type0 {
181 u32 revision;
182 u8 cache_line_size;
183 u8 latency_timer;
184 u8 enable_serr;
185 u8 enable_perr;
186};
187
188/* PCI-X Setting Record (Type 1) */
189struct hpp_type1 {
190 u32 revision;
191 u8 max_mem_read;
192 u8 avg_max_split;
193 u16 tot_max_split;
194};
195
196/* PCI Express Setting Record (Type 2) */
197struct hpp_type2 {
198 u32 revision;
199 u32 unc_err_mask_and;
200 u32 unc_err_mask_or;
201 u32 unc_err_sever_and;
202 u32 unc_err_sever_or;
203 u32 cor_err_mask_and;
204 u32 cor_err_mask_or;
205 u32 adv_err_cap_and;
206 u32 adv_err_cap_or;
207 u16 pci_exp_devctl_and;
208 u16 pci_exp_devctl_or;
209 u16 pci_exp_lnkctl_and;
210 u16 pci_exp_lnkctl_or;
211 u32 sec_unc_err_sever_and;
212 u32 sec_unc_err_sever_or;
213 u32 sec_unc_err_mask_and;
214 u32 sec_unc_err_mask_or;
215};
216
179struct hotplug_params { 217struct hotplug_params {
180 u8 cache_line_size; 218 struct hpp_type0 *t0; /* Type0: NULL if not available */
181 u8 latency_timer; 219 struct hpp_type1 *t1; /* Type1: NULL if not available */
182 u8 enable_serr; 220 struct hpp_type2 *t2; /* Type2: NULL if not available */
183 u8 enable_perr; 221 struct hpp_type0 type0_data;
222 struct hpp_type1 type1_data;
223 struct hpp_type2 type2_data;
184}; 224};
185 225
186#ifdef CONFIG_ACPI 226#ifdef CONFIG_ACPI
@@ -188,7 +228,7 @@ struct hotplug_params {
188#include <acpi/acpi_bus.h> 228#include <acpi/acpi_bus.h>
189#include <acpi/actypes.h> 229#include <acpi/actypes.h>
190extern acpi_status acpi_run_oshp(acpi_handle handle); 230extern acpi_status acpi_run_oshp(acpi_handle handle);
191extern acpi_status acpi_get_hp_params_from_firmware(struct pci_dev *dev, 231extern acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus,
192 struct hotplug_params *hpp); 232 struct hotplug_params *hpp);
193int acpi_root_bridge(acpi_handle handle); 233int acpi_root_bridge(acpi_handle handle);
194#endif 234#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/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 601cf9045b20..c67b7c3f1ddf 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -69,6 +69,7 @@ static int get_power_status (struct hotplug_slot *slot, u8 *value);
69static int get_attention_status (struct hotplug_slot *slot, u8 *value); 69static int get_attention_status (struct hotplug_slot *slot, u8 *value);
70static int get_latch_status (struct hotplug_slot *slot, u8 *value); 70static int get_latch_status (struct hotplug_slot *slot, u8 *value);
71static int get_adapter_status (struct hotplug_slot *slot, u8 *value); 71static int get_adapter_status (struct hotplug_slot *slot, u8 *value);
72static int get_address (struct hotplug_slot *slot, u32 *value);
72static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); 73static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value);
73static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); 74static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value);
74 75
@@ -81,6 +82,7 @@ static struct hotplug_slot_ops pciehp_hotplug_slot_ops = {
81 .get_attention_status = get_attention_status, 82 .get_attention_status = get_attention_status,
82 .get_latch_status = get_latch_status, 83 .get_latch_status = get_latch_status,
83 .get_adapter_status = get_adapter_status, 84 .get_adapter_status = get_adapter_status,
85 .get_address = get_address,
84 .get_max_bus_speed = get_max_bus_speed, 86 .get_max_bus_speed = get_max_bus_speed,
85 .get_cur_bus_speed = get_cur_bus_speed, 87 .get_cur_bus_speed = get_cur_bus_speed,
86}; 88};
@@ -331,6 +333,18 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
331 return 0; 333 return 0;
332} 334}
333 335
336static int get_address(struct hotplug_slot *hotplug_slot, u32 *value)
337{
338 struct slot *slot = hotplug_slot->private;
339 struct pci_bus *bus = slot->ctrl->pci_dev->subordinate;
340
341 dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
342
343 *value = (pci_domain_nr(bus) << 16) | (slot->bus << 8) | slot->device;
344
345 return 0;
346}
347
334static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) 348static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
335{ 349{
336 struct slot *slot = hotplug_slot->private; 350 struct slot *slot = hotplug_slot->private;
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 6c14d9e46b2e..d77138ecb098 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -1288,7 +1288,7 @@ int pciehp_acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev)
1288 if (ACPI_SUCCESS(status)) { 1288 if (ACPI_SUCCESS(status)) {
1289 dbg("Gained control for hotplug HW for pci %s (%s)\n", 1289 dbg("Gained control for hotplug HW for pci %s (%s)\n",
1290 pci_name(dev), (char *)string.pointer); 1290 pci_name(dev), (char *)string.pointer);
1291 acpi_os_free(string.pointer); 1291 kfree(string.pointer);
1292 return 0; 1292 return 0;
1293 } 1293 }
1294 if (acpi_root_bridge(handle)) 1294 if (acpi_root_bridge(handle))
@@ -1302,7 +1302,7 @@ int pciehp_acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev)
1302 err("Cannot get control of hotplug hardware for pci %s\n", 1302 err("Cannot get control of hotplug hardware for pci %s\n",
1303 pci_name(dev)); 1303 pci_name(dev));
1304 1304
1305 acpi_os_free(string.pointer); 1305 kfree(string.pointer);
1306 return -1; 1306 return -1;
1307} 1307}
1308#endif 1308#endif
@@ -1404,9 +1404,6 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
1404 info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, 1404 info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device,
1405 pdev->subsystem_vendor, pdev->subsystem_device); 1405 pdev->subsystem_vendor, pdev->subsystem_device);
1406 1406
1407 if (pci_enable_device(pdev))
1408 goto abort_free_ctlr;
1409
1410 mutex_init(&ctrl->crit_sect); 1407 mutex_init(&ctrl->crit_sect);
1411 /* setup wait queue */ 1408 /* setup wait queue */
1412 init_waitqueue_head(&ctrl->queue); 1409 init_waitqueue_head(&ctrl->queue);
@@ -1474,7 +1471,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
1474 rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); 1471 rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
1475 if (rc) { 1472 if (rc) {
1476 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); 1473 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
1477 goto abort_free_ctlr; 1474 goto abort_free_irq;
1478 } 1475 }
1479 1476
1480 intr_enable = intr_enable | PRSN_DETECT_ENABLE; 1477 intr_enable = intr_enable | PRSN_DETECT_ENABLE;
@@ -1500,19 +1497,19 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
1500 rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); 1497 rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
1501 if (rc) { 1498 if (rc) {
1502 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); 1499 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
1503 goto abort_free_ctlr; 1500 goto abort_free_irq;
1504 } 1501 }
1505 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); 1502 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
1506 if (rc) { 1503 if (rc) {
1507 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); 1504 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
1508 goto abort_free_ctlr; 1505 goto abort_disable_intr;
1509 } 1506 }
1510 1507
1511 temp_word = 0x1F; /* Clear all events */ 1508 temp_word = 0x1F; /* Clear all events */
1512 rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); 1509 rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
1513 if (rc) { 1510 if (rc) {
1514 err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); 1511 err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
1515 goto abort_free_ctlr; 1512 goto abort_disable_intr;
1516 } 1513 }
1517 1514
1518 if (pciehp_force) { 1515 if (pciehp_force) {
@@ -1521,7 +1518,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
1521 } else { 1518 } else {
1522 rc = pciehp_get_hp_hw_control_from_firmware(ctrl->pci_dev); 1519 rc = pciehp_get_hp_hw_control_from_firmware(ctrl->pci_dev);
1523 if (rc) 1520 if (rc)
1524 goto abort_free_ctlr; 1521 goto abort_disable_intr;
1525 } 1522 }
1526 1523
1527 /* Add this HPC instance into the HPC list */ 1524 /* Add this HPC instance into the HPC list */
@@ -1548,6 +1545,21 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev)
1548 return 0; 1545 return 0;
1549 1546
1550 /* We end up here for the many possible ways to fail this API. */ 1547 /* We end up here for the many possible ways to fail this API. */
1548abort_disable_intr:
1549 rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
1550 if (!rc) {
1551 temp_word &= ~(intr_enable | HP_INTR_ENABLE);
1552 rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
1553 }
1554 if (rc)
1555 err("%s : disabling interrupts failed\n", __FUNCTION__);
1556
1557abort_free_irq:
1558 if (pciehp_poll_mode)
1559 del_timer_sync(&php_ctlr->int_poll_timer);
1560 else
1561 free_irq(php_ctlr->irq, ctrl);
1562
1551abort_free_ctlr: 1563abort_free_ctlr:
1552 pcie_cap_base = saved_cap_base; 1564 pcie_cap_base = saved_cap_base;
1553 kfree(php_ctlr); 1565 kfree(php_ctlr);
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
index 4017fb03a0b8..854aaea09e4d 100644
--- a/drivers/pci/hotplug/pciehp_pci.c
+++ b/drivers/pci/hotplug/pciehp_pci.c
@@ -34,6 +34,144 @@
34#include "../pci.h" 34#include "../pci.h"
35#include "pciehp.h" 35#include "pciehp.h"
36 36
37static void program_hpp_type0(struct pci_dev *dev, struct hpp_type0 *hpp)
38{
39 u16 pci_cmd, pci_bctl;
40
41 if (hpp->revision > 1) {
42 printk(KERN_WARNING "%s: Rev.%d type0 record not supported\n",
43 __FUNCTION__, hpp->revision);
44 return;
45 }
46
47 pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, hpp->cache_line_size);
48 pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp->latency_timer);
49 pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
50 if (hpp->enable_serr)
51 pci_cmd |= PCI_COMMAND_SERR;
52 else
53 pci_cmd &= ~PCI_COMMAND_SERR;
54 if (hpp->enable_perr)
55 pci_cmd |= PCI_COMMAND_PARITY;
56 else
57 pci_cmd &= ~PCI_COMMAND_PARITY;
58 pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
59
60 /* Program bridge control value */
61 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
62 pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,
63 hpp->latency_timer);
64 pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
65 if (hpp->enable_serr)
66 pci_bctl |= PCI_BRIDGE_CTL_SERR;
67 else
68 pci_bctl &= ~PCI_BRIDGE_CTL_SERR;
69 if (hpp->enable_perr)
70 pci_bctl |= PCI_BRIDGE_CTL_PARITY;
71 else
72 pci_bctl &= ~PCI_BRIDGE_CTL_PARITY;
73 pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl);
74 }
75}
76
77static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
78{
79 int pos;
80 u16 reg16;
81 u32 reg32;
82
83 if (hpp->revision > 1) {
84 printk(KERN_WARNING "%s: Rev.%d type2 record not supported\n",
85 __FUNCTION__, hpp->revision);
86 return;
87 }
88
89 /* Find PCI Express capability */
90 pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
91 if (!pos)
92 return;
93
94 /* Initialize Device Control Register */
95 pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &reg16);
96 reg16 = (reg16 & hpp->pci_exp_devctl_and) | hpp->pci_exp_devctl_or;
97 pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, reg16);
98
99 /* Initialize Link Control Register */
100 if (dev->subordinate) {
101 pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &reg16);
102 reg16 = (reg16 & hpp->pci_exp_lnkctl_and)
103 | hpp->pci_exp_lnkctl_or;
104 pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, reg16);
105 }
106
107 /* Find Advanced Error Reporting Enhanced Capability */
108 pos = 256;
109 do {
110 pci_read_config_dword(dev, pos, &reg32);
111 if (PCI_EXT_CAP_ID(reg32) == PCI_EXT_CAP_ID_ERR)
112 break;
113 } while ((pos = PCI_EXT_CAP_NEXT(reg32)));
114 if (!pos)
115 return;
116
117 /* Initialize Uncorrectable Error Mask Register */
118 pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, &reg32);
119 reg32 = (reg32 & hpp->unc_err_mask_and) | hpp->unc_err_mask_or;
120 pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, reg32);
121
122 /* Initialize Uncorrectable Error Severity Register */
123 pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &reg32);
124 reg32 = (reg32 & hpp->unc_err_sever_and) | hpp->unc_err_sever_or;
125 pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, reg32);
126
127 /* Initialize Correctable Error Mask Register */
128 pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, &reg32);
129 reg32 = (reg32 & hpp->cor_err_mask_and) | hpp->cor_err_mask_or;
130 pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg32);
131
132 /* Initialize Advanced Error Capabilities and Control Register */
133 pci_read_config_dword(dev, pos + PCI_ERR_CAP, &reg32);
134 reg32 = (reg32 & hpp->adv_err_cap_and) | hpp->adv_err_cap_or;
135 pci_write_config_dword(dev, pos + PCI_ERR_CAP, reg32);
136
137 /*
138 * FIXME: The following two registers are not supported yet.
139 *
140 * o Secondary Uncorrectable Error Severity Register
141 * o Secondary Uncorrectable Error Mask Register
142 */
143}
144
145static void program_fw_provided_values(struct pci_dev *dev)
146{
147 struct pci_dev *cdev;
148 struct hotplug_params hpp;
149
150 /* Program hpp values for this device */
151 if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL ||
152 (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
153 (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
154 return;
155
156 if (pciehp_get_hp_params_from_firmware(dev, &hpp)) {
157 printk(KERN_WARNING "%s: Could not get hotplug parameters\n",
158 __FUNCTION__);
159 return;
160 }
161
162 if (hpp.t2)
163 program_hpp_type2(dev, hpp.t2);
164 if (hpp.t0)
165 program_hpp_type0(dev, hpp.t0);
166
167 /* Program child devices */
168 if (dev->subordinate) {
169 list_for_each_entry(cdev, &dev->subordinate->devices,
170 bus_list)
171 program_fw_provided_values(cdev);
172 }
173}
174
37static int pciehp_add_bridge(struct pci_dev *dev) 175static int pciehp_add_bridge(struct pci_dev *dev)
38{ 176{
39 struct pci_bus *parent = dev->bus; 177 struct pci_bus *parent = dev->bus;
@@ -66,10 +204,11 @@ int pciehp_configure_device(struct slot *p_slot)
66 struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate; 204 struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
67 int num, fn; 205 int num, fn;
68 206
69 dev = pci_find_slot(p_slot->bus, PCI_DEVFN(p_slot->device, 0)); 207 dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0));
70 if (dev) { 208 if (dev) {
71 err("Device %s already exists at %x:%x, cannot hot-add\n", 209 err("Device %s already exists at %x:%x, cannot hot-add\n",
72 pci_name(dev), p_slot->bus, p_slot->device); 210 pci_name(dev), p_slot->bus, p_slot->device);
211 pci_dev_put(dev);
73 return -EINVAL; 212 return -EINVAL;
74 } 213 }
75 214
@@ -86,14 +225,15 @@ int pciehp_configure_device(struct slot *p_slot)
86 if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) { 225 if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
87 err("Cannot hot-add display device %s\n", 226 err("Cannot hot-add display device %s\n",
88 pci_name(dev)); 227 pci_name(dev));
228 pci_dev_put(dev);
89 continue; 229 continue;
90 } 230 }
91 if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || 231 if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
92 (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { 232 (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) {
93 pciehp_add_bridge(dev); 233 pciehp_add_bridge(dev);
94 } 234 }
95 /* TBD: program firmware provided _HPP values */ 235 program_fw_provided_values(dev);
96 /* program_fw_provided_values(dev); */ 236 pci_dev_put(dev);
97 } 237 }
98 238
99 pci_bus_assign_resources(parent); 239 pci_bus_assign_resources(parent);
@@ -106,18 +246,20 @@ int pciehp_unconfigure_device(struct slot *p_slot)
106 int rc = 0; 246 int rc = 0;
107 int j; 247 int j;
108 u8 bctl = 0; 248 u8 bctl = 0;
249 struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
109 250
110 dbg("%s: bus/dev = %x/%x\n", __FUNCTION__, p_slot->bus, 251 dbg("%s: bus/dev = %x/%x\n", __FUNCTION__, p_slot->bus,
111 p_slot->device); 252 p_slot->device);
112 253
113 for (j=0; j<8 ; j++) { 254 for (j=0; j<8 ; j++) {
114 struct pci_dev* temp = pci_find_slot(p_slot->bus, 255 struct pci_dev* temp = pci_get_slot(parent,
115 (p_slot->device << 3) | j); 256 (p_slot->device << 3) | j);
116 if (!temp) 257 if (!temp)
117 continue; 258 continue;
118 if ((temp->class >> 16) == PCI_BASE_CLASS_DISPLAY) { 259 if ((temp->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
119 err("Cannot remove display device %s\n", 260 err("Cannot remove display device %s\n",
120 pci_name(temp)); 261 pci_name(temp));
262 pci_dev_put(temp);
121 continue; 263 continue;
122 } 264 }
123 if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE) { 265 if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
@@ -125,10 +267,12 @@ int pciehp_unconfigure_device(struct slot *p_slot)
125 if (bctl & PCI_BRIDGE_CTL_VGA) { 267 if (bctl & PCI_BRIDGE_CTL_VGA) {
126 err("Cannot remove display device %s\n", 268 err("Cannot remove display device %s\n",
127 pci_name(temp)); 269 pci_name(temp));
270 pci_dev_put(temp);
128 continue; 271 continue;
129 } 272 }
130 } 273 }
131 pci_remove_bus_device(temp); 274 pci_remove_bus_device(temp);
275 pci_dev_put(temp);
132 } 276 }
133 /* 277 /*
134 * Some PCI Express root ports require fixup after hot-plug operation. 278 * Some PCI Express root ports require fixup after hot-plug operation.
diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c
index 8cb9abde736b..f31d83c2c633 100644
--- a/drivers/pci/hotplug/sgi_hotplug.c
+++ b/drivers/pci/hotplug/sgi_hotplug.c
@@ -18,11 +18,13 @@
18#include <linux/mutex.h> 18#include <linux/mutex.h>
19 19
20#include <asm/sn/addrs.h> 20#include <asm/sn/addrs.h>
21#include <asm/sn/geo.h>
21#include <asm/sn/l1.h> 22#include <asm/sn/l1.h>
22#include <asm/sn/module.h> 23#include <asm/sn/module.h>
23#include <asm/sn/pcibr_provider.h> 24#include <asm/sn/pcibr_provider.h>
24#include <asm/sn/pcibus_provider_defs.h> 25#include <asm/sn/pcibus_provider_defs.h>
25#include <asm/sn/pcidev.h> 26#include <asm/sn/pcidev.h>
27#include <asm/sn/sn_feature_sets.h>
26#include <asm/sn/sn_sal.h> 28#include <asm/sn/sn_sal.h>
27#include <asm/sn/types.h> 29#include <asm/sn/types.h>
28 30
@@ -102,8 +104,7 @@ static struct hotplug_slot_attribute sn_slot_path_attr = __ATTR_RO(path);
102static int sn_pci_slot_valid(struct pci_bus *pci_bus, int device) 104static int sn_pci_slot_valid(struct pci_bus *pci_bus, int device)
103{ 105{
104 struct pcibus_info *pcibus_info; 106 struct pcibus_info *pcibus_info;
105 int bricktype; 107 u16 busnum, segment, ioboard_type;
106 int bus_num;
107 108
108 pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus); 109 pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus);
109 110
@@ -111,12 +112,14 @@ static int sn_pci_slot_valid(struct pci_bus *pci_bus, int device)
111 if (!(pcibus_info->pbi_valid_devices & (1 << device))) 112 if (!(pcibus_info->pbi_valid_devices & (1 << device)))
112 return -EPERM; 113 return -EPERM;
113 114
114 bricktype = MODULE_GET_BTYPE(pcibus_info->pbi_moduleid); 115 ioboard_type = sn_ioboard_to_pci_bus(pci_bus);
115 bus_num = pcibus_info->pbi_buscommon.bs_persist_busnum & 0xf; 116 busnum = pcibus_info->pbi_buscommon.bs_persist_busnum;
117 segment = pci_domain_nr(pci_bus) & 0xf;
116 118
117 /* Do not allow hotplug operations on base I/O cards */ 119 /* Do not allow hotplug operations on base I/O cards */
118 if ((bricktype == L1_BRICKTYPE_IX || bricktype == L1_BRICKTYPE_IA) && 120 if ((ioboard_type == L1_BRICKTYPE_IX ||
119 (bus_num == 1 && device != 1)) 121 ioboard_type == L1_BRICKTYPE_IA) &&
122 (segment == 1 && busnum == 0 && device != 1))
120 return -EPERM; 123 return -EPERM;
121 124
122 return 1; 125 return 1;
@@ -125,23 +128,23 @@ static int sn_pci_slot_valid(struct pci_bus *pci_bus, int device)
125static int sn_pci_bus_valid(struct pci_bus *pci_bus) 128static int sn_pci_bus_valid(struct pci_bus *pci_bus)
126{ 129{
127 struct pcibus_info *pcibus_info; 130 struct pcibus_info *pcibus_info;
128 int asic_type; 131 u32 asic_type;
129 int bricktype; 132 u16 ioboard_type;
130
131 pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus);
132 133
133 /* Don't register slots hanging off the TIOCA bus */ 134 /* Don't register slots hanging off the TIOCA bus */
135 pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus);
134 asic_type = pcibus_info->pbi_buscommon.bs_asic_type; 136 asic_type = pcibus_info->pbi_buscommon.bs_asic_type;
135 if (asic_type == PCIIO_ASIC_TYPE_TIOCA) 137 if (asic_type == PCIIO_ASIC_TYPE_TIOCA)
136 return -EPERM; 138 return -EPERM;
137 139
138 /* Only register slots in I/O Bricks that support hotplug */ 140 /* Only register slots in I/O Bricks that support hotplug */
139 bricktype = MODULE_GET_BTYPE(pcibus_info->pbi_moduleid); 141 ioboard_type = sn_ioboard_to_pci_bus(pci_bus);
140 switch (bricktype) { 142 switch (ioboard_type) {
141 case L1_BRICKTYPE_IX: 143 case L1_BRICKTYPE_IX:
142 case L1_BRICKTYPE_PX: 144 case L1_BRICKTYPE_PX:
143 case L1_BRICKTYPE_IA: 145 case L1_BRICKTYPE_IA:
144 case L1_BRICKTYPE_PA: 146 case L1_BRICKTYPE_PA:
147 case L1_BOARDTYPE_PCIX3SLOT:
145 return 1; 148 return 1;
146 break; 149 break;
147 default: 150 default:
@@ -175,14 +178,11 @@ static int sn_hp_slot_private_alloc(struct hotplug_slot *bss_hotplug_slot,
175 slot->pci_bus = pci_bus; 178 slot->pci_bus = pci_bus;
176 sprintf(bss_hotplug_slot->name, "%04x:%02x:%02x", 179 sprintf(bss_hotplug_slot->name, "%04x:%02x:%02x",
177 pci_domain_nr(pci_bus), 180 pci_domain_nr(pci_bus),
178 ((int)pcibus_info->pbi_buscommon.bs_persist_busnum) & 0xf, 181 ((u16)pcibus_info->pbi_buscommon.bs_persist_busnum),
179 device + 1); 182 device + 1);
180 sprintf(slot->physical_path, "module_%c%c%c%c%.2d", 183
181 '0'+RACK_GET_CLASS(MODULE_GET_RACK(pcibus_info->pbi_moduleid)), 184 sn_generate_path(pci_bus, slot->physical_path);
182 '0'+RACK_GET_GROUP(MODULE_GET_RACK(pcibus_info->pbi_moduleid)), 185
183 '0'+RACK_GET_NUM(MODULE_GET_RACK(pcibus_info->pbi_moduleid)),
184 MODULE_GET_BTCHAR(pcibus_info->pbi_moduleid),
185 MODULE_GET_BPOS(pcibus_info->pbi_moduleid));
186 slot->hotplug_slot = bss_hotplug_slot; 186 slot->hotplug_slot = bss_hotplug_slot;
187 list_add(&slot->hp_list, &sn_hp_list); 187 list_add(&slot->hp_list, &sn_hp_list);
188 188
@@ -461,10 +461,12 @@ static inline int get_power_status(struct hotplug_slot *bss_hotplug_slot,
461{ 461{
462 struct slot *slot = bss_hotplug_slot->private; 462 struct slot *slot = bss_hotplug_slot->private;
463 struct pcibus_info *pcibus_info; 463 struct pcibus_info *pcibus_info;
464 u32 power;
464 465
465 pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus); 466 pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
466 mutex_lock(&sn_hotplug_mutex); 467 mutex_lock(&sn_hotplug_mutex);
467 *value = pcibus_info->pbi_enabled_devices & (1 << slot->device_num); 468 power = pcibus_info->pbi_enabled_devices & (1 << slot->device_num);
469 *value = power ? 1 : 0;
468 mutex_unlock(&sn_hotplug_mutex); 470 mutex_unlock(&sn_hotplug_mutex);
469 return 0; 471 return 0;
470} 472}
@@ -553,8 +555,8 @@ static int sn_pci_hotplug_init(void)
553 int rc; 555 int rc;
554 int registered = 0; 556 int registered = 0;
555 557
556 if (sn_sal_rev() < SGI_HOTPLUG_PROM_REV) { 558 if (!sn_prom_feature_available(PRF_HOTPLUG_SUPPORT)) {
557 printk(KERN_ERR "%s: PROM version must be greater than 4.30\n", 559 printk(KERN_ERR "%s: PROM version does not support hotplug.\n",
558 __FUNCTION__); 560 __FUNCTION__);
559 return -EPERM; 561 return -EPERM;
560 } 562 }
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
index 5c70f43908c4..7208b95c6ee7 100644
--- a/drivers/pci/hotplug/shpchp.h
+++ b/drivers/pci/hotplug/shpchp.h
@@ -168,9 +168,9 @@ struct controller {
168 * error Messages 168 * error Messages
169 */ 169 */
170#define msg_initialization_err "Initialization failure, error=%d\n" 170#define msg_initialization_err "Initialization failure, error=%d\n"
171#define msg_button_on "PCI slot #%d - powering on due to button press.\n" 171#define msg_button_on "PCI slot #%s - powering on due to button press.\n"
172#define msg_button_off "PCI slot #%d - powering off due to button press.\n" 172#define msg_button_off "PCI slot #%s - powering off due to button press.\n"
173#define msg_button_cancel "PCI slot #%d - action canceled due to button press.\n" 173#define msg_button_cancel "PCI slot #%s - action canceled due to button press.\n"
174 174
175/* sysfs functions for the hotplug controller info */ 175/* sysfs functions for the hotplug controller info */
176extern void shpchp_create_ctrl_files (struct controller *ctrl); 176extern void shpchp_create_ctrl_files (struct controller *ctrl);
@@ -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}
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c
index 3be4d492ccc2..a14e7de19846 100644
--- a/drivers/pci/hotplug/shpchp_core.c
+++ b/drivers/pci/hotplug/shpchp_core.c
@@ -491,16 +491,9 @@ static int __init shpcd_init(void)
491 shpchp_poll_mode = 1; 491 shpchp_poll_mode = 1;
492#endif 492#endif
493 493
494 shpchp_wq = create_singlethread_workqueue("shpchpd");
495 if (!shpchp_wq)
496 return -ENOMEM;
497
498 retval = pci_register_driver(&shpc_driver); 494 retval = pci_register_driver(&shpc_driver);
499 dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval); 495 dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval);
500 info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); 496 info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
501 if (retval) {
502 destroy_workqueue(shpchp_wq);
503 }
504 return retval; 497 return retval;
505} 498}
506 499
@@ -508,7 +501,6 @@ static void __exit shpcd_cleanup(void)
508{ 501{
509 dbg("unload_shpchpd()\n"); 502 dbg("unload_shpchpd()\n");
510 pci_unregister_driver(&shpc_driver); 503 pci_unregister_driver(&shpc_driver);
511 destroy_workqueue(shpchp_wq);
512 info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n"); 504 info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n");
513} 505}
514 506
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
index 4e6381481c55..c39901dbff20 100644
--- a/drivers/pci/hotplug/shpchp_ctrl.c
+++ b/drivers/pci/hotplug/shpchp_ctrl.c
@@ -72,7 +72,7 @@ u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id)
72 /* 72 /*
73 * Button pressed - See if need to TAKE ACTION!!! 73 * Button pressed - See if need to TAKE ACTION!!!
74 */ 74 */
75 info("Button pressed on Slot(%d)\n", ctrl->first_slot + hp_slot); 75 info("Button pressed on Slot(%s)\n", p_slot->name);
76 event_type = INT_BUTTON_PRESS; 76 event_type = INT_BUTTON_PRESS;
77 77
78 queue_interrupt_event(p_slot, event_type); 78 queue_interrupt_event(p_slot, event_type);
@@ -101,7 +101,7 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id)
101 /* 101 /*
102 * Switch opened 102 * Switch opened
103 */ 103 */
104 info("Latch open on Slot(%d)\n", ctrl->first_slot + hp_slot); 104 info("Latch open on Slot(%s)\n", p_slot->name);
105 event_type = INT_SWITCH_OPEN; 105 event_type = INT_SWITCH_OPEN;
106 if (p_slot->pwr_save && p_slot->presence_save) { 106 if (p_slot->pwr_save && p_slot->presence_save) {
107 event_type = INT_POWER_FAULT; 107 event_type = INT_POWER_FAULT;
@@ -111,7 +111,7 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id)
111 /* 111 /*
112 * Switch closed 112 * Switch closed
113 */ 113 */
114 info("Latch close on Slot(%d)\n", ctrl->first_slot + hp_slot); 114 info("Latch close on Slot(%s)\n", p_slot->name);
115 event_type = INT_SWITCH_CLOSE; 115 event_type = INT_SWITCH_CLOSE;
116 } 116 }
117 117
@@ -139,13 +139,13 @@ u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id)
139 /* 139 /*
140 * Card Present 140 * Card Present
141 */ 141 */
142 info("Card present on Slot(%d)\n", ctrl->first_slot + hp_slot); 142 info("Card present on Slot(%s)\n", p_slot->name);
143 event_type = INT_PRESENCE_ON; 143 event_type = INT_PRESENCE_ON;
144 } else { 144 } else {
145 /* 145 /*
146 * Not Present 146 * Not Present
147 */ 147 */
148 info("Card not present on Slot(%d)\n", ctrl->first_slot + hp_slot); 148 info("Card not present on Slot(%s)\n", p_slot->name);
149 event_type = INT_PRESENCE_OFF; 149 event_type = INT_PRESENCE_OFF;
150 } 150 }
151 151
@@ -169,14 +169,14 @@ u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id)
169 /* 169 /*
170 * Power fault Cleared 170 * Power fault Cleared
171 */ 171 */
172 info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot); 172 info("Power fault cleared on Slot(%s)\n", p_slot->name);
173 p_slot->status = 0x00; 173 p_slot->status = 0x00;
174 event_type = INT_POWER_FAULT_CLEAR; 174 event_type = INT_POWER_FAULT_CLEAR;
175 } else { 175 } else {
176 /* 176 /*
177 * Power fault 177 * Power fault
178 */ 178 */
179 info("Power fault on Slot(%d)\n", ctrl->first_slot + hp_slot); 179 info("Power fault on Slot(%s)\n", p_slot->name);
180 event_type = INT_POWER_FAULT; 180 event_type = INT_POWER_FAULT;
181 /* set power fault status for this board */ 181 /* set power fault status for this board */
182 p_slot->status = 0xFF; 182 p_slot->status = 0xFF;
@@ -496,10 +496,10 @@ static void handle_button_press_event(struct slot *p_slot)
496 p_slot->hpc_ops->get_power_status(p_slot, &getstatus); 496 p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
497 if (getstatus) { 497 if (getstatus) {
498 p_slot->state = BLINKINGOFF_STATE; 498 p_slot->state = BLINKINGOFF_STATE;
499 info(msg_button_off, p_slot->number); 499 info(msg_button_off, p_slot->name);
500 } else { 500 } else {
501 p_slot->state = BLINKINGON_STATE; 501 p_slot->state = BLINKINGON_STATE;
502 info(msg_button_on, p_slot->number); 502 info(msg_button_on, p_slot->name);
503 } 503 }
504 /* blink green LED and turn off amber */ 504 /* blink green LED and turn off amber */
505 p_slot->hpc_ops->green_led_blink(p_slot); 505 p_slot->hpc_ops->green_led_blink(p_slot);
@@ -522,7 +522,7 @@ static void handle_button_press_event(struct slot *p_slot)
522 else 522 else
523 p_slot->hpc_ops->green_led_off(p_slot); 523 p_slot->hpc_ops->green_led_off(p_slot);
524 p_slot->hpc_ops->set_attention_status(p_slot, 0); 524 p_slot->hpc_ops->set_attention_status(p_slot, 0);
525 info(msg_button_cancel, p_slot->number); 525 info(msg_button_cancel, p_slot->name);
526 p_slot->state = STATIC_STATE; 526 p_slot->state = STATIC_STATE;
527 break; 527 break;
528 case POWEROFF_STATE: 528 case POWEROFF_STATE:
@@ -575,17 +575,17 @@ static int shpchp_enable_slot (struct slot *p_slot)
575 mutex_lock(&p_slot->ctrl->crit_sect); 575 mutex_lock(&p_slot->ctrl->crit_sect);
576 rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); 576 rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
577 if (rc || !getstatus) { 577 if (rc || !getstatus) {
578 info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); 578 info("No adapter on slot(%s)\n", p_slot->name);
579 goto out; 579 goto out;
580 } 580 }
581 rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 581 rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
582 if (rc || getstatus) { 582 if (rc || getstatus) {
583 info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); 583 info("Latch open on slot(%s)\n", p_slot->name);
584 goto out; 584 goto out;
585 } 585 }
586 rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); 586 rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
587 if (rc || getstatus) { 587 if (rc || getstatus) {
588 info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number); 588 info("Already enabled on slot(%s)\n", p_slot->name);
589 goto out; 589 goto out;
590 } 590 }
591 591
@@ -634,17 +634,17 @@ static int shpchp_disable_slot (struct slot *p_slot)
634 634
635 rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); 635 rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
636 if (rc || !getstatus) { 636 if (rc || !getstatus) {
637 info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); 637 info("No adapter on slot(%s)\n", p_slot->name);
638 goto out; 638 goto out;
639 } 639 }
640 rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 640 rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
641 if (rc || getstatus) { 641 if (rc || getstatus) {
642 info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); 642 info("Latch open on slot(%s)\n", p_slot->name);
643 goto out; 643 goto out;
644 } 644 }
645 rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); 645 rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
646 if (rc || !getstatus) { 646 if (rc || !getstatus) {
647 info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number); 647 info("Already disabled slot(%s)\n", p_slot->name);
648 goto out; 648 goto out;
649 } 649 }
650 650
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c
index 66123cf4deaa..45facaad39bd 100644
--- a/drivers/pci/hotplug/shpchp_hpc.c
+++ b/drivers/pci/hotplug/shpchp_hpc.c
@@ -90,77 +90,94 @@
90#define MRLSENSOR 0x40000000 90#define MRLSENSOR 0x40000000
91#define ATTN_BUTTON 0x80000000 91#define ATTN_BUTTON 0x80000000
92 92
93/* Slot Status Field Definitions */ 93/*
94/* Slot State */ 94 * Interrupt Locator Register definitions
95#define PWR_ONLY 0x0001 95 */
96#define ENABLED 0x0002 96#define CMD_INTR_PENDING (1 << 0)
97#define DISABLED 0x0003 97#define SLOT_INTR_PENDING(i) (1 << (i + 1))
98
99/* Power Indicator State */
100#define PWR_LED_ON 0x0004
101#define PWR_LED_BLINK 0x0008
102#define PWR_LED_OFF 0x000c
103
104/* Attention Indicator State */
105#define ATTEN_LED_ON 0x0010
106#define ATTEN_LED_BLINK 0x0020
107#define ATTEN_LED_OFF 0x0030
108
109/* Power Fault */
110#define pwr_fault 0x0040
111
112/* Attention Button */
113#define ATTEN_BUTTON 0x0080
114
115/* MRL Sensor */
116#define MRL_SENSOR 0x0100
117
118/* 66 MHz Capable */
119#define IS_66MHZ_CAP 0x0200
120
121/* PRSNT1#/PRSNT2# */
122#define SLOT_EMP 0x0c00
123
124/* PCI-X Capability */
125#define NON_PCIX 0x0000
126#define PCIX_66 0x1000
127#define PCIX_133 0x3000
128#define PCIX_266 0x4000 /* For PI = 2 only */
129#define PCIX_533 0x5000 /* For PI = 2 only */
130
131/* SHPC 'write' operations/commands */
132
133/* Slot operation - 0x00h to 0x3Fh */
134
135#define NO_CHANGE 0x00
136
137/* Slot state - Bits 0 & 1 of controller command register */
138#define SET_SLOT_PWR 0x01
139#define SET_SLOT_ENABLE 0x02
140#define SET_SLOT_DISABLE 0x03
141 98
142/* Power indicator state - Bits 2 & 3 of controller command register*/ 99/*
143#define SET_PWR_ON 0x04 100 * Controller SERR-INT Register
144#define SET_PWR_BLINK 0x08 101 */
145#define SET_PWR_OFF 0x0C 102#define GLOBAL_INTR_MASK (1 << 0)
103#define GLOBAL_SERR_MASK (1 << 1)
104#define COMMAND_INTR_MASK (1 << 2)
105#define ARBITER_SERR_MASK (1 << 3)
106#define COMMAND_DETECTED (1 << 16)
107#define ARBITER_DETECTED (1 << 17)
108#define SERR_INTR_RSVDZ_MASK 0xfffc0000
146 109
147/* Attention indicator state - Bits 4 & 5 of controller command register*/ 110/*
148#define SET_ATTN_ON 0x010 111 * Logical Slot Register definitions
149#define SET_ATTN_BLINK 0x020 112 */
150#define SET_ATTN_OFF 0x030 113#define SLOT_REG(i) (SLOT1 + (4 * i))
114
115#define SLOT_STATE_SHIFT (0)
116#define SLOT_STATE_MASK (3 << 0)
117#define SLOT_STATE_PWRONLY (1)
118#define SLOT_STATE_ENABLED (2)
119#define SLOT_STATE_DISABLED (3)
120#define PWR_LED_STATE_SHIFT (2)
121#define PWR_LED_STATE_MASK (3 << 2)
122#define ATN_LED_STATE_SHIFT (4)
123#define ATN_LED_STATE_MASK (3 << 4)
124#define ATN_LED_STATE_ON (1)
125#define ATN_LED_STATE_BLINK (2)
126#define ATN_LED_STATE_OFF (3)
127#define POWER_FAULT (1 << 6)
128#define ATN_BUTTON (1 << 7)
129#define MRL_SENSOR (1 << 8)
130#define MHZ66_CAP (1 << 9)
131#define PRSNT_SHIFT (10)
132#define PRSNT_MASK (3 << 10)
133#define PCIX_CAP_SHIFT (12)
134#define PCIX_CAP_MASK_PI1 (3 << 12)
135#define PCIX_CAP_MASK_PI2 (7 << 12)
136#define PRSNT_CHANGE_DETECTED (1 << 16)
137#define ISO_PFAULT_DETECTED (1 << 17)
138#define BUTTON_PRESS_DETECTED (1 << 18)
139#define MRL_CHANGE_DETECTED (1 << 19)
140#define CON_PFAULT_DETECTED (1 << 20)
141#define PRSNT_CHANGE_INTR_MASK (1 << 24)
142#define ISO_PFAULT_INTR_MASK (1 << 25)
143#define BUTTON_PRESS_INTR_MASK (1 << 26)
144#define MRL_CHANGE_INTR_MASK (1 << 27)
145#define CON_PFAULT_INTR_MASK (1 << 28)
146#define MRL_CHANGE_SERR_MASK (1 << 29)
147#define CON_PFAULT_SERR_MASK (1 << 30)
148#define SLOT_REG_RSVDZ_MASK (1 << 15) | (7 << 21)
151 149
152/* Set bus speed/mode A - 0x40h to 0x47h */ 150/*
153#define SETA_PCI_33MHZ 0x40 151 * SHPC Command Code definitnions
152 *
153 * Slot Operation 00h - 3Fh
154 * Set Bus Segment Speed/Mode A 40h - 47h
155 * Power-Only All Slots 48h
156 * Enable All Slots 49h
157 * Set Bus Segment Speed/Mode B (PI=2) 50h - 5Fh
158 * Reserved Command Codes 60h - BFh
159 * Vendor Specific Commands C0h - FFh
160 */
161#define SET_SLOT_PWR 0x01 /* Slot Operation */
162#define SET_SLOT_ENABLE 0x02
163#define SET_SLOT_DISABLE 0x03
164#define SET_PWR_ON 0x04
165#define SET_PWR_BLINK 0x08
166#define SET_PWR_OFF 0x0c
167#define SET_ATTN_ON 0x10
168#define SET_ATTN_BLINK 0x20
169#define SET_ATTN_OFF 0x30
170#define SETA_PCI_33MHZ 0x40 /* Set Bus Segment Speed/Mode A */
154#define SETA_PCI_66MHZ 0x41 171#define SETA_PCI_66MHZ 0x41
155#define SETA_PCIX_66MHZ 0x42 172#define SETA_PCIX_66MHZ 0x42
156#define SETA_PCIX_100MHZ 0x43 173#define SETA_PCIX_100MHZ 0x43
157#define SETA_PCIX_133MHZ 0x44 174#define SETA_PCIX_133MHZ 0x44
158#define RESERV_1 0x45 175#define SETA_RESERVED1 0x45
159#define RESERV_2 0x46 176#define SETA_RESERVED2 0x46
160#define RESERV_3 0x47 177#define SETA_RESERVED3 0x47
161 178#define SET_PWR_ONLY_ALL 0x48 /* Power-Only All Slots */
162/* Set bus speed/mode B - 0x50h to 0x5fh */ 179#define SET_ENABLE_ALL 0x49 /* Enable All Slots */
163#define SETB_PCI_33MHZ 0x50 180#define SETB_PCI_33MHZ 0x50 /* Set Bus Segment Speed/Mode B */
164#define SETB_PCI_66MHZ 0x51 181#define SETB_PCI_66MHZ 0x51
165#define SETB_PCIX_66MHZ_PM 0x52 182#define SETB_PCIX_66MHZ_PM 0x52
166#define SETB_PCIX_100MHZ_PM 0x53 183#define SETB_PCIX_100MHZ_PM 0x53
@@ -174,81 +191,115 @@
174#define SETB_PCIX_66MHZ_533 0x5b 191#define SETB_PCIX_66MHZ_533 0x5b
175#define SETB_PCIX_100MHZ_533 0x5c 192#define SETB_PCIX_100MHZ_533 0x5c
176#define SETB_PCIX_133MHZ_533 0x5d 193#define SETB_PCIX_133MHZ_533 0x5d
194#define SETB_RESERVED1 0x5e
195#define SETB_RESERVED2 0x5f
177 196
178 197/*
179/* Power-on all slots - 0x48h */ 198 * SHPC controller command error code
180#define SET_PWR_ON_ALL 0x48 199 */
181
182/* Enable all slots - 0x49h */
183#define SET_ENABLE_ALL 0x49
184
185/* SHPC controller command error code */
186#define SWITCH_OPEN 0x1 200#define SWITCH_OPEN 0x1
187#define INVALID_CMD 0x2 201#define INVALID_CMD 0x2
188#define INVALID_SPEED_MODE 0x4 202#define INVALID_SPEED_MODE 0x4
189 203
190/* For accessing SHPC Working Register Set */ 204/*
205 * For accessing SHPC Working Register Set via PCI Configuration Space
206 */
191#define DWORD_SELECT 0x2 207#define DWORD_SELECT 0x2
192#define DWORD_DATA 0x4 208#define DWORD_DATA 0x4
193#define BASE_OFFSET 0x0
194 209
195/* Field Offset in Logical Slot Register - byte boundary */ 210/* Field Offset in Logical Slot Register - byte boundary */
196#define SLOT_EVENT_LATCH 0x2 211#define SLOT_EVENT_LATCH 0x2
197#define SLOT_SERR_INT_MASK 0x3 212#define SLOT_SERR_INT_MASK 0x3
198 213
199static spinlock_t hpc_event_lock;
200
201DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */ 214DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */
202static struct php_ctlr_state_s *php_ctlr_list_head; /* HPC state linked list */ 215static struct php_ctlr_state_s *php_ctlr_list_head; /* HPC state linked list */
203static int ctlr_seq_num = 0; /* Controller sequenc # */ 216static int ctlr_seq_num = 0; /* Controller sequenc # */
204static spinlock_t list_lock; 217static spinlock_t list_lock;
205 218
206static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs); 219static atomic_t shpchp_num_controllers = ATOMIC_INIT(0);
207 220
208static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds); 221static irqreturn_t shpc_isr(int irq, void *dev_id, struct pt_regs *regs);
222static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int sec);
209static int hpc_check_cmd_status(struct controller *ctrl); 223static int hpc_check_cmd_status(struct controller *ctrl);
210 224
211/* This is the interrupt polling timeout function. */ 225static inline u8 shpc_readb(struct controller *ctrl, int reg)
212static void int_poll_timeout(unsigned long lphp_ctlr)
213{ 226{
214 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *)lphp_ctlr; 227 return readb(ctrl->hpc_ctlr_handle->creg + reg);
228}
215 229
216 DBG_ENTER_ROUTINE 230static inline void shpc_writeb(struct controller *ctrl, int reg, u8 val)
231{
232 writeb(val, ctrl->hpc_ctlr_handle->creg + reg);
233}
217 234
218 if ( !php_ctlr ) { 235static inline u16 shpc_readw(struct controller *ctrl, int reg)
219 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 236{
220 return; 237 return readw(ctrl->hpc_ctlr_handle->creg + reg);
221 } 238}
222 239
223 /* Poll for interrupt events. regs == NULL => polling */ 240static inline void shpc_writew(struct controller *ctrl, int reg, u16 val)
224 shpc_isr( 0, (void *)php_ctlr, NULL ); 241{
242 writew(val, ctrl->hpc_ctlr_handle->creg + reg);
243}
225 244
226 init_timer(&php_ctlr->int_poll_timer); 245static inline u32 shpc_readl(struct controller *ctrl, int reg)
227 if (!shpchp_poll_time) 246{
228 shpchp_poll_time = 2; /* reset timer to poll in 2 secs if user doesn't specify at module installation*/ 247 return readl(ctrl->hpc_ctlr_handle->creg + reg);
248}
229 249
230 start_int_poll_timer(php_ctlr, shpchp_poll_time); 250static inline void shpc_writel(struct controller *ctrl, int reg, u32 val)
231 251{
232 return; 252 writel(val, ctrl->hpc_ctlr_handle->creg + reg);
233} 253}
234 254
235/* This function starts the interrupt polling timer. */ 255static inline int shpc_indirect_read(struct controller *ctrl, int index,
236static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds) 256 u32 *value)
237{ 257{
238 if (!php_ctlr) { 258 int rc;
239 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 259 u32 cap_offset = ctrl->cap_offset;
240 return; 260 struct pci_dev *pdev = ctrl->pci_dev;
241 } 261
262 rc = pci_write_config_byte(pdev, cap_offset + DWORD_SELECT, index);
263 if (rc)
264 return rc;
265 return pci_read_config_dword(pdev, cap_offset + DWORD_DATA, value);
266}
267
268/*
269 * This is the interrupt polling timeout function.
270 */
271static void int_poll_timeout(unsigned long lphp_ctlr)
272{
273 struct php_ctlr_state_s *php_ctlr =
274 (struct php_ctlr_state_s *)lphp_ctlr;
275
276 DBG_ENTER_ROUTINE
277
278 /* Poll for interrupt events. regs == NULL => polling */
279 shpc_isr(0, php_ctlr->callback_instance_id, NULL);
280
281 init_timer(&php_ctlr->int_poll_timer);
282 if (!shpchp_poll_time)
283 shpchp_poll_time = 2; /* default polling interval is 2 sec */
242 284
243 if ( ( seconds <= 0 ) || ( seconds > 60 ) ) 285 start_int_poll_timer(php_ctlr, shpchp_poll_time);
244 seconds = 2; /* Clamp to sane value */
245 286
246 php_ctlr->int_poll_timer.function = &int_poll_timeout; 287 DBG_LEAVE_ROUTINE
247 php_ctlr->int_poll_timer.data = (unsigned long)php_ctlr; /* Instance data */ 288}
248 php_ctlr->int_poll_timer.expires = jiffies + seconds * HZ;
249 add_timer(&php_ctlr->int_poll_timer);
250 289
251 return; 290/*
291 * This function starts the interrupt polling timer.
292 */
293static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int sec)
294{
295 /* Clamp to sane value */
296 if ((sec <= 0) || (sec > 60))
297 sec = 2;
298
299 php_ctlr->int_poll_timer.function = &int_poll_timeout;
300 php_ctlr->int_poll_timer.data = (unsigned long)php_ctlr;
301 php_ctlr->int_poll_timer.expires = jiffies + sec * HZ;
302 add_timer(&php_ctlr->int_poll_timer);
252} 303}
253 304
254static inline int shpc_wait_cmd(struct controller *ctrl) 305static inline int shpc_wait_cmd(struct controller *ctrl)
@@ -272,7 +323,7 @@ static inline int shpc_wait_cmd(struct controller *ctrl)
272 323
273static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) 324static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
274{ 325{
275 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; 326 struct controller *ctrl = slot->ctrl;
276 u16 cmd_status; 327 u16 cmd_status;
277 int retval = 0; 328 int retval = 0;
278 u16 temp_word; 329 u16 temp_word;
@@ -282,14 +333,8 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
282 333
283 mutex_lock(&slot->ctrl->cmd_lock); 334 mutex_lock(&slot->ctrl->cmd_lock);
284 335
285 if (!php_ctlr) {
286 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
287 retval = -EINVAL;
288 goto out;
289 }
290
291 for (i = 0; i < 10; i++) { 336 for (i = 0; i < 10; i++) {
292 cmd_status = readw(php_ctlr->creg + CMD_STATUS); 337 cmd_status = shpc_readw(ctrl, CMD_STATUS);
293 338
294 if (!(cmd_status & 0x1)) 339 if (!(cmd_status & 0x1))
295 break; 340 break;
@@ -297,7 +342,7 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
297 msleep(100); 342 msleep(100);
298 } 343 }
299 344
300 cmd_status = readw(php_ctlr->creg + CMD_STATUS); 345 cmd_status = shpc_readw(ctrl, CMD_STATUS);
301 346
302 if (cmd_status & 0x1) { 347 if (cmd_status & 0x1) {
303 /* After 1 sec and and the controller is still busy */ 348 /* After 1 sec and and the controller is still busy */
@@ -314,7 +359,7 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
314 * command. 359 * command.
315 */ 360 */
316 slot->ctrl->cmd_busy = 1; 361 slot->ctrl->cmd_busy = 1;
317 writew(temp_word, php_ctlr->creg + CMD); 362 shpc_writew(ctrl, CMD, temp_word);
318 363
319 /* 364 /*
320 * Wait for command completion. 365 * Wait for command completion.
@@ -338,18 +383,12 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
338 383
339static int hpc_check_cmd_status(struct controller *ctrl) 384static int hpc_check_cmd_status(struct controller *ctrl)
340{ 385{
341 struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
342 u16 cmd_status; 386 u16 cmd_status;
343 int retval = 0; 387 int retval = 0;
344 388
345 DBG_ENTER_ROUTINE 389 DBG_ENTER_ROUTINE
346
347 if (!ctrl->hpc_ctlr_handle) {
348 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
349 return -1;
350 }
351 390
352 cmd_status = readw(php_ctlr->creg + CMD_STATUS) & 0x000F; 391 cmd_status = shpc_readw(ctrl, CMD_STATUS) & 0x000F;
353 392
354 switch (cmd_status >> 1) { 393 switch (cmd_status >> 1) {
355 case 0: 394 case 0:
@@ -378,37 +417,27 @@ static int hpc_check_cmd_status(struct controller *ctrl)
378 417
379static int hpc_get_attention_status(struct slot *slot, u8 *status) 418static int hpc_get_attention_status(struct slot *slot, u8 *status)
380{ 419{
381 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; 420 struct controller *ctrl = slot->ctrl;
382 u32 slot_reg; 421 u32 slot_reg;
383 u16 slot_status; 422 u8 state;
384 u8 atten_led_state;
385 423
386 DBG_ENTER_ROUTINE 424 DBG_ENTER_ROUTINE
387 425
388 if (!slot->ctrl->hpc_ctlr_handle) { 426 slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot));
389 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 427 state = (slot_reg & ATN_LED_STATE_MASK) >> ATN_LED_STATE_SHIFT;
390 return -1;
391 }
392
393 slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot));
394 slot_status = (u16) slot_reg;
395 atten_led_state = (slot_status & 0x0030) >> 4;
396 428
397 switch (atten_led_state) { 429 switch (state) {
398 case 0: 430 case ATN_LED_STATE_ON:
399 *status = 0xFF; /* Reserved */
400 break;
401 case 1:
402 *status = 1; /* On */ 431 *status = 1; /* On */
403 break; 432 break;
404 case 2: 433 case ATN_LED_STATE_BLINK:
405 *status = 2; /* Blink */ 434 *status = 2; /* Blink */
406 break; 435 break;
407 case 3: 436 case ATN_LED_STATE_OFF:
408 *status = 0; /* Off */ 437 *status = 0; /* Off */
409 break; 438 break;
410 default: 439 default:
411 *status = 0xFF; 440 *status = 0xFF; /* Reserved */
412 break; 441 break;
413 } 442 }
414 443
@@ -418,64 +447,44 @@ static int hpc_get_attention_status(struct slot *slot, u8 *status)
418 447
419static int hpc_get_power_status(struct slot * slot, u8 *status) 448static int hpc_get_power_status(struct slot * slot, u8 *status)
420{ 449{
421 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; 450 struct controller *ctrl = slot->ctrl;
422 u32 slot_reg; 451 u32 slot_reg;
423 u16 slot_status; 452 u8 state;
424 u8 slot_state;
425 int retval = 0;
426 453
427 DBG_ENTER_ROUTINE 454 DBG_ENTER_ROUTINE
428 455
429 if (!slot->ctrl->hpc_ctlr_handle) { 456 slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot));
430 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 457 state = (slot_reg & SLOT_STATE_MASK) >> SLOT_STATE_SHIFT;
431 return -1;
432 }
433
434 slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot));
435 slot_status = (u16) slot_reg;
436 slot_state = (slot_status & 0x0003);
437 458
438 switch (slot_state) { 459 switch (state) {
439 case 0: 460 case SLOT_STATE_PWRONLY:
440 *status = 0xFF;
441 break;
442 case 1:
443 *status = 2; /* Powered only */ 461 *status = 2; /* Powered only */
444 break; 462 break;
445 case 2: 463 case SLOT_STATE_ENABLED:
446 *status = 1; /* Enabled */ 464 *status = 1; /* Enabled */
447 break; 465 break;
448 case 3: 466 case SLOT_STATE_DISABLED:
449 *status = 0; /* Disabled */ 467 *status = 0; /* Disabled */
450 break; 468 break;
451 default: 469 default:
452 *status = 0xFF; 470 *status = 0xFF; /* Reserved */
453 break; 471 break;
454 } 472 }
455 473
456 DBG_LEAVE_ROUTINE 474 DBG_LEAVE_ROUTINE
457 return retval; 475 return 0;
458} 476}
459 477
460 478
461static int hpc_get_latch_status(struct slot *slot, u8 *status) 479static int hpc_get_latch_status(struct slot *slot, u8 *status)
462{ 480{
463 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; 481 struct controller *ctrl = slot->ctrl;
464 u32 slot_reg; 482 u32 slot_reg;
465 u16 slot_status;
466 483
467 DBG_ENTER_ROUTINE 484 DBG_ENTER_ROUTINE
468 485
469 if (!slot->ctrl->hpc_ctlr_handle) { 486 slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot));
470 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 487 *status = !!(slot_reg & MRL_SENSOR); /* 0 -> close; 1 -> open */
471 return -1;
472 }
473
474 slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot));
475 slot_status = (u16)slot_reg;
476
477 *status = ((slot_status & 0x0100) == 0) ? 0 : 1; /* 0 -> close; 1 -> open */
478
479 488
480 DBG_LEAVE_ROUTINE 489 DBG_LEAVE_ROUTINE
481 return 0; 490 return 0;
@@ -483,22 +492,15 @@ static int hpc_get_latch_status(struct slot *slot, u8 *status)
483 492
484static int hpc_get_adapter_status(struct slot *slot, u8 *status) 493static int hpc_get_adapter_status(struct slot *slot, u8 *status)
485{ 494{
486 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; 495 struct controller *ctrl = slot->ctrl;
487 u32 slot_reg; 496 u32 slot_reg;
488 u16 slot_status; 497 u8 state;
489 u8 card_state;
490 498
491 DBG_ENTER_ROUTINE 499 DBG_ENTER_ROUTINE
492 500
493 if (!slot->ctrl->hpc_ctlr_handle) { 501 slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot));
494 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 502 state = (slot_reg & PRSNT_MASK) >> PRSNT_SHIFT;
495 return -1; 503 *status = (state != 0x3) ? 1 : 0;
496 }
497
498 slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot));
499 slot_status = (u16)slot_reg;
500 card_state = (u8)((slot_status & 0x0C00) >> 10);
501 *status = (card_state != 0x3) ? 1 : 0;
502 504
503 DBG_LEAVE_ROUTINE 505 DBG_LEAVE_ROUTINE
504 return 0; 506 return 0;
@@ -506,16 +508,11 @@ static int hpc_get_adapter_status(struct slot *slot, u8 *status)
506 508
507static int hpc_get_prog_int(struct slot *slot, u8 *prog_int) 509static int hpc_get_prog_int(struct slot *slot, u8 *prog_int)
508{ 510{
509 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; 511 struct controller *ctrl = slot->ctrl;
510 512
511 DBG_ENTER_ROUTINE 513 DBG_ENTER_ROUTINE
512
513 if (!slot->ctrl->hpc_ctlr_handle) {
514 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
515 return -1;
516 }
517 514
518 *prog_int = readb(php_ctlr->creg + PROG_INTERFACE); 515 *prog_int = shpc_readb(ctrl, PROG_INTERFACE);
519 516
520 DBG_LEAVE_ROUTINE 517 DBG_LEAVE_ROUTINE
521 return 0; 518 return 0;
@@ -524,13 +521,27 @@ static int hpc_get_prog_int(struct slot *slot, u8 *prog_int)
524static int hpc_get_adapter_speed(struct slot *slot, enum pci_bus_speed *value) 521static int hpc_get_adapter_speed(struct slot *slot, enum pci_bus_speed *value)
525{ 522{
526 int retval = 0; 523 int retval = 0;
527 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; 524 struct controller *ctrl = slot->ctrl;
528 u32 slot_reg = readl(php_ctlr->creg + SLOT1 + 4 * slot->hp_slot); 525 u32 slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot));
529 u8 pcix_cap = (slot_reg >> 12) & 7; 526 u8 m66_cap = !!(slot_reg & MHZ66_CAP);
530 u8 m66_cap = (slot_reg >> 9) & 1; 527 u8 pi, pcix_cap;
531 528
532 DBG_ENTER_ROUTINE 529 DBG_ENTER_ROUTINE
533 530
531 if ((retval = hpc_get_prog_int(slot, &pi)))
532 return retval;
533
534 switch (pi) {
535 case 1:
536 pcix_cap = (slot_reg & PCIX_CAP_MASK_PI1) >> PCIX_CAP_SHIFT;
537 break;
538 case 2:
539 pcix_cap = (slot_reg & PCIX_CAP_MASK_PI2) >> PCIX_CAP_SHIFT;
540 break;
541 default:
542 return -ENODEV;
543 }
544
534 dbg("%s: slot_reg = %x, pcix_cap = %x, m66_cap = %x\n", 545 dbg("%s: slot_reg = %x, pcix_cap = %x, m66_cap = %x\n",
535 __FUNCTION__, slot_reg, pcix_cap, m66_cap); 546 __FUNCTION__, slot_reg, pcix_cap, m66_cap);
536 547
@@ -564,20 +575,15 @@ static int hpc_get_adapter_speed(struct slot *slot, enum pci_bus_speed *value)
564 575
565static int hpc_get_mode1_ECC_cap(struct slot *slot, u8 *mode) 576static int hpc_get_mode1_ECC_cap(struct slot *slot, u8 *mode)
566{ 577{
567 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; 578 struct controller *ctrl = slot->ctrl;
568 u16 sec_bus_status; 579 u16 sec_bus_status;
569 u8 pi; 580 u8 pi;
570 int retval = 0; 581 int retval = 0;
571 582
572 DBG_ENTER_ROUTINE 583 DBG_ENTER_ROUTINE
573 584
574 if (!slot->ctrl->hpc_ctlr_handle) { 585 pi = shpc_readb(ctrl, PROG_INTERFACE);
575 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 586 sec_bus_status = shpc_readw(ctrl, SEC_BUS_CONFIG);
576 return -1;
577 }
578
579 pi = readb(php_ctlr->creg + PROG_INTERFACE);
580 sec_bus_status = readw(php_ctlr->creg + SEC_BUS_CONFIG);
581 587
582 if (pi == 2) { 588 if (pi == 2) {
583 *mode = (sec_bus_status & 0x0100) >> 8; 589 *mode = (sec_bus_status & 0x0100) >> 8;
@@ -593,128 +599,53 @@ static int hpc_get_mode1_ECC_cap(struct slot *slot, u8 *mode)
593 599
594static int hpc_query_power_fault(struct slot * slot) 600static int hpc_query_power_fault(struct slot * slot)
595{ 601{
596 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; 602 struct controller *ctrl = slot->ctrl;
597 u32 slot_reg; 603 u32 slot_reg;
598 u16 slot_status;
599 u8 pwr_fault_state, status;
600 604
601 DBG_ENTER_ROUTINE 605 DBG_ENTER_ROUTINE
602 606
603 if (!slot->ctrl->hpc_ctlr_handle) { 607 slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot));
604 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
605 return -1;
606 }
607
608 slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot));
609 slot_status = (u16) slot_reg;
610 pwr_fault_state = (slot_status & 0x0040) >> 7;
611 status = (pwr_fault_state == 1) ? 0 : 1;
612 608
613 DBG_LEAVE_ROUTINE 609 DBG_LEAVE_ROUTINE
614 /* Note: Logic 0 => fault */ 610 /* Note: Logic 0 => fault */
615 return status; 611 return !(slot_reg & POWER_FAULT);
616} 612}
617 613
618static int hpc_set_attention_status(struct slot *slot, u8 value) 614static int hpc_set_attention_status(struct slot *slot, u8 value)
619{ 615{
620 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
621 u8 slot_cmd = 0; 616 u8 slot_cmd = 0;
622 int rc = 0;
623
624 if (!slot->ctrl->hpc_ctlr_handle) {
625 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
626 return -1;
627 }
628
629 if (slot->hp_slot >= php_ctlr->num_slots) {
630 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
631 return -1;
632 }
633 617
634 switch (value) { 618 switch (value) {
635 case 0 : 619 case 0 :
636 slot_cmd = 0x30; /* OFF */ 620 slot_cmd = SET_ATTN_OFF; /* OFF */
637 break; 621 break;
638 case 1: 622 case 1:
639 slot_cmd = 0x10; /* ON */ 623 slot_cmd = SET_ATTN_ON; /* ON */
640 break; 624 break;
641 case 2: 625 case 2:
642 slot_cmd = 0x20; /* BLINK */ 626 slot_cmd = SET_ATTN_BLINK; /* BLINK */
643 break; 627 break;
644 default: 628 default:
645 return -1; 629 return -1;
646 } 630 }
647 631
648 shpc_write_cmd(slot, slot->hp_slot, slot_cmd); 632 return shpc_write_cmd(slot, slot->hp_slot, slot_cmd);
649
650 return rc;
651} 633}
652 634
653 635
654static void hpc_set_green_led_on(struct slot *slot) 636static void hpc_set_green_led_on(struct slot *slot)
655{ 637{
656 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; 638 shpc_write_cmd(slot, slot->hp_slot, SET_PWR_ON);
657 u8 slot_cmd;
658
659 if (!slot->ctrl->hpc_ctlr_handle) {
660 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
661 return ;
662 }
663
664 if (slot->hp_slot >= php_ctlr->num_slots) {
665 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
666 return ;
667 }
668
669 slot_cmd = 0x04;
670
671 shpc_write_cmd(slot, slot->hp_slot, slot_cmd);
672
673 return;
674} 639}
675 640
676static void hpc_set_green_led_off(struct slot *slot) 641static void hpc_set_green_led_off(struct slot *slot)
677{ 642{
678 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; 643 shpc_write_cmd(slot, slot->hp_slot, SET_PWR_OFF);
679 u8 slot_cmd;
680
681 if (!slot->ctrl->hpc_ctlr_handle) {
682 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
683 return ;
684 }
685
686 if (slot->hp_slot >= php_ctlr->num_slots) {
687 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
688 return ;
689 }
690
691 slot_cmd = 0x0C;
692
693 shpc_write_cmd(slot, slot->hp_slot, slot_cmd);
694
695 return;
696} 644}
697 645
698static void hpc_set_green_led_blink(struct slot *slot) 646static void hpc_set_green_led_blink(struct slot *slot)
699{ 647{
700 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; 648 shpc_write_cmd(slot, slot->hp_slot, SET_PWR_BLINK);
701 u8 slot_cmd;
702
703 if (!slot->ctrl->hpc_ctlr_handle) {
704 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
705 return ;
706 }
707
708 if (slot->hp_slot >= php_ctlr->num_slots) {
709 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
710 return ;
711 }
712
713 slot_cmd = 0x08;
714
715 shpc_write_cmd(slot, slot->hp_slot, slot_cmd);
716
717 return;
718} 649}
719 650
720int shpc_get_ctlr_slot_config(struct controller *ctrl, 651int shpc_get_ctlr_slot_config(struct controller *ctrl,
@@ -724,21 +655,17 @@ int shpc_get_ctlr_slot_config(struct controller *ctrl,
724 int *updown, /* physical_slot_num increament: 1 or -1 */ 655 int *updown, /* physical_slot_num increament: 1 or -1 */
725 int *flags) 656 int *flags)
726{ 657{
727 struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle; 658 u32 slot_config;
728 659
729 DBG_ENTER_ROUTINE 660 DBG_ENTER_ROUTINE
730 661
731 if (!ctrl->hpc_ctlr_handle) { 662 slot_config = shpc_readl(ctrl, SLOT_CONFIG);
732 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 663 *first_device_num = (slot_config & FIRST_DEV_NUM) >> 8;
733 return -1; 664 *num_ctlr_slots = slot_config & SLOT_NUM;
734 } 665 *physical_slot_num = (slot_config & PSN) >> 16;
735 666 *updown = ((slot_config & UPDOWN) >> 29) ? 1 : -1;
736 *first_device_num = php_ctlr->slot_device_offset; /* Obtained in shpc_init() */
737 *num_ctlr_slots = php_ctlr->num_slots; /* Obtained in shpc_init() */
738 667
739 *physical_slot_num = (readl(php_ctlr->creg + SLOT_CONFIG) & PSN) >> 16;
740 dbg("%s: physical_slot_num = %x\n", __FUNCTION__, *physical_slot_num); 668 dbg("%s: physical_slot_num = %x\n", __FUNCTION__, *physical_slot_num);
741 *updown = ((readl(php_ctlr->creg + SLOT_CONFIG) & UPDOWN ) >> 29) ? 1 : -1;
742 669
743 DBG_LEAVE_ROUTINE 670 DBG_LEAVE_ROUTINE
744 return 0; 671 return 0;
@@ -749,22 +676,34 @@ static void hpc_release_ctlr(struct controller *ctrl)
749 struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle; 676 struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
750 struct php_ctlr_state_s *p, *p_prev; 677 struct php_ctlr_state_s *p, *p_prev;
751 int i; 678 int i;
679 u32 slot_reg, serr_int;
752 680
753 DBG_ENTER_ROUTINE 681 DBG_ENTER_ROUTINE
754 682
755 if (!ctrl->hpc_ctlr_handle) {
756 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
757 return ;
758 }
759
760 /* 683 /*
761 * Mask all slot event interrupts 684 * Mask event interrupts and SERRs of all slots
762 */ 685 */
763 for (i = 0; i < ctrl->num_slots; i++) 686 for (i = 0; i < ctrl->num_slots; i++) {
764 writel(0xffff3fff, php_ctlr->creg + SLOT1 + (4 * i)); 687 slot_reg = shpc_readl(ctrl, SLOT_REG(i));
688 slot_reg |= (PRSNT_CHANGE_INTR_MASK | ISO_PFAULT_INTR_MASK |
689 BUTTON_PRESS_INTR_MASK | MRL_CHANGE_INTR_MASK |
690 CON_PFAULT_INTR_MASK | MRL_CHANGE_SERR_MASK |
691 CON_PFAULT_SERR_MASK);
692 slot_reg &= ~SLOT_REG_RSVDZ_MASK;
693 shpc_writel(ctrl, SLOT_REG(i), slot_reg);
694 }
765 695
766 cleanup_slots(ctrl); 696 cleanup_slots(ctrl);
767 697
698 /*
699 * Mask SERR and System Interrut generation
700 */
701 serr_int = shpc_readl(ctrl, SERR_INTR_ENABLE);
702 serr_int |= (GLOBAL_INTR_MASK | GLOBAL_SERR_MASK |
703 COMMAND_INTR_MASK | ARBITER_SERR_MASK);
704 serr_int &= ~SERR_INTR_RSVDZ_MASK;
705 shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int);
706
768 if (shpchp_poll_mode) { 707 if (shpchp_poll_mode) {
769 del_timer(&php_ctlr->int_poll_timer); 708 del_timer(&php_ctlr->int_poll_timer);
770 } else { 709 } else {
@@ -800,113 +739,79 @@ static void hpc_release_ctlr(struct controller *ctrl)
800 739
801 kfree(php_ctlr); 740 kfree(php_ctlr);
802 741
742 /*
743 * If this is the last controller to be released, destroy the
744 * shpchpd work queue
745 */
746 if (atomic_dec_and_test(&shpchp_num_controllers))
747 destroy_workqueue(shpchp_wq);
748
803DBG_LEAVE_ROUTINE 749DBG_LEAVE_ROUTINE
804 750
805} 751}
806 752
807static int hpc_power_on_slot(struct slot * slot) 753static int hpc_power_on_slot(struct slot * slot)
808{ 754{
809 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; 755 int retval;
810 u8 slot_cmd;
811 int retval = 0;
812 756
813 DBG_ENTER_ROUTINE 757 DBG_ENTER_ROUTINE
814 758
815 if (!slot->ctrl->hpc_ctlr_handle) { 759 retval = shpc_write_cmd(slot, slot->hp_slot, SET_SLOT_PWR);
816 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
817 return -1;
818 }
819
820 if (slot->hp_slot >= php_ctlr->num_slots) {
821 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
822 return -1;
823 }
824 slot_cmd = 0x01;
825
826 retval = shpc_write_cmd(slot, slot->hp_slot, slot_cmd);
827
828 if (retval) { 760 if (retval) {
829 err("%s: Write command failed!\n", __FUNCTION__); 761 err("%s: Write command failed!\n", __FUNCTION__);
830 return -1; 762 return retval;
831 } 763 }
832 764
833 DBG_LEAVE_ROUTINE 765 DBG_LEAVE_ROUTINE
834 766
835 return retval; 767 return 0;
836} 768}
837 769
838static int hpc_slot_enable(struct slot * slot) 770static int hpc_slot_enable(struct slot * slot)
839{ 771{
840 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; 772 int retval;
841 u8 slot_cmd;
842 int retval = 0;
843 773
844 DBG_ENTER_ROUTINE 774 DBG_ENTER_ROUTINE
845 775
846 if (!slot->ctrl->hpc_ctlr_handle) { 776 /* Slot - Enable, Power Indicator - Blink, Attention Indicator - Off */
847 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 777 retval = shpc_write_cmd(slot, slot->hp_slot,
848 return -1; 778 SET_SLOT_ENABLE | SET_PWR_BLINK | SET_ATTN_OFF);
849 }
850
851 if (slot->hp_slot >= php_ctlr->num_slots) {
852 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
853 return -1;
854 }
855 /* 3A => Slot - Enable, Power Indicator - Blink, Attention Indicator - Off */
856 slot_cmd = 0x3A;
857
858 retval = shpc_write_cmd(slot, slot->hp_slot, slot_cmd);
859
860 if (retval) { 779 if (retval) {
861 err("%s: Write command failed!\n", __FUNCTION__); 780 err("%s: Write command failed!\n", __FUNCTION__);
862 return -1; 781 return retval;
863 } 782 }
864 783
865 DBG_LEAVE_ROUTINE 784 DBG_LEAVE_ROUTINE
866 return retval; 785 return 0;
867} 786}
868 787
869static int hpc_slot_disable(struct slot * slot) 788static int hpc_slot_disable(struct slot * slot)
870{ 789{
871 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; 790 int retval;
872 u8 slot_cmd;
873 int retval = 0;
874 791
875 DBG_ENTER_ROUTINE 792 DBG_ENTER_ROUTINE
876 793
877 if (!slot->ctrl->hpc_ctlr_handle) { 794 /* Slot - Disable, Power Indicator - Off, Attention Indicator - On */
878 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 795 retval = shpc_write_cmd(slot, slot->hp_slot,
879 return -1; 796 SET_SLOT_DISABLE | SET_PWR_OFF | SET_ATTN_ON);
880 }
881
882 if (slot->hp_slot >= php_ctlr->num_slots) {
883 err("%s: Invalid HPC slot number!\n", __FUNCTION__);
884 return -1;
885 }
886
887 /* 1F => Slot - Disable, Power Indicator - Off, Attention Indicator - On */
888 slot_cmd = 0x1F;
889
890 retval = shpc_write_cmd(slot, slot->hp_slot, slot_cmd);
891
892 if (retval) { 797 if (retval) {
893 err("%s: Write command failed!\n", __FUNCTION__); 798 err("%s: Write command failed!\n", __FUNCTION__);
894 return -1; 799 return retval;
895 } 800 }
896 801
897 DBG_LEAVE_ROUTINE 802 DBG_LEAVE_ROUTINE
898 return retval; 803 return 0;
899} 804}
900 805
901static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) 806static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value)
902{ 807{
903 int retval; 808 int retval;
904 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; 809 struct controller *ctrl = slot->ctrl;
905 u8 pi, cmd; 810 u8 pi, cmd;
906 811
907 DBG_ENTER_ROUTINE 812 DBG_ENTER_ROUTINE
908 813
909 pi = readb(php_ctlr->creg + PROG_INTERFACE); 814 pi = shpc_readb(ctrl, PROG_INTERFACE);
910 if ((pi == 1) && (value > PCI_SPEED_133MHz_PCIX)) 815 if ((pi == 1) && (value > PCI_SPEED_133MHz_PCIX))
911 return -EINVAL; 816 return -EINVAL;
912 817
@@ -965,100 +870,86 @@ static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value)
965 return retval; 870 return retval;
966} 871}
967 872
968static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs) 873static irqreturn_t shpc_isr(int irq, void *dev_id, struct pt_regs *regs)
969{ 874{
970 struct controller *ctrl = NULL; 875 struct controller *ctrl = (struct controller *)dev_id;
971 struct php_ctlr_state_s *php_ctlr; 876 struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
972 u8 schedule_flag = 0; 877 u32 serr_int, slot_reg, intr_loc, intr_loc2;
973 u8 temp_byte;
974 u32 temp_dword, intr_loc, intr_loc2;
975 int hp_slot; 878 int hp_slot;
976 879
977 if (!dev_id)
978 return IRQ_NONE;
979
980 if (!shpchp_poll_mode) {
981 ctrl = (struct controller *)dev_id;
982 php_ctlr = ctrl->hpc_ctlr_handle;
983 } else {
984 php_ctlr = (struct php_ctlr_state_s *) dev_id;
985 ctrl = (struct controller *)php_ctlr->callback_instance_id;
986 }
987
988 if (!ctrl)
989 return IRQ_NONE;
990
991 if (!php_ctlr || !php_ctlr->creg)
992 return IRQ_NONE;
993
994 /* Check to see if it was our interrupt */ 880 /* Check to see if it was our interrupt */
995 intr_loc = readl(php_ctlr->creg + INTR_LOC); 881 intr_loc = shpc_readl(ctrl, INTR_LOC);
996
997 if (!intr_loc) 882 if (!intr_loc)
998 return IRQ_NONE; 883 return IRQ_NONE;
884
999 dbg("%s: intr_loc = %x\n",__FUNCTION__, intr_loc); 885 dbg("%s: intr_loc = %x\n",__FUNCTION__, intr_loc);
1000 886
1001 if(!shpchp_poll_mode) { 887 if(!shpchp_poll_mode) {
1002 /* Mask Global Interrupt Mask - see implementation note on p. 139 */ 888 /*
1003 /* of SHPC spec rev 1.0*/ 889 * Mask Global Interrupt Mask - see implementation
1004 temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); 890 * note on p. 139 of SHPC spec rev 1.0
1005 temp_dword |= 0x00000001; 891 */
1006 writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE); 892 serr_int = shpc_readl(ctrl, SERR_INTR_ENABLE);
893 serr_int |= GLOBAL_INTR_MASK;
894 serr_int &= ~SERR_INTR_RSVDZ_MASK;
895 shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int);
1007 896
1008 intr_loc2 = readl(php_ctlr->creg + INTR_LOC); 897 intr_loc2 = shpc_readl(ctrl, INTR_LOC);
1009 dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2); 898 dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2);
1010 } 899 }
1011 900
1012 if (intr_loc & 0x0001) { 901 if (intr_loc & CMD_INTR_PENDING) {
1013 /* 902 /*
1014 * Command Complete Interrupt Pending 903 * Command Complete Interrupt Pending
1015 * RO only - clear by writing 1 to the Command Completion 904 * RO only - clear by writing 1 to the Command Completion
1016 * Detect bit in Controller SERR-INT register 905 * Detect bit in Controller SERR-INT register
1017 */ 906 */
1018 temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); 907 serr_int = shpc_readl(ctrl, SERR_INTR_ENABLE);
1019 temp_dword &= 0xfffdffff; 908 serr_int &= ~SERR_INTR_RSVDZ_MASK;
1020 writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE); 909 shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int);
910
1021 ctrl->cmd_busy = 0; 911 ctrl->cmd_busy = 0;
1022 wake_up_interruptible(&ctrl->queue); 912 wake_up_interruptible(&ctrl->queue);
1023 } 913 }
1024 914
1025 if ((intr_loc = (intr_loc >> 1)) == 0) 915 if (!(intr_loc & ~CMD_INTR_PENDING))
1026 goto out; 916 goto out;
1027 917
1028 for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) { 918 for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) {
1029 /* To find out which slot has interrupt pending */ 919 /* To find out which slot has interrupt pending */
1030 if ((intr_loc >> hp_slot) & 0x01) { 920 if (!(intr_loc & SLOT_INTR_PENDING(hp_slot)))
1031 temp_dword = readl(php_ctlr->creg + SLOT1 + (4*hp_slot)); 921 continue;
1032 dbg("%s: Slot %x with intr, slot register = %x\n", 922
1033 __FUNCTION__, hp_slot, temp_dword); 923 slot_reg = shpc_readl(ctrl, SLOT_REG(hp_slot));
1034 temp_byte = (temp_dword >> 16) & 0xFF; 924 dbg("%s: Slot %x with intr, slot register = %x\n",
1035 if ((php_ctlr->switch_change_callback) && (temp_byte & 0x08)) 925 __FUNCTION__, hp_slot, slot_reg);
1036 schedule_flag += php_ctlr->switch_change_callback( 926
1037 hp_slot, php_ctlr->callback_instance_id); 927 if (slot_reg & MRL_CHANGE_DETECTED)
1038 if ((php_ctlr->attention_button_callback) && (temp_byte & 0x04)) 928 php_ctlr->switch_change_callback(
1039 schedule_flag += php_ctlr->attention_button_callback( 929 hp_slot, php_ctlr->callback_instance_id);
1040 hp_slot, php_ctlr->callback_instance_id); 930
1041 if ((php_ctlr->presence_change_callback) && (temp_byte & 0x01)) 931 if (slot_reg & BUTTON_PRESS_DETECTED)
1042 schedule_flag += php_ctlr->presence_change_callback( 932 php_ctlr->attention_button_callback(
1043 hp_slot , php_ctlr->callback_instance_id); 933 hp_slot, php_ctlr->callback_instance_id);
1044 if ((php_ctlr->power_fault_callback) && (temp_byte & 0x12)) 934
1045 schedule_flag += php_ctlr->power_fault_callback( 935 if (slot_reg & PRSNT_CHANGE_DETECTED)
1046 hp_slot, php_ctlr->callback_instance_id); 936 php_ctlr->presence_change_callback(
1047 937 hp_slot , php_ctlr->callback_instance_id);
1048 /* Clear all slot events */ 938
1049 temp_dword = 0xe01f3fff; 939 if (slot_reg & (ISO_PFAULT_DETECTED | CON_PFAULT_DETECTED))
1050 writel(temp_dword, php_ctlr->creg + SLOT1 + (4*hp_slot)); 940 php_ctlr->power_fault_callback(
1051 941 hp_slot, php_ctlr->callback_instance_id);
1052 intr_loc2 = readl(php_ctlr->creg + INTR_LOC); 942
1053 dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2); 943 /* Clear all slot events */
1054 } 944 slot_reg &= ~SLOT_REG_RSVDZ_MASK;
945 shpc_writel(ctrl, SLOT_REG(hp_slot), slot_reg);
1055 } 946 }
1056 out: 947 out:
1057 if (!shpchp_poll_mode) { 948 if (!shpchp_poll_mode) {
1058 /* Unmask Global Interrupt Mask */ 949 /* Unmask Global Interrupt Mask */
1059 temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); 950 serr_int = shpc_readl(ctrl, SERR_INTR_ENABLE);
1060 temp_dword &= 0xfffffffe; 951 serr_int &= ~(GLOBAL_INTR_MASK | SERR_INTR_RSVDZ_MASK);
1061 writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE); 952 shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int);
1062 } 953 }
1063 954
1064 return IRQ_HANDLED; 955 return IRQ_HANDLED;
@@ -1067,11 +958,11 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs)
1067static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) 958static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value)
1068{ 959{
1069 int retval = 0; 960 int retval = 0;
1070 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; 961 struct controller *ctrl = slot->ctrl;
1071 enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; 962 enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN;
1072 u8 pi = readb(php_ctlr->creg + PROG_INTERFACE); 963 u8 pi = shpc_readb(ctrl, PROG_INTERFACE);
1073 u32 slot_avail1 = readl(php_ctlr->creg + SLOT_AVAIL1); 964 u32 slot_avail1 = shpc_readl(ctrl, SLOT_AVAIL1);
1074 u32 slot_avail2 = readl(php_ctlr->creg + SLOT_AVAIL2); 965 u32 slot_avail2 = shpc_readl(ctrl, SLOT_AVAIL2);
1075 966
1076 DBG_ENTER_ROUTINE 967 DBG_ENTER_ROUTINE
1077 968
@@ -1114,10 +1005,10 @@ static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value)
1114static int hpc_get_cur_bus_speed (struct slot *slot, enum pci_bus_speed *value) 1005static int hpc_get_cur_bus_speed (struct slot *slot, enum pci_bus_speed *value)
1115{ 1006{
1116 int retval = 0; 1007 int retval = 0;
1117 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; 1008 struct controller *ctrl = slot->ctrl;
1118 enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; 1009 enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN;
1119 u16 sec_bus_reg = readw(php_ctlr->creg + SEC_BUS_CONFIG); 1010 u16 sec_bus_reg = shpc_readw(ctrl, SEC_BUS_CONFIG);
1120 u8 pi = readb(php_ctlr->creg + PROG_INTERFACE); 1011 u8 pi = shpc_readb(ctrl, PROG_INTERFACE);
1121 u8 speed_mode = (pi == 2) ? (sec_bus_reg & 0xF) : (sec_bus_reg & 0x7); 1012 u8 speed_mode = (pi == 2) ? (sec_bus_reg & 0xF) : (sec_bus_reg & 0x7);
1122 1013
1123 DBG_ENTER_ROUTINE 1014 DBG_ENTER_ROUTINE
@@ -1206,28 +1097,14 @@ static struct hpc_ops shpchp_hpc_ops = {
1206 .release_ctlr = hpc_release_ctlr, 1097 .release_ctlr = hpc_release_ctlr,
1207}; 1098};
1208 1099
1209inline static int shpc_indirect_creg_read(struct controller *ctrl, int index,
1210 u32 *value)
1211{
1212 int rc;
1213 u32 cap_offset = ctrl->cap_offset;
1214 struct pci_dev *pdev = ctrl->pci_dev;
1215
1216 rc = pci_write_config_byte(pdev, cap_offset + DWORD_SELECT, index);
1217 if (rc)
1218 return rc;
1219 return pci_read_config_dword(pdev, cap_offset + DWORD_DATA, value);
1220}
1221
1222int shpc_init(struct controller * ctrl, struct pci_dev * pdev) 1100int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
1223{ 1101{
1224 struct php_ctlr_state_s *php_ctlr, *p; 1102 struct php_ctlr_state_s *php_ctlr, *p;
1225 void *instance_id = ctrl; 1103 void *instance_id = ctrl;
1226 int rc, num_slots = 0; 1104 int rc, num_slots = 0;
1227 u8 hp_slot; 1105 u8 hp_slot;
1228 static int first = 1;
1229 u32 shpc_base_offset; 1106 u32 shpc_base_offset;
1230 u32 tempdword, slot_reg; 1107 u32 tempdword, slot_reg, slot_config;
1231 u8 i; 1108 u8 i;
1232 1109
1233 DBG_ENTER_ROUTINE 1110 DBG_ENTER_ROUTINE
@@ -1257,13 +1134,13 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
1257 } 1134 }
1258 dbg("%s: cap_offset = %x\n", __FUNCTION__, ctrl->cap_offset); 1135 dbg("%s: cap_offset = %x\n", __FUNCTION__, ctrl->cap_offset);
1259 1136
1260 rc = shpc_indirect_creg_read(ctrl, 0, &shpc_base_offset); 1137 rc = shpc_indirect_read(ctrl, 0, &shpc_base_offset);
1261 if (rc) { 1138 if (rc) {
1262 err("%s: cannot read base_offset\n", __FUNCTION__); 1139 err("%s: cannot read base_offset\n", __FUNCTION__);
1263 goto abort_free_ctlr; 1140 goto abort_free_ctlr;
1264 } 1141 }
1265 1142
1266 rc = shpc_indirect_creg_read(ctrl, 3, &tempdword); 1143 rc = shpc_indirect_read(ctrl, 3, &tempdword);
1267 if (rc) { 1144 if (rc) {
1268 err("%s: cannot read slot config\n", __FUNCTION__); 1145 err("%s: cannot read slot config\n", __FUNCTION__);
1269 goto abort_free_ctlr; 1146 goto abort_free_ctlr;
@@ -1272,7 +1149,7 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
1272 dbg("%s: num_slots (indirect) %x\n", __FUNCTION__, num_slots); 1149 dbg("%s: num_slots (indirect) %x\n", __FUNCTION__, num_slots);
1273 1150
1274 for (i = 0; i < 9 + num_slots; i++) { 1151 for (i = 0; i < 9 + num_slots; i++) {
1275 rc = shpc_indirect_creg_read(ctrl, i, &tempdword); 1152 rc = shpc_indirect_read(ctrl, i, &tempdword);
1276 if (rc) { 1153 if (rc) {
1277 err("%s: cannot read creg (index = %d)\n", 1154 err("%s: cannot read creg (index = %d)\n",
1278 __FUNCTION__, i); 1155 __FUNCTION__, i);
@@ -1287,11 +1164,6 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
1287 ctrl->mmio_size = 0x24 + 0x4 * num_slots; 1164 ctrl->mmio_size = 0x24 + 0x4 * num_slots;
1288 } 1165 }
1289 1166
1290 if (first) {
1291 spin_lock_init(&hpc_event_lock);
1292 first = 0;
1293 }
1294
1295 info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, pdev->subsystem_vendor, 1167 info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, pdev->subsystem_vendor,
1296 pdev->subsystem_device); 1168 pdev->subsystem_device);
1297 1169
@@ -1326,29 +1198,39 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
1326 php_ctlr->power_fault_callback = shpchp_handle_power_fault; 1198 php_ctlr->power_fault_callback = shpchp_handle_power_fault;
1327 php_ctlr->callback_instance_id = instance_id; 1199 php_ctlr->callback_instance_id = instance_id;
1328 1200
1201 ctrl->hpc_ctlr_handle = php_ctlr;
1202 ctrl->hpc_ops = &shpchp_hpc_ops;
1203
1329 /* Return PCI Controller Info */ 1204 /* Return PCI Controller Info */
1330 php_ctlr->slot_device_offset = (readl(php_ctlr->creg + SLOT_CONFIG) & FIRST_DEV_NUM ) >> 8; 1205 slot_config = shpc_readl(ctrl, SLOT_CONFIG);
1331 php_ctlr->num_slots = readl(php_ctlr->creg + SLOT_CONFIG) & SLOT_NUM; 1206 php_ctlr->slot_device_offset = (slot_config & FIRST_DEV_NUM) >> 8;
1207 php_ctlr->num_slots = slot_config & SLOT_NUM;
1332 dbg("%s: slot_device_offset %x\n", __FUNCTION__, php_ctlr->slot_device_offset); 1208 dbg("%s: slot_device_offset %x\n", __FUNCTION__, php_ctlr->slot_device_offset);
1333 dbg("%s: num_slots %x\n", __FUNCTION__, php_ctlr->num_slots); 1209 dbg("%s: num_slots %x\n", __FUNCTION__, php_ctlr->num_slots);
1334 1210
1335 /* Mask Global Interrupt Mask & Command Complete Interrupt Mask */ 1211 /* Mask Global Interrupt Mask & Command Complete Interrupt Mask */
1336 tempdword = readl(php_ctlr->creg + SERR_INTR_ENABLE); 1212 tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE);
1337 dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword); 1213 dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword);
1338 tempdword = 0x0003000f; 1214 tempdword |= (GLOBAL_INTR_MASK | GLOBAL_SERR_MASK |
1339 writel(tempdword, php_ctlr->creg + SERR_INTR_ENABLE); 1215 COMMAND_INTR_MASK | ARBITER_SERR_MASK);
1340 tempdword = readl(php_ctlr->creg + SERR_INTR_ENABLE); 1216 tempdword &= ~SERR_INTR_RSVDZ_MASK;
1217 shpc_writel(ctrl, SERR_INTR_ENABLE, tempdword);
1218 tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE);
1341 dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword); 1219 dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword);
1342 1220
1343 /* Mask the MRL sensor SERR Mask of individual slot in 1221 /* Mask the MRL sensor SERR Mask of individual slot in
1344 * Slot SERR-INT Mask & clear all the existing event if any 1222 * Slot SERR-INT Mask & clear all the existing event if any
1345 */ 1223 */
1346 for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) { 1224 for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) {
1347 slot_reg = readl(php_ctlr->creg + SLOT1 + 4*hp_slot ); 1225 slot_reg = shpc_readl(ctrl, SLOT_REG(hp_slot));
1348 dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__, 1226 dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__,
1349 hp_slot, slot_reg); 1227 hp_slot, slot_reg);
1350 tempdword = 0xffff3fff; 1228 slot_reg |= (PRSNT_CHANGE_INTR_MASK | ISO_PFAULT_INTR_MASK |
1351 writel(tempdword, php_ctlr->creg + SLOT1 + (4*hp_slot)); 1229 BUTTON_PRESS_INTR_MASK | MRL_CHANGE_INTR_MASK |
1230 CON_PFAULT_INTR_MASK | MRL_CHANGE_SERR_MASK |
1231 CON_PFAULT_SERR_MASK);
1232 slot_reg &= ~SLOT_REG_RSVDZ_MASK;
1233 shpc_writel(ctrl, SLOT_REG(hp_slot), slot_reg);
1352 } 1234 }
1353 1235
1354 if (shpchp_poll_mode) {/* Install interrupt polling code */ 1236 if (shpchp_poll_mode) {/* Install interrupt polling code */
@@ -1392,24 +1274,37 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
1392 } 1274 }
1393 spin_unlock(&list_lock); 1275 spin_unlock(&list_lock);
1394 1276
1395
1396 ctlr_seq_num++; 1277 ctlr_seq_num++;
1397 ctrl->hpc_ctlr_handle = php_ctlr;
1398 ctrl->hpc_ops = &shpchp_hpc_ops;
1399 1278
1279 /*
1280 * If this is the first controller to be initialized,
1281 * initialize the shpchpd work queue
1282 */
1283 if (atomic_add_return(1, &shpchp_num_controllers) == 1) {
1284 shpchp_wq = create_singlethread_workqueue("shpchpd");
1285 if (!shpchp_wq)
1286 return -ENOMEM;
1287 }
1288
1289 /*
1290 * Unmask all event interrupts of all slots
1291 */
1400 for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) { 1292 for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) {
1401 slot_reg = readl(php_ctlr->creg + SLOT1 + 4*hp_slot ); 1293 slot_reg = shpc_readl(ctrl, SLOT_REG(hp_slot));
1402 dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__, 1294 dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__,
1403 hp_slot, slot_reg); 1295 hp_slot, slot_reg);
1404 tempdword = 0xe01f3fff; 1296 slot_reg &= ~(PRSNT_CHANGE_INTR_MASK | ISO_PFAULT_INTR_MASK |
1405 writel(tempdword, php_ctlr->creg + SLOT1 + (4*hp_slot)); 1297 BUTTON_PRESS_INTR_MASK | MRL_CHANGE_INTR_MASK |
1298 CON_PFAULT_INTR_MASK | SLOT_REG_RSVDZ_MASK);
1299 shpc_writel(ctrl, SLOT_REG(hp_slot), slot_reg);
1406 } 1300 }
1407 if (!shpchp_poll_mode) { 1301 if (!shpchp_poll_mode) {
1408 /* Unmask all general input interrupts and SERR */ 1302 /* Unmask all general input interrupts and SERR */
1409 tempdword = readl(php_ctlr->creg + SERR_INTR_ENABLE); 1303 tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE);
1410 tempdword = 0x0000000a; 1304 tempdword &= ~(GLOBAL_INTR_MASK | COMMAND_INTR_MASK |
1411 writel(tempdword, php_ctlr->creg + SERR_INTR_ENABLE); 1305 SERR_INTR_RSVDZ_MASK);
1412 tempdword = readl(php_ctlr->creg + SERR_INTR_ENABLE); 1306 shpc_writel(ctrl, SERR_INTR_ENABLE, tempdword);
1307 tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE);
1413 dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword); 1308 dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword);
1414 } 1309 }
1415 1310
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c
index 257adc233996..0a6b25ef194c 100644
--- a/drivers/pci/hotplug/shpchp_pci.c
+++ b/drivers/pci/hotplug/shpchp_pci.c
@@ -47,21 +47,28 @@ static void program_fw_provided_values(struct pci_dev *dev)
47 return; 47 return;
48 48
49 /* use default values if we can't get them from firmware */ 49 /* use default values if we can't get them from firmware */
50 if (get_hp_params_from_firmware(dev, &hpp)) { 50 if (get_hp_params_from_firmware(dev, &hpp) ||
51 hpp.cache_line_size = 8; 51 !hpp.t0 || (hpp.t0->revision > 1)) {
52 hpp.latency_timer = 0x40; 52 printk(KERN_WARNING
53 hpp.enable_serr = 0; 53 "%s: Could not get hotplug parameters. Use defaults\n",
54 hpp.enable_perr = 0; 54 __FUNCTION__);
55 hpp.t0 = &hpp.type0_data;
56 hpp.t0->revision = 0;
57 hpp.t0->cache_line_size = 8;
58 hpp.t0->latency_timer = 0x40;
59 hpp.t0->enable_serr = 0;
60 hpp.t0->enable_perr = 0;
55 } 61 }
56 62
57 pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, hpp.cache_line_size); 63 pci_write_config_byte(dev,
58 pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp.latency_timer); 64 PCI_CACHE_LINE_SIZE, hpp.t0->cache_line_size);
65 pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp.t0->latency_timer);
59 pci_read_config_word(dev, PCI_COMMAND, &pci_cmd); 66 pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
60 if (hpp.enable_serr) 67 if (hpp.t0->enable_serr)
61 pci_cmd |= PCI_COMMAND_SERR; 68 pci_cmd |= PCI_COMMAND_SERR;
62 else 69 else
63 pci_cmd &= ~PCI_COMMAND_SERR; 70 pci_cmd &= ~PCI_COMMAND_SERR;
64 if (hpp.enable_perr) 71 if (hpp.t0->enable_perr)
65 pci_cmd |= PCI_COMMAND_PARITY; 72 pci_cmd |= PCI_COMMAND_PARITY;
66 else 73 else
67 pci_cmd &= ~PCI_COMMAND_PARITY; 74 pci_cmd &= ~PCI_COMMAND_PARITY;
@@ -70,13 +77,13 @@ static void program_fw_provided_values(struct pci_dev *dev)
70 /* Program bridge control value and child devices */ 77 /* Program bridge control value and child devices */
71 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { 78 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
72 pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 79 pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,
73 hpp.latency_timer); 80 hpp.t0->latency_timer);
74 pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl); 81 pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
75 if (hpp.enable_serr) 82 if (hpp.t0->enable_serr)
76 pci_bctl |= PCI_BRIDGE_CTL_SERR; 83 pci_bctl |= PCI_BRIDGE_CTL_SERR;
77 else 84 else
78 pci_bctl &= ~PCI_BRIDGE_CTL_SERR; 85 pci_bctl &= ~PCI_BRIDGE_CTL_SERR;
79 if (hpp.enable_perr) 86 if (hpp.t0->enable_perr)
80 pci_bctl |= PCI_BRIDGE_CTL_PARITY; 87 pci_bctl |= PCI_BRIDGE_CTL_PARITY;
81 else 88 else
82 pci_bctl &= ~PCI_BRIDGE_CTL_PARITY; 89 pci_bctl &= ~PCI_BRIDGE_CTL_PARITY;