From: Wan Ahmad Zainie <wan.ahmad.zainie.wan.moha...@intel.com> This modification generates a 'uevent' to userland and adds the 'OVERCURRENT=1' environment when overcurrent event happens and adds the 'OVERCURRENT=0' environment when returning to normal current condition, with PORT number.
Any userland program listening to the 'uevent' interface can filter for the presence of this environment variable to distinguish this special 'uevent' from other 'add' or 'remove' events. Current disadvantage: Due to the fact, the hub driver tries to enable the port again immediately (it does not wait for user interaction) this powerfail event gets reported twice: First time when it really happens and second time when the external overcurrent detection device will be reset. The second false positive report must be sorted out by the userland application. This patch is derived from [PATCH] Generate a uevent when an overcurrent event happens by Juergen Beisert <jbe@@pengutronix.de> and Michael Grzeschik <m.grzeschik@@pengutronix>. Signed-off-by: Wan Ahmad Zainie <wan.ahmad.zainie.wan.moha...@intel.com> --- drivers/usb/core/Kconfig | 8 ++++++++ drivers/usb/core/hub.c | 41 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index a99c89e..560e455 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig @@ -84,6 +84,14 @@ config USB_OTG_FSM Implements OTG Finite State Machine as specified in On-The-Go and Embedded Host Supplement to the USB Revision 2.0 Specification. +config USB_OC_NOTIFICATION + bool "Enable Over Current Notification" + default n + help + Say Y here if you want to send uevent to userland for + over current condition on USB ports and ports coming to + normal state after over current condition is over. + config USB_ULPI_BUS tristate "USB ULPI PHY interface support" depends on USB_SUPPORT diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 563d84e..def3200 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -4891,6 +4891,16 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, usb_lock_port(port_dev); } +#ifdef CONFIG_USB_OC_NOTIFICATION +char oc_event[] = "OVERCURRENT=1"; +char oc_port[10]; +char *oc_envp[] = {oc_event, oc_port, NULL}; +char nc_event[] = "OVERCURRENT=0"; +char nc_port[10]; +char *nc_envp[] = {nc_event, nc_port, NULL}; +static int oc_flag; +#endif + static void port_event(struct usb_hub *hub, int port1) __must_hold(&port_dev->status_lock) { @@ -4934,13 +4944,42 @@ static void port_event(struct usb_hub *hub, int port1) u16 status = 0, unused; dev_dbg(&port_dev->dev, "over-current change\n"); +#ifdef CONFIG_USB_OC_NOTIFICATION + if (oc_flag & BIT(port1 - 1)) { + /* + * Send event to userland for overcurrent condition + * change at port with port number. + */ + snprintf(oc_port, sizeof(oc_port), "NPORT=%d", port1); + if (kobject_uevent_env(&hub->intfdev->kobj, + KOBJ_CHANGE, nc_envp)) + dev_err(&port_dev->dev, + "failed to send change OC event.\n"); + /* Clear port's oc_flag. */ + oc_flag &= ~(BIT(port1 - 1)); + } +#endif usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_OVER_CURRENT); msleep(100); /* Cool down */ hub_power_on(hub, true); hub_port_status(hub, port1, &status, &unused); - if (status & USB_PORT_STAT_OVERCURRENT) + if (status & USB_PORT_STAT_OVERCURRENT) { dev_err(&port_dev->dev, "over-current condition\n"); +#ifdef CONFIG_USB_OC_NOTIFICATION + /* + * Send event to userland for overcurrent condition + * with port number. + */ + snprintf(oc_port, sizeof(oc_port), "OCPORT=%d", port1); + if (kobject_uevent_env(&hub->intfdev->kobj, + KOBJ_CHANGE, oc_envp)) + dev_err(&port_dev->dev, + "failed to send OC event.\n"); + /* Set port's oc_flag. */ + oc_flag |= BIT(port1 - 1); +#endif + } } if (portchange & USB_PORT_STAT_C_RESET) { -- 1.9.1 -- _______________________________________________ linux-yocto mailing list linux-yocto@yoctoproject.org https://lists.yoctoproject.org/listinfo/linux-yocto