linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Ashok Raj <ashok.raj@intel.com>
To: Lukas Wunner <lukas@wunner.de>, Bjorn Helgaas <bhelgaas@google.com>
Cc: Ashok Raj <ashok.raj@intel.com>,
	linux-pci@vger.kernel.org,
	Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>,
	linux-kernel@vger.kernel.org
Subject: [Patch v2 1/1] PCI: pciehp: Add support for handling MRL events
Date: Sat, 21 Nov 2020 17:42:03 -0800	[thread overview]
Message-ID: <20201122014203.4706-1-ashok.raj@intel.com> (raw)

When Mechanical Retention Lock (MRL) is present, Linux doesn't process
those change events.

Support for these can be found starting Icelake Server.

The following changes need to be enabled when MRL is present.

1. Subscribe to MRL change events in SlotControl.
2. When MRL is closed,
   - If there is no ATTN button, then POWER on the slot.
   - If there is ATTN button, and an MRL event pending, ignore
     Presence Detect. Since we want ATTN button to drive the
     hotplug event.
   - If currently slot is powered on, but MRL is open,
     PCIe Base Spec 5.0 Chapter 6.7.1.3 states.
     If an MRL Sensor is implemented without a corresponding
     MRL Sensor input on the Hot-Plug Controller, it is recommended
     that the MRL Sensor be routed to power fault input of the Hot-Plug
     Controller. This allows an active adapter to be powered off when the
     MRL is opened."

     This seems to suggest that the slot should be brought
     down as soon as MRL is opened.

Signed-off-by: Ashok Raj <ashok.raj@intel.com>
Co-developed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
---
Changes since v1:
- Changes suggested by Lucas Wunner
  https://lore.kernel.org/linux-pci/20201119223749.GA103783@otc-nc-03/T/#m1f661ae901e7dedad73dea370bb63abd52c610eb
  - Consolidate MRL handling in pciehp_handle_presence_or_link_change()
  - Added helped latch_closed()
  - Add comments why MRL open should function as hot-remove.
  - Don't nuke PDC, it might mask a button PUSH synthesized event after 5
    secs.
- Bjorn: Fix Subject to be consistent with other commits.
---
 drivers/pci/hotplug/pciehp_ctrl.c | 36 +++++++++++++++++++++++++++++++++++-
 drivers/pci/hotplug/pciehp_hpc.c  | 14 ++++++++++++--
 2 files changed, 47 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index 9f85815b4f53..aa8b187ff769 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -224,9 +224,22 @@ void pciehp_handle_disable_request(struct controller *ctrl)
 	ctrl->request_result = pciehp_disable_slot(ctrl, SAFE_REMOVAL);
 }
 
+static bool latch_closed(struct controller *ctrl)
+{
+	u8 getstatus = 0;
+
+	if (!MRL_SENS(ctrl))
+		return true;
+
+	pciehp_get_latch_status(ctrl, &getstatus);
+
+	return (getstatus == 0 ? true : false);
+}
+
 void pciehp_handle_presence_or_link_change(struct controller *ctrl, u32 events)
 {
 	int present, link_active;
+	u8 getstatus = 0;
 
 	/*
 	 * If the slot is on and presence or link has changed, turn it off.
@@ -246,6 +259,20 @@ void pciehp_handle_presence_or_link_change(struct controller *ctrl, u32 events)
 		if (events & PCI_EXP_SLTSTA_PDC)
 			ctrl_info(ctrl, "Slot(%s): Card not present\n",
 				  slot_name(ctrl));
+		if (events & PCI_EXP_SLTSTA_MRLSC)
+			ctrl_info(ctrl, "Slot(%s): Latch %s\n",
+				  slot_name(ctrl), getstatus ? "Open" : "Closed");
+		/*
+		 * PCIe Base Spec 5.0 Chapter 6.7.1.3 states.
+		 *
+		 * If an MRL Sensor is implemented without a corresponding MRL Sensor input
+		 * on the Hot-Plug Controller, it is recommended that the MRL Sensor be
+		 * routed to power fault input of the Hot-Plug Controller.
+		 * This allows an active adapter to be powered off when the MRL is opened."
+		 *
+		 * This seems to suggest that the slot should be brought down as soon as MRL
+		 * is opened.
+		 */
 		pciehp_disable_slot(ctrl, SURPRISE_REMOVAL);
 		break;
 	default:
@@ -257,7 +284,7 @@ void pciehp_handle_presence_or_link_change(struct controller *ctrl, u32 events)
 	mutex_lock(&ctrl->state_lock);
 	present = pciehp_card_present(ctrl);
 	link_active = pciehp_check_link_active(ctrl);
-	if (present <= 0 && link_active <= 0) {
+	if ((present <= 0 && link_active <= 0) || !latch_closed(ctrl)) {
 		mutex_unlock(&ctrl->state_lock);
 		return;
 	}
@@ -275,6 +302,13 @@ void pciehp_handle_presence_or_link_change(struct controller *ctrl, u32 events)
 		if (link_active)
 			ctrl_info(ctrl, "Slot(%s): Link Up\n",
 				  slot_name(ctrl));
+		/*
+		 * If slot is closed && ATTN button exists
+		 * don't continue, let the ATTN button
+		 * drive the hot-plug
+		 */
+		if (((events & PCI_EXP_SLTSTA_MRLSC) && ATTN_BUTTN(ctrl)))
+			return;
 		ctrl->request_result = pciehp_enable_slot(ctrl);
 		break;
 	default:
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 53433b37e181..7cfa27bcf951 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -605,7 +605,7 @@ static irqreturn_t pciehp_isr(int irq, void *dev_id)
 	 */
 	status &= PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD |
 		  PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_CC |
-		  PCI_EXP_SLTSTA_DLLSC;
+		  PCI_EXP_SLTSTA_DLLSC | PCI_EXP_SLTSTA_MRLSC;
 
 	/*
 	 * If we've already reported a power fault, don't report it again
@@ -710,8 +710,10 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id)
 	down_read(&ctrl->reset_lock);
 	if (events & DISABLE_SLOT)
 		pciehp_handle_disable_request(ctrl);
-	else if (events & (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC))
+	else if (events & (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC |
+			   PCI_EXP_SLTSTA_MRLSC))
 		pciehp_handle_presence_or_link_change(ctrl, events);
+
 	up_read(&ctrl->reset_lock);
 
 	ret = IRQ_HANDLED;
@@ -768,6 +770,14 @@ static void pcie_enable_notification(struct controller *ctrl)
 		cmd |= PCI_EXP_SLTCTL_ABPE;
 	else
 		cmd |= PCI_EXP_SLTCTL_PDCE;
+
+	/*
+	 * If MRL sensor is present, then subscribe for MRL
+	 * Changes to be notified as well.
+	 */
+	if (MRL_SENS(ctrl))
+		cmd |= PCI_EXP_SLTCTL_MRLSCE;
+
 	if (!pciehp_poll_mode)
 		cmd |= PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE;
 
-- 
2.7.4


             reply	other threads:[~2020-11-22  1:42 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-22  1:42 Ashok Raj [this message]
2020-11-22  9:08 ` [Patch v2 1/1] PCI: pciehp: Add support for handling MRL events Lukas Wunner
2020-11-25 22:40   ` Raj, Ashok
2020-12-03 22:51   ` Raj, Ashok
2020-12-10 20:57     ` Lukas Wunner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201122014203.4706-1-ashok.raj@intel.com \
    --to=ashok.raj@intel.com \
    --cc=bhelgaas@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=lukas@wunner.de \
    --cc=sathyanarayanan.kuppuswamy@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).