i.MX28 usb_wakeup Blocking on Resume

cancel
Showing results for 
Search instead for 
Did you mean: 

i.MX28 usb_wakeup Blocking on Resume

Jump to solution
3,320 Views
SteveO1z
Contributor II

Hi, all:

I'm currently experiencing an issue on a board very similar to the i.MX28 dev board, running the 2.6.35_10.12.01 Linux kernel. What is happening is that after an extended period of standby sleep (so far longer than a half-hour), on occasion the system will resume running extremely slowly and unresponsively. This continues until the system is put back into standby and re-awakened. I was able to determine that the process listed as "[usb_wakeup thre]" was consuming 93% - 98% of CPU cycles and never stops this level of CPU usage. Nothing is plugged into either of the USB ports. The USB's are not set as wake-up sources and in fact the system does not wake up on insertion of flash drives or a host.

Has anyone experienced this issue on the i.MX28? Thanks in advance for any help or advice.

Labels (2)
1 Solution
476 Views
bartthoelen
Contributor II

I use the file_storage gadget.  In this gadget suspend and resume are implemented as a NOP function.  But this should be the same as no suspend/resume functionality.

With the fix added, the gadget never enumerates correctly; without the fix, it works all the time - although I noted the [usb_wakeup thre] consuming a lot of cpu.

View solution in original post

0 Kudos
19 Replies
476 Views
binoyjayan
Contributor III

This issue got resolved using the new BSP provided by freescale.

I downloaded this and merged all my changes to this BSP.

Find the newbsp here.

i.MX28 Software and Development Tool Resources Product Summary Page

On this page, go to Linux-> Linux Source Code files


0 Kudos
476 Views
eik
Contributor I

Hi all,

I am currently suffering the same issue.

In my case, when I load the 'g_ether' module, the process listed as "[usb_wakeup thre]" starts to consume 93% - 98% of CPU cycles, and it only stops this level of CPU usage if the USB is connected to my PC. If I disconnect the USB from my PC, the "usb_wakeup thre" come back again consuming almost the 100% of CPU cycles.

Thanks in advance for any help or advice.


Héctor

0 Kudos
476 Views
leonsun
Contributor I

Hi Bart,

I'm glad to know the problem has been fixed. Thanks for letting us know. It confirms that my fix didn't cause other issues. It's indeed a simple and perfect fix.

Thanks,

Leon

0 Kudos
476 Views
leonsun
Contributor I

The wakeup issue has been identified as a fake wakeup issue which is caused by static discharge. It can be from air or on contact. The following are the changes need to be made.

1. In ../arch/arm/mach-mx28/usb_dr.c, add the following code.

static void usbotg_wakeup_event_clear(void)

{

         void __iomem *phy_reg = IO_ADDRESS(USBPHY0_PHYS_ADDR);

         u32 wakeup_irq_bits;

         wakeup_irq_bits = BM_USBPHY_CTRL_RESUME_IRQ | BM_USBPHY_CTRL_WAKEUP_IRQ;

         if (__raw_readl(phy_reg + HW_USBPHY_CTRL) && wakeup_irq_bits) {

                 /* clear the wakeup interrupt status */

                 __raw_writel(wakeup_irq_bits, phy_reg + HW_USBPHY_CTRL_CLR);

         }

}

static struct fsl_usb2_wakeup_platform_data usbdr_wakeup_config = {

               .name = "DR wakeup",

               .usb_clock_for_pm  = usbotg_clock_gate,

               .usb_wakeup_exhandle = usbotg_wakeup_event_clear,

};

2. In ../linux/ include/linux/fsl_devices.h, add the following changes.

struct fsl_usb2_wakeup_platform_data {

               char *name;

               void (*usb_clock_for_pm) (bool);

               void (*usb_wakeup_exhandle) (void);

               struct fsl_usb2_platform_data *usb_pdata[3];

               /* This waitqueue is used to wait "usb_wakeup thread" to finish

               * during system resume routine. "usb_wakeup theard" should be finished

               * prior to usb resume routine.

               */

               wait_queue_head_t wq;

               /* This flag is used to indicate the "usb_wakeup thread" is finished during

               * usb wakeup routine.

               */

               bool usb_wakeup_is_pending;

               /* Store ctrl ptr so that usb_wakeup.c knows who should die at

               * wakeup_dev_exit() */

               void * ctrl;

};

3. In ../arch/arm/plat-mxs/usb_wakeup.c, add the following changes.

static void wakeup_event_handler(struct wakeup_ctrl *ctrl)

{

               struct fsl_usb2_wakeup_platform_data *pdata = ctrl->pdata;

               int already_waked = 0;

               int i;

               wakeup_clk_gate(ctrl->pdata, true);

               /* if this is an wakeup event, we should debounce ID pin

               * so we can get the correct ID value(ID status) here

               * */

               if (usb_event_is_otg_wakeup())

                              usb_debounce_id_pin();

               for (i = 0; i < 3; i++) {

                              struct fsl_usb2_platform_data *usb_pdata = pdata->usb_pdata[i];

                              if (usb_pdata) {

                                             if (is_wakeup(usb_pdata)) {

                                                            usb_pdata->wakeup_event = 1;

                                                            if (usb2_is_in_lowpower(ctrl))

                                                                           if (usb_pdata->usb_clock_for_pm)

                                                                                          usb_pdata->usb_clock_for_pm(true);

                                                            usb_pdata->lowpower = 0;

                                                            already_waked = 1;

                                             }

                              }

               }

               if (already_waked == 0)

               {              /* If nothing to wakeup, clear wakeup event */

                              /* It's a fake wakeup caused by static discharge. */

                             pdata->usb_wakeup_exhandle();

               }

               else

               {

                              /* Normal wakeup caused by shorting USB ID pin to ground or plug in a USB drive. */

                              wakeup_clk_gate(ctrl->pdata, false);

                              pdata->usb_wakeup_is_pending = false;

                              wake_up(&pdata->wq);

               }

}

476 Views
bartthoelen
Contributor II

Hi,

I tried the fix as given above, but now my gadget does no longer enumerate correctly on the host - this when the ID pins is 1 and a host connected usb0.

Anyone having the same issue ??

Thanks,

Bart

0 Kudos
476 Views
binoyjayan
Contributor III


With or without the fix, my board configured as printer gadget is not enumerated after a Suspend-Resume cycle.

0 Kudos
477 Views
bartthoelen
Contributor II

I use the file_storage gadget.  In this gadget suspend and resume are implemented as a NOP function.  But this should be the same as no suspend/resume functionality.

With the fix added, the gadget never enumerates correctly; without the fix, it works all the time - although I noted the [usb_wakeup thre] consuming a lot of cpu.

View solution in original post

0 Kudos
476 Views
binoyjayan
Contributor III

Hi Bart,

I have disabled the USB host support (USB_CONFIG) in my board and have only the printer gadget enabled.

Could you tell me what you meant when you said that you re-enabled the suspend / resume functions in the host driver.? Which is the driver file that you are referring to.?

After a suspend-resume cycle, the board stops being enumerated as a printer gadget when connected to a PC though USB cable.

Thanks,

Binoy


0 Kudos
476 Views
bartthoelen
Contributor II

Hi,

I had the .suspend and .resume function pointers commented out in the

freescale usb-host driver (file: ehci-arc.c).

After removing the comment, things worked as should be.

I have applied all latest freescale patches as well.

Note: I do use both host and gadget on usb0 - so CONFIG_USB is set in

my config.

Regards,

Bart

0 Kudos
476 Views
binoyjayan
Contributor III

Hi,

I did not have host support enabled on usb0 initially, but I tried enabling the same now.

The effect is still the same.

Has anyone else encountered this problem with a printer gadget.?

Thanks,

Binoy

0 Kudos
476 Views
bartthoelen
Contributor II

Hi,

The resume / suspend in the USB host driver got commented out of my sources.  With these functions enabled again this are working just fine.

Grtz,

Bart

0 Kudos
476 Views
binoyjayan
Contributor III

Thank you. Will try this out.

0 Kudos
476 Views
binoyjayan
Contributor III

Hi Everyone,

I am experiencing the same problem here. I noticed this when I designed a power management application. When the system resumed after a suspend, the CPU usage shoots up to the maximum possible levels and the interrupts keep coming in the usb_wakeup line.

Has anyone been able to fix this yet?

Thanks

Binoy

0 Kudos
476 Views
mbuch
Contributor I

I have found an easier way to re-create the issue Steve O reported.

Short the ID pin on the USB OTG port to ground, but just do it somewhat quickly (do not hold the short too long).  The idea is to just get noise on the ID line.  I modified one of my boards with a pushbutton that I can press to generate the error (I just push the button a few times and I get the error).  If you do not want to do that, then just use a probe.  Conveniently the shell of the USB connector and pin 5 are both grounds.

You can check for the error in two ways (both mentioned previously in this thread)

$ cat /proc/interrupts | grep usb

You should see that Interrupt 95 (the USB OTG Wakeup interrupt) has a large count and is increasing quickly

$ top

you should see "usb_wakeup thread" taking over 80% of the CPU time

To clear the fault, you have to hold the ID pin to ground for an extended time.

So it seems for some reason the system gets into a state where it cannot clear interrupt 95.  Almost like the line is unstable or something.

Has anyone experienced this?  Is there anything that can be done to avoid this?

Thanks!


0 Kudos
476 Views
YS
Contributor IV

May or may not related...

I experienced when I plug a USB memory stick and suspend/resume, kernel dump out message on console;

irq 94: nobody cared (try booting with the "irqpoll" option)

Backtrace:

[<c0023334>] (dump_backtrace+0x0/0x114) from [<c023dbd4>] (dump_stack+0x18/0x1c) r7:00000103 r6:00000000 r5:0000005e r4:c02ef138

.

.

.

Disabling IRQ #94

When I checked /proc/interrupts, sure there is 100,000 interrupts to IRQ94 which is USB wakeup.

92:         48           -  fsl ehci pre interrupt, ehci_hcd:usb2

93:          0           -  fsl ehci pre interrupt, ehci_hcd:usb1

94:     100000           -  usb_wakeup

95:          0           -  usb_wakeup

You have to configure the Kernel to turn on "Run-time PM core functionality" and "USB runtime power management (suspend/resume and wakeup)" in order to make iMX28 USB wakeup/suspend works as designed. Both configs are ending up CONFIG_PM_RUNTIME and CONFIG_USB_SUSPEND in .config file.


0 Kudos
476 Views
juwen
Contributor I

USB0 ( device function only ),when linux OS suspend and resume come back, it does not work and report a large number of wakeup interrupt, and system running slow. lastest patches do not have something about it, please help me!


Best Regards

0 Kudos
476 Views
imxcommunitysco
Senior Contributor II

Can you please try using the lastest patches from

http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git/log/?h=imx_2.6.35_10.12.01

Regards,

0 Kudos
476 Views
SteveO1z
Contributor II

Thanks for the reply. The patches do not address the issue, we are still experiencing usb_wakeup process consuming all processor cycles occasionally on resume from sleep. Any other ideas?

Regards,

Steve O


0 Kudos
476 Views
babur
Contributor II

I've faced almost same problem with 2.6.35 and Gingerbread.

This problem is never occur ADB Connector plugged-in. Also this problem came after my custom LCD redefinitons. When i modify the Board specific LCD parameter, the PM problem occured. I can't resolve.:(

0 Kudos