mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-10 14:19:09 -04:00
pci: msm: Add support to handle ep driver requested link down
In case PCIe endpoint driver infers link down because of completion timeout for config space access or if link fails to enumerate, ep driver can request to handle the link down. This allows to stream line the link down notification to ep driver to initiate recovery operation. Change-Id: I652e60e570c1e90c9f96d1c197e4b5501cd60a1e Signed-off-by: Hemant Kumar <hemantk@codeaurora.org>
This commit is contained in:
parent
85082b1d7a
commit
0d97dfe55c
2 changed files with 45 additions and 28 deletions
|
|
@ -4584,10 +4584,41 @@ static irqreturn_t handle_wake_irq(int irq, void *data)
|
|||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void msm_pcie_handle_linkdown(struct msm_pcie_dev_t *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (dev->link_status == MSM_PCIE_LINK_DOWN)
|
||||
return;
|
||||
|
||||
dev->link_status = MSM_PCIE_LINK_DOWN;
|
||||
dev->shadow_en = false;
|
||||
|
||||
/* assert PERST */
|
||||
if (!(msm_pcie_keep_resources_on & BIT(dev->rc_idx)))
|
||||
gpio_set_value(dev->gpio[MSM_PCIE_GPIO_PERST].num,
|
||||
dev->gpio[MSM_PCIE_GPIO_PERST].on);
|
||||
|
||||
PCIE_ERR(dev, "PCIe link is down for RC%d\n", dev->rc_idx);
|
||||
|
||||
if (dev->linkdown_panic)
|
||||
panic("User has chosen to panic on linkdown\n");
|
||||
|
||||
if (dev->num_ep > 1) {
|
||||
for (i = 0; i < MAX_DEVICE_NUM; i++) {
|
||||
dev->event_reg =
|
||||
dev->pcidev_table[i].event_reg;
|
||||
msm_pcie_notify_client(dev,
|
||||
MSM_PCIE_EVENT_LINKDOWN);
|
||||
}
|
||||
} else {
|
||||
msm_pcie_notify_client(dev, MSM_PCIE_EVENT_LINKDOWN);
|
||||
}
|
||||
}
|
||||
|
||||
static irqreturn_t handle_linkdown_irq(int irq, void *data)
|
||||
{
|
||||
struct msm_pcie_dev_t *dev = data;
|
||||
int i;
|
||||
|
||||
dev->linkdown_counter++;
|
||||
|
||||
|
|
@ -4595,39 +4626,16 @@ static irqreturn_t handle_linkdown_irq(int irq, void *data)
|
|||
"PCIe: No. %ld linkdown IRQ for RC%d.\n",
|
||||
dev->linkdown_counter, dev->rc_idx);
|
||||
|
||||
if (!dev->enumerated || dev->link_status != MSM_PCIE_LINK_ENABLED) {
|
||||
if (!dev->enumerated || dev->link_status != MSM_PCIE_LINK_ENABLED)
|
||||
PCIE_DBG(dev,
|
||||
"PCIe:Linkdown IRQ for RC%d when the link is not enabled\n",
|
||||
dev->rc_idx);
|
||||
} else if (dev->suspending) {
|
||||
else if (dev->suspending)
|
||||
PCIE_DBG(dev,
|
||||
"PCIe:the link of RC%d is suspending.\n",
|
||||
dev->rc_idx);
|
||||
} else {
|
||||
dev->link_status = MSM_PCIE_LINK_DOWN;
|
||||
dev->shadow_en = false;
|
||||
|
||||
if (dev->linkdown_panic)
|
||||
panic("User has chosen to panic on linkdown\n");
|
||||
|
||||
/* assert PERST */
|
||||
if (!(msm_pcie_keep_resources_on & BIT(dev->rc_idx)))
|
||||
gpio_set_value(dev->gpio[MSM_PCIE_GPIO_PERST].num,
|
||||
dev->gpio[MSM_PCIE_GPIO_PERST].on);
|
||||
|
||||
PCIE_ERR(dev, "PCIe link is down for RC%d\n", dev->rc_idx);
|
||||
|
||||
if (dev->num_ep > 1) {
|
||||
for (i = 0; i < MAX_DEVICE_NUM; i++) {
|
||||
dev->event_reg =
|
||||
dev->pcidev_table[i].event_reg;
|
||||
msm_pcie_notify_client(dev,
|
||||
MSM_PCIE_EVENT_LINKDOWN);
|
||||
}
|
||||
} else {
|
||||
msm_pcie_notify_client(dev, MSM_PCIE_EVENT_LINKDOWN);
|
||||
}
|
||||
}
|
||||
else
|
||||
msm_pcie_handle_linkdown(dev);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
|
@ -6827,6 +6835,7 @@ int msm_pcie_pm_control(enum msm_pcie_pm_opt pm_opt, u32 busnr, void *user,
|
|||
int ret = 0;
|
||||
struct pci_dev *dev;
|
||||
u32 rc_idx = 0;
|
||||
unsigned long flags;
|
||||
struct msm_pcie_dev_t *pcie_dev;
|
||||
|
||||
if (!user) {
|
||||
|
|
@ -6972,6 +6981,13 @@ int msm_pcie_pm_control(enum msm_pcie_pm_opt pm_opt, u32 busnr, void *user,
|
|||
spin_unlock_irqrestore(&msm_pcie_dev[rc_idx].cfg_lock,
|
||||
msm_pcie_dev[rc_idx].irqsave_flags);
|
||||
break;
|
||||
case MSM_PCIE_HANDLE_LINKDOWN:
|
||||
PCIE_DBG(&msm_pcie_dev[rc_idx],
|
||||
"User of RC%d requests handling link down.\n", rc_idx);
|
||||
spin_lock_irqsave(&msm_pcie_dev[rc_idx].irq_lock, flags);
|
||||
msm_pcie_handle_linkdown(pcie_dev);
|
||||
spin_unlock_irqrestore(&msm_pcie_dev[rc_idx].irq_lock, flags);
|
||||
break;
|
||||
default:
|
||||
PCIE_ERR(&msm_pcie_dev[rc_idx],
|
||||
"PCIe: RC%d: unsupported pm operation:%d.\n",
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ enum msm_pcie_pm_opt {
|
|||
MSM_PCIE_RESUME,
|
||||
MSM_PCIE_DISABLE_PC,
|
||||
MSM_PCIE_ENABLE_PC,
|
||||
MSM_PCIE_HANDLE_LINKDOWN,
|
||||
};
|
||||
|
||||
enum msm_pcie_event {
|
||||
|
|
|
|||
Loading…
Reference in a new issue