aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/hotplug/shpchp.h12
-rw-r--r--drivers/pci/hotplug/shpchp_core.c13
-rw-r--r--drivers/pci/hotplug/shpchp_ctrl.c1
-rw-r--r--drivers/pci/hotplug/shpchp_hpc.c2
-rw-r--r--drivers/pci/hotplug/shpchp_pci.c52
-rw-r--r--drivers/pci/hotplug/shpchprm.h43
-rw-r--r--drivers/pci/hotplug/shpchprm_acpi.c794
-rw-r--r--drivers/pci/hotplug/shpchprm_legacy.c97
-rw-r--r--drivers/pci/hotplug/shpchprm_nonacpi.c108
9 files changed, 138 insertions, 984 deletions
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
index deea56c73cf2..1b345ae81ddb 100644
--- a/drivers/pci/hotplug/shpchp.h
+++ b/drivers/pci/hotplug/shpchp.h
@@ -122,6 +122,13 @@ struct controller {
122 u16 vendor_id; 122 u16 vendor_id;
123}; 123};
124 124
125struct hotplug_params {
126 u8 cache_line_size;
127 u8 latency_timer;
128 u8 enable_serr;
129 u8 enable_perr;
130};
131
125/* Define AMD SHPC ID */ 132/* Define AMD SHPC ID */
126#define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450 133#define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450
127 134
@@ -192,6 +199,11 @@ extern int shpchp_save_config(struct controller *ctrl, int busnumber, int num_ct
192extern int shpchp_save_slot_config(struct controller *ctrl, struct pci_func * new_slot); 199extern int shpchp_save_slot_config(struct controller *ctrl, struct pci_func * new_slot);
193extern int shpchp_configure_device(struct slot *p_slot); 200extern int shpchp_configure_device(struct slot *p_slot);
194extern int shpchp_unconfigure_device(struct pci_func* func); 201extern int shpchp_unconfigure_device(struct pci_func* func);
202extern void get_hp_hw_control_from_firmware(struct pci_dev *dev);
203extern void get_hp_params_from_firmware(struct pci_dev *dev,
204 struct hotplug_params *hpp);
205extern int shpchprm_get_physical_slot_number(struct controller *ctrl,
206 u32 *sun, u8 busnum, u8 devnum);
195 207
196 208
197/* Global variables */ 209/* Global variables */
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c
index 8f5da504df34..e3c0c17295da 100644
--- a/drivers/pci/hotplug/shpchp_core.c
+++ b/drivers/pci/hotplug/shpchp_core.c
@@ -39,7 +39,6 @@
39#include <linux/init.h> 39#include <linux/init.h>
40#include <asm/uaccess.h> 40#include <asm/uaccess.h>
41#include "shpchp.h" 41#include "shpchp.h"
42#include "shpchprm.h"
43 42
44/* Global variables */ 43/* Global variables */
45int shpchp_debug; 44int shpchp_debug;
@@ -566,16 +565,12 @@ static int __init shpcd_init(void)
566 if (retval) 565 if (retval)
567 goto error_hpc_init; 566 goto error_hpc_init;
568 567
569 retval = shpchprm_init(PCI); 568 retval = pci_register_driver(&shpc_driver);
570 if (!retval) { 569 dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval);
571 retval = pci_register_driver(&shpc_driver); 570 info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
572 dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval);
573 info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
574 }
575 571
576error_hpc_init: 572error_hpc_init:
577 if (retval) { 573 if (retval) {
578 shpchprm_cleanup();
579 shpchp_event_stop_thread(); 574 shpchp_event_stop_thread();
580 } 575 }
581 return retval; 576 return retval;
@@ -586,8 +581,6 @@ static void __exit shpcd_cleanup(void)
586 dbg("unload_shpchpd()\n"); 581 dbg("unload_shpchpd()\n");
587 unload_shpchpd(); 582 unload_shpchpd();
588 583
589 shpchprm_cleanup();
590
591 dbg("pci_unregister_driver\n"); 584 dbg("pci_unregister_driver\n");
592 pci_unregister_driver(&shpc_driver); 585 pci_unregister_driver(&shpc_driver);
593 586
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
index aa507e453e49..23dd61c4c66c 100644
--- a/drivers/pci/hotplug/shpchp_ctrl.c
+++ b/drivers/pci/hotplug/shpchp_ctrl.c
@@ -40,7 +40,6 @@
40#include <linux/pci.h> 40#include <linux/pci.h>
41#include "../pci.h" 41#include "../pci.h"
42#include "shpchp.h" 42#include "shpchp.h"
43#include "shpchprm.h"
44 43
45static void interrupt_event_handler(struct controller *ctrl); 44static void interrupt_event_handler(struct controller *ctrl);
46 45
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c
index 8d98410bf1c0..d55a9a7f8d2b 100644
--- a/drivers/pci/hotplug/shpchp_hpc.c
+++ b/drivers/pci/hotplug/shpchp_hpc.c
@@ -1566,8 +1566,8 @@ int shpc_init(struct controller * ctrl,
1566 err("Can't get irq %d for the hotplug controller\n", php_ctlr->irq); 1566 err("Can't get irq %d for the hotplug controller\n", php_ctlr->irq);
1567 goto abort_free_ctlr; 1567 goto abort_free_ctlr;
1568 } 1568 }
1569 /* Execute OSHP method here */
1570 } 1569 }
1570 get_hp_hw_control_from_firmware(pdev);
1571 dbg("%s: Before adding HPC to HPC list\n", __FUNCTION__); 1571 dbg("%s: Before adding HPC to HPC list\n", __FUNCTION__);
1572 1572
1573 /* Add this HPC instance into the HPC list */ 1573 /* Add this HPC instance into the HPC list */
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c
index 89e404805777..6209972313f3 100644
--- a/drivers/pci/hotplug/shpchp_pci.c
+++ b/drivers/pci/hotplug/shpchp_pci.c
@@ -38,6 +38,55 @@
38#include "../pci.h" 38#include "../pci.h"
39#include "shpchp.h" 39#include "shpchp.h"
40 40
41void program_fw_provided_values(struct pci_dev *dev)
42{
43 u16 pci_cmd, pci_bctl;
44 struct pci_dev *cdev;
45 struct hotplug_params hpp = {0x8, 0x40, 0, 0}; /* defaults */
46
47 /* Program hpp values for this device */
48 if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL ||
49 (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
50 (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
51 return;
52
53 get_hp_params_from_firmware(dev, &hpp);
54
55 pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, hpp.cache_line_size);
56 pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp.latency_timer);
57 pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
58 if (hpp.enable_serr)
59 pci_cmd |= PCI_COMMAND_SERR;
60 else
61 pci_cmd &= ~PCI_COMMAND_SERR;
62 if (hpp.enable_perr)
63 pci_cmd |= PCI_COMMAND_PARITY;
64 else
65 pci_cmd &= ~PCI_COMMAND_PARITY;
66 pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
67
68 /* Program bridge control value and child devices */
69 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
70 pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,
71 hpp.latency_timer);
72 pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
73 if (hpp.enable_serr)
74 pci_bctl |= PCI_BRIDGE_CTL_SERR;
75 else
76 pci_bctl &= ~PCI_BRIDGE_CTL_SERR;
77 if (hpp.enable_perr)
78 pci_bctl |= PCI_BRIDGE_CTL_PARITY;
79 else
80 pci_bctl &= ~PCI_BRIDGE_CTL_PARITY;
81 pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl);
82 if (dev->subordinate) {
83 list_for_each_entry(cdev, &dev->subordinate->devices,
84 bus_list)
85 program_fw_provided_values(cdev);
86 }
87 }
88}
89
41int shpchp_configure_device(struct slot *p_slot) 90int shpchp_configure_device(struct slot *p_slot)
42{ 91{
43 struct pci_dev *dev; 92 struct pci_dev *dev;
@@ -90,8 +139,7 @@ int shpchp_configure_device(struct slot *p_slot)
90 child->subordinate = pci_do_scan_bus(child); 139 child->subordinate = pci_do_scan_bus(child);
91 pci_bus_size_bridges(child); 140 pci_bus_size_bridges(child);
92 } 141 }
93 /* TBD: program firmware provided _HPP values */ 142 program_fw_provided_values(dev);
94 /* program_fw_provided_values(dev); */
95 } 143 }
96 144
97 pci_bus_assign_resources(parent); 145 pci_bus_assign_resources(parent);
diff --git a/drivers/pci/hotplug/shpchprm.h b/drivers/pci/hotplug/shpchprm.h
deleted file mode 100644
index df474b27d6e8..000000000000
--- a/drivers/pci/hotplug/shpchprm.h
+++ /dev/null
@@ -1,43 +0,0 @@
1/*
2 * SHPCHPRM : SHPCHP Resource Manager for ACPI/non-ACPI platform
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2003-2004 Intel Corporation
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
27 *
28 */
29
30#ifndef _SHPCHPRM_H_
31#define _SHPCHPRM_H_
32
33#ifdef CONFIG_HOTPLUG_PCI_SHPC_PHPRM_LEGACY
34#include "shpchprm_legacy.h"
35#endif
36
37int shpchprm_init(enum php_ctlr_type ct);
38void shpchprm_cleanup(void);
39int shpchprm_set_hpp(struct controller *ctrl, struct pci_func *func, u8 card_type);
40void shpchprm_enable_card(struct controller *ctrl, struct pci_func *func, u8 card_type);
41int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum);
42
43#endif /* _SHPCHPRM_H_ */
diff --git a/drivers/pci/hotplug/shpchprm_acpi.c b/drivers/pci/hotplug/shpchprm_acpi.c
index 3d2f9c5269c7..3be518c7d47a 100644
--- a/drivers/pci/hotplug/shpchprm_acpi.c
+++ b/drivers/pci/hotplug/shpchprm_acpi.c
@@ -38,62 +38,11 @@
38#include <acpi/acpi_bus.h> 38#include <acpi/acpi_bus.h>
39#include <acpi/actypes.h> 39#include <acpi/actypes.h>
40#include "shpchp.h" 40#include "shpchp.h"
41#include "shpchprm.h"
42
43#define PCI_MAX_BUS 0x100
44#define ACPI_STA_DEVICE_PRESENT 0x01
45 41
46#define METHOD_NAME__SUN "_SUN" 42#define METHOD_NAME__SUN "_SUN"
47#define METHOD_NAME__HPP "_HPP" 43#define METHOD_NAME__HPP "_HPP"
48#define METHOD_NAME_OSHP "OSHP" 44#define METHOD_NAME_OSHP "OSHP"
49 45
50#define PHP_RES_BUS 0xA0
51#define PHP_RES_IO 0xA1
52#define PHP_RES_MEM 0xA2
53#define PHP_RES_PMEM 0xA3
54
55#define BRIDGE_TYPE_P2P 0x00
56#define BRIDGE_TYPE_HOST 0x01
57
58/* this should go to drivers/acpi/include/ */
59struct acpi__hpp {
60 u8 cache_line_size;
61 u8 latency_timer;
62 u8 enable_serr;
63 u8 enable_perr;
64};
65
66struct acpi_php_slot {
67 struct acpi_php_slot *next;
68 struct acpi_bridge *bridge;
69 acpi_handle handle;
70 int seg;
71 int bus;
72 int dev;
73 int fun;
74 u32 sun;
75 void *slot_ops; /* _STA, _EJx, etc */
76 struct slot *slot;
77}; /* per func */
78
79struct acpi_bridge {
80 struct acpi_bridge *parent;
81 struct acpi_bridge *next;
82 struct acpi_bridge *child;
83 acpi_handle handle;
84 int seg;
85 int pbus; /* pdev->bus->number */
86 int pdevice; /* PCI_SLOT(pdev->devfn) */
87 int pfunction; /* PCI_DEVFN(pdev->devfn) */
88 int bus; /* pdev->subordinate->number */
89 struct acpi__hpp *_hpp;
90 struct acpi_php_slot *slots;
91 int scanned;
92 int type;
93};
94
95static struct acpi_bridge *acpi_bridges_head;
96
97static u8 * acpi_path_name( acpi_handle handle) 46static u8 * acpi_path_name( acpi_handle handle)
98{ 47{
99 acpi_status status; 48 acpi_status status;
@@ -109,82 +58,43 @@ static u8 * acpi_path_name( acpi_handle handle)
109 return path_name; 58 return path_name;
110} 59}
111 60
112static void acpi_get__hpp ( struct acpi_bridge *ab); 61static acpi_status
113static void acpi_run_oshp ( struct acpi_bridge *ab); 62acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
114
115static int acpi_add_slot_to_php_slots(
116 struct acpi_bridge *ab,
117 int bus_num,
118 acpi_handle handle,
119 u32 adr,
120 u32 sun
121 )
122{
123 struct acpi_php_slot *aps;
124 static long samesun = -1;
125
126 aps = (struct acpi_php_slot *) kmalloc (sizeof(struct acpi_php_slot), GFP_KERNEL);
127 if (!aps) {
128 err ("acpi_shpchprm: alloc for aps fail\n");
129 return -1;
130 }
131 memset(aps, 0, sizeof(struct acpi_php_slot));
132
133 aps->handle = handle;
134 aps->bus = bus_num;
135 aps->dev = (adr >> 16) & 0xffff;
136 aps->fun = adr & 0xffff;
137 aps->sun = sun;
138
139 aps->next = ab->slots; /* cling to the bridge */
140 aps->bridge = ab;
141 ab->slots = aps;
142
143 ab->scanned += 1;
144 if (!ab->_hpp)
145 acpi_get__hpp(ab);
146
147 acpi_run_oshp(ab);
148
149 if (sun != samesun) {
150 info("acpi_shpchprm: Slot sun(%x) at s:b:d:f=0x%02x:%02x:%02x:%02x\n", aps->sun, ab->seg,
151 aps->bus, aps->dev, aps->fun);
152 samesun = sun;
153 }
154 return 0;
155}
156
157static void acpi_get__hpp ( struct acpi_bridge *ab)
158{ 63{
159 acpi_status status; 64 acpi_status status;
160 u8 nui[4]; 65 u8 nui[4];
161 struct acpi_buffer ret_buf = { 0, NULL}; 66 struct acpi_buffer ret_buf = { 0, NULL};
162 union acpi_object *ext_obj, *package; 67 union acpi_object *ext_obj, *package;
163 u8 *path_name = acpi_path_name(ab->handle); 68 u8 *path_name = acpi_path_name(handle);
164 int i, len = 0; 69 int i, len = 0;
165 70
166 /* get _hpp */ 71 /* get _hpp */
167 status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf); 72 status = acpi_evaluate_object(handle, METHOD_NAME__HPP, NULL, &ret_buf);
168 switch (status) { 73 switch (status) {
169 case AE_BUFFER_OVERFLOW: 74 case AE_BUFFER_OVERFLOW:
170 ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL); 75 ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL);
171 if (!ret_buf.pointer) { 76 if (!ret_buf.pointer) {
172 err ("acpi_shpchprm:%s alloc for _HPP fail\n", path_name); 77 err ("%s:%s alloc for _HPP fail\n", __FUNCTION__,
173 return; 78 path_name);
79 return AE_NO_MEMORY;
174 } 80 }
175 status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf); 81 status = acpi_evaluate_object(handle, METHOD_NAME__HPP,
82 NULL, &ret_buf);
176 if (ACPI_SUCCESS(status)) 83 if (ACPI_SUCCESS(status))
177 break; 84 break;
178 default: 85 default:
179 if (ACPI_FAILURE(status)) { 86 if (ACPI_FAILURE(status)) {
180 err("acpi_shpchprm:%s _HPP fail=0x%x\n", path_name, status); 87 dbg("%s:%s _HPP fail=0x%x\n", __FUNCTION__,
181 return; 88 path_name, status);
89 return status;
182 } 90 }
183 } 91 }
184 92
185 ext_obj = (union acpi_object *) ret_buf.pointer; 93 ext_obj = (union acpi_object *) ret_buf.pointer;
186 if (ext_obj->type != ACPI_TYPE_PACKAGE) { 94 if (ext_obj->type != ACPI_TYPE_PACKAGE) {
187 err ("acpi_shpchprm:%s _HPP obj not a package\n", path_name); 95 err ("%s:%s _HPP obj not a package\n", __FUNCTION__,
96 path_name);
97 status = AE_ERROR;
188 goto free_and_return; 98 goto free_and_return;
189 } 99 }
190 100
@@ -197,553 +107,41 @@ static void acpi_get__hpp ( struct acpi_bridge *ab)
197 nui[i] = (u8)ext_obj->integer.value; 107 nui[i] = (u8)ext_obj->integer.value;
198 break; 108 break;
199 default: 109 default:
200 err ("acpi_shpchprm:%s _HPP obj type incorrect\n", path_name); 110 err ("%s:%s _HPP obj type incorrect\n", __FUNCTION__,
111 path_name);
112 status = AE_ERROR;
201 goto free_and_return; 113 goto free_and_return;
202 } 114 }
203 } 115 }
204 116
205 ab->_hpp = kmalloc (sizeof (struct acpi__hpp), GFP_KERNEL); 117 hpp->cache_line_size = nui[0];
206 if (!ab->_hpp) { 118 hpp->latency_timer = nui[1];
207 err ("acpi_shpchprm:%s alloc for _HPP failed\n", path_name); 119 hpp->enable_serr = nui[2];
208 goto free_and_return; 120 hpp->enable_perr = nui[3];
209 }
210 memset(ab->_hpp, 0, sizeof(struct acpi__hpp));
211
212 ab->_hpp->cache_line_size = nui[0];
213 ab->_hpp->latency_timer = nui[1];
214 ab->_hpp->enable_serr = nui[2];
215 ab->_hpp->enable_perr = nui[3];
216 121
217 dbg(" _HPP: cache_line_size=0x%x\n", ab->_hpp->cache_line_size); 122 dbg(" _HPP: cache_line_size=0x%x\n", hpp->cache_line_size);
218 dbg(" _HPP: latency timer =0x%x\n", ab->_hpp->latency_timer); 123 dbg(" _HPP: latency timer =0x%x\n", hpp->latency_timer);
219 dbg(" _HPP: enable SERR =0x%x\n", ab->_hpp->enable_serr); 124 dbg(" _HPP: enable SERR =0x%x\n", hpp->enable_serr);
220 dbg(" _HPP: enable PERR =0x%x\n", ab->_hpp->enable_perr); 125 dbg(" _HPP: enable PERR =0x%x\n", hpp->enable_perr);
221 126
222free_and_return: 127free_and_return:
223 kfree(ret_buf.pointer); 128 kfree(ret_buf.pointer);
129 return status;
224} 130}
225 131
226static void acpi_run_oshp ( struct acpi_bridge *ab) 132static void acpi_run_oshp(acpi_handle handle)
227{
228 acpi_status status;
229 u8 *path_name = acpi_path_name(ab->handle);
230
231 /* run OSHP */
232 status = acpi_evaluate_object(ab->handle, METHOD_NAME_OSHP, NULL, NULL);
233 if (ACPI_FAILURE(status)) {
234 err("acpi_pciehprm:%s OSHP fails=0x%x\n", path_name, status);
235 } else
236 dbg("acpi_pciehprm:%s OSHP passes =0x%x\n", path_name, status);
237 return;
238}
239
240/* find acpi_bridge downword from ab. */
241static struct acpi_bridge *
242find_acpi_bridge_by_bus(
243 struct acpi_bridge *ab,
244 int seg,
245 int bus /* pdev->subordinate->number */
246 )
247{
248 struct acpi_bridge *lab = NULL;
249
250 if (!ab)
251 return NULL;
252
253 if ((ab->bus == bus) && (ab->seg == seg))
254 return ab;
255
256 if (ab->child)
257 lab = find_acpi_bridge_by_bus(ab->child, seg, bus);
258
259 if (!lab)
260 if (ab->next)
261 lab = find_acpi_bridge_by_bus(ab->next, seg, bus);
262
263 return lab;
264}
265
266/*
267 * Build a device tree of ACPI PCI Bridges
268 */
269static void shpchprm_acpi_register_a_bridge (
270 struct acpi_bridge **head,
271 struct acpi_bridge *pab, /* parent bridge to which child bridge is added */
272 struct acpi_bridge *cab /* child bridge to add */
273 )
274{
275 struct acpi_bridge *lpab;
276 struct acpi_bridge *lcab;
277
278 lpab = find_acpi_bridge_by_bus(*head, pab->seg, pab->bus);
279 if (!lpab) {
280 if (!(pab->type & BRIDGE_TYPE_HOST))
281 warn("PCI parent bridge s:b(%x:%x) not in list.\n", pab->seg, pab->bus);
282 pab->next = *head;
283 *head = pab;
284 lpab = pab;
285 }
286
287 if ((cab->type & BRIDGE_TYPE_HOST) && (pab == cab))
288 return;
289
290 lcab = find_acpi_bridge_by_bus(*head, cab->seg, cab->bus);
291 if (lcab) {
292 if ((pab->bus != lcab->parent->bus) || (lcab->bus != cab->bus))
293 err("PCI child bridge s:b(%x:%x) in list with diff parent.\n", cab->seg, cab->bus);
294 return;
295 } else
296 lcab = cab;
297
298 lcab->parent = lpab;
299 lcab->next = lpab->child;
300 lpab->child = lcab;
301}
302
303static acpi_status shpchprm_acpi_build_php_slots_callback(
304 acpi_handle handle,
305 u32 Level,
306 void *context,
307 void **retval
308 )
309{ 133{
310 ulong bus_num;
311 ulong seg_num;
312 ulong sun, adr;
313 ulong padr = 0;
314 acpi_handle phandle = NULL;
315 struct acpi_bridge *pab = (struct acpi_bridge *)context;
316 struct acpi_bridge *lab;
317 acpi_status status; 134 acpi_status status;
318 u8 *path_name = acpi_path_name(handle); 135 u8 *path_name = acpi_path_name(handle);
319 136
320 /* get _SUN */ 137 /* run OSHP */
321 status = acpi_evaluate_integer(handle, METHOD_NAME__SUN, NULL, &sun); 138 status = acpi_evaluate_object(handle, METHOD_NAME_OSHP, NULL, NULL);
322 switch(status) {
323 case AE_NOT_FOUND:
324 return AE_OK;
325 default:
326 if (ACPI_FAILURE(status)) {
327 err("acpi_shpchprm:%s _SUN fail=0x%x\n", path_name, status);
328 return status;
329 }
330 }
331
332 /* get _ADR. _ADR must exist if _SUN exists */
333 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
334 if (ACPI_FAILURE(status)) {
335 err("acpi_shpchprm:%s _ADR fail=0x%x\n", path_name, status);
336 return status;
337 }
338
339 dbg("acpi_shpchprm:%s sun=0x%08x adr=0x%08x\n", path_name, (u32)sun, (u32)adr);
340
341 status = acpi_get_parent(handle, &phandle);
342 if (ACPI_FAILURE(status)) { 139 if (ACPI_FAILURE(status)) {
343 err("acpi_shpchprm:%s get_parent fail=0x%x\n", path_name, status); 140 err("%s:%s OSHP fails=0x%x\n", __FUNCTION__, path_name,
344 return (status); 141 status);
345 }
346
347 bus_num = pab->bus;
348 seg_num = pab->seg;
349
350 if (pab->bus == bus_num) {
351 lab = pab;
352 } else { 142 } else {
353 dbg("WARN: pab is not parent\n"); 143 dbg("%s:%s OSHP passes\n", __FUNCTION__, path_name);
354 lab = find_acpi_bridge_by_bus(pab, seg_num, bus_num);
355 if (!lab) {
356 dbg("acpi_shpchprm: alloc new P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
357 lab = (struct acpi_bridge *)kmalloc(sizeof(struct acpi_bridge), GFP_KERNEL);
358 if (!lab) {
359 err("acpi_shpchprm: alloc for ab fail\n");
360 return AE_NO_MEMORY;
361 }
362 memset(lab, 0, sizeof(struct acpi_bridge));
363
364 lab->handle = phandle;
365 lab->pbus = pab->bus;
366 lab->pdevice = (int)(padr >> 16) & 0xffff;
367 lab->pfunction = (int)(padr & 0xffff);
368 lab->bus = (int)bus_num;
369 lab->scanned = 0;
370 lab->type = BRIDGE_TYPE_P2P;
371
372 shpchprm_acpi_register_a_bridge (&acpi_bridges_head, pab, lab);
373 } else
374 dbg("acpi_shpchprm: found P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
375 }
376
377 acpi_add_slot_to_php_slots(lab, (int)bus_num, handle, (u32)adr, (u32)sun);
378 return (status);
379}
380
381static int shpchprm_acpi_build_php_slots(
382 struct acpi_bridge *ab,
383 u32 depth
384 )
385{
386 acpi_status status;
387 u8 *path_name = acpi_path_name(ab->handle);
388
389 /* Walk down this pci bridge to get _SUNs if any behind P2P */
390 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
391 ab->handle,
392 depth,
393 shpchprm_acpi_build_php_slots_callback,
394 ab,
395 NULL );
396 if (ACPI_FAILURE(status)) {
397 dbg("acpi_shpchprm:%s walk for _SUN on pci bridge seg:bus(%x:%x) fail=0x%x\n", path_name, ab->seg, ab->bus, status);
398 return -1;
399 }
400
401 return 0;
402}
403
404static void build_a_bridge(
405 struct acpi_bridge *pab,
406 struct acpi_bridge *ab
407 )
408{
409 u8 *path_name = acpi_path_name(ab->handle);
410
411 shpchprm_acpi_register_a_bridge (&acpi_bridges_head, pab, ab);
412
413 switch (ab->type) {
414 case BRIDGE_TYPE_HOST:
415 dbg("acpi_shpchprm: Registered PCI HOST Bridge(%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
416 ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
417 break;
418 case BRIDGE_TYPE_P2P:
419 dbg("acpi_shpchprm: Registered PCI P2P Bridge(%02x-%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
420 ab->pbus, ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
421 break;
422 };
423
424 /* build any immediate PHP slots under this pci bridge */
425 shpchprm_acpi_build_php_slots(ab, 1);
426}
427
428static struct acpi_bridge * add_p2p_bridge(
429 acpi_handle handle,
430 struct acpi_bridge *pab, /* parent */
431 ulong adr
432 )
433{
434 struct acpi_bridge *ab;
435 struct pci_dev *pdev;
436 ulong devnum, funcnum;
437 u8 *path_name = acpi_path_name(handle);
438
439 ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
440 if (!ab) {
441 err("acpi_shpchprm: alloc for ab fail\n");
442 return NULL;
443 }
444 memset(ab, 0, sizeof(struct acpi_bridge));
445
446 devnum = (adr >> 16) & 0xffff;
447 funcnum = adr & 0xffff;
448
449 pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
450 if (!pdev || !pdev->subordinate) {
451 err("acpi_shpchprm:%s is not a P2P Bridge\n", path_name);
452 kfree(ab);
453 return NULL;
454 }
455
456 ab->handle = handle;
457 ab->seg = pab->seg;
458 ab->pbus = pab->bus; /* or pdev->bus->number */
459 ab->pdevice = devnum; /* or PCI_SLOT(pdev->devfn) */
460 ab->pfunction = funcnum; /* or PCI_FUNC(pdev->devfn) */
461 ab->bus = pdev->subordinate->number;
462 ab->scanned = 0;
463 ab->type = BRIDGE_TYPE_P2P;
464
465 dbg("acpi_shpchprm: P2P(%x-%x) on pci=b:d:f(%x:%x:%x) acpi=b:d:f(%x:%x:%x) [%s]\n",
466 pab->bus, ab->bus, pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
467 pab->bus, (u32)devnum, (u32)funcnum, path_name);
468
469 build_a_bridge(pab, ab);
470
471 return ab;
472}
473
474static acpi_status scan_p2p_bridge(
475 acpi_handle handle,
476 u32 Level,
477 void *context,
478 void **retval
479 )
480{
481 struct acpi_bridge *pab = (struct acpi_bridge *)context;
482 struct acpi_bridge *ab;
483 acpi_status status;
484 ulong adr = 0;
485 u8 *path_name = acpi_path_name(handle);
486 ulong devnum, funcnum;
487 struct pci_dev *pdev;
488
489 /* get device, function */
490 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
491 if (ACPI_FAILURE(status)) {
492 if (status != AE_NOT_FOUND)
493 err("acpi_shpchprm:%s _ADR fail=0x%x\n", path_name, status);
494 return AE_OK;
495 } 144 }
496
497 devnum = (adr >> 16) & 0xffff;
498 funcnum = adr & 0xffff;
499
500 pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
501 if (!pdev)
502 return AE_OK;
503 if (!pdev->subordinate)
504 return AE_OK;
505
506 ab = add_p2p_bridge(handle, pab, adr);
507 if (ab) {
508 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
509 handle,
510 (u32)1,
511 scan_p2p_bridge,
512 ab,
513 NULL);
514 if (ACPI_FAILURE(status))
515 dbg("acpi_shpchprm:%s find_p2p fail=0x%x\n", path_name, status);
516 }
517
518 return AE_OK;
519}
520
521static struct acpi_bridge * add_host_bridge(
522 acpi_handle handle,
523 ulong segnum,
524 ulong busnum
525 )
526{
527 ulong adr = 0;
528 acpi_status status;
529 struct acpi_bridge *ab;
530 u8 *path_name = acpi_path_name(handle);
531
532 /* get device, function: host br adr is always 0000 though. */
533 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
534 if (ACPI_FAILURE(status)) {
535 err("acpi_shpchprm:%s _ADR fail=0x%x\n", path_name, status);
536 return NULL;
537 }
538 dbg("acpi_shpchprm: ROOT PCI seg(0x%x)bus(0x%x)dev(0x%x)func(0x%x) [%s]\n", (u32)segnum, (u32)busnum,
539 (u32)(adr >> 16) & 0xffff, (u32)adr & 0xffff, path_name);
540
541 ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
542 if (!ab) {
543 err("acpi_shpchprm: alloc for ab fail\n");
544 return NULL;
545 }
546 memset(ab, 0, sizeof(struct acpi_bridge));
547
548 ab->handle = handle;
549 ab->seg = (int)segnum;
550 ab->bus = ab->pbus = (int)busnum;
551 ab->pdevice = (int)(adr >> 16) & 0xffff;
552 ab->pfunction = (int)(adr & 0xffff);
553 ab->scanned = 0;
554 ab->type = BRIDGE_TYPE_HOST;
555
556 build_a_bridge(ab, ab);
557
558 return ab;
559}
560
561static acpi_status acpi_scan_from_root_pci_callback (
562 acpi_handle handle,
563 u32 Level,
564 void *context,
565 void **retval
566 )
567{
568 ulong segnum = 0;
569 ulong busnum = 0;
570 acpi_status status;
571 struct acpi_bridge *ab;
572 u8 *path_name = acpi_path_name(handle);
573
574 /* get bus number of this pci root bridge */
575 status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL, &segnum);
576 if (ACPI_FAILURE(status)) {
577 if (status != AE_NOT_FOUND) {
578 err("acpi_shpchprm:%s evaluate _SEG fail=0x%x\n", path_name, status);
579 return status;
580 }
581 segnum = 0;
582 }
583
584 /* get bus number of this pci root bridge */
585 status = acpi_evaluate_integer(handle, METHOD_NAME__BBN, NULL, &busnum);
586 if (ACPI_FAILURE(status)) {
587 err("acpi_shpchprm:%s evaluate _BBN fail=0x%x\n", path_name, status);
588 return (status);
589 }
590
591 ab = add_host_bridge(handle, segnum, busnum);
592 if (ab) {
593 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
594 handle,
595 1,
596 scan_p2p_bridge,
597 ab,
598 NULL);
599 if (ACPI_FAILURE(status))
600 dbg("acpi_shpchprm:%s find_p2p fail=0x%x\n", path_name, status);
601 }
602
603 return AE_OK;
604}
605
606static int shpchprm_acpi_scan_pci (void)
607{
608 acpi_status status;
609
610 /*
611 * TBD: traverse LDM device tree with the help of
612 * unified ACPI augmented for php device population.
613 */
614 status = acpi_get_devices ( PCI_ROOT_HID_STRING,
615 acpi_scan_from_root_pci_callback,
616 NULL,
617 NULL );
618 if (ACPI_FAILURE(status)) {
619 err("acpi_shpchprm:get_device PCI ROOT HID fail=0x%x\n", status);
620 return -1;
621 }
622
623 return 0;
624}
625
626int shpchprm_init(enum php_ctlr_type ctlr_type)
627{
628 int rc;
629
630 if (ctlr_type != PCI)
631 return -ENODEV;
632
633 dbg("shpchprm ACPI init <enter>\n");
634 acpi_bridges_head = NULL;
635
636 /* construct PCI bus:device tree of acpi_handles */
637 rc = shpchprm_acpi_scan_pci();
638 if (rc)
639 return rc;
640
641 dbg("shpchprm ACPI init %s\n", (rc)?"fail":"success");
642 return rc;
643}
644
645static void free_a_slot(struct acpi_php_slot *aps)
646{
647 dbg(" free a php func of slot(0x%02x) on PCI b:d:f=0x%02x:%02x:%02x\n", aps->sun, aps->bus, aps->dev, aps->fun);
648
649 kfree(aps);
650}
651
652static void free_a_bridge( struct acpi_bridge *ab)
653{
654 struct acpi_php_slot *aps, *next;
655
656 switch (ab->type) {
657 case BRIDGE_TYPE_HOST:
658 dbg("Free ACPI PCI HOST Bridge(%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
659 ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
660 break;
661 case BRIDGE_TYPE_P2P:
662 dbg("Free ACPI PCI P2P Bridge(%x-%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
663 ab->pbus, ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
664 break;
665 };
666
667 /* free slots first */
668 for (aps = ab->slots; aps; aps = next) {
669 next = aps->next;
670 free_a_slot(aps);
671 }
672
673 kfree(ab);
674}
675
676static void shpchprm_free_bridges ( struct acpi_bridge *ab)
677{
678 if (!ab)
679 return;
680
681 if (ab->child)
682 shpchprm_free_bridges (ab->child);
683
684 if (ab->next)
685 shpchprm_free_bridges (ab->next);
686
687 free_a_bridge(ab);
688}
689
690void shpchprm_cleanup(void)
691{
692 shpchprm_free_bridges (acpi_bridges_head);
693}
694
695static int get_number_of_slots (
696 struct acpi_bridge *ab,
697 int selfonly
698 )
699{
700 struct acpi_php_slot *aps;
701 int prev_slot = -1;
702 int slot_num = 0;
703
704 for ( aps = ab->slots; aps; aps = aps->next)
705 if (aps->dev != prev_slot) {
706 prev_slot = aps->dev;
707 slot_num++;
708 }
709
710 if (ab->child)
711 slot_num += get_number_of_slots (ab->child, 0);
712
713 if (selfonly)
714 return slot_num;
715
716 if (ab->next)
717 slot_num += get_number_of_slots (ab->next, 0);
718
719 return slot_num;
720}
721
722static struct acpi_php_slot * get_acpi_slot (
723 struct acpi_bridge *ab,
724 u32 sun
725 )
726{
727 struct acpi_php_slot *aps = NULL;
728
729 for ( aps = ab->slots; aps; aps = aps->next)
730 if (aps->sun == sun)
731 return aps;
732
733 if (!aps && ab->child) {
734 aps = (struct acpi_php_slot *)get_acpi_slot (ab->child, sun);
735 if (aps)
736 return aps;
737 }
738
739 if (!aps && ab->next) {
740 aps = (struct acpi_php_slot *)get_acpi_slot (ab->next, sun);
741 if (aps)
742 return aps;
743 }
744
745 return aps;
746
747} 145}
748 146
749int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum) 147int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
@@ -755,108 +153,40 @@ int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busn
755 return 0; 153 return 0;
756} 154}
757 155
758int shpchprm_set_hpp( 156void get_hp_hw_control_from_firmware(struct pci_dev *dev)
759 struct controller *ctrl,
760 struct pci_func *func,
761 u8 card_type
762 )
763{ 157{
764 struct acpi_bridge *ab; 158 /*
765 struct pci_bus lpci_bus, *pci_bus; 159 * OSHP is an optional ACPI firmware control method. If present,
766 int rc = 0; 160 * we need to run it to inform BIOS that we will control SHPC
767 unsigned int devfn; 161 * hardware from now on.
768 u8 cls= 0x08; /* default cache line size */ 162 */
769 u8 lt = 0x40; /* default latency timer */ 163 acpi_handle handle = DEVICE_ACPI_HANDLE(&(dev->dev));
770 u8 ep = 0; 164 if (!handle)
771 u8 es = 0; 165 return;
772 166 acpi_run_oshp(handle);
773 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
774 pci_bus = &lpci_bus;
775 pci_bus->number = func->bus;
776 devfn = PCI_DEVFN(func->device, func->function);
777
778 ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->slot_bus);
779
780 if (ab) {
781 if (ab->_hpp) {
782 lt = (u8)ab->_hpp->latency_timer;
783 cls = (u8)ab->_hpp->cache_line_size;
784 ep = (u8)ab->_hpp->enable_perr;
785 es = (u8)ab->_hpp->enable_serr;
786 } else
787 dbg("_hpp: no _hpp for B/D/F=%#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
788 } else
789 dbg("_hpp: no acpi bridge for B/D/F = %#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
790
791
792 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
793 /* set subordinate Latency Timer */
794 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, lt);
795 }
796
797 /* set base Latency Timer */
798 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, lt);
799 dbg(" set latency timer =0x%02x: %x\n", lt, rc);
800
801 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, cls);
802 dbg(" set cache_line_size=0x%02x: %x\n", cls, rc);
803
804 return rc;
805} 167}
806 168
807void shpchprm_enable_card( 169void get_hp_params_from_firmware(struct pci_dev *dev,
808 struct controller *ctrl, 170 struct hotplug_params *hpp)
809 struct pci_func *func,
810 u8 card_type)
811{ 171{
812 u16 command, cmd, bcommand, bcmd; 172 acpi_status status = AE_NOT_FOUND;
813 struct pci_bus lpci_bus, *pci_bus; 173 struct pci_dev *pdev = dev;
814 struct acpi_bridge *ab;
815 unsigned int devfn;
816 int rc;
817
818 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
819 pci_bus = &lpci_bus;
820 pci_bus->number = func->bus;
821 devfn = PCI_DEVFN(func->device, func->function);
822
823 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command);
824
825 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
826 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand);
827 }
828
829 cmd = command = command | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
830 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
831 bcmd = bcommand = bcommand | PCI_BRIDGE_CTL_NO_ISA;
832 174
833 ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->slot_bus); 175 /*
834 if (ab) { 176 * _HPP settings apply to all child buses, until another _HPP is
835 if (ab->_hpp) { 177 * encountered. If we don't find an _HPP for the input pci dev,
836 if (ab->_hpp->enable_perr) { 178 * look for it in the parent device scope since that would apply to
837 command |= PCI_COMMAND_PARITY; 179 * this pci dev. If we don't find any _HPP, use hardcoded defaults
838 bcommand |= PCI_BRIDGE_CTL_PARITY; 180 */
839 } else { 181 while (pdev && (ACPI_FAILURE(status))) {
840 command &= ~PCI_COMMAND_PARITY; 182 acpi_handle handle = DEVICE_ACPI_HANDLE(&(pdev->dev));
841 bcommand &= ~PCI_BRIDGE_CTL_PARITY; 183 if (!handle)
842 } 184 break;
843 if (ab->_hpp->enable_serr) { 185 status = acpi_run_hpp(handle, hpp);
844 command |= PCI_COMMAND_SERR; 186 if (!(pdev->bus->parent))
845 bcommand |= PCI_BRIDGE_CTL_SERR; 187 break;
846 } else { 188 /* Check if a parent object supports _HPP */
847 command &= ~PCI_COMMAND_SERR; 189 pdev = pdev->bus->parent->self;
848 bcommand &= ~PCI_BRIDGE_CTL_SERR;
849 }
850 } else
851 dbg("no _hpp for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
852 } else
853 dbg("no acpi bridge for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
854
855 if (command != cmd) {
856 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
857 }
858 if ((card_type == PCI_HEADER_TYPE_BRIDGE) && (bcommand != bcmd)) {
859 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
860 } 190 }
861} 191}
862 192
diff --git a/drivers/pci/hotplug/shpchprm_legacy.c b/drivers/pci/hotplug/shpchprm_legacy.c
index 6c27debe9522..cfc6092e2afd 100644
--- a/drivers/pci/hotplug/shpchprm_legacy.c
+++ b/drivers/pci/hotplug/shpchprm_legacy.c
@@ -37,10 +37,6 @@
37#include "shpchp.h" 37#include "shpchp.h"
38#include "shpchprm.h" 38#include "shpchprm.h"
39 39
40void shpchprm_cleanup(void)
41{
42}
43
44int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum) 40int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
45{ 41{
46 int offset = devnum - ctrl->slot_device_offset; 42 int offset = devnum - ctrl->slot_device_offset;
@@ -49,97 +45,14 @@ int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busn
49 return 0; 45 return 0;
50} 46}
51 47
52int shpchprm_set_hpp( 48void get_hp_params_from_firmware(struct pci_dev *dev,
53 struct controller *ctrl, 49 struct hotplug_params *hpp)
54 struct pci_func *func,
55 u8 card_type)
56{ 50{
57 u32 rc; 51 return;
58 u8 temp_byte;
59 struct pci_bus lpci_bus, *pci_bus;
60 unsigned int devfn;
61 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
62 pci_bus = &lpci_bus;
63 pci_bus->number = func->bus;
64 devfn = PCI_DEVFN(func->device, func->function);
65
66 temp_byte = 0x40; /* hard coded value for LT */
67 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
68 /* set subordinate Latency Timer */
69 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, temp_byte);
70 if (rc) {
71 dbg("%s: set secondary LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus,
72 func->device, func->function);
73 return rc;
74 }
75 }
76
77 /* set base Latency Timer */
78 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
79 if (rc) {
80 dbg("%s: set LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
81 return rc;
82 }
83
84 /* set Cache Line size */
85 temp_byte = 0x08; /* hard coded value for CLS */
86 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
87 if (rc) {
88 dbg("%s: set CLS error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
89 }
90
91 /* set enable_perr */
92 /* set enable_serr */
93
94 return rc;
95} 52}
96 53
97void shpchprm_enable_card( 54void get_hp_hw_control_from_firmware(struct pci_dev *dev)
98 struct controller *ctrl,
99 struct pci_func *func,
100 u8 card_type)
101{ 55{
102 u16 command, bcommand; 56 return;
103 struct pci_bus lpci_bus, *pci_bus;
104 unsigned int devfn;
105 int rc;
106
107 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
108 pci_bus = &lpci_bus;
109 pci_bus->number = func->bus;
110 devfn = PCI_DEVFN(func->device, func->function);
111
112 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command);
113 command |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR
114 | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
115 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
116 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
117
118 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
119 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand);
120 bcommand |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR
121 | PCI_BRIDGE_CTL_NO_ISA;
122 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
123 }
124}
125
126static int legacy_shpchprm_init_pci(void)
127{
128 return 0;
129} 57}
130 58
131int shpchprm_init(enum php_ctlr_type ctrl_type)
132{
133 int retval;
134
135 switch (ctrl_type) {
136 case PCI:
137 retval = legacy_shpchprm_init_pci();
138 break;
139 default:
140 retval = -ENODEV;
141 break;
142 }
143
144 return retval;
145}
diff --git a/drivers/pci/hotplug/shpchprm_nonacpi.c b/drivers/pci/hotplug/shpchprm_nonacpi.c
index 9d4ccae5f78e..f36c188c23eb 100644
--- a/drivers/pci/hotplug/shpchprm_nonacpi.c
+++ b/drivers/pci/hotplug/shpchprm_nonacpi.c
@@ -37,11 +37,6 @@
37#include "shpchp.h" 37#include "shpchp.h"
38#include "shpchprm.h" 38#include "shpchprm.h"
39 39
40void shpchprm_cleanup(void)
41{
42 return;
43}
44
45int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum) 40int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
46{ 41{
47 int offset = devnum - ctrl->slot_device_offset; 42 int offset = devnum - ctrl->slot_device_offset;
@@ -51,106 +46,13 @@ int shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busn
51 return 0; 46 return 0;
52} 47}
53 48
54int shpchprm_set_hpp( 49void get_hp_params_from_firmware(struct pci_dev *dev,
55 struct controller *ctrl, 50 struct hotplug_params *hpp)
56 struct pci_func *func,
57 u8 card_type)
58{
59 u32 rc;
60 u8 temp_byte;
61 struct pci_bus lpci_bus, *pci_bus;
62 unsigned int devfn;
63 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
64 pci_bus = &lpci_bus;
65 pci_bus->number = func->bus;
66 devfn = PCI_DEVFN(func->device, func->function);
67
68 temp_byte = 0x40; /* hard coded value for LT */
69 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
70 /* set subordinate Latency Timer */
71 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, temp_byte);
72
73 if (rc) {
74 dbg("%s: set secondary LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus,
75 func->device, func->function);
76 return rc;
77 }
78 }
79
80 /* set base Latency Timer */
81 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
82
83 if (rc) {
84 dbg("%s: set LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
85 return rc;
86 }
87
88 /* set Cache Line size */
89 temp_byte = 0x08; /* hard coded value for CLS */
90
91 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
92
93 if (rc) {
94 dbg("%s: set CLS error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
95 }
96
97 /* set enable_perr */
98 /* set enable_serr */
99
100 return rc;
101}
102
103void shpchprm_enable_card(
104 struct controller *ctrl,
105 struct pci_func *func,
106 u8 card_type)
107{ 51{
108 u16 command, bcommand; 52 return;
109 struct pci_bus lpci_bus, *pci_bus;
110 unsigned int devfn;
111 int rc;
112
113 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
114 pci_bus = &lpci_bus;
115 pci_bus->number = func->bus;
116 devfn = PCI_DEVFN(func->device, func->function);
117
118 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command);
119
120 command |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR
121 | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
122 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
123
124 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
125
126 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
127
128 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand);
129
130 bcommand |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR
131 | PCI_BRIDGE_CTL_NO_ISA;
132
133 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
134 }
135}
136
137static int legacy_shpchprm_init_pci(void)
138{
139 return 0;
140} 53}
141 54
142int shpchprm_init(enum php_ctlr_type ctrl_type) 55void get_hp_hw_control_from_firmware(struct pci_dev *dev)
143{ 56{
144 int retval; 57 return;
145
146 switch (ctrl_type) {
147 case PCI:
148 retval = legacy_shpchprm_init_pci();
149 break;
150 default:
151 retval = -ENODEV;
152 break;
153 }
154
155 return retval;
156} 58}