* [PATCH v2 0/3] PCI hotplug feature
@ 2017-08-15 5:55 Oza Pawandeep
2017-08-15 5:55 ` [PATCH v2 1/3] PCI: iproc: Implement PCI hotplug support Oza Pawandeep
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Oza Pawandeep @ 2017-08-15 5:55 UTC (permalink / raw)
To: Bjorn Helgaas, Rob Herring, Mark Rutland, Ray Jui, Scott Branden,
Jon Mason, bcm-kernel-feedback-list, Oza Pawandeep,
Andy Gospodarek, linux-pci, devicetree, linux-arm-kernel,
linux-kernel, Oza Pawandeep
These patches bring in PCI hotplug support for iproc family chipsets.
It includes DT binding documentation update and, implementation in
iproc pcie RC driver.
These patch set is made on top of following patches.
[PATCH v6 2/2] PCI: iproc: add device shutdown for PCI RC
[PATCH v6 1/2] PCI: iproc: Retry request when CRS returned from EP
Changes since v2:
Addressed Rob Herring's comments.
Made generic PCI hotplug properties 'slot-pluggable' and 'prsnt-gpios'
Oza Pawandeep (3):
PCI: iproc: Implement PCI hotplug support
Documentation/devicetree: Add PCIe hotplug property
PCI: iproc: Implement optional property prsnt-gpios
.../devicetree/bindings/pci/brcm,iproc-pcie.txt | 14 +++
Documentation/devicetree/bindings/pci/pci.txt | 15 +++
drivers/pci/host/pcie-iproc-platform.c | 3 +
drivers/pci/host/pcie-iproc.c | 130 ++++++++++++++++++++-
drivers/pci/host/pcie-iproc.h | 7 ++
5 files changed, 163 insertions(+), 6 deletions(-)
--
1.9.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 1/3] PCI: iproc: Implement PCI hotplug support
2017-08-15 5:55 [PATCH v2 0/3] PCI hotplug feature Oza Pawandeep
@ 2017-08-15 5:55 ` Oza Pawandeep
2017-08-15 5:55 ` [PATCH v2 2/3] Documentation/devicetree: Add PCIe hotplug property Oza Pawandeep
[not found] ` <1502776547-30542-4-git-send-email-oza.oza@broadcom.com>
2 siblings, 0 replies; 5+ messages in thread
From: Oza Pawandeep @ 2017-08-15 5:55 UTC (permalink / raw)
To: Bjorn Helgaas, Rob Herring, Mark Rutland, Ray Jui, Scott Branden,
Jon Mason, bcm-kernel-feedback-list, Oza Pawandeep,
Andy Gospodarek, linux-pci, devicetree, linux-arm-kernel,
linux-kernel, Oza Pawandeep
This patch implements PCI hotplug support for iproc family chipsets.
iproc based SOC (e.g. Stingray) does not have hotplug controller
integrated.
Hence, standard PCI hotplug framework hooks can-not be used.
e.g. controlled power up/down of slot.
The mechanism, for e.g. Stingray has adopted for PCI hotplug is as
follows:
PCI present lines are input to GPIOs depending on the type of
connector (x2, x4, x8).
The implementation essentially takes care of following:
> Initializing hotplug irq thread.
> Detecting the endpoint device based on link state.
> Handling PERST and detecting the plugged devices.
> Ordered Hot plug-out, where User is expected
to write 1 to /sys/bus/pci/devices/<pci_dev>/remove
> Handling spurious interrupt
> Handling multiple interrupts and makes sure that card is
enumerated only once.
Signed-off-by: Oza Pawandeep <oza.oza@broadcom.com>
Reviewed-by: Ray Jui <ray.jui@broadcom.com>
diff --git a/drivers/pci/host/pcie-iproc-platform.c b/drivers/pci/host/pcie-iproc-platform.c
index 9512960..e1eb141 100644
--- a/drivers/pci/host/pcie-iproc-platform.c
+++ b/drivers/pci/host/pcie-iproc-platform.c
@@ -89,6 +89,9 @@ static int iproc_pcie_pltfm_probe(struct platform_device *pdev)
pcie->need_ob_cfg = true;
}
+ if (of_property_read_bool(np, "slot-pluggable"))
+ pcie->enable_hotplug = true;
+
/* PHY use is optional */
pcie->phy = devm_phy_get(dev, "pcie-phy");
if (IS_ERR(pcie->phy)) {
diff --git a/drivers/pci/host/pcie-iproc.c b/drivers/pci/host/pcie-iproc.c
index ee40651..eb919f7 100644
--- a/drivers/pci/host/pcie-iproc.c
+++ b/drivers/pci/host/pcie-iproc.c
@@ -28,6 +28,7 @@
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/phy/phy.h>
+#include <linux/gpio.h>
#include "pcie-iproc.h"
@@ -65,6 +66,17 @@
#define PCIE_DL_ACTIVE_SHIFT 2
#define PCIE_DL_ACTIVE BIT(PCIE_DL_ACTIVE_SHIFT)
+#define CFG_RC_LTSSM 0x1cf8
+#define CFG_RC_PHY_CTL 0x1804
+#define CFG_RC_LTSSM_TIMEOUT 1000
+#define CFG_RC_LTSSM_STATE_MASK 0xff
+#define CFG_RC_LTSSM_STATE_L1 0x1
+
+#define CFG_RC_CLR_LTSSM_HIST_SHIFT 29
+#define CFG_RC_CLR_LTSSM_HIST_MASK BIT(CFG_RC_CLR_LTSSM_HIST_SHIFT)
+#define CFG_RC_CLR_RECOV_HIST_SHIFT 31
+#define CFG_RC_CLR_RECOV_HIST_MASK BIT(CFG_RC_CLR_RECOV_HIST_SHIFT)
+
#define APB_ERR_EN_SHIFT 0
#define APB_ERR_EN BIT(APB_ERR_EN_SHIFT)
@@ -1306,12 +1318,106 @@ static int iproc_pcie_rev_init(struct iproc_pcie *pcie)
return 0;
}
+static bool iproc_pci_hp_check_ltssm(struct iproc_pcie *pcie)
+{
+ struct pci_bus *bus = pcie->root_bus;
+ u32 val, timeout = CFG_RC_LTSSM_TIMEOUT;
+
+ /* Clear LTSSM history. */
+ pci_bus_read_config_dword(pcie->root_bus, 0,
+ CFG_RC_PHY_CTL, &val);
+ pci_bus_write_config_dword(bus, 0, CFG_RC_PHY_CTL,
+ val | CFG_RC_CLR_RECOV_HIST_MASK |
+ CFG_RC_CLR_LTSSM_HIST_MASK);
+ /* write back the origional value. */
+ pci_bus_write_config_dword(bus, 0, CFG_RC_PHY_CTL, val);
+
+ do {
+ pci_bus_read_config_dword(pcie->root_bus, 0,
+ CFG_RC_LTSSM, &val);
+ /* check link state to see if link moved to L1 state. */
+ if ((val & CFG_RC_LTSSM_STATE_MASK) ==
+ CFG_RC_LTSSM_STATE_L1)
+ return true;
+ timeout--;
+ usleep_range(500, 1000);
+ } while (timeout);
+
+ return false;
+}
+
+static irqreturn_t iproc_pci_hotplug_thread(int irq, void *data)
+{
+ struct iproc_pcie *pcie = data;
+ struct pci_bus *bus = pcie->root_bus, *child;
+ bool link_status;
+
+ iproc_pcie_perst_ctrl(pcie, true);
+ iproc_pcie_perst_ctrl(pcie, false);
+
+ link_status = iproc_pci_hp_check_ltssm(pcie);
+
+ if (link_status &&
+ !iproc_pcie_check_link(pcie, bus) &&
+ !pcie->ep_is_present) {
+ pci_rescan_bus(bus);
+ list_for_each_entry(child, &bus->children, node)
+ pcie_bus_configure_settings(child);
+ pcie->ep_is_present = true;
+ dev_info(pcie->dev,
+ "PCI Hotplug: <device detected and enumerated>\n");
+ } else if (link_status && pcie->ep_is_present)
+ /*
+ * ep_is_present makes sure, enumuration done only once.
+ * So it can handle spurious intrrupts, and also if we
+ * get multiple interrupts for all the implemented pins,
+ * we handle it only once.
+ */
+ dev_info(pcie->dev,
+ "PCI Hotplug: <device already present>\n");
+ else {
+ iproc_pcie_perst_ctrl(pcie, true);
+ pcie->ep_is_present = false;
+ dev_info(pcie->dev,
+ "PCI Hotplug: <device removed>\n");
+ }
+ return IRQ_HANDLED;
+}
+
+static int iproc_pci_hp_gpio_irq_get(struct iproc_pcie *pcie)
+{
+ struct gpio_descs *hp_gpiod;
+ struct device *dev = pcie->dev;
+ int i;
+
+ hp_gpiod = devm_gpiod_get_array(dev, "prsnt", GPIOD_IN);
+ if (PTR_ERR(hp_gpiod) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+
+ if (!IS_ERR(hp_gpiod) && (hp_gpiod->ndescs > 0)) {
+ for (i = 0; i < hp_gpiod->ndescs; ++i) {
+ gpiod_direction_input(hp_gpiod->desc[i]);
+ if (request_threaded_irq(gpiod_to_irq
+ (hp_gpiod->desc[i]),
+ NULL, iproc_pci_hotplug_thread,
+ IRQF_TRIGGER_FALLING,
+ "PCI-hotplug", pcie))
+ dev_err(dev,
+ "PCI hotplug prsnt: request irq failed\n");
+ }
+ }
+ pcie->ep_is_present = false;
+
+ return 0;
+}
+
int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
{
struct device *dev;
int ret;
void *sysdata;
struct pci_bus *bus, *child;
+ bool is_link_active;
dev = pcie->dev;
@@ -1337,6 +1443,12 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
goto err_exit_phy;
}
+ if (pcie->enable_hotplug) {
+ ret = iproc_pci_hp_gpio_irq_get(pcie);
+ if (ret < 0)
+ return ret;
+ }
+
iproc_pcie_perst_ctrl(pcie, true);
iproc_pcie_perst_ctrl(pcie, false);
@@ -1367,8 +1479,11 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
}
pcie->root_bus = bus;
- ret = iproc_pcie_check_link(pcie, bus);
- if (ret) {
+ is_link_active = iproc_pcie_check_link(pcie, bus);
+ if (is_link_active && pcie->enable_hotplug) {
+ dev_err(dev, "no PCIe EP device detected\n");
+ iproc_pcie_perst_ctrl(pcie, true);
+ } else if (is_link_active) {
dev_err(dev, "no PCIe EP device detected\n");
goto err_rm_root_bus;
}
@@ -1379,14 +1494,17 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
if (iproc_pcie_msi_enable(pcie))
dev_info(dev, "not using iProc MSI\n");
- pci_scan_child_bus(bus);
- pci_assign_unassigned_bus_resources(bus);
+ if (!is_link_active) {
+ pci_scan_child_bus(bus);
+ pci_assign_unassigned_bus_resources(bus);
+ }
if (pcie->map_irq)
pci_fixup_irqs(pci_common_swizzle, pcie->map_irq);
- list_for_each_entry(child, &bus->children, node)
- pcie_bus_configure_settings(child);
+ if (!is_link_active)
+ list_for_each_entry(child, &bus->children, node)
+ pcie_bus_configure_settings(child);
pci_bus_add_devices(bus);
diff --git a/drivers/pci/host/pcie-iproc.h b/drivers/pci/host/pcie-iproc.h
index a6b55ce..e5d0cd4 100644
--- a/drivers/pci/host/pcie-iproc.h
+++ b/drivers/pci/host/pcie-iproc.h
@@ -77,6 +77,10 @@ struct iproc_pcie_ib {
* @ib: inbound mapping related parameters
* @ib_map: outbound mapping region related parameters
*
+ * @enable_hotplug: indicates PCI hotplug feature is enabled
+ * @ep_is_present: when PCIe hotplug is enabled, this flag is used to
+ * indicate whether or not the endpoint device is present
+ *
* @need_msi_steer: indicates additional configuration of the iProc PCIe
* controller is required to steer MSI writes to external interrupt controller
* @msi: MSI data
@@ -104,6 +108,9 @@ struct iproc_pcie {
struct iproc_pcie_ib ib;
const struct iproc_pcie_ib_map *ib_map;
+ bool enable_hotplug;
+ bool ep_is_present;
+
bool need_msi_steer;
struct iproc_msi *msi;
};
--
1.9.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v2 2/3] Documentation/devicetree: Add PCIe hotplug property
2017-08-15 5:55 [PATCH v2 0/3] PCI hotplug feature Oza Pawandeep
2017-08-15 5:55 ` [PATCH v2 1/3] PCI: iproc: Implement PCI hotplug support Oza Pawandeep
@ 2017-08-15 5:55 ` Oza Pawandeep
2017-08-17 20:58 ` Rob Herring
[not found] ` <1502776547-30542-4-git-send-email-oza.oza@broadcom.com>
2 siblings, 1 reply; 5+ messages in thread
From: Oza Pawandeep @ 2017-08-15 5:55 UTC (permalink / raw)
To: Bjorn Helgaas, Rob Herring, Mark Rutland, Ray Jui, Scott Branden,
Jon Mason, bcm-kernel-feedback-list, Oza Pawandeep,
Andy Gospodarek, linux-pci, devicetree, linux-arm-kernel,
linux-kernel, Oza Pawandeep
Host drivers have the requirement of implementing PCI hotplug
based on the how their SOC supports PCI hotplug.
Couple of properties have been added. the one to enable
the hotplug feature itself, and the other caters to
the PCI hotplug implementation with the use of gpios.
Signed-off-by: Oza Pawandeep <oza.oza@broadcom.com>
diff --git a/Documentation/devicetree/bindings/pci/pci.txt b/Documentation/devicetree/bindings/pci/pci.txt
index 50f9e2c..0bf25a1 100644
--- a/Documentation/devicetree/bindings/pci/pci.txt
+++ b/Documentation/devicetree/bindings/pci/pci.txt
@@ -24,3 +24,18 @@ driver implementation may support the following properties:
unsupported link speed, for instance, trying to do training for
unsupported link speed, etc. Must be '4' for gen4, '3' for gen3, '2'
for gen2, and '1' for gen1. Any other values are invalid.
+
+- slot-pluggable:
+ PCI hotplug feature is supported.
+ PCI hotplug implementation is SOC/Board specific, and also it depends on
+ how add-in card is designed (e.g. how many present pins are implemented).
+ If the slot-pluggable property is present, the following propertey could
+ become effective.
+ - prsnt-gpios:
+ Array of gpios, could be present if hotplug is supported.
+ This property defines gpio based hotplug implementation.
+ Example:
+ If x8 card is connected, then it might be possible that all the
+ 3 present pins could go low, or at least one pin goes low.
+ If x4 card is connected, then it might be possible that 2 present
+ pins go low, or at least one pin goes low.
--
1.9.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v2 2/3] Documentation/devicetree: Add PCIe hotplug property
2017-08-15 5:55 ` [PATCH v2 2/3] Documentation/devicetree: Add PCIe hotplug property Oza Pawandeep
@ 2017-08-17 20:58 ` Rob Herring
0 siblings, 0 replies; 5+ messages in thread
From: Rob Herring @ 2017-08-17 20:58 UTC (permalink / raw)
To: Oza Pawandeep
Cc: Mark Rutland, devicetree, Scott Branden, Oza Pawandeep, Jon Mason,
Ray Jui, linux-kernel, bcm-kernel-feedback-list, linux-pci,
Bjorn Helgaas, Andy Gospodarek, linux-arm-kernel
On Tue, Aug 15, 2017 at 11:25:46AM +0530, Oza Pawandeep wrote:
> Host drivers have the requirement of implementing PCI hotplug
> based on the how their SOC supports PCI hotplug.
>
> Couple of properties have been added. the one to enable
> the hotplug feature itself, and the other caters to
> the PCI hotplug implementation with the use of gpios.
>
> Signed-off-by: Oza Pawandeep <oza.oza@broadcom.com>
Acked-by: Rob Herring <robh@kernel.org>
"dt-bindings: PCI: ..." preferred for the subject if you respin.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v2 3/3] PCI: iproc: Implement optional property prsnt-gpios
[not found] ` <1502776547-30542-4-git-send-email-oza.oza@broadcom.com>
@ 2017-08-17 20:59 ` Rob Herring
0 siblings, 0 replies; 5+ messages in thread
From: Rob Herring @ 2017-08-17 20:59 UTC (permalink / raw)
To: Oza Pawandeep
Cc: Mark Rutland, devicetree, Scott Branden, Oza Pawandeep, Jon Mason,
Ray Jui, linux-kernel, bcm-kernel-feedback-list, linux-pci,
Bjorn Helgaas, Andy Gospodarek, linux-arm-kernel
On Tue, Aug 15, 2017 at 11:25:47AM +0530, Oza Pawandeep wrote:
> Add description for optional device tree property
> 'prsnt-gpios' for PCI hotplug feature.
>
> Signed-off-by: Oza Pawandeep <oza.oza@broadcom.com>
> Reviewed-by: Ray Jui <ray.jui@broadcom.com>
Acked-by: Rob Herring <robh@kernel.org>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2017-08-17 20:59 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-08-15 5:55 [PATCH v2 0/3] PCI hotplug feature Oza Pawandeep
2017-08-15 5:55 ` [PATCH v2 1/3] PCI: iproc: Implement PCI hotplug support Oza Pawandeep
2017-08-15 5:55 ` [PATCH v2 2/3] Documentation/devicetree: Add PCIe hotplug property Oza Pawandeep
2017-08-17 20:58 ` Rob Herring
[not found] ` <1502776547-30542-4-git-send-email-oza.oza@broadcom.com>
2017-08-17 20:59 ` [PATCH v2 3/3] PCI: iproc: Implement optional property prsnt-gpios Rob Herring
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).