linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 0/4] Simplify PCIe hotplug indicator control
@ 2019-09-03 11:10 Denis Efremov
  2019-09-03 11:10 ` [PATCH v4 1/4] PCI: pciehp: Add pciehp_set_indicators() to jointly set LED indicators Denis Efremov
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Denis Efremov @ 2019-09-03 11:10 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Denis Efremov, Lukas Wunner, linux-pci,
	Kuppuswamy Sathyanarayanan, Oliver O'Halloran, linux-kernel

PCIe defines two optional hotplug indicators: a Power indicator and an
Attention indicator. Both are controlled by the same register, and each
can be on, off or blinking. The current interfaces
(pciehp_green_led_{on,off,blink}() and pciehp_set_attention_status()) are
non-uniform and require two register writes in many cases where we could
do one.

This patchset introduces the new function pciehp_set_indicators(). It
allows one to set two indicators with a single register write. All
calls to previous interfaces (pciehp_green_led_* and
pciehp_set_attention_status()) are replaced with a new one. Thus,
the amount of duplicated code for setting indicators is reduced.

Changes in v4:
  - Changed the inputs validation in pciehp_set_indicators()
  - Moved PCI_EXP_SLTCTL_ATTN_IND_NONE, PCI_EXP_SLTCTL_PWR_IND_NONE
    to drivers/pci/hotplug/pciehp.h and set to -1 for not interfering
    with reserved values in the PCIe Base spec
  - Added set_power_indicator define

Changes in v3:
  - Changed pciehp_set_indicators() to work with existing
    PCI_EXP_SLTCTL_* macros
  - Reworked the inputs validation in pciehp_set_indicators()
  - Removed pciehp_set_attention_status() and pciehp_green_led_*()
    completely

Denis Efremov (4):
  PCI: pciehp: Add pciehp_set_indicators() to jointly set LED indicators
  PCI: pciehp: Switch LED indicators with a single write
  PCI: pciehp: Remove pciehp_set_attention_status()
  PCI: pciehp: Remove pciehp_green_led_{on,off,blink}()

 drivers/pci/hotplug/pciehp.h      | 12 ++++--
 drivers/pci/hotplug/pciehp_core.c |  7 ++-
 drivers/pci/hotplug/pciehp_ctrl.c | 26 +++++------
 drivers/pci/hotplug/pciehp_hpc.c  | 72 +++++++------------------------
 include/uapi/linux/pci_regs.h     |  1 +
 5 files changed, 45 insertions(+), 73 deletions(-)

-- 
2.21.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v4 1/4] PCI: pciehp: Add pciehp_set_indicators() to jointly set LED indicators
  2019-09-03 11:10 [PATCH v4 0/4] Simplify PCIe hotplug indicator control Denis Efremov
@ 2019-09-03 11:10 ` Denis Efremov
  2019-09-03 11:10 ` [PATCH v4 2/4] PCI: pciehp: Switch LED indicators with a single write Denis Efremov
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Denis Efremov @ 2019-09-03 11:10 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Denis Efremov, Lukas Wunner, linux-pci,
	Kuppuswamy Sathyanarayanan, Oliver O'Halloran, linux-kernel

Add pciehp_set_indicators() to set power and attention indicators with a
single register write. Thus, avoiding waiting twice for Command Complete.

Signed-off-by: Denis Efremov <efremov@linux.com>
---
 drivers/pci/hotplug/pciehp.h     |  5 +++++
 drivers/pci/hotplug/pciehp_hpc.c | 21 +++++++++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 8c51a04b8083..0214e09e91a4 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -167,6 +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);
 
+/* Special values for leaving indicators unchanged */
+#define PCI_EXP_SLTCTL_ATTN_IND_NONE -1 /* Attention Indicator noop */
+#define PCI_EXP_SLTCTL_PWR_IND_NONE  -1 /* Power Indicator noop */
+void pciehp_set_indicators(struct controller *ctrl, int pwr, int attn);
+
 void pciehp_set_attention_status(struct controller *ctrl, u8 status);
 void pciehp_get_latch_status(struct controller *ctrl, u8 *status);
 int pciehp_query_power_fault(struct controller *ctrl);
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index bd990e3371e3..4d0fe39ef049 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -443,6 +443,27 @@ void pciehp_set_attention_status(struct controller *ctrl, u8 value)
 		 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
 }
 
+void pciehp_set_indicators(struct controller *ctrl, int pwr, int attn)
+{
+	u16 cmd = 0, mask = 0;
+
+	if (PWR_LED(ctrl) && pwr > 0) {
+		cmd |= pwr;
+		mask |= PCI_EXP_SLTCTL_PIC;
+	}
+
+	if (ATTN_LED(ctrl) && attn > 0) {
+		cmd |= attn;
+		mask |= PCI_EXP_SLTCTL_AIC;
+	}
+
+	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);
+	}
+}
+
 void pciehp_green_led_on(struct controller *ctrl)
 {
 	if (!PWR_LED(ctrl))
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v4 2/4] PCI: pciehp: Switch LED indicators with a single write
  2019-09-03 11:10 [PATCH v4 0/4] Simplify PCIe hotplug indicator control Denis Efremov
  2019-09-03 11:10 ` [PATCH v4 1/4] PCI: pciehp: Add pciehp_set_indicators() to jointly set LED indicators Denis Efremov
@ 2019-09-03 11:10 ` Denis Efremov
  2019-09-03 11:10 ` [PATCH v4 3/4] PCI: pciehp: Remove pciehp_set_attention_status() Denis Efremov
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Denis Efremov @ 2019-09-03 11:10 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Denis Efremov, Lukas Wunner, linux-pci,
	Kuppuswamy Sathyanarayanan, Oliver O'Halloran, linux-kernel

This patch replaces all consecutive switches of power and attention
indicators with pciehp_set_indicators() call. Thus, performing only
single write to a register.

Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Reviewed-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Denis Efremov <efremov@linux.com>
---
 drivers/pci/hotplug/pciehp_ctrl.c | 19 ++++++++++---------
 drivers/pci/hotplug/pciehp_hpc.c  |  4 ++--
 2 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index 631ced0ab28a..232f7bfcfce9 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -42,8 +42,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);
 }
 
 /**
@@ -90,8 +90,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:
@@ -172,8 +172,8 @@ void pciehp_handle_button_press(struct controller *ctrl)
 				  slot_name(ctrl));
 		}
 		/* blink green LED and turn off amber */
-		pciehp_green_led_blink(ctrl);
-		pciehp_set_attention_status(ctrl, 0);
+		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 +187,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;
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 4d0fe39ef049..d2c60d844d30 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -659,8 +659,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);
 	}
 
 	/*
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v4 3/4] PCI: pciehp: Remove pciehp_set_attention_status()
  2019-09-03 11:10 [PATCH v4 0/4] Simplify PCIe hotplug indicator control Denis Efremov
  2019-09-03 11:10 ` [PATCH v4 1/4] PCI: pciehp: Add pciehp_set_indicators() to jointly set LED indicators Denis Efremov
  2019-09-03 11:10 ` [PATCH v4 2/4] PCI: pciehp: Switch LED indicators with a single write Denis Efremov
@ 2019-09-03 11:10 ` Denis Efremov
  2019-09-03 11:10 ` [PATCH v4 4/4] PCI: pciehp: Remove pciehp_green_led_{on,off,blink}() Denis Efremov
  2019-09-05 21:01 ` [PATCH v4 0/4] Simplify PCIe hotplug indicator control Bjorn Helgaas
  4 siblings, 0 replies; 8+ messages in thread
From: Denis Efremov @ 2019-09-03 11:10 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Denis Efremov, Lukas Wunner, linux-pci,
	Kuppuswamy Sathyanarayanan, Oliver O'Halloran, linux-kernel

Remove pciehp_set_attention_status() and use pciehp_set_indicators()
instead, since the code is mostly the same.

Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Signed-off-by: Denis Efremov <efremov@linux.com>
---
 drivers/pci/hotplug/pciehp.h      |  1 -
 drivers/pci/hotplug/pciehp_core.c |  7 ++++++-
 drivers/pci/hotplug/pciehp_hpc.c  | 25 -------------------------
 include/uapi/linux/pci_regs.h     |  1 +
 4 files changed, 7 insertions(+), 27 deletions(-)

diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 0214e09e91a4..cf59f70a33cc 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -172,7 +172,6 @@ void pciehp_get_power_status(struct controller *ctrl, u8 *status);
 #define PCI_EXP_SLTCTL_PWR_IND_NONE  -1 /* Power Indicator noop */
 void pciehp_set_indicators(struct controller *ctrl, int pwr, int attn);
 
-void pciehp_set_attention_status(struct controller *ctrl, u8 status);
 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);
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 6ad0d86762cb..7a86ea90ed94 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -102,8 +102,13 @@ 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, PCI_EXP_SLTCTL_PWR_IND_NONE, status);
 	pci_config_pm_runtime_put(pdev);
 	return 0;
 }
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index d2c60d844d30..eeac2e704c75 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -418,31 +418,6 @@ int pciehp_set_raw_indicator_status(struct hotplug_slot *hotplug_slot,
 	return 0;
 }
 
-void pciehp_set_attention_status(struct controller *ctrl, u8 value)
-{
-	u16 slot_cmd;
-
-	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;
-	}
-	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_set_indicators(struct controller *ctrl, int pwr, int attn)
 {
 	u16 cmd = 0, mask = 0;
diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h
index f28e562d7ca8..de3e58afc564 100644
--- a/include/uapi/linux/pci_regs.h
+++ b/include/uapi/linux/pci_regs.h
@@ -591,6 +591,7 @@
 #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 */
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v4 4/4] PCI: pciehp: Remove pciehp_green_led_{on,off,blink}()
  2019-09-03 11:10 [PATCH v4 0/4] Simplify PCIe hotplug indicator control Denis Efremov
                   ` (2 preceding siblings ...)
  2019-09-03 11:10 ` [PATCH v4 3/4] PCI: pciehp: Remove pciehp_set_attention_status() Denis Efremov
@ 2019-09-03 11:10 ` Denis Efremov
  2019-09-05 21:01 ` [PATCH v4 0/4] Simplify PCIe hotplug indicator control Bjorn Helgaas
  4 siblings, 0 replies; 8+ messages in thread
From: Denis Efremov @ 2019-09-03 11:10 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Denis Efremov, Lukas Wunner, linux-pci,
	Kuppuswamy Sathyanarayanan, Oliver O'Halloran, linux-kernel

Remove pciehp_green_led_{on,off,blink}() and use pciehp_set_indicators()
instead, since the code is mostly the same.

Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Signed-off-by: Denis Efremov <efremov@linux.com>
---
 drivers/pci/hotplug/pciehp.h      |  6 +++---
 drivers/pci/hotplug/pciehp_ctrl.c |  7 +++---
 drivers/pci/hotplug/pciehp_hpc.c  | 36 -------------------------------
 3 files changed, 7 insertions(+), 42 deletions(-)

diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index cf59f70a33cc..dcbf790b7508 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -174,9 +174,6 @@ 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);
@@ -190,6 +187,9 @@ int pciehp_get_attention_status(struct hotplug_slot *hotplug_slot, u8 *status);
 int pciehp_set_raw_indicator_status(struct hotplug_slot *h_slot, u8 status);
 int pciehp_get_raw_indicator_status(struct hotplug_slot *h_slot, u8 *status);
 
+#define set_power_indicator(ctrl, x) \
+	pciehp_set_indicators(ctrl, (x), PCI_EXP_SLTCTL_ATTN_IND_NONE)
+
 static inline const char *slot_name(struct controller *ctrl)
 {
 	return hotplug_slot_name(&ctrl->hotplug_slot);
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index 232f7bfcfce9..d0f55f695770 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -65,7 +65,7 @@ static int board_added(struct controller *ctrl)
 			return retval;
 	}
 
-	pciehp_green_led_blink(ctrl);
+	set_power_indicator(ctrl, PCI_EXP_SLTCTL_PWR_IND_BLINK);
 
 	/* Check link training status */
 	retval = pciehp_check_link_status(ctrl);
@@ -124,7 +124,7 @@ static void remove_board(struct controller *ctrl, bool safe_removal)
 	}
 
 	/* turn off Green LED */
-	pciehp_green_led_off(ctrl);
+	set_power_indicator(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF);
 }
 
 static int pciehp_enable_slot(struct controller *ctrl);
@@ -311,7 +311,8 @@ 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 */
+		set_power_indicator(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF);
 	pm_runtime_put(&ctrl->pcie->port->dev);
 
 	mutex_lock(&ctrl->state_lock);
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index eeac2e704c75..9fd8f99132bb 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -439,42 +439,6 @@ void pciehp_set_indicators(struct controller *ctrl, int pwr, int attn)
 	}
 }
 
-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;
-
-	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);
-}
-
 int pciehp_power_on_slot(struct controller *ctrl)
 {
 	struct pci_dev *pdev = ctrl_dev(ctrl);
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v4 0/4] Simplify PCIe hotplug indicator control
  2019-09-03 11:10 [PATCH v4 0/4] Simplify PCIe hotplug indicator control Denis Efremov
                   ` (3 preceding siblings ...)
  2019-09-03 11:10 ` [PATCH v4 4/4] PCI: pciehp: Remove pciehp_green_led_{on,off,blink}() Denis Efremov
@ 2019-09-05 21:01 ` Bjorn Helgaas
  2019-09-05 21:16   ` Denis Efremov
  2019-09-05 22:03   ` Lukas Wunner
  4 siblings, 2 replies; 8+ messages in thread
From: Bjorn Helgaas @ 2019-09-05 21:01 UTC (permalink / raw)
  To: Denis Efremov
  Cc: Lukas Wunner, linux-pci, Kuppuswamy Sathyanarayanan,
	Oliver O'Halloran, linux-kernel

On Tue, Sep 03, 2019 at 02:10:17PM +0300, Denis Efremov wrote:
> PCIe defines two optional hotplug indicators: a Power indicator and an
> Attention indicator. Both are controlled by the same register, and each
> can be on, off or blinking. The current interfaces
> (pciehp_green_led_{on,off,blink}() and pciehp_set_attention_status()) are
> non-uniform and require two register writes in many cases where we could
> do one.
> 
> This patchset introduces the new function pciehp_set_indicators(). It
> allows one to set two indicators with a single register write. All
> calls to previous interfaces (pciehp_green_led_* and
> pciehp_set_attention_status()) are replaced with a new one. Thus,
> the amount of duplicated code for setting indicators is reduced.
> 
> Changes in v4:
>   - Changed the inputs validation in pciehp_set_indicators()
>   - Moved PCI_EXP_SLTCTL_ATTN_IND_NONE, PCI_EXP_SLTCTL_PWR_IND_NONE
>     to drivers/pci/hotplug/pciehp.h and set to -1 for not interfering
>     with reserved values in the PCIe Base spec
>   - Added set_power_indicator define
> 
> Changes in v3:
>   - Changed pciehp_set_indicators() to work with existing
>     PCI_EXP_SLTCTL_* macros
>   - Reworked the inputs validation in pciehp_set_indicators()
>   - Removed pciehp_set_attention_status() and pciehp_green_led_*()
>     completely
> 
> Denis Efremov (4):
>   PCI: pciehp: Add pciehp_set_indicators() to jointly set LED indicators
>   PCI: pciehp: Switch LED indicators with a single write
>   PCI: pciehp: Remove pciehp_set_attention_status()
>   PCI: pciehp: Remove pciehp_green_led_{on,off,blink}()
> 
>  drivers/pci/hotplug/pciehp.h      | 12 ++++--
>  drivers/pci/hotplug/pciehp_core.c |  7 ++-
>  drivers/pci/hotplug/pciehp_ctrl.c | 26 +++++------
>  drivers/pci/hotplug/pciehp_hpc.c  | 72 +++++++------------------------
>  include/uapi/linux/pci_regs.h     |  1 +
>  5 files changed, 45 insertions(+), 73 deletions(-)

Thanks, Denis, I applied these to pci/pciehp for v5.4.  I think this
is a great improvement.

I tweaked a few things:

  - Updated comments to refer to "Power" intead of "green",
    "Attention" instead of "amber", and "Indicator" instead of "LED".

  - Replaced PCI_EXP_SLTCTL_ATTN_IND_NONE and
    PCI_EXP_SLTCTL_PWR_IND_NONE with INDICATOR_NOOP because I didn't
    want them to look like definitions from the spec.

  - Dropped set_power_indicator().  It does make things locally easier
    to read, but I think the overall benefit of having fewer
    interfaces outweighs that.

The interdiff from your v4 is below.  Let me know if I broke anything.


diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index dcbf790b7508..654c972b8ea0 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -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,9 +167,7 @@ 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);
 
-/* Special values for leaving indicators unchanged */
-#define PCI_EXP_SLTCTL_ATTN_IND_NONE -1 /* Attention Indicator noop */
-#define PCI_EXP_SLTCTL_PWR_IND_NONE  -1 /* Power Indicator noop */
+#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);
@@ -187,9 +185,6 @@ int pciehp_get_attention_status(struct hotplug_slot *hotplug_slot, u8 *status);
 int pciehp_set_raw_indicator_status(struct hotplug_slot *h_slot, u8 status);
 int pciehp_get_raw_indicator_status(struct hotplug_slot *h_slot, u8 *status);
 
-#define set_power_indicator(ctrl, x) \
-	pciehp_set_indicators(ctrl, (x), PCI_EXP_SLTCTL_ATTN_IND_NONE)
-
 static inline const char *slot_name(struct controller *ctrl)
 {
 	return hotplug_slot_name(&ctrl->hotplug_slot);
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 7a86ea90ed94..b3122c151b80 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -95,7 +95,7 @@ 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)
 {
@@ -108,7 +108,7 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
 		status = PCI_EXP_SLTCTL_ATTN_IND_OFF;
 
 	pci_config_pm_runtime_get(pdev);
-	pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_NONE, status);
+	pciehp_set_indicators(ctrl, INDICATOR_NOOP, status);
 	pci_config_pm_runtime_put(pdev);
 	return 0;
 }
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index d0f55f695770..21af7b16d7a4 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -30,7 +30,10 @@
 
 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);
 
@@ -65,7 +68,8 @@ static int board_added(struct controller *ctrl)
 			return retval;
 	}
 
-	set_power_indicator(ctrl, PCI_EXP_SLTCTL_PWR_IND_BLINK);
+	pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_BLINK,
+			      INDICATOR_NOOP);
 
 	/* Check link training status */
 	retval = pciehp_check_link_status(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
  * @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 */
-	set_power_indicator(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF);
+	pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF,
+			      INDICATOR_NOOP);
 }
 
 static int pciehp_enable_slot(struct controller *ctrl);
@@ -171,7 +175,7 @@ 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 */
+		/* 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);
@@ -312,7 +316,8 @@ static int pciehp_enable_slot(struct controller *ctrl)
 	ret = __pciehp_enable_slot(ctrl);
 	if (ret && ATTN_BUTTN(ctrl))
 		/* may be blinking */
-		set_power_indicator(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF);
+		pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF,
+				      INDICATOR_NOOP);
 	pm_runtime_put(&ctrl->pcie->port->dev);
 
 	mutex_lock(&ctrl->state_lock);
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 9fd8f99132bb..1a522c1c4177 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -418,17 +418,32 @@ int pciehp_set_raw_indicator_status(struct hotplug_slot *hotplug_slot,
 	return 0;
 }
 
+/**
+ * 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 cmd = 0, mask = 0;
 
-	if (PWR_LED(ctrl) && pwr > 0) {
-		cmd |= pwr;
+	if (PWR_LED(ctrl) && pwr != INDICATOR_NOOP) {
+		cmd |= (pwr & PCI_EXP_SLTCTL_PIC);
 		mask |= PCI_EXP_SLTCTL_PIC;
 	}
 
-	if (ATTN_LED(ctrl) && attn > 0) {
-		cmd |= attn;
+	if (ATTN_LED(ctrl) && attn != INDICATOR_NOOP) {
+		cmd |= (attn & PCI_EXP_SLTCTL_AIC);
 		mask |= PCI_EXP_SLTCTL_AIC;
 	}
 

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v4 0/4] Simplify PCIe hotplug indicator control
  2019-09-05 21:01 ` [PATCH v4 0/4] Simplify PCIe hotplug indicator control Bjorn Helgaas
@ 2019-09-05 21:16   ` Denis Efremov
  2019-09-05 22:03   ` Lukas Wunner
  1 sibling, 0 replies; 8+ messages in thread
From: Denis Efremov @ 2019-09-05 21:16 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Lukas Wunner, linux-pci, Kuppuswamy Sathyanarayanan,
	Oliver O'Halloran, linux-kernel



On 06.09.2019 00:01, Bjorn Helgaas wrote:
> On Tue, Sep 03, 2019 at 02:10:17PM +0300, Denis Efremov wrote:
>> PCIe defines two optional hotplug indicators: a Power indicator and an
>> Attention indicator. Both are controlled by the same register, and each
>> can be on, off or blinking. The current interfaces
>> (pciehp_green_led_{on,off,blink}() and pciehp_set_attention_status()) are
>> non-uniform and require two register writes in many cases where we could
>> do one.
>>
>> This patchset introduces the new function pciehp_set_indicators(). It
>> allows one to set two indicators with a single register write. All
>> calls to previous interfaces (pciehp_green_led_* and
>> pciehp_set_attention_status()) are replaced with a new one. Thus,
>> the amount of duplicated code for setting indicators is reduced.
>>
>> Changes in v4:
>>   - Changed the inputs validation in pciehp_set_indicators()
>>   - Moved PCI_EXP_SLTCTL_ATTN_IND_NONE, PCI_EXP_SLTCTL_PWR_IND_NONE
>>     to drivers/pci/hotplug/pciehp.h and set to -1 for not interfering
>>     with reserved values in the PCIe Base spec
>>   - Added set_power_indicator define
>>
>> Changes in v3:
>>   - Changed pciehp_set_indicators() to work with existing
>>     PCI_EXP_SLTCTL_* macros
>>   - Reworked the inputs validation in pciehp_set_indicators()
>>   - Removed pciehp_set_attention_status() and pciehp_green_led_*()
>>     completely
>>
>> Denis Efremov (4):
>>   PCI: pciehp: Add pciehp_set_indicators() to jointly set LED indicators
>>   PCI: pciehp: Switch LED indicators with a single write
>>   PCI: pciehp: Remove pciehp_set_attention_status()
>>   PCI: pciehp: Remove pciehp_green_led_{on,off,blink}()
>>
>>  drivers/pci/hotplug/pciehp.h      | 12 ++++--
>>  drivers/pci/hotplug/pciehp_core.c |  7 ++-
>>  drivers/pci/hotplug/pciehp_ctrl.c | 26 +++++------
>>  drivers/pci/hotplug/pciehp_hpc.c  | 72 +++++++------------------------
>>  include/uapi/linux/pci_regs.h     |  1 +
>>  5 files changed, 45 insertions(+), 73 deletions(-)
> 
> Thanks, Denis, I applied these to pci/pciehp for v5.4.  I think this
> is a great improvement.
> 
> I tweaked a few things:
> 
>   - Updated comments to refer to "Power" intead of "green",
>     "Attention" instead of "amber", and "Indicator" instead of "LED".
> 
>   - Replaced PCI_EXP_SLTCTL_ATTN_IND_NONE and
>     PCI_EXP_SLTCTL_PWR_IND_NONE with INDICATOR_NOOP because I didn't
>     want them to look like definitions from the spec.
> 
>   - Dropped set_power_indicator().  It does make things locally easier
>     to read, but I think the overall benefit of having fewer
>     interfaces outweighs that.
> 
> The interdiff from your v4 is below.  Let me know if I broke anything.

Thank you for the improvements. Looks good to me.

Regards,
Denis

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v4 0/4] Simplify PCIe hotplug indicator control
  2019-09-05 21:01 ` [PATCH v4 0/4] Simplify PCIe hotplug indicator control Bjorn Helgaas
  2019-09-05 21:16   ` Denis Efremov
@ 2019-09-05 22:03   ` Lukas Wunner
  1 sibling, 0 replies; 8+ messages in thread
From: Lukas Wunner @ 2019-09-05 22:03 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Denis Efremov, linux-pci, Kuppuswamy Sathyanarayanan,
	Oliver O'Halloran, linux-kernel

On Thu, Sep 05, 2019 at 04:01:02PM -0500, Bjorn Helgaas wrote:
>  void pciehp_set_indicators(struct controller *ctrl, int pwr, int attn)
>  {
>  	u16 cmd = 0, mask = 0;
>  
> -	if (PWR_LED(ctrl) && pwr > 0) {
> -		cmd |= pwr;
> +	if (PWR_LED(ctrl) && pwr != INDICATOR_NOOP) {
> +		cmd |= (pwr & PCI_EXP_SLTCTL_PIC);
>  		mask |= PCI_EXP_SLTCTL_PIC;
>  	}
>  
> -	if (ATTN_LED(ctrl) && attn > 0) {
> -		cmd |= attn;
> +	if (ATTN_LED(ctrl) && attn != INDICATOR_NOOP) {
> +		cmd |= (attn & PCI_EXP_SLTCTL_AIC);
>  		mask |= PCI_EXP_SLTCTL_AIC;
>  	}

There's a subtle issue here:  A value of "0" is "reserved" per PCIe r4.0,
sec 7.8.10.  Denis filtered that out, with your change it's an accepted
value.  I don't think the function ever gets called with a value of "0",
so it's not a big deal.  And maybe we don't even want to filter that
value out.  Just noting anyway.

Thanks,

Lukas

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2019-09-05 22:03 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-03 11:10 [PATCH v4 0/4] Simplify PCIe hotplug indicator control Denis Efremov
2019-09-03 11:10 ` [PATCH v4 1/4] PCI: pciehp: Add pciehp_set_indicators() to jointly set LED indicators Denis Efremov
2019-09-03 11:10 ` [PATCH v4 2/4] PCI: pciehp: Switch LED indicators with a single write Denis Efremov
2019-09-03 11:10 ` [PATCH v4 3/4] PCI: pciehp: Remove pciehp_set_attention_status() Denis Efremov
2019-09-03 11:10 ` [PATCH v4 4/4] PCI: pciehp: Remove pciehp_green_led_{on,off,blink}() Denis Efremov
2019-09-05 21:01 ` [PATCH v4 0/4] Simplify PCIe hotplug indicator control Bjorn Helgaas
2019-09-05 21:16   ` Denis Efremov
2019-09-05 22:03   ` Lukas Wunner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).