1 /*
2  * Standard PCI Hot Plug Driver
3  *
4  * Copyright (C) 1995,2001 Compaq Computer Corporation
5  * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6  * Copyright (C) 2001 IBM Corp.
7  * Copyright (C) 2003-2004 Intel Corporation
8  *
9  * All rights reserved.
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or (at
14  * your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful, but
17  * WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19  * NON INFRINGEMENT.  See the GNU General Public License for more
20  * details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25  *
26  * Send feedback to <greg@kroah.com>,<dely.l.sy@intel.com>
27  *
28  */
29 
30 #include <linux/config.h>
31 #include <linux/kernel.h>
32 #include <linux/module.h>
33 #include <linux/types.h>
34 #include <linux/slab.h>
35 #include <linux/vmalloc.h>
36 #include <linux/interrupt.h>
37 #include <linux/spinlock.h>
38 #include <linux/pci.h>
39 #include <asm/system.h>
40 #include "shpchp.h"
41 
42 #ifdef DEBUG
43 #define DBG_K_TRACE_ENTRY      ((unsigned int)0x00000001)	/* On function entry */
44 #define DBG_K_TRACE_EXIT       ((unsigned int)0x00000002)	/* On function exit */
45 #define DBG_K_INFO             ((unsigned int)0x00000004)	/* Info messages */
46 #define DBG_K_ERROR            ((unsigned int)0x00000008)	/* Error messages */
47 #define DBG_K_TRACE            (DBG_K_TRACE_ENTRY|DBG_K_TRACE_EXIT)
48 #define DBG_K_STANDARD         (DBG_K_INFO|DBG_K_ERROR|DBG_K_TRACE)
49 /* Redefine this flagword to set debug level */
50 #define DEBUG_LEVEL            DBG_K_STANDARD
51 
52 #define DEFINE_DBG_BUFFER     char __dbg_str_buf[256];
53 
54 #define DBG_PRINT( dbg_flags, args... )              \
55 	do {                                             \
56 	  if ( DEBUG_LEVEL & ( dbg_flags ) )             \
57 	  {                                              \
58 	    int len;                                     \
59 	    len = sprintf( __dbg_str_buf, "%s:%d: %s: ", \
60 		  __FILE__, __LINE__, __FUNCTION__ );    \
61 	    sprintf( __dbg_str_buf + len, args );        \
62 	    printk( KERN_NOTICE "%s\n", __dbg_str_buf ); \
63 	  }                                              \
64 	} while (0)
65 
66 #define DBG_ENTER_ROUTINE	DBG_PRINT (DBG_K_TRACE_ENTRY, "%s", "[Entry]");
67 #define DBG_LEAVE_ROUTINE	DBG_PRINT (DBG_K_TRACE_EXIT, "%s", "[Exit]");
68 #else
69 #define DEFINE_DBG_BUFFER
70 #define DBG_ENTER_ROUTINE
71 #define DBG_LEAVE_ROUTINE
72 #endif				/* DEBUG */
73 
74 /* Slot Available Register I field definition */
75 #define SLOT_33MHZ		0x0000001f
76 #define SLOT_66MHZ_PCIX		0x00001f00
77 #define SLOT_100MHZ_PCIX	0x001f0000
78 #define SLOT_133MHZ_PCIX	0x1f000000
79 
80 /* Slot Available Register II field definition */
81 #define SLOT_66MHZ		0x0000001f
82 #define SLOT_66MHZ_PCIX_266	0x00000f00
83 #define SLOT_100MHZ_PCIX_266	0x0000f000
84 #define SLOT_133MHZ_PCIX_266	0x000f0000
85 #define SLOT_66MHZ_PCIX_533		0x00f00000
86 #define SLOT_100MHZ_PCIX_533	0x0f000000
87 #define SLOT_133MHZ_PCIX_533	0xf0000000
88 
89 /* Secondary Bus Configuration Register */
90 /* For PI = 1, Bits 0 to 2 have been encoded as follows to show current bus speed/mode */
91 #define PCI_33MHZ	0x0
92 #define PCI_66MHZ	0x1
93 #define PCIX_66MHZ	0x2
94 #define PCIX_100MHZ	0x3
95 #define PCIX_133MHZ	0x4
96 
97 /* For PI = 2, Bits 0 to 3 have been encoded as follows to show current bus speed/mode */
98 #define PCI_33MHZ		0x0
99 #define PCI_66MHZ		0x1
100 #define PCIX_66MHZ		0x2
101 #define PCIX_100MHZ		0x3
102 #define PCIX_133MHZ		0x4
103 #define PCIX_66MHZ_ECC		0x5
104 #define PCIX_100MHZ_ECC		0x6
105 #define PCIX_133MHZ_ECC		0x7
106 #define PCIX_66MHZ_266		0x9
107 #define PCIX_100MHZ_266		0x0a
108 #define PCIX_133MHZ_266		0x0b
109 #define PCIX_66MHZ_533		0x11
110 #define PCIX_100MHZ_533		0x12
111 #define PCIX_133MHZ_533		0x13
112 
113 /* Slot Configuration */
114 #define SLOT_NUM		0x0000001F
115 #define	FIRST_DEV_NUM		0x00001F00
116 #define PSN			0x07FF0000
117 #define	UPDOWN			0x20000000
118 #define	MRLSENSOR		0x40000000
119 #define ATTN_BUTTON		0x80000000
120 
121 /* Slot Status Field Definitions */
122 /* Slot State */
123 #define PWR_ONLY	0x0001
124 #define ENABLED		0x0002
125 #define DISABLED	0x0003
126 
127 /* Power Indicator State */
128 #define PWR_LED_ON	0x0004
129 #define PWR_LED_BLINK	0x0008
130 #define PWR_LED_OFF	0x000c
131 
132 /* Attention Indicator State */
133 #define ATTEN_LED_ON	0x0010
134 #define	ATTEN_LED_BLINK	0x0020
135 #define ATTEN_LED_OFF	0x0030
136 
137 /* Power Fault */
138 #define pwr_fault	0x0040
139 
140 /* Attention Button */
141 #define ATTEN_BUTTON	0x0080
142 
143 /* MRL Sensor */
144 #define MRL_SENSOR	0x0100
145 
146 /* 66 MHz Capable */
147 #define IS_66MHZ_CAP	0x0200
148 
149 /* PRSNT1#/PRSNT2# */
150 #define SLOT_EMP	0x0c00
151 
152 /* PCI-X Capability */
153 #define NON_PCIX	0x0000
154 #define PCIX_66		0x1000
155 #define PCIX_133	0x3000
156 #define PCIX_266	0x4000  /* For PI = 2 only */
157 #define PCIX_533	0x5000	/* For PI = 2 only */
158 
159 /* SHPC 'write' operations/commands */
160 
161 /* Slot operation - 0x00h to 0x3Fh */
162 
163 #define NO_CHANGE	0x00
164 
165 /* Slot state - Bits 0 & 1 of controller command register */
166 #define SET_SLOT_PWR		0x01
167 #define SET_SLOT_ENABLE		0x02
168 #define SET_SLOT_DISABLE	0x03
169 
170 /* Power indicator state - Bits 2 & 3 of controller command register*/
171 #define SET_PWR_ON		0x04
172 #define SET_PWR_BLINK		0x08
173 #define SET_PWR_OFF		0x0C
174 
175 /* Attention indicator state - Bits 4 & 5 of controller command register*/
176 #define SET_ATTN_ON		0x010
177 #define SET_ATTN_BLINK		0x020
178 #define SET_ATTN_OFF		0x030
179 
180 /* Set bus speed/mode A - 0x40h to 0x47h */
181 #define SETA_PCI_33MHZ		0x40
182 #define SETA_PCI_66MHZ		0x41
183 #define SETA_PCIX_66MHZ		0x42
184 #define SETA_PCIX_100MHZ	0x43
185 #define SETA_PCIX_133MHZ	0x44
186 #define RESERV_1		0x45
187 #define RESERV_2		0x46
188 #define RESERV_3		0x47
189 
190 /* Set bus speed/mode B - 0x50h to 0x5fh */
191 #define	SETB_PCI_33MHZ		0x50
192 #define SETB_PCI_66MHZ		0x51
193 #define SETB_PCIX_66MHZ_PM	0x52
194 #define SETB_PCIX_100MHZ_PM	0x53
195 #define SETB_PCIX_133MHZ_PM	0x54
196 #define SETB_PCIX_66MHZ_EM	0x55
197 #define SETB_PCIX_100MHZ_EM	0x56
198 #define SETB_PCIX_133MHZ_EM	0x57
199 #define SETB_PCIX_66MHZ_266	0x58
200 #define SETB_PCIX_100MHZ_266	0x59
201 #define SETB_PCIX_133MHZ_266	0x5a
202 #define SETB_PCIX_66MHZ_533	0x5b
203 #define SETB_PCIX_100MHZ_533	0x5c
204 #define SETB_PCIX_133MHZ_533	0x5d
205 
206 /* Power-on all slots - 0x48h */
207 #define SET_PWR_ON_ALL	0x48
208 
209 /* Enable all slots	- 0x49h */
210 #define SET_ENABLE_ALL	0x49
211 
212 /*  SHPC controller command error code */
213 #define SWITCH_OPEN		0x1
214 #define INVALID_CMD		0x2
215 #define INVALID_SPEED_MODE	0x4
216 
217 /* For accessing SHPC Working Register Set */
218 #define DWORD_SELECT	0x2
219 #define DWORD_DATA		0x4
220 #define BASE_OFFSET		0x0
221 
222 /* Field Offset in Logical Slot Register - byte boundary */
223 #define SLOT_EVENT_LATCH	0x2
224 #define SLOT_SERR_INT_MASK	0x3
225 
226 static spinlock_t hpc_event_lock;
227 
228 DEFINE_DBG_BUFFER		/* Debug string buffer for entire HPC defined here */
229 static struct php_ctlr_state_s *php_ctlr_list_head = 0;	/* HPC state linked list */
230 static int ctlr_seq_num = 0;	/* Controller sequenc # */
231 
232 static spinlock_t list_lock;
233 
234 static void shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs);
235 
236 static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds);
237 
238 /* This is the interrupt polling timeout function. */
int_poll_timeout(unsigned long lphp_ctlr)239 static void int_poll_timeout(unsigned long lphp_ctlr)
240 {
241 	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *)lphp_ctlr;
242 
243 	DBG_ENTER_ROUTINE
244 
245 	if ( !php_ctlr ) {
246 		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
247 		return;
248 	}
249 
250 	/* Poll for interrupt events.  regs == NULL => polling */
251 	shpc_isr( 0, (void *)php_ctlr, NULL );
252 
253 	init_timer(&php_ctlr->int_poll_timer);
254 	if (!shpchp_poll_time)
255 	shpchp_poll_time = 2; /* reset timer to poll in 2 secs if user doesn't specify at module installation*/
256 
257 	start_int_poll_timer(php_ctlr, shpchp_poll_time);
258 
259 	return;
260 }
261 
262 /* This function starts the interrupt polling timer. */
start_int_poll_timer(struct php_ctlr_state_s * php_ctlr,int seconds)263 static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds)
264 {
265     if (!php_ctlr) {
266 		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
267 		return;
268 	}
269 
270     if ( ( seconds <= 0 ) || ( seconds > 60 ) )
271         seconds = 2;            /* Clamp to sane value */
272 
273     php_ctlr->int_poll_timer.function = &int_poll_timeout;
274     php_ctlr->int_poll_timer.data = (unsigned long)php_ctlr;    /* Instance data */
275     php_ctlr->int_poll_timer.expires = jiffies + seconds * HZ;
276     add_timer(&php_ctlr->int_poll_timer);
277 
278 	return;
279 }
280 
shpc_write_cmd(struct slot * slot,u8 t_slot,u8 cmd)281 static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
282 {
283 	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
284 	u16 cmd_status;
285 	int retval = 0;
286 	u16 temp_word;
287 	int i;
288 
289 	DBG_ENTER_ROUTINE
290 
291 	if (!php_ctlr) {
292 		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
293 		return -1;
294 	}
295 
296 	for (i = 0; i < 10; i++) {
297 		cmd_status = readw(php_ctlr->creg + CMD_STATUS);
298 
299 		if (!(cmd_status & 0x1))
300 			break;
301 		/*  Check every 0.1 sec for a total of 1 sec*/
302 		set_current_state(TASK_INTERRUPTIBLE);
303 		schedule_timeout(HZ/10);
304 	}
305 
306 	cmd_status = readw(php_ctlr->creg + CMD_STATUS);
307 
308 	if (cmd_status & 0x1) {
309 		/* After 1 sec and and the controller is still busy */
310 		err("%s : Controller is still busy after 1 sec.\n", __FUNCTION__);
311 		return -1;
312 	}
313 
314 	++t_slot;
315 	temp_word =  (t_slot << 8) | (cmd & 0xFF);
316 	dbg("%s :  t_slot %x cmd %x\n", __FUNCTION__, t_slot, cmd);
317 
318 	/* To make sure the Controller Busy bit is 0 before we send out the
319 	 * command.
320 	 */
321 	writew(temp_word, php_ctlr->creg + CMD);
322 	dbg("%s : temp_word written %x\n", __FUNCTION__, temp_word);
323 
324 	DBG_LEAVE_ROUTINE
325 	return retval;
326 }
327 
hpc_check_cmd_status(struct controller * ctrl)328 static int hpc_check_cmd_status(struct controller *ctrl)
329 {
330 	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) ctrl->hpc_ctlr_handle;
331 	u16 cmd_status;
332 	int retval = 0;
333 
334 	DBG_ENTER_ROUTINE
335 
336 	if (!ctrl->hpc_ctlr_handle) {
337 		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
338 		return -1;
339 	}
340 
341 	cmd_status = readw(php_ctlr->creg + CMD_STATUS) & 0x000F;
342 
343 	switch (cmd_status >> 1) {
344 	case 0:
345 		retval = 0;
346 		break;
347 	case 1:
348 		retval = SWITCH_OPEN;
349 		err("%s: Switch opened!\n", __FUNCTION__);
350 		break;
351 	case 2:
352 		retval = INVALID_CMD;
353 		err("%s: Invalid HPC command!\n", __FUNCTION__);
354 		break;
355 	case 4:
356 		retval = INVALID_SPEED_MODE;
357 		err("%s: Invalid bus speed/mode!\n", __FUNCTION__);
358 		break;
359 	default:
360 		retval = cmd_status;
361 	}
362 
363 	DBG_LEAVE_ROUTINE
364 	return retval;
365 }
366 
367 
hpc_get_attention_status(struct slot * slot,u8 * status)368 static int hpc_get_attention_status(struct slot *slot, u8 *status)
369 {
370 	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
371 	u32 slot_reg;
372 	u16 slot_status;
373 	u8 atten_led_state;
374 
375 	DBG_ENTER_ROUTINE
376 
377 	if (!slot->ctrl->hpc_ctlr_handle) {
378 		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
379 		return -1;
380 	}
381 
382 	slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot));
383 	slot_status = (u16) slot_reg;
384 	atten_led_state = (slot_status & 0x0030) >> 4;
385 
386 	switch (atten_led_state) {
387 	case 0:
388 		*status = 0xFF;	/* Reserved */
389 		break;
390 	case 1:
391 		*status = 1;	/* On */
392 		break;
393 	case 2:
394 		*status = 2;	/* Blink */
395 		break;
396 	case 3:
397 		*status = 0;	/* Off */
398 		break;
399 	default:
400 		*status = 0xFF;
401 		break;
402 	}
403 
404 	DBG_LEAVE_ROUTINE
405 	return 0;
406 }
407 
hpc_get_power_status(struct slot * slot,u8 * status)408 static int hpc_get_power_status(struct slot * slot, u8 *status)
409 {
410 	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
411 	u32 slot_reg;
412 	u16 slot_status;
413 	u8 slot_state;
414 	int	retval = 0;
415 
416 	DBG_ENTER_ROUTINE
417 
418 	if (!slot->ctrl->hpc_ctlr_handle) {
419 		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
420 		return -1;
421 	}
422 
423 	slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot));
424 	slot_status = (u16) slot_reg;
425 	slot_state = (slot_status & 0x0003);
426 
427 	switch (slot_state) {
428 	case 0:
429 		*status = 0xFF;
430 		break;
431 	case 1:
432 		*status = 2;	/* Powered only */
433 		break;
434 	case 2:
435 		*status = 1;	/* Enabled */
436 		break;
437 	case 3:
438 		*status = 0;	/* Disabled */
439 		break;
440 	default:
441 		*status = 0xFF;
442 		break;
443 	}
444 
445 	DBG_LEAVE_ROUTINE
446 	return retval;
447 }
448 
449 
hpc_get_latch_status(struct slot * slot,u8 * status)450 static int hpc_get_latch_status(struct slot *slot, u8 *status)
451 {
452 	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
453 	u32 slot_reg;
454 	u16 slot_status;
455 
456 	DBG_ENTER_ROUTINE
457 
458 	if (!slot->ctrl->hpc_ctlr_handle) {
459 		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
460 		return -1;
461 	}
462 
463 	slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot));
464 	slot_status = (u16)slot_reg;
465 
466 	*status = ((slot_status & 0x0100) == 0) ? 0 : 1;	/* 0 -> close; 1 -> open */
467 
468 	DBG_LEAVE_ROUTINE
469 	return 0;
470 }
471 
hpc_get_adapter_status(struct slot * slot,u8 * status)472 static int hpc_get_adapter_status(struct slot *slot, u8 *status)
473 {
474 	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
475 	u32 slot_reg;
476 	u16 slot_status;
477 	u8 card_state;
478 
479 	DBG_ENTER_ROUTINE
480 
481 	if (!slot->ctrl->hpc_ctlr_handle) {
482 		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
483 		return -1;
484 	}
485 
486 	slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot));
487 	slot_status = (u16)slot_reg;
488 	card_state = (u8)((slot_status & 0x0C00) >> 10);
489 	*status = (card_state != 0x3) ? 1 : 0;
490 
491 	DBG_LEAVE_ROUTINE
492 	return 0;
493 }
494 
hpc_get_prog_int(struct slot * slot,u8 * prog_int)495 static int hpc_get_prog_int(struct slot *slot, u8 *prog_int)
496 {
497 	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
498 
499 	DBG_ENTER_ROUTINE
500 
501 	if (!slot->ctrl->hpc_ctlr_handle) {
502 		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
503 		return -1;
504 	}
505 
506 	*prog_int = readb(php_ctlr->creg + PROG_INTERFACE);
507 
508 	DBG_LEAVE_ROUTINE
509 	return 0;
510 }
511 
hpc_get_adapter_speed(struct slot * slot,enum pci_bus_speed * value)512 static int hpc_get_adapter_speed(struct slot *slot, enum pci_bus_speed *value)
513 {
514 	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
515 	u32 slot_reg;
516 	u16 slot_status, sec_bus_status;
517 	u8 m66_cap, pcix_cap, pi;
518 	int retval = 0;
519 
520 	DBG_ENTER_ROUTINE
521 
522 	if (!slot->ctrl->hpc_ctlr_handle) {
523 		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
524 		return -1;
525 	}
526 
527 	if (slot->hp_slot >= php_ctlr->num_slots) {
528 		err("%s: Invalid HPC slot number!\n", __FUNCTION__);
529 		return -1;
530 	}
531 
532 	pi = readb(php_ctlr->creg + PROG_INTERFACE);
533 	slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot));
534 	dbg("%s: pi = %d, slot_reg = %x\n", __FUNCTION__, pi, slot_reg);
535 	slot_status = (u16) slot_reg;
536 	dbg("%s: slot_status = %x\n", __FUNCTION__, slot_status);
537 	sec_bus_status = readw(php_ctlr->creg + SEC_BUS_CONFIG);
538 
539 	pcix_cap = (u8) ((slot_status & 0x3000) >> 12);
540 	dbg("%s:  pcix_cap = %x\n", __FUNCTION__, pcix_cap);
541 	m66_cap = (u8) ((slot_status & 0x0200) >> 9);
542 	dbg("%s:  m66_cap = %x\n", __FUNCTION__, m66_cap);
543 
544 	if (pi == 2) {
545 		switch (pcix_cap) {
546 		case 0:
547 			*value = m66_cap ? PCI_SPEED_66MHz : PCI_SPEED_33MHz;
548 			break;
549 		case 1:
550 			*value = PCI_SPEED_66MHz_PCIX;
551 			break;
552 		case 3:
553 			*value = PCI_SPEED_133MHz_PCIX;
554 			break;
555 		case 4:
556 			*value = PCI_SPEED_133MHz_PCIX_266;
557 			break;
558 		case 5:
559 			*value = PCI_SPEED_133MHz_PCIX_533;
560 			break;
561 		case 2:	/* Reserved */
562 		default:
563 			*value = PCI_SPEED_UNKNOWN;
564 			retval = -ENODEV;
565 			break;
566 		}
567 	} else {
568 		switch (pcix_cap) {
569 		case 0:
570 			*value = m66_cap ? PCI_SPEED_66MHz : PCI_SPEED_33MHz;
571 			break;
572 		case 1:
573 			*value = PCI_SPEED_66MHz_PCIX;
574 			break;
575 		case 3:
576 			*value = PCI_SPEED_133MHz_PCIX;
577 			break;
578 		case 2:	/* Reserved */
579 		default:
580 			*value = PCI_SPEED_UNKNOWN;
581 			retval = -ENODEV;
582 			break;
583 		}
584 	}
585 
586 	dbg("Adapter speed = %d\n", *value);
587 
588 	DBG_LEAVE_ROUTINE
589 	return retval;
590 }
591 
hpc_get_mode1_ECC_cap(struct slot * slot,u8 * mode)592 static int hpc_get_mode1_ECC_cap(struct slot *slot, u8 *mode)
593 {
594 	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
595 	u16 sec_bus_status;
596 	u8 pi;
597 	int retval = 0;
598 
599 	DBG_ENTER_ROUTINE
600 
601 	if (!slot->ctrl->hpc_ctlr_handle) {
602 		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
603 		return -1;
604 	}
605 
606 	pi = readb(php_ctlr->creg + PROG_INTERFACE);
607 	sec_bus_status = readw(php_ctlr->creg + SEC_BUS_CONFIG);
608 
609 	if (pi == 2) {
610 		*mode = (sec_bus_status & 0x0100) >> 7;
611 	} else {
612 		retval = -1;
613 	}
614 
615 	dbg("Mode 1 ECC cap = %d\n", *mode);
616 
617 	DBG_LEAVE_ROUTINE
618 	return retval;
619 }
620 
hpc_query_power_fault(struct slot * slot)621 static int hpc_query_power_fault(struct slot * slot)
622 {
623 	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
624 	u32 slot_reg;
625 	u16 slot_status;
626 	u8 pwr_fault_state, status;
627 
628 	DBG_ENTER_ROUTINE
629 
630 	if (!slot->ctrl->hpc_ctlr_handle) {
631 		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
632 		return -1;
633 	}
634 
635 	slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot));
636 	slot_status = (u16) slot_reg;
637 	pwr_fault_state = (slot_status & 0x0040) >> 7;
638 	status = (pwr_fault_state == 1) ? 0 : 1;
639 
640 	DBG_LEAVE_ROUTINE
641 	/* Note: Logic 0 => fault */
642 	return status;
643 }
644 
hpc_set_attention_status(struct slot * slot,u8 value)645 static int hpc_set_attention_status(struct slot *slot, u8 value)
646 {
647 	struct php_ctlr_state_s *php_ctlr =(struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
648 	u8 slot_cmd = 0;
649 	int rc = 0;
650 
651 	if (!slot->ctrl->hpc_ctlr_handle) {
652 		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
653 		return -1;
654 	}
655 
656 	if (slot->hp_slot >= php_ctlr->num_slots) {
657 		err("%s: Invalid HPC slot number!\n", __FUNCTION__);
658 		return -1;
659 	}
660 
661 	switch (value) {
662 		case 0 :
663 			slot_cmd = 0x30;	/* OFF */
664 			break;
665 		case 1:
666 			slot_cmd = 0x10;	/* ON */
667 			break;
668 		case 2:
669 			slot_cmd = 0x20;	/* BLINK */
670 			break;
671 		default:
672 			return -1;
673 	}
674 
675 	shpc_write_cmd(slot, slot->hp_slot, slot_cmd);
676 
677 	return rc;
678 }
679 
680 
hpc_set_green_led_on(struct slot * slot)681 static void hpc_set_green_led_on(struct slot *slot)
682 {
683 	struct php_ctlr_state_s *php_ctlr =(struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
684 	u8 slot_cmd;
685 
686 	if (!slot->ctrl->hpc_ctlr_handle) {
687 		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
688 		return ;
689 	}
690 
691 	if (slot->hp_slot >= php_ctlr->num_slots) {
692 		err("%s: Invalid HPC slot number!\n", __FUNCTION__);
693 		return ;
694 	}
695 
696 	slot_cmd = 0x04;
697 
698 	shpc_write_cmd(slot, slot->hp_slot, slot_cmd);
699 
700 	return;
701 }
702 
hpc_set_green_led_off(struct slot * slot)703 static void hpc_set_green_led_off(struct slot *slot)
704 {
705 	struct php_ctlr_state_s *php_ctlr =(struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
706 	u8 slot_cmd;
707 
708 	if (!slot->ctrl->hpc_ctlr_handle) {
709 		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
710 		return ;
711 	}
712 
713 	if (slot->hp_slot >= php_ctlr->num_slots) {
714 		err("%s: Invalid HPC slot number!\n", __FUNCTION__);
715 		return ;
716 	}
717 
718 	slot_cmd = 0x0C;
719 
720 	shpc_write_cmd(slot, slot->hp_slot, slot_cmd);
721 
722 	return;
723 }
724 
hpc_set_green_led_blink(struct slot * slot)725 static void hpc_set_green_led_blink(struct slot *slot)
726 {
727 	struct php_ctlr_state_s *php_ctlr =(struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
728 	u8 slot_cmd;
729 
730 	if (!slot->ctrl->hpc_ctlr_handle) {
731 		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
732 		return ;
733 	}
734 
735 	if (slot->hp_slot >= php_ctlr->num_slots) {
736 		err("%s: Invalid HPC slot number!\n", __FUNCTION__);
737 		return ;
738 	}
739 
740 	slot_cmd = 0x08;
741 
742 	shpc_write_cmd(slot, slot->hp_slot, slot_cmd);
743 
744 	return;
745 }
746 
shpc_get_ctlr_slot_config(struct controller * ctrl,int * num_ctlr_slots,int * first_device_num,int * physical_slot_num,int * updown,int * flags)747 int shpc_get_ctlr_slot_config(struct controller *ctrl,
748 	int *num_ctlr_slots,	/* number of slots in this HPC					*/
749 	int *first_device_num,	/* PCI dev num of the first slot in this SHPC	*/
750 	int *physical_slot_num,	/* phy slot num of the first slot in this SHPC	*/
751 	int *updown,			/* physical_slot_num increament: 1 or -1		*/
752 	int *flags)
753 {
754 	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) ctrl->hpc_ctlr_handle;
755 
756 	DBG_ENTER_ROUTINE
757 
758 	if (!ctrl->hpc_ctlr_handle) {
759 		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
760 		return -1;
761 	}
762 
763 	*first_device_num = php_ctlr->slot_device_offset;	/* Obtained in shpc_init() */
764 	*num_ctlr_slots = php_ctlr->num_slots;				/* Obtained in shpc_init() */
765 
766 	*physical_slot_num = (readl(php_ctlr->creg + SLOT_CONFIG) & PSN) >> 16;
767 	dbg("%s: physical_slot_num = %x\n", __FUNCTION__, *physical_slot_num);
768 	*updown = ((readl(php_ctlr->creg + SLOT_CONFIG) & UPDOWN ) >> 29) ? 1 : -1;
769 
770 	DBG_LEAVE_ROUTINE
771 	return 0;
772 }
773 
hpc_release_ctlr(struct controller * ctrl)774 static void hpc_release_ctlr(struct controller *ctrl)
775 {
776 	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) ctrl->hpc_ctlr_handle;
777 	struct php_ctlr_state_s *p, *p_prev;
778 
779 	DBG_ENTER_ROUTINE
780 
781 	if (!ctrl->hpc_ctlr_handle) {
782 		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
783 		return ;
784 	}
785 
786 	if (shpchp_poll_mode) {
787 	    del_timer(&php_ctlr->int_poll_timer);
788 	} else {
789 		if (php_ctlr->irq) {
790 			free_irq(php_ctlr->irq, ctrl);
791 			php_ctlr->irq = 0;
792 		}
793 	}
794 	if (php_ctlr->pci_dev) {
795 		dbg("%s: before calling iounmap & release_mem_region\n", __FUNCTION__);
796 		iounmap(php_ctlr->creg);
797 		release_mem_region(pci_resource_start(php_ctlr->pci_dev, 0), pci_resource_len(php_ctlr->pci_dev, 0));
798 		dbg("%s: before calling iounmap & release_mem_region\n", __FUNCTION__);
799 		php_ctlr->pci_dev = 0;
800 	}
801 
802 	spin_lock(&list_lock);
803 	p = php_ctlr_list_head;
804 	p_prev = NULL;
805 	while (p) {
806 		if (p == php_ctlr) {
807 			if (p_prev)
808 				p_prev->pnext = p->pnext;
809 			else
810 				php_ctlr_list_head = p->pnext;
811 			break;
812 		} else {
813 			p_prev = p;
814 			p = p->pnext;
815 		}
816 	}
817 	spin_unlock(&list_lock);
818 
819 	kfree(php_ctlr);
820 
821 	DBG_LEAVE_ROUTINE
822 
823 }
824 
hpc_power_on_slot(struct slot * slot)825 static int hpc_power_on_slot(struct slot * slot)
826 {
827 	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
828 	u8 slot_cmd;
829 	int retval = 0;
830 
831 	DBG_ENTER_ROUTINE
832 
833 	if (!slot->ctrl->hpc_ctlr_handle) {
834 		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
835 		return -1;
836 	}
837 
838 	if (slot->hp_slot >= php_ctlr->num_slots) {
839 		err("%s: Invalid HPC slot number!\n", __FUNCTION__);
840 		return -1;
841 	}
842 	slot_cmd = 0x01;
843 
844 	retval = shpc_write_cmd(slot, slot->hp_slot, slot_cmd);
845 
846 	if (retval) {
847 		err("%s: Write command failed!\n", __FUNCTION__);
848 		return -1;
849 	}
850 
851 	DBG_LEAVE_ROUTINE
852 
853 	return retval;
854 }
855 
hpc_slot_enable(struct slot * slot)856 static int hpc_slot_enable(struct slot * slot)
857 {
858 	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
859 	u8 slot_cmd;
860 	int retval = 0;
861 
862 	DBG_ENTER_ROUTINE
863 
864 	if (!slot->ctrl->hpc_ctlr_handle) {
865 		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
866 		return -1;
867 	}
868 
869 	if (slot->hp_slot >= php_ctlr->num_slots) {
870 		err("%s: Invalid HPC slot number!\n", __FUNCTION__);
871 		return -1;
872 	}
873 	/* 3A => Slot - Enable, Power Indicator - Blink, Attention Indicator - Off */
874 	slot_cmd = 0x3A;
875 
876 	retval = shpc_write_cmd(slot, slot->hp_slot, slot_cmd);
877 
878 	if (retval) {
879 		err("%s: Write command failed!\n", __FUNCTION__);
880 		return -1;
881 	}
882 
883 	DBG_LEAVE_ROUTINE
884 	return retval;
885 }
886 
hpc_slot_disable(struct slot * slot)887 static int hpc_slot_disable(struct slot * slot)
888 {
889 	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
890 	u8 slot_cmd;
891 	int retval = 0;
892 
893 	DBG_ENTER_ROUTINE
894 
895 	if (!slot->ctrl->hpc_ctlr_handle) {
896 		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
897 		return -1;
898 	}
899 
900 	if (slot->hp_slot >= php_ctlr->num_slots) {
901 		err("%s: Invalid HPC slot number!\n", __FUNCTION__);
902 		return -1;
903 	}
904 
905 	/* 1F => Slot - Disable, Power Indicator - Off, Attention Indicator - On */
906 	slot_cmd = 0x1F;
907 
908 	retval = shpc_write_cmd(slot, slot->hp_slot, slot_cmd);
909 
910 	if (retval) {
911 		err("%s: Write command failed!\n", __FUNCTION__);
912 		return -1;
913 	}
914 
915 	DBG_LEAVE_ROUTINE
916 	return retval;
917 }
918 
hpc_enable_all_slots(struct slot * slot)919 static int hpc_enable_all_slots( struct slot *slot )
920 {
921 	int retval = 0;
922 
923 	DBG_ENTER_ROUTINE
924 
925 	if (!slot->ctrl->hpc_ctlr_handle) {
926 		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
927 		return -1;
928 	}
929 
930 	retval = shpc_write_cmd(slot, 0, SET_ENABLE_ALL);
931 	if (retval) {
932 		err("%s: Write command failed!\n", __FUNCTION__);
933 		return -1;
934 	}
935 
936 	DBG_LEAVE_ROUTINE
937 
938 	return retval;
939 }
940 
hpc_pwr_on_all_slots(struct slot * slot)941 static int hpc_pwr_on_all_slots(struct slot *slot)
942 {
943 	int retval = 0;
944 
945 	DBG_ENTER_ROUTINE
946 
947 	retval = shpc_write_cmd(slot, 0, SET_PWR_ON_ALL);
948 
949 	if (retval) {
950 		err("%s: Write command failed!\n", __FUNCTION__);
951 		return -1;
952 	}
953 
954 	DBG_LEAVE_ROUTINE
955 	return retval;
956 }
957 
hpc_set_bus_speed_mode(struct slot * slot,enum pci_bus_speed value)958 static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value)
959 {
960 	u8 slot_cmd;
961 	u8 pi;
962 	int retval = 0;
963 	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
964 
965 	DBG_ENTER_ROUTINE
966 
967 	if (!slot->ctrl->hpc_ctlr_handle) {
968 		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
969 		return -1;
970 	}
971 
972 	pi = readb(php_ctlr->creg + PROG_INTERFACE);
973 
974 	if (pi == 1) {
975 		switch (value) {
976 		case 0:
977 			slot_cmd = SETA_PCI_33MHZ;
978 			break;
979 		case 1:
980 			slot_cmd = SETA_PCI_66MHZ;
981 			break;
982 		case 2:
983 			slot_cmd = SETA_PCIX_66MHZ;
984 			break;
985 		case 3:
986 			slot_cmd = SETA_PCIX_100MHZ;
987 			break;
988 		case 4:
989 			slot_cmd = SETA_PCIX_133MHZ;
990 			break;
991 		default:
992 			slot_cmd = PCI_SPEED_UNKNOWN;
993 			retval = -ENODEV;
994 			return retval;
995 		}
996 	} else {
997 		switch (value) {
998 		case 0:
999 			slot_cmd = SETB_PCI_33MHZ;
1000 			break;
1001 		case 1:
1002 			slot_cmd = SETB_PCI_66MHZ;
1003 			break;
1004 		case 2:
1005 			slot_cmd = SETB_PCIX_66MHZ_PM;
1006 			break;
1007 		case 3:
1008 			slot_cmd = SETB_PCIX_100MHZ_PM;
1009 			break;
1010 		case 4:
1011 			slot_cmd = SETB_PCIX_133MHZ_PM;
1012 			break;
1013 		case 5:
1014 			slot_cmd = SETB_PCIX_66MHZ_EM;
1015 			break;
1016 		case 6:
1017 			slot_cmd = SETB_PCIX_100MHZ_EM;
1018 			break;
1019 		case 7:
1020 			slot_cmd = SETB_PCIX_133MHZ_EM;
1021 			break;
1022 		case 8:
1023 			slot_cmd = SETB_PCIX_66MHZ_266;
1024 			break;
1025 		case 9:
1026 			slot_cmd = SETB_PCIX_100MHZ_266;
1027 			break;
1028 		case 0xa:
1029 			slot_cmd = SETB_PCIX_133MHZ_266;
1030 			break;
1031 		case 0xb:
1032 			slot_cmd = SETB_PCIX_66MHZ_533;
1033 			break;
1034 		case 0xc:
1035 			slot_cmd = SETB_PCIX_100MHZ_533;
1036 			break;
1037 		case 0xd:
1038 			slot_cmd = SETB_PCIX_133MHZ_533;
1039 			break;
1040 		default:
1041 			slot_cmd = PCI_SPEED_UNKNOWN;
1042 			retval = -ENODEV;
1043 			return retval;
1044 		}
1045 
1046 	}
1047 	retval = shpc_write_cmd(slot, 0, slot_cmd);
1048 	if (retval) {
1049 		err("%s: Write command failed!\n", __FUNCTION__);
1050 		return -1;
1051 	}
1052 
1053 	DBG_LEAVE_ROUTINE
1054 	return retval;
1055 }
1056 
shpc_isr(int IRQ,void * dev_id,struct pt_regs * regs)1057 static void shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs)
1058 {
1059 	struct controller *ctrl = NULL;
1060 	struct php_ctlr_state_s *php_ctlr;
1061 	u8 schedule_flag = 0;
1062 	u8 temp_byte;
1063 	u32 temp_dword, intr_loc, intr_loc2;
1064 	int hp_slot;
1065 
1066 	if (!dev_id)
1067 		return;
1068 
1069 	if (!shpchp_poll_mode) {
1070 		ctrl = (struct controller *)dev_id;
1071 		php_ctlr = ctrl->hpc_ctlr_handle;
1072 	} else {
1073 		php_ctlr = (struct php_ctlr_state_s *) dev_id;
1074 		ctrl = (struct controller *)php_ctlr->callback_instance_id;
1075 	}
1076 
1077 	if (!ctrl)
1078 		return;
1079 
1080 	if (!php_ctlr || !php_ctlr->creg)
1081 		return;
1082 
1083 	/* Check to see if it was our interrupt */
1084 	intr_loc = readl(php_ctlr->creg + INTR_LOC);
1085 
1086 	if (!intr_loc)
1087 		return;
1088 
1089 	dbg("%s: intr_loc = %x\n",__FUNCTION__, intr_loc);
1090 
1091 	if (!shpchp_poll_mode) {
1092 		/* Mask Global Interrupt Mask - see implementation note on p. 139 */
1093 		/* of SHPC spec rev 1.0*/
1094 		temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
1095 		dbg("%s: Before masking global interrupt, temp_dword = %x\n",
1096 			__FUNCTION__, temp_dword);
1097 		temp_dword |= 0x00000001;
1098 		dbg("%s: After masking global interrupt, temp_dword = %x\n",
1099 			__FUNCTION__, temp_dword);
1100 		writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE);
1101 
1102 		intr_loc2 = readl(php_ctlr->creg + INTR_LOC);
1103 		dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2);
1104 	}
1105 
1106 	if (intr_loc & 0x0001) {
1107 		/*
1108 		 * Command Complete Interrupt Pending
1109 		 * RO only - clear by writing 0 to the Command Completion
1110 		 * Detect bit in Controller SERR-INT register
1111 		 */
1112 		temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
1113 		dbg("%s: Before clearing CCIP, temp_dword = %x\n",
1114 			__FUNCTION__, temp_dword);
1115 		temp_dword &= 0xfffeffff;
1116 		dbg("%s: After clearing CCIP, temp_dword = %x\n",
1117 			__FUNCTION__, temp_dword);
1118 		writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE);
1119 
1120 		wake_up_interruptible(&ctrl->queue);
1121 	}
1122 
1123 	if ((intr_loc = (intr_loc >> 1)) == 0) {
1124 		/* Unmask Global Interrupt Mask */
1125 		temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
1126 		dbg("%s: 1-Before unmasking global interrupt, temp_dword = %x\n",
1127 			__FUNCTION__, temp_dword);
1128 		temp_dword &= 0xfffffffe;
1129 		dbg("%s: 1-After unmasking global interrupt, temp_dword = %x\n",
1130 			__FUNCTION__, temp_dword);
1131 		writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE);
1132 		return;
1133 	}
1134 
1135 	for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) {
1136 	/* To find out which slot has interrupt pending */
1137 		if ((intr_loc >> hp_slot) & 0x01) {
1138 			temp_dword = readl(php_ctlr->creg + SLOT1 + (4*hp_slot));
1139 			dbg("%s: Slot %x with intr, temp_dword = %x\n",
1140 				__FUNCTION__, hp_slot, temp_dword);
1141 			temp_byte = (temp_dword >> 16) & 0xFF;
1142 			dbg("%s: Slot with intr, temp_byte = %x\n",
1143 				__FUNCTION__, temp_byte);
1144 			if ((php_ctlr->switch_change_callback) && (temp_byte & 0x08))
1145 				schedule_flag += php_ctlr->switch_change_callback(
1146 					hp_slot, php_ctlr->callback_instance_id);
1147 			if ((php_ctlr->attention_button_callback) && (temp_byte & 0x04))
1148 				schedule_flag += php_ctlr->attention_button_callback(
1149 					hp_slot, php_ctlr->callback_instance_id);
1150 			if ((php_ctlr->presence_change_callback) && (temp_byte & 0x01))
1151 				schedule_flag += php_ctlr->presence_change_callback(
1152 					hp_slot , php_ctlr->callback_instance_id);
1153 			if ((php_ctlr->power_fault_callback) && (temp_byte & 0x12))
1154 				schedule_flag += php_ctlr->power_fault_callback(
1155 					hp_slot, php_ctlr->callback_instance_id);
1156 
1157 			/* Clear all slot events */
1158 			temp_dword = 0xe01fffff;
1159 			dbg("%s: Clearing slot events, temp_dword = %x\n",
1160 				__FUNCTION__, temp_dword);
1161 			writel(temp_dword, php_ctlr->creg + SLOT1 + (4*hp_slot));
1162 
1163 			intr_loc2 = readl(php_ctlr->creg + INTR_LOC);
1164 			dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2);
1165 		}
1166 	}
1167 
1168 	if (!shpchp_poll_mode) {
1169 		/* Unmask Global Interrupt Mask */
1170 		temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
1171 		dbg("%s: 2-Before unmasking global interrupt, temp_dword = %x\n",
1172 			__FUNCTION__, temp_dword);
1173 		temp_dword &= 0xfffffffe;
1174 		dbg("%s: 2-After unmasking global interrupt, temp_dword = %x\n",
1175 			__FUNCTION__, temp_dword);
1176 		writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE);
1177 	}
1178 
1179 	return;
1180 }
1181 
hpc_get_max_bus_speed(struct slot * slot,enum pci_bus_speed * value)1182 static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value)
1183 {
1184 	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
1185 	enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN;
1186 	int retval = 0;
1187 	u8 pi;
1188 	u32 slot_avail1, slot_avail2;
1189 	int slot_num;
1190 
1191 	DBG_ENTER_ROUTINE
1192 
1193 	if (!slot->ctrl->hpc_ctlr_handle) {
1194 		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
1195 		return -1;
1196 	}
1197 
1198 	if (slot->hp_slot >= php_ctlr->num_slots) {
1199 		err("%s: Invalid HPC slot number!\n", __FUNCTION__);
1200 		return -1;
1201 	}
1202 
1203 	pi = readb(php_ctlr->creg + PROG_INTERFACE);
1204 	slot_avail1 = readl(php_ctlr->creg + SLOT_AVAIL1);
1205 	slot_avail2 = readl(php_ctlr->creg + SLOT_AVAIL2);
1206 
1207 	if (pi == 2) {
1208 		if ((slot_num = ((slot_avail2 & SLOT_133MHZ_PCIX_533) >> 27)  ) != 0 )
1209 			bus_speed = PCIX_133MHZ_533;
1210 		else if ((slot_num = ((slot_avail2 & SLOT_100MHZ_PCIX_533) >> 23)  ) != 0 )
1211 			bus_speed = PCIX_100MHZ_533;
1212 		else if ((slot_num = ((slot_avail2 & SLOT_66MHZ_PCIX_533) >> 19)  ) != 0 )
1213 			bus_speed = PCIX_66MHZ_533;
1214 		else if ((slot_num = ((slot_avail2 & SLOT_133MHZ_PCIX_266) >> 15)  ) != 0 )
1215 			bus_speed = PCIX_133MHZ_266;
1216 		else if ((slot_num = ((slot_avail2 & SLOT_100MHZ_PCIX_266) >> 11)  ) != 0 )
1217 			bus_speed = PCIX_100MHZ_266;
1218 		else if ((slot_num = ((slot_avail2 & SLOT_66MHZ_PCIX_266) >> 7)  ) != 0 )
1219 			bus_speed = PCIX_66MHZ_266;
1220 		else if ((slot_num = ((slot_avail1 & SLOT_133MHZ_PCIX) >> 23)  ) != 0 )
1221 			bus_speed = PCIX_133MHZ;
1222 		else if ((slot_num = ((slot_avail1 & SLOT_100MHZ_PCIX) >> 15)  ) != 0 )
1223 			bus_speed = PCIX_100MHZ;
1224 		else if ((slot_num = ((slot_avail1 & SLOT_66MHZ_PCIX) >> 7)  ) != 0 )
1225 			bus_speed = PCIX_66MHZ;
1226 		else if ((slot_num = (slot_avail2 & SLOT_66MHZ)) != 0 )
1227 			bus_speed = PCI_66MHZ;
1228 		else if ((slot_num = (slot_avail1 & SLOT_33MHZ)) != 0 )
1229 			bus_speed = PCI_33MHZ;
1230 		else bus_speed = PCI_SPEED_UNKNOWN;
1231 	} else {
1232 		if ((slot_num = ((slot_avail1 & SLOT_133MHZ_PCIX) >> 23)  ) != 0 )
1233 			bus_speed = PCIX_133MHZ;
1234 		else if ((slot_num = ((slot_avail1 & SLOT_100MHZ_PCIX) >> 15)  ) != 0 )
1235 			bus_speed = PCIX_100MHZ;
1236 		else if ((slot_num = ((slot_avail1 & SLOT_66MHZ_PCIX) >> 7)  ) != 0 )
1237 			bus_speed = PCIX_66MHZ;
1238 		else if ((slot_num = (slot_avail2 & SLOT_66MHZ)) != 0 )
1239 			bus_speed = PCI_66MHZ;
1240 		else if ((slot_num = (slot_avail1 & SLOT_33MHZ)) != 0 )
1241 			bus_speed = PCI_33MHZ;
1242 		else bus_speed = PCI_SPEED_UNKNOWN;
1243 	}
1244 
1245 	*value = bus_speed;
1246 	dbg("Max bus speed = %d\n", bus_speed);
1247 	DBG_LEAVE_ROUTINE
1248 	return retval;
1249 }
1250 
hpc_get_cur_bus_speed(struct slot * slot,enum pci_bus_speed * value)1251 static int hpc_get_cur_bus_speed (struct slot *slot, enum pci_bus_speed *value)
1252 {
1253 	struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
1254 	enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN;
1255 	u16 sec_bus_status;
1256 	int retval = 0;
1257 	u8 pi;
1258 
1259 	DBG_ENTER_ROUTINE
1260 
1261 	if (!slot->ctrl->hpc_ctlr_handle) {
1262 		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
1263 		return -1;
1264 	}
1265 
1266 	if (slot->hp_slot >= php_ctlr->num_slots) {
1267 		err("%s: Invalid HPC slot number!\n", __FUNCTION__);
1268 		return -1;
1269 	}
1270 
1271 	pi = readb(php_ctlr->creg + PROG_INTERFACE);
1272 	sec_bus_status = readw(php_ctlr->creg + SEC_BUS_CONFIG);
1273 
1274 	if (pi == 2) {
1275 		switch (sec_bus_status & 0x000f) {
1276 		case 0:
1277 			bus_speed = PCI_SPEED_33MHz;
1278 			break;
1279 		case 1:
1280 			bus_speed = PCI_SPEED_66MHz;
1281 			break;
1282 		case 2:
1283 			bus_speed = PCI_SPEED_66MHz_PCIX;
1284 			break;
1285 		case 3:
1286 			bus_speed = PCI_SPEED_100MHz_PCIX;
1287 			break;
1288 		case 4:
1289 			bus_speed = PCI_SPEED_133MHz_PCIX;
1290 			break;
1291 		case 5:
1292 			bus_speed = PCI_SPEED_66MHz_PCIX_ECC;
1293 			break;
1294 		case 6:
1295 			bus_speed = PCI_SPEED_100MHz_PCIX_ECC;
1296 			break;
1297 		case 7:
1298 			bus_speed = PCI_SPEED_133MHz_PCIX_ECC;
1299 			break;
1300 		case 8:
1301 			bus_speed = PCI_SPEED_66MHz_PCIX_266;
1302 			break;
1303 		case 9:
1304 			bus_speed = PCI_SPEED_100MHz_PCIX_266;
1305 			break;
1306 		case 0xa:
1307 			bus_speed = PCI_SPEED_133MHz_PCIX_266;
1308 			break;
1309 		case 0xb:
1310 			bus_speed = PCI_SPEED_66MHz_PCIX_533;
1311 			break;
1312 		case 0xc:
1313 			bus_speed = PCI_SPEED_100MHz_PCIX_533;
1314 			break;
1315 		case 0xd:
1316 			bus_speed = PCI_SPEED_133MHz_PCIX_533;
1317 			break;
1318 		case 0xe:
1319 		case 0xf:
1320 		default:
1321 			bus_speed = PCI_SPEED_UNKNOWN;
1322 			break;
1323 		}
1324 	} else {
1325 		/* In the case where pi is undefined, default it to 1 */
1326 		switch (sec_bus_status & 0x0007) {
1327 		case 0:
1328 			bus_speed = PCI_SPEED_33MHz;
1329 			break;
1330 		case 1:
1331 			bus_speed = PCI_SPEED_66MHz;
1332 			break;
1333 		case 2:
1334 			bus_speed = PCI_SPEED_66MHz_PCIX;
1335 			break;
1336 		case 3:
1337 			bus_speed = PCI_SPEED_100MHz_PCIX;
1338 			break;
1339 		case 4:
1340 			bus_speed = PCI_SPEED_133MHz_PCIX;
1341 			break;
1342 		case 5:
1343 			bus_speed = PCI_SPEED_UNKNOWN;		/*	Reserved */
1344 			break;
1345 		case 6:
1346 			bus_speed = PCI_SPEED_UNKNOWN;		/*	Reserved */
1347 			break;
1348 		case 7:
1349 			bus_speed = PCI_SPEED_UNKNOWN;		/*	Reserved */
1350 			break;
1351 		default:
1352 			bus_speed = PCI_SPEED_UNKNOWN;
1353 			break;
1354 		}
1355 	}
1356 	*value = bus_speed;
1357 	dbg("Current bus speed = %d\n", bus_speed);
1358 	DBG_LEAVE_ROUTINE
1359 	return retval;
1360 
1361 }
1362 
1363 static struct hpc_ops shpchp_hpc_ops = {
1364 	.power_on_slot			= hpc_power_on_slot,
1365 	.slot_enable			= hpc_slot_enable,
1366 	.slot_disable			= hpc_slot_disable,
1367 	.enable_all_slots		= hpc_enable_all_slots,
1368 	.pwr_on_all_slots		= hpc_pwr_on_all_slots,
1369 	.set_bus_speed_mode		= hpc_set_bus_speed_mode,
1370 	.set_attention_status	= hpc_set_attention_status,
1371 	.get_power_status		= hpc_get_power_status,
1372 	.get_attention_status	= hpc_get_attention_status,
1373 	.get_latch_status		= hpc_get_latch_status,
1374 	.get_adapter_status		= hpc_get_adapter_status,
1375 
1376 	.get_max_bus_speed		= hpc_get_max_bus_speed,
1377 	.get_cur_bus_speed		= hpc_get_cur_bus_speed,
1378 	.get_adapter_speed		= hpc_get_adapter_speed,
1379 	.get_mode1_ECC_cap		= hpc_get_mode1_ECC_cap,
1380 	.get_prog_int			= hpc_get_prog_int,
1381 
1382 	.query_power_fault		= hpc_query_power_fault,
1383 	.green_led_on			= hpc_set_green_led_on,
1384 	.green_led_off			= hpc_set_green_led_off,
1385 	.green_led_blink		= hpc_set_green_led_blink,
1386 
1387 	.release_ctlr			= hpc_release_ctlr,
1388 	.check_cmd_status		= hpc_check_cmd_status,
1389 };
1390 
shpc_init(struct controller * ctrl,struct pci_dev * pdev,php_intr_callback_t attention_button_callback,php_intr_callback_t switch_change_callback,php_intr_callback_t presence_change_callback,php_intr_callback_t power_fault_callback)1391 int shpc_init(struct controller * ctrl,
1392 		struct pci_dev * pdev,
1393 		php_intr_callback_t attention_button_callback,
1394 		php_intr_callback_t switch_change_callback,
1395 		php_intr_callback_t presence_change_callback,
1396 		php_intr_callback_t power_fault_callback)
1397 {
1398 	struct php_ctlr_state_s *php_ctlr, *p;
1399 	void *instance_id = ctrl;
1400 	int rc;
1401 	u8 hp_slot;
1402 	static int first = 1;
1403 	u32 shpc_cap_offset, shpc_base_offset;
1404 	u32 tempdword, slot_reg;
1405 	u16 vendor_id, device_id;
1406 	u8  i;
1407 
1408 	DBG_ENTER_ROUTINE
1409 
1410 	spin_lock_init(&list_lock);
1411 	php_ctlr = (struct php_ctlr_state_s *) kmalloc(sizeof(struct php_ctlr_state_s), GFP_KERNEL);
1412 
1413 	if (!php_ctlr) {	/* allocate controller state data */
1414 		err("%s: HPC controller memory allocation error!\n", __FUNCTION__);
1415 		goto abort;
1416 	}
1417 
1418 	memset(php_ctlr, 0, sizeof(struct php_ctlr_state_s));
1419 
1420 	php_ctlr->pci_dev = pdev;	/* save pci_dev in context */
1421 
1422 	rc = pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor_id);
1423 	dbg("%s: Vendor ID: %x\n",__FUNCTION__, vendor_id);
1424 	if (rc) {
1425 		err("%s: Unable to read PCI COnfiguration data\n", __FUNCTION__);
1426 		goto abort_free_ctlr;
1427 	}
1428 
1429 	rc = pci_read_config_word(pdev, PCI_DEVICE_ID, &device_id);
1430 	dbg("%s: Device ID: %x\n",__FUNCTION__, device_id);
1431 	if (rc) {
1432 		err("%s: Unable to read PCI COnfiguration data\n", __FUNCTION__);
1433 		goto abort_free_ctlr;
1434 	}
1435 
1436 	if ((vendor_id == PCI_VENDOR_ID_AMD) || (device_id == PCI_DEVICE_ID_AMD_GOLAM_7450)) {
1437 		shpc_base_offset = 0;  /* amd shpc driver doesn't use this; assume 0 */
1438 	} else {
1439 		if ((shpc_cap_offset = pci_find_capability(pdev, PCI_CAP_ID_SHPC)) == 0) {
1440 			err("%s : shpc_cap_offset == 0\n", __FUNCTION__);
1441 			goto abort_free_ctlr;
1442 		}
1443 		dbg("%s: shpc_cap_offset = %x\n", __FUNCTION__, shpc_cap_offset);
1444 
1445 		rc = pci_write_config_byte(pdev, (u8)shpc_cap_offset + DWORD_SELECT , BASE_OFFSET);
1446 		if (rc) {
1447 			err("%s : pci_word_config_byte failed\n", __FUNCTION__);
1448 			goto abort_free_ctlr;
1449 		}
1450 
1451 		rc = pci_read_config_dword(pdev, (u8)shpc_cap_offset + DWORD_DATA, &shpc_base_offset);
1452 		if (rc) {
1453 			err("%s : pci_read_config_dword failed\n", __FUNCTION__);
1454 			goto abort_free_ctlr;
1455 		}
1456 
1457 		for (i = 0; i <= 14; i++) {
1458 			rc = pci_write_config_byte(pdev, (u8)shpc_cap_offset +  DWORD_SELECT , i);
1459 			if (rc) {
1460 				err("%s : pci_word_config_byte failed\n", __FUNCTION__);
1461 				goto abort_free_ctlr;
1462 			}
1463 
1464 			rc = pci_read_config_dword(pdev, (u8)shpc_cap_offset + DWORD_DATA, &tempdword);
1465 			if (rc) {
1466 				err("%s : pci_read_config_dword failed\n", __FUNCTION__);
1467 				goto abort_free_ctlr;
1468 			}
1469 			dbg("%s: offset %d: tempdword %x\n", __FUNCTION__,i, tempdword);
1470 		}
1471 	}
1472 
1473 	if (first) {
1474 		spin_lock_init(&hpc_event_lock);
1475 		first = 0;
1476 	}
1477 
1478 	dbg("pdev = %p: b:d:f:irq=0x%x:%x:%x:%x\n", pdev, pdev->bus->number, PCI_SLOT(pdev->devfn),
1479 		PCI_FUNC(pdev->devfn), pdev->irq);
1480 	for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++)
1481 		if (pci_resource_len(pdev, rc) > 0)
1482 			dbg("pci resource[%d] start=0x%lx(len=0x%lx), shpc_base_offset %x\n", rc,
1483 				pci_resource_start(pdev, rc), pci_resource_len(pdev, rc), shpc_base_offset);
1484 
1485 	info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device,
1486 		pdev->subsystem_vendor, pdev->subsystem_device);
1487 
1488 	if (!request_mem_region(pci_resource_start(pdev, 0) + shpc_base_offset, pci_resource_len(pdev, 0), MY_NAME)) {
1489 		err("%s: cannot reserve MMIO region\n", __FUNCTION__);
1490 		goto abort_free_ctlr;
1491 	}
1492 
1493 	php_ctlr->creg = (struct ctrl_reg *)
1494 		ioremap(pci_resource_start(pdev, 0) + shpc_base_offset, pci_resource_len(pdev, 0));
1495 	if (!php_ctlr->creg) {
1496 		err("%s: cannot remap MMIO region %lx @ %lx\n", __FUNCTION__, pci_resource_len(pdev, 0),
1497 			pci_resource_start(pdev, 0) + shpc_base_offset);
1498 		release_mem_region(pci_resource_start(pdev, 0) + shpc_base_offset, pci_resource_len(pdev, 0));
1499 		goto abort_free_ctlr;
1500 	}
1501 	dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg);
1502 	dbg("%s: physical addr %p\n", __FUNCTION__, (void*)pci_resource_start(pdev, 0));
1503 
1504 	init_MUTEX(&ctrl->crit_sect);
1505 	/* Ssetup wait queue */
1506 	init_waitqueue_head(&ctrl->queue);
1507 
1508 	/* Find the IRQ */
1509 	php_ctlr->irq = pdev->irq;
1510 	dbg("HPC interrupt = %d\n", php_ctlr->irq);
1511 
1512 	/* Save interrupt callback info */
1513 	php_ctlr->attention_button_callback = attention_button_callback;
1514 	php_ctlr->switch_change_callback = switch_change_callback;
1515 	php_ctlr->presence_change_callback = presence_change_callback;
1516 	php_ctlr->power_fault_callback = power_fault_callback;
1517 	php_ctlr->callback_instance_id = instance_id;
1518 
1519 	/* Return PCI Controller Info */
1520 	php_ctlr->slot_device_offset = (readl(php_ctlr->creg + SLOT_CONFIG) & FIRST_DEV_NUM ) >> 8;
1521 	php_ctlr->num_slots = readl(php_ctlr->creg + SLOT_CONFIG) & SLOT_NUM;
1522 	dbg("%s: slot_device_offset %x\n", __FUNCTION__, php_ctlr->slot_device_offset);
1523 	dbg("%s: num_slots %x\n", __FUNCTION__, php_ctlr->num_slots);
1524 
1525 	/* Mask Global Interrupt Mask & Command Complete Interrupt Mask */
1526 	tempdword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
1527 	dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword);
1528 	tempdword = 0x0003000f;
1529 	writel(tempdword, php_ctlr->creg + SERR_INTR_ENABLE);
1530 	tempdword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
1531 	dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword);
1532 
1533 	/* Mask the MRL sensor SERR Mask of individual slot in
1534 	 * Slot SERR-INT Mask & clear all the existing event if any
1535 	 */
1536 	for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) {
1537 		slot_reg = readl(php_ctlr->creg + SLOT1 + 4*hp_slot );
1538 		dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__,
1539 			hp_slot, slot_reg);
1540 		tempdword = 0xffffffff;
1541 		writel(tempdword, php_ctlr->creg + SLOT1 + (4*hp_slot));
1542 	}
1543 
1544 	if (shpchp_poll_mode)  {/* Install interrupt polling code */
1545 		/* Install and start the interrupt polling timer */
1546 		init_timer(&php_ctlr->int_poll_timer);
1547 		start_int_poll_timer( php_ctlr, 10 );   /* start with 10 second delay */
1548 	} else {
1549 		/* Installs the interrupt handler */
1550 		rc = request_irq(php_ctlr->irq, shpc_isr, SA_SHIRQ, MY_NAME, (void *) ctrl);
1551 		dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq,
1552 			ctlr_seq_num, rc);
1553 		if (rc) {
1554 			err("Can't get irq %d for the hotplug controller\n", php_ctlr->irq);
1555 			goto abort_free_ctlr;
1556 		}
1557 	}
1558 	dbg("%s: Before adding HPC to HPC list\n", __FUNCTION__);
1559 
1560 	/*  Add this HPC instance into the HPC list */
1561 	spin_lock(&list_lock);
1562 	if (php_ctlr_list_head == 0) {
1563 		php_ctlr_list_head = php_ctlr;
1564 		p = php_ctlr_list_head;
1565 		p->pnext = 0;
1566 	} else {
1567 		p = php_ctlr_list_head;
1568 
1569 		while (p->pnext)
1570 			p = p->pnext;
1571 
1572 		p->pnext = php_ctlr;
1573 	}
1574 	spin_unlock(&list_lock);
1575 
1576 	ctlr_seq_num++;
1577 	ctrl->hpc_ctlr_handle = php_ctlr;
1578 	ctrl->hpc_ops = &shpchp_hpc_ops;
1579 	for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) {
1580 		slot_reg = readl(php_ctlr->creg + SLOT1 + 4*hp_slot );
1581 		dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__,
1582 			hp_slot, slot_reg);
1583 		tempdword = 0xe01fffff;
1584 		writel(tempdword, php_ctlr->creg + SLOT1 + (4*hp_slot));
1585 	}
1586 	if (!shpchp_poll_mode) {
1587 		/* Unmask all general input interrupts and SERR */
1588 		tempdword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
1589 		tempdword = 0x0000000a;
1590 		writel(tempdword, php_ctlr->creg + SERR_INTR_ENABLE);
1591 		tempdword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
1592 		dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword);
1593 	}
1594 
1595 	dbg("%s: Leaving shpc_init\n", __FUNCTION__);
1596 	DBG_LEAVE_ROUTINE
1597 	return 0;
1598 
1599 	/* We end up here for the many possible ways to fail this API.  */
1600 abort_free_ctlr:
1601 	kfree(php_ctlr);
1602 abort:
1603 	DBG_LEAVE_ROUTINE
1604 	return -1;
1605 }
1606