From 28a0241ccd48963a13638c1dfbef161ab1bf557e Mon Sep 17 00:00:00 2001 From: patacongo Date: Thu, 31 Jan 2013 19:20:26 +0000 Subject: Missing calls to class SUSPEND/RESUME methods in all USB drivers git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5590 42af7a65-404d-4744-a932-0658087f49c3 --- nuttx/arch/arm/src/lpc31xx/lpc31_usbdev.c | 51 ++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 7 deletions(-) (limited to 'nuttx/arch/arm/src/lpc31xx/lpc31_usbdev.c') diff --git a/nuttx/arch/arm/src/lpc31xx/lpc31_usbdev.c b/nuttx/arch/arm/src/lpc31xx/lpc31_usbdev.c index 386abb5b8..ddeb1bf6b 100644 --- a/nuttx/arch/arm/src/lpc31xx/lpc31_usbdev.c +++ b/nuttx/arch/arm/src/lpc31xx/lpc31_usbdev.c @@ -6,7 +6,7 @@ * * Part of the NuttX OS and based, in part, on the LPC2148 USB driver: * - * Copyright (C) 2010-2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2010-2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -160,8 +160,9 @@ #define LPC31_TRACEINTID_IFGETSTATUS 0x0015 #define LPC31_TRACEINTID_SETCONFIG 0x0016 #define LPC31_TRACEINTID_SETFEATURE 0x0017 -#define LPC31_TRACEINTID_SUSPENDCHG 0x0018 -#define LPC31_TRACEINTID_SYNCHFRAME 0x0019 +#define LPC31_TRACEINTID_SUSPENDED 0x0018 +#define LPC31_TRACEINTID_RESUMED 0x0019 +#define LPC31_TRACEINTID_SYNCHFRAME 0x001a /* Hardware interface **********************************************************/ @@ -309,6 +310,7 @@ struct lpc31_usbdev_s uint8_t selfpowered:1; /* 1: Device is self powered */ uint8_t paddrset:1; /* 1: Peripheral addr has been set */ uint8_t attached:1; /* 1: Host attached */ + uint8_t suspended:1; /* 1: Suspended */ uint32_t softprio; /* Bitset of high priority interrupts */ uint32_t epavail; /* Bitset of available endpoints */ #ifdef CONFIG_LPC31_USBDEV_FRAME_INTERRUPT @@ -1065,7 +1067,9 @@ static void lpc31_usbreset(struct lpc31_usbdev_s *priv) * driver should then accept any new configurations. */ if (priv->driver) + { CLASS_DISCONNECT(priv->driver, &priv->usbdev); + } /* Set the interrupt Threshold control interval to 0 */ lpc31_chgbits(USBDEV_USBCMD_ITC_MASK, USBDEV_USBCMD_ITCIMME, LPC31_USBDEV_USBCMD); @@ -1649,6 +1653,7 @@ static int lpc31_usbinterrupt(int irq, FAR void *context) usbtrace(TRACE_INTENTRY(LPC31_TRACEINTID_USB), 0); /* Read the interrupts and then clear them */ + disr = lpc31_getreg(LPC31_USBDEV_USBSTS); lpc31_putreg(disr, LPC31_USBDEV_USBSTS); @@ -1661,11 +1666,43 @@ static int lpc31_usbinterrupt(int irq, FAR void *context) usbtrace(TRACE_INTEXIT(LPC31_TRACEINTID_USB), 0); return OK; } - - if (disr & USBDEV_USBSTS_SLI) + + /* When the device controller enters a suspend state from an active state, + * the SLI bit will be set to a one. + */ + + if (!priv->suspended && (disr & USBDEV_USBSTS_SLI) != 0) { - // FIXME: what do we need to do here... - usbtrace(TRACE_INTDECODE(LPC31_TRACEINTID_SUSPENDCHG),0); + usbtrace(TRACE_INTDECODE(LPC31_TRACEINTID_SUSPENDED),0); + + /* Inform the Class driver of the suspend event */ + + priv->suspended = 1; + if (priv->driver) + { + CLASS_SUSPEND(priv->driver, &priv->usbdev); + } + + /* TODO: Perform power management operations here. */ + } + + /* The device controller clears the SLI bit upon exiting from a suspend + * state. This bit can also be cleared by software writing a one to it. + */ + + else if (priv->suspended && (disr & USBDEV_USBSTS_SLI) == 0) + { + usbtrace(TRACE_INTDECODE(LPC31_TRACEINTID_RESUMED),0); + + /* Inform the Class driver of the resume event */ + + priv->suspended = 0; + if (priv->driver) + { + CLASS_RESUME(priv->driver, &priv->usbdev); + } + + /* TODO: Perform power management operations here. */ } if (disr & USBDEV_USBSTS_PCI) -- cgit v1.2.3