Commit 203104c8 authored by Bjorn Helgaas's avatar Bjorn Helgaas

Merge branch 'pci/pciehp'

  - Cleanup pciehp LED/indicator control with a new consolidated
    pciehp_set_indicators() interface that controls both Attention and
    Power Indicators (Denis Efremov)

* pci/pciehp:
  PCI: pciehp: Refer to "Indicators" instead of "LEDs" in comments
  PCI: pciehp: Remove pciehp_green_led_{on,off,blink}()
  PCI: pciehp: Remove pciehp_set_attention_status()
  PCI: pciehp: Combine adjacent indicator updates
  PCI: pciehp: Add pciehp_set_indicators() to set both indicators
parents 63fa8437 4a06c2c3
...@@ -110,9 +110,9 @@ struct controller { ...@@ -110,9 +110,9 @@ struct controller {
* *
* @OFF_STATE: slot is powered off, no subordinate devices are enumerated * @OFF_STATE: slot is powered off, no subordinate devices are enumerated
* @BLINKINGON_STATE: slot will be powered on after the 5 second delay, * @BLINKINGON_STATE: slot will be powered on after the 5 second delay,
* green led is blinking * Power Indicator is blinking
* @BLINKINGOFF_STATE: slot will be powered off after the 5 second delay, * @BLINKINGOFF_STATE: slot will be powered off after the 5 second delay,
* green led is blinking * Power Indicator is blinking
* @POWERON_STATE: slot is currently powering on * @POWERON_STATE: slot is currently powering on
* @POWEROFF_STATE: slot is currently powering off * @POWEROFF_STATE: slot is currently powering off
* @ON_STATE: slot is powered on, subordinate devices have been enumerated * @ON_STATE: slot is powered on, subordinate devices have been enumerated
...@@ -167,12 +167,11 @@ int pciehp_power_on_slot(struct controller *ctrl); ...@@ -167,12 +167,11 @@ int pciehp_power_on_slot(struct controller *ctrl);
void pciehp_power_off_slot(struct controller *ctrl); void pciehp_power_off_slot(struct controller *ctrl);
void pciehp_get_power_status(struct controller *ctrl, u8 *status); void pciehp_get_power_status(struct controller *ctrl, u8 *status);
void pciehp_set_attention_status(struct controller *ctrl, u8 status); #define INDICATOR_NOOP -1 /* Leave indicator unchanged */
void pciehp_set_indicators(struct controller *ctrl, int pwr, int attn);
void pciehp_get_latch_status(struct controller *ctrl, u8 *status); void pciehp_get_latch_status(struct controller *ctrl, u8 *status);
int pciehp_query_power_fault(struct controller *ctrl); int pciehp_query_power_fault(struct controller *ctrl);
void pciehp_green_led_on(struct controller *ctrl);
void pciehp_green_led_off(struct controller *ctrl);
void pciehp_green_led_blink(struct controller *ctrl);
bool pciehp_card_present(struct controller *ctrl); bool pciehp_card_present(struct controller *ctrl);
bool pciehp_card_present_or_link_active(struct controller *ctrl); bool pciehp_card_present_or_link_active(struct controller *ctrl);
int pciehp_check_link_status(struct controller *ctrl); int pciehp_check_link_status(struct controller *ctrl);
......
...@@ -95,15 +95,20 @@ static void cleanup_slot(struct controller *ctrl) ...@@ -95,15 +95,20 @@ static void cleanup_slot(struct controller *ctrl)
} }
/* /*
* set_attention_status - Turns the Amber LED for a slot on, off or blink * set_attention_status - Turns the Attention Indicator on, off or blinking
*/ */
static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
{ {
struct controller *ctrl = to_ctrl(hotplug_slot); struct controller *ctrl = to_ctrl(hotplug_slot);
struct pci_dev *pdev = ctrl->pcie->port; struct pci_dev *pdev = ctrl->pcie->port;
if (status)
status <<= PCI_EXP_SLTCTL_ATTN_IND_SHIFT;
else
status = PCI_EXP_SLTCTL_ATTN_IND_OFF;
pci_config_pm_runtime_get(pdev); pci_config_pm_runtime_get(pdev);
pciehp_set_attention_status(ctrl, status); pciehp_set_indicators(ctrl, INDICATOR_NOOP, status);
pci_config_pm_runtime_put(pdev); pci_config_pm_runtime_put(pdev);
return 0; return 0;
} }
......
...@@ -30,7 +30,10 @@ ...@@ -30,7 +30,10 @@
static void set_slot_off(struct controller *ctrl) static void set_slot_off(struct controller *ctrl)
{ {
/* turn off slot, turn on Amber LED, turn off Green LED if supported*/ /*
* Turn off slot, turn on attention indicator, turn off power
* indicator
*/
if (POWER_CTRL(ctrl)) { if (POWER_CTRL(ctrl)) {
pciehp_power_off_slot(ctrl); pciehp_power_off_slot(ctrl);
...@@ -42,8 +45,8 @@ static void set_slot_off(struct controller *ctrl) ...@@ -42,8 +45,8 @@ static void set_slot_off(struct controller *ctrl)
msleep(1000); msleep(1000);
} }
pciehp_green_led_off(ctrl); pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF,
pciehp_set_attention_status(ctrl, 1); PCI_EXP_SLTCTL_ATTN_IND_ON);
} }
/** /**
...@@ -65,7 +68,8 @@ static int board_added(struct controller *ctrl) ...@@ -65,7 +68,8 @@ static int board_added(struct controller *ctrl)
return retval; return retval;
} }
pciehp_green_led_blink(ctrl); pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_BLINK,
INDICATOR_NOOP);
/* Check link training status */ /* Check link training status */
retval = pciehp_check_link_status(ctrl); retval = pciehp_check_link_status(ctrl);
...@@ -90,8 +94,8 @@ static int board_added(struct controller *ctrl) ...@@ -90,8 +94,8 @@ static int board_added(struct controller *ctrl)
} }
} }
pciehp_green_led_on(ctrl); pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_ON,
pciehp_set_attention_status(ctrl, 0); PCI_EXP_SLTCTL_ATTN_IND_OFF);
return 0; return 0;
err_exit: err_exit:
...@@ -100,7 +104,7 @@ static int board_added(struct controller *ctrl) ...@@ -100,7 +104,7 @@ static int board_added(struct controller *ctrl)
} }
/** /**
* remove_board - Turns off slot and LEDs * remove_board - Turn off slot and Power Indicator
* @ctrl: PCIe hotplug controller where board is being removed * @ctrl: PCIe hotplug controller where board is being removed
* @safe_removal: whether the board is safely removed (versus surprise removed) * @safe_removal: whether the board is safely removed (versus surprise removed)
*/ */
...@@ -123,8 +127,8 @@ static void remove_board(struct controller *ctrl, bool safe_removal) ...@@ -123,8 +127,8 @@ static void remove_board(struct controller *ctrl, bool safe_removal)
&ctrl->pending_events); &ctrl->pending_events);
} }
/* turn off Green LED */ pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF,
pciehp_green_led_off(ctrl); INDICATOR_NOOP);
} }
static int pciehp_enable_slot(struct controller *ctrl); static int pciehp_enable_slot(struct controller *ctrl);
...@@ -171,9 +175,9 @@ void pciehp_handle_button_press(struct controller *ctrl) ...@@ -171,9 +175,9 @@ void pciehp_handle_button_press(struct controller *ctrl)
ctrl_info(ctrl, "Slot(%s) Powering on due to button press\n", ctrl_info(ctrl, "Slot(%s) Powering on due to button press\n",
slot_name(ctrl)); slot_name(ctrl));
} }
/* blink green LED and turn off amber */ /* blink power indicator and turn off attention */
pciehp_green_led_blink(ctrl); pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_BLINK,
pciehp_set_attention_status(ctrl, 0); PCI_EXP_SLTCTL_ATTN_IND_OFF);
schedule_delayed_work(&ctrl->button_work, 5 * HZ); schedule_delayed_work(&ctrl->button_work, 5 * HZ);
break; break;
case BLINKINGOFF_STATE: case BLINKINGOFF_STATE:
...@@ -187,12 +191,13 @@ void pciehp_handle_button_press(struct controller *ctrl) ...@@ -187,12 +191,13 @@ void pciehp_handle_button_press(struct controller *ctrl)
cancel_delayed_work(&ctrl->button_work); cancel_delayed_work(&ctrl->button_work);
if (ctrl->state == BLINKINGOFF_STATE) { if (ctrl->state == BLINKINGOFF_STATE) {
ctrl->state = ON_STATE; ctrl->state = ON_STATE;
pciehp_green_led_on(ctrl); pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_ON,
PCI_EXP_SLTCTL_ATTN_IND_OFF);
} else { } else {
ctrl->state = OFF_STATE; ctrl->state = OFF_STATE;
pciehp_green_led_off(ctrl); pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF,
PCI_EXP_SLTCTL_ATTN_IND_OFF);
} }
pciehp_set_attention_status(ctrl, 0);
ctrl_info(ctrl, "Slot(%s): Action canceled due to button press\n", ctrl_info(ctrl, "Slot(%s): Action canceled due to button press\n",
slot_name(ctrl)); slot_name(ctrl));
break; break;
...@@ -310,7 +315,9 @@ static int pciehp_enable_slot(struct controller *ctrl) ...@@ -310,7 +315,9 @@ static int pciehp_enable_slot(struct controller *ctrl)
pm_runtime_get_sync(&ctrl->pcie->port->dev); pm_runtime_get_sync(&ctrl->pcie->port->dev);
ret = __pciehp_enable_slot(ctrl); ret = __pciehp_enable_slot(ctrl);
if (ret && ATTN_BUTTN(ctrl)) if (ret && ATTN_BUTTN(ctrl))
pciehp_green_led_off(ctrl); /* may be blinking */ /* may be blinking */
pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF,
INDICATOR_NOOP);
pm_runtime_put(&ctrl->pcie->port->dev); pm_runtime_put(&ctrl->pcie->port->dev);
mutex_lock(&ctrl->state_lock); mutex_lock(&ctrl->state_lock);
......
...@@ -418,65 +418,40 @@ int pciehp_set_raw_indicator_status(struct hotplug_slot *hotplug_slot, ...@@ -418,65 +418,40 @@ int pciehp_set_raw_indicator_status(struct hotplug_slot *hotplug_slot,
return 0; return 0;
} }
void pciehp_set_attention_status(struct controller *ctrl, u8 value) /**
* pciehp_set_indicators() - set attention indicator, power indicator, or both
* @ctrl: PCIe hotplug controller
* @pwr: one of:
* PCI_EXP_SLTCTL_PWR_IND_ON
* PCI_EXP_SLTCTL_PWR_IND_BLINK
* PCI_EXP_SLTCTL_PWR_IND_OFF
* @attn: one of:
* PCI_EXP_SLTCTL_ATTN_IND_ON
* PCI_EXP_SLTCTL_ATTN_IND_BLINK
* PCI_EXP_SLTCTL_ATTN_IND_OFF
*
* Either @pwr or @attn can also be INDICATOR_NOOP to leave that indicator
* unchanged.
*/
void pciehp_set_indicators(struct controller *ctrl, int pwr, int attn)
{ {
u16 slot_cmd; u16 cmd = 0, mask = 0;
if (!ATTN_LED(ctrl)) if (PWR_LED(ctrl) && pwr != INDICATOR_NOOP) {
return; cmd |= (pwr & PCI_EXP_SLTCTL_PIC);
mask |= PCI_EXP_SLTCTL_PIC;
switch (value) {
case 0: /* turn off */
slot_cmd = PCI_EXP_SLTCTL_ATTN_IND_OFF;
break;
case 1: /* turn on */
slot_cmd = PCI_EXP_SLTCTL_ATTN_IND_ON;
break;
case 2: /* turn blink */
slot_cmd = PCI_EXP_SLTCTL_ATTN_IND_BLINK;
break;
default:
return;
} }
pcie_write_cmd_nowait(ctrl, slot_cmd, PCI_EXP_SLTCTL_AIC);
ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
}
void pciehp_green_led_on(struct controller *ctrl)
{
if (!PWR_LED(ctrl))
return;
pcie_write_cmd_nowait(ctrl, PCI_EXP_SLTCTL_PWR_IND_ON,
PCI_EXP_SLTCTL_PIC);
ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL,
PCI_EXP_SLTCTL_PWR_IND_ON);
}
void pciehp_green_led_off(struct controller *ctrl) if (ATTN_LED(ctrl) && attn != INDICATOR_NOOP) {
{ cmd |= (attn & PCI_EXP_SLTCTL_AIC);
if (!PWR_LED(ctrl)) mask |= PCI_EXP_SLTCTL_AIC;
return; }
pcie_write_cmd_nowait(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF,
PCI_EXP_SLTCTL_PIC);
ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL,
PCI_EXP_SLTCTL_PWR_IND_OFF);
}
void pciehp_green_led_blink(struct controller *ctrl)
{
if (!PWR_LED(ctrl))
return;
pcie_write_cmd_nowait(ctrl, PCI_EXP_SLTCTL_PWR_IND_BLINK, if (cmd) {
PCI_EXP_SLTCTL_PIC); pcie_write_cmd_nowait(ctrl, cmd, mask);
ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, cmd);
PCI_EXP_SLTCTL_PWR_IND_BLINK); }
} }
int pciehp_power_on_slot(struct controller *ctrl) int pciehp_power_on_slot(struct controller *ctrl)
...@@ -638,8 +613,8 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id) ...@@ -638,8 +613,8 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id)
if ((events & PCI_EXP_SLTSTA_PFD) && !ctrl->power_fault_detected) { if ((events & PCI_EXP_SLTSTA_PFD) && !ctrl->power_fault_detected) {
ctrl->power_fault_detected = 1; ctrl->power_fault_detected = 1;
ctrl_err(ctrl, "Slot(%s): Power fault\n", slot_name(ctrl)); ctrl_err(ctrl, "Slot(%s): Power fault\n", slot_name(ctrl));
pciehp_set_attention_status(ctrl, 1); pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF,
pciehp_green_led_off(ctrl); PCI_EXP_SLTCTL_ATTN_IND_ON);
} }
/* /*
......
...@@ -591,6 +591,7 @@ ...@@ -591,6 +591,7 @@
#define PCI_EXP_SLTCTL_CCIE 0x0010 /* Command Completed Interrupt Enable */ #define PCI_EXP_SLTCTL_CCIE 0x0010 /* Command Completed Interrupt Enable */
#define PCI_EXP_SLTCTL_HPIE 0x0020 /* Hot-Plug Interrupt Enable */ #define PCI_EXP_SLTCTL_HPIE 0x0020 /* Hot-Plug Interrupt Enable */
#define PCI_EXP_SLTCTL_AIC 0x00c0 /* Attention Indicator Control */ #define PCI_EXP_SLTCTL_AIC 0x00c0 /* Attention Indicator Control */
#define PCI_EXP_SLTCTL_ATTN_IND_SHIFT 6 /* Attention Indicator shift */
#define PCI_EXP_SLTCTL_ATTN_IND_ON 0x0040 /* Attention Indicator on */ #define PCI_EXP_SLTCTL_ATTN_IND_ON 0x0040 /* Attention Indicator on */
#define PCI_EXP_SLTCTL_ATTN_IND_BLINK 0x0080 /* Attention Indicator blinking */ #define PCI_EXP_SLTCTL_ATTN_IND_BLINK 0x0080 /* Attention Indicator blinking */
#define PCI_EXP_SLTCTL_ATTN_IND_OFF 0x00c0 /* Attention Indicator off */ #define PCI_EXP_SLTCTL_ATTN_IND_OFF 0x00c0 /* Attention Indicator off */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment