pci: msm: create a de-enumerate api

SD Express endpoint requires hotplug detection, there is a detection
driver which monitors card detect gpio to know card is inserted or removed.

As part of card removal we need to make sure we are de-registering
from the pci platform drivers and deinitng clk's etc.

For this purpose created this api for de registering.

Change-Id: If67e3b34f0efc1959624f3d43d1de0ee6d09101a
Signed-off-by: Krishna chaitanya chundru <quic_krichai@quicinc.com>
Signed-off-by: Paras Sharma <quic_parass@quicinc.com>
This commit is contained in:
Paras Sharma 2022-05-26 09:44:48 +05:30
parent 868a5e3f4b
commit 47019eca68
2 changed files with 94 additions and 8 deletions

View File

@ -505,6 +505,7 @@ enum msm_pcie_debugfs_option {
MSM_PCIE_DISABLE_L1SS,
MSM_PCIE_ENABLE_L1SS,
MSM_PCIE_ENUMERATION,
MSM_PCIE_DEENUMERATION,
MSM_PCIE_READ_PCIE_REGISTER,
MSM_PCIE_WRITE_PCIE_REGISTER,
MSM_PCIE_DUMP_PCIE_REGISTER_SPACE,
@ -536,6 +537,7 @@ static const char * const
"DISABLE L1SS",
"ENABLE L1SS",
"ENUMERATE",
"DE-ENUMERATE",
"READ A PCIE REGISTER",
"WRITE TO PCIE REGISTER",
"DUMP PCIE REGISTER SPACE",
@ -1198,6 +1200,7 @@ struct msm_pcie_dev_t {
u32 l1ss_timeout_us;
u32 l1ss_sleep_disable;
u32 clkreq_gpio;
struct pci_host_bridge *bridge;
};
struct msm_root_dev_t {
@ -2240,6 +2243,23 @@ static void msm_pcie_sel_debug_testcase(struct msm_pcie_dev_t *dev,
dev->rc_idx);
}
break;
case MSM_PCIE_DEENUMERATION:
PCIE_DBG_FS(dev, "\n\nPCIe: attempting to de enumerate RC%d\n\n",
dev->rc_idx);
if (!dev->enumerated)
PCIE_DBG_FS(dev, "PCIe: RC%d is already de enumerated\n",
dev->rc_idx);
else {
if (!msm_pcie_deenumerate(dev->rc_idx))
PCIE_DBG_FS(dev,
"PCIe: RC%d is successfully de enumerated\n",
dev->rc_idx);
else
PCIE_DBG_FS(dev,
"PCIe: RC%d de enumeration failed\n",
dev->rc_idx);
}
break;
case MSM_PCIE_READ_PCIE_REGISTER:
msm_pcie_access_reg(dev, false);
break;
@ -6068,6 +6088,8 @@ int msm_pcie_enumerate(u32 rc_idx)
goto out;
}
dev->cfg_access = true;
/* kick start ARM PCI configuration framework */
ids = readl_relaxed(dev->dm_core);
vendor_id = ids & 0xffff;
@ -6076,16 +6098,26 @@ int msm_pcie_enumerate(u32 rc_idx)
PCIE_DBG(dev, "PCIe: RC%d: vendor-id:0x%x device_id:0x%x\n",
dev->rc_idx, vendor_id, device_id);
bridge = devm_pci_alloc_host_bridge(&dev->pdev->dev, sizeof(*dev));
if (!bridge) {
ret = -ENOMEM;
goto out;
}
if (!dev->bridge) {
bridge = devm_pci_alloc_host_bridge(&dev->pdev->dev, sizeof(*dev));
if (!bridge) {
if (!dev->lpi_enable) {
ret = msm_msi_init(&dev->pdev->dev);
if (ret)
PCIE_ERR(dev, "PCIe: RC%d: bridge allocation failed\n", dev->rc_idx);
ret = -ENOMEM;
goto out;
}
dev->bridge = bridge;
if (!dev->lpi_enable) {
ret = msm_msi_init(&dev->pdev->dev);
if (ret)
goto out;
}
} else {
bridge = dev->bridge;
msm_msi_config_access(dev_get_msi_domain(&dev->dev->dev),
true);
}
bridge->sysdata = dev;
@ -6136,6 +6168,45 @@ int msm_pcie_enumerate(u32 rc_idx)
}
EXPORT_SYMBOL(msm_pcie_enumerate);
int msm_pcie_deenumerate(u32 rc_idx)
{
struct msm_pcie_dev_t *dev = &msm_pcie_dev[rc_idx];
struct pci_host_bridge *bridge = dev->bridge;
mutex_lock(&dev->enumerate_lock);
PCIE_DBG(dev, "RC%d: Entry\n", dev->rc_idx);
if (!dev->enumerated) {
PCIE_DBG(dev, "RC%d:device is not enumerated\n", dev->rc_idx);
mutex_unlock(&dev->enumerate_lock);
return 0;
}
if (dev->config_recovery) {
PCIE_DBG(dev, "RC%d: cancel link_recover_wq\n", dev->rc_idx);
cancel_work_sync(&dev->link_recover_wq);
}
spin_lock_irqsave(&dev->cfg_lock, dev->irqsave_flags);
dev->cfg_access = false;
spin_unlock_irqrestore(&dev->cfg_lock, dev->irqsave_flags);
pci_stop_root_bus(bridge->bus);
pci_remove_root_bus(bridge->bus);
msm_pcie_disable(dev);
dev->enumerated = false;
mutex_unlock(&dev->enumerate_lock);
PCIE_DBG(dev, "RC%d: exit\n", dev->rc_idx);
return 0;
}
EXPORT_SYMBOL_GPL(msm_pcie_deenumerate);
static void msm_pcie_notify_client(struct msm_pcie_dev_t *dev,
enum msm_pcie_event event)
{

View File

@ -187,6 +187,16 @@ int msm_pcie_deregister_event(struct msm_pcie_register_event *reg);
*/
int msm_pcie_enumerate(u32 rc_idx);
/**
* msm_pcie_deenumerate - deenumerates the Endpoints.
* @rc_idx: RC that Endpoints connect to.
*
* This function de-enumerates Endpoints connected to RC.
*
* Return: 0 on success, negative value on error
*/
int msm_pcie_deenumerate(u32 rc_idx);
/*
* msm_pcie_debug_info - run a PCIe specific debug testcase.
* @dev: pci device structure
@ -262,6 +272,11 @@ static inline int msm_pcie_enumerate(u32 rc_idx)
return -ENODEV;
}
static inline int msm_pcie_deenumerate(u32 rc_idx)
{
return -ENODEV;
}
static inline int msm_pcie_debug_info(struct pci_dev *dev, u32 option, u32 base,
u32 offset, u32 mask, u32 value)
{