aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2006-06-22 22:51:46 -0400
committerJeff Garzik <jeff@garzik.org>2006-06-22 22:51:46 -0400
commitdbe1ab9514c231c9b062140a107d9dea0eabefcc (patch)
tree0001c7143cf923fc704215f0a0e54221e9e5cbb9 /drivers/pci
parent612eff0e3715a6faff5ba1b74873b99e036c59fe (diff)
parentd588fcbe5a7ba8bba2cebf7799ab2d573717a806 (diff)
Merge branch 'master' into upstream
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/Makefile6
-rw-r--r--drivers/pci/bus.c21
-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
-rw-r--r--drivers/pci/msi-altix.c210
-rw-r--r--drivers/pci/msi-apic.c100
-rw-r--r--drivers/pci/msi.c285
-rw-r--r--drivers/pci/msi.h133
-rw-r--r--drivers/pci/pci-acpi.c16
-rw-r--r--drivers/pci/pci-sysfs.c45
-rw-r--r--drivers/pci/pci.c16
-rw-r--r--drivers/pci/pci.h2
-rw-r--r--drivers/pci/probe.c45
-rw-r--r--drivers/pci/quirks.c47
-rw-r--r--drivers/pci/remove.c12
-rw-r--r--drivers/pci/search.c32
-rw-r--r--drivers/pci/setup-bus.c5
-rw-r--r--drivers/pci/setup-res.c40
31 files changed, 1836 insertions, 931 deletions
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 6707df968934..f2d152b818f0 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -26,7 +26,11 @@ obj-$(CONFIG_PPC32) += setup-irq.o
26obj-$(CONFIG_PPC64) += setup-bus.o 26obj-$(CONFIG_PPC64) += setup-bus.o
27obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o 27obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o
28obj-$(CONFIG_X86_VISWS) += setup-irq.o 28obj-$(CONFIG_X86_VISWS) += setup-irq.o
29obj-$(CONFIG_PCI_MSI) += msi.o 29
30msiobj-y := msi.o msi-apic.o
31msiobj-$(CONFIG_IA64_GENERIC) += msi-altix.o
32msiobj-$(CONFIG_IA64_SGI_SN2) += msi-altix.o
33obj-$(CONFIG_PCI_MSI) += $(msiobj-y)
30 34
31# 35#
32# ACPI Related PCI FW Functions 36# ACPI Related PCI FW Functions
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index eed67d9e73bc..723092682023 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -81,9 +81,9 @@ void __devinit pci_bus_add_device(struct pci_dev *dev)
81{ 81{
82 device_add(&dev->dev); 82 device_add(&dev->dev);
83 83
84 spin_lock(&pci_bus_lock); 84 down_write(&pci_bus_sem);
85 list_add_tail(&dev->global_list, &pci_devices); 85 list_add_tail(&dev->global_list, &pci_devices);
86 spin_unlock(&pci_bus_lock); 86 up_write(&pci_bus_sem);
87 87
88 pci_proc_attach_device(dev); 88 pci_proc_attach_device(dev);
89 pci_create_sysfs_dev_files(dev); 89 pci_create_sysfs_dev_files(dev);
@@ -125,10 +125,10 @@ void __devinit pci_bus_add_devices(struct pci_bus *bus)
125 */ 125 */
126 if (dev->subordinate) { 126 if (dev->subordinate) {
127 if (list_empty(&dev->subordinate->node)) { 127 if (list_empty(&dev->subordinate->node)) {
128 spin_lock(&pci_bus_lock); 128 down_write(&pci_bus_sem);
129 list_add_tail(&dev->subordinate->node, 129 list_add_tail(&dev->subordinate->node,
130 &dev->bus->children); 130 &dev->bus->children);
131 spin_unlock(&pci_bus_lock); 131 up_write(&pci_bus_sem);
132 } 132 }
133 pci_bus_add_devices(dev->subordinate); 133 pci_bus_add_devices(dev->subordinate);
134 134
@@ -168,7 +168,7 @@ void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *),
168 struct list_head *next; 168 struct list_head *next;
169 169
170 bus = top; 170 bus = top;
171 spin_lock(&pci_bus_lock); 171 down_read(&pci_bus_sem);
172 next = top->devices.next; 172 next = top->devices.next;
173 for (;;) { 173 for (;;) {
174 if (next == &bus->devices) { 174 if (next == &bus->devices) {
@@ -180,22 +180,19 @@ void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *),
180 continue; 180 continue;
181 } 181 }
182 dev = list_entry(next, struct pci_dev, bus_list); 182 dev = list_entry(next, struct pci_dev, bus_list);
183 pci_dev_get(dev);
184 if (dev->subordinate) { 183 if (dev->subordinate) {
185 /* this is a pci-pci bridge, do its devices next */ 184 /* this is a pci-pci bridge, do its devices next */
186 next = dev->subordinate->devices.next; 185 next = dev->subordinate->devices.next;
187 bus = dev->subordinate; 186 bus = dev->subordinate;
188 } else 187 } else
189 next = dev->bus_list.next; 188 next = dev->bus_list.next;
190 spin_unlock(&pci_bus_lock);
191 189
192 /* Run device routines with the bus unlocked */ 190 /* Run device routines with the device locked */
191 down(&dev->dev.sem);
193 cb(dev, userdata); 192 cb(dev, userdata);
194 193 up(&dev->dev.sem);
195 spin_lock(&pci_bus_lock);
196 pci_dev_put(dev);
197 } 194 }
198 spin_unlock(&pci_bus_lock); 195 up_read(&pci_bus_sem);
199} 196}
200EXPORT_SYMBOL_GPL(pci_walk_bus); 197EXPORT_SYMBOL_GPL(pci_walk_bus);
201 198
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;
diff --git a/drivers/pci/msi-altix.c b/drivers/pci/msi-altix.c
new file mode 100644
index 000000000000..bed4183a5e39
--- /dev/null
+++ b/drivers/pci/msi-altix.c
@@ -0,0 +1,210 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2006 Silicon Graphics, Inc. All Rights Reserved.
7 */
8
9#include <linux/types.h>
10#include <linux/pci.h>
11#include <linux/cpumask.h>
12
13#include <asm/sn/addrs.h>
14#include <asm/sn/intr.h>
15#include <asm/sn/pcibus_provider_defs.h>
16#include <asm/sn/pcidev.h>
17#include <asm/sn/nodepda.h>
18
19#include "msi.h"
20
21struct sn_msi_info {
22 u64 pci_addr;
23 struct sn_irq_info *sn_irq_info;
24};
25
26static struct sn_msi_info *sn_msi_info;
27
28static void
29sn_msi_teardown(unsigned int vector)
30{
31 nasid_t nasid;
32 int widget;
33 struct pci_dev *pdev;
34 struct pcidev_info *sn_pdev;
35 struct sn_irq_info *sn_irq_info;
36 struct pcibus_bussoft *bussoft;
37 struct sn_pcibus_provider *provider;
38
39 sn_irq_info = sn_msi_info[vector].sn_irq_info;
40 if (sn_irq_info == NULL || sn_irq_info->irq_int_bit >= 0)
41 return;
42
43 sn_pdev = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
44 pdev = sn_pdev->pdi_linux_pcidev;
45 provider = SN_PCIDEV_BUSPROVIDER(pdev);
46
47 (*provider->dma_unmap)(pdev,
48 sn_msi_info[vector].pci_addr,
49 PCI_DMA_FROMDEVICE);
50 sn_msi_info[vector].pci_addr = 0;
51
52 bussoft = SN_PCIDEV_BUSSOFT(pdev);
53 nasid = NASID_GET(bussoft->bs_base);
54 widget = (nasid & 1) ?
55 TIO_SWIN_WIDGETNUM(bussoft->bs_base) :
56 SWIN_WIDGETNUM(bussoft->bs_base);
57
58 sn_intr_free(nasid, widget, sn_irq_info);
59 sn_msi_info[vector].sn_irq_info = NULL;
60
61 return;
62}
63
64int
65sn_msi_setup(struct pci_dev *pdev, unsigned int vector,
66 u32 *addr_hi, u32 *addr_lo, u32 *data)
67{
68 int widget;
69 int status;
70 nasid_t nasid;
71 u64 bus_addr;
72 struct sn_irq_info *sn_irq_info;
73 struct pcibus_bussoft *bussoft = SN_PCIDEV_BUSSOFT(pdev);
74 struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
75
76 if (bussoft == NULL)
77 return -EINVAL;
78
79 if (provider == NULL || provider->dma_map_consistent == NULL)
80 return -EINVAL;
81
82 /*
83 * Set up the vector plumbing. Let the prom (via sn_intr_alloc)
84 * decide which cpu to direct this msi at by default.
85 */
86
87 nasid = NASID_GET(bussoft->bs_base);
88 widget = (nasid & 1) ?
89 TIO_SWIN_WIDGETNUM(bussoft->bs_base) :
90 SWIN_WIDGETNUM(bussoft->bs_base);
91
92 sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL);
93 if (! sn_irq_info)
94 return -ENOMEM;
95
96 status = sn_intr_alloc(nasid, widget, sn_irq_info, vector, -1, -1);
97 if (status) {
98 kfree(sn_irq_info);
99 return -ENOMEM;
100 }
101
102 sn_irq_info->irq_int_bit = -1; /* mark this as an MSI irq */
103 sn_irq_fixup(pdev, sn_irq_info);
104
105 /* Prom probably should fill these in, but doesn't ... */
106 sn_irq_info->irq_bridge_type = bussoft->bs_asic_type;
107 sn_irq_info->irq_bridge = (void *)bussoft->bs_base;
108
109 /*
110 * Map the xio address into bus space
111 */
112 bus_addr = (*provider->dma_map_consistent)(pdev,
113 sn_irq_info->irq_xtalkaddr,
114 sizeof(sn_irq_info->irq_xtalkaddr),
115 SN_DMA_MSI|SN_DMA_ADDR_XIO);
116 if (! bus_addr) {
117 sn_intr_free(nasid, widget, sn_irq_info);
118 kfree(sn_irq_info);
119 return -ENOMEM;
120 }
121
122 sn_msi_info[vector].sn_irq_info = sn_irq_info;
123 sn_msi_info[vector].pci_addr = bus_addr;
124
125 *addr_hi = (u32)(bus_addr >> 32);
126 *addr_lo = (u32)(bus_addr & 0x00000000ffffffff);
127
128 /*
129 * In the SN platform, bit 16 is a "send vector" bit which
130 * must be present in order to move the vector through the system.
131 */
132 *data = 0x100 + (unsigned int)vector;
133
134#ifdef CONFIG_SMP
135 set_irq_affinity_info((vector & 0xff), sn_irq_info->irq_cpuid, 0);
136#endif
137
138 return 0;
139}
140
141static void
142sn_msi_target(unsigned int vector, unsigned int cpu,
143 u32 *addr_hi, u32 *addr_lo)
144{
145 int slice;
146 nasid_t nasid;
147 u64 bus_addr;
148 struct pci_dev *pdev;
149 struct pcidev_info *sn_pdev;
150 struct sn_irq_info *sn_irq_info;
151 struct sn_irq_info *new_irq_info;
152 struct sn_pcibus_provider *provider;
153
154 sn_irq_info = sn_msi_info[vector].sn_irq_info;
155 if (sn_irq_info == NULL || sn_irq_info->irq_int_bit >= 0)
156 return;
157
158 /*
159 * Release XIO resources for the old MSI PCI address
160 */
161
162 sn_pdev = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
163 pdev = sn_pdev->pdi_linux_pcidev;
164 provider = SN_PCIDEV_BUSPROVIDER(pdev);
165
166 bus_addr = (u64)(*addr_hi) << 32 | (u64)(*addr_lo);
167 (*provider->dma_unmap)(pdev, bus_addr, PCI_DMA_FROMDEVICE);
168 sn_msi_info[vector].pci_addr = 0;
169
170 nasid = cpuid_to_nasid(cpu);
171 slice = cpuid_to_slice(cpu);
172
173 new_irq_info = sn_retarget_vector(sn_irq_info, nasid, slice);
174 sn_msi_info[vector].sn_irq_info = new_irq_info;
175 if (new_irq_info == NULL)
176 return;
177
178 /*
179 * Map the xio address into bus space
180 */
181
182 bus_addr = (*provider->dma_map_consistent)(pdev,
183 new_irq_info->irq_xtalkaddr,
184 sizeof(new_irq_info->irq_xtalkaddr),
185 SN_DMA_MSI|SN_DMA_ADDR_XIO);
186
187 sn_msi_info[vector].pci_addr = bus_addr;
188 *addr_hi = (u32)(bus_addr >> 32);
189 *addr_lo = (u32)(bus_addr & 0x00000000ffffffff);
190}
191
192struct msi_ops sn_msi_ops = {
193 .setup = sn_msi_setup,
194 .teardown = sn_msi_teardown,
195#ifdef CONFIG_SMP
196 .target = sn_msi_target,
197#endif
198};
199
200int
201sn_msi_init(void)
202{
203 sn_msi_info =
204 kzalloc(sizeof(struct sn_msi_info) * NR_VECTORS, GFP_KERNEL);
205 if (! sn_msi_info)
206 return -ENOMEM;
207
208 msi_register(&sn_msi_ops);
209 return 0;
210}
diff --git a/drivers/pci/msi-apic.c b/drivers/pci/msi-apic.c
new file mode 100644
index 000000000000..0eb5fe9003a2
--- /dev/null
+++ b/drivers/pci/msi-apic.c
@@ -0,0 +1,100 @@
1/*
2 * MSI hooks for standard x86 apic
3 */
4
5#include <linux/pci.h>
6#include <linux/irq.h>
7
8#include "msi.h"
9
10/*
11 * Shifts for APIC-based data
12 */
13
14#define MSI_DATA_VECTOR_SHIFT 0
15#define MSI_DATA_VECTOR(v) (((u8)v) << MSI_DATA_VECTOR_SHIFT)
16
17#define MSI_DATA_DELIVERY_SHIFT 8
18#define MSI_DATA_DELIVERY_FIXED (0 << MSI_DATA_DELIVERY_SHIFT)
19#define MSI_DATA_DELIVERY_LOWPRI (1 << MSI_DATA_DELIVERY_SHIFT)
20
21#define MSI_DATA_LEVEL_SHIFT 14
22#define MSI_DATA_LEVEL_DEASSERT (0 << MSI_DATA_LEVEL_SHIFT)
23#define MSI_DATA_LEVEL_ASSERT (1 << MSI_DATA_LEVEL_SHIFT)
24
25#define MSI_DATA_TRIGGER_SHIFT 15
26#define MSI_DATA_TRIGGER_EDGE (0 << MSI_DATA_TRIGGER_SHIFT)
27#define MSI_DATA_TRIGGER_LEVEL (1 << MSI_DATA_TRIGGER_SHIFT)
28
29/*
30 * Shift/mask fields for APIC-based bus address
31 */
32
33#define MSI_ADDR_HEADER 0xfee00000
34
35#define MSI_ADDR_DESTID_MASK 0xfff0000f
36#define MSI_ADDR_DESTID_CPU(cpu) ((cpu) << MSI_TARGET_CPU_SHIFT)
37
38#define MSI_ADDR_DESTMODE_SHIFT 2
39#define MSI_ADDR_DESTMODE_PHYS (0 << MSI_ADDR_DESTMODE_SHIFT)
40#define MSI_ADDR_DESTMODE_LOGIC (1 << MSI_ADDR_DESTMODE_SHIFT)
41
42#define MSI_ADDR_REDIRECTION_SHIFT 3
43#define MSI_ADDR_REDIRECTION_CPU (0 << MSI_ADDR_REDIRECTION_SHIFT)
44#define MSI_ADDR_REDIRECTION_LOWPRI (1 << MSI_ADDR_REDIRECTION_SHIFT)
45
46
47static void
48msi_target_apic(unsigned int vector,
49 unsigned int dest_cpu,
50 u32 *address_hi, /* in/out */
51 u32 *address_lo) /* in/out */
52{
53 u32 addr = *address_lo;
54
55 addr &= MSI_ADDR_DESTID_MASK;
56 addr |= MSI_ADDR_DESTID_CPU(cpu_physical_id(dest_cpu));
57
58 *address_lo = addr;
59}
60
61static int
62msi_setup_apic(struct pci_dev *pdev, /* unused in generic */
63 unsigned int vector,
64 u32 *address_hi,
65 u32 *address_lo,
66 u32 *data)
67{
68 unsigned long dest_phys_id;
69
70 dest_phys_id = cpu_physical_id(first_cpu(cpu_online_map));
71
72 *address_hi = 0;
73 *address_lo = MSI_ADDR_HEADER |
74 MSI_ADDR_DESTMODE_PHYS |
75 MSI_ADDR_REDIRECTION_CPU |
76 MSI_ADDR_DESTID_CPU(dest_phys_id);
77
78 *data = MSI_DATA_TRIGGER_EDGE |
79 MSI_DATA_LEVEL_ASSERT |
80 MSI_DATA_DELIVERY_FIXED |
81 MSI_DATA_VECTOR(vector);
82
83 return 0;
84}
85
86static void
87msi_teardown_apic(unsigned int vector)
88{
89 return; /* no-op */
90}
91
92/*
93 * Generic ops used on most IA archs/platforms. Set with msi_register()
94 */
95
96struct msi_ops msi_apic_ops = {
97 .setup = msi_setup_apic,
98 .teardown = msi_teardown_apic,
99 .target = msi_target_apic,
100};
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 9855c4c920b8..7f8429284fab 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -23,8 +23,6 @@
23#include "pci.h" 23#include "pci.h"
24#include "msi.h" 24#include "msi.h"
25 25
26#define MSI_TARGET_CPU first_cpu(cpu_online_map)
27
28static DEFINE_SPINLOCK(msi_lock); 26static DEFINE_SPINLOCK(msi_lock);
29static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL }; 27static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL };
30static kmem_cache_t* msi_cachep; 28static kmem_cache_t* msi_cachep;
@@ -37,9 +35,17 @@ static int nr_msix_devices;
37 35
38#ifndef CONFIG_X86_IO_APIC 36#ifndef CONFIG_X86_IO_APIC
39int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1}; 37int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1};
40u8 irq_vector[NR_IRQ_VECTORS] = { FIRST_DEVICE_VECTOR , 0 };
41#endif 38#endif
42 39
40static struct msi_ops *msi_ops;
41
42int
43msi_register(struct msi_ops *ops)
44{
45 msi_ops = ops;
46 return 0;
47}
48
43static void msi_cache_ctor(void *p, kmem_cache_t *cache, unsigned long flags) 49static void msi_cache_ctor(void *p, kmem_cache_t *cache, unsigned long flags)
44{ 50{
45 memset(p, 0, NR_IRQS * sizeof(struct msi_desc)); 51 memset(p, 0, NR_IRQS * sizeof(struct msi_desc));
@@ -92,7 +98,7 @@ static void msi_set_mask_bit(unsigned int vector, int flag)
92static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask) 98static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask)
93{ 99{
94 struct msi_desc *entry; 100 struct msi_desc *entry;
95 struct msg_address address; 101 u32 address_hi, address_lo;
96 unsigned int irq = vector; 102 unsigned int irq = vector;
97 unsigned int dest_cpu = first_cpu(cpu_mask); 103 unsigned int dest_cpu = first_cpu(cpu_mask);
98 104
@@ -108,28 +114,36 @@ static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask)
108 if (!pos) 114 if (!pos)
109 return; 115 return;
110 116
117 pci_read_config_dword(entry->dev, msi_upper_address_reg(pos),
118 &address_hi);
111 pci_read_config_dword(entry->dev, msi_lower_address_reg(pos), 119 pci_read_config_dword(entry->dev, msi_lower_address_reg(pos),
112 &address.lo_address.value); 120 &address_lo);
113 address.lo_address.value &= MSI_ADDRESS_DEST_ID_MASK; 121
114 address.lo_address.value |= (cpu_physical_id(dest_cpu) << 122 msi_ops->target(vector, dest_cpu, &address_hi, &address_lo);
115 MSI_TARGET_CPU_SHIFT); 123
116 entry->msi_attrib.current_cpu = cpu_physical_id(dest_cpu); 124 pci_write_config_dword(entry->dev, msi_upper_address_reg(pos),
125 address_hi);
117 pci_write_config_dword(entry->dev, msi_lower_address_reg(pos), 126 pci_write_config_dword(entry->dev, msi_lower_address_reg(pos),
118 address.lo_address.value); 127 address_lo);
119 set_native_irq_info(irq, cpu_mask); 128 set_native_irq_info(irq, cpu_mask);
120 break; 129 break;
121 } 130 }
122 case PCI_CAP_ID_MSIX: 131 case PCI_CAP_ID_MSIX:
123 { 132 {
124 int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + 133 int offset_hi =
125 PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET; 134 entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
126 135 PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET;
127 address.lo_address.value = readl(entry->mask_base + offset); 136 int offset_lo =
128 address.lo_address.value &= MSI_ADDRESS_DEST_ID_MASK; 137 entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
129 address.lo_address.value |= (cpu_physical_id(dest_cpu) << 138 PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET;
130 MSI_TARGET_CPU_SHIFT); 139
131 entry->msi_attrib.current_cpu = cpu_physical_id(dest_cpu); 140 address_hi = readl(entry->mask_base + offset_hi);
132 writel(address.lo_address.value, entry->mask_base + offset); 141 address_lo = readl(entry->mask_base + offset_lo);
142
143 msi_ops->target(vector, dest_cpu, &address_hi, &address_lo);
144
145 writel(address_hi, entry->mask_base + offset_hi);
146 writel(address_lo, entry->mask_base + offset_lo);
133 set_native_irq_info(irq, cpu_mask); 147 set_native_irq_info(irq, cpu_mask);
134 break; 148 break;
135 } 149 }
@@ -251,30 +265,6 @@ static struct hw_interrupt_type msi_irq_wo_maskbit_type = {
251 .set_affinity = set_msi_affinity 265 .set_affinity = set_msi_affinity
252}; 266};
253 267
254static void msi_data_init(struct msg_data *msi_data,
255 unsigned int vector)
256{
257 memset(msi_data, 0, sizeof(struct msg_data));
258 msi_data->vector = (u8)vector;
259 msi_data->delivery_mode = MSI_DELIVERY_MODE;
260 msi_data->level = MSI_LEVEL_MODE;
261 msi_data->trigger = MSI_TRIGGER_MODE;
262}
263
264static void msi_address_init(struct msg_address *msi_address)
265{
266 unsigned int dest_id;
267 unsigned long dest_phys_id = cpu_physical_id(MSI_TARGET_CPU);
268
269 memset(msi_address, 0, sizeof(struct msg_address));
270 msi_address->hi_address = (u32)0;
271 dest_id = (MSI_ADDRESS_HEADER << MSI_ADDRESS_HEADER_SHIFT);
272 msi_address->lo_address.u.dest_mode = MSI_PHYSICAL_MODE;
273 msi_address->lo_address.u.redirection_hint = MSI_REDIRECTION_HINT_MODE;
274 msi_address->lo_address.u.dest_id = dest_id;
275 msi_address->lo_address.value |= (dest_phys_id << MSI_TARGET_CPU_SHIFT);
276}
277
278static int msi_free_vector(struct pci_dev* dev, int vector, int reassign); 268static int msi_free_vector(struct pci_dev* dev, int vector, int reassign);
279static int assign_msi_vector(void) 269static int assign_msi_vector(void)
280{ 270{
@@ -369,13 +359,29 @@ static int msi_init(void)
369 return status; 359 return status;
370 } 360 }
371 361
362 status = msi_arch_init();
363 if (status < 0) {
364 pci_msi_enable = 0;
365 printk(KERN_WARNING
366 "PCI: MSI arch init failed. MSI disabled.\n");
367 return status;
368 }
369
370 if (! msi_ops) {
371 printk(KERN_WARNING
372 "PCI: MSI ops not registered. MSI disabled.\n");
373 status = -EINVAL;
374 return status;
375 }
376
377 last_alloc_vector = assign_irq_vector(AUTO_ASSIGN);
372 status = msi_cache_init(); 378 status = msi_cache_init();
373 if (status < 0) { 379 if (status < 0) {
374 pci_msi_enable = 0; 380 pci_msi_enable = 0;
375 printk(KERN_WARNING "PCI: MSI cache init failed\n"); 381 printk(KERN_WARNING "PCI: MSI cache init failed\n");
376 return status; 382 return status;
377 } 383 }
378 last_alloc_vector = assign_irq_vector(AUTO_ASSIGN); 384
379 if (last_alloc_vector < 0) { 385 if (last_alloc_vector < 0) {
380 pci_msi_enable = 0; 386 pci_msi_enable = 0;
381 printk(KERN_WARNING "PCI: No interrupt vectors available for MSI\n"); 387 printk(KERN_WARNING "PCI: No interrupt vectors available for MSI\n");
@@ -442,9 +448,11 @@ static void enable_msi_mode(struct pci_dev *dev, int pos, int type)
442 /* Set enabled bits to single MSI & enable MSI_enable bit */ 448 /* Set enabled bits to single MSI & enable MSI_enable bit */
443 msi_enable(control, 1); 449 msi_enable(control, 1);
444 pci_write_config_word(dev, msi_control_reg(pos), control); 450 pci_write_config_word(dev, msi_control_reg(pos), control);
451 dev->msi_enabled = 1;
445 } else { 452 } else {
446 msix_enable(control); 453 msix_enable(control);
447 pci_write_config_word(dev, msi_control_reg(pos), control); 454 pci_write_config_word(dev, msi_control_reg(pos), control);
455 dev->msix_enabled = 1;
448 } 456 }
449 if (pci_find_capability(dev, PCI_CAP_ID_EXP)) { 457 if (pci_find_capability(dev, PCI_CAP_ID_EXP)) {
450 /* PCI Express Endpoint device detected */ 458 /* PCI Express Endpoint device detected */
@@ -461,9 +469,11 @@ void disable_msi_mode(struct pci_dev *dev, int pos, int type)
461 /* Set enabled bits to single MSI & enable MSI_enable bit */ 469 /* Set enabled bits to single MSI & enable MSI_enable bit */
462 msi_disable(control); 470 msi_disable(control);
463 pci_write_config_word(dev, msi_control_reg(pos), control); 471 pci_write_config_word(dev, msi_control_reg(pos), control);
472 dev->msi_enabled = 0;
464 } else { 473 } else {
465 msix_disable(control); 474 msix_disable(control);
466 pci_write_config_word(dev, msi_control_reg(pos), control); 475 pci_write_config_word(dev, msi_control_reg(pos), control);
476 dev->msix_enabled = 0;
467 } 477 }
468 if (pci_find_capability(dev, PCI_CAP_ID_EXP)) { 478 if (pci_find_capability(dev, PCI_CAP_ID_EXP)) {
469 /* PCI Express Endpoint device detected */ 479 /* PCI Express Endpoint device detected */
@@ -538,7 +548,6 @@ int pci_save_msi_state(struct pci_dev *dev)
538 pci_read_config_dword(dev, pos + PCI_MSI_DATA_32, &cap[i++]); 548 pci_read_config_dword(dev, pos + PCI_MSI_DATA_32, &cap[i++]);
539 if (control & PCI_MSI_FLAGS_MASKBIT) 549 if (control & PCI_MSI_FLAGS_MASKBIT)
540 pci_read_config_dword(dev, pos + PCI_MSI_MASK_BIT, &cap[i++]); 550 pci_read_config_dword(dev, pos + PCI_MSI_MASK_BIT, &cap[i++]);
541 disable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
542 save_state->cap_nr = PCI_CAP_ID_MSI; 551 save_state->cap_nr = PCI_CAP_ID_MSI;
543 pci_add_saved_cap(dev, save_state); 552 pci_add_saved_cap(dev, save_state);
544 return 0; 553 return 0;
@@ -575,6 +584,8 @@ void pci_restore_msi_state(struct pci_dev *dev)
575int pci_save_msix_state(struct pci_dev *dev) 584int pci_save_msix_state(struct pci_dev *dev)
576{ 585{
577 int pos; 586 int pos;
587 int temp;
588 int vector, head, tail = 0;
578 u16 control; 589 u16 control;
579 struct pci_cap_saved_state *save_state; 590 struct pci_cap_saved_state *save_state;
580 591
@@ -582,6 +593,7 @@ int pci_save_msix_state(struct pci_dev *dev)
582 if (pos <= 0 || dev->no_msi) 593 if (pos <= 0 || dev->no_msi)
583 return 0; 594 return 0;
584 595
596 /* save the capability */
585 pci_read_config_word(dev, msi_control_reg(pos), &control); 597 pci_read_config_word(dev, msi_control_reg(pos), &control);
586 if (!(control & PCI_MSIX_FLAGS_ENABLE)) 598 if (!(control & PCI_MSIX_FLAGS_ENABLE))
587 return 0; 599 return 0;
@@ -593,7 +605,38 @@ int pci_save_msix_state(struct pci_dev *dev)
593 } 605 }
594 *((u16 *)&save_state->data[0]) = control; 606 *((u16 *)&save_state->data[0]) = control;
595 607
596 disable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); 608 /* save the table */
609 temp = dev->irq;
610 if (msi_lookup_vector(dev, PCI_CAP_ID_MSIX)) {
611 kfree(save_state);
612 return -EINVAL;
613 }
614
615 vector = head = dev->irq;
616 while (head != tail) {
617 int j;
618 void __iomem *base;
619 struct msi_desc *entry;
620
621 entry = msi_desc[vector];
622 base = entry->mask_base;
623 j = entry->msi_attrib.entry_nr;
624
625 entry->address_lo_save =
626 readl(base + j * PCI_MSIX_ENTRY_SIZE +
627 PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
628 entry->address_hi_save =
629 readl(base + j * PCI_MSIX_ENTRY_SIZE +
630 PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
631 entry->data_save =
632 readl(base + j * PCI_MSIX_ENTRY_SIZE +
633 PCI_MSIX_ENTRY_DATA_OFFSET);
634
635 tail = msi_desc[vector]->link.tail;
636 vector = tail;
637 }
638 dev->irq = temp;
639
597 save_state->cap_nr = PCI_CAP_ID_MSIX; 640 save_state->cap_nr = PCI_CAP_ID_MSIX;
598 pci_add_saved_cap(dev, save_state); 641 pci_add_saved_cap(dev, save_state);
599 return 0; 642 return 0;
@@ -606,8 +649,6 @@ void pci_restore_msix_state(struct pci_dev *dev)
606 int vector, head, tail = 0; 649 int vector, head, tail = 0;
607 void __iomem *base; 650 void __iomem *base;
608 int j; 651 int j;
609 struct msg_address address;
610 struct msg_data data;
611 struct msi_desc *entry; 652 struct msi_desc *entry;
612 int temp; 653 int temp;
613 struct pci_cap_saved_state *save_state; 654 struct pci_cap_saved_state *save_state;
@@ -633,20 +674,13 @@ void pci_restore_msix_state(struct pci_dev *dev)
633 base = entry->mask_base; 674 base = entry->mask_base;
634 j = entry->msi_attrib.entry_nr; 675 j = entry->msi_attrib.entry_nr;
635 676
636 msi_address_init(&address); 677 writel(entry->address_lo_save,
637 msi_data_init(&data, vector);
638
639 address.lo_address.value &= MSI_ADDRESS_DEST_ID_MASK;
640 address.lo_address.value |= entry->msi_attrib.current_cpu <<
641 MSI_TARGET_CPU_SHIFT;
642
643 writel(address.lo_address.value,
644 base + j * PCI_MSIX_ENTRY_SIZE + 678 base + j * PCI_MSIX_ENTRY_SIZE +
645 PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET); 679 PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
646 writel(address.hi_address, 680 writel(entry->address_hi_save,
647 base + j * PCI_MSIX_ENTRY_SIZE + 681 base + j * PCI_MSIX_ENTRY_SIZE +
648 PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET); 682 PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
649 writel(*(u32*)&data, 683 writel(entry->data_save,
650 base + j * PCI_MSIX_ENTRY_SIZE + 684 base + j * PCI_MSIX_ENTRY_SIZE +
651 PCI_MSIX_ENTRY_DATA_OFFSET); 685 PCI_MSIX_ENTRY_DATA_OFFSET);
652 686
@@ -660,30 +694,32 @@ void pci_restore_msix_state(struct pci_dev *dev)
660} 694}
661#endif 695#endif
662 696
663static void msi_register_init(struct pci_dev *dev, struct msi_desc *entry) 697static int msi_register_init(struct pci_dev *dev, struct msi_desc *entry)
664{ 698{
665 struct msg_address address; 699 int status;
666 struct msg_data data; 700 u32 address_hi;
701 u32 address_lo;
702 u32 data;
667 int pos, vector = dev->irq; 703 int pos, vector = dev->irq;
668 u16 control; 704 u16 control;
669 705
670 pos = pci_find_capability(dev, PCI_CAP_ID_MSI); 706 pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
671 pci_read_config_word(dev, msi_control_reg(pos), &control); 707 pci_read_config_word(dev, msi_control_reg(pos), &control);
708
672 /* Configure MSI capability structure */ 709 /* Configure MSI capability structure */
673 msi_address_init(&address); 710 status = msi_ops->setup(dev, vector, &address_hi, &address_lo, &data);
674 msi_data_init(&data, vector); 711 if (status < 0)
675 entry->msi_attrib.current_cpu = ((address.lo_address.u.dest_id >> 712 return status;
676 MSI_TARGET_CPU_SHIFT) & MSI_TARGET_CPU_MASK); 713
677 pci_write_config_dword(dev, msi_lower_address_reg(pos), 714 pci_write_config_dword(dev, msi_lower_address_reg(pos), address_lo);
678 address.lo_address.value);
679 if (is_64bit_address(control)) { 715 if (is_64bit_address(control)) {
680 pci_write_config_dword(dev, 716 pci_write_config_dword(dev,
681 msi_upper_address_reg(pos), address.hi_address); 717 msi_upper_address_reg(pos), address_hi);
682 pci_write_config_word(dev, 718 pci_write_config_word(dev,
683 msi_data_reg(pos, 1), *((u32*)&data)); 719 msi_data_reg(pos, 1), data);
684 } else 720 } else
685 pci_write_config_word(dev, 721 pci_write_config_word(dev,
686 msi_data_reg(pos, 0), *((u32*)&data)); 722 msi_data_reg(pos, 0), data);
687 if (entry->msi_attrib.maskbit) { 723 if (entry->msi_attrib.maskbit) {
688 unsigned int maskbits, temp; 724 unsigned int maskbits, temp;
689 /* All MSIs are unmasked by default, Mask them all */ 725 /* All MSIs are unmasked by default, Mask them all */
@@ -697,6 +733,8 @@ static void msi_register_init(struct pci_dev *dev, struct msi_desc *entry)
697 msi_mask_bits_reg(pos, is_64bit_address(control)), 733 msi_mask_bits_reg(pos, is_64bit_address(control)),
698 maskbits); 734 maskbits);
699 } 735 }
736
737 return 0;
700} 738}
701 739
702/** 740/**
@@ -710,6 +748,7 @@ static void msi_register_init(struct pci_dev *dev, struct msi_desc *entry)
710 **/ 748 **/
711static int msi_capability_init(struct pci_dev *dev) 749static int msi_capability_init(struct pci_dev *dev)
712{ 750{
751 int status;
713 struct msi_desc *entry; 752 struct msi_desc *entry;
714 int pos, vector; 753 int pos, vector;
715 u16 control; 754 u16 control;
@@ -742,7 +781,12 @@ static int msi_capability_init(struct pci_dev *dev)
742 /* Replace with MSI handler */ 781 /* Replace with MSI handler */
743 irq_handler_init(PCI_CAP_ID_MSI, vector, entry->msi_attrib.maskbit); 782 irq_handler_init(PCI_CAP_ID_MSI, vector, entry->msi_attrib.maskbit);
744 /* Configure MSI capability structure */ 783 /* Configure MSI capability structure */
745 msi_register_init(dev, entry); 784 status = msi_register_init(dev, entry);
785 if (status != 0) {
786 dev->irq = entry->msi_attrib.default_vector;
787 kmem_cache_free(msi_cachep, entry);
788 return status;
789 }
746 790
747 attach_msi_entry(entry, vector); 791 attach_msi_entry(entry, vector);
748 /* Set MSI enabled bits */ 792 /* Set MSI enabled bits */
@@ -765,8 +809,10 @@ static int msix_capability_init(struct pci_dev *dev,
765 struct msix_entry *entries, int nvec) 809 struct msix_entry *entries, int nvec)
766{ 810{
767 struct msi_desc *head = NULL, *tail = NULL, *entry = NULL; 811 struct msi_desc *head = NULL, *tail = NULL, *entry = NULL;
768 struct msg_address address; 812 u32 address_hi;
769 struct msg_data data; 813 u32 address_lo;
814 u32 data;
815 int status;
770 int vector, pos, i, j, nr_entries, temp = 0; 816 int vector, pos, i, j, nr_entries, temp = 0;
771 unsigned long phys_addr; 817 unsigned long phys_addr;
772 u32 table_offset; 818 u32 table_offset;
@@ -822,18 +868,20 @@ static int msix_capability_init(struct pci_dev *dev,
822 /* Replace with MSI-X handler */ 868 /* Replace with MSI-X handler */
823 irq_handler_init(PCI_CAP_ID_MSIX, vector, 1); 869 irq_handler_init(PCI_CAP_ID_MSIX, vector, 1);
824 /* Configure MSI-X capability structure */ 870 /* Configure MSI-X capability structure */
825 msi_address_init(&address); 871 status = msi_ops->setup(dev, vector,
826 msi_data_init(&data, vector); 872 &address_hi,
827 entry->msi_attrib.current_cpu = 873 &address_lo,
828 ((address.lo_address.u.dest_id >> 874 &data);
829 MSI_TARGET_CPU_SHIFT) & MSI_TARGET_CPU_MASK); 875 if (status < 0)
830 writel(address.lo_address.value, 876 break;
877
878 writel(address_lo,
831 base + j * PCI_MSIX_ENTRY_SIZE + 879 base + j * PCI_MSIX_ENTRY_SIZE +
832 PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET); 880 PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
833 writel(address.hi_address, 881 writel(address_hi,
834 base + j * PCI_MSIX_ENTRY_SIZE + 882 base + j * PCI_MSIX_ENTRY_SIZE +
835 PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET); 883 PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
836 writel(*(u32*)&data, 884 writel(data,
837 base + j * PCI_MSIX_ENTRY_SIZE + 885 base + j * PCI_MSIX_ENTRY_SIZE +
838 PCI_MSIX_ENTRY_DATA_OFFSET); 886 PCI_MSIX_ENTRY_DATA_OFFSET);
839 attach_msi_entry(entry, vector); 887 attach_msi_entry(entry, vector);
@@ -865,6 +913,7 @@ static int msix_capability_init(struct pci_dev *dev,
865 **/ 913 **/
866int pci_enable_msi(struct pci_dev* dev) 914int pci_enable_msi(struct pci_dev* dev)
867{ 915{
916 struct pci_bus *bus;
868 int pos, temp, status = -EINVAL; 917 int pos, temp, status = -EINVAL;
869 u16 control; 918 u16 control;
870 919
@@ -874,8 +923,9 @@ int pci_enable_msi(struct pci_dev* dev)
874 if (dev->no_msi) 923 if (dev->no_msi)
875 return status; 924 return status;
876 925
877 if (dev->bus->bus_flags & PCI_BUS_FLAGS_NO_MSI) 926 for (bus = dev->bus; bus; bus = bus->parent)
878 return -EINVAL; 927 if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI)
928 return -EINVAL;
879 929
880 temp = dev->irq; 930 temp = dev->irq;
881 931
@@ -887,23 +937,23 @@ int pci_enable_msi(struct pci_dev* dev)
887 if (!pos) 937 if (!pos)
888 return -EINVAL; 938 return -EINVAL;
889 939
890 pci_read_config_word(dev, msi_control_reg(pos), &control);
891 if (control & PCI_MSI_FLAGS_ENABLE)
892 return 0; /* Already in MSI mode */
893
894 if (!msi_lookup_vector(dev, PCI_CAP_ID_MSI)) { 940 if (!msi_lookup_vector(dev, PCI_CAP_ID_MSI)) {
895 /* Lookup Sucess */ 941 /* Lookup Sucess */
896 unsigned long flags; 942 unsigned long flags;
897 943
944 pci_read_config_word(dev, msi_control_reg(pos), &control);
945 if (control & PCI_MSI_FLAGS_ENABLE)
946 return 0; /* Already in MSI mode */
898 spin_lock_irqsave(&msi_lock, flags); 947 spin_lock_irqsave(&msi_lock, flags);
899 if (!vector_irq[dev->irq]) { 948 if (!vector_irq[dev->irq]) {
900 msi_desc[dev->irq]->msi_attrib.state = 0; 949 msi_desc[dev->irq]->msi_attrib.state = 0;
901 vector_irq[dev->irq] = -1; 950 vector_irq[dev->irq] = -1;
902 nr_released_vectors--; 951 nr_released_vectors--;
903 spin_unlock_irqrestore(&msi_lock, flags); 952 spin_unlock_irqrestore(&msi_lock, flags);
904 msi_register_init(dev, msi_desc[dev->irq]); 953 status = msi_register_init(dev, msi_desc[dev->irq]);
905 enable_msi_mode(dev, pos, PCI_CAP_ID_MSI); 954 if (status == 0)
906 return 0; 955 enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
956 return status;
907 } 957 }
908 spin_unlock_irqrestore(&msi_lock, flags); 958 spin_unlock_irqrestore(&msi_lock, flags);
909 dev->irq = temp; 959 dev->irq = temp;
@@ -980,6 +1030,8 @@ static int msi_free_vector(struct pci_dev* dev, int vector, int reassign)
980 void __iomem *base; 1030 void __iomem *base;
981 unsigned long flags; 1031 unsigned long flags;
982 1032
1033 msi_ops->teardown(vector);
1034
983 spin_lock_irqsave(&msi_lock, flags); 1035 spin_lock_irqsave(&msi_lock, flags);
984 entry = msi_desc[vector]; 1036 entry = msi_desc[vector];
985 if (!entry || entry->dev != dev) { 1037 if (!entry || entry->dev != dev) {
@@ -1008,33 +1060,8 @@ static int msi_free_vector(struct pci_dev* dev, int vector, int reassign)
1008 entry_nr * PCI_MSIX_ENTRY_SIZE + 1060 entry_nr * PCI_MSIX_ENTRY_SIZE +
1009 PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET); 1061 PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
1010 1062
1011 if (head == vector) { 1063 if (head == vector)
1012 /*
1013 * Detect last MSI-X vector to be released.
1014 * Release the MSI-X memory-mapped table.
1015 */
1016#if 0
1017 int pos, nr_entries;
1018 unsigned long phys_addr;
1019 u32 table_offset;
1020 u16 control;
1021 u8 bir;
1022
1023 pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
1024 pci_read_config_word(dev, msi_control_reg(pos),
1025 &control);
1026 nr_entries = multi_msix_capable(control);
1027 pci_read_config_dword(dev, msix_table_offset_reg(pos),
1028 &table_offset);
1029 bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK);
1030 table_offset &= ~PCI_MSIX_FLAGS_BIRMASK;
1031 phys_addr = pci_resource_start(dev, bir) + table_offset;
1032/*
1033 * FIXME! and what did you want to do with phys_addr?
1034 */
1035#endif
1036 iounmap(base); 1064 iounmap(base);
1037 }
1038 } 1065 }
1039 1066
1040 return 0; 1067 return 0;
@@ -1108,6 +1135,7 @@ static int reroute_msix_table(int head, struct msix_entry *entries, int *nvec)
1108 **/ 1135 **/
1109int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) 1136int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
1110{ 1137{
1138 struct pci_bus *bus;
1111 int status, pos, nr_entries, free_vectors; 1139 int status, pos, nr_entries, free_vectors;
1112 int i, j, temp; 1140 int i, j, temp;
1113 u16 control; 1141 u16 control;
@@ -1116,6 +1144,13 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
1116 if (!pci_msi_enable || !dev || !entries) 1144 if (!pci_msi_enable || !dev || !entries)
1117 return -EINVAL; 1145 return -EINVAL;
1118 1146
1147 if (dev->no_msi)
1148 return -EINVAL;
1149
1150 for (bus = dev->bus; bus; bus = bus->parent)
1151 if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI)
1152 return -EINVAL;
1153
1119 status = msi_init(); 1154 status = msi_init();
1120 if (status < 0) 1155 if (status < 0)
1121 return status; 1156 return status;
@@ -1300,24 +1335,6 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev)
1300 } 1335 }
1301 msi_free_vector(dev, vector, 0); 1336 msi_free_vector(dev, vector, 0);
1302 if (warning) { 1337 if (warning) {
1303 /* Force to release the MSI-X memory-mapped table */
1304#if 0
1305 unsigned long phys_addr;
1306 u32 table_offset;
1307 u16 control;
1308 u8 bir;
1309
1310 pci_read_config_word(dev, msi_control_reg(pos),
1311 &control);
1312 pci_read_config_dword(dev, msix_table_offset_reg(pos),
1313 &table_offset);
1314 bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK);
1315 table_offset &= ~PCI_MSIX_FLAGS_BIRMASK;
1316 phys_addr = pci_resource_start(dev, bir) + table_offset;
1317/*
1318 * FIXME! and what did you want to do with phys_addr?
1319 */
1320#endif
1321 iounmap(base); 1338 iounmap(base);
1322 printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() " 1339 printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() "
1323 "called without free_irq() on all MSI-X vectors\n", 1340 "called without free_irq() on all MSI-X vectors\n",
diff --git a/drivers/pci/msi.h b/drivers/pci/msi.h
index 4ac52d441e47..56951c39d3a3 100644
--- a/drivers/pci/msi.h
+++ b/drivers/pci/msi.h
@@ -6,6 +6,68 @@
6#ifndef MSI_H 6#ifndef MSI_H
7#define MSI_H 7#define MSI_H
8 8
9/*
10 * MSI operation vector. Used by the msi core code (drivers/pci/msi.c)
11 * to abstract platform-specific tasks relating to MSI address generation
12 * and resource management.
13 */
14struct msi_ops {
15 /**
16 * setup - generate an MSI bus address and data for a given vector
17 * @pdev: PCI device context (in)
18 * @vector: vector allocated by the msi core (in)
19 * @addr_hi: upper 32 bits of PCI bus MSI address (out)
20 * @addr_lo: lower 32 bits of PCI bus MSI address (out)
21 * @data: MSI data payload (out)
22 *
23 * Description: The setup op is used to generate a PCI bus addres and
24 * data which the msi core will program into the card MSI capability
25 * registers. The setup routine is responsible for picking an initial
26 * cpu to target the MSI at. The setup routine is responsible for
27 * examining pdev to determine the MSI capabilities of the card and
28 * generating a suitable address/data. The setup routine is
29 * responsible for allocating and tracking any system resources it
30 * needs to route the MSI to the cpu it picks, and for associating
31 * those resources with the passed in vector.
32 *
33 * Returns 0 if the MSI address/data was successfully setup.
34 **/
35
36 int (*setup) (struct pci_dev *pdev, unsigned int vector,
37 u32 *addr_hi, u32 *addr_lo, u32 *data);
38
39 /**
40 * teardown - release resources allocated by setup
41 * @vector: vector context for resources (in)
42 *
43 * Description: The teardown op is used to release any resources
44 * that were allocated in the setup routine associated with the passed
45 * in vector.
46 **/
47
48 void (*teardown) (unsigned int vector);
49
50 /**
51 * target - retarget an MSI at a different cpu
52 * @vector: vector context for resources (in)
53 * @cpu: new cpu to direct vector at (in)
54 * @addr_hi: new value of PCI bus upper 32 bits (in/out)
55 * @addr_lo: new value of PCI bus lower 32 bits (in/out)
56 *
57 * Description: The target op is used to redirect an MSI vector
58 * at a different cpu. addr_hi/addr_lo coming in are the existing
59 * values that the MSI core has programmed into the card. The
60 * target code is responsible for freeing any resources (if any)
61 * associated with the old address, and generating a new PCI bus
62 * addr_hi/addr_lo that will redirect the vector at the indicated cpu.
63 **/
64
65 void (*target) (unsigned int vector, unsigned int cpu,
66 u32 *addr_hi, u32 *addr_lo);
67};
68
69extern int msi_register(struct msi_ops *ops);
70
9#include <asm/msi.h> 71#include <asm/msi.h>
10 72
11/* 73/*
@@ -63,67 +125,6 @@ extern int pci_vector_resources(int last, int nr_released);
63#define msix_mask(address) (address | PCI_MSIX_FLAGS_BITMASK) 125#define msix_mask(address) (address | PCI_MSIX_FLAGS_BITMASK)
64#define msix_is_pending(address) (address & PCI_MSIX_FLAGS_PENDMASK) 126#define msix_is_pending(address) (address & PCI_MSIX_FLAGS_PENDMASK)
65 127
66/*
67 * MSI Defined Data Structures
68 */
69#define MSI_ADDRESS_HEADER 0xfee
70#define MSI_ADDRESS_HEADER_SHIFT 12
71#define MSI_ADDRESS_HEADER_MASK 0xfff000
72#define MSI_ADDRESS_DEST_ID_MASK 0xfff0000f
73#define MSI_TARGET_CPU_MASK 0xff
74#define MSI_DELIVERY_MODE 0
75#define MSI_LEVEL_MODE 1 /* Edge always assert */
76#define MSI_TRIGGER_MODE 0 /* MSI is edge sensitive */
77#define MSI_PHYSICAL_MODE 0
78#define MSI_LOGICAL_MODE 1
79#define MSI_REDIRECTION_HINT_MODE 0
80
81struct msg_data {
82#if defined(__LITTLE_ENDIAN_BITFIELD)
83 __u32 vector : 8;
84 __u32 delivery_mode : 3; /* 000b: FIXED | 001b: lowest prior */
85 __u32 reserved_1 : 3;
86 __u32 level : 1; /* 0: deassert | 1: assert */
87 __u32 trigger : 1; /* 0: edge | 1: level */
88 __u32 reserved_2 : 16;
89#elif defined(__BIG_ENDIAN_BITFIELD)
90 __u32 reserved_2 : 16;
91 __u32 trigger : 1; /* 0: edge | 1: level */
92 __u32 level : 1; /* 0: deassert | 1: assert */
93 __u32 reserved_1 : 3;
94 __u32 delivery_mode : 3; /* 000b: FIXED | 001b: lowest prior */
95 __u32 vector : 8;
96#else
97#error "Bitfield endianness not defined! Check your byteorder.h"
98#endif
99} __attribute__ ((packed));
100
101struct msg_address {
102 union {
103 struct {
104#if defined(__LITTLE_ENDIAN_BITFIELD)
105 __u32 reserved_1 : 2;
106 __u32 dest_mode : 1; /*0:physic | 1:logic */
107 __u32 redirection_hint: 1; /*0: dedicated CPU
108 1: lowest priority */
109 __u32 reserved_2 : 4;
110 __u32 dest_id : 24; /* Destination ID */
111#elif defined(__BIG_ENDIAN_BITFIELD)
112 __u32 dest_id : 24; /* Destination ID */
113 __u32 reserved_2 : 4;
114 __u32 redirection_hint: 1; /*0: dedicated CPU
115 1: lowest priority */
116 __u32 dest_mode : 1; /*0:physic | 1:logic */
117 __u32 reserved_1 : 2;
118#else
119#error "Bitfield endianness not defined! Check your byteorder.h"
120#endif
121 }u;
122 __u32 value;
123 }lo_address;
124 __u32 hi_address;
125} __attribute__ ((packed));
126
127struct msi_desc { 128struct msi_desc {
128 struct { 129 struct {
129 __u8 type : 5; /* {0: unused, 5h:MSI, 11h:MSI-X} */ 130 __u8 type : 5; /* {0: unused, 5h:MSI, 11h:MSI-X} */
@@ -132,7 +133,7 @@ struct msi_desc {
132 __u8 reserved: 1; /* reserved */ 133 __u8 reserved: 1; /* reserved */
133 __u8 entry_nr; /* specific enabled entry */ 134 __u8 entry_nr; /* specific enabled entry */
134 __u8 default_vector; /* default pre-assigned vector */ 135 __u8 default_vector; /* default pre-assigned vector */
135 __u8 current_cpu; /* current destination cpu */ 136 __u8 unused; /* formerly unused destination cpu*/
136 }msi_attrib; 137 }msi_attrib;
137 138
138 struct { 139 struct {
@@ -142,6 +143,14 @@ struct msi_desc {
142 143
143 void __iomem *mask_base; 144 void __iomem *mask_base;
144 struct pci_dev *dev; 145 struct pci_dev *dev;
146
147#ifdef CONFIG_PM
148 /* PM save area for MSIX address/data */
149
150 u32 address_hi_save;
151 u32 address_lo_save;
152 u32 data_save;
153#endif
145}; 154};
146 155
147#endif /* MSI_H */ 156#endif /* MSI_H */
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index c2ecae5ff0c1..bb7456c1dbac 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -267,7 +267,7 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
267 267
268 268
269/* ACPI bus type */ 269/* ACPI bus type */
270static int pci_acpi_find_device(struct device *dev, acpi_handle *handle) 270static int acpi_pci_find_device(struct device *dev, acpi_handle *handle)
271{ 271{
272 struct pci_dev * pci_dev; 272 struct pci_dev * pci_dev;
273 acpi_integer addr; 273 acpi_integer addr;
@@ -281,7 +281,7 @@ static int pci_acpi_find_device(struct device *dev, acpi_handle *handle)
281 return 0; 281 return 0;
282} 282}
283 283
284static int pci_acpi_find_root_bridge(struct device *dev, acpi_handle *handle) 284static int acpi_pci_find_root_bridge(struct device *dev, acpi_handle *handle)
285{ 285{
286 int num; 286 int num;
287 unsigned int seg, bus; 287 unsigned int seg, bus;
@@ -299,21 +299,21 @@ static int pci_acpi_find_root_bridge(struct device *dev, acpi_handle *handle)
299 return 0; 299 return 0;
300} 300}
301 301
302static struct acpi_bus_type pci_acpi_bus = { 302static struct acpi_bus_type acpi_pci_bus = {
303 .bus = &pci_bus_type, 303 .bus = &pci_bus_type,
304 .find_device = pci_acpi_find_device, 304 .find_device = acpi_pci_find_device,
305 .find_bridge = pci_acpi_find_root_bridge, 305 .find_bridge = acpi_pci_find_root_bridge,
306}; 306};
307 307
308static int __init pci_acpi_init(void) 308static int __init acpi_pci_init(void)
309{ 309{
310 int ret; 310 int ret;
311 311
312 ret = register_acpi_bus_type(&pci_acpi_bus); 312 ret = register_acpi_bus_type(&acpi_pci_bus);
313 if (ret) 313 if (ret)
314 return 0; 314 return 0;
315 platform_pci_choose_state = acpi_pci_choose_state; 315 platform_pci_choose_state = acpi_pci_choose_state;
316 platform_pci_set_power_state = acpi_pci_set_power_state; 316 platform_pci_set_power_state = acpi_pci_set_power_state;
317 return 0; 317 return 0;
318} 318}
319arch_initcall(pci_acpi_init); 319arch_initcall(acpi_pci_init);
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 56ac2bc003c7..bc405c035ce3 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -43,6 +43,29 @@ pci_config_attr(subsystem_vendor, "0x%04x\n");
43pci_config_attr(subsystem_device, "0x%04x\n"); 43pci_config_attr(subsystem_device, "0x%04x\n");
44pci_config_attr(class, "0x%06x\n"); 44pci_config_attr(class, "0x%06x\n");
45pci_config_attr(irq, "%u\n"); 45pci_config_attr(irq, "%u\n");
46pci_config_attr(is_enabled, "%u\n");
47
48static ssize_t broken_parity_status_show(struct device *dev,
49 struct device_attribute *attr,
50 char *buf)
51{
52 struct pci_dev *pdev = to_pci_dev(dev);
53 return sprintf (buf, "%u\n", pdev->broken_parity_status);
54}
55
56static ssize_t broken_parity_status_store(struct device *dev,
57 struct device_attribute *attr,
58 const char *buf, size_t count)
59{
60 struct pci_dev *pdev = to_pci_dev(dev);
61 ssize_t consumed = -EINVAL;
62
63 if ((count > 0) && (*buf == '0' || *buf == '1')) {
64 pdev->broken_parity_status = *buf == '1' ? 1 : 0;
65 consumed = count;
66 }
67 return consumed;
68}
46 69
47static ssize_t local_cpus_show(struct device *dev, 70static ssize_t local_cpus_show(struct device *dev,
48 struct device_attribute *attr, char *buf) 71 struct device_attribute *attr, char *buf)
@@ -90,6 +113,25 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
90 (u8)(pci_dev->class >> 16), (u8)(pci_dev->class >> 8), 113 (u8)(pci_dev->class >> 16), (u8)(pci_dev->class >> 8),
91 (u8)(pci_dev->class)); 114 (u8)(pci_dev->class));
92} 115}
116static ssize_t
117is_enabled_store(struct device *dev, struct device_attribute *attr,
118 const char *buf, size_t count)
119{
120 struct pci_dev *pdev = to_pci_dev(dev);
121
122 /* this can crash the machine when done on the "wrong" device */
123 if (!capable(CAP_SYS_ADMIN))
124 return count;
125
126 if (*buf == '0')
127 pci_disable_device(pdev);
128
129 if (*buf == '1')
130 pci_enable_device(pdev);
131
132 return count;
133}
134
93 135
94struct device_attribute pci_dev_attrs[] = { 136struct device_attribute pci_dev_attrs[] = {
95 __ATTR_RO(resource), 137 __ATTR_RO(resource),
@@ -101,6 +143,9 @@ struct device_attribute pci_dev_attrs[] = {
101 __ATTR_RO(irq), 143 __ATTR_RO(irq),
102 __ATTR_RO(local_cpus), 144 __ATTR_RO(local_cpus),
103 __ATTR_RO(modalias), 145 __ATTR_RO(modalias),
146 __ATTR(enable, 0600, is_enabled_show, is_enabled_store),
147 __ATTR(broken_parity_status,(S_IRUGO|S_IWUSR),
148 broken_parity_status_show,broken_parity_status_store),
104 __ATTR_NULL, 149 __ATTR_NULL,
105}; 150};
106 151
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index fde41cc14734..d408a3c30426 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -517,7 +517,12 @@ pci_enable_device_bars(struct pci_dev *dev, int bars)
517int 517int
518pci_enable_device(struct pci_dev *dev) 518pci_enable_device(struct pci_dev *dev)
519{ 519{
520 int err = pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1); 520 int err;
521
522 if (dev->is_enabled)
523 return 0;
524
525 err = pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1);
521 if (err) 526 if (err)
522 return err; 527 return err;
523 pci_fixup_device(pci_fixup_enable, dev); 528 pci_fixup_device(pci_fixup_enable, dev);
@@ -546,7 +551,14 @@ void
546pci_disable_device(struct pci_dev *dev) 551pci_disable_device(struct pci_dev *dev)
547{ 552{
548 u16 pci_command; 553 u16 pci_command;
549 554
555 if (dev->msi_enabled)
556 disable_msi_mode(dev, pci_find_capability(dev, PCI_CAP_ID_MSI),
557 PCI_CAP_ID_MSI);
558 if (dev->msix_enabled)
559 disable_msi_mode(dev, pci_find_capability(dev, PCI_CAP_ID_MSI),
560 PCI_CAP_ID_MSIX);
561
550 pci_read_config_word(dev, PCI_COMMAND, &pci_command); 562 pci_read_config_word(dev, PCI_COMMAND, &pci_command);
551 if (pci_command & PCI_COMMAND_MASTER) { 563 if (pci_command & PCI_COMMAND_MASTER) {
552 pci_command &= ~PCI_COMMAND_MASTER; 564 pci_command &= ~PCI_COMMAND_MASTER;
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 30630cbe2fe3..29bdeca031a8 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -40,7 +40,7 @@ extern int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int
40extern void pci_remove_legacy_files(struct pci_bus *bus); 40extern void pci_remove_legacy_files(struct pci_bus *bus);
41 41
42/* Lock for read/write access to pci device and bus lists */ 42/* Lock for read/write access to pci device and bus lists */
43extern spinlock_t pci_bus_lock; 43extern struct rw_semaphore pci_bus_sem;
44 44
45#ifdef CONFIG_X86_IO_APIC 45#ifdef CONFIG_X86_IO_APIC
46extern int pci_msi_quirk; 46extern int pci_msi_quirk;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index a10ed9dab2c2..f89dbc3738b7 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -180,25 +180,31 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
180 res->flags |= pci_calc_resource_flags(l); 180 res->flags |= pci_calc_resource_flags(l);
181 if ((l & (PCI_BASE_ADDRESS_SPACE | PCI_BASE_ADDRESS_MEM_TYPE_MASK)) 181 if ((l & (PCI_BASE_ADDRESS_SPACE | PCI_BASE_ADDRESS_MEM_TYPE_MASK))
182 == (PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64)) { 182 == (PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64)) {
183 pci_read_config_dword(dev, reg+4, &l); 183 u32 szhi, lhi;
184 pci_read_config_dword(dev, reg+4, &lhi);
185 pci_write_config_dword(dev, reg+4, ~0);
186 pci_read_config_dword(dev, reg+4, &szhi);
187 pci_write_config_dword(dev, reg+4, lhi);
188 szhi = pci_size(lhi, szhi, 0xffffffff);
184 next++; 189 next++;
185#if BITS_PER_LONG == 64 190#if BITS_PER_LONG == 64
186 res->start |= ((unsigned long) l) << 32; 191 res->start |= ((unsigned long) lhi) << 32;
187 res->end = res->start + sz; 192 res->end = res->start + sz;
188 pci_write_config_dword(dev, reg+4, ~0); 193 if (szhi) {
189 pci_read_config_dword(dev, reg+4, &sz);
190 pci_write_config_dword(dev, reg+4, l);
191 sz = pci_size(l, sz, 0xffffffff);
192 if (sz) {
193 /* This BAR needs > 4GB? Wow. */ 194 /* This BAR needs > 4GB? Wow. */
194 res->end |= (unsigned long)sz<<32; 195 res->end |= (unsigned long)szhi<<32;
195 } 196 }
196#else 197#else
197 if (l) { 198 if (szhi) {
198 printk(KERN_ERR "PCI: Unable to handle 64-bit address for device %s\n", pci_name(dev)); 199 printk(KERN_ERR "PCI: Unable to handle 64-bit BAR for device %s\n", pci_name(dev));
199 res->start = 0; 200 res->start = 0;
200 res->flags = 0; 201 res->flags = 0;
201 continue; 202 } else if (lhi) {
203 /* 64-bit wide address, treat as disabled */
204 pci_write_config_dword(dev, reg, l & ~(u32)PCI_BASE_ADDRESS_MEM_MASK);
205 pci_write_config_dword(dev, reg+4, 0);
206 res->start = 0;
207 res->end = sz;
202 } 208 }
203#endif 209#endif
204 } 210 }
@@ -377,9 +383,9 @@ struct pci_bus * __devinit pci_add_new_bus(struct pci_bus *parent, struct pci_de
377 383
378 child = pci_alloc_child_bus(parent, dev, busnr); 384 child = pci_alloc_child_bus(parent, dev, busnr);
379 if (child) { 385 if (child) {
380 spin_lock(&pci_bus_lock); 386 down_write(&pci_bus_sem);
381 list_add_tail(&child->node, &parent->children); 387 list_add_tail(&child->node, &parent->children);
382 spin_unlock(&pci_bus_lock); 388 up_write(&pci_bus_sem);
383 } 389 }
384 return child; 390 return child;
385} 391}
@@ -838,9 +844,9 @@ void __devinit pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
838 * and the bus list for fixup functions, etc. 844 * and the bus list for fixup functions, etc.
839 */ 845 */
840 INIT_LIST_HEAD(&dev->global_list); 846 INIT_LIST_HEAD(&dev->global_list);
841 spin_lock(&pci_bus_lock); 847 down_write(&pci_bus_sem);
842 list_add_tail(&dev->bus_list, &bus->devices); 848 list_add_tail(&dev->bus_list, &bus->devices);
843 spin_unlock(&pci_bus_lock); 849 up_write(&pci_bus_sem);
844} 850}
845 851
846struct pci_dev * __devinit 852struct pci_dev * __devinit
@@ -975,9 +981,10 @@ struct pci_bus * __devinit pci_create_bus(struct device *parent,
975 pr_debug("PCI: Bus %04x:%02x already known\n", pci_domain_nr(b), bus); 981 pr_debug("PCI: Bus %04x:%02x already known\n", pci_domain_nr(b), bus);
976 goto err_out; 982 goto err_out;
977 } 983 }
978 spin_lock(&pci_bus_lock); 984
985 down_write(&pci_bus_sem);
979 list_add_tail(&b->node, &pci_root_buses); 986 list_add_tail(&b->node, &pci_root_buses);
980 spin_unlock(&pci_bus_lock); 987 up_write(&pci_bus_sem);
981 988
982 memset(dev, 0, sizeof(*dev)); 989 memset(dev, 0, sizeof(*dev));
983 dev->parent = parent; 990 dev->parent = parent;
@@ -1017,9 +1024,9 @@ class_dev_create_file_err:
1017class_dev_reg_err: 1024class_dev_reg_err:
1018 device_unregister(dev); 1025 device_unregister(dev);
1019dev_reg_err: 1026dev_reg_err:
1020 spin_lock(&pci_bus_lock); 1027 down_write(&pci_bus_sem);
1021 list_del(&b->node); 1028 list_del(&b->node);
1022 spin_unlock(&pci_bus_lock); 1029 up_write(&pci_bus_sem);
1023err_out: 1030err_out:
1024 kfree(dev); 1031 kfree(dev);
1025 kfree(b); 1032 kfree(b);
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index d378478612fb..4364d793f73b 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -24,6 +24,17 @@
24#include <linux/acpi.h> 24#include <linux/acpi.h>
25#include "pci.h" 25#include "pci.h"
26 26
27/* The Mellanox Tavor device gives false positive parity errors
28 * Mark this device with a broken_parity_status, to allow
29 * PCI scanning code to "skip" this now blacklisted device.
30 */
31static void __devinit quirk_mellanox_tavor(struct pci_dev *dev)
32{
33 dev->broken_parity_status = 1; /* This device gives false positives */
34}
35DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_MELLANOX,PCI_DEVICE_ID_MELLANOX_TAVOR,quirk_mellanox_tavor);
36DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_MELLANOX,PCI_DEVICE_ID_MELLANOX_TAVOR_BRIDGE,quirk_mellanox_tavor);
37
27/* Deal with broken BIOS'es that neglect to enable passive release, 38/* Deal with broken BIOS'es that neglect to enable passive release,
28 which can cause problems in combination with the 82441FX/PPro MTRRs */ 39 which can cause problems in combination with the 82441FX/PPro MTRRs */
29static void __devinit quirk_passive_release(struct pci_dev *dev) 40static void __devinit quirk_passive_release(struct pci_dev *dev)
@@ -878,27 +889,30 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82375, quirk_e
878 * when a PCI-Soundcard is added. The BIOS only gives Options 889 * when a PCI-Soundcard is added. The BIOS only gives Options
879 * "Disabled" and "AUTO". This Quirk Sets the corresponding 890 * "Disabled" and "AUTO". This Quirk Sets the corresponding
880 * Register-Value to enable the Soundcard. 891 * Register-Value to enable the Soundcard.
892 *
893 * FIXME: Presently this quirk will run on anything that has an 8237
894 * which isn't correct, we need to check DMI tables or something in
895 * order to make sure it only runs on the MSI-K8T-Neo2Fir. Because it
896 * runs everywhere at present we suppress the printk output in most
897 * irrelevant cases.
881 */ 898 */
882static void __init k8t_sound_hostbridge(struct pci_dev *dev) 899static void __init k8t_sound_hostbridge(struct pci_dev *dev)
883{ 900{
884 unsigned char val; 901 unsigned char val;
885 902
886 printk(KERN_INFO "PCI: Quirk-MSI-K8T Soundcard On\n");
887 pci_read_config_byte(dev, 0x50, &val); 903 pci_read_config_byte(dev, 0x50, &val);
888 if (val == 0x88 || val == 0xc8) { 904 if (val == 0x88 || val == 0xc8) {
905 /* Assume it's probably a MSI-K8T-Neo2Fir */
906 printk(KERN_INFO "PCI: MSI-K8T-Neo2Fir, attempting to turn soundcard ON\n");
889 pci_write_config_byte(dev, 0x50, val & (~0x40)); 907 pci_write_config_byte(dev, 0x50, val & (~0x40));
890 908
891 /* Verify the Change for Status output */ 909 /* Verify the Change for Status output */
892 pci_read_config_byte(dev, 0x50, &val); 910 pci_read_config_byte(dev, 0x50, &val);
893 if (val & 0x40) 911 if (val & 0x40)
894 printk(KERN_INFO "PCI: MSI-K8T soundcard still off\n"); 912 printk(KERN_INFO "PCI: MSI-K8T-Neo2Fir, soundcard still off\n");
895 else 913 else
896 printk(KERN_INFO "PCI: MSI-K8T soundcard on\n"); 914 printk(KERN_INFO "PCI: MSI-K8T-Neo2Fir, soundcard on\n");
897 } else {
898 printk(KERN_INFO "PCI: Unexpected Value in PCI-Register: "
899 "no Change!\n");
900 } 915 }
901
902} 916}
903DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_hostbridge); 917DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_hostbridge);
904 918
@@ -1485,6 +1499,25 @@ static void __devinit quirk_p64h2_1k_io(struct pci_dev *dev)
1485} 1499}
1486DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1460, quirk_p64h2_1k_io); 1500DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1460, quirk_p64h2_1k_io);
1487 1501
1502/* Under some circumstances, AER is not linked with extended capabilities.
1503 * Force it to be linked by setting the corresponding control bit in the
1504 * config space.
1505 */
1506static void __devinit quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev)
1507{
1508 uint8_t b;
1509 if (pci_read_config_byte(dev, 0xf41, &b) == 0) {
1510 if (!(b & 0x20)) {
1511 pci_write_config_byte(dev, 0xf41, b | 0x20);
1512 printk(KERN_INFO
1513 "PCI: Linking AER extended capability on %s\n",
1514 pci_name(dev));
1515 }
1516 }
1517}
1518DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
1519 quirk_nvidia_ck804_pcie_aer_ext_cap);
1520
1488EXPORT_SYMBOL(pcie_mch_quirk); 1521EXPORT_SYMBOL(pcie_mch_quirk);
1489#ifdef CONFIG_HOTPLUG 1522#ifdef CONFIG_HOTPLUG
1490EXPORT_SYMBOL(pci_fixup_device); 1523EXPORT_SYMBOL(pci_fixup_device);
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index 1a6bf9de166f..99ffbd478b29 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -22,18 +22,18 @@ static void pci_destroy_dev(struct pci_dev *dev)
22 pci_proc_detach_device(dev); 22 pci_proc_detach_device(dev);
23 pci_remove_sysfs_dev_files(dev); 23 pci_remove_sysfs_dev_files(dev);
24 device_unregister(&dev->dev); 24 device_unregister(&dev->dev);
25 spin_lock(&pci_bus_lock); 25 down_write(&pci_bus_sem);
26 list_del(&dev->global_list); 26 list_del(&dev->global_list);
27 dev->global_list.next = dev->global_list.prev = NULL; 27 dev->global_list.next = dev->global_list.prev = NULL;
28 spin_unlock(&pci_bus_lock); 28 up_write(&pci_bus_sem);
29 } 29 }
30 30
31 /* Remove the device from the device lists, and prevent any further 31 /* Remove the device from the device lists, and prevent any further
32 * list accesses from this device */ 32 * list accesses from this device */
33 spin_lock(&pci_bus_lock); 33 down_write(&pci_bus_sem);
34 list_del(&dev->bus_list); 34 list_del(&dev->bus_list);
35 dev->bus_list.next = dev->bus_list.prev = NULL; 35 dev->bus_list.next = dev->bus_list.prev = NULL;
36 spin_unlock(&pci_bus_lock); 36 up_write(&pci_bus_sem);
37 37
38 pci_free_resources(dev); 38 pci_free_resources(dev);
39 pci_dev_put(dev); 39 pci_dev_put(dev);
@@ -62,9 +62,9 @@ void pci_remove_bus(struct pci_bus *pci_bus)
62{ 62{
63 pci_proc_detach_bus(pci_bus); 63 pci_proc_detach_bus(pci_bus);
64 64
65 spin_lock(&pci_bus_lock); 65 down_write(&pci_bus_sem);
66 list_del(&pci_bus->node); 66 list_del(&pci_bus->node);
67 spin_unlock(&pci_bus_lock); 67 up_write(&pci_bus_sem);
68 pci_remove_legacy_files(pci_bus); 68 pci_remove_legacy_files(pci_bus);
69 class_device_remove_file(&pci_bus->class_dev, 69 class_device_remove_file(&pci_bus->class_dev,
70 &class_device_attr_cpuaffinity); 70 &class_device_attr_cpuaffinity);
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index ce7dd6e7be60..622b3f8ba820 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -13,7 +13,7 @@
13#include <linux/interrupt.h> 13#include <linux/interrupt.h>
14#include "pci.h" 14#include "pci.h"
15 15
16DEFINE_SPINLOCK(pci_bus_lock); 16DECLARE_RWSEM(pci_bus_sem);
17 17
18static struct pci_bus * __devinit 18static struct pci_bus * __devinit
19pci_do_find_bus(struct pci_bus* bus, unsigned char busnr) 19pci_do_find_bus(struct pci_bus* bus, unsigned char busnr)
@@ -72,11 +72,11 @@ pci_find_next_bus(const struct pci_bus *from)
72 struct pci_bus *b = NULL; 72 struct pci_bus *b = NULL;
73 73
74 WARN_ON(in_interrupt()); 74 WARN_ON(in_interrupt());
75 spin_lock(&pci_bus_lock); 75 down_read(&pci_bus_sem);
76 n = from ? from->node.next : pci_root_buses.next; 76 n = from ? from->node.next : pci_root_buses.next;
77 if (n != &pci_root_buses) 77 if (n != &pci_root_buses)
78 b = pci_bus_b(n); 78 b = pci_bus_b(n);
79 spin_unlock(&pci_bus_lock); 79 up_read(&pci_bus_sem);
80 return b; 80 return b;
81} 81}
82 82
@@ -124,7 +124,7 @@ struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn)
124 struct pci_dev *dev; 124 struct pci_dev *dev;
125 125
126 WARN_ON(in_interrupt()); 126 WARN_ON(in_interrupt());
127 spin_lock(&pci_bus_lock); 127 down_read(&pci_bus_sem);
128 128
129 list_for_each(tmp, &bus->devices) { 129 list_for_each(tmp, &bus->devices) {
130 dev = pci_dev_b(tmp); 130 dev = pci_dev_b(tmp);
@@ -135,7 +135,7 @@ struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn)
135 dev = NULL; 135 dev = NULL;
136 out: 136 out:
137 pci_dev_get(dev); 137 pci_dev_get(dev);
138 spin_unlock(&pci_bus_lock); 138 up_read(&pci_bus_sem);
139 return dev; 139 return dev;
140} 140}
141 141
@@ -167,7 +167,7 @@ static struct pci_dev * pci_find_subsys(unsigned int vendor,
167 struct pci_dev *dev; 167 struct pci_dev *dev;
168 168
169 WARN_ON(in_interrupt()); 169 WARN_ON(in_interrupt());
170 spin_lock(&pci_bus_lock); 170 down_read(&pci_bus_sem);
171 n = from ? from->global_list.next : pci_devices.next; 171 n = from ? from->global_list.next : pci_devices.next;
172 172
173 while (n && (n != &pci_devices)) { 173 while (n && (n != &pci_devices)) {
@@ -181,7 +181,7 @@ static struct pci_dev * pci_find_subsys(unsigned int vendor,
181 } 181 }
182 dev = NULL; 182 dev = NULL;
183exit: 183exit:
184 spin_unlock(&pci_bus_lock); 184 up_read(&pci_bus_sem);
185 return dev; 185 return dev;
186} 186}
187 187
@@ -232,7 +232,7 @@ pci_get_subsys(unsigned int vendor, unsigned int device,
232 struct pci_dev *dev; 232 struct pci_dev *dev;
233 233
234 WARN_ON(in_interrupt()); 234 WARN_ON(in_interrupt());
235 spin_lock(&pci_bus_lock); 235 down_read(&pci_bus_sem);
236 n = from ? from->global_list.next : pci_devices.next; 236 n = from ? from->global_list.next : pci_devices.next;
237 237
238 while (n && (n != &pci_devices)) { 238 while (n && (n != &pci_devices)) {
@@ -247,7 +247,7 @@ pci_get_subsys(unsigned int vendor, unsigned int device,
247 dev = NULL; 247 dev = NULL;
248exit: 248exit:
249 dev = pci_dev_get(dev); 249 dev = pci_dev_get(dev);
250 spin_unlock(&pci_bus_lock); 250 up_read(&pci_bus_sem);
251 pci_dev_put(from); 251 pci_dev_put(from);
252 return dev; 252 return dev;
253} 253}
@@ -292,7 +292,7 @@ pci_find_device_reverse(unsigned int vendor, unsigned int device, const struct p
292 struct pci_dev *dev; 292 struct pci_dev *dev;
293 293
294 WARN_ON(in_interrupt()); 294 WARN_ON(in_interrupt());
295 spin_lock(&pci_bus_lock); 295 down_read(&pci_bus_sem);
296 n = from ? from->global_list.prev : pci_devices.prev; 296 n = from ? from->global_list.prev : pci_devices.prev;
297 297
298 while (n && (n != &pci_devices)) { 298 while (n && (n != &pci_devices)) {
@@ -304,7 +304,7 @@ pci_find_device_reverse(unsigned int vendor, unsigned int device, const struct p
304 } 304 }
305 dev = NULL; 305 dev = NULL;
306exit: 306exit:
307 spin_unlock(&pci_bus_lock); 307 up_read(&pci_bus_sem);
308 return dev; 308 return dev;
309} 309}
310 310
@@ -328,7 +328,7 @@ struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from)
328 struct pci_dev *dev; 328 struct pci_dev *dev;
329 329
330 WARN_ON(in_interrupt()); 330 WARN_ON(in_interrupt());
331 spin_lock(&pci_bus_lock); 331 down_read(&pci_bus_sem);
332 n = from ? from->global_list.next : pci_devices.next; 332 n = from ? from->global_list.next : pci_devices.next;
333 333
334 while (n && (n != &pci_devices)) { 334 while (n && (n != &pci_devices)) {
@@ -340,7 +340,7 @@ struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from)
340 dev = NULL; 340 dev = NULL;
341exit: 341exit:
342 dev = pci_dev_get(dev); 342 dev = pci_dev_get(dev);
343 spin_unlock(&pci_bus_lock); 343 up_read(&pci_bus_sem);
344 pci_dev_put(from); 344 pci_dev_put(from);
345 return dev; 345 return dev;
346} 346}
@@ -362,7 +362,7 @@ int pci_dev_present(const struct pci_device_id *ids)
362 int found = 0; 362 int found = 0;
363 363
364 WARN_ON(in_interrupt()); 364 WARN_ON(in_interrupt());
365 spin_lock(&pci_bus_lock); 365 down_read(&pci_bus_sem);
366 while (ids->vendor || ids->subvendor || ids->class_mask) { 366 while (ids->vendor || ids->subvendor || ids->class_mask) {
367 list_for_each_entry(dev, &pci_devices, global_list) { 367 list_for_each_entry(dev, &pci_devices, global_list) {
368 if (pci_match_one_device(ids, dev)) { 368 if (pci_match_one_device(ids, dev)) {
@@ -372,8 +372,8 @@ int pci_dev_present(const struct pci_device_id *ids)
372 } 372 }
373 ids++; 373 ids++;
374 } 374 }
375exit: 375exit:
376 spin_unlock(&pci_bus_lock); 376 up_read(&pci_bus_sem);
377 return found; 377 return found;
378} 378}
379EXPORT_SYMBOL(pci_dev_present); 379EXPORT_SYMBOL(pci_dev_present);
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 28ce3a7ee434..35086e80faa9 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -55,9 +55,10 @@ pbus_assign_resources_sorted(struct pci_bus *bus)
55 list_for_each_entry(dev, &bus->devices, bus_list) { 55 list_for_each_entry(dev, &bus->devices, bus_list) {
56 u16 class = dev->class >> 8; 56 u16 class = dev->class >> 8;
57 57
58 /* Don't touch classless devices and host bridges. */ 58 /* Don't touch classless devices or host bridges or ioapics. */
59 if (class == PCI_CLASS_NOT_DEFINED || 59 if (class == PCI_CLASS_NOT_DEFINED ||
60 class == PCI_CLASS_BRIDGE_HOST) 60 class == PCI_CLASS_BRIDGE_HOST ||
61 class == PCI_CLASS_SYSTEM_PIC)
61 continue; 62 continue;
62 63
63 pdev_sort_resources(dev, &head); 64 pdev_sort_resources(dev, &head);
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index ea9277b7f899..577f4b55c46d 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -155,6 +155,46 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
155 return ret; 155 return ret;
156} 156}
157 157
158#ifdef CONFIG_EMBEDDED
159int pci_assign_resource_fixed(struct pci_dev *dev, int resno)
160{
161 struct pci_bus *bus = dev->bus;
162 struct resource *res = dev->resource + resno;
163 unsigned int type_mask;
164 int i, ret = -EBUSY;
165
166 type_mask = IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH;
167
168 for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
169 struct resource *r = bus->resource[i];
170 if (!r)
171 continue;
172
173 /* type_mask must match */
174 if ((res->flags ^ r->flags) & type_mask)
175 continue;
176
177 ret = request_resource(r, res);
178
179 if (ret == 0)
180 break;
181 }
182
183 if (ret) {
184 printk(KERN_ERR "PCI: Failed to allocate %s resource "
185 "#%d:%llx@%llx for %s\n",
186 res->flags & IORESOURCE_IO ? "I/O" : "mem",
187 resno, (unsigned long long)(res->end - res->start + 1),
188 (unsigned long long)res->start, pci_name(dev));
189 } else if (resno < PCI_BRIDGE_RESOURCES) {
190 pci_update_resource(dev, res, resno);
191 }
192
193 return ret;
194}
195EXPORT_SYMBOL_GPL(pci_assign_resource_fixed);
196#endif
197
158/* Sort resources by alignment */ 198/* Sort resources by alignment */
159void __devinit 199void __devinit
160pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) 200pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)