Merge "msm: ep_pcie: Move link enumeration part to workqueue"

This commit is contained in:
qctecmdr 2023-04-02 23:11:16 -07:00 committed by Gerrit - the friendly Code Review server
commit 1c893f7c9f
2 changed files with 60 additions and 9 deletions

View File

@ -419,6 +419,7 @@ struct ep_pcie_dev_t {
bool conf_ipa_msi_iatu;
struct ep_pcie_register_event *event_reg;
struct work_struct handle_enumeration_work;
struct work_struct handle_bme_work;
struct work_struct handle_d3cold_work;

View File

@ -566,6 +566,14 @@ static void ep_pcie_pipe_clk_deinit(struct ep_pcie_dev_t *dev)
dev->pipeclk[i].hdl);
}
static void ep_pcie_irq_deinit(struct ep_pcie_dev_t *dev)
{
EP_PCIE_DBG(dev, "PCIe V%d\n", dev->rev);
if (dev->perst_irq >= 0)
disable_irq(dev->perst_irq);
}
static void ep_pcie_bar_init(struct ep_pcie_dev_t *dev)
{
struct resource *res = dev->res[EP_PCIE_RES_MMIO].resource;
@ -2400,7 +2408,21 @@ static int ep_pcie_enumeration(struct ep_pcie_dev_t *dev)
"PCIe V%d: start PCIe link enumeration per host side\n",
dev->rev);
ret = ep_pcie_core_enable_endpoint(EP_PCIE_OPT_ALL);
ret = ep_pcie_core_enable_endpoint(EP_PCIE_OPT_POWER_ON | EP_PCIE_OPT_ENUM_ASYNC);
/*
* When there is no host attached ep driver is creating a huge boot delay about 35sec,
* as our driver is waiting for the host to deassert PERST in response to WAKE. All this
* waiting happening in the driver probe context. So it's delaying our driver probe
* completion and thus affecting the overall kernel bootup. To avoid this scenario,
* offloading the link training part to a worker thread context.
*
* This issue is seen mainly on products that can act as PCIe EP but can boot up from flash
* without any dependency on the host (They can boot up irrespective of RC is attached
* or not) and can function as standalone products with partial functionality.
*/
if (!(dev->link_status == EP_PCIE_LINK_ENABLED ||
dev->link_status == EP_PCIE_LINK_UP))
schedule_work(&dev->handle_enumeration_work);
if (ret) {
EP_PCIE_ERR(&ep_pcie_dev,
@ -2450,6 +2472,41 @@ static void handle_d3cold_func(struct work_struct *work)
spin_unlock_irqrestore(&dev->isr_lock, irqsave_flags);
}
/*
* handle_enumeration_func - workqueue function will handle link enumeration.
* @work: PCIe endpoint handle_enumeration_work structure.
*/
static void handle_enumeration_func(struct work_struct *work)
{
int ret;
struct ep_pcie_dev_t *dev = container_of(work,
struct ep_pcie_dev_t, handle_enumeration_work);
ret = ep_pcie_core_enable_endpoint(EP_PCIE_OPT_ENUM_ASYNC | EP_PCIE_OPT_AST_WAKE
| EP_PCIE_OPT_ENUM);
if (ret) {
EP_PCIE_ERR(&ep_pcie_dev,
"PCIe V%d: PCIe link enumeration failed\n",
ep_pcie_dev.rev);
} else {
if (dev->link_status == EP_PCIE_LINK_UP) {
EP_PCIE_INFO(&ep_pcie_dev,
"PCIe V%d: PCIe link training is successful with host side. Waiting for enumeration to complete\n",
ep_pcie_dev.rev);
} else if (dev->link_status != EP_PCIE_LINK_ENABLED) {
EP_PCIE_ERR(&ep_pcie_dev,
"PCIe V%d: PCIe link is in the unexpected status: %d\n",
ep_pcie_dev.rev, dev->link_status);
if (!ep_pcie_debug_keep_resource) {
ep_pcie_irq_deinit(&ep_pcie_dev);
ep_pcie_gpio_deinit(&ep_pcie_dev);
ep_pcie_release_resources(&ep_pcie_dev);
}
}
}
}
static void handle_bme_func(struct work_struct *work)
{
struct ep_pcie_dev_t *dev = container_of(work,
@ -2677,6 +2734,7 @@ int32_t ep_pcie_irq_init(struct ep_pcie_dev_t *dev)
EP_PCIE_DBG(dev, "PCIe V%d\n", dev->rev);
/* Initialize all works to be performed before registering for IRQs*/
INIT_WORK(&dev->handle_enumeration_work, handle_enumeration_func);
INIT_WORK(&dev->handle_bme_work, handle_bme_func);
INIT_WORK(&dev->handle_d3cold_work, handle_d3cold_func);
@ -2839,14 +2897,6 @@ int32_t ep_pcie_irq_init(struct ep_pcie_dev_t *dev)
return 0;
}
void ep_pcie_irq_deinit(struct ep_pcie_dev_t *dev)
{
EP_PCIE_DBG(dev, "PCIe V%d\n", dev->rev);
if (dev->perst_irq >= 0)
disable_irq(dev->perst_irq);
}
int ep_pcie_core_register_event(struct ep_pcie_register_event *reg)
{
if (!reg) {