diff options
Diffstat (limited to 'drivers/pci/hotplug')
-rw-r--r-- | drivers/pci/hotplug/Kconfig | 9 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp.h | 194 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_core.c | 292 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_ctrl.c | 223 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_hpc.c | 827 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp.h | 4 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp_core.c | 4 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp_ctrl.c | 20 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp_hpc.c | 185 |
9 files changed, 630 insertions, 1128 deletions
diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig index adce4204d87d..be92695a7833 100644 --- a/drivers/pci/hotplug/Kconfig +++ b/drivers/pci/hotplug/Kconfig | |||
@@ -145,15 +145,6 @@ config HOTPLUG_PCI_SHPC | |||
145 | 145 | ||
146 | When in doubt, say N. | 146 | When in doubt, say N. |
147 | 147 | ||
148 | config HOTPLUG_PCI_SHPC_POLL_EVENT_MODE | ||
149 | bool "Use polling mechanism for hot-plug events (for testing purpose)" | ||
150 | depends on HOTPLUG_PCI_SHPC | ||
151 | help | ||
152 | Say Y here if you want to use the polling mechanism for hot-plug | ||
153 | events for early platform testing. | ||
154 | |||
155 | When in doubt, say N. | ||
156 | |||
157 | config HOTPLUG_PCI_RPA | 148 | config HOTPLUG_PCI_RPA |
158 | tristate "RPA PCI Hotplug driver" | 149 | tristate "RPA PCI Hotplug driver" |
159 | depends on HOTPLUG_PCI && PPC_PSERIES && PPC64 && !HOTPLUG_PCI_FAKE | 150 | depends on HOTPLUG_PCI && PPC_PSERIES && PPC64 && !HOTPLUG_PCI_FAKE |
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 4fb12fcda563..d19fcae8a7c0 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
@@ -44,15 +44,20 @@ extern int pciehp_poll_time; | |||
44 | extern int pciehp_debug; | 44 | extern int pciehp_debug; |
45 | extern int pciehp_force; | 45 | extern int pciehp_force; |
46 | 46 | ||
47 | /*#define dbg(format, arg...) do { if (pciehp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/ | 47 | #define dbg(format, arg...) \ |
48 | #define dbg(format, arg...) do { if (pciehp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0) | 48 | do { \ |
49 | #define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg) | 49 | if (pciehp_debug) \ |
50 | #define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg) | 50 | printk("%s: " format, MY_NAME , ## arg); \ |
51 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg) | 51 | } while (0) |
52 | 52 | #define err(format, arg...) \ | |
53 | printk(KERN_ERR "%s: " format, MY_NAME , ## arg) | ||
54 | #define info(format, arg...) \ | ||
55 | printk(KERN_INFO "%s: " format, MY_NAME , ## arg) | ||
56 | #define warn(format, arg...) \ | ||
57 | printk(KERN_WARNING "%s: " format, MY_NAME , ## arg) | ||
53 | 58 | ||
59 | #define SLOT_NAME_SIZE 10 | ||
54 | struct slot { | 60 | struct slot { |
55 | struct slot *next; | ||
56 | u8 bus; | 61 | u8 bus; |
57 | u8 device; | 62 | u8 device; |
58 | u32 number; | 63 | u32 number; |
@@ -63,6 +68,8 @@ struct slot { | |||
63 | struct hpc_ops *hpc_ops; | 68 | struct hpc_ops *hpc_ops; |
64 | struct hotplug_slot *hotplug_slot; | 69 | struct hotplug_slot *hotplug_slot; |
65 | struct list_head slot_list; | 70 | struct list_head slot_list; |
71 | char name[SLOT_NAME_SIZE]; | ||
72 | unsigned long last_emi_toggle; | ||
66 | }; | 73 | }; |
67 | 74 | ||
68 | struct event_info { | 75 | struct event_info { |
@@ -70,34 +77,15 @@ struct event_info { | |||
70 | u8 hp_slot; | 77 | u8 hp_slot; |
71 | }; | 78 | }; |
72 | 79 | ||
73 | typedef u8(*php_intr_callback_t) (u8 hp_slot, void *instance_id); | ||
74 | |||
75 | struct php_ctlr_state_s { | ||
76 | struct php_ctlr_state_s *pnext; | ||
77 | struct pci_dev *pci_dev; | ||
78 | unsigned int irq; | ||
79 | unsigned long flags; /* spinlock's */ | ||
80 | u32 slot_device_offset; | ||
81 | u32 num_slots; | ||
82 | struct timer_list int_poll_timer; /* Added for poll event */ | ||
83 | php_intr_callback_t attention_button_callback; | ||
84 | php_intr_callback_t switch_change_callback; | ||
85 | php_intr_callback_t presence_change_callback; | ||
86 | php_intr_callback_t power_fault_callback; | ||
87 | void *callback_instance_id; | ||
88 | struct ctrl_reg *creg; /* Ptr to controller register space */ | ||
89 | }; | ||
90 | |||
91 | #define MAX_EVENTS 10 | 80 | #define MAX_EVENTS 10 |
92 | struct controller { | 81 | struct controller { |
93 | struct controller *next; | 82 | struct controller *next; |
94 | struct mutex crit_sect; /* critical section mutex */ | 83 | struct mutex crit_sect; /* critical section mutex */ |
95 | struct mutex ctrl_lock; /* controller lock */ | 84 | struct mutex ctrl_lock; /* controller lock */ |
96 | struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */ | ||
97 | int num_slots; /* Number of slots on ctlr */ | 85 | int num_slots; /* Number of slots on ctlr */ |
98 | int slot_num_inc; /* 1 or -1 */ | 86 | int slot_num_inc; /* 1 or -1 */ |
99 | struct pci_dev *pci_dev; | 87 | struct pci_dev *pci_dev; |
100 | struct pci_bus *pci_bus; | 88 | struct list_head slot_list; |
101 | struct event_info event_queue[MAX_EVENTS]; | 89 | struct event_info event_queue[MAX_EVENTS]; |
102 | struct slot *slot; | 90 | struct slot *slot; |
103 | struct hpc_ops *hpc_ops; | 91 | struct hpc_ops *hpc_ops; |
@@ -112,6 +100,8 @@ struct controller { | |||
112 | u8 ctrlcap; | 100 | u8 ctrlcap; |
113 | u16 vendor_id; | 101 | u16 vendor_id; |
114 | u8 cap_base; | 102 | u8 cap_base; |
103 | struct timer_list poll_timer; | ||
104 | volatile int cmd_busy; | ||
115 | }; | 105 | }; |
116 | 106 | ||
117 | #define INT_BUTTON_IGNORE 0 | 107 | #define INT_BUTTON_IGNORE 0 |
@@ -131,8 +121,6 @@ struct controller { | |||
131 | #define POWERON_STATE 3 | 121 | #define POWERON_STATE 3 |
132 | #define POWEROFF_STATE 4 | 122 | #define POWEROFF_STATE 4 |
133 | 123 | ||
134 | #define PCI_TO_PCI_BRIDGE_CLASS 0x00060400 | ||
135 | |||
136 | /* Error messages */ | 124 | /* Error messages */ |
137 | #define INTERLOCK_OPEN 0x00000002 | 125 | #define INTERLOCK_OPEN 0x00000002 |
138 | #define ADD_NOT_SUPPORTED 0x00000003 | 126 | #define ADD_NOT_SUPPORTED 0x00000003 |
@@ -144,10 +132,6 @@ struct controller { | |||
144 | #define WRONG_BUS_FREQUENCY 0x0000000D | 132 | #define WRONG_BUS_FREQUENCY 0x0000000D |
145 | #define POWER_FAILURE 0x0000000E | 133 | #define POWER_FAILURE 0x0000000E |
146 | 134 | ||
147 | #define REMOVE_NOT_SUPPORTED 0x00000003 | ||
148 | |||
149 | #define DISABLE_CARD 1 | ||
150 | |||
151 | /* Field definitions in Slot Capabilities Register */ | 135 | /* Field definitions in Slot Capabilities Register */ |
152 | #define ATTN_BUTTN_PRSN 0x00000001 | 136 | #define ATTN_BUTTN_PRSN 0x00000001 |
153 | #define PWR_CTRL_PRSN 0x00000002 | 137 | #define PWR_CTRL_PRSN 0x00000002 |
@@ -155,6 +139,7 @@ struct controller { | |||
155 | #define ATTN_LED_PRSN 0x00000008 | 139 | #define ATTN_LED_PRSN 0x00000008 |
156 | #define PWR_LED_PRSN 0x00000010 | 140 | #define PWR_LED_PRSN 0x00000010 |
157 | #define HP_SUPR_RM_SUP 0x00000020 | 141 | #define HP_SUPR_RM_SUP 0x00000020 |
142 | #define EMI_PRSN 0x00020000 | ||
158 | 143 | ||
159 | #define ATTN_BUTTN(cap) (cap & ATTN_BUTTN_PRSN) | 144 | #define ATTN_BUTTN(cap) (cap & ATTN_BUTTN_PRSN) |
160 | #define POWER_CTRL(cap) (cap & PWR_CTRL_PRSN) | 145 | #define POWER_CTRL(cap) (cap & PWR_CTRL_PRSN) |
@@ -162,130 +147,65 @@ struct controller { | |||
162 | #define ATTN_LED(cap) (cap & ATTN_LED_PRSN) | 147 | #define ATTN_LED(cap) (cap & ATTN_LED_PRSN) |
163 | #define PWR_LED(cap) (cap & PWR_LED_PRSN) | 148 | #define PWR_LED(cap) (cap & PWR_LED_PRSN) |
164 | #define HP_SUPR_RM(cap) (cap & HP_SUPR_RM_SUP) | 149 | #define HP_SUPR_RM(cap) (cap & HP_SUPR_RM_SUP) |
165 | 150 | #define EMI(cap) (cap & EMI_PRSN) | |
166 | /* | 151 | |
167 | * error Messages | 152 | extern int pciehp_event_start_thread(void); |
168 | */ | 153 | extern void pciehp_event_stop_thread(void); |
169 | #define msg_initialization_err "Initialization failure, error=%d\n" | 154 | extern int pciehp_enable_slot(struct slot *slot); |
170 | #define msg_button_on "PCI slot #%s - powering on due to button press.\n" | 155 | extern int pciehp_disable_slot(struct slot *slot); |
171 | #define msg_button_off "PCI slot #%s - powering off due to button press.\n" | 156 | extern u8 pciehp_handle_attention_button(u8 hp_slot, struct controller *ctrl); |
172 | #define msg_button_cancel "PCI slot #%s - action canceled due to button press.\n" | 157 | extern u8 pciehp_handle_switch_change(u8 hp_slot, struct controller *ctrl); |
173 | #define msg_button_ignore "PCI slot #%s - button press ignored. (action in progress...)\n" | 158 | extern u8 pciehp_handle_presence_change(u8 hp_slot, struct controller *ctrl); |
174 | 159 | extern u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl); | |
175 | /* controller functions */ | 160 | extern int pciehp_configure_device(struct slot *p_slot); |
176 | extern int pciehp_event_start_thread (void); | 161 | extern int pciehp_unconfigure_device(struct slot *p_slot); |
177 | extern void pciehp_event_stop_thread (void); | 162 | int pcie_init(struct controller *ctrl, struct pcie_device *dev); |
178 | extern int pciehp_enable_slot (struct slot *slot); | ||
179 | extern int pciehp_disable_slot (struct slot *slot); | ||
180 | |||
181 | extern u8 pciehp_handle_attention_button (u8 hp_slot, void *inst_id); | ||
182 | extern u8 pciehp_handle_switch_change (u8 hp_slot, void *inst_id); | ||
183 | extern u8 pciehp_handle_presence_change (u8 hp_slot, void *inst_id); | ||
184 | extern u8 pciehp_handle_power_fault (u8 hp_slot, void *inst_id); | ||
185 | /* extern void long_delay (int delay); */ | ||
186 | |||
187 | /* pci functions */ | ||
188 | extern int pciehp_configure_device (struct slot *p_slot); | ||
189 | extern int pciehp_unconfigure_device (struct slot *p_slot); | ||
190 | |||
191 | |||
192 | 163 | ||
193 | /* Global variables */ | 164 | /* Global variables */ |
194 | extern struct controller *pciehp_ctrl_list; | 165 | extern struct controller *pciehp_ctrl_list; |
195 | 166 | ||
196 | /* Inline functions */ | ||
197 | |||
198 | static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device) | 167 | static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device) |
199 | { | 168 | { |
200 | struct slot *p_slot, *tmp_slot = NULL; | 169 | struct slot *slot; |
201 | |||
202 | p_slot = ctrl->slot; | ||
203 | 170 | ||
204 | while (p_slot && (p_slot->device != device)) { | 171 | list_for_each_entry(slot, &ctrl->slot_list, slot_list) { |
205 | tmp_slot = p_slot; | 172 | if (slot->device == device) |
206 | p_slot = p_slot->next; | 173 | return slot; |
207 | } | 174 | } |
208 | if (p_slot == NULL) { | ||
209 | err("ERROR: pciehp_find_slot device=0x%x\n", device); | ||
210 | p_slot = tmp_slot; | ||
211 | } | ||
212 | |||
213 | return p_slot; | ||
214 | } | ||
215 | |||
216 | static inline int wait_for_ctrl_irq(struct controller *ctrl) | ||
217 | { | ||
218 | int retval = 0; | ||
219 | |||
220 | DECLARE_WAITQUEUE(wait, current); | ||
221 | |||
222 | add_wait_queue(&ctrl->queue, &wait); | ||
223 | if (!pciehp_poll_mode) | ||
224 | /* Sleep for up to 1 second */ | ||
225 | msleep_interruptible(1000); | ||
226 | else | ||
227 | msleep_interruptible(2500); | ||
228 | |||
229 | remove_wait_queue(&ctrl->queue, &wait); | ||
230 | if (signal_pending(current)) | ||
231 | retval = -EINTR; | ||
232 | |||
233 | return retval; | ||
234 | } | ||
235 | |||
236 | #define SLOT_NAME_SIZE 10 | ||
237 | 175 | ||
238 | static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot) | 176 | err("%s: slot (device=0x%x) not found\n", __FUNCTION__, device); |
239 | { | 177 | return NULL; |
240 | snprintf(buffer, buffer_size, "%04d_%04d", slot->bus, slot->number); | ||
241 | } | 178 | } |
242 | 179 | ||
243 | enum php_ctlr_type { | ||
244 | PCI, | ||
245 | ISA, | ||
246 | ACPI | ||
247 | }; | ||
248 | |||
249 | int pcie_init(struct controller *ctrl, struct pcie_device *dev); | ||
250 | |||
251 | /* This has no meaning for PCI Express, as there is only 1 slot per port */ | ||
252 | int pcie_get_ctlr_slot_config(struct controller *ctrl, | ||
253 | int *num_ctlr_slots, | ||
254 | int *first_device_num, | ||
255 | int *physical_slot_num, | ||
256 | u8 *ctrlcap); | ||
257 | |||
258 | struct hpc_ops { | 180 | struct hpc_ops { |
259 | int (*power_on_slot) (struct slot *slot); | 181 | int (*power_on_slot)(struct slot *slot); |
260 | int (*power_off_slot) (struct slot *slot); | 182 | int (*power_off_slot)(struct slot *slot); |
261 | int (*get_power_status) (struct slot *slot, u8 *status); | 183 | int (*get_power_status)(struct slot *slot, u8 *status); |
262 | int (*get_attention_status) (struct slot *slot, u8 *status); | 184 | int (*get_attention_status)(struct slot *slot, u8 *status); |
263 | int (*set_attention_status) (struct slot *slot, u8 status); | 185 | int (*set_attention_status)(struct slot *slot, u8 status); |
264 | int (*get_latch_status) (struct slot *slot, u8 *status); | 186 | int (*get_latch_status)(struct slot *slot, u8 *status); |
265 | int (*get_adapter_status) (struct slot *slot, u8 *status); | 187 | int (*get_adapter_status)(struct slot *slot, u8 *status); |
266 | 188 | int (*get_emi_status)(struct slot *slot, u8 *status); | |
267 | int (*get_max_bus_speed) (struct slot *slot, enum pci_bus_speed *speed); | 189 | int (*toggle_emi)(struct slot *slot); |
268 | int (*get_cur_bus_speed) (struct slot *slot, enum pci_bus_speed *speed); | 190 | int (*get_max_bus_speed)(struct slot *slot, enum pci_bus_speed *speed); |
269 | 191 | int (*get_cur_bus_speed)(struct slot *slot, enum pci_bus_speed *speed); | |
270 | int (*get_max_lnk_width) (struct slot *slot, enum pcie_link_width *value); | 192 | int (*get_max_lnk_width)(struct slot *slot, enum pcie_link_width *val); |
271 | int (*get_cur_lnk_width) (struct slot *slot, enum pcie_link_width *value); | 193 | int (*get_cur_lnk_width)(struct slot *slot, enum pcie_link_width *val); |
272 | 194 | int (*query_power_fault)(struct slot *slot); | |
273 | int (*query_power_fault) (struct slot *slot); | 195 | void (*green_led_on)(struct slot *slot); |
274 | void (*green_led_on) (struct slot *slot); | 196 | void (*green_led_off)(struct slot *slot); |
275 | void (*green_led_off) (struct slot *slot); | 197 | void (*green_led_blink)(struct slot *slot); |
276 | void (*green_led_blink) (struct slot *slot); | 198 | void (*release_ctlr)(struct controller *ctrl); |
277 | void (*release_ctlr) (struct controller *ctrl); | 199 | int (*check_lnk_status)(struct controller *ctrl); |
278 | int (*check_lnk_status) (struct controller *ctrl); | ||
279 | }; | 200 | }; |
280 | 201 | ||
281 | |||
282 | #ifdef CONFIG_ACPI | 202 | #ifdef CONFIG_ACPI |
283 | #include <acpi/acpi.h> | 203 | #include <acpi/acpi.h> |
284 | #include <acpi/acpi_bus.h> | 204 | #include <acpi/acpi_bus.h> |
285 | #include <acpi/actypes.h> | 205 | #include <acpi/actypes.h> |
286 | #include <linux/pci-acpi.h> | 206 | #include <linux/pci-acpi.h> |
287 | 207 | ||
288 | #define pciehp_get_hp_hw_control_from_firmware(dev) \ | 208 | #define pciehp_get_hp_hw_control_from_firmware(dev) \ |
289 | pciehp_acpi_get_hp_hw_control_from_firmware(dev) | 209 | pciehp_acpi_get_hp_hw_control_from_firmware(dev) |
290 | static inline int pciehp_get_hp_params_from_firmware(struct pci_dev *dev, | 210 | static inline int pciehp_get_hp_params_from_firmware(struct pci_dev *dev, |
291 | struct hotplug_params *hpp) | 211 | struct hotplug_params *hpp) |
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index f13f31323e85..a92eda6e02f6 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/pci.h> | 34 | #include <linux/pci.h> |
35 | #include "pciehp.h" | 35 | #include "pciehp.h" |
36 | #include <linux/interrupt.h> | 36 | #include <linux/interrupt.h> |
37 | #include <linux/time.h> | ||
37 | 38 | ||
38 | /* Global variables */ | 39 | /* Global variables */ |
39 | int pciehp_debug; | 40 | int pciehp_debug; |
@@ -87,6 +88,95 @@ static struct hotplug_slot_ops pciehp_hotplug_slot_ops = { | |||
87 | .get_cur_bus_speed = get_cur_bus_speed, | 88 | .get_cur_bus_speed = get_cur_bus_speed, |
88 | }; | 89 | }; |
89 | 90 | ||
91 | /* | ||
92 | * Check the status of the Electro Mechanical Interlock (EMI) | ||
93 | */ | ||
94 | static int get_lock_status(struct hotplug_slot *hotplug_slot, u8 *value) | ||
95 | { | ||
96 | struct slot *slot = hotplug_slot->private; | ||
97 | return (slot->hpc_ops->get_emi_status(slot, value)); | ||
98 | } | ||
99 | |||
100 | /* | ||
101 | * sysfs interface for the Electro Mechanical Interlock (EMI) | ||
102 | * 1 == locked, 0 == unlocked | ||
103 | */ | ||
104 | static ssize_t lock_read_file(struct hotplug_slot *slot, char *buf) | ||
105 | { | ||
106 | int retval; | ||
107 | u8 value; | ||
108 | |||
109 | retval = get_lock_status(slot, &value); | ||
110 | if (retval) | ||
111 | goto lock_read_exit; | ||
112 | retval = sprintf (buf, "%d\n", value); | ||
113 | |||
114 | lock_read_exit: | ||
115 | return retval; | ||
116 | } | ||
117 | |||
118 | /* | ||
119 | * Change the status of the Electro Mechanical Interlock (EMI) | ||
120 | * This is a toggle - in addition there must be at least 1 second | ||
121 | * in between toggles. | ||
122 | */ | ||
123 | static int set_lock_status(struct hotplug_slot *hotplug_slot, u8 status) | ||
124 | { | ||
125 | struct slot *slot = hotplug_slot->private; | ||
126 | int retval; | ||
127 | u8 value; | ||
128 | |||
129 | mutex_lock(&slot->ctrl->crit_sect); | ||
130 | |||
131 | /* has it been >1 sec since our last toggle? */ | ||
132 | if ((get_seconds() - slot->last_emi_toggle) < 1) | ||
133 | return -EINVAL; | ||
134 | |||
135 | /* see what our current state is */ | ||
136 | retval = get_lock_status(hotplug_slot, &value); | ||
137 | if (retval || (value == status)) | ||
138 | goto set_lock_exit; | ||
139 | |||
140 | slot->hpc_ops->toggle_emi(slot); | ||
141 | set_lock_exit: | ||
142 | mutex_unlock(&slot->ctrl->crit_sect); | ||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | /* | ||
147 | * sysfs interface which allows the user to toggle the Electro Mechanical | ||
148 | * Interlock. Valid values are either 0 or 1. 0 == unlock, 1 == lock | ||
149 | */ | ||
150 | static ssize_t lock_write_file(struct hotplug_slot *slot, const char *buf, | ||
151 | size_t count) | ||
152 | { | ||
153 | unsigned long llock; | ||
154 | u8 lock; | ||
155 | int retval = 0; | ||
156 | |||
157 | llock = simple_strtoul(buf, NULL, 10); | ||
158 | lock = (u8)(llock & 0xff); | ||
159 | |||
160 | switch (lock) { | ||
161 | case 0: | ||
162 | case 1: | ||
163 | retval = set_lock_status(slot, lock); | ||
164 | break; | ||
165 | default: | ||
166 | err ("%d is an invalid lock value\n", lock); | ||
167 | retval = -EINVAL; | ||
168 | } | ||
169 | if (retval) | ||
170 | return retval; | ||
171 | return count; | ||
172 | } | ||
173 | |||
174 | static struct hotplug_slot_attribute hotplug_slot_attr_lock = { | ||
175 | .attr = {.name = "lock", .mode = S_IFREG | S_IRUGO | S_IWUSR}, | ||
176 | .show = lock_read_file, | ||
177 | .store = lock_write_file | ||
178 | }; | ||
179 | |||
90 | /** | 180 | /** |
91 | * release_slot - free up the memory used by a slot | 181 | * release_slot - free up the memory used by a slot |
92 | * @hotplug_slot: slot to free | 182 | * @hotplug_slot: slot to free |
@@ -98,148 +188,108 @@ static void release_slot(struct hotplug_slot *hotplug_slot) | |||
98 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); | 188 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); |
99 | 189 | ||
100 | kfree(slot->hotplug_slot->info); | 190 | kfree(slot->hotplug_slot->info); |
101 | kfree(slot->hotplug_slot->name); | ||
102 | kfree(slot->hotplug_slot); | 191 | kfree(slot->hotplug_slot); |
103 | kfree(slot); | 192 | kfree(slot); |
104 | } | 193 | } |
105 | 194 | ||
195 | static void make_slot_name(struct slot *slot) | ||
196 | { | ||
197 | snprintf(slot->hotplug_slot->name, SLOT_NAME_SIZE, "%04d_%04d", | ||
198 | slot->bus, slot->number); | ||
199 | } | ||
200 | |||
106 | static int init_slots(struct controller *ctrl) | 201 | static int init_slots(struct controller *ctrl) |
107 | { | 202 | { |
108 | struct slot *slot; | 203 | struct slot *slot; |
109 | struct hpc_ops *hpc_ops; | ||
110 | struct hotplug_slot *hotplug_slot; | 204 | struct hotplug_slot *hotplug_slot; |
111 | struct hotplug_slot_info *hotplug_slot_info; | 205 | struct hotplug_slot_info *info; |
112 | u8 number_of_slots; | 206 | int retval = -ENOMEM; |
113 | u8 slot_device; | 207 | int i; |
114 | u32 slot_number; | ||
115 | int result = -ENOMEM; | ||
116 | 208 | ||
117 | number_of_slots = ctrl->num_slots; | 209 | for (i = 0; i < ctrl->num_slots; i++) { |
118 | slot_device = ctrl->slot_device_offset; | ||
119 | slot_number = ctrl->first_slot; | ||
120 | |||
121 | while (number_of_slots) { | ||
122 | slot = kzalloc(sizeof(*slot), GFP_KERNEL); | 210 | slot = kzalloc(sizeof(*slot), GFP_KERNEL); |
123 | if (!slot) | 211 | if (!slot) |
124 | goto error; | 212 | goto error; |
125 | 213 | ||
126 | slot->hotplug_slot = | 214 | hotplug_slot = kzalloc(sizeof(*hotplug_slot), GFP_KERNEL); |
127 | kzalloc(sizeof(*(slot->hotplug_slot)), | 215 | if (!hotplug_slot) |
128 | GFP_KERNEL); | ||
129 | if (!slot->hotplug_slot) | ||
130 | goto error_slot; | 216 | goto error_slot; |
131 | hotplug_slot = slot->hotplug_slot; | 217 | slot->hotplug_slot = hotplug_slot; |
132 | 218 | ||
133 | hotplug_slot->info = | 219 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
134 | kzalloc(sizeof(*(hotplug_slot->info)), | 220 | if (!info) |
135 | GFP_KERNEL); | ||
136 | if (!hotplug_slot->info) | ||
137 | goto error_hpslot; | 221 | goto error_hpslot; |
138 | hotplug_slot_info = hotplug_slot->info; | 222 | hotplug_slot->info = info; |
139 | hotplug_slot->name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL); | ||
140 | if (!hotplug_slot->name) | ||
141 | goto error_info; | ||
142 | 223 | ||
143 | slot->ctrl = ctrl; | 224 | hotplug_slot->name = slot->name; |
144 | slot->bus = ctrl->slot_bus; | ||
145 | slot->device = slot_device; | ||
146 | slot->hpc_ops = hpc_ops = ctrl->hpc_ops; | ||
147 | 225 | ||
226 | slot->hp_slot = i; | ||
227 | slot->ctrl = ctrl; | ||
228 | slot->bus = ctrl->pci_dev->subordinate->number; | ||
229 | slot->device = ctrl->slot_device_offset + i; | ||
230 | slot->hpc_ops = ctrl->hpc_ops; | ||
148 | slot->number = ctrl->first_slot; | 231 | slot->number = ctrl->first_slot; |
149 | slot->hp_slot = slot_device - ctrl->slot_device_offset; | ||
150 | 232 | ||
151 | /* register this slot with the hotplug pci core */ | 233 | /* register this slot with the hotplug pci core */ |
152 | hotplug_slot->private = slot; | 234 | hotplug_slot->private = slot; |
153 | hotplug_slot->release = &release_slot; | 235 | hotplug_slot->release = &release_slot; |
154 | make_slot_name(hotplug_slot->name, SLOT_NAME_SIZE, slot); | 236 | make_slot_name(slot); |
155 | hotplug_slot->ops = &pciehp_hotplug_slot_ops; | 237 | hotplug_slot->ops = &pciehp_hotplug_slot_ops; |
156 | 238 | ||
157 | hpc_ops->get_power_status(slot, | 239 | get_power_status(hotplug_slot, &info->power_status); |
158 | &(hotplug_slot_info->power_status)); | 240 | get_attention_status(hotplug_slot, &info->attention_status); |
159 | hpc_ops->get_attention_status(slot, | 241 | get_latch_status(hotplug_slot, &info->latch_status); |
160 | &(hotplug_slot_info->attention_status)); | 242 | get_adapter_status(hotplug_slot, &info->adapter_status); |
161 | hpc_ops->get_latch_status(slot, | ||
162 | &(hotplug_slot_info->latch_status)); | ||
163 | hpc_ops->get_adapter_status(slot, | ||
164 | &(hotplug_slot_info->adapter_status)); | ||
165 | 243 | ||
166 | dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x " | 244 | dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x " |
167 | "slot_device_offset=%x\n", | 245 | "slot_device_offset=%x\n", slot->bus, slot->device, |
168 | slot->bus, slot->device, slot->hp_slot, slot->number, | 246 | slot->hp_slot, slot->number, ctrl->slot_device_offset); |
169 | ctrl->slot_device_offset); | 247 | retval = pci_hp_register(hotplug_slot); |
170 | result = pci_hp_register(hotplug_slot); | 248 | if (retval) { |
171 | if (result) { | 249 | err ("pci_hp_register failed with error %d\n", retval); |
172 | err ("pci_hp_register failed with error %d\n", result); | 250 | goto error_info; |
173 | goto error_name; | 251 | } |
252 | /* create additional sysfs entries */ | ||
253 | if (EMI(ctrl->ctrlcap)) { | ||
254 | retval = sysfs_create_file(&hotplug_slot->kobj, | ||
255 | &hotplug_slot_attr_lock.attr); | ||
256 | if (retval) { | ||
257 | pci_hp_deregister(hotplug_slot); | ||
258 | err("cannot create additional sysfs entries\n"); | ||
259 | goto error_info; | ||
260 | } | ||
174 | } | 261 | } |
175 | 262 | ||
176 | slot->next = ctrl->slot; | 263 | list_add(&slot->slot_list, &ctrl->slot_list); |
177 | ctrl->slot = slot; | ||
178 | |||
179 | number_of_slots--; | ||
180 | slot_device++; | ||
181 | slot_number += ctrl->slot_num_inc; | ||
182 | } | 264 | } |
183 | 265 | ||
184 | return 0; | 266 | return 0; |
185 | |||
186 | error_name: | ||
187 | kfree(hotplug_slot->name); | ||
188 | error_info: | 267 | error_info: |
189 | kfree(hotplug_slot_info); | 268 | kfree(info); |
190 | error_hpslot: | 269 | error_hpslot: |
191 | kfree(hotplug_slot); | 270 | kfree(hotplug_slot); |
192 | error_slot: | 271 | error_slot: |
193 | kfree(slot); | 272 | kfree(slot); |
194 | error: | 273 | error: |
195 | return result; | 274 | return retval; |
196 | } | ||
197 | |||
198 | |||
199 | static int cleanup_slots (struct controller * ctrl) | ||
200 | { | ||
201 | struct slot *old_slot, *next_slot; | ||
202 | |||
203 | old_slot = ctrl->slot; | ||
204 | ctrl->slot = NULL; | ||
205 | |||
206 | while (old_slot) { | ||
207 | next_slot = old_slot->next; | ||
208 | pci_hp_deregister (old_slot->hotplug_slot); | ||
209 | old_slot = next_slot; | ||
210 | } | ||
211 | |||
212 | |||
213 | return(0); | ||
214 | } | 275 | } |
215 | 276 | ||
216 | static int get_ctlr_slot_config(struct controller *ctrl) | 277 | static void cleanup_slots(struct controller *ctrl) |
217 | { | 278 | { |
218 | int num_ctlr_slots; /* Not needed; PCI Express has 1 slot per port*/ | 279 | struct list_head *tmp; |
219 | int first_device_num; /* Not needed */ | 280 | struct list_head *next; |
220 | int physical_slot_num; | 281 | struct slot *slot; |
221 | u8 ctrlcap; | ||
222 | int rc; | ||
223 | 282 | ||
224 | rc = pcie_get_ctlr_slot_config(ctrl, &num_ctlr_slots, &first_device_num, &physical_slot_num, &ctrlcap); | 283 | list_for_each_safe(tmp, next, &ctrl->slot_list) { |
225 | if (rc) { | 284 | slot = list_entry(tmp, struct slot, slot_list); |
226 | err("%s: get_ctlr_slot_config fail for b:d (%x:%x)\n", __FUNCTION__, ctrl->bus, ctrl->device); | 285 | list_del(&slot->slot_list); |
227 | return (-1); | 286 | if (EMI(ctrl->ctrlcap)) |
287 | sysfs_remove_file(&slot->hotplug_slot->kobj, | ||
288 | &hotplug_slot_attr_lock.attr); | ||
289 | pci_hp_deregister(slot->hotplug_slot); | ||
228 | } | 290 | } |
229 | |||
230 | ctrl->num_slots = num_ctlr_slots; /* PCI Express has 1 slot per port */ | ||
231 | ctrl->slot_device_offset = first_device_num; | ||
232 | ctrl->first_slot = physical_slot_num; | ||
233 | ctrl->ctrlcap = ctrlcap; | ||
234 | |||
235 | dbg("%s: bus(0x%x) num_slot(0x%x) 1st_dev(0x%x) psn(0x%x) ctrlcap(%x) for b:d (%x:%x)\n", | ||
236 | __FUNCTION__, ctrl->slot_bus, num_ctlr_slots, first_device_num, physical_slot_num, ctrlcap, | ||
237 | ctrl->bus, ctrl->device); | ||
238 | |||
239 | return (0); | ||
240 | } | 291 | } |
241 | 292 | ||
242 | |||
243 | /* | 293 | /* |
244 | * set_attention_status - Turns the Amber LED for a slot on, off or blink | 294 | * set_attention_status - Turns the Amber LED for a slot on, off or blink |
245 | */ | 295 | */ |
@@ -378,8 +428,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ | |||
378 | int rc; | 428 | int rc; |
379 | struct controller *ctrl; | 429 | struct controller *ctrl; |
380 | struct slot *t_slot; | 430 | struct slot *t_slot; |
381 | int first_device_num = 0 ; /* first PCI device number supported by this PCIE */ | ||
382 | int num_ctlr_slots; /* number of slots supported by this HPC */ | ||
383 | u8 value; | 431 | u8 value; |
384 | struct pci_dev *pdev; | 432 | struct pci_dev *pdev; |
385 | 433 | ||
@@ -388,6 +436,7 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ | |||
388 | err("%s : out of memory\n", __FUNCTION__); | 436 | err("%s : out of memory\n", __FUNCTION__); |
389 | goto err_out_none; | 437 | goto err_out_none; |
390 | } | 438 | } |
439 | INIT_LIST_HEAD(&ctrl->slot_list); | ||
391 | 440 | ||
392 | pdev = dev->port; | 441 | pdev = dev->port; |
393 | ctrl->pci_dev = pdev; | 442 | ctrl->pci_dev = pdev; |
@@ -400,13 +449,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ | |||
400 | 449 | ||
401 | pci_set_drvdata(pdev, ctrl); | 450 | pci_set_drvdata(pdev, ctrl); |
402 | 451 | ||
403 | ctrl->pci_bus = kmalloc(sizeof(*ctrl->pci_bus), GFP_KERNEL); | ||
404 | if (!ctrl->pci_bus) { | ||
405 | err("%s: out of memory\n", __FUNCTION__); | ||
406 | rc = -ENOMEM; | ||
407 | goto err_out_unmap_mmio_region; | ||
408 | } | ||
409 | memcpy (ctrl->pci_bus, pdev->bus, sizeof (*ctrl->pci_bus)); | ||
410 | ctrl->bus = pdev->bus->number; /* ctrl bus */ | 452 | ctrl->bus = pdev->bus->number; /* ctrl bus */ |
411 | ctrl->slot_bus = pdev->subordinate->number; /* bus controlled by this HPC */ | 453 | ctrl->slot_bus = pdev->subordinate->number; /* bus controlled by this HPC */ |
412 | 454 | ||
@@ -415,26 +457,14 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ | |||
415 | dbg("%s: ctrl bus=0x%x, device=%x, function=%x, irq=%x\n", __FUNCTION__, | 457 | dbg("%s: ctrl bus=0x%x, device=%x, function=%x, irq=%x\n", __FUNCTION__, |
416 | ctrl->bus, ctrl->device, ctrl->function, pdev->irq); | 458 | ctrl->bus, ctrl->device, ctrl->function, pdev->irq); |
417 | 459 | ||
418 | /* | ||
419 | * Save configuration headers for this and subordinate PCI buses | ||
420 | */ | ||
421 | |||
422 | rc = get_ctlr_slot_config(ctrl); | ||
423 | if (rc) { | ||
424 | err(msg_initialization_err, rc); | ||
425 | goto err_out_free_ctrl_bus; | ||
426 | } | ||
427 | first_device_num = ctrl->slot_device_offset; | ||
428 | num_ctlr_slots = ctrl->num_slots; | ||
429 | |||
430 | /* Setup the slot information structures */ | 460 | /* Setup the slot information structures */ |
431 | rc = init_slots(ctrl); | 461 | rc = init_slots(ctrl); |
432 | if (rc) { | 462 | if (rc) { |
433 | err(msg_initialization_err, 6); | 463 | err("%s: slot initialization failed\n", PCIE_MODULE_NAME); |
434 | goto err_out_free_ctrl_slot; | 464 | goto err_out_release_ctlr; |
435 | } | 465 | } |
436 | 466 | ||
437 | t_slot = pciehp_find_slot(ctrl, first_device_num); | 467 | t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset); |
438 | 468 | ||
439 | /* Finish setting up the hot plug ctrl device */ | 469 | /* Finish setting up the hot plug ctrl device */ |
440 | ctrl->next_event = 0; | 470 | ctrl->next_event = 0; |
@@ -447,32 +477,18 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ | |||
447 | pciehp_ctrl_list = ctrl; | 477 | pciehp_ctrl_list = ctrl; |
448 | } | 478 | } |
449 | 479 | ||
450 | /* Wait for exclusive access to hardware */ | ||
451 | mutex_lock(&ctrl->ctrl_lock); | ||
452 | |||
453 | t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */ | 480 | t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */ |
454 | |||
455 | if ((POWER_CTRL(ctrl->ctrlcap)) && !value) { | 481 | if ((POWER_CTRL(ctrl->ctrlcap)) && !value) { |
456 | rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/ | 482 | rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/ |
457 | if (rc) { | 483 | if (rc) |
458 | /* Done with exclusive hardware access */ | ||
459 | mutex_unlock(&ctrl->ctrl_lock); | ||
460 | goto err_out_free_ctrl_slot; | 484 | goto err_out_free_ctrl_slot; |
461 | } else | ||
462 | /* Wait for the command to complete */ | ||
463 | wait_for_ctrl_irq (ctrl); | ||
464 | } | 485 | } |
465 | 486 | ||
466 | /* Done with exclusive hardware access */ | ||
467 | mutex_unlock(&ctrl->ctrl_lock); | ||
468 | |||
469 | return 0; | 487 | return 0; |
470 | 488 | ||
471 | err_out_free_ctrl_slot: | 489 | err_out_free_ctrl_slot: |
472 | cleanup_slots(ctrl); | 490 | cleanup_slots(ctrl); |
473 | err_out_free_ctrl_bus: | 491 | err_out_release_ctlr: |
474 | kfree(ctrl->pci_bus); | ||
475 | err_out_unmap_mmio_region: | ||
476 | ctrl->hpc_ops->release_ctlr(ctrl); | 492 | ctrl->hpc_ops->release_ctlr(ctrl); |
477 | err_out_free_ctrl: | 493 | err_out_free_ctrl: |
478 | kfree(ctrl); | 494 | kfree(ctrl); |
@@ -506,8 +522,6 @@ static void __exit unload_pciehpd(void) | |||
506 | while (ctrl) { | 522 | while (ctrl) { |
507 | cleanup_slots(ctrl); | 523 | cleanup_slots(ctrl); |
508 | 524 | ||
509 | kfree (ctrl->pci_bus); | ||
510 | |||
511 | ctrl->hpc_ops->release_ctlr(ctrl); | 525 | ctrl->hpc_ops->release_ctlr(ctrl); |
512 | 526 | ||
513 | tctrl = ctrl; | 527 | tctrl = ctrl; |
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 372c63e35aa9..4283ef56dbd9 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c | |||
@@ -48,9 +48,8 @@ static inline char *slot_name(struct slot *p_slot) | |||
48 | return p_slot->hotplug_slot->name; | 48 | return p_slot->hotplug_slot->name; |
49 | } | 49 | } |
50 | 50 | ||
51 | u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id) | 51 | u8 pciehp_handle_attention_button(u8 hp_slot, struct controller *ctrl) |
52 | { | 52 | { |
53 | struct controller *ctrl = (struct controller *) inst_id; | ||
54 | struct slot *p_slot; | 53 | struct slot *p_slot; |
55 | u8 rc = 0; | 54 | u8 rc = 0; |
56 | u8 getstatus; | 55 | u8 getstatus; |
@@ -101,9 +100,8 @@ u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id) | |||
101 | 100 | ||
102 | } | 101 | } |
103 | 102 | ||
104 | u8 pciehp_handle_switch_change(u8 hp_slot, void *inst_id) | 103 | u8 pciehp_handle_switch_change(u8 hp_slot, struct controller *ctrl) |
105 | { | 104 | { |
106 | struct controller *ctrl = (struct controller *) inst_id; | ||
107 | struct slot *p_slot; | 105 | struct slot *p_slot; |
108 | u8 rc = 0; | 106 | u8 rc = 0; |
109 | u8 getstatus; | 107 | u8 getstatus; |
@@ -143,9 +141,8 @@ u8 pciehp_handle_switch_change(u8 hp_slot, void *inst_id) | |||
143 | return rc; | 141 | return rc; |
144 | } | 142 | } |
145 | 143 | ||
146 | u8 pciehp_handle_presence_change(u8 hp_slot, void *inst_id) | 144 | u8 pciehp_handle_presence_change(u8 hp_slot, struct controller *ctrl) |
147 | { | 145 | { |
148 | struct controller *ctrl = (struct controller *) inst_id; | ||
149 | struct slot *p_slot; | 146 | struct slot *p_slot; |
150 | u8 presence_save, rc = 0; | 147 | u8 presence_save, rc = 0; |
151 | struct event_info *taskInfo; | 148 | struct event_info *taskInfo; |
@@ -187,9 +184,8 @@ u8 pciehp_handle_presence_change(u8 hp_slot, void *inst_id) | |||
187 | return rc; | 184 | return rc; |
188 | } | 185 | } |
189 | 186 | ||
190 | u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id) | 187 | u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl) |
191 | { | 188 | { |
192 | struct controller *ctrl = (struct controller *) inst_id; | ||
193 | struct slot *p_slot; | 189 | struct slot *p_slot; |
194 | u8 rc = 0; | 190 | u8 rc = 0; |
195 | struct event_info *taskInfo; | 191 | struct event_info *taskInfo; |
@@ -233,35 +229,25 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id) | |||
233 | 229 | ||
234 | static void set_slot_off(struct controller *ctrl, struct slot * pslot) | 230 | static void set_slot_off(struct controller *ctrl, struct slot * pslot) |
235 | { | 231 | { |
236 | /* Wait for exclusive access to hardware */ | ||
237 | mutex_lock(&ctrl->ctrl_lock); | ||
238 | |||
239 | /* turn off slot, turn on Amber LED, turn off Green LED if supported*/ | 232 | /* turn off slot, turn on Amber LED, turn off Green LED if supported*/ |
240 | if (POWER_CTRL(ctrl->ctrlcap)) { | 233 | if (POWER_CTRL(ctrl->ctrlcap)) { |
241 | if (pslot->hpc_ops->power_off_slot(pslot)) { | 234 | if (pslot->hpc_ops->power_off_slot(pslot)) { |
242 | err("%s: Issue of Slot Power Off command failed\n", __FUNCTION__); | 235 | err("%s: Issue of Slot Power Off command failed\n", |
243 | mutex_unlock(&ctrl->ctrl_lock); | 236 | __FUNCTION__); |
244 | return; | 237 | return; |
245 | } | 238 | } |
246 | wait_for_ctrl_irq (ctrl); | ||
247 | } | 239 | } |
248 | 240 | ||
249 | if (PWR_LED(ctrl->ctrlcap)) { | 241 | if (PWR_LED(ctrl->ctrlcap)) |
250 | pslot->hpc_ops->green_led_off(pslot); | 242 | pslot->hpc_ops->green_led_off(pslot); |
251 | wait_for_ctrl_irq (ctrl); | ||
252 | } | ||
253 | 243 | ||
254 | if (ATTN_LED(ctrl->ctrlcap)) { | 244 | if (ATTN_LED(ctrl->ctrlcap)) { |
255 | if (pslot->hpc_ops->set_attention_status(pslot, 1)) { | 245 | if (pslot->hpc_ops->set_attention_status(pslot, 1)) { |
256 | err("%s: Issue of Set Attention Led command failed\n", __FUNCTION__); | 246 | err("%s: Issue of Set Attention Led command failed\n", |
257 | mutex_unlock(&ctrl->ctrl_lock); | 247 | __FUNCTION__); |
258 | return; | 248 | return; |
259 | } | 249 | } |
260 | wait_for_ctrl_irq (ctrl); | ||
261 | } | 250 | } |
262 | |||
263 | /* Done with exclusive hardware access */ | ||
264 | mutex_unlock(&ctrl->ctrl_lock); | ||
265 | } | 251 | } |
266 | 252 | ||
267 | /** | 253 | /** |
@@ -274,7 +260,7 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot) | |||
274 | static int board_added(struct slot *p_slot) | 260 | static int board_added(struct slot *p_slot) |
275 | { | 261 | { |
276 | u8 hp_slot; | 262 | u8 hp_slot; |
277 | int rc = 0; | 263 | int retval = 0; |
278 | struct controller *ctrl = p_slot->ctrl; | 264 | struct controller *ctrl = p_slot->ctrl; |
279 | 265 | ||
280 | hp_slot = p_slot->device - ctrl->slot_device_offset; | 266 | hp_slot = p_slot->device - ctrl->slot_device_offset; |
@@ -283,53 +269,38 @@ static int board_added(struct slot *p_slot) | |||
283 | __FUNCTION__, p_slot->device, | 269 | __FUNCTION__, p_slot->device, |
284 | ctrl->slot_device_offset, hp_slot); | 270 | ctrl->slot_device_offset, hp_slot); |
285 | 271 | ||
286 | /* Wait for exclusive access to hardware */ | ||
287 | mutex_lock(&ctrl->ctrl_lock); | ||
288 | |||
289 | if (POWER_CTRL(ctrl->ctrlcap)) { | 272 | if (POWER_CTRL(ctrl->ctrlcap)) { |
290 | /* Power on slot */ | 273 | /* Power on slot */ |
291 | rc = p_slot->hpc_ops->power_on_slot(p_slot); | 274 | retval = p_slot->hpc_ops->power_on_slot(p_slot); |
292 | if (rc) { | 275 | if (retval) |
293 | mutex_unlock(&ctrl->ctrl_lock); | 276 | return retval; |
294 | return -1; | ||
295 | } | ||
296 | |||
297 | /* Wait for the command to complete */ | ||
298 | wait_for_ctrl_irq (ctrl); | ||
299 | } | 277 | } |
300 | 278 | ||
301 | if (PWR_LED(ctrl->ctrlcap)) { | 279 | if (PWR_LED(ctrl->ctrlcap)) |
302 | p_slot->hpc_ops->green_led_blink(p_slot); | 280 | p_slot->hpc_ops->green_led_blink(p_slot); |
303 | |||
304 | /* Wait for the command to complete */ | ||
305 | wait_for_ctrl_irq (ctrl); | ||
306 | } | ||
307 | |||
308 | /* Done with exclusive hardware access */ | ||
309 | mutex_unlock(&ctrl->ctrl_lock); | ||
310 | 281 | ||
311 | /* Wait for ~1 second */ | 282 | /* Wait for ~1 second */ |
312 | wait_for_ctrl_irq (ctrl); | 283 | msleep(1000); |
313 | 284 | ||
314 | /* Check link training status */ | 285 | /* Check link training status */ |
315 | rc = p_slot->hpc_ops->check_lnk_status(ctrl); | 286 | retval = p_slot->hpc_ops->check_lnk_status(ctrl); |
316 | if (rc) { | 287 | if (retval) { |
317 | err("%s: Failed to check link status\n", __FUNCTION__); | 288 | err("%s: Failed to check link status\n", __FUNCTION__); |
318 | set_slot_off(ctrl, p_slot); | 289 | set_slot_off(ctrl, p_slot); |
319 | return rc; | 290 | return retval; |
320 | } | 291 | } |
321 | 292 | ||
322 | /* Check for a power fault */ | 293 | /* Check for a power fault */ |
323 | if (p_slot->hpc_ops->query_power_fault(p_slot)) { | 294 | if (p_slot->hpc_ops->query_power_fault(p_slot)) { |
324 | dbg("%s: power fault detected\n", __FUNCTION__); | 295 | dbg("%s: power fault detected\n", __FUNCTION__); |
325 | rc = POWER_FAILURE; | 296 | retval = POWER_FAILURE; |
326 | goto err_exit; | 297 | goto err_exit; |
327 | } | 298 | } |
328 | 299 | ||
329 | rc = pciehp_configure_device(p_slot); | 300 | retval = pciehp_configure_device(p_slot); |
330 | if (rc) { | 301 | if (retval) { |
331 | err("Cannot add device 0x%x:%x\n", p_slot->bus, | 302 | err("Cannot add device 0x%x:%x\n", p_slot->bus, |
332 | p_slot->device); | 303 | p_slot->device); |
333 | goto err_exit; | 304 | goto err_exit; |
334 | } | 305 | } |
335 | 306 | ||
@@ -338,26 +309,16 @@ static int board_added(struct slot *p_slot) | |||
338 | */ | 309 | */ |
339 | if (pcie_mch_quirk) | 310 | if (pcie_mch_quirk) |
340 | pci_fixup_device(pci_fixup_final, ctrl->pci_dev); | 311 | pci_fixup_device(pci_fixup_final, ctrl->pci_dev); |
341 | if (PWR_LED(ctrl->ctrlcap)) { | 312 | if (PWR_LED(ctrl->ctrlcap)) |
342 | /* Wait for exclusive access to hardware */ | ||
343 | mutex_lock(&ctrl->ctrl_lock); | ||
344 | |||
345 | p_slot->hpc_ops->green_led_on(p_slot); | 313 | p_slot->hpc_ops->green_led_on(p_slot); |
346 | 314 | ||
347 | /* Wait for the command to complete */ | ||
348 | wait_for_ctrl_irq (ctrl); | ||
349 | |||
350 | /* Done with exclusive hardware access */ | ||
351 | mutex_unlock(&ctrl->ctrl_lock); | ||
352 | } | ||
353 | return 0; | 315 | return 0; |
354 | 316 | ||
355 | err_exit: | 317 | err_exit: |
356 | set_slot_off(ctrl, p_slot); | 318 | set_slot_off(ctrl, p_slot); |
357 | return -1; | 319 | return retval; |
358 | } | 320 | } |
359 | 321 | ||
360 | |||
361 | /** | 322 | /** |
362 | * remove_board - Turns off slot and LED's | 323 | * remove_board - Turns off slot and LED's |
363 | * | 324 | * |
@@ -366,44 +327,32 @@ static int remove_board(struct slot *p_slot) | |||
366 | { | 327 | { |
367 | u8 device; | 328 | u8 device; |
368 | u8 hp_slot; | 329 | u8 hp_slot; |
369 | int rc; | 330 | int retval = 0; |
370 | struct controller *ctrl = p_slot->ctrl; | 331 | struct controller *ctrl = p_slot->ctrl; |
371 | 332 | ||
372 | if (pciehp_unconfigure_device(p_slot)) | 333 | retval = pciehp_unconfigure_device(p_slot); |
373 | return 1; | 334 | if (retval) |
335 | return retval; | ||
374 | 336 | ||
375 | device = p_slot->device; | 337 | device = p_slot->device; |
376 | |||
377 | hp_slot = p_slot->device - ctrl->slot_device_offset; | 338 | hp_slot = p_slot->device - ctrl->slot_device_offset; |
378 | p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); | 339 | p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); |
379 | 340 | ||
380 | dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot); | 341 | dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot); |
381 | 342 | ||
382 | /* Wait for exclusive access to hardware */ | ||
383 | mutex_lock(&ctrl->ctrl_lock); | ||
384 | |||
385 | if (POWER_CTRL(ctrl->ctrlcap)) { | 343 | if (POWER_CTRL(ctrl->ctrlcap)) { |
386 | /* power off slot */ | 344 | /* power off slot */ |
387 | rc = p_slot->hpc_ops->power_off_slot(p_slot); | 345 | retval = p_slot->hpc_ops->power_off_slot(p_slot); |
388 | if (rc) { | 346 | if (retval) { |
389 | err("%s: Issue of Slot Disable command failed\n", __FUNCTION__); | 347 | err("%s: Issue of Slot Disable command failed\n", |
390 | mutex_unlock(&ctrl->ctrl_lock); | 348 | __FUNCTION__); |
391 | return rc; | 349 | return retval; |
392 | } | 350 | } |
393 | /* Wait for the command to complete */ | ||
394 | wait_for_ctrl_irq (ctrl); | ||
395 | } | 351 | } |
396 | 352 | ||
397 | if (PWR_LED(ctrl->ctrlcap)) { | 353 | if (PWR_LED(ctrl->ctrlcap)) |
398 | /* turn off Green LED */ | 354 | /* turn off Green LED */ |
399 | p_slot->hpc_ops->green_led_off(p_slot); | 355 | p_slot->hpc_ops->green_led_off(p_slot); |
400 | |||
401 | /* Wait for the command to complete */ | ||
402 | wait_for_ctrl_irq (ctrl); | ||
403 | } | ||
404 | |||
405 | /* Done with exclusive hardware access */ | ||
406 | mutex_unlock(&ctrl->ctrl_lock); | ||
407 | 356 | ||
408 | return 0; | 357 | return 0; |
409 | } | 358 | } |
@@ -448,18 +397,10 @@ static void pciehp_pushbutton_thread(unsigned long slot) | |||
448 | dbg("%s: adding bus:device(%x:%x)\n", __FUNCTION__, | 397 | dbg("%s: adding bus:device(%x:%x)\n", __FUNCTION__, |
449 | p_slot->bus, p_slot->device); | 398 | p_slot->bus, p_slot->device); |
450 | 399 | ||
451 | if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) { | 400 | if (pciehp_enable_slot(p_slot) && |
452 | /* Wait for exclusive access to hardware */ | 401 | PWR_LED(p_slot->ctrl->ctrlcap)) |
453 | mutex_lock(&p_slot->ctrl->ctrl_lock); | ||
454 | |||
455 | p_slot->hpc_ops->green_led_off(p_slot); | 402 | p_slot->hpc_ops->green_led_off(p_slot); |
456 | 403 | ||
457 | /* Wait for the command to complete */ | ||
458 | wait_for_ctrl_irq (p_slot->ctrl); | ||
459 | |||
460 | /* Done with exclusive hardware access */ | ||
461 | mutex_unlock(&p_slot->ctrl->ctrl_lock); | ||
462 | } | ||
463 | p_slot->state = STATIC_STATE; | 404 | p_slot->state = STATIC_STATE; |
464 | } | 405 | } |
465 | 406 | ||
@@ -498,18 +439,10 @@ static void pciehp_surprise_rm_thread(unsigned long slot) | |||
498 | dbg("%s: adding bus:device(%x:%x)\n", | 439 | dbg("%s: adding bus:device(%x:%x)\n", |
499 | __FUNCTION__, p_slot->bus, p_slot->device); | 440 | __FUNCTION__, p_slot->bus, p_slot->device); |
500 | 441 | ||
501 | if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) { | 442 | if (pciehp_enable_slot(p_slot) && |
502 | /* Wait for exclusive access to hardware */ | 443 | PWR_LED(p_slot->ctrl->ctrlcap)) |
503 | mutex_lock(&p_slot->ctrl->ctrl_lock); | ||
504 | |||
505 | p_slot->hpc_ops->green_led_off(p_slot); | 444 | p_slot->hpc_ops->green_led_off(p_slot); |
506 | 445 | ||
507 | /* Wait for the command to complete */ | ||
508 | wait_for_ctrl_irq (p_slot->ctrl); | ||
509 | |||
510 | /* Done with exclusive hardware access */ | ||
511 | mutex_unlock(&p_slot->ctrl->ctrl_lock); | ||
512 | } | ||
513 | p_slot->state = STATIC_STATE; | 446 | p_slot->state = STATIC_STATE; |
514 | } | 447 | } |
515 | 448 | ||
@@ -620,46 +553,24 @@ static void interrupt_event_handler(struct controller *ctrl) | |||
620 | 553 | ||
621 | switch (p_slot->state) { | 554 | switch (p_slot->state) { |
622 | case BLINKINGOFF_STATE: | 555 | case BLINKINGOFF_STATE: |
623 | /* Wait for exclusive access to hardware */ | 556 | if (PWR_LED(ctrl->ctrlcap)) |
624 | mutex_lock(&ctrl->ctrl_lock); | ||
625 | |||
626 | if (PWR_LED(ctrl->ctrlcap)) { | ||
627 | p_slot->hpc_ops->green_led_on(p_slot); | 557 | p_slot->hpc_ops->green_led_on(p_slot); |
628 | /* Wait for the command to complete */ | ||
629 | wait_for_ctrl_irq (ctrl); | ||
630 | } | ||
631 | if (ATTN_LED(ctrl->ctrlcap)) { | ||
632 | p_slot->hpc_ops->set_attention_status(p_slot, 0); | ||
633 | 558 | ||
634 | /* Wait for the command to complete */ | 559 | if (ATTN_LED(ctrl->ctrlcap)) |
635 | wait_for_ctrl_irq (ctrl); | 560 | p_slot->hpc_ops->set_attention_status(p_slot, 0); |
636 | } | ||
637 | /* Done with exclusive hardware access */ | ||
638 | mutex_unlock(&ctrl->ctrl_lock); | ||
639 | break; | 561 | break; |
640 | case BLINKINGON_STATE: | 562 | case BLINKINGON_STATE: |
641 | /* Wait for exclusive access to hardware */ | 563 | if (PWR_LED(ctrl->ctrlcap)) |
642 | mutex_lock(&ctrl->ctrl_lock); | ||
643 | |||
644 | if (PWR_LED(ctrl->ctrlcap)) { | ||
645 | p_slot->hpc_ops->green_led_off(p_slot); | 564 | p_slot->hpc_ops->green_led_off(p_slot); |
646 | /* Wait for the command to complete */ | ||
647 | wait_for_ctrl_irq (ctrl); | ||
648 | } | ||
649 | if (ATTN_LED(ctrl->ctrlcap)){ | ||
650 | p_slot->hpc_ops->set_attention_status(p_slot, 0); | ||
651 | /* Wait for the command to complete */ | ||
652 | wait_for_ctrl_irq (ctrl); | ||
653 | } | ||
654 | /* Done with exclusive hardware access */ | ||
655 | mutex_unlock(&ctrl->ctrl_lock); | ||
656 | 565 | ||
566 | if (ATTN_LED(ctrl->ctrlcap)) | ||
567 | p_slot->hpc_ops->set_attention_status(p_slot, 0); | ||
657 | break; | 568 | break; |
658 | default: | 569 | default: |
659 | warn("Not a valid state\n"); | 570 | warn("Not a valid state\n"); |
660 | return; | 571 | return; |
661 | } | 572 | } |
662 | info(msg_button_cancel, slot_name(p_slot)); | 573 | info("PCI slot #%s - action canceled due to button press.\n", slot_name(p_slot)); |
663 | p_slot->state = STATIC_STATE; | 574 | p_slot->state = STATIC_STATE; |
664 | } | 575 | } |
665 | /* ***********Button Pressed (No action on 1st press...) */ | 576 | /* ***********Button Pressed (No action on 1st press...) */ |
@@ -672,34 +583,21 @@ static void interrupt_event_handler(struct controller *ctrl) | |||
672 | /* slot is on */ | 583 | /* slot is on */ |
673 | dbg("slot is on\n"); | 584 | dbg("slot is on\n"); |
674 | p_slot->state = BLINKINGOFF_STATE; | 585 | p_slot->state = BLINKINGOFF_STATE; |
675 | info(msg_button_off, slot_name(p_slot)); | 586 | info("PCI slot #%s - powering off due to button press.\n", slot_name(p_slot)); |
676 | } else { | 587 | } else { |
677 | /* slot is off */ | 588 | /* slot is off */ |
678 | dbg("slot is off\n"); | 589 | dbg("slot is off\n"); |
679 | p_slot->state = BLINKINGON_STATE; | 590 | p_slot->state = BLINKINGON_STATE; |
680 | info(msg_button_on, slot_name(p_slot)); | 591 | info("PCI slot #%s - powering on due to button press.\n", slot_name(p_slot)); |
681 | } | 592 | } |
682 | 593 | ||
683 | /* Wait for exclusive access to hardware */ | ||
684 | mutex_lock(&ctrl->ctrl_lock); | ||
685 | |||
686 | /* blink green LED and turn off amber */ | 594 | /* blink green LED and turn off amber */ |
687 | if (PWR_LED(ctrl->ctrlcap)) { | 595 | if (PWR_LED(ctrl->ctrlcap)) |
688 | p_slot->hpc_ops->green_led_blink(p_slot); | 596 | p_slot->hpc_ops->green_led_blink(p_slot); |
689 | /* Wait for the command to complete */ | ||
690 | wait_for_ctrl_irq (ctrl); | ||
691 | } | ||
692 | 597 | ||
693 | if (ATTN_LED(ctrl->ctrlcap)) { | 598 | if (ATTN_LED(ctrl->ctrlcap)) |
694 | p_slot->hpc_ops->set_attention_status(p_slot, 0); | 599 | p_slot->hpc_ops->set_attention_status(p_slot, 0); |
695 | 600 | ||
696 | /* Wait for the command to complete */ | ||
697 | wait_for_ctrl_irq (ctrl); | ||
698 | } | ||
699 | |||
700 | /* Done with exclusive hardware access */ | ||
701 | mutex_unlock(&ctrl->ctrl_lock); | ||
702 | |||
703 | init_timer(&p_slot->task_event); | 601 | init_timer(&p_slot->task_event); |
704 | p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */ | 602 | p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */ |
705 | p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread; | 603 | p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread; |
@@ -712,21 +610,11 @@ static void interrupt_event_handler(struct controller *ctrl) | |||
712 | else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) { | 610 | else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) { |
713 | if (POWER_CTRL(ctrl->ctrlcap)) { | 611 | if (POWER_CTRL(ctrl->ctrlcap)) { |
714 | dbg("power fault\n"); | 612 | dbg("power fault\n"); |
715 | /* Wait for exclusive access to hardware */ | 613 | if (ATTN_LED(ctrl->ctrlcap)) |
716 | mutex_lock(&ctrl->ctrl_lock); | ||
717 | |||
718 | if (ATTN_LED(ctrl->ctrlcap)) { | ||
719 | p_slot->hpc_ops->set_attention_status(p_slot, 1); | 614 | p_slot->hpc_ops->set_attention_status(p_slot, 1); |
720 | wait_for_ctrl_irq (ctrl); | ||
721 | } | ||
722 | 615 | ||
723 | if (PWR_LED(ctrl->ctrlcap)) { | 616 | if (PWR_LED(ctrl->ctrlcap)) |
724 | p_slot->hpc_ops->green_led_off(p_slot); | 617 | p_slot->hpc_ops->green_led_off(p_slot); |
725 | wait_for_ctrl_irq (ctrl); | ||
726 | } | ||
727 | |||
728 | /* Done with exclusive hardware access */ | ||
729 | mutex_unlock(&ctrl->ctrl_lock); | ||
730 | } | 618 | } |
731 | } | 619 | } |
732 | /***********SURPRISE REMOVAL********************/ | 620 | /***********SURPRISE REMOVAL********************/ |
@@ -754,7 +642,6 @@ static void interrupt_event_handler(struct controller *ctrl) | |||
754 | } | 642 | } |
755 | } | 643 | } |
756 | 644 | ||
757 | |||
758 | int pciehp_enable_slot(struct slot *p_slot) | 645 | int pciehp_enable_slot(struct slot *p_slot) |
759 | { | 646 | { |
760 | u8 getstatus = 0; | 647 | u8 getstatus = 0; |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 25d3aadfddbf..fbc64aa2dd68 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/timer.h> | 35 | #include <linux/timer.h> |
36 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
37 | #include <linux/interrupt.h> | 37 | #include <linux/interrupt.h> |
38 | #include <linux/time.h> | ||
38 | 39 | ||
39 | #include "../pci.h" | 40 | #include "../pci.h" |
40 | #include "pciehp.h" | 41 | #include "pciehp.h" |
@@ -105,34 +106,30 @@ enum ctrl_offsets { | |||
105 | ROOTCTRL = offsetof(struct ctrl_reg, root_ctrl), | 106 | ROOTCTRL = offsetof(struct ctrl_reg, root_ctrl), |
106 | ROOTSTATUS = offsetof(struct ctrl_reg, root_status), | 107 | ROOTSTATUS = offsetof(struct ctrl_reg, root_status), |
107 | }; | 108 | }; |
108 | static int pcie_cap_base = 0; /* Base of the PCI Express capability item structure */ | 109 | |
109 | 110 | static inline int pciehp_readw(struct controller *ctrl, int reg, u16 *value) | |
110 | #define PCIE_CAP_ID(cb) ( cb + PCIECAPID ) | 111 | { |
111 | #define NXT_CAP_PTR(cb) ( cb + NXTCAPPTR ) | 112 | struct pci_dev *dev = ctrl->pci_dev; |
112 | #define CAP_REG(cb) ( cb + CAPREG ) | 113 | return pci_read_config_word(dev, ctrl->cap_base + reg, value); |
113 | #define DEV_CAP(cb) ( cb + DEVCAP ) | 114 | } |
114 | #define DEV_CTRL(cb) ( cb + DEVCTRL ) | 115 | |
115 | #define DEV_STATUS(cb) ( cb + DEVSTATUS ) | 116 | static inline int pciehp_readl(struct controller *ctrl, int reg, u32 *value) |
116 | #define LNK_CAP(cb) ( cb + LNKCAP ) | 117 | { |
117 | #define LNK_CTRL(cb) ( cb + LNKCTRL ) | 118 | struct pci_dev *dev = ctrl->pci_dev; |
118 | #define LNK_STATUS(cb) ( cb + LNKSTATUS ) | 119 | return pci_read_config_dword(dev, ctrl->cap_base + reg, value); |
119 | #define SLOT_CAP(cb) ( cb + SLOTCAP ) | 120 | } |
120 | #define SLOT_CTRL(cb) ( cb + SLOTCTRL ) | 121 | |
121 | #define SLOT_STATUS(cb) ( cb + SLOTSTATUS ) | 122 | static inline int pciehp_writew(struct controller *ctrl, int reg, u16 value) |
122 | #define ROOT_CTRL(cb) ( cb + ROOTCTRL ) | 123 | { |
123 | #define ROOT_STATUS(cb) ( cb + ROOTSTATUS ) | 124 | struct pci_dev *dev = ctrl->pci_dev; |
124 | 125 | return pci_write_config_word(dev, ctrl->cap_base + reg, value); | |
125 | #define hp_register_read_word(pdev, reg , value) \ | 126 | } |
126 | pci_read_config_word(pdev, reg, &value) | 127 | |
127 | 128 | static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value) | |
128 | #define hp_register_read_dword(pdev, reg , value) \ | 129 | { |
129 | pci_read_config_dword(pdev, reg, &value) | 130 | struct pci_dev *dev = ctrl->pci_dev; |
130 | 131 | return pci_write_config_dword(dev, ctrl->cap_base + reg, value); | |
131 | #define hp_register_write_word(pdev, reg , value) \ | 132 | } |
132 | pci_write_config_word(pdev, reg, value) | ||
133 | |||
134 | #define hp_register_dwrite_word(pdev, reg , value) \ | ||
135 | pci_write_config_dword(pdev, reg, value) | ||
136 | 133 | ||
137 | /* Field definitions in PCI Express Capabilities Register */ | 134 | /* Field definitions in PCI Express Capabilities Register */ |
138 | #define CAP_VER 0x000F | 135 | #define CAP_VER 0x000F |
@@ -196,6 +193,7 @@ static int pcie_cap_base = 0; /* Base of the PCI Express capability item struct | |||
196 | #define ATTN_LED_CTRL 0x00C0 | 193 | #define ATTN_LED_CTRL 0x00C0 |
197 | #define PWR_LED_CTRL 0x0300 | 194 | #define PWR_LED_CTRL 0x0300 |
198 | #define PWR_CTRL 0x0400 | 195 | #define PWR_CTRL 0x0400 |
196 | #define EMI_CTRL 0x0800 | ||
199 | 197 | ||
200 | /* Attention indicator and Power indicator states */ | 198 | /* Attention indicator and Power indicator states */ |
201 | #define LED_ON 0x01 | 199 | #define LED_ON 0x01 |
@@ -206,6 +204,10 @@ static int pcie_cap_base = 0; /* Base of the PCI Express capability item struct | |||
206 | #define POWER_ON 0 | 204 | #define POWER_ON 0 |
207 | #define POWER_OFF 0x0400 | 205 | #define POWER_OFF 0x0400 |
208 | 206 | ||
207 | /* EMI Status defines */ | ||
208 | #define EMI_DISENGAGED 0 | ||
209 | #define EMI_ENGAGED 1 | ||
210 | |||
209 | /* Field definitions in Slot Status Register */ | 211 | /* Field definitions in Slot Status Register */ |
210 | #define ATTN_BUTTN_PRESSED 0x0001 | 212 | #define ATTN_BUTTN_PRESSED 0x0001 |
211 | #define PWR_FAULT_DETECTED 0x0002 | 213 | #define PWR_FAULT_DETECTED 0x0002 |
@@ -214,114 +216,117 @@ static int pcie_cap_base = 0; /* Base of the PCI Express capability item struct | |||
214 | #define CMD_COMPLETED 0x0010 | 216 | #define CMD_COMPLETED 0x0010 |
215 | #define MRL_STATE 0x0020 | 217 | #define MRL_STATE 0x0020 |
216 | #define PRSN_STATE 0x0040 | 218 | #define PRSN_STATE 0x0040 |
219 | #define EMI_STATE 0x0080 | ||
220 | #define EMI_STATUS_BIT 7 | ||
217 | 221 | ||
218 | static spinlock_t hpc_event_lock; | 222 | static spinlock_t hpc_event_lock; |
219 | 223 | ||
220 | DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */ | 224 | DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */ |
221 | static struct php_ctlr_state_s *php_ctlr_list_head; /* HPC state linked list */ | ||
222 | static int ctlr_seq_num = 0; /* Controller sequence # */ | 225 | static int ctlr_seq_num = 0; /* Controller sequence # */ |
223 | static spinlock_t list_lock; | ||
224 | |||
225 | static irqreturn_t pcie_isr(int IRQ, void *dev_id); | ||
226 | 226 | ||
227 | static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds); | 227 | static irqreturn_t pcie_isr(int irq, void *dev_id); |
228 | static void start_int_poll_timer(struct controller *ctrl, int sec); | ||
228 | 229 | ||
229 | /* This is the interrupt polling timeout function. */ | 230 | /* This is the interrupt polling timeout function. */ |
230 | static void int_poll_timeout(unsigned long lphp_ctlr) | 231 | static void int_poll_timeout(unsigned long data) |
231 | { | 232 | { |
232 | struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *)lphp_ctlr; | 233 | struct controller *ctrl = (struct controller *)data; |
233 | 234 | ||
234 | DBG_ENTER_ROUTINE | 235 | DBG_ENTER_ROUTINE |
235 | 236 | ||
236 | if ( !php_ctlr ) { | ||
237 | err("%s: Invalid HPC controller handle!\n", __FUNCTION__); | ||
238 | return; | ||
239 | } | ||
240 | |||
241 | /* Poll for interrupt events. regs == NULL => polling */ | 237 | /* Poll for interrupt events. regs == NULL => polling */ |
242 | pcie_isr( 0, (void *)php_ctlr ); | 238 | pcie_isr(0, ctrl); |
243 | |||
244 | init_timer(&php_ctlr->int_poll_timer); | ||
245 | 239 | ||
240 | init_timer(&ctrl->poll_timer); | ||
246 | if (!pciehp_poll_time) | 241 | if (!pciehp_poll_time) |
247 | pciehp_poll_time = 2; /* reset timer to poll in 2 secs if user doesn't specify at module installation*/ | 242 | pciehp_poll_time = 2; /* reset timer to poll in 2 secs if user doesn't specify at module installation*/ |
248 | 243 | ||
249 | start_int_poll_timer(php_ctlr, pciehp_poll_time); | 244 | start_int_poll_timer(ctrl, pciehp_poll_time); |
250 | |||
251 | return; | ||
252 | } | 245 | } |
253 | 246 | ||
254 | /* This function starts the interrupt polling timer. */ | 247 | /* This function starts the interrupt polling timer. */ |
255 | static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds) | 248 | static void start_int_poll_timer(struct controller *ctrl, int sec) |
256 | { | 249 | { |
257 | if (!php_ctlr) { | 250 | /* Clamp to sane value */ |
258 | err("%s: Invalid HPC controller handle!\n", __FUNCTION__); | 251 | if ((sec <= 0) || (sec > 60)) |
259 | return; | 252 | sec = 2; |
260 | } | 253 | |
254 | ctrl->poll_timer.function = &int_poll_timeout; | ||
255 | ctrl->poll_timer.data = (unsigned long)ctrl; | ||
256 | ctrl->poll_timer.expires = jiffies + sec * HZ; | ||
257 | add_timer(&ctrl->poll_timer); | ||
258 | } | ||
261 | 259 | ||
262 | if ( ( seconds <= 0 ) || ( seconds > 60 ) ) | 260 | static inline int pcie_wait_cmd(struct controller *ctrl) |
263 | seconds = 2; /* Clamp to sane value */ | 261 | { |
262 | int retval = 0; | ||
263 | unsigned int msecs = pciehp_poll_mode ? 2500 : 1000; | ||
264 | unsigned long timeout = msecs_to_jiffies(msecs); | ||
265 | int rc; | ||
264 | 266 | ||
265 | php_ctlr->int_poll_timer.function = &int_poll_timeout; | 267 | rc = wait_event_interruptible_timeout(ctrl->queue, |
266 | php_ctlr->int_poll_timer.data = (unsigned long)php_ctlr; /* Instance data */ | 268 | !ctrl->cmd_busy, timeout); |
267 | php_ctlr->int_poll_timer.expires = jiffies + seconds * HZ; | 269 | if (!rc) |
268 | add_timer(&php_ctlr->int_poll_timer); | 270 | dbg("Command not completed in 1000 msec\n"); |
271 | else if (rc < 0) { | ||
272 | retval = -EINTR; | ||
273 | info("Command was interrupted by a signal\n"); | ||
274 | } | ||
269 | 275 | ||
270 | return; | 276 | return retval; |
271 | } | 277 | } |
272 | 278 | ||
273 | static int pcie_write_cmd(struct slot *slot, u16 cmd) | 279 | static int pcie_write_cmd(struct slot *slot, u16 cmd) |
274 | { | 280 | { |
275 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | 281 | struct controller *ctrl = slot->ctrl; |
276 | int retval = 0; | 282 | int retval = 0; |
277 | u16 slot_status; | 283 | u16 slot_status; |
278 | 284 | ||
279 | DBG_ENTER_ROUTINE | 285 | DBG_ENTER_ROUTINE |
280 | |||
281 | if (!php_ctlr) { | ||
282 | err("%s: Invalid HPC controller handle!\n", __FUNCTION__); | ||
283 | return -1; | ||
284 | } | ||
285 | 286 | ||
286 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status); | 287 | mutex_lock(&ctrl->ctrl_lock); |
288 | |||
289 | retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); | ||
287 | if (retval) { | 290 | if (retval) { |
288 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); | 291 | err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); |
289 | return retval; | 292 | goto out; |
290 | } | 293 | } |
291 | 294 | ||
292 | if ((slot_status & CMD_COMPLETED) == CMD_COMPLETED ) { | 295 | if ((slot_status & CMD_COMPLETED) == CMD_COMPLETED ) { |
293 | /* After 1 sec and CMD_COMPLETED still not set, just proceed forward to issue | 296 | /* After 1 sec and CMD_COMPLETED still not set, just |
294 | the next command according to spec. Just print out the error message */ | 297 | proceed forward to issue the next command according |
295 | dbg("%s : CMD_COMPLETED not clear after 1 sec.\n", __FUNCTION__); | 298 | to spec. Just print out the error message */ |
299 | dbg("%s: CMD_COMPLETED not clear after 1 sec.\n", | ||
300 | __FUNCTION__); | ||
296 | } | 301 | } |
297 | 302 | ||
298 | retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), cmd | CMD_CMPL_INTR_ENABLE); | 303 | ctrl->cmd_busy = 1; |
304 | retval = pciehp_writew(ctrl, SLOTCTRL, (cmd | CMD_CMPL_INTR_ENABLE)); | ||
299 | if (retval) { | 305 | if (retval) { |
300 | err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); | 306 | err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__); |
301 | return retval; | 307 | goto out; |
302 | } | 308 | } |
303 | 309 | ||
310 | /* | ||
311 | * Wait for command completion. | ||
312 | */ | ||
313 | retval = pcie_wait_cmd(ctrl); | ||
314 | out: | ||
315 | mutex_unlock(&ctrl->ctrl_lock); | ||
304 | DBG_LEAVE_ROUTINE | 316 | DBG_LEAVE_ROUTINE |
305 | return retval; | 317 | return retval; |
306 | } | 318 | } |
307 | 319 | ||
308 | static int hpc_check_lnk_status(struct controller *ctrl) | 320 | static int hpc_check_lnk_status(struct controller *ctrl) |
309 | { | 321 | { |
310 | struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle; | ||
311 | u16 lnk_status; | 322 | u16 lnk_status; |
312 | int retval = 0; | 323 | int retval = 0; |
313 | 324 | ||
314 | DBG_ENTER_ROUTINE | 325 | DBG_ENTER_ROUTINE |
315 | 326 | ||
316 | if (!php_ctlr) { | 327 | retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status); |
317 | err("%s: Invalid HPC controller handle!\n", __FUNCTION__); | ||
318 | return -1; | ||
319 | } | ||
320 | |||
321 | retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(ctrl->cap_base), lnk_status); | ||
322 | |||
323 | if (retval) { | 328 | if (retval) { |
324 | err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__); | 329 | err("%s: Cannot read LNKSTATUS register\n", __FUNCTION__); |
325 | return retval; | 330 | return retval; |
326 | } | 331 | } |
327 | 332 | ||
@@ -340,26 +345,21 @@ static int hpc_check_lnk_status(struct controller *ctrl) | |||
340 | 345 | ||
341 | static int hpc_get_attention_status(struct slot *slot, u8 *status) | 346 | static int hpc_get_attention_status(struct slot *slot, u8 *status) |
342 | { | 347 | { |
343 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | 348 | struct controller *ctrl = slot->ctrl; |
344 | u16 slot_ctrl; | 349 | u16 slot_ctrl; |
345 | u8 atten_led_state; | 350 | u8 atten_led_state; |
346 | int retval = 0; | 351 | int retval = 0; |
347 | 352 | ||
348 | DBG_ENTER_ROUTINE | 353 | DBG_ENTER_ROUTINE |
349 | 354 | ||
350 | if (!php_ctlr) { | 355 | retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); |
351 | err("%s: Invalid HPC controller handle!\n", __FUNCTION__); | ||
352 | return -1; | ||
353 | } | ||
354 | |||
355 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); | ||
356 | |||
357 | if (retval) { | 356 | if (retval) { |
358 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 357 | err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); |
359 | return retval; | 358 | return retval; |
360 | } | 359 | } |
361 | 360 | ||
362 | dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__,SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); | 361 | dbg("%s: SLOTCTRL %x, value read %x\n", |
362 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_ctrl); | ||
363 | 363 | ||
364 | atten_led_state = (slot_ctrl & ATTN_LED_CTRL) >> 6; | 364 | atten_led_state = (slot_ctrl & ATTN_LED_CTRL) >> 6; |
365 | 365 | ||
@@ -385,27 +385,22 @@ static int hpc_get_attention_status(struct slot *slot, u8 *status) | |||
385 | return 0; | 385 | return 0; |
386 | } | 386 | } |
387 | 387 | ||
388 | static int hpc_get_power_status(struct slot * slot, u8 *status) | 388 | static int hpc_get_power_status(struct slot *slot, u8 *status) |
389 | { | 389 | { |
390 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | 390 | struct controller *ctrl = slot->ctrl; |
391 | u16 slot_ctrl; | 391 | u16 slot_ctrl; |
392 | u8 pwr_state; | 392 | u8 pwr_state; |
393 | int retval = 0; | 393 | int retval = 0; |
394 | 394 | ||
395 | DBG_ENTER_ROUTINE | 395 | DBG_ENTER_ROUTINE |
396 | 396 | ||
397 | if (!php_ctlr) { | 397 | retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); |
398 | err("%s: Invalid HPC controller handle!\n", __FUNCTION__); | ||
399 | return -1; | ||
400 | } | ||
401 | |||
402 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); | ||
403 | |||
404 | if (retval) { | 398 | if (retval) { |
405 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 399 | err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); |
406 | return retval; | 400 | return retval; |
407 | } | 401 | } |
408 | dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); | 402 | dbg("%s: SLOTCTRL %x value read %x\n", |
403 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_ctrl); | ||
409 | 404 | ||
410 | pwr_state = (slot_ctrl & PWR_CTRL) >> 10; | 405 | pwr_state = (slot_ctrl & PWR_CTRL) >> 10; |
411 | 406 | ||
@@ -428,21 +423,15 @@ static int hpc_get_power_status(struct slot * slot, u8 *status) | |||
428 | 423 | ||
429 | static int hpc_get_latch_status(struct slot *slot, u8 *status) | 424 | static int hpc_get_latch_status(struct slot *slot, u8 *status) |
430 | { | 425 | { |
431 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | 426 | struct controller *ctrl = slot->ctrl; |
432 | u16 slot_status; | 427 | u16 slot_status; |
433 | int retval = 0; | 428 | int retval = 0; |
434 | 429 | ||
435 | DBG_ENTER_ROUTINE | 430 | DBG_ENTER_ROUTINE |
436 | 431 | ||
437 | if (!php_ctlr) { | 432 | retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); |
438 | err("%s: Invalid HPC controller handle!\n", __FUNCTION__); | ||
439 | return -1; | ||
440 | } | ||
441 | |||
442 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status); | ||
443 | |||
444 | if (retval) { | 433 | if (retval) { |
445 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); | 434 | err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); |
446 | return retval; | 435 | return retval; |
447 | } | 436 | } |
448 | 437 | ||
@@ -454,22 +443,16 @@ static int hpc_get_latch_status(struct slot *slot, u8 *status) | |||
454 | 443 | ||
455 | static int hpc_get_adapter_status(struct slot *slot, u8 *status) | 444 | static int hpc_get_adapter_status(struct slot *slot, u8 *status) |
456 | { | 445 | { |
457 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | 446 | struct controller *ctrl = slot->ctrl; |
458 | u16 slot_status; | 447 | u16 slot_status; |
459 | u8 card_state; | 448 | u8 card_state; |
460 | int retval = 0; | 449 | int retval = 0; |
461 | 450 | ||
462 | DBG_ENTER_ROUTINE | 451 | DBG_ENTER_ROUTINE |
463 | 452 | ||
464 | if (!php_ctlr) { | 453 | retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); |
465 | err("%s: Invalid HPC controller handle!\n", __FUNCTION__); | ||
466 | return -1; | ||
467 | } | ||
468 | |||
469 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status); | ||
470 | |||
471 | if (retval) { | 454 | if (retval) { |
472 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); | 455 | err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); |
473 | return retval; | 456 | return retval; |
474 | } | 457 | } |
475 | card_state = (u8)((slot_status & PRSN_STATE) >> 6); | 458 | card_state = (u8)((slot_status & PRSN_STATE) >> 6); |
@@ -479,24 +462,18 @@ static int hpc_get_adapter_status(struct slot *slot, u8 *status) | |||
479 | return 0; | 462 | return 0; |
480 | } | 463 | } |
481 | 464 | ||
482 | static int hpc_query_power_fault(struct slot * slot) | 465 | static int hpc_query_power_fault(struct slot *slot) |
483 | { | 466 | { |
484 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | 467 | struct controller *ctrl = slot->ctrl; |
485 | u16 slot_status; | 468 | u16 slot_status; |
486 | u8 pwr_fault; | 469 | u8 pwr_fault; |
487 | int retval = 0; | 470 | int retval = 0; |
488 | 471 | ||
489 | DBG_ENTER_ROUTINE | 472 | DBG_ENTER_ROUTINE |
490 | 473 | ||
491 | if (!php_ctlr) { | 474 | retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); |
492 | err("%s: Invalid HPC controller handle!\n", __FUNCTION__); | ||
493 | return -1; | ||
494 | } | ||
495 | |||
496 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status); | ||
497 | |||
498 | if (retval) { | 475 | if (retval) { |
499 | err("%s : Cannot check for power fault\n", __FUNCTION__); | 476 | err("%s: Cannot check for power fault\n", __FUNCTION__); |
500 | return retval; | 477 | return retval; |
501 | } | 478 | } |
502 | pwr_fault = (u8)((slot_status & PWR_FAULT_DETECTED) >> 1); | 479 | pwr_fault = (u8)((slot_status & PWR_FAULT_DETECTED) >> 1); |
@@ -505,28 +482,63 @@ static int hpc_query_power_fault(struct slot * slot) | |||
505 | return pwr_fault; | 482 | return pwr_fault; |
506 | } | 483 | } |
507 | 484 | ||
508 | static int hpc_set_attention_status(struct slot *slot, u8 value) | 485 | static int hpc_get_emi_status(struct slot *slot, u8 *status) |
509 | { | 486 | { |
510 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | 487 | struct controller *ctrl = slot->ctrl; |
488 | u16 slot_status; | ||
489 | int retval = 0; | ||
490 | |||
491 | DBG_ENTER_ROUTINE | ||
492 | |||
493 | retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); | ||
494 | if (retval) { | ||
495 | err("%s : Cannot check EMI status\n", __FUNCTION__); | ||
496 | return retval; | ||
497 | } | ||
498 | *status = (slot_status & EMI_STATE) >> EMI_STATUS_BIT; | ||
499 | |||
500 | DBG_LEAVE_ROUTINE | ||
501 | return retval; | ||
502 | } | ||
503 | |||
504 | static int hpc_toggle_emi(struct slot *slot) | ||
505 | { | ||
506 | struct controller *ctrl = slot->ctrl; | ||
511 | u16 slot_cmd = 0; | 507 | u16 slot_cmd = 0; |
512 | u16 slot_ctrl; | 508 | u16 slot_ctrl; |
513 | int rc = 0; | 509 | int rc = 0; |
514 | 510 | ||
515 | DBG_ENTER_ROUTINE | 511 | DBG_ENTER_ROUTINE |
516 | 512 | ||
517 | if (!php_ctlr) { | 513 | rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); |
518 | err("%s: Invalid HPC controller handle!\n", __FUNCTION__); | 514 | if (rc) { |
519 | return -1; | 515 | err("%s : hp_register_read_word SLOT_CTRL failed\n", |
516 | __FUNCTION__); | ||
517 | return rc; | ||
520 | } | 518 | } |
521 | 519 | ||
522 | if (slot->hp_slot >= php_ctlr->num_slots) { | 520 | slot_cmd = (slot_ctrl | EMI_CTRL); |
523 | err("%s: Invalid HPC slot number!\n", __FUNCTION__); | 521 | if (!pciehp_poll_mode) |
524 | return -1; | 522 | slot_cmd = slot_cmd | HP_INTR_ENABLE; |
525 | } | ||
526 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); | ||
527 | 523 | ||
524 | pcie_write_cmd(slot, slot_cmd); | ||
525 | slot->last_emi_toggle = get_seconds(); | ||
526 | DBG_LEAVE_ROUTINE | ||
527 | return rc; | ||
528 | } | ||
529 | |||
530 | static int hpc_set_attention_status(struct slot *slot, u8 value) | ||
531 | { | ||
532 | struct controller *ctrl = slot->ctrl; | ||
533 | u16 slot_cmd = 0; | ||
534 | u16 slot_ctrl; | ||
535 | int rc = 0; | ||
536 | |||
537 | DBG_ENTER_ROUTINE | ||
538 | |||
539 | rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); | ||
528 | if (rc) { | 540 | if (rc) { |
529 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 541 | err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); |
530 | return rc; | 542 | return rc; |
531 | } | 543 | } |
532 | 544 | ||
@@ -547,7 +559,8 @@ static int hpc_set_attention_status(struct slot *slot, u8 value) | |||
547 | slot_cmd = slot_cmd | HP_INTR_ENABLE; | 559 | slot_cmd = slot_cmd | HP_INTR_ENABLE; |
548 | 560 | ||
549 | pcie_write_cmd(slot, slot_cmd); | 561 | pcie_write_cmd(slot, slot_cmd); |
550 | dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); | 562 | dbg("%s: SLOTCTRL %x write cmd %x\n", |
563 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); | ||
551 | 564 | ||
552 | DBG_LEAVE_ROUTINE | 565 | DBG_LEAVE_ROUTINE |
553 | return rc; | 566 | return rc; |
@@ -556,27 +569,16 @@ static int hpc_set_attention_status(struct slot *slot, u8 value) | |||
556 | 569 | ||
557 | static void hpc_set_green_led_on(struct slot *slot) | 570 | static void hpc_set_green_led_on(struct slot *slot) |
558 | { | 571 | { |
559 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | 572 | struct controller *ctrl = slot->ctrl; |
560 | u16 slot_cmd; | 573 | u16 slot_cmd; |
561 | u16 slot_ctrl; | 574 | u16 slot_ctrl; |
562 | int rc = 0; | 575 | int rc = 0; |
563 | 576 | ||
564 | DBG_ENTER_ROUTINE | 577 | DBG_ENTER_ROUTINE |
565 | 578 | ||
566 | if (!php_ctlr) { | 579 | rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); |
567 | err("%s: Invalid HPC controller handle!\n", __FUNCTION__); | ||
568 | return ; | ||
569 | } | ||
570 | |||
571 | if (slot->hp_slot >= php_ctlr->num_slots) { | ||
572 | err("%s: Invalid HPC slot number!\n", __FUNCTION__); | ||
573 | return ; | ||
574 | } | ||
575 | |||
576 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); | ||
577 | |||
578 | if (rc) { | 580 | if (rc) { |
579 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 581 | err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); |
580 | return; | 582 | return; |
581 | } | 583 | } |
582 | slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0100; | 584 | slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0100; |
@@ -585,34 +587,24 @@ static void hpc_set_green_led_on(struct slot *slot) | |||
585 | 587 | ||
586 | pcie_write_cmd(slot, slot_cmd); | 588 | pcie_write_cmd(slot, slot_cmd); |
587 | 589 | ||
588 | dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); | 590 | dbg("%s: SLOTCTRL %x write cmd %x\n", |
591 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); | ||
589 | DBG_LEAVE_ROUTINE | 592 | DBG_LEAVE_ROUTINE |
590 | return; | 593 | return; |
591 | } | 594 | } |
592 | 595 | ||
593 | static void hpc_set_green_led_off(struct slot *slot) | 596 | static void hpc_set_green_led_off(struct slot *slot) |
594 | { | 597 | { |
595 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | 598 | struct controller *ctrl = slot->ctrl; |
596 | u16 slot_cmd; | 599 | u16 slot_cmd; |
597 | u16 slot_ctrl; | 600 | u16 slot_ctrl; |
598 | int rc = 0; | 601 | int rc = 0; |
599 | 602 | ||
600 | DBG_ENTER_ROUTINE | 603 | DBG_ENTER_ROUTINE |
601 | 604 | ||
602 | if (!php_ctlr) { | 605 | rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); |
603 | err("%s: Invalid HPC controller handle!\n", __FUNCTION__); | ||
604 | return ; | ||
605 | } | ||
606 | |||
607 | if (slot->hp_slot >= php_ctlr->num_slots) { | ||
608 | err("%s: Invalid HPC slot number!\n", __FUNCTION__); | ||
609 | return ; | ||
610 | } | ||
611 | |||
612 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); | ||
613 | |||
614 | if (rc) { | 606 | if (rc) { |
615 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 607 | err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); |
616 | return; | 608 | return; |
617 | } | 609 | } |
618 | 610 | ||
@@ -621,7 +613,8 @@ static void hpc_set_green_led_off(struct slot *slot) | |||
621 | if (!pciehp_poll_mode) | 613 | if (!pciehp_poll_mode) |
622 | slot_cmd = slot_cmd | HP_INTR_ENABLE; | 614 | slot_cmd = slot_cmd | HP_INTR_ENABLE; |
623 | pcie_write_cmd(slot, slot_cmd); | 615 | pcie_write_cmd(slot, slot_cmd); |
624 | dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); | 616 | dbg("%s: SLOTCTRL %x write cmd %x\n", |
617 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); | ||
625 | 618 | ||
626 | DBG_LEAVE_ROUTINE | 619 | DBG_LEAVE_ROUTINE |
627 | return; | 620 | return; |
@@ -629,27 +622,16 @@ static void hpc_set_green_led_off(struct slot *slot) | |||
629 | 622 | ||
630 | static void hpc_set_green_led_blink(struct slot *slot) | 623 | static void hpc_set_green_led_blink(struct slot *slot) |
631 | { | 624 | { |
632 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | 625 | struct controller *ctrl = slot->ctrl; |
633 | u16 slot_cmd; | 626 | u16 slot_cmd; |
634 | u16 slot_ctrl; | 627 | u16 slot_ctrl; |
635 | int rc = 0; | 628 | int rc = 0; |
636 | 629 | ||
637 | DBG_ENTER_ROUTINE | 630 | DBG_ENTER_ROUTINE |
638 | 631 | ||
639 | if (!php_ctlr) { | 632 | rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); |
640 | err("%s: Invalid HPC controller handle!\n", __FUNCTION__); | ||
641 | return ; | ||
642 | } | ||
643 | |||
644 | if (slot->hp_slot >= php_ctlr->num_slots) { | ||
645 | err("%s: Invalid HPC slot number!\n", __FUNCTION__); | ||
646 | return ; | ||
647 | } | ||
648 | |||
649 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); | ||
650 | |||
651 | if (rc) { | 633 | if (rc) { |
652 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 634 | err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); |
653 | return; | 635 | return; |
654 | } | 636 | } |
655 | 637 | ||
@@ -659,126 +641,54 @@ static void hpc_set_green_led_blink(struct slot *slot) | |||
659 | slot_cmd = slot_cmd | HP_INTR_ENABLE; | 641 | slot_cmd = slot_cmd | HP_INTR_ENABLE; |
660 | pcie_write_cmd(slot, slot_cmd); | 642 | pcie_write_cmd(slot, slot_cmd); |
661 | 643 | ||
662 | dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); | 644 | dbg("%s: SLOTCTRL %x write cmd %x\n", |
645 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); | ||
663 | DBG_LEAVE_ROUTINE | 646 | DBG_LEAVE_ROUTINE |
664 | return; | 647 | return; |
665 | } | 648 | } |
666 | 649 | ||
667 | int pcie_get_ctlr_slot_config(struct controller *ctrl, | ||
668 | int *num_ctlr_slots, /* number of slots in this HPC; only 1 in PCIE */ | ||
669 | int *first_device_num, /* PCI dev num of the first slot in this PCIE */ | ||
670 | int *physical_slot_num, /* phy slot num of the first slot in this PCIE */ | ||
671 | u8 *ctrlcap) | ||
672 | { | ||
673 | struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle; | ||
674 | u32 slot_cap; | ||
675 | int rc = 0; | ||
676 | |||
677 | DBG_ENTER_ROUTINE | ||
678 | |||
679 | if (!php_ctlr) { | ||
680 | err("%s: Invalid HPC controller handle!\n", __FUNCTION__); | ||
681 | return -1; | ||
682 | } | ||
683 | |||
684 | *first_device_num = 0; | ||
685 | *num_ctlr_slots = 1; | ||
686 | |||
687 | rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP(ctrl->cap_base), slot_cap); | ||
688 | |||
689 | if (rc) { | ||
690 | err("%s : hp_register_read_dword SLOT_CAP failed\n", __FUNCTION__); | ||
691 | return -1; | ||
692 | } | ||
693 | |||
694 | *physical_slot_num = slot_cap >> 19; | ||
695 | dbg("%s: PSN %d \n", __FUNCTION__, *physical_slot_num); | ||
696 | |||
697 | *ctrlcap = slot_cap & 0x0000007f; | ||
698 | |||
699 | DBG_LEAVE_ROUTINE | ||
700 | return 0; | ||
701 | } | ||
702 | |||
703 | static void hpc_release_ctlr(struct controller *ctrl) | 650 | static void hpc_release_ctlr(struct controller *ctrl) |
704 | { | 651 | { |
705 | struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle; | ||
706 | struct php_ctlr_state_s *p, *p_prev; | ||
707 | |||
708 | DBG_ENTER_ROUTINE | 652 | DBG_ENTER_ROUTINE |
709 | 653 | ||
710 | if (!php_ctlr) { | 654 | if (pciehp_poll_mode) |
711 | err("%s: Invalid HPC controller handle!\n", __FUNCTION__); | 655 | del_timer(&ctrl->poll_timer); |
712 | return ; | 656 | else |
713 | } | 657 | free_irq(ctrl->pci_dev->irq, ctrl); |
714 | |||
715 | if (pciehp_poll_mode) { | ||
716 | del_timer(&php_ctlr->int_poll_timer); | ||
717 | } else { | ||
718 | if (php_ctlr->irq) { | ||
719 | free_irq(php_ctlr->irq, ctrl); | ||
720 | php_ctlr->irq = 0; | ||
721 | } | ||
722 | } | ||
723 | if (php_ctlr->pci_dev) | ||
724 | php_ctlr->pci_dev = NULL; | ||
725 | |||
726 | spin_lock(&list_lock); | ||
727 | p = php_ctlr_list_head; | ||
728 | p_prev = NULL; | ||
729 | while (p) { | ||
730 | if (p == php_ctlr) { | ||
731 | if (p_prev) | ||
732 | p_prev->pnext = p->pnext; | ||
733 | else | ||
734 | php_ctlr_list_head = p->pnext; | ||
735 | break; | ||
736 | } else { | ||
737 | p_prev = p; | ||
738 | p = p->pnext; | ||
739 | } | ||
740 | } | ||
741 | spin_unlock(&list_lock); | ||
742 | |||
743 | kfree(php_ctlr); | ||
744 | 658 | ||
745 | DBG_LEAVE_ROUTINE | 659 | DBG_LEAVE_ROUTINE |
746 | |||
747 | } | 660 | } |
748 | 661 | ||
749 | static int hpc_power_on_slot(struct slot * slot) | 662 | static int hpc_power_on_slot(struct slot * slot) |
750 | { | 663 | { |
751 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | 664 | struct controller *ctrl = slot->ctrl; |
752 | u16 slot_cmd; | 665 | u16 slot_cmd; |
753 | u16 slot_ctrl, slot_status; | 666 | u16 slot_ctrl, slot_status; |
754 | |||
755 | int retval = 0; | 667 | int retval = 0; |
756 | 668 | ||
757 | DBG_ENTER_ROUTINE | 669 | DBG_ENTER_ROUTINE |
758 | 670 | ||
759 | if (!php_ctlr) { | ||
760 | err("%s: Invalid HPC controller handle!\n", __FUNCTION__); | ||
761 | return -1; | ||
762 | } | ||
763 | |||
764 | dbg("%s: slot->hp_slot %x\n", __FUNCTION__, slot->hp_slot); | 671 | dbg("%s: slot->hp_slot %x\n", __FUNCTION__, slot->hp_slot); |
765 | if (slot->hp_slot >= php_ctlr->num_slots) { | ||
766 | err("%s: Invalid HPC slot number!\n", __FUNCTION__); | ||
767 | return -1; | ||
768 | } | ||
769 | 672 | ||
770 | /* Clear sticky power-fault bit from previous power failures */ | 673 | /* Clear sticky power-fault bit from previous power failures */ |
771 | hp_register_read_word(php_ctlr->pci_dev, | 674 | retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); |
772 | SLOT_STATUS(slot->ctrl->cap_base), slot_status); | 675 | if (retval) { |
676 | err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); | ||
677 | return retval; | ||
678 | } | ||
773 | slot_status &= PWR_FAULT_DETECTED; | 679 | slot_status &= PWR_FAULT_DETECTED; |
774 | if (slot_status) | 680 | if (slot_status) { |
775 | hp_register_write_word(php_ctlr->pci_dev, | 681 | retval = pciehp_writew(ctrl, SLOTSTATUS, slot_status); |
776 | SLOT_STATUS(slot->ctrl->cap_base), slot_status); | 682 | if (retval) { |
777 | 683 | err("%s: Cannot write to SLOTSTATUS register\n", | |
778 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); | 684 | __FUNCTION__); |
685 | return retval; | ||
686 | } | ||
687 | } | ||
779 | 688 | ||
689 | retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); | ||
780 | if (retval) { | 690 | if (retval) { |
781 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 691 | err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); |
782 | return retval; | 692 | return retval; |
783 | } | 693 | } |
784 | 694 | ||
@@ -798,7 +708,8 @@ static int hpc_power_on_slot(struct slot * slot) | |||
798 | err("%s: Write %x command failed!\n", __FUNCTION__, slot_cmd); | 708 | err("%s: Write %x command failed!\n", __FUNCTION__, slot_cmd); |
799 | return -1; | 709 | return -1; |
800 | } | 710 | } |
801 | dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); | 711 | dbg("%s: SLOTCTRL %x write cmd %x\n", |
712 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); | ||
802 | 713 | ||
803 | DBG_LEAVE_ROUTINE | 714 | DBG_LEAVE_ROUTINE |
804 | 715 | ||
@@ -807,29 +718,18 @@ static int hpc_power_on_slot(struct slot * slot) | |||
807 | 718 | ||
808 | static int hpc_power_off_slot(struct slot * slot) | 719 | static int hpc_power_off_slot(struct slot * slot) |
809 | { | 720 | { |
810 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | 721 | struct controller *ctrl = slot->ctrl; |
811 | u16 slot_cmd; | 722 | u16 slot_cmd; |
812 | u16 slot_ctrl; | 723 | u16 slot_ctrl; |
813 | |||
814 | int retval = 0; | 724 | int retval = 0; |
815 | 725 | ||
816 | DBG_ENTER_ROUTINE | 726 | DBG_ENTER_ROUTINE |
817 | 727 | ||
818 | if (!php_ctlr) { | ||
819 | err("%s: Invalid HPC controller handle!\n", __FUNCTION__); | ||
820 | return -1; | ||
821 | } | ||
822 | |||
823 | dbg("%s: slot->hp_slot %x\n", __FUNCTION__, slot->hp_slot); | 728 | dbg("%s: slot->hp_slot %x\n", __FUNCTION__, slot->hp_slot); |
824 | slot->hp_slot = 0; | ||
825 | if (slot->hp_slot >= php_ctlr->num_slots) { | ||
826 | err("%s: Invalid HPC slot number!\n", __FUNCTION__); | ||
827 | return -1; | ||
828 | } | ||
829 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); | ||
830 | 729 | ||
730 | retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); | ||
831 | if (retval) { | 731 | if (retval) { |
832 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 732 | err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); |
833 | return retval; | 733 | return retval; |
834 | } | 734 | } |
835 | 735 | ||
@@ -854,47 +754,25 @@ static int hpc_power_off_slot(struct slot * slot) | |||
854 | err("%s: Write command failed!\n", __FUNCTION__); | 754 | err("%s: Write command failed!\n", __FUNCTION__); |
855 | return -1; | 755 | return -1; |
856 | } | 756 | } |
857 | dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); | 757 | dbg("%s: SLOTCTRL %x write cmd %x\n", |
758 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); | ||
858 | 759 | ||
859 | DBG_LEAVE_ROUTINE | 760 | DBG_LEAVE_ROUTINE |
860 | 761 | ||
861 | return retval; | 762 | return retval; |
862 | } | 763 | } |
863 | 764 | ||
864 | static irqreturn_t pcie_isr(int IRQ, void *dev_id) | 765 | static irqreturn_t pcie_isr(int irq, void *dev_id) |
865 | { | 766 | { |
866 | struct controller *ctrl = NULL; | 767 | struct controller *ctrl = (struct controller *)dev_id; |
867 | struct php_ctlr_state_s *php_ctlr; | ||
868 | u8 schedule_flag = 0; | ||
869 | u16 slot_status, intr_detect, intr_loc; | 768 | u16 slot_status, intr_detect, intr_loc; |
870 | u16 temp_word; | 769 | u16 temp_word; |
871 | int hp_slot = 0; /* only 1 slot per PCI Express port */ | 770 | int hp_slot = 0; /* only 1 slot per PCI Express port */ |
872 | int rc = 0; | 771 | int rc = 0; |
873 | 772 | ||
874 | if (!dev_id) | 773 | rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); |
875 | return IRQ_NONE; | ||
876 | |||
877 | if (!pciehp_poll_mode) { | ||
878 | ctrl = dev_id; | ||
879 | php_ctlr = ctrl->hpc_ctlr_handle; | ||
880 | } else { | ||
881 | php_ctlr = dev_id; | ||
882 | ctrl = (struct controller *)php_ctlr->callback_instance_id; | ||
883 | } | ||
884 | |||
885 | if (!ctrl) { | ||
886 | dbg("%s: dev_id %p ctlr == NULL\n", __FUNCTION__, (void*) dev_id); | ||
887 | return IRQ_NONE; | ||
888 | } | ||
889 | |||
890 | if (!php_ctlr) { | ||
891 | dbg("%s: php_ctlr == NULL\n", __FUNCTION__); | ||
892 | return IRQ_NONE; | ||
893 | } | ||
894 | |||
895 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); | ||
896 | if (rc) { | 774 | if (rc) { |
897 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); | 775 | err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); |
898 | return IRQ_NONE; | 776 | return IRQ_NONE; |
899 | } | 777 | } |
900 | 778 | ||
@@ -910,33 +788,38 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id) | |||
910 | dbg("%s: intr_loc %x\n", __FUNCTION__, intr_loc); | 788 | dbg("%s: intr_loc %x\n", __FUNCTION__, intr_loc); |
911 | /* Mask Hot-plug Interrupt Enable */ | 789 | /* Mask Hot-plug Interrupt Enable */ |
912 | if (!pciehp_poll_mode) { | 790 | if (!pciehp_poll_mode) { |
913 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word); | 791 | rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); |
914 | if (rc) { | 792 | if (rc) { |
915 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 793 | err("%s: Cannot read SLOT_CTRL register\n", |
794 | __FUNCTION__); | ||
916 | return IRQ_NONE; | 795 | return IRQ_NONE; |
917 | } | 796 | } |
918 | 797 | ||
919 | dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); | 798 | dbg("%s: pciehp_readw(SLOTCTRL) with value %x\n", |
799 | __FUNCTION__, temp_word); | ||
920 | temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00; | 800 | temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00; |
921 | 801 | rc = pciehp_writew(ctrl, SLOTCTRL, temp_word); | |
922 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word); | ||
923 | if (rc) { | 802 | if (rc) { |
924 | err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); | 803 | err("%s: Cannot write to SLOTCTRL register\n", |
804 | __FUNCTION__); | ||
925 | return IRQ_NONE; | 805 | return IRQ_NONE; |
926 | } | 806 | } |
927 | 807 | ||
928 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); | 808 | rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); |
929 | if (rc) { | 809 | if (rc) { |
930 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); | 810 | err("%s: Cannot read SLOT_STATUS register\n", |
811 | __FUNCTION__); | ||
931 | return IRQ_NONE; | 812 | return IRQ_NONE; |
932 | } | 813 | } |
933 | dbg("%s: hp_register_read_word SLOT_STATUS with value %x\n", __FUNCTION__, slot_status); | 814 | dbg("%s: pciehp_readw(SLOTSTATUS) with value %x\n", |
815 | __FUNCTION__, slot_status); | ||
934 | 816 | ||
935 | /* Clear command complete interrupt caused by this write */ | 817 | /* Clear command complete interrupt caused by this write */ |
936 | temp_word = 0x1f; | 818 | temp_word = 0x1f; |
937 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); | 819 | rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word); |
938 | if (rc) { | 820 | if (rc) { |
939 | err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); | 821 | err("%s: Cannot write to SLOTSTATUS register\n", |
822 | __FUNCTION__); | ||
940 | return IRQ_NONE; | 823 | return IRQ_NONE; |
941 | } | 824 | } |
942 | } | 825 | } |
@@ -945,60 +828,65 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id) | |||
945 | /* | 828 | /* |
946 | * Command Complete Interrupt Pending | 829 | * Command Complete Interrupt Pending |
947 | */ | 830 | */ |
831 | ctrl->cmd_busy = 0; | ||
948 | wake_up_interruptible(&ctrl->queue); | 832 | wake_up_interruptible(&ctrl->queue); |
949 | } | 833 | } |
950 | 834 | ||
951 | if ((php_ctlr->switch_change_callback) && (intr_loc & MRL_SENS_CHANGED)) | 835 | if (intr_loc & MRL_SENS_CHANGED) |
952 | schedule_flag += php_ctlr->switch_change_callback( | 836 | pciehp_handle_switch_change(hp_slot, ctrl); |
953 | hp_slot, php_ctlr->callback_instance_id); | 837 | |
954 | if ((php_ctlr->attention_button_callback) && (intr_loc & ATTN_BUTTN_PRESSED)) | 838 | if (intr_loc & ATTN_BUTTN_PRESSED) |
955 | schedule_flag += php_ctlr->attention_button_callback( | 839 | pciehp_handle_attention_button(hp_slot, ctrl); |
956 | hp_slot, php_ctlr->callback_instance_id); | 840 | |
957 | if ((php_ctlr->presence_change_callback) && (intr_loc & PRSN_DETECT_CHANGED)) | 841 | if (intr_loc & PRSN_DETECT_CHANGED) |
958 | schedule_flag += php_ctlr->presence_change_callback( | 842 | pciehp_handle_presence_change(hp_slot, ctrl); |
959 | hp_slot , php_ctlr->callback_instance_id); | 843 | |
960 | if ((php_ctlr->power_fault_callback) && (intr_loc & PWR_FAULT_DETECTED)) | 844 | if (intr_loc & PWR_FAULT_DETECTED) |
961 | schedule_flag += php_ctlr->power_fault_callback( | 845 | pciehp_handle_power_fault(hp_slot, ctrl); |
962 | hp_slot, php_ctlr->callback_instance_id); | ||
963 | 846 | ||
964 | /* Clear all events after serving them */ | 847 | /* Clear all events after serving them */ |
965 | temp_word = 0x1F; | 848 | temp_word = 0x1F; |
966 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); | 849 | rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word); |
967 | if (rc) { | 850 | if (rc) { |
968 | err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); | 851 | err("%s: Cannot write to SLOTSTATUS register\n", __FUNCTION__); |
969 | return IRQ_NONE; | 852 | return IRQ_NONE; |
970 | } | 853 | } |
971 | /* Unmask Hot-plug Interrupt Enable */ | 854 | /* Unmask Hot-plug Interrupt Enable */ |
972 | if (!pciehp_poll_mode) { | 855 | if (!pciehp_poll_mode) { |
973 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word); | 856 | rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); |
974 | if (rc) { | 857 | if (rc) { |
975 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 858 | err("%s: Cannot read SLOTCTRL register\n", |
859 | __FUNCTION__); | ||
976 | return IRQ_NONE; | 860 | return IRQ_NONE; |
977 | } | 861 | } |
978 | 862 | ||
979 | dbg("%s: Unmask Hot-plug Interrupt Enable\n", __FUNCTION__); | 863 | dbg("%s: Unmask Hot-plug Interrupt Enable\n", __FUNCTION__); |
980 | temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE; | 864 | temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE; |
981 | 865 | ||
982 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word); | 866 | rc = pciehp_writew(ctrl, SLOTCTRL, temp_word); |
983 | if (rc) { | 867 | if (rc) { |
984 | err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); | 868 | err("%s: Cannot write to SLOTCTRL register\n", |
869 | __FUNCTION__); | ||
985 | return IRQ_NONE; | 870 | return IRQ_NONE; |
986 | } | 871 | } |
987 | 872 | ||
988 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); | 873 | rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); |
989 | if (rc) { | 874 | if (rc) { |
990 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); | 875 | err("%s: Cannot read SLOT_STATUS register\n", |
876 | __FUNCTION__); | ||
991 | return IRQ_NONE; | 877 | return IRQ_NONE; |
992 | } | 878 | } |
993 | 879 | ||
994 | /* Clear command complete interrupt caused by this write */ | 880 | /* Clear command complete interrupt caused by this write */ |
995 | temp_word = 0x1F; | 881 | temp_word = 0x1F; |
996 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); | 882 | rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word); |
997 | if (rc) { | 883 | if (rc) { |
998 | err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); | 884 | err("%s: Cannot write to SLOTSTATUS failed\n", |
885 | __FUNCTION__); | ||
999 | return IRQ_NONE; | 886 | return IRQ_NONE; |
1000 | } | 887 | } |
1001 | dbg("%s: hp_register_write_word SLOT_STATUS with value %x\n", __FUNCTION__, temp_word); | 888 | dbg("%s: pciehp_writew(SLOTSTATUS) with value %x\n", |
889 | __FUNCTION__, temp_word); | ||
1002 | } | 890 | } |
1003 | 891 | ||
1004 | return IRQ_HANDLED; | 892 | return IRQ_HANDLED; |
@@ -1006,27 +894,16 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id) | |||
1006 | 894 | ||
1007 | static int hpc_get_max_lnk_speed (struct slot *slot, enum pci_bus_speed *value) | 895 | static int hpc_get_max_lnk_speed (struct slot *slot, enum pci_bus_speed *value) |
1008 | { | 896 | { |
1009 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | 897 | struct controller *ctrl = slot->ctrl; |
1010 | enum pcie_link_speed lnk_speed; | 898 | enum pcie_link_speed lnk_speed; |
1011 | u32 lnk_cap; | 899 | u32 lnk_cap; |
1012 | int retval = 0; | 900 | int retval = 0; |
1013 | 901 | ||
1014 | DBG_ENTER_ROUTINE | 902 | DBG_ENTER_ROUTINE |
1015 | 903 | ||
1016 | if (!php_ctlr) { | 904 | retval = pciehp_readl(ctrl, LNKCAP, &lnk_cap); |
1017 | err("%s: Invalid HPC controller handle!\n", __FUNCTION__); | ||
1018 | return -1; | ||
1019 | } | ||
1020 | |||
1021 | if (slot->hp_slot >= php_ctlr->num_slots) { | ||
1022 | err("%s: Invalid HPC slot number!\n", __FUNCTION__); | ||
1023 | return -1; | ||
1024 | } | ||
1025 | |||
1026 | retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP(slot->ctrl->cap_base), lnk_cap); | ||
1027 | |||
1028 | if (retval) { | 905 | if (retval) { |
1029 | err("%s : hp_register_read_dword LNK_CAP failed\n", __FUNCTION__); | 906 | err("%s: Cannot read LNKCAP register\n", __FUNCTION__); |
1030 | return retval; | 907 | return retval; |
1031 | } | 908 | } |
1032 | 909 | ||
@@ -1047,27 +924,16 @@ static int hpc_get_max_lnk_speed (struct slot *slot, enum pci_bus_speed *value) | |||
1047 | 924 | ||
1048 | static int hpc_get_max_lnk_width (struct slot *slot, enum pcie_link_width *value) | 925 | static int hpc_get_max_lnk_width (struct slot *slot, enum pcie_link_width *value) |
1049 | { | 926 | { |
1050 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | 927 | struct controller *ctrl = slot->ctrl; |
1051 | enum pcie_link_width lnk_wdth; | 928 | enum pcie_link_width lnk_wdth; |
1052 | u32 lnk_cap; | 929 | u32 lnk_cap; |
1053 | int retval = 0; | 930 | int retval = 0; |
1054 | 931 | ||
1055 | DBG_ENTER_ROUTINE | 932 | DBG_ENTER_ROUTINE |
1056 | 933 | ||
1057 | if (!php_ctlr) { | 934 | retval = pciehp_readl(ctrl, LNKCAP, &lnk_cap); |
1058 | err("%s: Invalid HPC controller handle!\n", __FUNCTION__); | ||
1059 | return -1; | ||
1060 | } | ||
1061 | |||
1062 | if (slot->hp_slot >= php_ctlr->num_slots) { | ||
1063 | err("%s: Invalid HPC slot number!\n", __FUNCTION__); | ||
1064 | return -1; | ||
1065 | } | ||
1066 | |||
1067 | retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP(slot->ctrl->cap_base), lnk_cap); | ||
1068 | |||
1069 | if (retval) { | 935 | if (retval) { |
1070 | err("%s : hp_register_read_dword LNK_CAP failed\n", __FUNCTION__); | 936 | err("%s: Cannot read LNKCAP register\n", __FUNCTION__); |
1071 | return retval; | 937 | return retval; |
1072 | } | 938 | } |
1073 | 939 | ||
@@ -1109,27 +975,16 @@ static int hpc_get_max_lnk_width (struct slot *slot, enum pcie_link_width *value | |||
1109 | 975 | ||
1110 | static int hpc_get_cur_lnk_speed (struct slot *slot, enum pci_bus_speed *value) | 976 | static int hpc_get_cur_lnk_speed (struct slot *slot, enum pci_bus_speed *value) |
1111 | { | 977 | { |
1112 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | 978 | struct controller *ctrl = slot->ctrl; |
1113 | enum pcie_link_speed lnk_speed = PCI_SPEED_UNKNOWN; | 979 | enum pcie_link_speed lnk_speed = PCI_SPEED_UNKNOWN; |
1114 | int retval = 0; | 980 | int retval = 0; |
1115 | u16 lnk_status; | 981 | u16 lnk_status; |
1116 | 982 | ||
1117 | DBG_ENTER_ROUTINE | 983 | DBG_ENTER_ROUTINE |
1118 | 984 | ||
1119 | if (!php_ctlr) { | 985 | retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status); |
1120 | err("%s: Invalid HPC controller handle!\n", __FUNCTION__); | ||
1121 | return -1; | ||
1122 | } | ||
1123 | |||
1124 | if (slot->hp_slot >= php_ctlr->num_slots) { | ||
1125 | err("%s: Invalid HPC slot number!\n", __FUNCTION__); | ||
1126 | return -1; | ||
1127 | } | ||
1128 | |||
1129 | retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(slot->ctrl->cap_base), lnk_status); | ||
1130 | |||
1131 | if (retval) { | 986 | if (retval) { |
1132 | err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__); | 987 | err("%s: Cannot read LNKSTATUS register\n", __FUNCTION__); |
1133 | return retval; | 988 | return retval; |
1134 | } | 989 | } |
1135 | 990 | ||
@@ -1150,27 +1005,16 @@ static int hpc_get_cur_lnk_speed (struct slot *slot, enum pci_bus_speed *value) | |||
1150 | 1005 | ||
1151 | static int hpc_get_cur_lnk_width (struct slot *slot, enum pcie_link_width *value) | 1006 | static int hpc_get_cur_lnk_width (struct slot *slot, enum pcie_link_width *value) |
1152 | { | 1007 | { |
1153 | struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; | 1008 | struct controller *ctrl = slot->ctrl; |
1154 | enum pcie_link_width lnk_wdth = PCIE_LNK_WIDTH_UNKNOWN; | 1009 | enum pcie_link_width lnk_wdth = PCIE_LNK_WIDTH_UNKNOWN; |
1155 | int retval = 0; | 1010 | int retval = 0; |
1156 | u16 lnk_status; | 1011 | u16 lnk_status; |
1157 | 1012 | ||
1158 | DBG_ENTER_ROUTINE | 1013 | DBG_ENTER_ROUTINE |
1159 | 1014 | ||
1160 | if (!php_ctlr) { | 1015 | retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status); |
1161 | err("%s: Invalid HPC controller handle!\n", __FUNCTION__); | ||
1162 | return -1; | ||
1163 | } | ||
1164 | |||
1165 | if (slot->hp_slot >= php_ctlr->num_slots) { | ||
1166 | err("%s: Invalid HPC slot number!\n", __FUNCTION__); | ||
1167 | return -1; | ||
1168 | } | ||
1169 | |||
1170 | retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(slot->ctrl->cap_base), lnk_status); | ||
1171 | |||
1172 | if (retval) { | 1016 | if (retval) { |
1173 | err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__); | 1017 | err("%s: Cannot read LNKSTATUS register\n", __FUNCTION__); |
1174 | return retval; | 1018 | return retval; |
1175 | } | 1019 | } |
1176 | 1020 | ||
@@ -1218,6 +1062,8 @@ static struct hpc_ops pciehp_hpc_ops = { | |||
1218 | .get_attention_status = hpc_get_attention_status, | 1062 | .get_attention_status = hpc_get_attention_status, |
1219 | .get_latch_status = hpc_get_latch_status, | 1063 | .get_latch_status = hpc_get_latch_status, |
1220 | .get_adapter_status = hpc_get_adapter_status, | 1064 | .get_adapter_status = hpc_get_adapter_status, |
1065 | .get_emi_status = hpc_get_emi_status, | ||
1066 | .toggle_emi = hpc_toggle_emi, | ||
1221 | 1067 | ||
1222 | .get_max_bus_speed = hpc_get_max_lnk_speed, | 1068 | .get_max_bus_speed = hpc_get_max_lnk_speed, |
1223 | .get_cur_bus_speed = hpc_get_cur_lnk_speed, | 1069 | .get_cur_bus_speed = hpc_get_cur_lnk_speed, |
@@ -1305,38 +1151,24 @@ int pciehp_acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev) | |||
1305 | 1151 | ||
1306 | int pcie_init(struct controller * ctrl, struct pcie_device *dev) | 1152 | int pcie_init(struct controller * ctrl, struct pcie_device *dev) |
1307 | { | 1153 | { |
1308 | struct php_ctlr_state_s *php_ctlr, *p; | ||
1309 | void *instance_id = ctrl; | ||
1310 | int rc; | 1154 | int rc; |
1311 | static int first = 1; | 1155 | static int first = 1; |
1312 | u16 temp_word; | 1156 | u16 temp_word; |
1313 | u16 cap_reg; | 1157 | u16 cap_reg; |
1314 | u16 intr_enable = 0; | 1158 | u16 intr_enable = 0; |
1315 | u32 slot_cap; | 1159 | u32 slot_cap; |
1316 | int cap_base, saved_cap_base; | 1160 | int cap_base; |
1317 | u16 slot_status, slot_ctrl; | 1161 | u16 slot_status, slot_ctrl; |
1318 | struct pci_dev *pdev; | 1162 | struct pci_dev *pdev; |
1319 | 1163 | ||
1320 | DBG_ENTER_ROUTINE | 1164 | DBG_ENTER_ROUTINE |
1321 | 1165 | ||
1322 | spin_lock_init(&list_lock); | ||
1323 | php_ctlr = kmalloc(sizeof(struct php_ctlr_state_s), GFP_KERNEL); | ||
1324 | |||
1325 | if (!php_ctlr) { /* allocate controller state data */ | ||
1326 | err("%s: HPC controller memory allocation error!\n", __FUNCTION__); | ||
1327 | goto abort; | ||
1328 | } | ||
1329 | |||
1330 | memset(php_ctlr, 0, sizeof(struct php_ctlr_state_s)); | ||
1331 | |||
1332 | pdev = dev->port; | 1166 | pdev = dev->port; |
1333 | php_ctlr->pci_dev = pdev; /* save pci_dev in context */ | 1167 | ctrl->pci_dev = pdev; /* save pci_dev in context */ |
1334 | 1168 | ||
1335 | dbg("%s: hotplug controller vendor id 0x%x device id 0x%x\n", | 1169 | dbg("%s: hotplug controller vendor id 0x%x device id 0x%x\n", |
1336 | __FUNCTION__, pdev->vendor, pdev->device); | 1170 | __FUNCTION__, pdev->vendor, pdev->device); |
1337 | 1171 | ||
1338 | saved_cap_base = pcie_cap_base; | ||
1339 | |||
1340 | if ((cap_base = pci_find_capability(pdev, PCI_CAP_ID_EXP)) == 0) { | 1172 | if ((cap_base = pci_find_capability(pdev, PCI_CAP_ID_EXP)) == 0) { |
1341 | dbg("%s: Can't find PCI_CAP_ID_EXP (0x10)\n", __FUNCTION__); | 1173 | dbg("%s: Can't find PCI_CAP_ID_EXP (0x10)\n", __FUNCTION__); |
1342 | goto abort_free_ctlr; | 1174 | goto abort_free_ctlr; |
@@ -1344,14 +1176,15 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) | |||
1344 | 1176 | ||
1345 | ctrl->cap_base = cap_base; | 1177 | ctrl->cap_base = cap_base; |
1346 | 1178 | ||
1347 | dbg("%s: pcie_cap_base %x\n", __FUNCTION__, pcie_cap_base); | 1179 | dbg("%s: pcie_cap_base %x\n", __FUNCTION__, cap_base); |
1348 | 1180 | ||
1349 | rc = hp_register_read_word(pdev, CAP_REG(ctrl->cap_base), cap_reg); | 1181 | rc = pciehp_readw(ctrl, CAPREG, &cap_reg); |
1350 | if (rc) { | 1182 | if (rc) { |
1351 | err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__); | 1183 | err("%s: Cannot read CAPREG register\n", __FUNCTION__); |
1352 | goto abort_free_ctlr; | 1184 | goto abort_free_ctlr; |
1353 | } | 1185 | } |
1354 | dbg("%s: CAP_REG offset %x cap_reg %x\n", __FUNCTION__, CAP_REG(ctrl->cap_base), cap_reg); | 1186 | dbg("%s: CAPREG offset %x cap_reg %x\n", |
1187 | __FUNCTION__, ctrl->cap_base + CAPREG, cap_reg); | ||
1355 | 1188 | ||
1356 | if (((cap_reg & SLOT_IMPL) == 0) || (((cap_reg & DEV_PORT_TYPE) != 0x0040) | 1189 | if (((cap_reg & SLOT_IMPL) == 0) || (((cap_reg & DEV_PORT_TYPE) != 0x0040) |
1357 | && ((cap_reg & DEV_PORT_TYPE) != 0x0060))) { | 1190 | && ((cap_reg & DEV_PORT_TYPE) != 0x0060))) { |
@@ -1359,31 +1192,34 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) | |||
1359 | goto abort_free_ctlr; | 1192 | goto abort_free_ctlr; |
1360 | } | 1193 | } |
1361 | 1194 | ||
1362 | rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP(ctrl->cap_base), slot_cap); | 1195 | rc = pciehp_readl(ctrl, SLOTCAP, &slot_cap); |
1363 | if (rc) { | 1196 | if (rc) { |
1364 | err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__); | 1197 | err("%s: Cannot read SLOTCAP register\n", __FUNCTION__); |
1365 | goto abort_free_ctlr; | 1198 | goto abort_free_ctlr; |
1366 | } | 1199 | } |
1367 | dbg("%s: SLOT_CAP offset %x slot_cap %x\n", __FUNCTION__, SLOT_CAP(ctrl->cap_base), slot_cap); | 1200 | dbg("%s: SLOTCAP offset %x slot_cap %x\n", |
1201 | __FUNCTION__, ctrl->cap_base + SLOTCAP, slot_cap); | ||
1368 | 1202 | ||
1369 | if (!(slot_cap & HP_CAP)) { | 1203 | if (!(slot_cap & HP_CAP)) { |
1370 | dbg("%s : This slot is not hot-plug capable\n", __FUNCTION__); | 1204 | dbg("%s : This slot is not hot-plug capable\n", __FUNCTION__); |
1371 | goto abort_free_ctlr; | 1205 | goto abort_free_ctlr; |
1372 | } | 1206 | } |
1373 | /* For debugging purpose */ | 1207 | /* For debugging purpose */ |
1374 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); | 1208 | rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); |
1375 | if (rc) { | 1209 | if (rc) { |
1376 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); | 1210 | err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); |
1377 | goto abort_free_ctlr; | 1211 | goto abort_free_ctlr; |
1378 | } | 1212 | } |
1379 | dbg("%s: SLOT_STATUS offset %x slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), slot_status); | 1213 | dbg("%s: SLOTSTATUS offset %x slot_status %x\n", |
1214 | __FUNCTION__, ctrl->cap_base + SLOTSTATUS, slot_status); | ||
1380 | 1215 | ||
1381 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), slot_ctrl); | 1216 | rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); |
1382 | if (rc) { | 1217 | if (rc) { |
1383 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 1218 | err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); |
1384 | goto abort_free_ctlr; | 1219 | goto abort_free_ctlr; |
1385 | } | 1220 | } |
1386 | dbg("%s: SLOT_CTRL offset %x slot_ctrl %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), slot_ctrl); | 1221 | dbg("%s: SLOTCTRL offset %x slot_ctrl %x\n", |
1222 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_ctrl); | ||
1387 | 1223 | ||
1388 | if (first) { | 1224 | if (first) { |
1389 | spin_lock_init(&hpc_event_lock); | 1225 | spin_lock_init(&hpc_event_lock); |
@@ -1405,69 +1241,64 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) | |||
1405 | /* setup wait queue */ | 1241 | /* setup wait queue */ |
1406 | init_waitqueue_head(&ctrl->queue); | 1242 | init_waitqueue_head(&ctrl->queue); |
1407 | 1243 | ||
1408 | /* find the IRQ */ | ||
1409 | php_ctlr->irq = dev->irq; | ||
1410 | |||
1411 | /* Save interrupt callback info */ | ||
1412 | php_ctlr->attention_button_callback = pciehp_handle_attention_button; | ||
1413 | php_ctlr->switch_change_callback = pciehp_handle_switch_change; | ||
1414 | php_ctlr->presence_change_callback = pciehp_handle_presence_change; | ||
1415 | php_ctlr->power_fault_callback = pciehp_handle_power_fault; | ||
1416 | php_ctlr->callback_instance_id = instance_id; | ||
1417 | |||
1418 | /* return PCI Controller Info */ | 1244 | /* return PCI Controller Info */ |
1419 | php_ctlr->slot_device_offset = 0; | 1245 | ctrl->slot_device_offset = 0; |
1420 | php_ctlr->num_slots = 1; | 1246 | ctrl->num_slots = 1; |
1247 | ctrl->first_slot = slot_cap >> 19; | ||
1248 | ctrl->ctrlcap = slot_cap & 0x0000007f; | ||
1421 | 1249 | ||
1422 | /* Mask Hot-plug Interrupt Enable */ | 1250 | /* Mask Hot-plug Interrupt Enable */ |
1423 | rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); | 1251 | rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); |
1424 | if (rc) { | 1252 | if (rc) { |
1425 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 1253 | err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); |
1426 | goto abort_free_ctlr; | 1254 | goto abort_free_ctlr; |
1427 | } | 1255 | } |
1428 | 1256 | ||
1429 | dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), temp_word); | 1257 | dbg("%s: SLOTCTRL %x value read %x\n", |
1258 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, temp_word); | ||
1430 | temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00; | 1259 | temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00; |
1431 | 1260 | ||
1432 | rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); | 1261 | rc = pciehp_writew(ctrl, SLOTCTRL, temp_word); |
1433 | if (rc) { | 1262 | if (rc) { |
1434 | err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); | 1263 | err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__); |
1435 | goto abort_free_ctlr; | 1264 | goto abort_free_ctlr; |
1436 | } | 1265 | } |
1437 | 1266 | ||
1438 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); | 1267 | rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); |
1439 | if (rc) { | 1268 | if (rc) { |
1440 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); | 1269 | err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); |
1441 | goto abort_free_ctlr; | 1270 | goto abort_free_ctlr; |
1442 | } | 1271 | } |
1443 | 1272 | ||
1444 | temp_word = 0x1F; /* Clear all events */ | 1273 | temp_word = 0x1F; /* Clear all events */ |
1445 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); | 1274 | rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word); |
1446 | if (rc) { | 1275 | if (rc) { |
1447 | err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); | 1276 | err("%s: Cannot write to SLOTSTATUS register\n", __FUNCTION__); |
1448 | goto abort_free_ctlr; | 1277 | goto abort_free_ctlr; |
1449 | } | 1278 | } |
1450 | 1279 | ||
1451 | if (pciehp_poll_mode) {/* Install interrupt polling code */ | 1280 | if (pciehp_poll_mode) { |
1452 | /* Install and start the interrupt polling timer */ | 1281 | /* Install interrupt polling timer. Start with 10 sec delay */ |
1453 | init_timer(&php_ctlr->int_poll_timer); | 1282 | init_timer(&ctrl->poll_timer); |
1454 | start_int_poll_timer( php_ctlr, 10 ); /* start with 10 second delay */ | 1283 | start_int_poll_timer(ctrl, 10); |
1455 | } else { | 1284 | } else { |
1456 | /* Installs the interrupt handler */ | 1285 | /* Installs the interrupt handler */ |
1457 | rc = request_irq(php_ctlr->irq, pcie_isr, IRQF_SHARED, MY_NAME, (void *) ctrl); | 1286 | rc = request_irq(ctrl->pci_dev->irq, pcie_isr, IRQF_SHARED, |
1458 | dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc); | 1287 | MY_NAME, (void *)ctrl); |
1288 | dbg("%s: request_irq %d for hpc%d (returns %d)\n", | ||
1289 | __FUNCTION__, ctrl->pci_dev->irq, ctlr_seq_num, rc); | ||
1459 | if (rc) { | 1290 | if (rc) { |
1460 | err("Can't get irq %d for the hotplug controller\n", php_ctlr->irq); | 1291 | err("Can't get irq %d for the hotplug controller\n", |
1292 | ctrl->pci_dev->irq); | ||
1461 | goto abort_free_ctlr; | 1293 | goto abort_free_ctlr; |
1462 | } | 1294 | } |
1463 | } | 1295 | } |
1464 | |||
1465 | dbg("pciehp ctrl b:d:f:irq=0x%x:%x:%x:%x\n", pdev->bus->number, | 1296 | dbg("pciehp ctrl b:d:f:irq=0x%x:%x:%x:%x\n", pdev->bus->number, |
1466 | PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), dev->irq); | 1297 | PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), dev->irq); |
1467 | 1298 | ||
1468 | rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); | 1299 | rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); |
1469 | if (rc) { | 1300 | if (rc) { |
1470 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 1301 | err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); |
1471 | goto abort_free_irq; | 1302 | goto abort_free_irq; |
1472 | } | 1303 | } |
1473 | 1304 | ||
@@ -1491,21 +1322,21 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) | |||
1491 | } | 1322 | } |
1492 | 1323 | ||
1493 | /* Unmask Hot-plug Interrupt Enable for the interrupt notification mechanism case */ | 1324 | /* Unmask Hot-plug Interrupt Enable for the interrupt notification mechanism case */ |
1494 | rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); | 1325 | rc = pciehp_writew(ctrl, SLOTCTRL, temp_word); |
1495 | if (rc) { | 1326 | if (rc) { |
1496 | err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); | 1327 | err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__); |
1497 | goto abort_free_irq; | 1328 | goto abort_free_irq; |
1498 | } | 1329 | } |
1499 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); | 1330 | rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); |
1500 | if (rc) { | 1331 | if (rc) { |
1501 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); | 1332 | err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__); |
1502 | goto abort_disable_intr; | 1333 | goto abort_disable_intr; |
1503 | } | 1334 | } |
1504 | 1335 | ||
1505 | temp_word = 0x1F; /* Clear all events */ | 1336 | temp_word = 0x1F; /* Clear all events */ |
1506 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); | 1337 | rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word); |
1507 | if (rc) { | 1338 | if (rc) { |
1508 | err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); | 1339 | err("%s: Cannot write to SLOTSTATUS register\n", __FUNCTION__); |
1509 | goto abort_disable_intr; | 1340 | goto abort_disable_intr; |
1510 | } | 1341 | } |
1511 | 1342 | ||
@@ -1518,24 +1349,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) | |||
1518 | goto abort_disable_intr; | 1349 | goto abort_disable_intr; |
1519 | } | 1350 | } |
1520 | 1351 | ||
1521 | /* Add this HPC instance into the HPC list */ | ||
1522 | spin_lock(&list_lock); | ||
1523 | if (php_ctlr_list_head == 0) { | ||
1524 | php_ctlr_list_head = php_ctlr; | ||
1525 | p = php_ctlr_list_head; | ||
1526 | p->pnext = NULL; | ||
1527 | } else { | ||
1528 | p = php_ctlr_list_head; | ||
1529 | |||
1530 | while (p->pnext) | ||
1531 | p = p->pnext; | ||
1532 | |||
1533 | p->pnext = php_ctlr; | ||
1534 | } | ||
1535 | spin_unlock(&list_lock); | ||
1536 | |||
1537 | ctlr_seq_num++; | 1352 | ctlr_seq_num++; |
1538 | ctrl->hpc_ctlr_handle = php_ctlr; | ||
1539 | ctrl->hpc_ops = &pciehp_hpc_ops; | 1353 | ctrl->hpc_ops = &pciehp_hpc_ops; |
1540 | 1354 | ||
1541 | DBG_LEAVE_ROUTINE | 1355 | DBG_LEAVE_ROUTINE |
@@ -1543,24 +1357,21 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) | |||
1543 | 1357 | ||
1544 | /* We end up here for the many possible ways to fail this API. */ | 1358 | /* We end up here for the many possible ways to fail this API. */ |
1545 | abort_disable_intr: | 1359 | abort_disable_intr: |
1546 | rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); | 1360 | rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); |
1547 | if (!rc) { | 1361 | if (!rc) { |
1548 | temp_word &= ~(intr_enable | HP_INTR_ENABLE); | 1362 | temp_word &= ~(intr_enable | HP_INTR_ENABLE); |
1549 | rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); | 1363 | rc = pciehp_writew(ctrl, SLOTCTRL, temp_word); |
1550 | } | 1364 | } |
1551 | if (rc) | 1365 | if (rc) |
1552 | err("%s : disabling interrupts failed\n", __FUNCTION__); | 1366 | err("%s : disabling interrupts failed\n", __FUNCTION__); |
1553 | 1367 | ||
1554 | abort_free_irq: | 1368 | abort_free_irq: |
1555 | if (pciehp_poll_mode) | 1369 | if (pciehp_poll_mode) |
1556 | del_timer_sync(&php_ctlr->int_poll_timer); | 1370 | del_timer_sync(&ctrl->poll_timer); |
1557 | else | 1371 | else |
1558 | free_irq(php_ctlr->irq, ctrl); | 1372 | free_irq(ctrl->pci_dev->irq, ctrl); |
1559 | 1373 | ||
1560 | abort_free_ctlr: | 1374 | abort_free_ctlr: |
1561 | pcie_cap_base = saved_cap_base; | ||
1562 | kfree(php_ctlr); | ||
1563 | abort: | ||
1564 | DBG_LEAVE_ROUTINE | 1375 | DBG_LEAVE_ROUTINE |
1565 | return -1; | 1376 | return -1; |
1566 | } | 1377 | } |
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index 3ca6a4f574b3..01d31a1f697c 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h | |||
@@ -106,7 +106,7 @@ struct controller { | |||
106 | }; | 106 | }; |
107 | 107 | ||
108 | /* Define AMD SHPC ID */ | 108 | /* Define AMD SHPC ID */ |
109 | #define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450 | 109 | #define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450 |
110 | #define PCI_DEVICE_ID_AMD_POGO_7458 0x7458 | 110 | #define PCI_DEVICE_ID_AMD_POGO_7458 0x7458 |
111 | 111 | ||
112 | /* AMD PCIX bridge registers */ | 112 | /* AMD PCIX bridge registers */ |
@@ -221,7 +221,7 @@ enum ctrl_offsets { | |||
221 | }; | 221 | }; |
222 | 222 | ||
223 | static inline struct slot *get_slot(struct hotplug_slot *hotplug_slot) | 223 | static inline struct slot *get_slot(struct hotplug_slot *hotplug_slot) |
224 | { | 224 | { |
225 | return hotplug_slot->private; | 225 | return hotplug_slot->private; |
226 | } | 226 | } |
227 | 227 | ||
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index 590cd3cbe010..5f4bc08a633a 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c | |||
@@ -401,10 +401,6 @@ static int __init shpcd_init(void) | |||
401 | { | 401 | { |
402 | int retval = 0; | 402 | int retval = 0; |
403 | 403 | ||
404 | #ifdef CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE | ||
405 | shpchp_poll_mode = 1; | ||
406 | #endif | ||
407 | |||
408 | retval = pci_register_driver(&shpc_driver); | 404 | retval = pci_register_driver(&shpc_driver); |
409 | dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval); | 405 | dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval); |
410 | info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); | 406 | info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); |
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index 6bb84734cd6c..b746bd265bc6 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c | |||
@@ -64,7 +64,7 @@ u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl) | |||
64 | 64 | ||
65 | /* Attention Button Change */ | 65 | /* Attention Button Change */ |
66 | dbg("shpchp: Attention button interrupt received.\n"); | 66 | dbg("shpchp: Attention button interrupt received.\n"); |
67 | 67 | ||
68 | p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); | 68 | p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); |
69 | p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save)); | 69 | p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save)); |
70 | 70 | ||
@@ -128,7 +128,7 @@ u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl) | |||
128 | 128 | ||
129 | p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); | 129 | p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); |
130 | 130 | ||
131 | /* | 131 | /* |
132 | * Save the presence state | 132 | * Save the presence state |
133 | */ | 133 | */ |
134 | p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save)); | 134 | p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save)); |
@@ -184,12 +184,12 @@ u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl) | |||
184 | return 1; | 184 | return 1; |
185 | } | 185 | } |
186 | 186 | ||
187 | /* The following routines constitute the bulk of the | 187 | /* The following routines constitute the bulk of the |
188 | hotplug controller logic | 188 | hotplug controller logic |
189 | */ | 189 | */ |
190 | static int change_bus_speed(struct controller *ctrl, struct slot *p_slot, | 190 | static int change_bus_speed(struct controller *ctrl, struct slot *p_slot, |
191 | enum pci_bus_speed speed) | 191 | enum pci_bus_speed speed) |
192 | { | 192 | { |
193 | int rc = 0; | 193 | int rc = 0; |
194 | 194 | ||
195 | dbg("%s: change to speed %d\n", __FUNCTION__, speed); | 195 | dbg("%s: change to speed %d\n", __FUNCTION__, speed); |
@@ -204,7 +204,7 @@ static int change_bus_speed(struct controller *ctrl, struct slot *p_slot, | |||
204 | static int fix_bus_speed(struct controller *ctrl, struct slot *pslot, | 204 | static int fix_bus_speed(struct controller *ctrl, struct slot *pslot, |
205 | u8 flag, enum pci_bus_speed asp, enum pci_bus_speed bsp, | 205 | u8 flag, enum pci_bus_speed asp, enum pci_bus_speed bsp, |
206 | enum pci_bus_speed msp) | 206 | enum pci_bus_speed msp) |
207 | { | 207 | { |
208 | int rc = 0; | 208 | int rc = 0; |
209 | 209 | ||
210 | /* | 210 | /* |
@@ -257,23 +257,23 @@ static int board_added(struct slot *p_slot) | |||
257 | err("%s: Failed to power on slot\n", __FUNCTION__); | 257 | err("%s: Failed to power on slot\n", __FUNCTION__); |
258 | return -1; | 258 | return -1; |
259 | } | 259 | } |
260 | 260 | ||
261 | if ((ctrl->pci_dev->vendor == 0x8086) && (ctrl->pci_dev->device == 0x0332)) { | 261 | if ((ctrl->pci_dev->vendor == 0x8086) && (ctrl->pci_dev->device == 0x0332)) { |
262 | if (slots_not_empty) | 262 | if (slots_not_empty) |
263 | return WRONG_BUS_FREQUENCY; | 263 | return WRONG_BUS_FREQUENCY; |
264 | 264 | ||
265 | if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, PCI_SPEED_33MHz))) { | 265 | if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, PCI_SPEED_33MHz))) { |
266 | err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__); | 266 | err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__); |
267 | return WRONG_BUS_FREQUENCY; | 267 | return WRONG_BUS_FREQUENCY; |
268 | } | 268 | } |
269 | 269 | ||
270 | /* turn on board, blink green LED, turn off Amber LED */ | 270 | /* turn on board, blink green LED, turn off Amber LED */ |
271 | if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) { | 271 | if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) { |
272 | err("%s: Issue of Slot Enable command failed\n", __FUNCTION__); | 272 | err("%s: Issue of Slot Enable command failed\n", __FUNCTION__); |
273 | return rc; | 273 | return rc; |
274 | } | 274 | } |
275 | } | 275 | } |
276 | 276 | ||
277 | rc = p_slot->hpc_ops->get_adapter_speed(p_slot, &asp); | 277 | rc = p_slot->hpc_ops->get_adapter_speed(p_slot, &asp); |
278 | if (rc) { | 278 | if (rc) { |
279 | err("%s: Can't get adapter speed or bus mode mismatch\n", | 279 | err("%s: Can't get adapter speed or bus mode mismatch\n", |
@@ -378,7 +378,7 @@ static int remove_board(struct slot *p_slot) | |||
378 | err("%s: Issue of Slot Disable command failed\n", __FUNCTION__); | 378 | err("%s: Issue of Slot Disable command failed\n", __FUNCTION__); |
379 | return rc; | 379 | return rc; |
380 | } | 380 | } |
381 | 381 | ||
382 | rc = p_slot->hpc_ops->set_attention_status(p_slot, 0); | 382 | rc = p_slot->hpc_ops->set_attention_status(p_slot, 0); |
383 | if (rc) { | 383 | if (rc) { |
384 | err("%s: Issue of Set Attention command failed\n", __FUNCTION__); | 384 | err("%s: Issue of Set Attention command failed\n", __FUNCTION__); |
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index b7bede4b7c27..5183a45d45b5 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c | |||
@@ -35,38 +35,6 @@ | |||
35 | 35 | ||
36 | #include "shpchp.h" | 36 | #include "shpchp.h" |
37 | 37 | ||
38 | #ifdef DEBUG | ||
39 | #define DBG_K_TRACE_ENTRY ((unsigned int)0x00000001) /* On function entry */ | ||
40 | #define DBG_K_TRACE_EXIT ((unsigned int)0x00000002) /* On function exit */ | ||
41 | #define DBG_K_INFO ((unsigned int)0x00000004) /* Info messages */ | ||
42 | #define DBG_K_ERROR ((unsigned int)0x00000008) /* Error messages */ | ||
43 | #define DBG_K_TRACE (DBG_K_TRACE_ENTRY|DBG_K_TRACE_EXIT) | ||
44 | #define DBG_K_STANDARD (DBG_K_INFO|DBG_K_ERROR|DBG_K_TRACE) | ||
45 | /* Redefine this flagword to set debug level */ | ||
46 | #define DEBUG_LEVEL DBG_K_STANDARD | ||
47 | |||
48 | #define DEFINE_DBG_BUFFER char __dbg_str_buf[256]; | ||
49 | |||
50 | #define DBG_PRINT( dbg_flags, args... ) \ | ||
51 | do { \ | ||
52 | if ( DEBUG_LEVEL & ( dbg_flags ) ) \ | ||
53 | { \ | ||
54 | int len; \ | ||
55 | len = sprintf( __dbg_str_buf, "%s:%d: %s: ", \ | ||
56 | __FILE__, __LINE__, __FUNCTION__ ); \ | ||
57 | sprintf( __dbg_str_buf + len, args ); \ | ||
58 | printk( KERN_NOTICE "%s\n", __dbg_str_buf ); \ | ||
59 | } \ | ||
60 | } while (0) | ||
61 | |||
62 | #define DBG_ENTER_ROUTINE DBG_PRINT (DBG_K_TRACE_ENTRY, "%s", "[Entry]"); | ||
63 | #define DBG_LEAVE_ROUTINE DBG_PRINT (DBG_K_TRACE_EXIT, "%s", "[Exit]"); | ||
64 | #else | ||
65 | #define DEFINE_DBG_BUFFER | ||
66 | #define DBG_ENTER_ROUTINE | ||
67 | #define DBG_LEAVE_ROUTINE | ||
68 | #endif /* DEBUG */ | ||
69 | |||
70 | /* Slot Available Register I field definition */ | 38 | /* Slot Available Register I field definition */ |
71 | #define SLOT_33MHZ 0x0000001f | 39 | #define SLOT_33MHZ 0x0000001f |
72 | #define SLOT_66MHZ_PCIX 0x00001f00 | 40 | #define SLOT_66MHZ_PCIX 0x00001f00 |
@@ -211,7 +179,6 @@ | |||
211 | #define SLOT_EVENT_LATCH 0x2 | 179 | #define SLOT_EVENT_LATCH 0x2 |
212 | #define SLOT_SERR_INT_MASK 0x3 | 180 | #define SLOT_SERR_INT_MASK 0x3 |
213 | 181 | ||
214 | DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */ | ||
215 | static atomic_t shpchp_num_controllers = ATOMIC_INIT(0); | 182 | static atomic_t shpchp_num_controllers = ATOMIC_INIT(0); |
216 | 183 | ||
217 | static irqreturn_t shpc_isr(int irq, void *dev_id); | 184 | static irqreturn_t shpc_isr(int irq, void *dev_id); |
@@ -268,8 +235,6 @@ static void int_poll_timeout(unsigned long data) | |||
268 | { | 235 | { |
269 | struct controller *ctrl = (struct controller *)data; | 236 | struct controller *ctrl = (struct controller *)data; |
270 | 237 | ||
271 | DBG_ENTER_ROUTINE | ||
272 | |||
273 | /* Poll for interrupt events. regs == NULL => polling */ | 238 | /* Poll for interrupt events. regs == NULL => polling */ |
274 | shpc_isr(0, ctrl); | 239 | shpc_isr(0, ctrl); |
275 | 240 | ||
@@ -278,8 +243,6 @@ static void int_poll_timeout(unsigned long data) | |||
278 | shpchp_poll_time = 2; /* default polling interval is 2 sec */ | 243 | shpchp_poll_time = 2; /* default polling interval is 2 sec */ |
279 | 244 | ||
280 | start_int_poll_timer(ctrl, shpchp_poll_time); | 245 | start_int_poll_timer(ctrl, shpchp_poll_time); |
281 | |||
282 | DBG_LEAVE_ROUTINE | ||
283 | } | 246 | } |
284 | 247 | ||
285 | /* | 248 | /* |
@@ -353,8 +316,6 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) | |||
353 | int retval = 0; | 316 | int retval = 0; |
354 | u16 temp_word; | 317 | u16 temp_word; |
355 | 318 | ||
356 | DBG_ENTER_ROUTINE | ||
357 | |||
358 | mutex_lock(&slot->ctrl->cmd_lock); | 319 | mutex_lock(&slot->ctrl->cmd_lock); |
359 | 320 | ||
360 | if (!shpc_poll_ctrl_busy(ctrl)) { | 321 | if (!shpc_poll_ctrl_busy(ctrl)) { |
@@ -368,9 +329,9 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) | |||
368 | ++t_slot; | 329 | ++t_slot; |
369 | temp_word = (t_slot << 8) | (cmd & 0xFF); | 330 | temp_word = (t_slot << 8) | (cmd & 0xFF); |
370 | dbg("%s: t_slot %x cmd %x\n", __FUNCTION__, t_slot, cmd); | 331 | dbg("%s: t_slot %x cmd %x\n", __FUNCTION__, t_slot, cmd); |
371 | 332 | ||
372 | /* To make sure the Controller Busy bit is 0 before we send out the | 333 | /* To make sure the Controller Busy bit is 0 before we send out the |
373 | * command. | 334 | * command. |
374 | */ | 335 | */ |
375 | shpc_writew(ctrl, CMD, temp_word); | 336 | shpc_writew(ctrl, CMD, temp_word); |
376 | 337 | ||
@@ -389,20 +350,14 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) | |||
389 | } | 350 | } |
390 | out: | 351 | out: |
391 | mutex_unlock(&slot->ctrl->cmd_lock); | 352 | mutex_unlock(&slot->ctrl->cmd_lock); |
392 | |||
393 | DBG_LEAVE_ROUTINE | ||
394 | return retval; | 353 | return retval; |
395 | } | 354 | } |
396 | 355 | ||
397 | static int hpc_check_cmd_status(struct controller *ctrl) | 356 | static int hpc_check_cmd_status(struct controller *ctrl) |
398 | { | 357 | { |
399 | u16 cmd_status; | ||
400 | int retval = 0; | 358 | int retval = 0; |
359 | u16 cmd_status = shpc_readw(ctrl, CMD_STATUS) & 0x000F; | ||
401 | 360 | ||
402 | DBG_ENTER_ROUTINE | ||
403 | |||
404 | cmd_status = shpc_readw(ctrl, CMD_STATUS) & 0x000F; | ||
405 | |||
406 | switch (cmd_status >> 1) { | 361 | switch (cmd_status >> 1) { |
407 | case 0: | 362 | case 0: |
408 | retval = 0; | 363 | retval = 0; |
@@ -423,7 +378,6 @@ static int hpc_check_cmd_status(struct controller *ctrl) | |||
423 | retval = cmd_status; | 378 | retval = cmd_status; |
424 | } | 379 | } |
425 | 380 | ||
426 | DBG_LEAVE_ROUTINE | ||
427 | return retval; | 381 | return retval; |
428 | } | 382 | } |
429 | 383 | ||
@@ -431,13 +385,8 @@ static int hpc_check_cmd_status(struct controller *ctrl) | |||
431 | static int hpc_get_attention_status(struct slot *slot, u8 *status) | 385 | static int hpc_get_attention_status(struct slot *slot, u8 *status) |
432 | { | 386 | { |
433 | struct controller *ctrl = slot->ctrl; | 387 | struct controller *ctrl = slot->ctrl; |
434 | u32 slot_reg; | 388 | u32 slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); |
435 | u8 state; | 389 | u8 state = (slot_reg & ATN_LED_STATE_MASK) >> ATN_LED_STATE_SHIFT; |
436 | |||
437 | DBG_ENTER_ROUTINE | ||
438 | |||
439 | slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); | ||
440 | state = (slot_reg & ATN_LED_STATE_MASK) >> ATN_LED_STATE_SHIFT; | ||
441 | 390 | ||
442 | switch (state) { | 391 | switch (state) { |
443 | case ATN_LED_STATE_ON: | 392 | case ATN_LED_STATE_ON: |
@@ -454,20 +403,14 @@ static int hpc_get_attention_status(struct slot *slot, u8 *status) | |||
454 | break; | 403 | break; |
455 | } | 404 | } |
456 | 405 | ||
457 | DBG_LEAVE_ROUTINE | ||
458 | return 0; | 406 | return 0; |
459 | } | 407 | } |
460 | 408 | ||
461 | static int hpc_get_power_status(struct slot * slot, u8 *status) | 409 | static int hpc_get_power_status(struct slot * slot, u8 *status) |
462 | { | 410 | { |
463 | struct controller *ctrl = slot->ctrl; | 411 | struct controller *ctrl = slot->ctrl; |
464 | u32 slot_reg; | 412 | u32 slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); |
465 | u8 state; | 413 | u8 state = (slot_reg & SLOT_STATE_MASK) >> SLOT_STATE_SHIFT; |
466 | |||
467 | DBG_ENTER_ROUTINE | ||
468 | |||
469 | slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); | ||
470 | state = (slot_reg & SLOT_STATE_MASK) >> SLOT_STATE_SHIFT; | ||
471 | 414 | ||
472 | switch (state) { | 415 | switch (state) { |
473 | case SLOT_STATE_PWRONLY: | 416 | case SLOT_STATE_PWRONLY: |
@@ -484,7 +427,6 @@ static int hpc_get_power_status(struct slot * slot, u8 *status) | |||
484 | break; | 427 | break; |
485 | } | 428 | } |
486 | 429 | ||
487 | DBG_LEAVE_ROUTINE | ||
488 | return 0; | 430 | return 0; |
489 | } | 431 | } |
490 | 432 | ||
@@ -492,30 +434,21 @@ static int hpc_get_power_status(struct slot * slot, u8 *status) | |||
492 | static int hpc_get_latch_status(struct slot *slot, u8 *status) | 434 | static int hpc_get_latch_status(struct slot *slot, u8 *status) |
493 | { | 435 | { |
494 | struct controller *ctrl = slot->ctrl; | 436 | struct controller *ctrl = slot->ctrl; |
495 | u32 slot_reg; | 437 | u32 slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); |
496 | |||
497 | DBG_ENTER_ROUTINE | ||
498 | 438 | ||
499 | slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); | ||
500 | *status = !!(slot_reg & MRL_SENSOR); /* 0 -> close; 1 -> open */ | 439 | *status = !!(slot_reg & MRL_SENSOR); /* 0 -> close; 1 -> open */ |
501 | 440 | ||
502 | DBG_LEAVE_ROUTINE | ||
503 | return 0; | 441 | return 0; |
504 | } | 442 | } |
505 | 443 | ||
506 | static int hpc_get_adapter_status(struct slot *slot, u8 *status) | 444 | static int hpc_get_adapter_status(struct slot *slot, u8 *status) |
507 | { | 445 | { |
508 | struct controller *ctrl = slot->ctrl; | 446 | struct controller *ctrl = slot->ctrl; |
509 | u32 slot_reg; | 447 | u32 slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); |
510 | u8 state; | 448 | u8 state = (slot_reg & PRSNT_MASK) >> PRSNT_SHIFT; |
511 | |||
512 | DBG_ENTER_ROUTINE | ||
513 | 449 | ||
514 | slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); | ||
515 | state = (slot_reg & PRSNT_MASK) >> PRSNT_SHIFT; | ||
516 | *status = (state != 0x3) ? 1 : 0; | 450 | *status = (state != 0x3) ? 1 : 0; |
517 | 451 | ||
518 | DBG_LEAVE_ROUTINE | ||
519 | return 0; | 452 | return 0; |
520 | } | 453 | } |
521 | 454 | ||
@@ -523,11 +456,8 @@ static int hpc_get_prog_int(struct slot *slot, u8 *prog_int) | |||
523 | { | 456 | { |
524 | struct controller *ctrl = slot->ctrl; | 457 | struct controller *ctrl = slot->ctrl; |
525 | 458 | ||
526 | DBG_ENTER_ROUTINE | ||
527 | |||
528 | *prog_int = shpc_readb(ctrl, PROG_INTERFACE); | 459 | *prog_int = shpc_readb(ctrl, PROG_INTERFACE); |
529 | 460 | ||
530 | DBG_LEAVE_ROUTINE | ||
531 | return 0; | 461 | return 0; |
532 | } | 462 | } |
533 | 463 | ||
@@ -539,8 +469,6 @@ static int hpc_get_adapter_speed(struct slot *slot, enum pci_bus_speed *value) | |||
539 | u8 m66_cap = !!(slot_reg & MHZ66_CAP); | 469 | u8 m66_cap = !!(slot_reg & MHZ66_CAP); |
540 | u8 pi, pcix_cap; | 470 | u8 pi, pcix_cap; |
541 | 471 | ||
542 | DBG_ENTER_ROUTINE | ||
543 | |||
544 | if ((retval = hpc_get_prog_int(slot, &pi))) | 472 | if ((retval = hpc_get_prog_int(slot, &pi))) |
545 | return retval; | 473 | return retval; |
546 | 474 | ||
@@ -582,21 +510,15 @@ static int hpc_get_adapter_speed(struct slot *slot, enum pci_bus_speed *value) | |||
582 | } | 510 | } |
583 | 511 | ||
584 | dbg("Adapter speed = %d\n", *value); | 512 | dbg("Adapter speed = %d\n", *value); |
585 | DBG_LEAVE_ROUTINE | ||
586 | return retval; | 513 | return retval; |
587 | } | 514 | } |
588 | 515 | ||
589 | static int hpc_get_mode1_ECC_cap(struct slot *slot, u8 *mode) | 516 | static int hpc_get_mode1_ECC_cap(struct slot *slot, u8 *mode) |
590 | { | 517 | { |
591 | struct controller *ctrl = slot->ctrl; | ||
592 | u16 sec_bus_status; | ||
593 | u8 pi; | ||
594 | int retval = 0; | 518 | int retval = 0; |
595 | 519 | struct controller *ctrl = slot->ctrl; | |
596 | DBG_ENTER_ROUTINE | 520 | u16 sec_bus_status = shpc_readw(ctrl, SEC_BUS_CONFIG); |
597 | 521 | u8 pi = shpc_readb(ctrl, PROG_INTERFACE); | |
598 | pi = shpc_readb(ctrl, PROG_INTERFACE); | ||
599 | sec_bus_status = shpc_readw(ctrl, SEC_BUS_CONFIG); | ||
600 | 522 | ||
601 | if (pi == 2) { | 523 | if (pi == 2) { |
602 | *mode = (sec_bus_status & 0x0100) >> 8; | 524 | *mode = (sec_bus_status & 0x0100) >> 8; |
@@ -605,21 +527,14 @@ static int hpc_get_mode1_ECC_cap(struct slot *slot, u8 *mode) | |||
605 | } | 527 | } |
606 | 528 | ||
607 | dbg("Mode 1 ECC cap = %d\n", *mode); | 529 | dbg("Mode 1 ECC cap = %d\n", *mode); |
608 | |||
609 | DBG_LEAVE_ROUTINE | ||
610 | return retval; | 530 | return retval; |
611 | } | 531 | } |
612 | 532 | ||
613 | static int hpc_query_power_fault(struct slot * slot) | 533 | static int hpc_query_power_fault(struct slot * slot) |
614 | { | 534 | { |
615 | struct controller *ctrl = slot->ctrl; | 535 | struct controller *ctrl = slot->ctrl; |
616 | u32 slot_reg; | 536 | u32 slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); |
617 | |||
618 | DBG_ENTER_ROUTINE | ||
619 | |||
620 | slot_reg = shpc_readl(ctrl, SLOT_REG(slot->hp_slot)); | ||
621 | 537 | ||
622 | DBG_LEAVE_ROUTINE | ||
623 | /* Note: Logic 0 => fault */ | 538 | /* Note: Logic 0 => fault */ |
624 | return !(slot_reg & POWER_FAULT); | 539 | return !(slot_reg & POWER_FAULT); |
625 | } | 540 | } |
@@ -629,7 +544,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value) | |||
629 | u8 slot_cmd = 0; | 544 | u8 slot_cmd = 0; |
630 | 545 | ||
631 | switch (value) { | 546 | switch (value) { |
632 | case 0 : | 547 | case 0 : |
633 | slot_cmd = SET_ATTN_OFF; /* OFF */ | 548 | slot_cmd = SET_ATTN_OFF; /* OFF */ |
634 | break; | 549 | break; |
635 | case 1: | 550 | case 1: |
@@ -666,8 +581,6 @@ static void hpc_release_ctlr(struct controller *ctrl) | |||
666 | int i; | 581 | int i; |
667 | u32 slot_reg, serr_int; | 582 | u32 slot_reg, serr_int; |
668 | 583 | ||
669 | DBG_ENTER_ROUTINE | ||
670 | |||
671 | /* | 584 | /* |
672 | * Mask event interrupts and SERRs of all slots | 585 | * Mask event interrupts and SERRs of all slots |
673 | */ | 586 | */ |
@@ -708,61 +621,43 @@ static void hpc_release_ctlr(struct controller *ctrl) | |||
708 | */ | 621 | */ |
709 | if (atomic_dec_and_test(&shpchp_num_controllers)) | 622 | if (atomic_dec_and_test(&shpchp_num_controllers)) |
710 | destroy_workqueue(shpchp_wq); | 623 | destroy_workqueue(shpchp_wq); |
711 | |||
712 | DBG_LEAVE_ROUTINE | ||
713 | } | 624 | } |
714 | 625 | ||
715 | static int hpc_power_on_slot(struct slot * slot) | 626 | static int hpc_power_on_slot(struct slot * slot) |
716 | { | 627 | { |
717 | int retval; | 628 | int retval; |
718 | 629 | ||
719 | DBG_ENTER_ROUTINE | ||
720 | |||
721 | retval = shpc_write_cmd(slot, slot->hp_slot, SET_SLOT_PWR); | 630 | retval = shpc_write_cmd(slot, slot->hp_slot, SET_SLOT_PWR); |
722 | if (retval) { | 631 | if (retval) |
723 | err("%s: Write command failed!\n", __FUNCTION__); | 632 | err("%s: Write command failed!\n", __FUNCTION__); |
724 | return retval; | ||
725 | } | ||
726 | |||
727 | DBG_LEAVE_ROUTINE | ||
728 | 633 | ||
729 | return 0; | 634 | return retval; |
730 | } | 635 | } |
731 | 636 | ||
732 | static int hpc_slot_enable(struct slot * slot) | 637 | static int hpc_slot_enable(struct slot * slot) |
733 | { | 638 | { |
734 | int retval; | 639 | int retval; |
735 | 640 | ||
736 | DBG_ENTER_ROUTINE | ||
737 | |||
738 | /* Slot - Enable, Power Indicator - Blink, Attention Indicator - Off */ | 641 | /* Slot - Enable, Power Indicator - Blink, Attention Indicator - Off */ |
739 | retval = shpc_write_cmd(slot, slot->hp_slot, | 642 | retval = shpc_write_cmd(slot, slot->hp_slot, |
740 | SET_SLOT_ENABLE | SET_PWR_BLINK | SET_ATTN_OFF); | 643 | SET_SLOT_ENABLE | SET_PWR_BLINK | SET_ATTN_OFF); |
741 | if (retval) { | 644 | if (retval) |
742 | err("%s: Write command failed!\n", __FUNCTION__); | 645 | err("%s: Write command failed!\n", __FUNCTION__); |
743 | return retval; | ||
744 | } | ||
745 | 646 | ||
746 | DBG_LEAVE_ROUTINE | 647 | return retval; |
747 | return 0; | ||
748 | } | 648 | } |
749 | 649 | ||
750 | static int hpc_slot_disable(struct slot * slot) | 650 | static int hpc_slot_disable(struct slot * slot) |
751 | { | 651 | { |
752 | int retval; | 652 | int retval; |
753 | 653 | ||
754 | DBG_ENTER_ROUTINE | ||
755 | |||
756 | /* Slot - Disable, Power Indicator - Off, Attention Indicator - On */ | 654 | /* Slot - Disable, Power Indicator - Off, Attention Indicator - On */ |
757 | retval = shpc_write_cmd(slot, slot->hp_slot, | 655 | retval = shpc_write_cmd(slot, slot->hp_slot, |
758 | SET_SLOT_DISABLE | SET_PWR_OFF | SET_ATTN_ON); | 656 | SET_SLOT_DISABLE | SET_PWR_OFF | SET_ATTN_ON); |
759 | if (retval) { | 657 | if (retval) |
760 | err("%s: Write command failed!\n", __FUNCTION__); | 658 | err("%s: Write command failed!\n", __FUNCTION__); |
761 | return retval; | ||
762 | } | ||
763 | 659 | ||
764 | DBG_LEAVE_ROUTINE | 660 | return retval; |
765 | return 0; | ||
766 | } | 661 | } |
767 | 662 | ||
768 | static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) | 663 | static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) |
@@ -771,8 +666,6 @@ static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) | |||
771 | struct controller *ctrl = slot->ctrl; | 666 | struct controller *ctrl = slot->ctrl; |
772 | u8 pi, cmd; | 667 | u8 pi, cmd; |
773 | 668 | ||
774 | DBG_ENTER_ROUTINE | ||
775 | |||
776 | pi = shpc_readb(ctrl, PROG_INTERFACE); | 669 | pi = shpc_readb(ctrl, PROG_INTERFACE); |
777 | if ((pi == 1) && (value > PCI_SPEED_133MHz_PCIX)) | 670 | if ((pi == 1) && (value > PCI_SPEED_133MHz_PCIX)) |
778 | return -EINVAL; | 671 | return -EINVAL; |
@@ -828,7 +721,6 @@ static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) | |||
828 | if (retval) | 721 | if (retval) |
829 | err("%s: Write command failed!\n", __FUNCTION__); | 722 | err("%s: Write command failed!\n", __FUNCTION__); |
830 | 723 | ||
831 | DBG_LEAVE_ROUTINE | ||
832 | return retval; | 724 | return retval; |
833 | } | 725 | } |
834 | 726 | ||
@@ -843,7 +735,7 @@ static irqreturn_t shpc_isr(int irq, void *dev_id) | |||
843 | if (!intr_loc) | 735 | if (!intr_loc) |
844 | return IRQ_NONE; | 736 | return IRQ_NONE; |
845 | 737 | ||
846 | dbg("%s: intr_loc = %x\n",__FUNCTION__, intr_loc); | 738 | dbg("%s: intr_loc = %x\n",__FUNCTION__, intr_loc); |
847 | 739 | ||
848 | if(!shpchp_poll_mode) { | 740 | if(!shpchp_poll_mode) { |
849 | /* | 741 | /* |
@@ -856,12 +748,12 @@ static irqreturn_t shpc_isr(int irq, void *dev_id) | |||
856 | shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int); | 748 | shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int); |
857 | 749 | ||
858 | intr_loc2 = shpc_readl(ctrl, INTR_LOC); | 750 | intr_loc2 = shpc_readl(ctrl, INTR_LOC); |
859 | dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2); | 751 | dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2); |
860 | } | 752 | } |
861 | 753 | ||
862 | if (intr_loc & CMD_INTR_PENDING) { | 754 | if (intr_loc & CMD_INTR_PENDING) { |
863 | /* | 755 | /* |
864 | * Command Complete Interrupt Pending | 756 | * Command Complete Interrupt Pending |
865 | * RO only - clear by writing 1 to the Command Completion | 757 | * RO only - clear by writing 1 to the Command Completion |
866 | * Detect bit in Controller SERR-INT register | 758 | * Detect bit in Controller SERR-INT register |
867 | */ | 759 | */ |
@@ -875,7 +767,7 @@ static irqreturn_t shpc_isr(int irq, void *dev_id) | |||
875 | if (!(intr_loc & ~CMD_INTR_PENDING)) | 767 | if (!(intr_loc & ~CMD_INTR_PENDING)) |
876 | goto out; | 768 | goto out; |
877 | 769 | ||
878 | for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) { | 770 | for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) { |
879 | /* To find out which slot has interrupt pending */ | 771 | /* To find out which slot has interrupt pending */ |
880 | if (!(intr_loc & SLOT_INTR_PENDING(hp_slot))) | 772 | if (!(intr_loc & SLOT_INTR_PENDING(hp_slot))) |
881 | continue; | 773 | continue; |
@@ -907,7 +799,7 @@ static irqreturn_t shpc_isr(int irq, void *dev_id) | |||
907 | serr_int &= ~(GLOBAL_INTR_MASK | SERR_INTR_RSVDZ_MASK); | 799 | serr_int &= ~(GLOBAL_INTR_MASK | SERR_INTR_RSVDZ_MASK); |
908 | shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int); | 800 | shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int); |
909 | } | 801 | } |
910 | 802 | ||
911 | return IRQ_HANDLED; | 803 | return IRQ_HANDLED; |
912 | } | 804 | } |
913 | 805 | ||
@@ -920,8 +812,6 @@ static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) | |||
920 | u32 slot_avail1 = shpc_readl(ctrl, SLOT_AVAIL1); | 812 | u32 slot_avail1 = shpc_readl(ctrl, SLOT_AVAIL1); |
921 | u32 slot_avail2 = shpc_readl(ctrl, SLOT_AVAIL2); | 813 | u32 slot_avail2 = shpc_readl(ctrl, SLOT_AVAIL2); |
922 | 814 | ||
923 | DBG_ENTER_ROUTINE | ||
924 | |||
925 | if (pi == 2) { | 815 | if (pi == 2) { |
926 | if (slot_avail2 & SLOT_133MHZ_PCIX_533) | 816 | if (slot_avail2 & SLOT_133MHZ_PCIX_533) |
927 | bus_speed = PCI_SPEED_133MHz_PCIX_533; | 817 | bus_speed = PCI_SPEED_133MHz_PCIX_533; |
@@ -954,7 +844,7 @@ static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) | |||
954 | 844 | ||
955 | *value = bus_speed; | 845 | *value = bus_speed; |
956 | dbg("Max bus speed = %d\n", bus_speed); | 846 | dbg("Max bus speed = %d\n", bus_speed); |
957 | DBG_LEAVE_ROUTINE | 847 | |
958 | return retval; | 848 | return retval; |
959 | } | 849 | } |
960 | 850 | ||
@@ -967,8 +857,6 @@ static int hpc_get_cur_bus_speed (struct slot *slot, enum pci_bus_speed *value) | |||
967 | u8 pi = shpc_readb(ctrl, PROG_INTERFACE); | 857 | u8 pi = shpc_readb(ctrl, PROG_INTERFACE); |
968 | u8 speed_mode = (pi == 2) ? (sec_bus_reg & 0xF) : (sec_bus_reg & 0x7); | 858 | u8 speed_mode = (pi == 2) ? (sec_bus_reg & 0xF) : (sec_bus_reg & 0x7); |
969 | 859 | ||
970 | DBG_ENTER_ROUTINE | ||
971 | |||
972 | if ((pi == 1) && (speed_mode > 4)) { | 860 | if ((pi == 1) && (speed_mode > 4)) { |
973 | *value = PCI_SPEED_UNKNOWN; | 861 | *value = PCI_SPEED_UNKNOWN; |
974 | return -ENODEV; | 862 | return -ENODEV; |
@@ -1024,7 +912,6 @@ static int hpc_get_cur_bus_speed (struct slot *slot, enum pci_bus_speed *value) | |||
1024 | } | 912 | } |
1025 | 913 | ||
1026 | dbg("Current bus speed = %d\n", bus_speed); | 914 | dbg("Current bus speed = %d\n", bus_speed); |
1027 | DBG_LEAVE_ROUTINE | ||
1028 | return retval; | 915 | return retval; |
1029 | } | 916 | } |
1030 | 917 | ||
@@ -1032,7 +919,7 @@ static struct hpc_ops shpchp_hpc_ops = { | |||
1032 | .power_on_slot = hpc_power_on_slot, | 919 | .power_on_slot = hpc_power_on_slot, |
1033 | .slot_enable = hpc_slot_enable, | 920 | .slot_enable = hpc_slot_enable, |
1034 | .slot_disable = hpc_slot_disable, | 921 | .slot_disable = hpc_slot_disable, |
1035 | .set_bus_speed_mode = hpc_set_bus_speed_mode, | 922 | .set_bus_speed_mode = hpc_set_bus_speed_mode, |
1036 | .set_attention_status = hpc_set_attention_status, | 923 | .set_attention_status = hpc_set_attention_status, |
1037 | .get_power_status = hpc_get_power_status, | 924 | .get_power_status = hpc_get_power_status, |
1038 | .get_attention_status = hpc_get_attention_status, | 925 | .get_attention_status = hpc_get_attention_status, |
@@ -1049,7 +936,7 @@ static struct hpc_ops shpchp_hpc_ops = { | |||
1049 | .green_led_on = hpc_set_green_led_on, | 936 | .green_led_on = hpc_set_green_led_on, |
1050 | .green_led_off = hpc_set_green_led_off, | 937 | .green_led_off = hpc_set_green_led_off, |
1051 | .green_led_blink = hpc_set_green_led_blink, | 938 | .green_led_blink = hpc_set_green_led_blink, |
1052 | 939 | ||
1053 | .release_ctlr = hpc_release_ctlr, | 940 | .release_ctlr = hpc_release_ctlr, |
1054 | }; | 941 | }; |
1055 | 942 | ||
@@ -1061,8 +948,6 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev) | |||
1061 | u32 tempdword, slot_reg, slot_config; | 948 | u32 tempdword, slot_reg, slot_config; |
1062 | u8 i; | 949 | u8 i; |
1063 | 950 | ||
1064 | DBG_ENTER_ROUTINE | ||
1065 | |||
1066 | ctrl->pci_dev = pdev; /* pci_dev of the P2P bridge */ | 951 | ctrl->pci_dev = pdev; /* pci_dev of the P2P bridge */ |
1067 | 952 | ||
1068 | if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device == | 953 | if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device == |
@@ -1108,9 +993,9 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev) | |||
1108 | ctrl->mmio_size = 0x24 + 0x4 * num_slots; | 993 | ctrl->mmio_size = 0x24 + 0x4 * num_slots; |
1109 | } | 994 | } |
1110 | 995 | ||
1111 | info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, pdev->subsystem_vendor, | 996 | info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, pdev->subsystem_vendor, |
1112 | pdev->subsystem_device); | 997 | pdev->subsystem_device); |
1113 | 998 | ||
1114 | rc = pci_enable_device(pdev); | 999 | rc = pci_enable_device(pdev); |
1115 | if (rc) { | 1000 | if (rc) { |
1116 | err("%s: pci_enable_device failed\n", __FUNCTION__); | 1001 | err("%s: pci_enable_device failed\n", __FUNCTION__); |
@@ -1172,7 +1057,7 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev) | |||
1172 | slot_reg &= ~SLOT_REG_RSVDZ_MASK; | 1057 | slot_reg &= ~SLOT_REG_RSVDZ_MASK; |
1173 | shpc_writel(ctrl, SLOT_REG(hp_slot), slot_reg); | 1058 | shpc_writel(ctrl, SLOT_REG(hp_slot), slot_reg); |
1174 | } | 1059 | } |
1175 | 1060 | ||
1176 | if (shpchp_poll_mode) { | 1061 | if (shpchp_poll_mode) { |
1177 | /* Install interrupt polling timer. Start with 10 sec delay */ | 1062 | /* Install interrupt polling timer. Start with 10 sec delay */ |
1178 | init_timer(&ctrl->poll_timer); | 1063 | init_timer(&ctrl->poll_timer); |
@@ -1184,7 +1069,7 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev) | |||
1184 | info("Can't get msi for the hotplug controller\n"); | 1069 | info("Can't get msi for the hotplug controller\n"); |
1185 | info("Use INTx for the hotplug controller\n"); | 1070 | info("Use INTx for the hotplug controller\n"); |
1186 | } | 1071 | } |
1187 | 1072 | ||
1188 | rc = request_irq(ctrl->pci_dev->irq, shpc_isr, IRQF_SHARED, | 1073 | rc = request_irq(ctrl->pci_dev->irq, shpc_isr, IRQF_SHARED, |
1189 | MY_NAME, (void *)ctrl); | 1074 | MY_NAME, (void *)ctrl); |
1190 | dbg("%s: request_irq %d for hpc%d (returns %d)\n", | 1075 | dbg("%s: request_irq %d for hpc%d (returns %d)\n", |
@@ -1235,13 +1120,11 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev) | |||
1235 | dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword); | 1120 | dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword); |
1236 | } | 1121 | } |
1237 | 1122 | ||
1238 | DBG_LEAVE_ROUTINE | ||
1239 | return 0; | 1123 | return 0; |
1240 | 1124 | ||
1241 | /* We end up here for the many possible ways to fail this API. */ | 1125 | /* We end up here for the many possible ways to fail this API. */ |
1242 | abort_iounmap: | 1126 | abort_iounmap: |
1243 | iounmap(ctrl->creg); | 1127 | iounmap(ctrl->creg); |
1244 | abort: | 1128 | abort: |
1245 | DBG_LEAVE_ROUTINE | ||
1246 | return rc; | 1129 | return rc; |
1247 | } | 1130 | } |