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