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