Loading arch/arm/configs/sdxpoorwills-auto-perf_defconfig +4 −4 Original line number Diff line number Diff line Loading @@ -227,12 +227,12 @@ CONFIG_USB_USBNET=y CONFIG_USB_NET_SMSC75XX=y CONFIG_USB_NET_SMSC95XX=y CONFIG_WCNSS_MEM_PRE_ALLOC=y CONFIG_CNSS=y CONFIG_CNSS_SDIO=y CONFIG_CNSS_PCI=y CONFIG_CNSS2=y CONFIG_CNSS2_DEBUG=y CONFIG_CNSS2_QMI=y CONFIG_CLD_HL_SDIO_CORE=y CONFIG_CLD_LL_CORE=y CONFIG_CNSS_LOGGER=y CONFIG_CNSS_GENL=y # CONFIG_INPUT_MOUSEDEV is not set CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_KEYBOARD is not set Loading arch/arm/configs/sdxpoorwills-auto_defconfig +4 −4 Original line number Diff line number Diff line Loading @@ -221,12 +221,12 @@ CONFIG_USB_USBNET=y CONFIG_USB_NET_SMSC75XX=y CONFIG_USB_NET_SMSC95XX=y CONFIG_WCNSS_MEM_PRE_ALLOC=y CONFIG_CNSS=y CONFIG_CNSS_SDIO=y CONFIG_CNSS_PCI=y CONFIG_CNSS2=y CONFIG_CNSS2_DEBUG=y CONFIG_CNSS2_QMI=y CONFIG_CLD_HL_SDIO_CORE=y CONFIG_CLD_LL_CORE=y CONFIG_CNSS_LOGGER=y CONFIG_CNSS_GENL=y # CONFIG_INPUT_MOUSEDEV is not set CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_KEYBOARD is not set Loading drivers/net/wireless/cnss2/pci.c +167 −143 Original line number Diff line number Diff line /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -1523,40 +1523,6 @@ static void cnss_pci_free_m3_mem(struct cnss_pci_data *pci_priv) m3_mem->size = 0; } int cnss_pci_force_fw_assert_hdlr(struct cnss_pci_data *pci_priv) { int ret; struct cnss_plat_data *plat_priv; if (!pci_priv) return -ENODEV; plat_priv = pci_priv->plat_priv; if (!plat_priv) return -ENODEV; if (test_bit(CNSS_MHI_RDDM_DONE, &pci_priv->mhi_state)) { cnss_pr_err("RDDM already collected 0x%x, return\n", pci_priv->mhi_state); return 0; } ret = cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_TRIGGER_RDDM); if (ret) { cnss_pr_err("Failed to trigger RDDM, err = %d\n", ret); cnss_schedule_recovery(&pci_priv->pci_dev->dev, CNSS_REASON_DEFAULT); return 0; } if (!test_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state)) { mod_timer(&plat_priv->fw_boot_timer, jiffies + msecs_to_jiffies(FW_ASSERT_TIMEOUT)); } return 0; } void cnss_pci_fw_boot_timeout_hdlr(struct cnss_pci_data *pci_priv) { if (!pci_priv) Loading Loading @@ -1885,21 +1851,32 @@ static void cnss_pci_disable_bus(struct cnss_pci_data *pci_priv) pci_disable_device(pci_dev); } static int cnss_mhi_pm_runtime_get(struct mhi_controller *mhi_ctrl, void *priv) #ifndef CONFIG_MHI_BUS void cnss_pci_collect_dump_info(struct cnss_pci_data *pci_priv, bool in_panic) { struct cnss_pci_data *pci_priv = priv; } return pm_runtime_get(&pci_priv->pci_dev->dev); static inline int cnss_pci_register_mhi(struct cnss_pci_data *pci_priv) { return -EINVAL; } static void cnss_mhi_pm_runtime_put_noidle(struct mhi_controller *mhi_ctrl, void *priv) static inline void cnss_pci_unregister_mhi(struct cnss_pci_data *pci_priv) { struct cnss_pci_data *pci_priv = priv; } pm_runtime_put_noidle(&pci_priv->pci_dev->dev); inline int cnss_pci_set_mhi_state(struct cnss_pci_data *pci_priv, enum cnss_mhi_state mhi_state) { return -EINVAL; } inline int cnss_pci_force_fw_assert_hdlr(struct cnss_pci_data *pci_priv) { return -EINVAL; } #else static char *cnss_mhi_state_to_str(enum cnss_mhi_state mhi_state) { switch (mhi_state) { Loading @@ -1926,6 +1903,21 @@ static char *cnss_mhi_state_to_str(enum cnss_mhi_state mhi_state) } }; static int cnss_mhi_pm_runtime_get(struct mhi_controller *mhi_ctrl, void *priv) { struct cnss_pci_data *pci_priv = priv; return pm_runtime_get(&pci_priv->pci_dev->dev); } static void cnss_mhi_pm_runtime_put_noidle(struct mhi_controller *mhi_ctrl, void *priv) { struct cnss_pci_data *pci_priv = priv; pm_runtime_put_noidle(&pci_priv->pci_dev->dev); } void cnss_pci_collect_dump_info(struct cnss_pci_data *pci_priv, bool in_panic) { struct cnss_plat_data *plat_priv = pci_priv->plat_priv; Loading Loading @@ -2002,34 +1994,6 @@ void cnss_pci_collect_dump_info(struct cnss_pci_data *pci_priv, bool in_panic) complete(&plat_priv->rddm_complete); } void cnss_pci_clear_dump_info(struct cnss_pci_data *pci_priv) { struct cnss_plat_data *plat_priv = pci_priv->plat_priv; plat_priv->ramdump_info_v2.dump_data.nentries = 0; plat_priv->ramdump_info_v2.dump_data_valid = false; } static int cnss_mhi_link_status(struct mhi_controller *mhi_ctrl, void *priv) { struct cnss_pci_data *pci_priv = priv; u16 device_id; if (!pci_priv) { cnss_pr_err("pci_priv is NULL\n"); return -EINVAL; } pci_read_config_word(pci_priv->pci_dev, PCI_DEVICE_ID, &device_id); if (device_id != pci_priv->device_id) { cnss_pr_err("PCI device ID mismatch, link possibly down, current read ID: 0x%x, record ID: 0x%x\n", device_id, pci_priv->device_id); return -EIO; } return 0; } static void cnss_mhi_notify_status(struct mhi_controller *mhi_ctrl, void *priv, enum MHI_CB reason) { Loading Loading @@ -2172,6 +2136,99 @@ static void cnss_pci_unregister_mhi(struct cnss_pci_data *pci_priv) kfree(mhi_ctrl->irq); } int cnss_pci_set_mhi_state(struct cnss_pci_data *pci_priv, enum cnss_mhi_state mhi_state) { int ret = 0; if (!pci_priv) { cnss_pr_err("pci_priv is NULL!\n"); return -ENODEV; } if (pci_priv->device_id == QCA6174_DEVICE_ID) return 0; if (mhi_state < 0) { cnss_pr_err("Invalid MHI state (%d)\n", mhi_state); return -EINVAL; } ret = cnss_pci_check_mhi_state_bit(pci_priv, mhi_state); if (ret) goto out; cnss_pr_dbg("Setting MHI state: %s(%d)\n", cnss_mhi_state_to_str(mhi_state), mhi_state); switch (mhi_state) { case CNSS_MHI_INIT: ret = mhi_prepare_for_power_up(pci_priv->mhi_ctrl); break; case CNSS_MHI_DEINIT: mhi_unprepare_after_power_down(pci_priv->mhi_ctrl); ret = 0; break; case CNSS_MHI_POWER_ON: ret = mhi_sync_power_up(pci_priv->mhi_ctrl); break; case CNSS_MHI_POWER_OFF: mhi_power_down(pci_priv->mhi_ctrl, true); ret = 0; break; case CNSS_MHI_FORCE_POWER_OFF: mhi_power_down(pci_priv->mhi_ctrl, false); ret = 0; break; case CNSS_MHI_SUSPEND: ret = mhi_pm_suspend(pci_priv->mhi_ctrl); break; case CNSS_MHI_RESUME: ret = mhi_pm_resume(pci_priv->mhi_ctrl); break; case CNSS_MHI_TRIGGER_RDDM: ret = mhi_force_rddm_mode(pci_priv->mhi_ctrl); break; case CNSS_MHI_RDDM_DONE: break; default: cnss_pr_err("Unhandled MHI state (%d)\n", mhi_state); ret = -EINVAL; } if (ret) goto out; cnss_pci_set_mhi_state_bit(pci_priv, mhi_state); return 0; out: cnss_pr_err("Failed to set MHI state: %s(%d)\n", cnss_mhi_state_to_str(mhi_state), mhi_state); return ret; } static int cnss_mhi_link_status(struct mhi_controller *mhi_ctrl, void *priv) { struct cnss_pci_data *pci_priv = priv; u16 device_id; if (!pci_priv) { cnss_pr_err("pci_priv is NULL\n"); return -EINVAL; } pci_read_config_word(pci_priv->pci_dev, PCI_DEVICE_ID, &device_id); if (device_id != pci_priv->device_id) { cnss_pr_err("PCI device ID mismatch, link possibly down, current read ID: 0x%x, record ID: 0x%x\n", device_id, pci_priv->device_id); return -EIO; } return 0; } static int cnss_pci_check_mhi_state_bit(struct cnss_pci_data *pci_priv, enum cnss_mhi_state mhi_state) { Loading Loading @@ -2219,111 +2276,78 @@ static int cnss_pci_check_mhi_state_bit(struct cnss_pci_data *pci_priv, return -EINVAL; } static void cnss_pci_set_mhi_state_bit(struct cnss_pci_data *pci_priv, enum cnss_mhi_state mhi_state) static int cnss_pci_force_fw_assert_hdlr(struct cnss_pci_data *pci_priv) { switch (mhi_state) { case CNSS_MHI_INIT: set_bit(CNSS_MHI_INIT, &pci_priv->mhi_state); break; case CNSS_MHI_DEINIT: clear_bit(CNSS_MHI_INIT, &pci_priv->mhi_state); break; case CNSS_MHI_POWER_ON: set_bit(CNSS_MHI_POWER_ON, &pci_priv->mhi_state); break; case CNSS_MHI_POWER_OFF: case CNSS_MHI_FORCE_POWER_OFF: clear_bit(CNSS_MHI_POWER_ON, &pci_priv->mhi_state); clear_bit(CNSS_MHI_RDDM_DONE, &pci_priv->mhi_state); break; case CNSS_MHI_SUSPEND: set_bit(CNSS_MHI_SUSPEND, &pci_priv->mhi_state); break; case CNSS_MHI_RESUME: clear_bit(CNSS_MHI_SUSPEND, &pci_priv->mhi_state); break; case CNSS_MHI_TRIGGER_RDDM: break; case CNSS_MHI_RDDM_DONE: set_bit(CNSS_MHI_RDDM_DONE, &pci_priv->mhi_state); break; default: cnss_pr_err("Unhandled MHI state (%d)\n", mhi_state); } } int ret; struct cnss_plat_data *plat_priv; int cnss_pci_set_mhi_state(struct cnss_pci_data *pci_priv, enum cnss_mhi_state mhi_state) { int ret = 0; if (!pci_priv) return -ENODEV; if (!pci_priv) { cnss_pr_err("pci_priv is NULL!\n"); plat_priv = pci_priv->plat_priv; if (!plat_priv) return -ENODEV; } if (pci_priv->device_id == QCA6174_DEVICE_ID) if (test_bit(CNSS_MHI_RDDM_DONE, &pci_priv->mhi_state)) return 0; if (mhi_state < 0) { cnss_pr_err("Invalid MHI state (%d)\n", mhi_state); return -EINVAL; ret = cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_TRIGGER_RDDM); if (ret) { cnss_pr_err("Failed to trigger RDDM, err = %d\n", ret); cnss_schedule_recovery(&pci_priv->pci_dev->dev, CNSS_REASON_DEFAULT); return ret; } ret = cnss_pci_check_mhi_state_bit(pci_priv, mhi_state); if (ret) goto out; if (!test_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state)) { mod_timer(&plat_priv->fw_boot_timer, jiffies + msecs_to_jiffies(FW_ASSERT_TIMEOUT)); } cnss_pr_dbg("Setting MHI state: %s(%d)\n", cnss_mhi_state_to_str(mhi_state), mhi_state); return 0; } #endif void cnss_pci_clear_dump_info(struct cnss_pci_data *pci_priv) { struct cnss_plat_data *plat_priv = pci_priv->plat_priv; plat_priv->ramdump_info_v2.dump_data.nentries = 0; plat_priv->ramdump_info_v2.dump_data_valid = false; } static void cnss_pci_set_mhi_state_bit(struct cnss_pci_data *pci_priv, enum cnss_mhi_state mhi_state) { switch (mhi_state) { case CNSS_MHI_INIT: ret = mhi_prepare_for_power_up(pci_priv->mhi_ctrl); set_bit(CNSS_MHI_INIT, &pci_priv->mhi_state); break; case CNSS_MHI_DEINIT: mhi_unprepare_after_power_down(pci_priv->mhi_ctrl); ret = 0; clear_bit(CNSS_MHI_INIT, &pci_priv->mhi_state); break; case CNSS_MHI_POWER_ON: ret = mhi_sync_power_up(pci_priv->mhi_ctrl); set_bit(CNSS_MHI_POWER_ON, &pci_priv->mhi_state); break; case CNSS_MHI_POWER_OFF: mhi_power_down(pci_priv->mhi_ctrl, true); ret = 0; break; case CNSS_MHI_FORCE_POWER_OFF: mhi_power_down(pci_priv->mhi_ctrl, false); ret = 0; clear_bit(CNSS_MHI_POWER_ON, &pci_priv->mhi_state); clear_bit(CNSS_MHI_RDDM_DONE, &pci_priv->mhi_state); break; case CNSS_MHI_SUSPEND: ret = mhi_pm_suspend(pci_priv->mhi_ctrl); set_bit(CNSS_MHI_SUSPEND, &pci_priv->mhi_state); break; case CNSS_MHI_RESUME: ret = mhi_pm_resume(pci_priv->mhi_ctrl); clear_bit(CNSS_MHI_SUSPEND, &pci_priv->mhi_state); break; case CNSS_MHI_TRIGGER_RDDM: ret = mhi_force_rddm_mode(pci_priv->mhi_ctrl); break; case CNSS_MHI_RDDM_DONE: set_bit(CNSS_MHI_RDDM_DONE, &pci_priv->mhi_state); break; default: cnss_pr_err("Unhandled MHI state (%d)\n", mhi_state); ret = -EINVAL; } if (ret) goto out; cnss_pci_set_mhi_state_bit(pci_priv, mhi_state); return 0; out: cnss_pr_err("Failed to set MHI state: %s(%d)\n", cnss_mhi_state_to_str(mhi_state), mhi_state); return ret; } int cnss_pci_start_mhi(struct cnss_pci_data *pci_priv) Loading drivers/net/wireless/cnss2/pci.h +3 −1 Original line number Diff line number Diff line /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -69,7 +69,9 @@ struct cnss_pci_data { void __iomem *bar; struct cnss_msi_config *msi_config; u32 msi_ep_base_data; #ifdef CONFIG_MHI_BUS struct mhi_controller *mhi_ctrl; #endif unsigned long mhi_state; }; Loading Loading
arch/arm/configs/sdxpoorwills-auto-perf_defconfig +4 −4 Original line number Diff line number Diff line Loading @@ -227,12 +227,12 @@ CONFIG_USB_USBNET=y CONFIG_USB_NET_SMSC75XX=y CONFIG_USB_NET_SMSC95XX=y CONFIG_WCNSS_MEM_PRE_ALLOC=y CONFIG_CNSS=y CONFIG_CNSS_SDIO=y CONFIG_CNSS_PCI=y CONFIG_CNSS2=y CONFIG_CNSS2_DEBUG=y CONFIG_CNSS2_QMI=y CONFIG_CLD_HL_SDIO_CORE=y CONFIG_CLD_LL_CORE=y CONFIG_CNSS_LOGGER=y CONFIG_CNSS_GENL=y # CONFIG_INPUT_MOUSEDEV is not set CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_KEYBOARD is not set Loading
arch/arm/configs/sdxpoorwills-auto_defconfig +4 −4 Original line number Diff line number Diff line Loading @@ -221,12 +221,12 @@ CONFIG_USB_USBNET=y CONFIG_USB_NET_SMSC75XX=y CONFIG_USB_NET_SMSC95XX=y CONFIG_WCNSS_MEM_PRE_ALLOC=y CONFIG_CNSS=y CONFIG_CNSS_SDIO=y CONFIG_CNSS_PCI=y CONFIG_CNSS2=y CONFIG_CNSS2_DEBUG=y CONFIG_CNSS2_QMI=y CONFIG_CLD_HL_SDIO_CORE=y CONFIG_CLD_LL_CORE=y CONFIG_CNSS_LOGGER=y CONFIG_CNSS_GENL=y # CONFIG_INPUT_MOUSEDEV is not set CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_KEYBOARD is not set Loading
drivers/net/wireless/cnss2/pci.c +167 −143 Original line number Diff line number Diff line /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -1523,40 +1523,6 @@ static void cnss_pci_free_m3_mem(struct cnss_pci_data *pci_priv) m3_mem->size = 0; } int cnss_pci_force_fw_assert_hdlr(struct cnss_pci_data *pci_priv) { int ret; struct cnss_plat_data *plat_priv; if (!pci_priv) return -ENODEV; plat_priv = pci_priv->plat_priv; if (!plat_priv) return -ENODEV; if (test_bit(CNSS_MHI_RDDM_DONE, &pci_priv->mhi_state)) { cnss_pr_err("RDDM already collected 0x%x, return\n", pci_priv->mhi_state); return 0; } ret = cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_TRIGGER_RDDM); if (ret) { cnss_pr_err("Failed to trigger RDDM, err = %d\n", ret); cnss_schedule_recovery(&pci_priv->pci_dev->dev, CNSS_REASON_DEFAULT); return 0; } if (!test_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state)) { mod_timer(&plat_priv->fw_boot_timer, jiffies + msecs_to_jiffies(FW_ASSERT_TIMEOUT)); } return 0; } void cnss_pci_fw_boot_timeout_hdlr(struct cnss_pci_data *pci_priv) { if (!pci_priv) Loading Loading @@ -1885,21 +1851,32 @@ static void cnss_pci_disable_bus(struct cnss_pci_data *pci_priv) pci_disable_device(pci_dev); } static int cnss_mhi_pm_runtime_get(struct mhi_controller *mhi_ctrl, void *priv) #ifndef CONFIG_MHI_BUS void cnss_pci_collect_dump_info(struct cnss_pci_data *pci_priv, bool in_panic) { struct cnss_pci_data *pci_priv = priv; } return pm_runtime_get(&pci_priv->pci_dev->dev); static inline int cnss_pci_register_mhi(struct cnss_pci_data *pci_priv) { return -EINVAL; } static void cnss_mhi_pm_runtime_put_noidle(struct mhi_controller *mhi_ctrl, void *priv) static inline void cnss_pci_unregister_mhi(struct cnss_pci_data *pci_priv) { struct cnss_pci_data *pci_priv = priv; } pm_runtime_put_noidle(&pci_priv->pci_dev->dev); inline int cnss_pci_set_mhi_state(struct cnss_pci_data *pci_priv, enum cnss_mhi_state mhi_state) { return -EINVAL; } inline int cnss_pci_force_fw_assert_hdlr(struct cnss_pci_data *pci_priv) { return -EINVAL; } #else static char *cnss_mhi_state_to_str(enum cnss_mhi_state mhi_state) { switch (mhi_state) { Loading @@ -1926,6 +1903,21 @@ static char *cnss_mhi_state_to_str(enum cnss_mhi_state mhi_state) } }; static int cnss_mhi_pm_runtime_get(struct mhi_controller *mhi_ctrl, void *priv) { struct cnss_pci_data *pci_priv = priv; return pm_runtime_get(&pci_priv->pci_dev->dev); } static void cnss_mhi_pm_runtime_put_noidle(struct mhi_controller *mhi_ctrl, void *priv) { struct cnss_pci_data *pci_priv = priv; pm_runtime_put_noidle(&pci_priv->pci_dev->dev); } void cnss_pci_collect_dump_info(struct cnss_pci_data *pci_priv, bool in_panic) { struct cnss_plat_data *plat_priv = pci_priv->plat_priv; Loading Loading @@ -2002,34 +1994,6 @@ void cnss_pci_collect_dump_info(struct cnss_pci_data *pci_priv, bool in_panic) complete(&plat_priv->rddm_complete); } void cnss_pci_clear_dump_info(struct cnss_pci_data *pci_priv) { struct cnss_plat_data *plat_priv = pci_priv->plat_priv; plat_priv->ramdump_info_v2.dump_data.nentries = 0; plat_priv->ramdump_info_v2.dump_data_valid = false; } static int cnss_mhi_link_status(struct mhi_controller *mhi_ctrl, void *priv) { struct cnss_pci_data *pci_priv = priv; u16 device_id; if (!pci_priv) { cnss_pr_err("pci_priv is NULL\n"); return -EINVAL; } pci_read_config_word(pci_priv->pci_dev, PCI_DEVICE_ID, &device_id); if (device_id != pci_priv->device_id) { cnss_pr_err("PCI device ID mismatch, link possibly down, current read ID: 0x%x, record ID: 0x%x\n", device_id, pci_priv->device_id); return -EIO; } return 0; } static void cnss_mhi_notify_status(struct mhi_controller *mhi_ctrl, void *priv, enum MHI_CB reason) { Loading Loading @@ -2172,6 +2136,99 @@ static void cnss_pci_unregister_mhi(struct cnss_pci_data *pci_priv) kfree(mhi_ctrl->irq); } int cnss_pci_set_mhi_state(struct cnss_pci_data *pci_priv, enum cnss_mhi_state mhi_state) { int ret = 0; if (!pci_priv) { cnss_pr_err("pci_priv is NULL!\n"); return -ENODEV; } if (pci_priv->device_id == QCA6174_DEVICE_ID) return 0; if (mhi_state < 0) { cnss_pr_err("Invalid MHI state (%d)\n", mhi_state); return -EINVAL; } ret = cnss_pci_check_mhi_state_bit(pci_priv, mhi_state); if (ret) goto out; cnss_pr_dbg("Setting MHI state: %s(%d)\n", cnss_mhi_state_to_str(mhi_state), mhi_state); switch (mhi_state) { case CNSS_MHI_INIT: ret = mhi_prepare_for_power_up(pci_priv->mhi_ctrl); break; case CNSS_MHI_DEINIT: mhi_unprepare_after_power_down(pci_priv->mhi_ctrl); ret = 0; break; case CNSS_MHI_POWER_ON: ret = mhi_sync_power_up(pci_priv->mhi_ctrl); break; case CNSS_MHI_POWER_OFF: mhi_power_down(pci_priv->mhi_ctrl, true); ret = 0; break; case CNSS_MHI_FORCE_POWER_OFF: mhi_power_down(pci_priv->mhi_ctrl, false); ret = 0; break; case CNSS_MHI_SUSPEND: ret = mhi_pm_suspend(pci_priv->mhi_ctrl); break; case CNSS_MHI_RESUME: ret = mhi_pm_resume(pci_priv->mhi_ctrl); break; case CNSS_MHI_TRIGGER_RDDM: ret = mhi_force_rddm_mode(pci_priv->mhi_ctrl); break; case CNSS_MHI_RDDM_DONE: break; default: cnss_pr_err("Unhandled MHI state (%d)\n", mhi_state); ret = -EINVAL; } if (ret) goto out; cnss_pci_set_mhi_state_bit(pci_priv, mhi_state); return 0; out: cnss_pr_err("Failed to set MHI state: %s(%d)\n", cnss_mhi_state_to_str(mhi_state), mhi_state); return ret; } static int cnss_mhi_link_status(struct mhi_controller *mhi_ctrl, void *priv) { struct cnss_pci_data *pci_priv = priv; u16 device_id; if (!pci_priv) { cnss_pr_err("pci_priv is NULL\n"); return -EINVAL; } pci_read_config_word(pci_priv->pci_dev, PCI_DEVICE_ID, &device_id); if (device_id != pci_priv->device_id) { cnss_pr_err("PCI device ID mismatch, link possibly down, current read ID: 0x%x, record ID: 0x%x\n", device_id, pci_priv->device_id); return -EIO; } return 0; } static int cnss_pci_check_mhi_state_bit(struct cnss_pci_data *pci_priv, enum cnss_mhi_state mhi_state) { Loading Loading @@ -2219,111 +2276,78 @@ static int cnss_pci_check_mhi_state_bit(struct cnss_pci_data *pci_priv, return -EINVAL; } static void cnss_pci_set_mhi_state_bit(struct cnss_pci_data *pci_priv, enum cnss_mhi_state mhi_state) static int cnss_pci_force_fw_assert_hdlr(struct cnss_pci_data *pci_priv) { switch (mhi_state) { case CNSS_MHI_INIT: set_bit(CNSS_MHI_INIT, &pci_priv->mhi_state); break; case CNSS_MHI_DEINIT: clear_bit(CNSS_MHI_INIT, &pci_priv->mhi_state); break; case CNSS_MHI_POWER_ON: set_bit(CNSS_MHI_POWER_ON, &pci_priv->mhi_state); break; case CNSS_MHI_POWER_OFF: case CNSS_MHI_FORCE_POWER_OFF: clear_bit(CNSS_MHI_POWER_ON, &pci_priv->mhi_state); clear_bit(CNSS_MHI_RDDM_DONE, &pci_priv->mhi_state); break; case CNSS_MHI_SUSPEND: set_bit(CNSS_MHI_SUSPEND, &pci_priv->mhi_state); break; case CNSS_MHI_RESUME: clear_bit(CNSS_MHI_SUSPEND, &pci_priv->mhi_state); break; case CNSS_MHI_TRIGGER_RDDM: break; case CNSS_MHI_RDDM_DONE: set_bit(CNSS_MHI_RDDM_DONE, &pci_priv->mhi_state); break; default: cnss_pr_err("Unhandled MHI state (%d)\n", mhi_state); } } int ret; struct cnss_plat_data *plat_priv; int cnss_pci_set_mhi_state(struct cnss_pci_data *pci_priv, enum cnss_mhi_state mhi_state) { int ret = 0; if (!pci_priv) return -ENODEV; if (!pci_priv) { cnss_pr_err("pci_priv is NULL!\n"); plat_priv = pci_priv->plat_priv; if (!plat_priv) return -ENODEV; } if (pci_priv->device_id == QCA6174_DEVICE_ID) if (test_bit(CNSS_MHI_RDDM_DONE, &pci_priv->mhi_state)) return 0; if (mhi_state < 0) { cnss_pr_err("Invalid MHI state (%d)\n", mhi_state); return -EINVAL; ret = cnss_pci_set_mhi_state(pci_priv, CNSS_MHI_TRIGGER_RDDM); if (ret) { cnss_pr_err("Failed to trigger RDDM, err = %d\n", ret); cnss_schedule_recovery(&pci_priv->pci_dev->dev, CNSS_REASON_DEFAULT); return ret; } ret = cnss_pci_check_mhi_state_bit(pci_priv, mhi_state); if (ret) goto out; if (!test_bit(CNSS_DEV_ERR_NOTIFY, &plat_priv->driver_state)) { mod_timer(&plat_priv->fw_boot_timer, jiffies + msecs_to_jiffies(FW_ASSERT_TIMEOUT)); } cnss_pr_dbg("Setting MHI state: %s(%d)\n", cnss_mhi_state_to_str(mhi_state), mhi_state); return 0; } #endif void cnss_pci_clear_dump_info(struct cnss_pci_data *pci_priv) { struct cnss_plat_data *plat_priv = pci_priv->plat_priv; plat_priv->ramdump_info_v2.dump_data.nentries = 0; plat_priv->ramdump_info_v2.dump_data_valid = false; } static void cnss_pci_set_mhi_state_bit(struct cnss_pci_data *pci_priv, enum cnss_mhi_state mhi_state) { switch (mhi_state) { case CNSS_MHI_INIT: ret = mhi_prepare_for_power_up(pci_priv->mhi_ctrl); set_bit(CNSS_MHI_INIT, &pci_priv->mhi_state); break; case CNSS_MHI_DEINIT: mhi_unprepare_after_power_down(pci_priv->mhi_ctrl); ret = 0; clear_bit(CNSS_MHI_INIT, &pci_priv->mhi_state); break; case CNSS_MHI_POWER_ON: ret = mhi_sync_power_up(pci_priv->mhi_ctrl); set_bit(CNSS_MHI_POWER_ON, &pci_priv->mhi_state); break; case CNSS_MHI_POWER_OFF: mhi_power_down(pci_priv->mhi_ctrl, true); ret = 0; break; case CNSS_MHI_FORCE_POWER_OFF: mhi_power_down(pci_priv->mhi_ctrl, false); ret = 0; clear_bit(CNSS_MHI_POWER_ON, &pci_priv->mhi_state); clear_bit(CNSS_MHI_RDDM_DONE, &pci_priv->mhi_state); break; case CNSS_MHI_SUSPEND: ret = mhi_pm_suspend(pci_priv->mhi_ctrl); set_bit(CNSS_MHI_SUSPEND, &pci_priv->mhi_state); break; case CNSS_MHI_RESUME: ret = mhi_pm_resume(pci_priv->mhi_ctrl); clear_bit(CNSS_MHI_SUSPEND, &pci_priv->mhi_state); break; case CNSS_MHI_TRIGGER_RDDM: ret = mhi_force_rddm_mode(pci_priv->mhi_ctrl); break; case CNSS_MHI_RDDM_DONE: set_bit(CNSS_MHI_RDDM_DONE, &pci_priv->mhi_state); break; default: cnss_pr_err("Unhandled MHI state (%d)\n", mhi_state); ret = -EINVAL; } if (ret) goto out; cnss_pci_set_mhi_state_bit(pci_priv, mhi_state); return 0; out: cnss_pr_err("Failed to set MHI state: %s(%d)\n", cnss_mhi_state_to_str(mhi_state), mhi_state); return ret; } int cnss_pci_start_mhi(struct cnss_pci_data *pci_priv) Loading
drivers/net/wireless/cnss2/pci.h +3 −1 Original line number Diff line number Diff line /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -69,7 +69,9 @@ struct cnss_pci_data { void __iomem *bar; struct cnss_msi_config *msi_config; u32 msi_ep_base_data; #ifdef CONFIG_MHI_BUS struct mhi_controller *mhi_ctrl; #endif unsigned long mhi_state; }; Loading