Merge branch 'pci/pciehp'
authorBjorn Helgaas <bhelgaas@google.com>
Mon, 23 Sep 2019 21:10:14 +0000 (16:10 -0500)
committerBjorn Helgaas <bhelgaas@google.com>
Mon, 23 Sep 2019 21:10:14 +0000 (16:10 -0500)
  - 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

drivers/pci/hotplug/pciehp.h
drivers/pci/hotplug/pciehp_core.c
drivers/pci/hotplug/pciehp_ctrl.c
drivers/pci/hotplug/pciehp_hpc.c
include/uapi/linux/pci_regs.h

index 8c51a04..654c972 100644 (file)
@@ -110,9 +110,9 @@ struct controller {
  *
  * @OFF_STATE: slot is powered off, no subordinate devices are enumerated
  * @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,
- *     green led is blinking
+ *     Power Indicator is blinking
  * @POWERON_STATE: slot is currently powering on
  * @POWEROFF_STATE: slot is currently powering off
  * @ON_STATE: slot is powered on, subordinate devices have been enumerated
@@ -167,12 +167,11 @@ int pciehp_power_on_slot(struct controller *ctrl);
 void pciehp_power_off_slot(struct controller *ctrl);
 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);
 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_or_link_active(struct controller *ctrl);
 int pciehp_check_link_status(struct controller *ctrl);
index 6ad0d86..b3122c1 100644 (file)
@@ -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)
 {
        struct controller *ctrl = to_ctrl(hotplug_slot);
        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);
-       pciehp_set_attention_status(ctrl, status);
+       pciehp_set_indicators(ctrl, INDICATOR_NOOP, status);
        pci_config_pm_runtime_put(pdev);
        return 0;
 }
index 631ced0..21af7b1 100644 (file)
 
 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)) {
                pciehp_power_off_slot(ctrl);
 
@@ -42,8 +45,8 @@ static void set_slot_off(struct controller *ctrl)
                msleep(1000);
        }
 
-       pciehp_green_led_off(ctrl);
-       pciehp_set_attention_status(ctrl, 1);
+       pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF,
+                             PCI_EXP_SLTCTL_ATTN_IND_ON);
 }
 
 /**
@@ -65,7 +68,8 @@ static int board_added(struct controller *ctrl)
                        return retval;
        }
 
-       pciehp_green_led_blink(ctrl);
+       pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_BLINK,
+                             INDICATOR_NOOP);
 
        /* Check link training status */
        retval = pciehp_check_link_status(ctrl);
@@ -90,8 +94,8 @@ static int board_added(struct controller *ctrl)
                }
        }
 
-       pciehp_green_led_on(ctrl);
-       pciehp_set_attention_status(ctrl, 0);
+       pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_ON,
+                             PCI_EXP_SLTCTL_ATTN_IND_OFF);
        return 0;
 
 err_exit:
@@ -100,7 +104,7 @@ err_exit:
 }
 
 /**
- * remove_board - Turns off slot and LEDs
+ * remove_board - Turn off slot and Power Indicator
  * @ctrl: PCIe hotplug controller where board is being 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)
                           &ctrl->pending_events);
        }
 
-       /* turn off Green LED */
-       pciehp_green_led_off(ctrl);
+       pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF,
+                             INDICATOR_NOOP);
 }
 
 static int pciehp_enable_slot(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",
                                  slot_name(ctrl));
                }
-               /* blink green LED and turn off amber */
-               pciehp_green_led_blink(ctrl);
-               pciehp_set_attention_status(ctrl, 0);
+               /* blink power indicator and turn off attention */
+               pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_BLINK,
+                                     PCI_EXP_SLTCTL_ATTN_IND_OFF);
                schedule_delayed_work(&ctrl->button_work, 5 * HZ);
                break;
        case BLINKINGOFF_STATE:
@@ -187,12 +191,13 @@ void pciehp_handle_button_press(struct controller *ctrl)
                cancel_delayed_work(&ctrl->button_work);
                if (ctrl->state == BLINKINGOFF_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 {
                        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",
                          slot_name(ctrl));
                break;
@@ -310,7 +315,9 @@ static int pciehp_enable_slot(struct controller *ctrl)
        pm_runtime_get_sync(&ctrl->pcie->port->dev);
        ret = __pciehp_enable_slot(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);
 
        mutex_lock(&ctrl->state_lock);
index bd990e3..1a522c1 100644 (file)
@@ -418,65 +418,40 @@ int pciehp_set_raw_indicator_status(struct hotplug_slot *hotplug_slot,
        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))
-               return;
-
-       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;
+       if (PWR_LED(ctrl) && pwr != INDICATOR_NOOP) {
+               cmd |= (pwr & PCI_EXP_SLTCTL_PIC);
+               mask |= PCI_EXP_SLTCTL_PIC;
        }
-       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 (!PWR_LED(ctrl))
-               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;
+       if (ATTN_LED(ctrl) && attn != INDICATOR_NOOP) {
+               cmd |= (attn & PCI_EXP_SLTCTL_AIC);
+               mask |= PCI_EXP_SLTCTL_AIC;
+       }
 
-       pcie_write_cmd_nowait(ctrl, PCI_EXP_SLTCTL_PWR_IND_BLINK,
-                             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_BLINK);
+       if (cmd) {
+               pcie_write_cmd_nowait(ctrl, cmd, mask);
+               ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
+                        pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, cmd);
+       }
 }
 
 int pciehp_power_on_slot(struct controller *ctrl)
@@ -638,8 +613,8 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id)
        if ((events & PCI_EXP_SLTSTA_PFD) && !ctrl->power_fault_detected) {
                ctrl->power_fault_detected = 1;
                ctrl_err(ctrl, "Slot(%s): Power fault\n", slot_name(ctrl));
-               pciehp_set_attention_status(ctrl, 1);
-               pciehp_green_led_off(ctrl);
+               pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF,
+                                     PCI_EXP_SLTCTL_ATTN_IND_ON);
        }
 
        /*
index f28e562..de3e58a 100644 (file)
 #define  PCI_EXP_SLTCTL_CCIE   0x0010  /* Command Completed 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_ATTN_IND_SHIFT 6      /* Attention Indicator shift */
 #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_OFF   0x00c0 /* Attention Indicator off */