Re: mmc: sdio: runtime PM and 8686 problems

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 26 Apr 2012 16:51:10 -0700 Steve Sakoman <sakoman@xxxxxxxxx> wrote:

> On Mon, Dec 19, 2011 at 1:10 AM, Ohad Ben-Cohen <ohad@xxxxxxxxxx> wrote:
> 
> > We're slowly progressing towards understanding the issues we have with
> > the 8686 (it seems there are a few different hw revisions of it, some
> > of which do require toggling the reset pin before sending another init
> > sequence), but it might take some more time until a solution fully
> > materializes.
> >
> > Since 3.2 is just around the corner, I suggest we should now proceed
> > with the revert (see patch below), and later revisit this once we have
> > a complete solution in hand.
> 
> Has any progress been made on this issue?
> 
> I too have been trying to power down/up the wifi module on the Overo.
> I'm seeing the same issue described in this thread.
> 
> Some additional data:
> 
> I rebuilt my kernel (3.2) with a CD GPIO enabled for the mmc port the module
> is connected to and in turn connected that GPIO to another one that I
> can toggle from user space.
> 
> Toggling the CD GPIO after powering back up the module does indeed
> work properly -- the module is detected, the driver loaded, and proper function
> restored.
> 
> So basically the procedure I've used is:
> 
> - decide wifi can be powered down
> - unload the libertas modules
> - put the wifi hw in reset with gpio16
> - wait till wifi is needed again
> - take the chip out of reset
> - toggle the CD gpio
> - libertas modules are autoloaded, as is the firmware
> - wifi is up and functioning
> 
> So the next step is to get rid of the silly two GPIO external hardware
> hack.  Is it possible to trigger a card insertion/removal event via
> some standard API?
> 
> Or does the above information provide a clue as to why normal code
> paths don't work?
> 
> Any other ideas?

I thought I had a nicely working solution, but I recently discovered that it
doesn't work as well as I thought it did.  I now think we need some help from
the mmc layer to get it really working.

My understanding of the underlying problem is that the wifi chip can get
into a state where it really needs a hardware reset, but it isn't given one.
Applying the reset at the right time is needed.

When the mmc layer wants to power-up the device, it tells the configured
regulator to turn on, then sends some standard command sequence.
If the regulator was actually off, this works (I think - it is a while since
I experimented).  However if the regulator wasn't actually off, it doesn't
work - the wifi chip gets confused by getting the init sequence when it is
already inited, and fails to continue.
So pulsing the resent line low after turning on the power is necessary and
sufficient.
In my case, the regulator is shared by the bluetooth and the wifi so if
bluetooth is on while the wifi is off the regulator never gets turned off,
and so bad things happen when we try to turn the wifi back on.

I had worked around this by defining a separate 'fixed' regulator to power
the wifi chip.  It declared the real regulator as the 'supply' regulator so
that when the mmc driver turns on this pseudo regulator, the real one gets
turned on too.  The 'fixed' regulator can drive a gpio and I configured it to
drive the wifi reset line.  So when the regulator was turned off, the wifi
was held in reset.  When the regulator was turned back on, the reset was
release, the power was on, and it all worked beautifully.

But there are two problems with this:
 1/ the reset line is also shared with the bluetooth :-( so I cannot hold it
    down.  It is safe to pulse it down, but the 'fixed' regulator won't do
    that (without a bit of hacking)
 2/ When the voltage is set for the 'fixed' regulator, it is not propagated
    back to the real regulator, so the real regulator's voltage doesn't get
    set properly to make the requirements of the wifi chip.

I can work around the first problem by hacking the 'fixed' regulator, but I
wouldn't expect that hack to go upstream.

I can work around the second by observing the hsmmc enables 2 regulators if
they are defined: vmmc and vmmc_aux
So I configure the real regulator as vmmc, which gets the voltage setting,
and configure the pseudo regulator as vmmc_aux.  This gets powered on after
vmmc, so the reset happens at the right time.

But I think all this is really just hacking around the problem.
I think we need for omap_hsmmc.c to be able to accept a 'reset_gpio' config,
and to toggle that after power-on.
It is unfortunate to have to include functionality for one particular device
in common code like this, but I really cannot see any other way.

BTW I explicitly set MMC_CAP_POWER_OFF so I don't need any card detect
enabled and there is no need to rmmod the device.  A simple "ifconfig wlan0
down" will power off the wifi chip, and "ifconfig wlan0 up" will power it on
again.

NeilBrown

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux