diff options
| author | Rajasekaran Kalidoss <rkalidos@codeaurora.org> | 2019-03-28 14:05:28 +0530 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2019-04-09 17:46:24 -0700 |
| commit | 04235478f2978f84c0d6b3bfd60263e02d66aa4f (patch) | |
| tree | e3363279b85294af5eb1fa9851028fe5a437340c | |
| parent | 9ec08ea59b839ac61ee6fcd9f073e713d35fe3e8 (diff) | |
cnss2: Support USB SSR and disconnect scenarios
For USB devices, irrecoverable scenarios in firmware
can lead to USB bus disconnect. In USB disconnect, the
interface and dev structures passed by USB sub system
are freed and are no longer valid. The current
implementation is PCIe specific and assumes dev struct
being present and valid always. The clean way to handle
this for HL(USB/SDIO) is to call pld_usb_remove in
disconnect and pld_usb_probe in re-connect after a recovery
Change-Id: I3fc9a5a2fc7bb53439b0410e61f381aa94e18634
Signed-off-by: Rajasekaran Kalidoss <rkalidos@codeaurora.org>
| -rw-r--r-- | drivers/net/wireless/cnss2/usb.c | 39 | ||||
| -rw-r--r-- | include/net/cnss2.h | 3 |
2 files changed, 22 insertions, 20 deletions
diff --git a/drivers/net/wireless/cnss2/usb.c b/drivers/net/wireless/cnss2/usb.c index cf4137ac5102..def619e05c9e 100644 --- a/drivers/net/wireless/cnss2/usb.c +++ b/drivers/net/wireless/cnss2/usb.c @@ -173,10 +173,10 @@ int cnss_usb_dev_shutdown(struct cnss_usb_data *usb_priv) case QCN7605_VER20_STANDALONE_DEVICE_ID: case QCN7605_VER20_COMPOSITE_DEVICE_ID: cnss_pr_dbg("cnss driver state %lu\n", plat_priv->driver_state); - if (!test_bit(CNSS_DEV_REMOVED, &plat_priv->driver_state)) + if (!test_bit(CNSS_DEV_REMOVED, &plat_priv->driver_state)) { cnss_usb_call_driver_remove(usb_priv); - - cnss_power_off_device(plat_priv); + cnss_power_off_device(plat_priv); + } clear_bit(CNSS_FW_READY, &plat_priv->driver_state); clear_bit(CNSS_DRIVER_UNLOADING, &plat_priv->driver_state); break; @@ -199,22 +199,12 @@ int cnss_usb_call_driver_probe(struct cnss_usb_data *usb_priv) goto out; } - if (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state) && - test_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state)) { - ret = usb_priv->driver_ops->reinit(usb_priv->usb_intf, - usb_priv->usb_device_id); - if (ret) { - cnss_pr_err("Failed to reinit host driver, err = %d\n", - ret); - goto out; - } - clear_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state); - } else if (test_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state)) { + if (test_bit(CNSS_DRIVER_LOADING, &plat_priv->driver_state) || + test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state)) { ret = usb_priv->driver_ops->probe(usb_priv->usb_intf, usb_priv->usb_device_id); if (ret) { - cnss_pr_err("Failed to probe host driver, err = %d\n", - ret); + cnss_pr_err("Host drv probe failed, err = %d\n", ret); goto out; } clear_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state); @@ -331,15 +321,26 @@ static void cnss_usb_remove(struct usb_interface *interface) struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(NULL); struct cnss_usb_data *usb_priv = plat_priv->bus_priv; - cnss_pr_dbg("driver state %lu\n", plat_priv->driver_state); + del_timer(&plat_priv->fw_boot_timer); + + clear_bit(CNSS_FW_READY, &plat_priv->driver_state); + set_bit(CNSS_DEV_REMOVED, &plat_priv->driver_state); + set_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state); + if (usb_priv->driver_ops) { + cnss_pr_dbg("driver_ops remove state %lu\n", + plat_priv->driver_state); + usb_priv->driver_ops->update_status(usb_priv->usb_intf, + CNSS_FW_DOWN); + usb_priv->driver_ops->remove(usb_priv->usb_intf); + clear_bit(CNSS_DRIVER_PROBED, &plat_priv->driver_state); + } cnss_unregister_ramdump(plat_priv); cnss_unregister_subsys(plat_priv); usb_dev = interface_to_usbdev(interface); usb_put_dev(usb_dev); usb_priv->usb_intf = NULL; usb_priv->usb_device_id = NULL; - set_bit(CNSS_DEV_REMOVED, &plat_priv->driver_state); - del_timer(&plat_priv->fw_boot_timer); + cnss_pr_dbg("driver state %lu\n", plat_priv->driver_state); } static int cnss_usb_suspend(struct usb_interface *interface, pm_message_t state) diff --git a/include/net/cnss2.h b/include/net/cnss2.h index 0b2c9d272fac..de0161915a75 100644 --- a/include/net/cnss2.h +++ b/include/net/cnss2.h @@ -1,4 +1,4 @@ -/* 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 @@ -96,6 +96,7 @@ struct cnss_usb_wlan_driver { int (*suspend)(struct usb_interface *pintf, pm_message_t state); int (*resume)(struct usb_interface *pintf); int (*reset_resume)(struct usb_interface *pintf); + void (*update_status)(struct usb_interface *pintf, uint32_t status); const struct usb_device_id *id_table; }; |
