diff options
author | Howard Yen <howardyen@google.com> | 2021-12-13 22:48:09 +0800 |
---|---|---|
committer | Howard Yen <howardyen@google.com> | 2021-12-23 02:18:45 +0000 |
commit | 758b6c92bb9ddb8d4745cc9c41be21ab7a34df1a (patch) | |
tree | 5521f2baf894110dbbc6c7450eafbc3c0db64185 | |
parent | 099098334e7b6a33ee412e9f14c8813ba561be6b (diff) | |
download | aoc-758b6c92bb9ddb8d4745cc9c41be21ab7a34df1a.tar.gz |
aoc: usb: notify AoC if xhci driver is active
Notify AoC if xhci driver is active when aoc_usb_dev module is reload by
AoC SSR.
Bug: 201670940
Change-Id: Ic7c49ed4d6f97a55026550b66216620375b19033
Signed-off-by: Howard Yen <howardyen@google.com>
-rw-r--r-- | usb/aoc_usb.h | 2 | ||||
-rw-r--r-- | usb/aoc_usb_dev.c | 50 | ||||
-rw-r--r-- | usb/xhci_hooks_impl_whi.c | 7 |
3 files changed, 58 insertions, 1 deletions
diff --git a/usb/aoc_usb.h b/usb/aoc_usb.h index e9ebcfc..8574bc2 100644 --- a/usb/aoc_usb.h +++ b/usb/aoc_usb.h @@ -119,6 +119,8 @@ extern void xhci_update_erst_dequeue(struct xhci_hcd *xhci, union xhci_trb *event_ring_deq); extern int xhci_exynos_register_vendor_ops(struct xhci_vendor_ops *vendor_ops); +int usb_host_mode_state_notify(enum aoc_usb_state usb_state); + int register_aoc_usb_notifier(struct notifier_block *nb); int unregister_aoc_usb_notifier(struct notifier_block *nb); diff --git a/usb/aoc_usb_dev.c b/usb/aoc_usb_dev.c index 0eff9e1..97693db 100644 --- a/usb/aoc_usb_dev.c +++ b/usb/aoc_usb_dev.c @@ -10,6 +10,8 @@ #include <linux/init.h> #include <linux/jiffies.h> #include <linux/module.h> +#include <linux/of_platform.h> +#include <linux/platform_device.h> #include <linux/slab.h> #include "aoc.h" @@ -355,6 +357,51 @@ static void usb_recovery_work(struct work_struct *ws) return; } +static int aoc_usb_match(struct device *dev, void *data) +{ + if (sysfs_streq(dev_driver_string(dev), "xhci-hcd-exynos")) + return 1; + + return 0; +} + +static bool aoc_usb_is_hcd_working() +{ + struct device_node *np; + struct platform_device *pdev; + struct device *udev; + int ret; + + np = of_find_node_by_name(NULL, "dwc3"); + if (!np || !of_device_is_available(np)) { + pr_err("Cannot find dwc3 device node\n"); + return false; + } + + pdev = of_find_device_by_node(np); + if (!pdev) + return false; + + udev = device_find_child(&pdev->dev, NULL, aoc_usb_match); + if (!udev) + return false; + + ret = usb_host_mode_state_notify(USB_CONNECTED); + if (ret) + dev_err(udev, "Notifying AoC for xhci driver status is failed.\n"); + + return true; +} + +static struct work_struct usb_host_mode_checking_ws; +static void usb_host_mode_checking_work(struct work_struct *ws) +{ + if (aoc_usb_is_hcd_working()) + pr_info("USB HCD is working, send notification to AoC\n"); + + return; +} + bool aoc_usb_probe_done; static int aoc_usb_probe(struct aoc_service_dev *adev) { @@ -391,6 +438,8 @@ static int aoc_usb_probe(struct aoc_service_dev *adev) recover_state = NONE; } + schedule_work(&usb_host_mode_checking_ws); + return 0; } @@ -439,6 +488,7 @@ static int __init aoc_usb_init(void) xhci_vendor_helper_init(); usb_vendor_helper_init(); INIT_WORK(&usb_recovery_ws, usb_recovery_work); + INIT_WORK(&usb_host_mode_checking_ws, usb_host_mode_checking_work); return aoc_driver_register(&aoc_usb_driver); } diff --git a/usb/xhci_hooks_impl_whi.c b/usb/xhci_hooks_impl_whi.c index 5a8f131..6c51275 100644 --- a/usb/xhci_hooks_impl_whi.c +++ b/usb/xhci_hooks_impl_whi.c @@ -129,6 +129,11 @@ static int xhci_sync_conn_stat(unsigned int bus_id, unsigned int dev_num, unsign return 0; } +int usb_host_mode_state_notify(enum aoc_usb_state usb_state) +{ + return xhci_sync_conn_stat(0, 0, 0, usb_state); +} + static int xhci_get_isoc_tr_info(u16 ep_id, u16 dir, struct xhci_ring *ep_ring) { struct get_isoc_tr_info_args tr_info; @@ -595,7 +600,7 @@ static void usb_audio_offload_cleanup(struct xhci_hcd *xhci) usb_unregister_notify(&xhci_udev_nb); /* Notification for xhci driver removing */ - xhci_sync_conn_stat(0, 0, 0, 0); + usb_host_mode_state_notify(USB_DISCONNECTED); mutex_destroy(&vendor_data->lock); |