Skip to content

Commit 1742b76

Browse files
Chunfeng Yungregkh
authored andcommitted
usb: mtu3: support function remote wakeup
Add function wake notification to support function remote wakeup, currently assume the composite device only enable function wake for the first interface. Forward request to function driver when the recipient is an interface, including: GetStatus() request to the first interface in a function returns the information about 'function remote wakeup' and 'function remote wakeup capalbe'; SetFeature request of FUNCTION_SUSPEND to an interface recipient, the controller driver saves the suspend option; Signed-off-by: Chunfeng Yun <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 683ff6e commit 1742b76

File tree

3 files changed

+38
-4
lines changed

3 files changed

+38
-4
lines changed

drivers/usb/mtu3/mtu3_gadget.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,13 @@ static int mtu3_gadget_get_frame(struct usb_gadget *gadget)
433433
return (int)mtu3_readl(mtu->mac_base, U3D_USB20_FRAME_NUM);
434434
}
435435

436+
static void function_wake_notif(struct mtu3 *mtu, u8 intf)
437+
{
438+
mtu3_writel(mtu->mac_base, U3D_DEV_NOTIF_0,
439+
TYPE_FUNCTION_WAKE | DEV_NOTIF_VAL_FW(intf));
440+
mtu3_setbits(mtu->mac_base, U3D_DEV_NOTIF_0, SEND_DEV_NOTIF);
441+
}
442+
436443
static int mtu3_gadget_wakeup(struct usb_gadget *gadget)
437444
{
438445
struct mtu3 *mtu = gadget_to_mtu3(gadget);
@@ -446,7 +453,18 @@ static int mtu3_gadget_wakeup(struct usb_gadget *gadget)
446453

447454
spin_lock_irqsave(&mtu->lock, flags);
448455
if (mtu->g.speed >= USB_SPEED_SUPER) {
456+
/*
457+
* class driver may do function wakeup even UFP is in U0,
458+
* and UX_EXIT only takes effect in U1/U2/U3;
459+
*/
449460
mtu3_setbits(mtu->mac_base, U3D_LINK_POWER_CONTROL, UX_EXIT);
461+
/*
462+
* Assume there's only one function on the composite device
463+
* and enable remote wake for the first interface.
464+
* FIXME if the IAD (interface association descriptor) shows
465+
* there is more than one function.
466+
*/
467+
function_wake_notif(mtu, 0);
450468
} else {
451469
mtu3_setbits(mtu->mac_base, U3D_POWER_MANAGEMENT, RESUME);
452470
spin_unlock_irqrestore(&mtu->lock, flags);

drivers/usb/mtu3/mtu3_gadget_ep0.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,8 @@ ep0_get_status(struct mtu3 *mtu, const struct usb_ctrlrequest *setup)
226226

227227
break;
228228
case USB_RECIP_INTERFACE:
229+
/* status of function remote wakeup, forward request */
230+
handled = 0;
229231
break;
230232
case USB_RECIP_ENDPOINT:
231233
epnum = (u8) le16_to_cpu(setup->wIndex);
@@ -397,10 +399,8 @@ static int ep0_handle_feature(struct mtu3 *mtu,
397399
/* superspeed only */
398400
if (value == USB_INTRF_FUNC_SUSPEND &&
399401
mtu->g.speed >= USB_SPEED_SUPER) {
400-
/*
401-
* forward the request because function drivers
402-
* should handle it
403-
*/
402+
/* forward the request for function suspend */
403+
mtu->may_wakeup = !!(index & USB_INTRF_FUNC_SUSPEND_RW);
404404
handled = 0;
405405
}
406406
break;

drivers/usb/mtu3/mtu3_hw_regs.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,8 @@
341341
#define U3D_LINK_UX_INACT_TIMER (SSUSB_USB3_SYS_CSR_BASE + 0x020C)
342342
#define U3D_LINK_POWER_CONTROL (SSUSB_USB3_SYS_CSR_BASE + 0x0210)
343343
#define U3D_LINK_ERR_COUNT (SSUSB_USB3_SYS_CSR_BASE + 0x0214)
344+
#define U3D_DEV_NOTIF_0 (SSUSB_USB3_SYS_CSR_BASE + 0x0290)
345+
#define U3D_DEV_NOTIF_1 (SSUSB_USB3_SYS_CSR_BASE + 0x0294)
344346

345347
/*---------------- SSUSB_USB3_SYS_CSR FIELD DEFINITION ----------------*/
346348

@@ -365,6 +367,20 @@
365367
#define CLR_LINK_ERR_CNT BIT(16)
366368
#define LINK_ERROR_COUNT GENMASK(15, 0)
367369

370+
/* U3D_DEV_NOTIF_0 */
371+
#define DEV_NOTIF_TYPE_SPECIFIC_LOW_MSK GENMASK(31, 8)
372+
#define DEV_NOTIF_VAL_FW(x) (((x) & 0xff) << 8)
373+
#define DEV_NOTIF_VAL_LTM(x) (((x) & 0xfff) << 8)
374+
#define DEV_NOTIF_VAL_IAM(x) (((x) & 0xffff) << 8)
375+
#define DEV_NOTIF_TYPE_MSK GENMASK(7, 4)
376+
/* Notification Type */
377+
#define TYPE_FUNCTION_WAKE (0x1 << 4)
378+
#define TYPE_LATENCY_TOLERANCE_MESSAGE (0x2 << 4)
379+
#define TYPE_BUS_INTERVAL_ADJUST_MESSAGE (0x3 << 4)
380+
#define TYPE_HOST_ROLE_REQUEST (0x4 << 4)
381+
#define TYPE_SUBLINK_SPEED (0x5 << 4)
382+
#define SEND_DEV_NOTIF BIT(0)
383+
368384
/*---------------- SSUSB_USB2_CSR REGISTER DEFINITION ----------------*/
369385

370386
#define U3D_POWER_MANAGEMENT (SSUSB_USB2_CSR_BASE + 0x0004)

0 commit comments

Comments
 (0)