Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[firefly-linux-kernel-4.4.55.git] / 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/slab.h>
34 #include <linux/pci.h>
35 #include "../pci.h"
36 #include "pciehp.h"
37
38 static void interrupt_event_handler(struct work_struct *work);
39
40 static int queue_interrupt_event(struct slot *p_slot, u32 event_type)
41 {
42         struct event_info *info;
43
44         info = kmalloc(sizeof(*info), GFP_ATOMIC);
45         if (!info)
46                 return -ENOMEM;
47
48         info->event_type = event_type;
49         info->p_slot = p_slot;
50         INIT_WORK(&info->work, interrupt_event_handler);
51
52         queue_work(p_slot->wq, &info->work);
53
54         return 0;
55 }
56
57 u8 pciehp_handle_attention_button(struct slot *p_slot)
58 {
59         u32 event_type;
60         struct controller *ctrl = p_slot->ctrl;
61
62         /* Attention Button Change */
63         ctrl_dbg(ctrl, "Attention button interrupt received\n");
64
65         /*
66          *  Button pressed - See if need to TAKE ACTION!!!
67          */
68         ctrl_info(ctrl, "Button pressed on Slot(%s)\n", slot_name(p_slot));
69         event_type = INT_BUTTON_PRESS;
70
71         queue_interrupt_event(p_slot, event_type);
72
73         return 0;
74 }
75
76 u8 pciehp_handle_switch_change(struct slot *p_slot)
77 {
78         u8 getstatus;
79         u32 event_type;
80         struct controller *ctrl = p_slot->ctrl;
81
82         /* Switch Change */
83         ctrl_dbg(ctrl, "Switch interrupt received\n");
84
85         pciehp_get_latch_status(p_slot, &getstatus);
86         if (getstatus) {
87                 /*
88                  * Switch opened
89                  */
90                 ctrl_info(ctrl, "Latch open on Slot(%s)\n", slot_name(p_slot));
91                 event_type = INT_SWITCH_OPEN;
92         } else {
93                 /*
94                  *  Switch closed
95                  */
96                 ctrl_info(ctrl, "Latch close on Slot(%s)\n", slot_name(p_slot));
97                 event_type = INT_SWITCH_CLOSE;
98         }
99
100         queue_interrupt_event(p_slot, event_type);
101
102         return 1;
103 }
104
105 u8 pciehp_handle_presence_change(struct slot *p_slot)
106 {
107         u32 event_type;
108         u8 presence_save;
109         struct controller *ctrl = p_slot->ctrl;
110
111         /* Presence Change */
112         ctrl_dbg(ctrl, "Presence/Notify input change\n");
113
114         /* Switch is open, assume a presence change
115          * Save the presence state
116          */
117         pciehp_get_adapter_status(p_slot, &presence_save);
118         if (presence_save) {
119                 /*
120                  * Card Present
121                  */
122                 ctrl_info(ctrl, "Card present on Slot(%s)\n", slot_name(p_slot));
123                 event_type = INT_PRESENCE_ON;
124         } else {
125                 /*
126                  * Not Present
127                  */
128                 ctrl_info(ctrl, "Card not present on Slot(%s)\n",
129                           slot_name(p_slot));
130                 event_type = INT_PRESENCE_OFF;
131         }
132
133         queue_interrupt_event(p_slot, event_type);
134
135         return 1;
136 }
137
138 u8 pciehp_handle_power_fault(struct slot *p_slot)
139 {
140         u32 event_type;
141         struct controller *ctrl = p_slot->ctrl;
142
143         /* power fault */
144         ctrl_dbg(ctrl, "Power fault interrupt received\n");
145         ctrl_err(ctrl, "Power fault on slot %s\n", slot_name(p_slot));
146         event_type = INT_POWER_FAULT;
147         ctrl_info(ctrl, "Power fault bit %x set\n", 0);
148         queue_interrupt_event(p_slot, event_type);
149
150         return 1;
151 }
152
153 /* The following routines constitute the bulk of the
154    hotplug controller logic
155  */
156
157 static void set_slot_off(struct controller *ctrl, struct slot * pslot)
158 {
159         /* turn off slot, turn on Amber LED, turn off Green LED if supported*/
160         if (POWER_CTRL(ctrl)) {
161                 pciehp_power_off_slot(pslot);
162
163                 /*
164                  * After turning power off, we must wait for at least 1 second
165                  * before taking any action that relies on power having been
166                  * removed from the slot/adapter.
167                  */
168                 msleep(1000);
169         }
170
171         pciehp_green_led_off(pslot);
172         pciehp_set_attention_status(pslot, 1);
173 }
174
175 /**
176  * board_added - Called after a board has been added to the system.
177  * @p_slot: &slot where board is added
178  *
179  * Turns power on for the board.
180  * Configures board.
181  */
182 static int board_added(struct slot *p_slot)
183 {
184         int retval = 0;
185         struct controller *ctrl = p_slot->ctrl;
186         struct pci_bus *parent = ctrl->pcie->port->subordinate;
187
188         if (POWER_CTRL(ctrl)) {
189                 /* Power on slot */
190                 retval = pciehp_power_on_slot(p_slot);
191                 if (retval)
192                         return retval;
193         }
194
195         pciehp_green_led_blink(p_slot);
196
197         /* Check link training status */
198         retval = pciehp_check_link_status(ctrl);
199         if (retval) {
200                 ctrl_err(ctrl, "Failed to check link status\n");
201                 goto err_exit;
202         }
203
204         /* Check for a power fault */
205         if (ctrl->power_fault_detected || pciehp_query_power_fault(p_slot)) {
206                 ctrl_err(ctrl, "Power fault on slot %s\n", slot_name(p_slot));
207                 retval = -EIO;
208                 goto err_exit;
209         }
210
211         retval = pciehp_configure_device(p_slot);
212         if (retval) {
213                 ctrl_err(ctrl, "Cannot add device at %04x:%02x:00\n",
214                          pci_domain_nr(parent), parent->number);
215                 goto err_exit;
216         }
217
218         pciehp_green_led_on(p_slot);
219         return 0;
220
221 err_exit:
222         set_slot_off(ctrl, p_slot);
223         return retval;
224 }
225
226 /**
227  * remove_board - Turns off slot and LEDs
228  * @p_slot: slot where board is being removed
229  */
230 static int remove_board(struct slot *p_slot)
231 {
232         int retval;
233         struct controller *ctrl = p_slot->ctrl;
234
235         retval = pciehp_unconfigure_device(p_slot);
236         if (retval)
237                 return retval;
238
239         if (POWER_CTRL(ctrl)) {
240                 pciehp_power_off_slot(p_slot);
241
242                 /*
243                  * After turning power off, we must wait for at least 1 second
244                  * before taking any action that relies on power having been
245                  * removed from the slot/adapter.
246                  */
247                 msleep(1000);
248         }
249
250         /* turn off Green LED */
251         pciehp_green_led_off(p_slot);
252         return 0;
253 }
254
255 struct power_work_info {
256         struct slot *p_slot;
257         struct work_struct work;
258 };
259
260 /**
261  * pciehp_power_thread - handle pushbutton events
262  * @work: &struct work_struct describing work to be done
263  *
264  * Scheduled procedure to handle blocking stuff for the pushbuttons.
265  * Handles all pending events and exits.
266  */
267 static void pciehp_power_thread(struct work_struct *work)
268 {
269         struct power_work_info *info =
270                 container_of(work, struct power_work_info, work);
271         struct slot *p_slot = info->p_slot;
272
273         mutex_lock(&p_slot->lock);
274         switch (p_slot->state) {
275         case POWEROFF_STATE:
276                 mutex_unlock(&p_slot->lock);
277                 ctrl_dbg(p_slot->ctrl,
278                          "Disabling domain:bus:device=%04x:%02x:00\n",
279                          pci_domain_nr(p_slot->ctrl->pcie->port->subordinate),
280                          p_slot->ctrl->pcie->port->subordinate->number);
281                 pciehp_disable_slot(p_slot);
282                 mutex_lock(&p_slot->lock);
283                 p_slot->state = STATIC_STATE;
284                 break;
285         case POWERON_STATE:
286                 mutex_unlock(&p_slot->lock);
287                 if (pciehp_enable_slot(p_slot))
288                         pciehp_green_led_off(p_slot);
289                 mutex_lock(&p_slot->lock);
290                 p_slot->state = STATIC_STATE;
291                 break;
292         default:
293                 break;
294         }
295         mutex_unlock(&p_slot->lock);
296
297         kfree(info);
298 }
299
300 void pciehp_queue_pushbutton_work(struct work_struct *work)
301 {
302         struct slot *p_slot = container_of(work, struct slot, work.work);
303         struct power_work_info *info;
304
305         info = kmalloc(sizeof(*info), GFP_KERNEL);
306         if (!info) {
307                 ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n",
308                          __func__);
309                 return;
310         }
311         info->p_slot = p_slot;
312         INIT_WORK(&info->work, pciehp_power_thread);
313
314         mutex_lock(&p_slot->lock);
315         switch (p_slot->state) {
316         case BLINKINGOFF_STATE:
317                 p_slot->state = POWEROFF_STATE;
318                 break;
319         case BLINKINGON_STATE:
320                 p_slot->state = POWERON_STATE;
321                 break;
322         default:
323                 kfree(info);
324                 goto out;
325         }
326         queue_work(p_slot->wq, &info->work);
327  out:
328         mutex_unlock(&p_slot->lock);
329 }
330
331 /*
332  * Note: This function must be called with slot->lock held
333  */
334 static void handle_button_press_event(struct slot *p_slot)
335 {
336         struct controller *ctrl = p_slot->ctrl;
337         u8 getstatus;
338
339         switch (p_slot->state) {
340         case STATIC_STATE:
341                 pciehp_get_power_status(p_slot, &getstatus);
342                 if (getstatus) {
343                         p_slot->state = BLINKINGOFF_STATE;
344                         ctrl_info(ctrl,
345                                   "PCI slot #%s - powering off due to button "
346                                   "press.\n", slot_name(p_slot));
347                 } else {
348                         p_slot->state = BLINKINGON_STATE;
349                         ctrl_info(ctrl,
350                                   "PCI slot #%s - powering on due to button "
351                                   "press.\n", slot_name(p_slot));
352                 }
353                 /* blink green LED and turn off amber */
354                 pciehp_green_led_blink(p_slot);
355                 pciehp_set_attention_status(p_slot, 0);
356                 queue_delayed_work(p_slot->wq, &p_slot->work, 5*HZ);
357                 break;
358         case BLINKINGOFF_STATE:
359         case BLINKINGON_STATE:
360                 /*
361                  * Cancel if we are still blinking; this means that we
362                  * press the attention again before the 5 sec. limit
363                  * expires to cancel hot-add or hot-remove
364                  */
365                 ctrl_info(ctrl, "Button cancel on Slot(%s)\n", slot_name(p_slot));
366                 cancel_delayed_work(&p_slot->work);
367                 if (p_slot->state == BLINKINGOFF_STATE) {
368                         pciehp_green_led_on(p_slot);
369                 } else {
370                         pciehp_green_led_off(p_slot);
371                 }
372                 pciehp_set_attention_status(p_slot, 0);
373                 ctrl_info(ctrl, "PCI slot #%s - action canceled "
374                           "due to button press\n", slot_name(p_slot));
375                 p_slot->state = STATIC_STATE;
376                 break;
377         case POWEROFF_STATE:
378         case POWERON_STATE:
379                 /*
380                  * Ignore if the slot is on power-on or power-off state;
381                  * this means that the previous attention button action
382                  * to hot-add or hot-remove is undergoing
383                  */
384                 ctrl_info(ctrl, "Button ignore on Slot(%s)\n", slot_name(p_slot));
385                 break;
386         default:
387                 ctrl_warn(ctrl, "Not a valid state\n");
388                 break;
389         }
390 }
391
392 /*
393  * Note: This function must be called with slot->lock held
394  */
395 static void handle_surprise_event(struct slot *p_slot)
396 {
397         u8 getstatus;
398         struct power_work_info *info;
399
400         info = kmalloc(sizeof(*info), GFP_KERNEL);
401         if (!info) {
402                 ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n",
403                          __func__);
404                 return;
405         }
406         info->p_slot = p_slot;
407         INIT_WORK(&info->work, pciehp_power_thread);
408
409         pciehp_get_adapter_status(p_slot, &getstatus);
410         if (!getstatus)
411                 p_slot->state = POWEROFF_STATE;
412         else
413                 p_slot->state = POWERON_STATE;
414
415         queue_work(p_slot->wq, &info->work);
416 }
417
418 static void interrupt_event_handler(struct work_struct *work)
419 {
420         struct event_info *info = container_of(work, struct event_info, work);
421         struct slot *p_slot = info->p_slot;
422         struct controller *ctrl = p_slot->ctrl;
423
424         mutex_lock(&p_slot->lock);
425         switch (info->event_type) {
426         case INT_BUTTON_PRESS:
427                 handle_button_press_event(p_slot);
428                 break;
429         case INT_POWER_FAULT:
430                 if (!POWER_CTRL(ctrl))
431                         break;
432                 pciehp_set_attention_status(p_slot, 1);
433                 pciehp_green_led_off(p_slot);
434                 break;
435         case INT_PRESENCE_ON:
436         case INT_PRESENCE_OFF:
437                 if (!HP_SUPR_RM(ctrl))
438                         break;
439                 ctrl_dbg(ctrl, "Surprise Removal\n");
440                 handle_surprise_event(p_slot);
441                 break;
442         default:
443                 break;
444         }
445         mutex_unlock(&p_slot->lock);
446
447         kfree(info);
448 }
449
450 int pciehp_enable_slot(struct slot *p_slot)
451 {
452         u8 getstatus = 0;
453         int rc;
454         struct controller *ctrl = p_slot->ctrl;
455
456         pciehp_get_adapter_status(p_slot, &getstatus);
457         if (!getstatus) {
458                 ctrl_info(ctrl, "No adapter on slot(%s)\n", slot_name(p_slot));
459                 return -ENODEV;
460         }
461         if (MRL_SENS(p_slot->ctrl)) {
462                 pciehp_get_latch_status(p_slot, &getstatus);
463                 if (getstatus) {
464                         ctrl_info(ctrl, "Latch open on slot(%s)\n",
465                                   slot_name(p_slot));
466                         return -ENODEV;
467                 }
468         }
469
470         if (POWER_CTRL(p_slot->ctrl)) {
471                 pciehp_get_power_status(p_slot, &getstatus);
472                 if (getstatus) {
473                         ctrl_info(ctrl, "Already enabled on slot(%s)\n",
474                                   slot_name(p_slot));
475                         return -EINVAL;
476                 }
477         }
478
479         pciehp_get_latch_status(p_slot, &getstatus);
480
481         rc = board_added(p_slot);
482         if (rc) {
483                 pciehp_get_latch_status(p_slot, &getstatus);
484         }
485         return rc;
486 }
487
488
489 int pciehp_disable_slot(struct slot *p_slot)
490 {
491         u8 getstatus = 0;
492         struct controller *ctrl = p_slot->ctrl;
493
494         if (!p_slot->ctrl)
495                 return 1;
496
497         if (!HP_SUPR_RM(p_slot->ctrl)) {
498                 pciehp_get_adapter_status(p_slot, &getstatus);
499                 if (!getstatus) {
500                         ctrl_info(ctrl, "No adapter on slot(%s)\n",
501                                   slot_name(p_slot));
502                         return -ENODEV;
503                 }
504         }
505
506         if (MRL_SENS(p_slot->ctrl)) {
507                 pciehp_get_latch_status(p_slot, &getstatus);
508                 if (getstatus) {
509                         ctrl_info(ctrl, "Latch open on slot(%s)\n",
510                                   slot_name(p_slot));
511                         return -ENODEV;
512                 }
513         }
514
515         if (POWER_CTRL(p_slot->ctrl)) {
516                 pciehp_get_power_status(p_slot, &getstatus);
517                 if (!getstatus) {
518                         ctrl_info(ctrl, "Already disabled on slot(%s)\n",
519                                   slot_name(p_slot));
520                         return -EINVAL;
521                 }
522         }
523
524         return remove_board(p_slot);
525 }
526
527 int pciehp_sysfs_enable_slot(struct slot *p_slot)
528 {
529         int retval = -ENODEV;
530         struct controller *ctrl = p_slot->ctrl;
531
532         mutex_lock(&p_slot->lock);
533         switch (p_slot->state) {
534         case BLINKINGON_STATE:
535                 cancel_delayed_work(&p_slot->work);
536         case STATIC_STATE:
537                 p_slot->state = POWERON_STATE;
538                 mutex_unlock(&p_slot->lock);
539                 retval = pciehp_enable_slot(p_slot);
540                 mutex_lock(&p_slot->lock);
541                 p_slot->state = STATIC_STATE;
542                 break;
543         case POWERON_STATE:
544                 ctrl_info(ctrl, "Slot %s is already in powering on state\n",
545                           slot_name(p_slot));
546                 break;
547         case BLINKINGOFF_STATE:
548         case POWEROFF_STATE:
549                 ctrl_info(ctrl, "Already enabled on slot %s\n",
550                           slot_name(p_slot));
551                 break;
552         default:
553                 ctrl_err(ctrl, "Not a valid state on slot %s\n",
554                          slot_name(p_slot));
555                 break;
556         }
557         mutex_unlock(&p_slot->lock);
558
559         return retval;
560 }
561
562 int pciehp_sysfs_disable_slot(struct slot *p_slot)
563 {
564         int retval = -ENODEV;
565         struct controller *ctrl = p_slot->ctrl;
566
567         mutex_lock(&p_slot->lock);
568         switch (p_slot->state) {
569         case BLINKINGOFF_STATE:
570                 cancel_delayed_work(&p_slot->work);
571         case STATIC_STATE:
572                 p_slot->state = POWEROFF_STATE;
573                 mutex_unlock(&p_slot->lock);
574                 retval = pciehp_disable_slot(p_slot);
575                 mutex_lock(&p_slot->lock);
576                 p_slot->state = STATIC_STATE;
577                 break;
578         case POWEROFF_STATE:
579                 ctrl_info(ctrl, "Slot %s is already in powering off state\n",
580                           slot_name(p_slot));
581                 break;
582         case BLINKINGON_STATE:
583         case POWERON_STATE:
584                 ctrl_info(ctrl, "Already disabled on slot %s\n",
585                           slot_name(p_slot));
586                 break;
587         default:
588                 ctrl_err(ctrl, "Not a valid state on slot %s\n",
589                          slot_name(p_slot));
590                 break;
591         }
592         mutex_unlock(&p_slot->lock);
593
594         return retval;
595 }