aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug/pciehp_hpc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/hotplug/pciehp_hpc.c')
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index eb1862b50bb1..fbc64aa2dd68 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -35,6 +35,7 @@
35#include <linux/timer.h> 35#include <linux/timer.h>
36#include <linux/pci.h> 36#include <linux/pci.h>
37#include <linux/interrupt.h> 37#include <linux/interrupt.h>
38#include <linux/time.h>
38 39
39#include "../pci.h" 40#include "../pci.h"
40#include "pciehp.h" 41#include "pciehp.h"
@@ -192,6 +193,7 @@ static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value)
192#define ATTN_LED_CTRL 0x00C0 193#define ATTN_LED_CTRL 0x00C0
193#define PWR_LED_CTRL 0x0300 194#define PWR_LED_CTRL 0x0300
194#define PWR_CTRL 0x0400 195#define PWR_CTRL 0x0400
196#define EMI_CTRL 0x0800
195 197
196/* Attention indicator and Power indicator states */ 198/* Attention indicator and Power indicator states */
197#define LED_ON 0x01 199#define LED_ON 0x01
@@ -202,6 +204,10 @@ static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value)
202#define POWER_ON 0 204#define POWER_ON 0
203#define POWER_OFF 0x0400 205#define POWER_OFF 0x0400
204 206
207/* EMI Status defines */
208#define EMI_DISENGAGED 0
209#define EMI_ENGAGED 1
210
205/* Field definitions in Slot Status Register */ 211/* Field definitions in Slot Status Register */
206#define ATTN_BUTTN_PRESSED 0x0001 212#define ATTN_BUTTN_PRESSED 0x0001
207#define PWR_FAULT_DETECTED 0x0002 213#define PWR_FAULT_DETECTED 0x0002
@@ -210,6 +216,8 @@ static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value)
210#define CMD_COMPLETED 0x0010 216#define CMD_COMPLETED 0x0010
211#define MRL_STATE 0x0020 217#define MRL_STATE 0x0020
212#define PRSN_STATE 0x0040 218#define PRSN_STATE 0x0040
219#define EMI_STATE 0x0080
220#define EMI_STATUS_BIT 7
213 221
214static spinlock_t hpc_event_lock; 222static spinlock_t hpc_event_lock;
215 223
@@ -474,6 +482,51 @@ static int hpc_query_power_fault(struct slot *slot)
474 return pwr_fault; 482 return pwr_fault;
475} 483}
476 484
485static int hpc_get_emi_status(struct slot *slot, u8 *status)
486{
487 struct controller *ctrl = slot->ctrl;
488 u16 slot_status;
489 int retval = 0;
490
491 DBG_ENTER_ROUTINE
492
493 retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
494 if (retval) {
495 err("%s : Cannot check EMI status\n", __FUNCTION__);
496 return retval;
497 }
498 *status = (slot_status & EMI_STATE) >> EMI_STATUS_BIT;
499
500 DBG_LEAVE_ROUTINE
501 return retval;
502}
503
504static int hpc_toggle_emi(struct slot *slot)
505{
506 struct controller *ctrl = slot->ctrl;
507 u16 slot_cmd = 0;
508 u16 slot_ctrl;
509 int rc = 0;
510
511 DBG_ENTER_ROUTINE
512
513 rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
514 if (rc) {
515 err("%s : hp_register_read_word SLOT_CTRL failed\n",
516 __FUNCTION__);
517 return rc;
518 }
519
520 slot_cmd = (slot_ctrl | EMI_CTRL);
521 if (!pciehp_poll_mode)
522 slot_cmd = slot_cmd | HP_INTR_ENABLE;
523
524 pcie_write_cmd(slot, slot_cmd);
525 slot->last_emi_toggle = get_seconds();
526 DBG_LEAVE_ROUTINE
527 return rc;
528}
529
477static int hpc_set_attention_status(struct slot *slot, u8 value) 530static int hpc_set_attention_status(struct slot *slot, u8 value)
478{ 531{
479 struct controller *ctrl = slot->ctrl; 532 struct controller *ctrl = slot->ctrl;
@@ -1009,6 +1062,8 @@ static struct hpc_ops pciehp_hpc_ops = {
1009 .get_attention_status = hpc_get_attention_status, 1062 .get_attention_status = hpc_get_attention_status,
1010 .get_latch_status = hpc_get_latch_status, 1063 .get_latch_status = hpc_get_latch_status,
1011 .get_adapter_status = hpc_get_adapter_status, 1064 .get_adapter_status = hpc_get_adapter_status,
1065 .get_emi_status = hpc_get_emi_status,
1066 .toggle_emi = hpc_toggle_emi,
1012 1067
1013 .get_max_bus_speed = hpc_get_max_lnk_speed, 1068 .get_max_bus_speed = hpc_get_max_lnk_speed,
1014 .get_cur_bus_speed = hpc_get_cur_lnk_speed, 1069 .get_cur_bus_speed = hpc_get_cur_lnk_speed,