PCI Hotplug: acpiphp: remove unneeded acpi_get_name function call
[safe/jmp/linux-2.6] / drivers / pci / hotplug / pciehp_ctrl.c
1 /*
2  * PCI Express Hot Plug Controller 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/module.h>
31 #include <linux/kernel.h>
32 #include <linux/types.h>
33 #include <linux/smp_lock.h>
34 #include <linux/pci.h>
35 #include <linux/workqueue.h>
36 #include "../pci.h"
37 #include "pciehp.h"
38
39 static void interrupt_event_handler(struct work_struct *work);
40
41 static int queue_interrupt_event(struct slot *p_slot, u32 event_type)
42 {
43         struct event_info *info;
44
45         info = kmalloc(sizeof(*info), GFP_ATOMIC);
46         if (!info)
47                 return -ENOMEM;
48
49         info->event_type = event_type;
50         info->p_slot = p_slot;
51         INIT_WORK(&info->work, interrupt_event_handler);
52
53         schedule_work(&info->work);
54
55         return 0;
56 }
57
58 u8 pciehp_handle_attention_button(u8 hp_slot, struct controller *ctrl)
59 {
60         struct slot *p_slot;
61         u32 event_type;
62
63         /* Attention Button Change */
64         dbg("pciehp:  Attention button interrupt received.\n");
65
66         p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
67
68         /*
69          *  Button pressed - See if need to TAKE ACTION!!!
70          */
71         info("Button pressed on Slot(%s)\n", p_slot->name);
72         event_type = INT_BUTTON_PRESS;
73
74         queue_interrupt_event(p_slot, event_type);
75
76         return 0;
77 }
78
79 u8 pciehp_handle_switch_change(u8 hp_slot, struct controller *ctrl)
80 {
81         struct slot *p_slot;
82         u8 getstatus;
83         u32 event_type;
84
85         /* Switch Change */
86         dbg("pciehp:  Switch interrupt received.\n");
87
88         p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
89         p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
90
91         if (getstatus) {
92                 /*
93                  * Switch opened
94                  */
95                 info("Latch open on Slot(%s)\n", p_slot->name);
96                 event_type = INT_SWITCH_OPEN;
97         } else {
98                 /*
99                  *  Switch closed
100                  */
101                 info("Latch close on Slot(%s)\n", p_slot->name);
102                 event_type = INT_SWITCH_CLOSE;
103         }
104
105         queue_interrupt_event(p_slot, event_type);
106
107         return 1;
108 }
109
110 u8 pciehp_handle_presence_change(u8 hp_slot, struct controller *ctrl)
111 {
112         struct slot *p_slot;
113         u32 event_type;
114         u8 presence_save;
115
116         /* Presence Change */
117         dbg("pciehp:  Presence/Notify input change.\n");
118
119         p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
120
121         /* Switch is open, assume a presence change
122          * Save the presence state
123          */
124         p_slot->hpc_ops->get_adapter_status(p_slot, &presence_save);
125         if (presence_save) {
126                 /*
127                  * Card Present
128                  */
129                 info("Card present on Slot(%s)\n", p_slot->name);
130                 event_type = INT_PRESENCE_ON;
131         } else {
132                 /*
133                  * Not Present
134                  */
135                 info("Card not present on Slot(%s)\n", p_slot->name);
136                 event_type = INT_PRESENCE_OFF;
137         }
138
139         queue_interrupt_event(p_slot, event_type);
140
141         return 1;
142 }
143
144 u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl)
145 {
146         struct slot *p_slot;
147         u32 event_type;
148
149         /* power fault */
150         dbg("pciehp:  Power fault interrupt received.\n");
151
152         p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
153
154         if ( !(p_slot->hpc_ops->query_power_fault(p_slot))) {
155                 /*
156                  * power fault Cleared
157                  */
158                 info("Power fault cleared on Slot(%s)\n", p_slot->name);
159                 event_type = INT_POWER_FAULT_CLEAR;
160         } else {
161                 /*
162                  *   power fault
163                  */
164                 info("Power fault on Slot(%s)\n", p_slot->name);
165                 event_type = INT_POWER_FAULT;
166                 info("power fault bit %x set\n", hp_slot);
167         }
168
169         queue_interrupt_event(p_slot, event_type);
170
171         return 1;
172 }
173
174 /* The following routines constitute the bulk of the
175    hotplug controller logic
176  */
177
178 static void set_slot_off(struct controller *ctrl, struct slot * pslot)
179 {
180         /* turn off slot, turn on Amber LED, turn off Green LED if supported*/
181         if (POWER_CTRL(ctrl->ctrlcap)) {
182                 if (pslot->hpc_ops->power_off_slot(pslot)) {
183                         err("%s: Issue of Slot Power Off command failed\n",
184                             __FUNCTION__);
185                         return;
186                 }
187         }
188
189         if (PWR_LED(ctrl->ctrlcap))
190                 pslot->hpc_ops->green_led_off(pslot);
191
192         if (ATTN_LED(ctrl->ctrlcap)) {
193                 if (pslot->hpc_ops->set_attention_status(pslot, 1)) {
194                         err("%s: Issue of Set Attention Led command failed\n",
195                             __FUNCTION__);
196                         return;
197                 }
198                 /*
199                  * After turning power off, we must wait for at least
200                  * 1 second before taking any action that relies on
201                  * power having been removed from the slot/adapter.
202                  */
203                 msleep(1000);
204         }
205 }
206
207 /**
208  * board_added - Called after a board has been added to the system.
209  * @p_slot: &slot where board is added
210  *
211  * Turns power on for the board.
212  * Configures board.
213  */
214 static int board_added(struct slot *p_slot)
215 {
216         u8 hp_slot;
217         int retval = 0;
218         struct controller *ctrl = p_slot->ctrl;
219
220         hp_slot = p_slot->device - ctrl->slot_device_offset;
221
222         dbg("%s: slot device, slot offset, hp slot = %d, %d ,%d\n",
223                         __FUNCTION__, p_slot->device,
224                         ctrl->slot_device_offset, hp_slot);
225
226         if (POWER_CTRL(ctrl->ctrlcap)) {
227                 /* Power on slot */
228                 retval = p_slot->hpc_ops->power_on_slot(p_slot);
229                 if (retval)
230                         return retval;
231         }
232
233         if (PWR_LED(ctrl->ctrlcap))
234                 p_slot->hpc_ops->green_led_blink(p_slot);
235
236         /* Wait for ~1 second */
237         msleep(1000);
238
239         /* Check link training status */
240         retval = p_slot->hpc_ops->check_lnk_status(ctrl);
241         if (retval) {
242                 err("%s: Failed to check link status\n", __FUNCTION__);
243                 set_slot_off(ctrl, p_slot);
244                 return retval;
245         }
246
247         /* Check for a power fault */
248         if (p_slot->hpc_ops->query_power_fault(p_slot)) {
249                 dbg("%s: power fault detected\n", __FUNCTION__);
250                 retval = POWER_FAILURE;
251                 goto err_exit;
252         }
253
254         retval = pciehp_configure_device(p_slot);
255         if (retval) {
256                 err("Cannot add device 0x%x:%x\n", p_slot->bus,
257                     p_slot->device);
258                 goto err_exit;
259         }
260
261         /*
262          * Some PCI Express root ports require fixup after hot-plug operation.
263          */
264         if (pcie_mch_quirk)
265                 pci_fixup_device(pci_fixup_final, ctrl->pci_dev);
266         if (PWR_LED(ctrl->ctrlcap))
267                 p_slot->hpc_ops->green_led_on(p_slot);
268
269         return 0;
270
271 err_exit:
272         set_slot_off(ctrl, p_slot);
273         return retval;
274 }
275
276 /**
277  * remove_board - Turns off slot and LEDs
278  * @p_slot: slot where board is being removed
279  */
280 static int remove_board(struct slot *p_slot)
281 {
282         u8 device;
283         u8 hp_slot;
284         int retval = 0;
285         struct controller *ctrl = p_slot->ctrl;
286
287         retval = pciehp_unconfigure_device(p_slot);
288         if (retval)
289                 return retval;
290
291         device = p_slot->device;
292         hp_slot = p_slot->device - ctrl->slot_device_offset;
293         p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
294
295         dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
296
297         if (POWER_CTRL(ctrl->ctrlcap)) {
298                 /* power off slot */
299                 retval = p_slot->hpc_ops->power_off_slot(p_slot);
300                 if (retval) {
301                         err("%s: Issue of Slot Disable command failed\n",
302                             __FUNCTION__);
303                         return retval;
304                 }
305         }
306
307         if (PWR_LED(ctrl->ctrlcap))
308                 /* turn off Green LED */
309                 p_slot->hpc_ops->green_led_off(p_slot);
310
311         return 0;
312 }
313
314 struct power_work_info {
315         struct slot *p_slot;
316         struct work_struct work;
317 };
318
319 /**
320  * pciehp_power_thread - handle pushbutton events
321  * @work: &struct work_struct describing work to be done
322  *
323  * Scheduled procedure to handle blocking stuff for the pushbuttons.
324  * Handles all pending events and exits.
325  */
326 static void pciehp_power_thread(struct work_struct *work)
327 {
328         struct power_work_info *info =
329                 container_of(work, struct power_work_info, work);
330         struct slot *p_slot = info->p_slot;
331
332         mutex_lock(&p_slot->lock);
333         switch (p_slot->state) {
334         case POWEROFF_STATE:
335                 mutex_unlock(&p_slot->lock);
336                 dbg("%s: disabling bus:device(%x:%x)\n",
337                     __FUNCTION__, p_slot->bus, p_slot->device);
338                 pciehp_disable_slot(p_slot);
339                 mutex_lock(&p_slot->lock);
340                 p_slot->state = STATIC_STATE;
341                 break;
342         case POWERON_STATE:
343                 mutex_unlock(&p_slot->lock);
344                 if (pciehp_enable_slot(p_slot) &&
345                     PWR_LED(p_slot->ctrl->ctrlcap))
346                         p_slot->hpc_ops->green_led_off(p_slot);
347                 mutex_lock(&p_slot->lock);
348                 p_slot->state = STATIC_STATE;
349                 break;
350         default:
351                 break;
352         }
353         mutex_unlock(&p_slot->lock);
354
355         kfree(info);
356 }
357
358 void pciehp_queue_pushbutton_work(struct work_struct *work)
359 {
360         struct slot *p_slot = container_of(work, struct slot, work.work);
361         struct power_work_info *info;
362
363         info = kmalloc(sizeof(*info), GFP_KERNEL);
364         if (!info) {
365                 err("%s: Cannot allocate memory\n", __FUNCTION__);
366                 return;
367         }
368         info->p_slot = p_slot;
369         INIT_WORK(&info->work, pciehp_power_thread);
370
371         mutex_lock(&p_slot->lock);
372         switch (p_slot->state) {
373         case BLINKINGOFF_STATE:
374                 p_slot->state = POWEROFF_STATE;
375                 break;
376         case BLINKINGON_STATE:
377                 p_slot->state = POWERON_STATE;
378                 break;
379         default:
380                 goto out;
381         }
382         queue_work(pciehp_wq, &info->work);
383  out:
384         mutex_unlock(&p_slot->lock);
385 }
386
387 static int update_slot_info(struct slot *slot)
388 {
389         struct hotplug_slot_info *info;
390         int result;
391
392         info = kmalloc(sizeof(*info), GFP_KERNEL);
393         if (!info)
394                 return -ENOMEM;
395
396         slot->hpc_ops->get_power_status(slot, &(info->power_status));
397         slot->hpc_ops->get_attention_status(slot, &(info->attention_status));
398         slot->hpc_ops->get_latch_status(slot, &(info->latch_status));
399         slot->hpc_ops->get_adapter_status(slot, &(info->adapter_status));
400
401         result = pci_hp_change_slot_info(slot->hotplug_slot, info);
402         kfree (info);
403         return result;
404 }
405
406 /*
407  * Note: This function must be called with slot->lock held
408  */
409 static void handle_button_press_event(struct slot *p_slot)
410 {
411         struct controller *ctrl = p_slot->ctrl;
412         u8 getstatus;
413
414         switch (p_slot->state) {
415         case STATIC_STATE:
416                 p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
417                 if (getstatus) {
418                         p_slot->state = BLINKINGOFF_STATE;
419                         info("PCI slot #%s - powering off due to button "
420                              "press.\n", p_slot->name);
421                 } else {
422                         p_slot->state = BLINKINGON_STATE;
423                         info("PCI slot #%s - powering on due to button "
424                              "press.\n", p_slot->name);
425                 }
426                 /* blink green LED and turn off amber */
427                 if (PWR_LED(ctrl->ctrlcap))
428                         p_slot->hpc_ops->green_led_blink(p_slot);
429                 if (ATTN_LED(ctrl->ctrlcap))
430                         p_slot->hpc_ops->set_attention_status(p_slot, 0);
431
432                 schedule_delayed_work(&p_slot->work, 5*HZ);
433                 break;
434         case BLINKINGOFF_STATE:
435         case BLINKINGON_STATE:
436                 /*
437                  * Cancel if we are still blinking; this means that we
438                  * press the attention again before the 5 sec. limit
439                  * expires to cancel hot-add or hot-remove
440                  */
441                 info("Button cancel on Slot(%s)\n", p_slot->name);
442                 dbg("%s: button cancel\n", __FUNCTION__);
443                 cancel_delayed_work(&p_slot->work);
444                 if (p_slot->state == BLINKINGOFF_STATE) {
445                         if (PWR_LED(ctrl->ctrlcap))
446                                 p_slot->hpc_ops->green_led_on(p_slot);
447                 } else {
448                         if (PWR_LED(ctrl->ctrlcap))
449                                 p_slot->hpc_ops->green_led_off(p_slot);
450                 }
451                 if (ATTN_LED(ctrl->ctrlcap))
452                         p_slot->hpc_ops->set_attention_status(p_slot, 0);
453                 info("PCI slot #%s - action canceled due to button press\n",
454                      p_slot->name);
455                 p_slot->state = STATIC_STATE;
456                 break;
457         case POWEROFF_STATE:
458         case POWERON_STATE:
459                 /*
460                  * Ignore if the slot is on power-on or power-off state;
461                  * this means that the previous attention button action
462                  * to hot-add or hot-remove is undergoing
463                  */
464                 info("Button ignore on Slot(%s)\n", p_slot->name);
465                 update_slot_info(p_slot);
466                 break;
467         default:
468                 warn("Not a valid state\n");
469                 break;
470         }
471 }
472
473 /*
474  * Note: This function must be called with slot->lock held
475  */
476 static void handle_surprise_event(struct slot *p_slot)
477 {
478         u8 getstatus;
479         struct power_work_info *info;
480
481         info = kmalloc(sizeof(*info), GFP_KERNEL);
482         if (!info) {
483                 err("%s: Cannot allocate memory\n", __FUNCTION__);
484                 return;
485         }
486         info->p_slot = p_slot;
487         INIT_WORK(&info->work, pciehp_power_thread);
488
489         p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
490         if (!getstatus)
491                 p_slot->state = POWEROFF_STATE;
492         else
493                 p_slot->state = POWERON_STATE;
494
495         queue_work(pciehp_wq, &info->work);
496 }
497
498 static void interrupt_event_handler(struct work_struct *work)
499 {
500         struct event_info *info = container_of(work, struct event_info, work);
501         struct slot *p_slot = info->p_slot;
502         struct controller *ctrl = p_slot->ctrl;
503
504         mutex_lock(&p_slot->lock);
505         switch (info->event_type) {
506         case INT_BUTTON_PRESS:
507                 handle_button_press_event(p_slot);
508                 break;
509         case INT_POWER_FAULT:
510                 if (!POWER_CTRL(ctrl->ctrlcap))
511                         break;
512                 if (ATTN_LED(ctrl->ctrlcap))
513                         p_slot->hpc_ops->set_attention_status(p_slot, 1);
514                 if (PWR_LED(ctrl->ctrlcap))
515                         p_slot->hpc_ops->green_led_off(p_slot);
516                 break;
517         case INT_PRESENCE_ON:
518         case INT_PRESENCE_OFF:
519                 if (!HP_SUPR_RM(ctrl->ctrlcap))
520                         break;
521                 dbg("Surprise Removal\n");
522                 update_slot_info(p_slot);
523                 handle_surprise_event(p_slot);
524                 break;
525         default:
526                 update_slot_info(p_slot);
527                 break;
528         }
529         mutex_unlock(&p_slot->lock);
530
531         kfree(info);
532 }
533
534 int pciehp_enable_slot(struct slot *p_slot)
535 {
536         u8 getstatus = 0;
537         int rc;
538
539         /* Check to see if (latch closed, card present, power off) */
540         mutex_lock(&p_slot->ctrl->crit_sect);
541
542         rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
543         if (rc || !getstatus) {
544                 info("%s: no adapter on slot(%s)\n", __FUNCTION__,
545                      p_slot->name);
546                 mutex_unlock(&p_slot->ctrl->crit_sect);
547                 return -ENODEV;
548         }
549         if (MRL_SENS(p_slot->ctrl->ctrlcap)) {
550                 rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
551                 if (rc || getstatus) {
552                         info("%s: latch open on slot(%s)\n", __FUNCTION__,
553                              p_slot->name);
554                         mutex_unlock(&p_slot->ctrl->crit_sect);
555                         return -ENODEV;
556                 }
557         }
558
559         if (POWER_CTRL(p_slot->ctrl->ctrlcap)) {
560                 rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
561                 if (rc || getstatus) {
562                         info("%s: already enabled on slot(%s)\n", __FUNCTION__,
563                              p_slot->name);
564                         mutex_unlock(&p_slot->ctrl->crit_sect);
565                         return -EINVAL;
566                 }
567         }
568
569         p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
570
571         rc = board_added(p_slot);
572         if (rc) {
573                 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
574         }
575
576         update_slot_info(p_slot);
577
578         mutex_unlock(&p_slot->ctrl->crit_sect);
579         return rc;
580 }
581
582
583 int pciehp_disable_slot(struct slot *p_slot)
584 {
585         u8 getstatus = 0;
586         int ret = 0;
587
588         if (!p_slot->ctrl)
589                 return 1;
590
591         /* Check to see if (latch closed, card present, power on) */
592         mutex_lock(&p_slot->ctrl->crit_sect);
593
594         if (!HP_SUPR_RM(p_slot->ctrl->ctrlcap)) {
595                 ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
596                 if (ret || !getstatus) {
597                         info("%s: no adapter on slot(%s)\n", __FUNCTION__,
598                              p_slot->name);
599                         mutex_unlock(&p_slot->ctrl->crit_sect);
600                         return -ENODEV;
601                 }
602         }
603
604         if (MRL_SENS(p_slot->ctrl->ctrlcap)) {
605                 ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
606                 if (ret || getstatus) {
607                         info("%s: latch open on slot(%s)\n", __FUNCTION__,
608                              p_slot->name);
609                         mutex_unlock(&p_slot->ctrl->crit_sect);
610                         return -ENODEV;
611                 }
612         }
613
614         if (POWER_CTRL(p_slot->ctrl->ctrlcap)) {
615                 ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
616                 if (ret || !getstatus) {
617                         info("%s: already disabled slot(%s)\n", __FUNCTION__,
618                              p_slot->name);
619                         mutex_unlock(&p_slot->ctrl->crit_sect);
620                         return -EINVAL;
621                 }
622                 /*
623                  * After turning power off, we must wait for at least
624                  * 1 second before taking any action that relies on
625                  * power having been removed from the slot/adapter.
626                  */
627                 msleep(1000);
628         }
629
630         ret = remove_board(p_slot);
631         update_slot_info(p_slot);
632
633         mutex_unlock(&p_slot->ctrl->crit_sect);
634         return ret;
635 }
636
637 int pciehp_sysfs_enable_slot(struct slot *p_slot)
638 {
639         int retval = -ENODEV;
640
641         mutex_lock(&p_slot->lock);
642         switch (p_slot->state) {
643         case BLINKINGON_STATE:
644                 cancel_delayed_work(&p_slot->work);
645         case STATIC_STATE:
646                 p_slot->state = POWERON_STATE;
647                 mutex_unlock(&p_slot->lock);
648                 retval = pciehp_enable_slot(p_slot);
649                 mutex_lock(&p_slot->lock);
650                 p_slot->state = STATIC_STATE;
651                 break;
652         case POWERON_STATE:
653                 info("Slot %s is already in powering on state\n",
654                      p_slot->name);
655                 break;
656         case BLINKINGOFF_STATE:
657         case POWEROFF_STATE:
658                 info("Already enabled on slot %s\n", p_slot->name);
659                 break;
660         default:
661                 err("Not a valid state on slot %s\n", p_slot->name);
662                 break;
663         }
664         mutex_unlock(&p_slot->lock);
665
666         return retval;
667 }
668
669 int pciehp_sysfs_disable_slot(struct slot *p_slot)
670 {
671         int retval = -ENODEV;
672
673         mutex_lock(&p_slot->lock);
674         switch (p_slot->state) {
675         case BLINKINGOFF_STATE:
676                 cancel_delayed_work(&p_slot->work);
677         case STATIC_STATE:
678                 p_slot->state = POWEROFF_STATE;
679                 mutex_unlock(&p_slot->lock);
680                 retval = pciehp_disable_slot(p_slot);
681                 mutex_lock(&p_slot->lock);
682                 p_slot->state = STATIC_STATE;
683                 break;
684         case POWEROFF_STATE:
685                 info("Slot %s is already in powering off state\n",
686                      p_slot->name);
687                 break;
688         case BLINKINGON_STATE:
689         case POWERON_STATE:
690                 info("Already disabled on slot %s\n", p_slot->name);
691                 break;
692         default:
693                 err("Not a valid state on slot %s\n", p_slot->name);
694                 break;
695         }
696         mutex_unlock(&p_slot->lock);
697
698         return retval;
699 }