ANDROID: GKI: usb: hcd: Add USB atomic notifier callback for HC died error

Add support for USB atomic notifier callbacks when host controller
drivers reports death of controller on some fatal error.
Current implementation doesn't help to recover from this condition.
Controller platform drivers can register for this callback and take
necessary steps to reset and add hcd again.

Bug: 152001148
Test: Builds

Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
(cherry picked from commit b31fc5d204)
Signed-off-by: Sandeep Patil <sspatil@google.com>
Change-Id: Ie9064e669424096fee8c35cddccab29faf60cc6b
Signed-off-by: Will McVicker <willmcvicker@google.com>
This commit is contained in:
Manu Gautam
2016-08-12 16:55:26 +05:30
committed by Will McVicker
parent fbfc98114a
commit 639d56b96d
4 changed files with 36 additions and 0 deletions

View File

@@ -2543,6 +2543,7 @@ void usb_hc_died (struct usb_hcd *hcd)
}
spin_unlock_irqrestore (&hcd_root_hub_lock, flags);
/* Make sure that the other roothub is also deallocated. */
usb_atomic_notify_dead_bus(&hcd->self);
}
EXPORT_SYMBOL_GPL (usb_hc_died);

View File

@@ -19,6 +19,7 @@
#include "usb.h"
static BLOCKING_NOTIFIER_HEAD(usb_notifier_list);
static ATOMIC_NOTIFIER_HEAD(usb_atomic_notifier_list);
/**
* usb_register_notify - register a notifier callback whenever a usb change happens
@@ -69,3 +70,33 @@ void usb_notify_remove_bus(struct usb_bus *ubus)
{
blocking_notifier_call_chain(&usb_notifier_list, USB_BUS_REMOVE, ubus);
}
/**
* usb_register_atomic_notify - register a atomic notifier callback whenever a
* HC dies
* @nb: pointer to the atomic notifier block for the callback events.
*
*/
void usb_register_atomic_notify(struct notifier_block *nb)
{
atomic_notifier_chain_register(&usb_atomic_notifier_list, nb);
}
EXPORT_SYMBOL_GPL(usb_register_atomic_notify);
/**
* usb_unregister_atomic_notify - unregister a atomic notifier callback
* @nb: pointer to the notifier block for the callback events.
*
*/
void usb_unregister_atomic_notify(struct notifier_block *nb)
{
atomic_notifier_chain_unregister(&usb_atomic_notifier_list, nb);
}
EXPORT_SYMBOL_GPL(usb_unregister_atomic_notify);
void usb_atomic_notify_dead_bus(struct usb_bus *ubus)
{
atomic_notifier_call_chain(&usb_atomic_notifier_list, USB_BUS_DIED,
ubus);
}

View File

@@ -192,6 +192,7 @@ extern void usb_notify_add_device(struct usb_device *udev);
extern void usb_notify_remove_device(struct usb_device *udev);
extern void usb_notify_add_bus(struct usb_bus *ubus);
extern void usb_notify_remove_bus(struct usb_bus *ubus);
extern void usb_atomic_notify_dead_bus(struct usb_bus *ubus);
extern void usb_hub_adjust_deviceremovable(struct usb_device *hdev,
struct usb_hub_descriptor *desc);

View File

@@ -2007,8 +2007,11 @@ static inline int usb_translate_errors(int error_code)
#define USB_DEVICE_REMOVE 0x0002
#define USB_BUS_ADD 0x0003
#define USB_BUS_REMOVE 0x0004
#define USB_BUS_DIED 0x0005
extern void usb_register_notify(struct notifier_block *nb);
extern void usb_unregister_notify(struct notifier_block *nb);
extern void usb_register_atomic_notify(struct notifier_block *nb);
extern void usb_unregister_atomic_notify(struct notifier_block *nb);
/* debugfs stuff */
extern struct dentry *usb_debug_root;