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