Loading drivers/platform/msm/ep_pcie/ep_pcie_com.h +1 −0 Original line number Diff line number Diff line Loading @@ -359,6 +359,7 @@ struct ep_pcie_dev_t { bool m2_autonomous; bool mhi_soc_reset_en; bool aoss_rst_clear; bool avoid_reboot_in_d3hot; u32 dbi_base_reg; u32 slv_space_reg; u32 phy_status_reg; Loading drivers/platform/msm/ep_pcie/ep_pcie_core.c +64 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,9 @@ #include <linux/of_gpio.h> #include <linux/clk/qcom.h> #include <linux/reset.h> #include <linux/reboot.h> #include <linux/notifier.h> #include <linux/kdebug.h> #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/interconnect.h> Loading Loading @@ -3190,6 +3193,49 @@ int ep_pcie_core_config_db_routing(struct ep_pcie_db_config chdb_cfg, return 0; } static int ep_pcie_core_panic_reboot_callback(struct notifier_block *nb, unsigned long reason, void *arg) { struct ep_pcie_dev_t *dev = &ep_pcie_dev; u32 mhi_syserr = BIT(2)|(0xff << 8); unsigned long irqsave_flags; if (!ep_pcie_dev.avoid_reboot_in_d3hot) goto out; /* If the device is in D3hot state, bring it to D0 */ spin_lock_irqsave(&dev->isr_lock, irqsave_flags); if (dev->l23_ready && atomic_read(&dev->perst_deast)) { EP_PCIE_INFO(dev, "PCIe V%d got %s notification while in D3hot\n", dev->rev, reason ? "reboot":"panic/die"); /* Set MHI to SYSERR state */ if (dev->config_mmio_init) ep_pcie_write_reg(dev->mmio, PCIE20_MHISTATUS, mhi_syserr); /* Bring device out of D3hot */ ep_pcie_core_issue_inband_pme(); } spin_unlock_irqrestore(&dev->isr_lock, irqsave_flags); out: return NOTIFY_DONE; } static struct notifier_block ep_pcie_core_reboot_notifier = { .notifier_call = ep_pcie_core_panic_reboot_callback, }; static struct notifier_block ep_pcie_core_die_notifier = { .notifier_call = ep_pcie_core_panic_reboot_callback, }; static struct notifier_block ep_pcie_core_panic_notifier = { .notifier_call = ep_pcie_core_panic_reboot_callback, }; struct ep_pcie_hw hw_drv = { .register_event = ep_pcie_core_register_event, .deregister_event = ep_pcie_core_deregister_event, Loading Loading @@ -3361,6 +3407,13 @@ static int ep_pcie_probe(struct platform_device *pdev) "PCIe V%d: MHI M2 autonomous is %s enabled\n", ep_pcie_dev.rev, ep_pcie_dev.m2_autonomous ? "" : "not"); ep_pcie_dev.avoid_reboot_in_d3hot = of_property_read_bool((&pdev->dev)->of_node, "qcom,avoid-reboot-in-d3hot"); EP_PCIE_DBG(&ep_pcie_dev, "PCIe V%d: PME during reboot/panic (in D3hot) is %s needed\n", ep_pcie_dev.rev, ep_pcie_dev.avoid_reboot_in_d3hot ? "" : "not"); ret = of_property_read_u32((&pdev->dev)->of_node, "qcom,mhi-soc-reset-offset", &ep_pcie_dev.mhi_soc_reset_offset); Loading Loading @@ -3453,6 +3506,12 @@ static int ep_pcie_probe(struct platform_device *pdev) if (ret && !ep_pcie_debug_keep_resource) goto irq_deinit; register_reboot_notifier(&ep_pcie_core_reboot_notifier); /* Handler for wilful crash like BUG_ON */ register_die_notifier(&ep_pcie_core_die_notifier); atomic_notifier_chain_register(&panic_notifier_list, &ep_pcie_core_panic_notifier); qcom_edma_init(&pdev->dev); if (!ep_pcie_dev.perst_enum) Loading @@ -3476,6 +3535,11 @@ static int __exit ep_pcie_remove(struct platform_device *pdev) { pr_debug("%s\n", __func__); unregister_reboot_notifier(&ep_pcie_core_reboot_notifier); unregister_die_notifier(&ep_pcie_core_die_notifier); atomic_notifier_chain_unregister(&panic_notifier_list, &ep_pcie_core_panic_notifier); ep_pcie_irq_deinit(&ep_pcie_dev); ep_pcie_vreg_deinit(&ep_pcie_dev); ep_pcie_pipe_clk_deinit(&ep_pcie_dev); Loading Loading
drivers/platform/msm/ep_pcie/ep_pcie_com.h +1 −0 Original line number Diff line number Diff line Loading @@ -359,6 +359,7 @@ struct ep_pcie_dev_t { bool m2_autonomous; bool mhi_soc_reset_en; bool aoss_rst_clear; bool avoid_reboot_in_d3hot; u32 dbi_base_reg; u32 slv_space_reg; u32 phy_status_reg; Loading
drivers/platform/msm/ep_pcie/ep_pcie_core.c +64 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,9 @@ #include <linux/of_gpio.h> #include <linux/clk/qcom.h> #include <linux/reset.h> #include <linux/reboot.h> #include <linux/notifier.h> #include <linux/kdebug.h> #include <linux/interrupt.h> #include <linux/irq.h> #include <linux/interconnect.h> Loading Loading @@ -3190,6 +3193,49 @@ int ep_pcie_core_config_db_routing(struct ep_pcie_db_config chdb_cfg, return 0; } static int ep_pcie_core_panic_reboot_callback(struct notifier_block *nb, unsigned long reason, void *arg) { struct ep_pcie_dev_t *dev = &ep_pcie_dev; u32 mhi_syserr = BIT(2)|(0xff << 8); unsigned long irqsave_flags; if (!ep_pcie_dev.avoid_reboot_in_d3hot) goto out; /* If the device is in D3hot state, bring it to D0 */ spin_lock_irqsave(&dev->isr_lock, irqsave_flags); if (dev->l23_ready && atomic_read(&dev->perst_deast)) { EP_PCIE_INFO(dev, "PCIe V%d got %s notification while in D3hot\n", dev->rev, reason ? "reboot":"panic/die"); /* Set MHI to SYSERR state */ if (dev->config_mmio_init) ep_pcie_write_reg(dev->mmio, PCIE20_MHISTATUS, mhi_syserr); /* Bring device out of D3hot */ ep_pcie_core_issue_inband_pme(); } spin_unlock_irqrestore(&dev->isr_lock, irqsave_flags); out: return NOTIFY_DONE; } static struct notifier_block ep_pcie_core_reboot_notifier = { .notifier_call = ep_pcie_core_panic_reboot_callback, }; static struct notifier_block ep_pcie_core_die_notifier = { .notifier_call = ep_pcie_core_panic_reboot_callback, }; static struct notifier_block ep_pcie_core_panic_notifier = { .notifier_call = ep_pcie_core_panic_reboot_callback, }; struct ep_pcie_hw hw_drv = { .register_event = ep_pcie_core_register_event, .deregister_event = ep_pcie_core_deregister_event, Loading Loading @@ -3361,6 +3407,13 @@ static int ep_pcie_probe(struct platform_device *pdev) "PCIe V%d: MHI M2 autonomous is %s enabled\n", ep_pcie_dev.rev, ep_pcie_dev.m2_autonomous ? "" : "not"); ep_pcie_dev.avoid_reboot_in_d3hot = of_property_read_bool((&pdev->dev)->of_node, "qcom,avoid-reboot-in-d3hot"); EP_PCIE_DBG(&ep_pcie_dev, "PCIe V%d: PME during reboot/panic (in D3hot) is %s needed\n", ep_pcie_dev.rev, ep_pcie_dev.avoid_reboot_in_d3hot ? "" : "not"); ret = of_property_read_u32((&pdev->dev)->of_node, "qcom,mhi-soc-reset-offset", &ep_pcie_dev.mhi_soc_reset_offset); Loading Loading @@ -3453,6 +3506,12 @@ static int ep_pcie_probe(struct platform_device *pdev) if (ret && !ep_pcie_debug_keep_resource) goto irq_deinit; register_reboot_notifier(&ep_pcie_core_reboot_notifier); /* Handler for wilful crash like BUG_ON */ register_die_notifier(&ep_pcie_core_die_notifier); atomic_notifier_chain_register(&panic_notifier_list, &ep_pcie_core_panic_notifier); qcom_edma_init(&pdev->dev); if (!ep_pcie_dev.perst_enum) Loading @@ -3476,6 +3535,11 @@ static int __exit ep_pcie_remove(struct platform_device *pdev) { pr_debug("%s\n", __func__); unregister_reboot_notifier(&ep_pcie_core_reboot_notifier); unregister_die_notifier(&ep_pcie_core_die_notifier); atomic_notifier_chain_unregister(&panic_notifier_list, &ep_pcie_core_panic_notifier); ep_pcie_irq_deinit(&ep_pcie_dev); ep_pcie_vreg_deinit(&ep_pcie_dev); ep_pcie_pipe_clk_deinit(&ep_pcie_dev); Loading