Loading drivers/usb/gadget/function/f_serial.c +45 −1 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com) * Copyright (C) 2008 by David Brownell * Copyright (C) 2008 by Nokia Corporation * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This software is distributed under the terms of the GNU General * Public License ("GPL") as published by the Free Software Foundation, Loading Loading @@ -643,6 +643,7 @@ static void gser_suspend(struct usb_function *f) static void gser_resume(struct usb_function *f) { struct f_gser *gser = func_to_gser(f); struct usb_composite_dev *cdev = gser->port.func.config->cdev; unsigned port_num; port_num = gserial_ports[gser->port_num].client_port_num; Loading @@ -650,6 +651,13 @@ static void gser_resume(struct usb_function *f) pr_debug("%s: transport: %s f_gser: %p gserial: %p port_num: %d\n", __func__, xport_to_str(gser->transport), gser, &gser->port, gser->port_num); /* * If the function is in USB3 Function Suspend state, resume is * canceled. In this case resume is done by a Function Resume request. */ if ((cdev->gadget->speed == USB_SPEED_SUPER) && f->func_is_suspended) return; switch (gser->transport) { case USB_GADGET_XPORT_SMD: Loading @@ -661,6 +669,40 @@ static void gser_resume(struct usb_function *f) } } static int gser_func_suspend(struct usb_function *f, u8 options) { bool func_wakeup_allowed; pr_debug("func susp %u cmd for %s", options, f->name ? f->name : ""); func_wakeup_allowed = ((options & FUNC_SUSPEND_OPT_RW_EN_MASK) != 0); if (options & FUNC_SUSPEND_OPT_SUSP_MASK) { f->func_wakeup_allowed = func_wakeup_allowed; if (!f->func_is_suspended) { gser_suspend(f); f->func_is_suspended = true; } } else { if (f->func_is_suspended) { f->func_is_suspended = false; gser_resume(f); } f->func_wakeup_allowed = func_wakeup_allowed; } return 0; } static int gser_get_status(struct usb_function *f) { unsigned remote_wakeup_en_status = f->func_wakeup_allowed ? 1 : 0; return (remote_wakeup_en_status << FUNC_WAKEUP_ENABLE_SHIFT) | (1 << FUNC_WAKEUP_CAPABLE_SHIFT); } static int gser_notify(struct f_gser *gser, u8 type, u16 value, void *data, unsigned length) { Loading Loading @@ -1100,6 +1142,8 @@ static struct usb_function *gser_alloc(struct usb_function_instance *fi) gser->port.func.setup = gser_setup; gser->port.func.suspend = gser_suspend; gser->port.func.resume = gser_resume; gser->port.func.func_suspend = gser_func_suspend; gser->port.func.get_status = gser_get_status; gser->port.connect = gser_connect; gser->port.get_dtr = gser_get_dtr; gser->port.get_rts = gser_get_rts; Loading drivers/usb/gadget/function/u_smd.c +11 −6 Original line number Diff line number Diff line /* * u_smd.c - utilities for USB gadget serial over smd * * Copyright (c) 2011, 2013-2015, The Linux Foundation. All rights reserved. * Copyright (c) 2011, 2013-2016, The Linux Foundation. All rights reserved. * * This code also borrows from drivers/usb/gadget/u_serial.c, which is * Copyright (C) 2000 - 2003 Al Borchers (alborchers@steinerpoint.com) Loading Loading @@ -322,13 +322,18 @@ static void gsmd_tx_pull(struct work_struct *w) gadget = func->config->cdev->gadget; if (port->is_suspended) { spin_unlock_irq(&port->port_lock); if ((gadget->speed == USB_SPEED_SUPER) && (func->func_is_suspended)) ret = usb_func_wakeup(func); else ret = usb_gadget_wakeup(gadget); spin_lock_irq(&port->port_lock); if (ret) pr_err("Failed to wake up the USB core. ret=%d.\n", ret); if ((ret == -EBUSY) || (ret == -EAGAIN)) pr_debug("Remote wakeup is delayed due to LPM exit\n"); else if (ret) pr_err("Failed to wake up the USB core. ret=%d\n", ret); spin_lock_irq(&port->port_lock); if (!port->port_usb) { pr_debug("%s: USB disconnected\n", __func__); spin_unlock_irq(&port->port_lock); Loading include/linux/usb/composite.h +3 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,9 @@ #define FUNC_SUSPEND_OPT_SUSP_MASK BIT(0) #define FUNC_SUSPEND_OPT_RW_EN_MASK BIT(1) #define FUNC_WAKEUP_CAPABLE_SHIFT 0 #define FUNC_WAKEUP_ENABLE_SHIFT 1 /* * USB function drivers should return USB_GADGET_DELAYED_STATUS if they * wish to delay the data/status stages of the control transfer till they Loading Loading
drivers/usb/gadget/function/f_serial.c +45 −1 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ * Copyright (C) 2003 Al Borchers (alborchers@steinerpoint.com) * Copyright (C) 2008 by David Brownell * Copyright (C) 2008 by Nokia Corporation * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This software is distributed under the terms of the GNU General * Public License ("GPL") as published by the Free Software Foundation, Loading Loading @@ -643,6 +643,7 @@ static void gser_suspend(struct usb_function *f) static void gser_resume(struct usb_function *f) { struct f_gser *gser = func_to_gser(f); struct usb_composite_dev *cdev = gser->port.func.config->cdev; unsigned port_num; port_num = gserial_ports[gser->port_num].client_port_num; Loading @@ -650,6 +651,13 @@ static void gser_resume(struct usb_function *f) pr_debug("%s: transport: %s f_gser: %p gserial: %p port_num: %d\n", __func__, xport_to_str(gser->transport), gser, &gser->port, gser->port_num); /* * If the function is in USB3 Function Suspend state, resume is * canceled. In this case resume is done by a Function Resume request. */ if ((cdev->gadget->speed == USB_SPEED_SUPER) && f->func_is_suspended) return; switch (gser->transport) { case USB_GADGET_XPORT_SMD: Loading @@ -661,6 +669,40 @@ static void gser_resume(struct usb_function *f) } } static int gser_func_suspend(struct usb_function *f, u8 options) { bool func_wakeup_allowed; pr_debug("func susp %u cmd for %s", options, f->name ? f->name : ""); func_wakeup_allowed = ((options & FUNC_SUSPEND_OPT_RW_EN_MASK) != 0); if (options & FUNC_SUSPEND_OPT_SUSP_MASK) { f->func_wakeup_allowed = func_wakeup_allowed; if (!f->func_is_suspended) { gser_suspend(f); f->func_is_suspended = true; } } else { if (f->func_is_suspended) { f->func_is_suspended = false; gser_resume(f); } f->func_wakeup_allowed = func_wakeup_allowed; } return 0; } static int gser_get_status(struct usb_function *f) { unsigned remote_wakeup_en_status = f->func_wakeup_allowed ? 1 : 0; return (remote_wakeup_en_status << FUNC_WAKEUP_ENABLE_SHIFT) | (1 << FUNC_WAKEUP_CAPABLE_SHIFT); } static int gser_notify(struct f_gser *gser, u8 type, u16 value, void *data, unsigned length) { Loading Loading @@ -1100,6 +1142,8 @@ static struct usb_function *gser_alloc(struct usb_function_instance *fi) gser->port.func.setup = gser_setup; gser->port.func.suspend = gser_suspend; gser->port.func.resume = gser_resume; gser->port.func.func_suspend = gser_func_suspend; gser->port.func.get_status = gser_get_status; gser->port.connect = gser_connect; gser->port.get_dtr = gser_get_dtr; gser->port.get_rts = gser_get_rts; Loading
drivers/usb/gadget/function/u_smd.c +11 −6 Original line number Diff line number Diff line /* * u_smd.c - utilities for USB gadget serial over smd * * Copyright (c) 2011, 2013-2015, The Linux Foundation. All rights reserved. * Copyright (c) 2011, 2013-2016, The Linux Foundation. All rights reserved. * * This code also borrows from drivers/usb/gadget/u_serial.c, which is * Copyright (C) 2000 - 2003 Al Borchers (alborchers@steinerpoint.com) Loading Loading @@ -322,13 +322,18 @@ static void gsmd_tx_pull(struct work_struct *w) gadget = func->config->cdev->gadget; if (port->is_suspended) { spin_unlock_irq(&port->port_lock); if ((gadget->speed == USB_SPEED_SUPER) && (func->func_is_suspended)) ret = usb_func_wakeup(func); else ret = usb_gadget_wakeup(gadget); spin_lock_irq(&port->port_lock); if (ret) pr_err("Failed to wake up the USB core. ret=%d.\n", ret); if ((ret == -EBUSY) || (ret == -EAGAIN)) pr_debug("Remote wakeup is delayed due to LPM exit\n"); else if (ret) pr_err("Failed to wake up the USB core. ret=%d\n", ret); spin_lock_irq(&port->port_lock); if (!port->port_usb) { pr_debug("%s: USB disconnected\n", __func__); spin_unlock_irq(&port->port_lock); Loading
include/linux/usb/composite.h +3 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,9 @@ #define FUNC_SUSPEND_OPT_SUSP_MASK BIT(0) #define FUNC_SUSPEND_OPT_RW_EN_MASK BIT(1) #define FUNC_WAKEUP_CAPABLE_SHIFT 0 #define FUNC_WAKEUP_ENABLE_SHIFT 1 /* * USB function drivers should return USB_GADGET_DELAYED_STATUS if they * wish to delay the data/status stages of the control transfer till they Loading