* Re: insmod: unresolved symbol XIo_In32/XIo_Out32
From: Grant Likely @ 2008-07-11 18:31 UTC (permalink / raw)
To: Juliana Su; +Cc: linuxppc-embedded
In-Reply-To: <48776D93.5080504@bucknell.edu>
On Fri, Jul 11, 2008 at 10:26:27AM -0400, Juliana Su wrote:
> Hi,
>
> Is anybody familiar with the following error?
>
> insmod: unresolved symbol XIo_In32
> insmod: unresolved symbol XIo_Out32
>
> I am trying to write a device driver for a Custom IP and get it to run
> on a Xilinx ML310's Linux OS. I am using Xilinx EDK 10.1 and MontaVista
> Linux version 2.4.20_mvl31-ml300. I ran into this error when trying to
> load my module into the kernel. When I try to load the module using
> insmod on the ".o" file, the module refuses to load and gives me the
> unresolved symbol error message. I actually stumbled upon an older
> posting from June 2006 on this mailing list that described a similar
> problem, but those suggestions did not help me. Maybe two years later,
> there are more ideas/suggestions/solutions to this problem?
I can't help much with the 2.4 montavista kernel, but I can say that the
error means that the XIo_* helper routines are either not compiled into
the kernel or are not exported with EXPORT_SYMBOL(). The XIo_* routines
are hooks used by Xilinx cross platform device drivers to make the
actual accesses to hardware. If they are not implemented, then you need
to create them yourself.
g.
^ permalink raw reply
* Re: [PATCH 1/2] Convert i2c-mpc from a platform driver into a of_platform driver, V4
From: Anton Vorontsov @ 2008-07-11 18:45 UTC (permalink / raw)
To: Grant Likely; +Cc: Linuxppc-dev, Timur Tabi, i2c
In-Reply-To: <20080711181214.GA15321@secretlab.ca>
On Fri, Jul 11, 2008 at 12:12:14PM -0600, Grant Likely wrote:
> On Thu, Jul 10, 2008 at 12:36:58PM -0400, Timur Tabi wrote:
> >
> > On Jul 9, 2008, at 1:22 PM, Grant Likely wrote:
> >
> >> On Mon, Jun 30, 2008 at 5:01 PM, Jon Smirl <jonsmirl@gmail.com> wrote:
> >>> Convert i2c-mpc to an of_platform driver. Utilize the code in
> >>> drivers/of-i2c.c to make i2c modules dynamically loadable by the
> >>> device tree.
> >>
> >> Timur, can you please test this one on an 83xx platform? It works on
> >> 5200, but I want to make sure 83xx doesn't break before I pick it up.
> >
> > I'm on vacation this week, so I'll have to deal with it next week, after
> > I've handled higher-priority issues.
>
> Kumar, is there anyone else who can test this out before the merge
> window opens?
FWIW, they seem to work for me. At least RTC still works.
p.s. [1/2] conflicts with fsl_soc.c. And these patches will
conflict a bit more (now with of_i2c.c), if/when
"[PATCH] of/i2c: don't pass -1 to irq_dispose_mapping, otherwise kernel
kernel will oops"
will be applied to 2.6.26.
--
Anton Vorontsov
email: cbouatmailru@gmail.com
irc://irc.freenode.net/bd2
^ permalink raw reply
* Re: [PATCH 1/2] Convert i2c-mpc from a platform driver into a of_platform driver, V4
From: Grant Likely @ 2008-07-11 18:54 UTC (permalink / raw)
To: Anton Vorontsov; +Cc: Linuxppc-dev, Timur Tabi, i2c
In-Reply-To: <20080711184556.GA14368@polina.dev.rtsoft.ru>
On Fri, Jul 11, 2008 at 10:45:56PM +0400, Anton Vorontsov wrote:
> On Fri, Jul 11, 2008 at 12:12:14PM -0600, Grant Likely wrote:
> > On Thu, Jul 10, 2008 at 12:36:58PM -0400, Timur Tabi wrote:
> > >
> > > On Jul 9, 2008, at 1:22 PM, Grant Likely wrote:
> > >
> > >> On Mon, Jun 30, 2008 at 5:01 PM, Jon Smirl <jonsmirl@gmail.com> wrote:
> > >>> Convert i2c-mpc to an of_platform driver. Utilize the code in
> > >>> drivers/of-i2c.c to make i2c modules dynamically loadable by the
> > >>> device tree.
> > >>
> > >> Timur, can you please test this one on an 83xx platform? It works on
> > >> 5200, but I want to make sure 83xx doesn't break before I pick it up.
> > >
> > > I'm on vacation this week, so I'll have to deal with it next week, after
> > > I've handled higher-priority issues.
> >
> > Kumar, is there anyone else who can test this out before the merge
> > window opens?
>
> FWIW, they seem to work for me. At least RTC still works.
Good enough for me. Unless someone screams really loudly I'm going to
go ahead and pick it up.
Cheers,
g.
^ permalink raw reply
* Re: [PATCH] of/i2c: don't pass -1 to irq_dispose_mapping, otherwise kernel will oops
From: Anton Vorontsov @ 2008-07-11 18:55 UTC (permalink / raw)
To: Grant Likely; +Cc: khali, linuxppc-dev, i2c
In-Reply-To: <20080711182323.GB15321@secretlab.ca>
On Fri, Jul 11, 2008 at 12:23:23PM -0600, Grant Likely wrote:
> On Fri, Jul 11, 2008 at 09:48:59PM +0400, Anton Vorontsov wrote:
> > Firstly kernel warns at set_irq_chip, and then dies completely:
> >
> > Trying to install chip for IRQ-1
> >
> > diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c
> > index b2ccdcb..95a24de 100644
> > --- a/drivers/of/of_i2c.c
> > +++ b/drivers/of/of_i2c.c
> > @@ -93,10 +93,8 @@ void of_register_i2c_devices(struct i2c_adapter *adap,
> > if (info.irq == NO_IRQ)
> > info.irq = -1;
>
> What is the reason that info.irq is set to -1 in the first place?
I believe this is because of this checking mess:
grep irq -r drivers/rtc/ drivers/i2c/chips/ | grep if
grep "define NO_IRQ" -r include/
--
Anton Vorontsov
email: cbouatmailru@gmail.com
irc://irc.freenode.net/bd2
^ permalink raw reply
* Re: [PATCH] of/i2c: don't pass -1 to irq_dispose_mapping, otherwise kernel will oops
From: Jochen Friedrich @ 2008-07-11 19:01 UTC (permalink / raw)
To: Grant Likely; +Cc: khali, linuxppc-dev, i2c
In-Reply-To: <20080711182323.GB15321@secretlab.ca>
Hi Grant,
> What is the reason that info.irq is set to -1 in the first place? This
> looks like another bug to me. Does something in the i2c layer depend on
> the -1 value?
Nope, it was a bug in the i2c documentation fixed recently:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=8e29da9ee8958cc17e27f4053420f1c982614793
Thanks,
Jochen
^ permalink raw reply
* Re: insmod: unresolved symbol XIo_In32/XIo_Out32
From: Juliana Su @ 2008-07-11 19:11 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-embedded
In-Reply-To: <20080711183117.GD15321@secretlab.ca>
Hi,
Thanks for your reply! I am new to creating loadable kernel modules, so
I hope you do not mind some more questions... How can I get the XIo_*
helper routines to compile into the kernel or export them with
EXPORT_SYMBOL( )? In my c file (my driver file from which I create the
object file), I made sure to include xio.h, which is where XIo_In32 and
XIo_Out32 are defined (see below section from xio.h).
/************************** Function Prototypes
******************************/
/* The following functions allow the software to be transportable across
* processors which may use memory mapped I/O or I/O which is mapped into a
* seperate address space such as X86. The functions are better suited for
* debugging and are therefore the default implementation. Macros can
instead
* be used if USE_IO_MACROS is defined.
*/
#ifndef USE_IO_MACROS
/* Functions */
u8 XIo_In8(XIo_Address InAddress);
u16 XIo_In16(XIo_Address InAddress);
u32 XIo_In32(XIo_Address InAddress);
void XIo_Out8(XIo_Address OutAddress, u8 Value);
void XIo_Out16(XIo_Address OutAddress, u16 Value);
void XIo_Out32(XIo_Address OutAddress, u32 Value);
#else
/* The following macros allow optimized I/O operations for memory mapped I/O
* Note that the SYNCHRONIZE_IO may be moved by the compiler during
* optimization.
*/
#define XIo_In8(InputPtr) (*(volatile u8 *)(InputPtr)); SYNCHRONIZE_IO;
#define XIo_In16(InputPtr) (*(volatile u16 *)(InputPtr)); SYNCHRONIZE_IO;
#define XIo_In32(InputPtr) (*(volatile u32 *)(InputPtr)); SYNCHRONIZE_IO;
#define XIo_Out8(OutputPtr, Value) \
{ (*(volatile u8 *)(OutputPtr) = Value); SYNCHRONIZE_IO; }
#define XIo_Out16(OutputPtr, Value) \
{ (*(volatile u16 *)(OutputPtr) = Value); SYNCHRONIZE_IO; }
#define XIo_Out32(OutputPtr, Value) \
{ (*(volatile u32 *)(OutputPtr) = Value); SYNCHRONIZE_IO; }
#endif
I thought that, by including xio.h, XIo_In32 and XIo_Out32 would be
taken care of, but that is probably a novice assumption of mine...
-Juliana
Grant Likely wrote:
> On Fri, Jul 11, 2008 at 10:26:27AM -0400, Juliana Su wrote:
>
>> Hi,
>>
>> Is anybody familiar with the following error?
>>
>> insmod: unresolved symbol XIo_In32
>> insmod: unresolved symbol XIo_Out32
>>
>> I am trying to write a device driver for a Custom IP and get it to run
>> on a Xilinx ML310's Linux OS. I am using Xilinx EDK 10.1 and MontaVista
>> Linux version 2.4.20_mvl31-ml300. I ran into this error when trying to
>> load my module into the kernel. When I try to load the module using
>> insmod on the ".o" file, the module refuses to load and gives me the
>> unresolved symbol error message. I actually stumbled upon an older
>> posting from June 2006 on this mailing list that described a similar
>> problem, but those suggestions did not help me. Maybe two years later,
>> there are more ideas/suggestions/solutions to this problem?
>>
>
> I can't help much with the 2.4 montavista kernel, but I can say that the
> error means that the XIo_* helper routines are either not compiled into
> the kernel or are not exported with EXPORT_SYMBOL(). The XIo_* routines
> are hooks used by Xilinx cross platform device drivers to make the
> actual accesses to hardware. If they are not implemented, then you need
> to create them yourself.
>
> g.
>
>
>
^ permalink raw reply
* Re: [PATCH] of/i2c: don't pass -1 to irq_dispose_mapping, otherwise kernel will oops
From: Jochen Friedrich @ 2008-07-11 19:11 UTC (permalink / raw)
To: Anton Vorontsov; +Cc: linuxppc-dev
In-Reply-To: <20080711174859.GA24260@polina.dev.rtsoft.ru>
Hi Anton,
> diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c
> index b2ccdcb..95a24de 100644
> --- a/drivers/of/of_i2c.c
> +++ b/drivers/of/of_i2c.c
> @@ -93,10 +93,8 @@ void of_register_i2c_devices(struct i2c_adapter *adap,
> if (info.irq == NO_IRQ)
> info.irq = -1;
>
> - if (of_find_i2c_driver(node, &info) < 0) {
> - irq_dispose_mapping(info.irq);
> - continue;
> - }
> + if (of_find_i2c_driver(node, &info) < 0)
> + goto err;
>
> info.addr = *addr;
>
> @@ -107,9 +105,12 @@ void of_register_i2c_devices(struct i2c_adapter *adap,
> printk(KERN_ERR
> "of-i2c: Failed to load driver for %s\n",
> info.type);
> - irq_dispose_mapping(info.irq);
> - continue;
> + goto err;
> }
> + continue;
> +err:
> + if (info.irq > 0)
> + irq_dispose_mapping(info.irq);
Shouldn't this be:
if (info.irq != NO_IRQ)
> }
> }
> EXPORT_SYMBOL(of_register_i2c_devices);
Thanks,
Jochen
^ permalink raw reply
* Re: [PATCH] of/i2c: don't pass -1 to irq_dispose_mapping, otherwise kernel will oops
From: Anton Vorontsov @ 2008-07-11 19:15 UTC (permalink / raw)
To: Jochen Friedrich; +Cc: khali, i2c, linuxppc-dev
In-Reply-To: <4877ADF6.8070702@scram.de>
On Fri, Jul 11, 2008 at 09:01:10PM +0200, Jochen Friedrich wrote:
> Hi Grant,
>
> > What is the reason that info.irq is set to -1 in the first place? This
> > looks like another bug to me. Does something in the i2c layer depend on
> > the -1 value?
>
> Nope, it was a bug in the i2c documentation fixed recently:
Nope? I'm looking into i2c-core.c:
.. i2c_new_device(...)
{
client->irq = info->irq;
Core will blindly pass irq, so clients should ensure that irq contains
correct value. And as far as there is no common scheme of checking that
"there is no irq specified", the most safe option is -1.
> http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=8e29da9ee8958cc17e27f4053420f1c982614793
--
Anton Vorontsov
email: cbouatmailru@gmail.com
irc://irc.freenode.net/bd2
^ permalink raw reply
* Re: [PATCH] of/i2c: don't pass -1 to irq_dispose_mapping, otherwise kernel will oops
From: Anton Vorontsov @ 2008-07-11 19:19 UTC (permalink / raw)
To: Jochen Friedrich; +Cc: linuxppc-dev
In-Reply-To: <4877B046.8070206@scram.de>
On Fri, Jul 11, 2008 at 09:11:02PM +0200, Jochen Friedrich wrote:
> Hi Anton,
>
> > diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c
> > index b2ccdcb..95a24de 100644
> > --- a/drivers/of/of_i2c.c
> > +++ b/drivers/of/of_i2c.c
> > @@ -93,10 +93,8 @@ void of_register_i2c_devices(struct i2c_adapter *adap,
> > if (info.irq == NO_IRQ)
> > info.irq = -1;
> >
> > - if (of_find_i2c_driver(node, &info) < 0) {
> > - irq_dispose_mapping(info.irq);
> > - continue;
> > - }
> > + if (of_find_i2c_driver(node, &info) < 0)
> > + goto err;
> >
> > info.addr = *addr;
> >
> > @@ -107,9 +105,12 @@ void of_register_i2c_devices(struct i2c_adapter *adap,
> > printk(KERN_ERR
> > "of-i2c: Failed to load driver for %s\n",
> > info.type);
> > - irq_dispose_mapping(info.irq);
> > - continue;
> > + goto err;
> > }
> > + continue;
> > +err:
> > + if (info.irq > 0)
> > + irq_dispose_mapping(info.irq);
>
> Shouldn't this be:
> if (info.irq != NO_IRQ)
Maybe, maybe not. See
http://lkml.org/lkml/2005/11/21/211
I.e. maybe we should use "if (irq)". Or if we should use NO_IRQ, then we
need to fixup all the users of .irq.
--
Anton Vorontsov
email: cbouatmailru@gmail.com
irc://irc.freenode.net/bd2
^ permalink raw reply
* linux boot sequence
From: Siva Prasad @ 2008-07-11 20:47 UTC (permalink / raw)
To: rwehbi; +Cc: linuxppc-embedded
In-Reply-To: <mailman.1640.1215763007.2883.linuxppc-embedded@ozlabs.org>
Well!... You can pass the size as part of the OF memory=3D<>.
Typically your boot loader should detect the amount of memory on the
system and update the OF dtb to reflect the available memory.
You may also tweak the kernel yourself to autodetect, instead of reading
from the OF. How ever, I would recommend the previous approach.
- Siva
Date: Fri, 11 Jul 2008 08:34:54 +0200
From: "Rami WEHBI" <rwehbi@wirecom-tech.com>
Subject: linux boot sequence
To: <linuxppc-embedded@ozlabs.org>
Message-ID:
=09
<D3C541E264C021479BFB60B3B790C0FB497014@etoilenoire.STARWARS.local>
Content-Type: text/plain; charset=3D"iso-8859-1"
Hi all,
=20
I am using the ppc405 and I would like to know, how does linux on
this architect detect the available memory size in details !!!
is it a parameter passed to linux at startup by the boot loader
??
is it an automatic detection ?? what are the steps to accomplish
this job then ???
=20
Best regards to all,
=20
Rami
=20
Rami WEHBI =09
Recherche & D?veloppement =09
T?l : +33 2 36 56 86 00=09
Fax : +33 2 36 56 86 01=09
www.wirecom-tech.com=09
<http://www.wirecom-tech.com> =09
WIRECOM Technologies=20
135, Rue Jacques Charles
45166 Olivet
=09
^ permalink raw reply
* Re: insmod: unresolved symbol XIo_In32/XIo_Out32
From: Grant Likely @ 2008-07-11 21:05 UTC (permalink / raw)
To: Juliana Su; +Cc: linuxppc-embedded
In-Reply-To: <4877B04A.8090801@bucknell.edu>
On Fri, Jul 11, 2008 at 03:11:06PM -0400, Juliana Su wrote:
> Hi,
>
> Thanks for your reply! I am new to creating loadable kernel modules, so
> I hope you do not mind some more questions... How can I get the XIo_*
> helper routines to compile into the kernel or export them with
> EXPORT_SYMBOL( )? In my c file (my driver file from which I create the
> object file), I made sure to include xio.h, which is where XIo_In32 and
> XIo_Out32 are defined (see below section from xio.h).
Add an EXPORT_SYMBOL() line to the location where the io accessors are
implemented. However, you'd probably be better just to replace xio.h
implementation with macros that just map them to the in_be32() and
out_be32() macros.
g.
^ permalink raw reply
* Re: [PATCH] of/i2c: don't pass -1 to irq_dispose_mapping, otherwise kernel will oops
From: Grant Likely @ 2008-07-11 21:18 UTC (permalink / raw)
To: Anton Vorontsov; +Cc: linuxppc-dev
In-Reply-To: <20080711191930.GA23723@polina.dev.rtsoft.ru>
On Fri, Jul 11, 2008 at 11:19:30PM +0400, Anton Vorontsov wrote:
> On Fri, Jul 11, 2008 at 09:11:02PM +0200, Jochen Friedrich wrote:
> >
> > Shouldn't this be:
> > if (info.irq != NO_IRQ)
>
> Maybe, maybe not. See
>
> http://lkml.org/lkml/2005/11/21/211
>
> I.e. maybe we should use "if (irq)". Or if we should use NO_IRQ, then we
> need to fixup all the users of .irq.
Yes, these are definitely wrong and need to be fixed.
g.
^ permalink raw reply
* Re: [PATCH] of/i2c: don't pass -1 to irq_dispose_mapping, otherwise kernel will oops
From: Anton Vorontsov @ 2008-07-11 21:46 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-dev
In-Reply-To: <20080711211813.GC18239@secretlab.ca>
On Fri, Jul 11, 2008 at 03:18:13PM -0600, Grant Likely wrote:
> On Fri, Jul 11, 2008 at 11:19:30PM +0400, Anton Vorontsov wrote:
> > On Fri, Jul 11, 2008 at 09:11:02PM +0200, Jochen Friedrich wrote:
> > >
> > > Shouldn't this be:
> > > if (info.irq != NO_IRQ)
> >
> > Maybe, maybe not. See
> >
> > http://lkml.org/lkml/2005/11/21/211
> >
> > I.e. maybe we should use "if (irq)". Or if we should use NO_IRQ, then we
> > need to fixup all the users of .irq.
>
> Yes, these are definitely wrong and need to be fixed.
In rc9? ;-)
Something tells me that even for 2.6.27 such change would be somewhat
late...
--
Anton Vorontsov
email: cbouatmailru@gmail.com
irc://irc.freenode.net/bd2
^ permalink raw reply
* Re: [PATCH] of/i2c: don't pass -1 to irq_dispose_mapping, otherwise kernel will oops
From: Grant Likely @ 2008-07-11 22:08 UTC (permalink / raw)
To: Anton Vorontsov; +Cc: linuxppc-dev
In-Reply-To: <20080711214614.GA22000@polina.dev.rtsoft.ru>
On Sat, Jul 12, 2008 at 01:46:14AM +0400, Anton Vorontsov wrote:
> On Fri, Jul 11, 2008 at 03:18:13PM -0600, Grant Likely wrote:
> > On Fri, Jul 11, 2008 at 11:19:30PM +0400, Anton Vorontsov wrote:
> > > On Fri, Jul 11, 2008 at 09:11:02PM +0200, Jochen Friedrich wrote:
> > > >
> > > > Shouldn't this be:
> > > > if (info.irq != NO_IRQ)
> > >
> > > Maybe, maybe not. See
> > >
> > > http://lkml.org/lkml/2005/11/21/211
> > >
> > > I.e. maybe we should use "if (irq)". Or if we should use NO_IRQ, then we
> > > need to fixup all the users of .irq.
> >
> > Yes, these are definitely wrong and need to be fixed.
>
> In rc9? ;-)
I said no such thing. :-) It agree that it is too late for .26, but I
think is a reasonable goal to get fixed for 2.6.27.
g.
^ permalink raw reply
* Re: Installation on a MPC5200 based custom board
From: Grant Likely @ 2008-07-11 22:12 UTC (permalink / raw)
To: Sylvain Lamontagne; +Cc: Michel Lemieux, linuxppc-dev, Craig Cornwall
In-Reply-To: <1215814074.9106.76.camel@NV10035>
On Fri, Jul 11, 2008 at 06:07:54PM -0400, Sylvain Lamontagne wrote:
> Greetings
>
> We are currently trying to put a Kernel 2.6.26 on a custom board based
> on the MPC5200 processor and the designed of the board was based on the
> lite5200b evaluation board.
>
> We would like to have some advice regarding the installation process for
> this kernel. The hardware currently work (still buggy, but work) with a
> kernel 2.6.23 compiled with ARCH ppc running on a U-Boot 1.1.6. For what
> I understand now, the ARCH ppc if kind of deprecated and we have to
> switch to ARCH powerpc. I'm new to the concept of device tree, do I have
> to modify it myself or the file wild be generated automatically ?
You need to modify it yourself. I suspect that most of it will be
identical to the lite5200b, but you'll need to make adjustments for
things like PSC usage and PCI interrupt mappings.
> Should it be better for us to upgrade our version of U-Boot to 1.3.* to
> get the support of device tree? Currently we tried with the wrapper
> trick of using cuImage.lite5200b and the v1.1.6 but it doesn't seem to
> work.
It's a good idea, but you don't need to. The cuImage target should work
well after you've created a custom .dts file for your board.
> Also, we would like to know if we have to recompile everything on the
> board (U-Boot/Kernel/Busybox) since we switched ARCH from ppc to
> powerpc?
No, you do not.
> We are also wondering what is the cross-compilation tools that you are
> using? Or do you have any good advice on a choice? Currently we are
> building with gcc-4.1.0-glibc-2.3.6 for ppc on an x86 host running
> Ubuntu 8.04 or we also have a Fedora Core 7 laptop but, I have see a
> kernel compilation warning regarding gcc 4.1 saying that it's known to
> brake the kernel.
Personally, I use ELDK from Denx.
> Should we upgrade everything (U-Boot/Kernel/Busybox) and recreate a new
> Ramdisk ?
No, you don't have to.
> Anybody know a good development tools to use with a CodeWarrior USB TAP
> from freescale ? The CodeWarrior IDE doesn't seems to work properly for
> us.
I haven't used codewarrior for Linux development. The Abatron BDI-3000
works really well for me.
Cheers,
g.
^ permalink raw reply
* Installation on a MPC5200 based custom board
From: Sylvain Lamontagne @ 2008-07-11 22:07 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Michel Lemieux, Craig Cornwall
Greetings
We are currently trying to put a Kernel 2.6.26 on a custom board based
on the MPC5200 processor and the designed of the board was based on the
lite5200b evaluation board.
We would like to have some advice regarding the installation process for
this kernel. The hardware currently work (still buggy, but work) with a
kernel 2.6.23 compiled with ARCH ppc running on a U-Boot 1.1.6. For what
I understand now, the ARCH ppc if kind of deprecated and we have to
switch to ARCH powerpc. I'm new to the concept of device tree, do I have
to modify it myself or the file wild be generated automatically ?
Should it be better for us to upgrade our version of U-Boot to 1.3.* to
get the support of device tree? Currently we tried with the wrapper
trick of using cuImage.lite5200b and the v1.1.6 but it doesn't seem to
work.
Also, we would like to know if we have to recompile everything on the
board (U-Boot/Kernel/Busybox) since we switched ARCH from ppc to
powerpc?
We are also wondering what is the cross-compilation tools that you are
using? Or do you have any good advice on a choice? Currently we are
building with gcc-4.1.0-glibc-2.3.6 for ppc on an x86 host running
Ubuntu 8.04 or we also have a Fedora Core 7 laptop but, I have see a
kernel compilation warning regarding gcc 4.1 saying that it's known to
brake the kernel.
Should we upgrade everything (U-Boot/Kernel/Busybox) and recreate a new
Ramdisk ?
Anybody know a good development tools to use with a CodeWarrior USB TAP
from freescale ? The CodeWarrior IDE doesn't seems to work properly for
us.
This is a lot of questions and they maybe unclear since I'm new to all
this, but if you need any more information I can provide them.
Best Regards,
--
Sylvain Lamontagne
--------------------
Software Developer
Novariant Canada
Ext.: 4940
^ permalink raw reply
* [PATCH] powerpc: Modify MPC52xx maintainers entry to cover all MPC5xxx parts
From: Grant Likely @ 2008-07-11 22:39 UTC (permalink / raw)
To: benh, jrigby, tnt, linuxppc-dev
From: Grant Likely <grant.likely@secretlab.ca>
Linux now supports the MPC5121 part and is handled by the same
maintainer. Update MAINTAINERS to reflect this. Also remove URLs
which do not work or contain out of date information.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
MAINTAINERS | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index 8f0ec46..c984014 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2489,13 +2489,11 @@ W: http://www.penguinppc.org/
L: linuxppc-dev@ozlabs.org
S: Maintained
-LINUX FOR POWERPC EMBEDDED MPC52XX
+LINUX FOR POWERPC EMBEDDED MPC5XXX
P: Sylvain Munaut
M: tnt@246tNt.com
P: Grant Likely
M: grant.likely@secretlab.ca
-W: http://www.246tNt.com/mpc52xx/
-W: http://www.penguinppc.org/
L: linuxppc-dev@ozlabs.org
S: Maintained
^ permalink raw reply related
* [PATCH] powerpc: don't spin on sync
From: Sonny Rao @ 2008-07-11 23:00 UTC (permalink / raw)
To: benh; +Cc: linuxppc-dev, sonnyrao, paulus, miltonm
Push the sync below the secondary smp init hold loop and comment its purpose.
This should speed up boot by reducing global traffic during the single-threaded
portion of boot.
Signed-off-by: Sonny Rao <sonnyrao@us.ibm.com>
Signed-off-by: Milton Miller <miltonm@bga.com>
--- next.git/arch/powerpc/kernel/head_64.S~orig 2008-07-11 17:28:47.000000000 -0500
+++ next.git/arch/powerpc/kernel/head_64.S 2008-07-11 17:31:50.000000000 -0500
@@ -1198,7 +1198,6 @@ _GLOBAL(generic_secondary_smp_init)
3: HMT_LOW
lbz r23,PACAPROCSTART(r13) /* Test if this processor should */
/* start. */
- sync
#ifndef CONFIG_SMP
b 3b /* Never go on non-SMP */
@@ -1206,6 +1205,8 @@ _GLOBAL(generic_secondary_smp_init)
cmpwi 0,r23,0
beq 3b /* Loop until told to go */
+ sync /* order paca.run and cur_cpu_spec */
+
/* See if we need to call a cpu state restore handler */
LOAD_REG_IMMEDIATE(r23, cur_cpu_spec)
ld r23,0(r23)
^ permalink raw reply
* [PATCH 1/6] Document Freescale power management nodes, and the sleep property.
From: Scott Wood @ 2008-07-11 23:03 UTC (permalink / raw)
To: galak; +Cc: linuxppc-dev
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
Documentation/powerpc/booting-without-of.txt | 142 +++++++++++++++++-------
Documentation/powerpc/dts-bindings/fsl/pmc.txt | 63 +++++++++++
2 files changed, 163 insertions(+), 42 deletions(-)
create mode 100644 Documentation/powerpc/dts-bindings/fsl/pmc.txt
diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
index de2e5c0..5cd1ef0 100644
--- a/Documentation/powerpc/booting-without-of.txt
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -77,10 +77,12 @@ Table of Contents
3) OpenPIC Interrupt Controllers
4) ISA Interrupt Controllers
- VIII - Specifying GPIO information for devices
+ IX - Specifying GPIO information for devices
1) gpios property
2) gpio-controller nodes
+ X - Specifying device power management information (sleep property)
+
Appendix A - Sample SOC node for MPC8540
@@ -2422,8 +2424,8 @@ encodings listed below:
2 = high to low edge sensitive type enabled
3 = low to high edge sensitive type enabled
-VIII - Specifying GPIO information for devices
-==============================================
+IX - Specifying GPIO information for devices
+============================================
1) gpios property
-----------------
@@ -2471,6 +2473,37 @@ Example of two SOC GPIO banks defined as gpio-controller nodes:
gpio-controller;
};
+X - Specifying Device Power Management Information (sleep property)
+===================================================================
+
+Devices on SOCs often have mechanisms for placing devices into low-power
+states that are decoupled from the devices' own register blocks. Sometimes,
+this information is more complicated than a cell-index property can
+reasonably describe. Thus, each device controlled in such a manner
+may contain a "sleep" property which describes these connections.
+
+The sleep property consists of one or more sleep resources, each of
+which consists of a phandle to a sleep controller, followed by a
+controller-specific sleep specifier of zero or more cells.
+
+The semantics of what type of low power modes are possible are defined
+by the sleep controller. Some examples of the types of low power modes
+that may be supported are:
+
+ - Dynamic: The device may be disabled or enabled at any time.
+ - System Suspend: The device may request to be disabled or remain
+ awake during system suspend, but will not be disabled until then.
+ - Permanent: The device is disabled permanently (until the next hard
+ reset).
+
+Some devices may share a clock domain with each other, such that they should
+only be suspended when none of the devices are in use. Where reasonable,
+such nodes should be placed on a virtual bus, where the bus has the sleep
+property. If the clock domain is shared among devices that cannot be
+reasonably grouped in this manner, then create a virtual sleep controller
+(similar to an interrupt nexus, except that defining a standardized
+sleep-map should wait until its necessity is demonstrated).
+
Appendix A - Sample SOC node for MPC8540
========================================
@@ -2487,47 +2520,48 @@ not necessary as they are usually the same as the root node.
reg = <e0000000 00003000>;
bus-frequency = <0>;
- mdio@24520 {
- reg = <24520 20>;
- device_type = "mdio";
- compatible = "gianfar";
-
- ethernet-phy@0 {
- linux,phandle = <2452000>
- interrupt-parent = <40000>;
- interrupts = <35 1>;
- reg = <0>;
- device_type = "ethernet-phy";
- };
-
- ethernet-phy@1 {
- linux,phandle = <2452001>
- interrupt-parent = <40000>;
- interrupts = <35 1>;
- reg = <1>;
- device_type = "ethernet-phy";
- };
-
- ethernet-phy@3 {
- linux,phandle = <2452002>
- interrupt-parent = <40000>;
- interrupts = <35 1>;
- reg = <3>;
- device_type = "ethernet-phy";
- };
-
- };
-
ethernet@24000 {
- #size-cells = <0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
device_type = "network";
model = "TSEC";
- compatible = "gianfar";
+ compatible = "gianfar", "simple-bus";
reg = <24000 1000>;
mac-address = [ 00 E0 0C 00 73 00 ];
interrupts = <d 3 e 3 12 3>;
interrupt-parent = <40000>;
phy-handle = <2452000>;
+ sleep = <&pmc 00000080>;
+ ranges;
+
+ mdio@24520 {
+ reg = <24520 20>;
+ compatible = "fsl,gianfar-mdio";
+
+ ethernet-phy@0 {
+ linux,phandle = <2452000>
+ interrupt-parent = <40000>;
+ interrupts = <35 1>;
+ reg = <0>;
+ device_type = "ethernet-phy";
+ };
+
+ ethernet-phy@1 {
+ linux,phandle = <2452001>
+ interrupt-parent = <40000>;
+ interrupts = <35 1>;
+ reg = <1>;
+ device_type = "ethernet-phy";
+ };
+
+ ethernet-phy@3 {
+ linux,phandle = <2452002>
+ interrupt-parent = <40000>;
+ interrupts = <35 1>;
+ reg = <3>;
+ device_type = "ethernet-phy";
+ };
+ };
};
ethernet@25000 {
@@ -2541,6 +2575,7 @@ not necessary as they are usually the same as the root node.
interrupts = <13 3 14 3 18 3>;
interrupt-parent = <40000>;
phy-handle = <2452001>;
+ sleep = <&pmc 00000040>;
};
ethernet@26000 {
@@ -2554,15 +2589,33 @@ not necessary as they are usually the same as the root node.
interrupts = <19 3>;
interrupt-parent = <40000>;
phy-handle = <2452002>;
+ sleep = <&pmc 00000020>;
};
serial@4500 {
- device_type = "serial";
- compatible = "ns16550";
- reg = <4500 100>;
- clock-frequency = <0>;
- interrupts = <1a 3>;
- interrupt-parent = <40000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8540-duart", "simple-bus";
+ sleep = <&pmc 00000002>;
+ ranges;
+
+ serial@4500 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <4500 100>;
+ clock-frequency = <0>;
+ interrupts = <1a 3>;
+ interrupt-parent = <40000>;
+ };
+
+ serial@4600 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <4600 100>;
+ clock-frequency = <0>;
+ interrupts = <1a 3>;
+ interrupt-parent = <40000>;
+ };
};
pic@40000 {
@@ -2581,6 +2634,11 @@ not necessary as they are usually the same as the root node.
device_type = "i2c";
compatible = "fsl-i2c";
dfsrr;
+ sleep = <&pmc 00000004>;
};
+ pmc: power@e0070 {
+ compatible = "fsl,mpc8540-pmc", "fsl,mpc8548-pmc";
+ reg = <e0070 20>;
+ };
};
diff --git a/Documentation/powerpc/dts-bindings/fsl/pmc.txt b/Documentation/powerpc/dts-bindings/fsl/pmc.txt
new file mode 100644
index 0000000..02f6f43
--- /dev/null
+++ b/Documentation/powerpc/dts-bindings/fsl/pmc.txt
@@ -0,0 +1,63 @@
+* Power Management Controller
+
+Properties:
+- compatible: "fsl,<chip>-pmc".
+
+ "fsl,mpc8349-pmc" should be listed for any chip whose PMC is
+ compatible. "fsl,mpc8313-pmc" should also be listed for any chip
+ whose PMC is compatible, and implies deep-sleep capability.
+
+ "fsl,mpc8548-pmc" should be listed for any chip whose PMC is
+ compatible. "fsl,mpc8536-pmc" should also be listed for any chip
+ whose PMC is compatible, and implies deep-sleep capability.
+
+ "fsl,mpc8641d-pmc" should be listed for any chip whose PMC is
+ compatible; all statements below that apply to "fsl,mpc8548-pmc" also
+ apply to "fsl,mpc8641d-pmc".
+
+ Compatibility does not include bit assigments in SCCR/PMCDR/DEVDISR; these
+ bit assigments are indicated via the sleep specifier in each device's
+ sleep property.
+
+- reg: For devices compatible with "fsl,mpc8349-pmc", the first resource
+ is the PMC block, and the second resource is the Clock Configuration
+ block.
+
+ For devices compatible with "fsl,mpc8548-pmc", the first resource
+ is a 32-byte block beginning with DEVDISR.
+
+- interrupts: For "fsl,mpc8349-pmc"-compatible devices, the first
+ resource is the PMC block interrupt.
+
+- fsl,mpc8313-wakeup-timer: For "fsl,mpc8313-pmc"-compatible devices,
+ this is a phandle to an "fsl,gtm" node on which timer 4 can be used as
+ a wakeup source from deep sleep.
+
+Sleep specifiers:
+
+ fsl,mpc8349-pmc: Sleep specifiers consist of one cell. For each bit
+ that is set in the cell, the corresponding bit in SCCR will be saved
+ and cleared on suspend, and restored on resume. This sleep controller
+ supports disabling and resuming devices at any time.
+
+ fsl,mpc8536-pmc: Sleep specifiers consist of three cells, the third of
+ which will be ORed into PMCDR upon suspend, and cleared from PMCDR
+ upon resume. The first two cells are as described for fsl,mpc8578-pmc.
+ This sleep controller only supports disabling devices during system
+ sleep, or permanently.
+
+ fsl,mpc8548-pmc: Sleep specifiers consist of one or two cells, the
+ first of which will be ORed into DEVDISR (and the second into
+ DEVDISR2, if present -- this cell should be zero or absent if the
+ hardware does not have DEVDISR2) upon a request for permanent device
+ disabling. This sleep controller does not support configuring devices
+ to disable during system sleep (unless supported by another compatible
+ match), or dynamically.
+
+Example:
+
+ power@b00 {
+ compatible = "fsl,mpc8313-pmc", "fsl,mpc8349-pmc";
+ reg = <0xb00 0x100 0xa00 0x100>;
+ interrupts = <80 8>;
+ };
--
1.5.6.rc1.6.gc53ad.dirty
^ permalink raw reply related
* [PATCH 4/6] Add fsl,magic-packet to, and clean up, the gianfar binding.
From: Scott Wood @ 2008-07-11 23:04 UTC (permalink / raw)
To: galak; +Cc: linuxppc-dev
In-Reply-To: <20080711230328.GA3835@loki.buserror.net>
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
Documentation/powerpc/dts-bindings/fsl/tsec.txt | 31 +++++++++--------------
1 files changed, 12 insertions(+), 19 deletions(-)
diff --git a/Documentation/powerpc/dts-bindings/fsl/tsec.txt b/Documentation/powerpc/dts-bindings/fsl/tsec.txt
index 583ef6b..cf55fa4 100644
--- a/Documentation/powerpc/dts-bindings/fsl/tsec.txt
+++ b/Documentation/powerpc/dts-bindings/fsl/tsec.txt
@@ -24,46 +24,39 @@ Example:
* Gianfar-compatible ethernet nodes
-Required properties:
+Properties:
- device_type : Should be "network"
- model : Model of the device. Can be "TSEC", "eTSEC", or "FEC"
- compatible : Should be "gianfar"
- reg : Offset and length of the register set for the device
- - mac-address : List of bytes representing the ethernet address of
+ - local-mac-address : List of bytes representing the ethernet address of
this controller
- - interrupts : <a b> where a is the interrupt number and b is a
- field that represents an encoding of the sense and level
- information for the interrupt. This should be encoded based on
- the information in section 2) depending on the type of interrupt
- controller you have.
- - interrupt-parent : the phandle for the interrupt controller that
- services interrupts for this device.
+ - interrupts : For FEC devices, the first interrupt is the device's
+ interrupt. For TSEC and eTSEC devices, the first interrupt is
+ transmit, the second is receive, and the third is error.
- phy-handle : The phandle for the PHY connected to this ethernet
controller.
- fixed-link : <a b c d e> where a is emulated phy id - choose any,
but unique to the all specified fixed-links, b is duplex - 0 half,
1 full, c is link speed - d#10/d#100/d#1000, d is pause - 0 no
pause, 1 pause, e is asym_pause - 0 no asym_pause, 1 asym_pause.
-
-Recommended properties:
-
- phy-connection-type : a string naming the controller/PHY interface type,
i.e., "mii" (default), "rmii", "gmii", "rgmii", "rgmii-id", "sgmii",
"tbi", or "rtbi". This property is only really needed if the connection
is of type "rgmii-id", as all other connection types are detected by
hardware.
-
+ - fsl,magic-packet : If present, indicates that the hardware supports
+ waking up via magic packet.
Example:
ethernet@24000 {
- #size-cells = <0>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
- reg = <24000 1000>;
- mac-address = [ 00 E0 0C 00 73 00 ];
- interrupts = <d 3 e 3 12 3>;
- interrupt-parent = <40000>;
- phy-handle = <2452000>
+ reg = <0x24000 0x1000>;
+ local-mac-address = [ 00 E0 0C 00 73 00 ];
+ interrupts = <29 2 30 2 34 2>;
+ interrupt-parent = <&mpic>;
+ phy-handle = <&phy0>
};
--
1.5.6.rc1.6.gc53ad.dirty
^ permalink raw reply related
* [PATCH 5/6] gianfar: Add magic packet and suspend/resume support.
From: Scott Wood @ 2008-07-11 23:04 UTC (permalink / raw)
To: galak; +Cc: linuxppc-dev
In-Reply-To: <20080711230328.GA3835@loki.buserror.net>
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
arch/powerpc/sysdev/fsl_soc.c | 3 +
drivers/net/gianfar.c | 118 ++++++++++++++++++++++++++++++++++++++++-
drivers/net/gianfar.h | 12 ++++-
drivers/net/gianfar_ethtool.c | 41 +++++++++++++-
include/linux/fsl_devices.h | 1 +
5 files changed, 169 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index ca54563..2fcd714 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -357,6 +357,9 @@ static int __init gfar_of_init(void)
else
gfar_data.interface = PHY_INTERFACE_MODE_MII;
+ if (of_get_property(np, "fsl,magic-packet", NULL))
+ gfar_data.device_flags |= FSL_GIANFAR_DEV_HAS_MAGIC_PACKET;
+
ph = of_get_property(np, "phy-handle", NULL);
if (ph == NULL) {
u32 *fixed_link;
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 25bdd08..f218dcc 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -142,6 +142,7 @@ static int gfar_clean_tx_ring(struct net_device *dev);
static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int length);
static void gfar_vlan_rx_register(struct net_device *netdev,
struct vlan_group *grp);
+static void gfar_halt_nodisable(struct net_device *dev);
void gfar_halt(struct net_device *dev);
void gfar_start(struct net_device *dev);
static void gfar_clear_exact_match(struct net_device *dev);
@@ -216,6 +217,7 @@ static int gfar_probe(struct platform_device *pdev)
spin_lock_init(&priv->txlock);
spin_lock_init(&priv->rxlock);
+ spin_lock_init(&priv->bflock);
platform_set_drvdata(pdev, dev);
@@ -393,6 +395,103 @@ static int gfar_remove(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_PM
+static int gfar_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct gfar_private *priv = netdev_priv(dev);
+ unsigned long flags;
+ u32 tempval;
+
+ int magic_packet = priv->wol_en &&
+ (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
+
+ netif_device_detach(dev);
+
+ if (netif_running(dev)) {
+ spin_lock_irqsave(&priv->txlock, flags);
+ spin_lock(&priv->rxlock);
+
+ gfar_halt_nodisable(dev);
+
+ /* Disable Tx, and Rx if wake-on-LAN is disabled. */
+ tempval = gfar_read(&priv->regs->maccfg1);
+
+ tempval &= ~MACCFG1_TX_EN;
+
+ if (!magic_packet)
+ tempval &= ~MACCFG1_RX_EN;
+
+ gfar_write(&priv->regs->maccfg1, tempval);
+
+ spin_unlock(&priv->rxlock);
+ spin_unlock_irqrestore(&priv->txlock, flags);
+
+#ifdef CONFIG_GFAR_NAPI
+ napi_disable(&priv->napi);
+#endif
+
+ if (magic_packet) {
+ /* Enable interrupt on Magic Packet */
+ gfar_write(&priv->regs->imask, IMASK_MAG);
+
+ /* Enable Magic Packet mode */
+ tempval = gfar_read(&priv->regs->maccfg2);
+ tempval |= MACCFG2_MPEN;
+ gfar_write(&priv->regs->maccfg2, tempval);
+ } else {
+ phy_stop(priv->phydev);
+ }
+ }
+
+ return 0;
+}
+
+static int gfar_resume(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct gfar_private *priv = netdev_priv(dev);
+ unsigned long flags;
+ u32 tempval;
+ int magic_packet = priv->wol_en &&
+ (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
+
+ if (!netif_running(dev)) {
+ netif_device_attach(dev);
+ return 0;
+ }
+
+ if (!magic_packet && priv->phydev)
+ phy_start(priv->phydev);
+
+ /* Disable Magic Packet mode, in case something
+ * else woke us up.
+ */
+
+ spin_lock_irqsave(&priv->txlock, flags);
+ spin_lock(&priv->rxlock);
+
+ tempval = gfar_read(&priv->regs->maccfg2);
+ tempval &= ~MACCFG2_MPEN;
+ gfar_write(&priv->regs->maccfg2, tempval);
+
+ gfar_start(dev);
+
+ spin_unlock(&priv->rxlock);
+ spin_unlock_irqrestore(&priv->txlock, flags);
+
+ netif_device_attach(dev);
+
+#ifdef CONFIG_GFAR_NAPI
+ napi_enable(&priv->napi);
+#endif
+
+ return 0;
+}
+#else
+#define gfar_suspend NULL
+#define gfar_resume NULL
+#endif
/* Reads the controller's registers to determine what interface
* connects it to the PHY.
@@ -550,7 +649,7 @@ static void init_registers(struct net_device *dev)
/* Halt the receive and transmit queues */
-void gfar_halt(struct net_device *dev)
+static void gfar_halt_nodisable(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
struct gfar __iomem *regs = priv->regs;
@@ -573,6 +672,14 @@ void gfar_halt(struct net_device *dev)
(IEVENT_GRSC | IEVENT_GTSC)))
cpu_relax();
}
+}
+
+/* Halt the receive and transmit queues */
+void gfar_halt(struct net_device *dev)
+{
+ struct gfar_private *priv = netdev_priv(dev);
+ struct gfar __iomem *regs = priv->regs;
+ u32 tempval;
/* Disable Rx and Tx */
tempval = gfar_read(®s->maccfg1);
@@ -1969,7 +2076,12 @@ static irqreturn_t gfar_error(int irq, void *dev_id)
u32 events = gfar_read(&priv->regs->ievent);
/* Clear IEVENT */
- gfar_write(&priv->regs->ievent, IEVENT_ERR_MASK);
+ gfar_write(&priv->regs->ievent, events & IEVENT_ERR_MASK);
+
+ /* Magic Packet is not an error. */
+ if ((priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) &&
+ (events & IEVENT_MAG))
+ events &= ~IEVENT_MAG;
/* Hmm... */
if (netif_msg_rx_err(priv) || netif_msg_tx_err(priv))
@@ -2042,6 +2154,8 @@ MODULE_ALIAS("platform:fsl-gianfar");
static struct platform_driver gfar_driver = {
.probe = gfar_probe,
.remove = gfar_remove,
+ .suspend = gfar_suspend,
+ .resume = gfar_resume,
.driver = {
.name = "fsl-gianfar",
.owner = THIS_MODULE,
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index 27f37c8..5ee518a 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -168,6 +168,7 @@ extern const char gfar_driver_version[];
#define MACCFG2_GMII 0x00000200
#define MACCFG2_HUGEFRAME 0x00000020
#define MACCFG2_LENGTHCHECK 0x00000010
+#define MACCFG2_MPEN 0x00000008
#define ECNTRL_INIT_SETTINGS 0x00001000
#define ECNTRL_TBI_MODE 0x00000020
@@ -240,6 +241,7 @@ extern const char gfar_driver_version[];
#define IEVENT_CRL 0x00020000
#define IEVENT_XFUN 0x00010000
#define IEVENT_RXB0 0x00008000
+#define IEVENT_MAG 0x00000800
#define IEVENT_GRSC 0x00000100
#define IEVENT_RXF0 0x00000080
#define IEVENT_FIR 0x00000008
@@ -252,7 +254,8 @@ extern const char gfar_driver_version[];
#define IEVENT_ERR_MASK \
(IEVENT_RXC | IEVENT_BSY | IEVENT_EBERR | IEVENT_MSRO | \
IEVENT_BABT | IEVENT_TXC | IEVENT_TXE | IEVENT_LC \
- | IEVENT_CRL | IEVENT_XFUN | IEVENT_DPE | IEVENT_PERR)
+ | IEVENT_CRL | IEVENT_XFUN | IEVENT_DPE | IEVENT_PERR \
+ | IEVENT_MAG)
#define IMASK_INIT_CLEAR 0x00000000
#define IMASK_BABR 0x80000000
@@ -270,6 +273,7 @@ extern const char gfar_driver_version[];
#define IMASK_CRL 0x00020000
#define IMASK_XFUN 0x00010000
#define IMASK_RXB0 0x00008000
+#define IMASK_MAG 0x00000800
#define IMASK_GTSC 0x00000100
#define IMASK_RXFEN0 0x00000080
#define IMASK_FIR 0x00000008
@@ -737,10 +741,14 @@ struct gfar_private {
unsigned int fifo_starve;
unsigned int fifo_starve_off;
+ /* Bitfield update lock */
+ spinlock_t bflock;
+
unsigned char vlan_enable:1,
rx_csum_enable:1,
extended_hash:1,
- bd_stash_en:1;
+ bd_stash_en:1,
+ wol_en:1; /* Wake-on-LAN enabled */
unsigned short padding;
unsigned int interruptTransmit;
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c
index 6007147..fb7d3cc 100644
--- a/drivers/net/gianfar_ethtool.c
+++ b/drivers/net/gianfar_ethtool.c
@@ -479,14 +479,13 @@ static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rva
static int gfar_set_rx_csum(struct net_device *dev, uint32_t data)
{
struct gfar_private *priv = netdev_priv(dev);
+ unsigned long flags;
int err = 0;
if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
return -EOPNOTSUPP;
if (dev->flags & IFF_UP) {
- unsigned long flags;
-
/* Halt TX and RX, and process the frames which
* have already been received */
spin_lock_irqsave(&priv->txlock, flags);
@@ -502,7 +501,9 @@ static int gfar_set_rx_csum(struct net_device *dev, uint32_t data)
stop_gfar(dev);
}
+ spin_lock_irqsave(&priv->bflock, flags);
priv->rx_csum_enable = data;
+ spin_unlock_irqrestore(&priv->bflock, flags);
if (dev->flags & IFF_UP)
err = startup_gfar(dev);
@@ -564,6 +565,38 @@ static void gfar_set_msglevel(struct net_device *dev, uint32_t data)
priv->msg_enable = data;
}
+#ifdef CONFIG_PM
+static void gfar_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+ struct gfar_private *priv = netdev_priv(dev);
+
+ if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) {
+ wol->supported = WAKE_MAGIC;
+ wol->wolopts = priv->wol_en ? WAKE_MAGIC : 0;
+ } else {
+ wol->supported = wol->wolopts = 0;
+ }
+}
+
+static int gfar_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+ struct gfar_private *priv = netdev_priv(dev);
+ unsigned long flags;
+
+ if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) &&
+ wol->wolopts != 0)
+ return -EINVAL;
+
+ if (wol->wolopts & ~WAKE_MAGIC)
+ return -EINVAL;
+
+ spin_lock_irqsave(&priv->bflock, flags);
+ priv->wol_en = wol->wolopts & WAKE_MAGIC ? 1 : 0;
+ spin_unlock_irqrestore(&priv->bflock, flags);
+
+ return 0;
+}
+#endif
const struct ethtool_ops gfar_ethtool_ops = {
.get_settings = gfar_gsettings,
@@ -585,4 +618,8 @@ const struct ethtool_ops gfar_ethtool_ops = {
.set_tx_csum = gfar_set_tx_csum,
.get_msglevel = gfar_get_msglevel,
.set_msglevel = gfar_set_msglevel,
+#ifdef CONFIG_PM
+ .get_wol = gfar_get_wol,
+ .set_wol = gfar_set_wol,
+#endif
};
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
index 0472877..4e625e0 100644
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -69,6 +69,7 @@ struct gianfar_mdio_data {
#define FSL_GIANFAR_DEV_HAS_VLAN 0x00000020
#define FSL_GIANFAR_DEV_HAS_EXTENDED_HASH 0x00000040
#define FSL_GIANFAR_DEV_HAS_PADDING 0x00000080
+#define FSL_GIANFAR_DEV_HAS_MAGIC_PACKET 0x00000100
/* Flags in gianfar_platform_data */
#define FSL_GIANFAR_BRD_HAS_PHY_INTR 0x00000001 /* set or use a timer */
--
1.5.6.rc1.6.gc53ad.dirty
^ permalink raw reply related
* [PATCH 6/6] mpc8313erdb: Add power management to the device tree.
From: Scott Wood @ 2008-07-11 23:04 UTC (permalink / raw)
To: galak; +Cc: linuxppc-dev
In-Reply-To: <20080711230328.GA3835@loki.buserror.net>
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
arch/powerpc/boot/dts/mpc8313erdb.dts | 241 +++++++++++++++++++++++----------
1 files changed, 171 insertions(+), 70 deletions(-)
diff --git a/arch/powerpc/boot/dts/mpc8313erdb.dts b/arch/powerpc/boot/dts/mpc8313erdb.dts
index 3664fb5..2a94ae0 100644
--- a/arch/powerpc/boot/dts/mpc8313erdb.dts
+++ b/arch/powerpc/boot/dts/mpc8313erdb.dts
@@ -109,18 +109,38 @@
reg = <0x200 0x100>;
};
- i2c@3000 {
+ sleep-nexus {
#address-cells = <1>;
- #size-cells = <0>;
- cell-index = <0>;
- compatible = "fsl-i2c";
- reg = <0x3000 0x100>;
- interrupts = <14 0x8>;
- interrupt-parent = <&ipic>;
- dfsrr;
- rtc@68 {
- compatible = "dallas,ds1339";
- reg = <0x68>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ sleep = <&pmc 0x03000000>;
+ ranges;
+
+ i2c@3000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cell-index = <0>;
+ compatible = "fsl-i2c";
+ reg = <0x3000 0x100>;
+ interrupts = <14 0x8>;
+ interrupt-parent = <&ipic>;
+ dfsrr;
+ rtc@68 {
+ compatible = "dallas,ds1339";
+ reg = <0x68>;
+ };
+ };
+
+ crypto@30000 {
+ compatible = "fsl,sec2.2", "fsl,sec2.1",
+ "fsl,sec2.0";
+ reg = <0x30000 0x10000>;
+ interrupts = <11 0x8>;
+ interrupt-parent = <&ipic>;
+ fsl,num-channels = <1>;
+ fsl,channel-fifo-len = <24>;
+ fsl,exec-units-mask = <0x4c>;
+ fsl,descriptor-types-mask = <0x0122003f>;
};
};
@@ -188,37 +208,44 @@
interrupt-parent = <&ipic>;
interrupts = <38 0x8>;
phy_type = "utmi_wide";
+ sleep = <&pmc 0x00300000>;
};
- mdio@24520 {
+ enet0: ethernet@24000 {
#address-cells = <1>;
- #size-cells = <0>;
- compatible = "fsl,gianfar-mdio";
- reg = <0x24520 0x20>;
- phy1: ethernet-phy@1 {
- interrupt-parent = <&ipic>;
- interrupts = <19 0x8>;
- reg = <0x1>;
- device_type = "ethernet-phy";
- };
- phy4: ethernet-phy@4 {
- interrupt-parent = <&ipic>;
- interrupts = <20 0x8>;
- reg = <0x4>;
- device_type = "ethernet-phy";
- };
- };
+ #size-cells = <1>;
+ sleep = <&pmc 0x20000000>;
+ ranges;
- enet0: ethernet@24000 {
cell-index = <0>;
device_type = "network";
model = "eTSEC";
- compatible = "gianfar";
+ compatible = "gianfar", "simple-bus";
reg = <0x24000 0x1000>;
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <37 0x8 36 0x8 35 0x8>;
interrupt-parent = <&ipic>;
phy-handle = < &phy1 >;
+ fsl,magic-packet;
+
+ mdio@24520 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,gianfar-mdio";
+ reg = <0x24520 0x20>;
+ phy1: ethernet-phy@1 {
+ interrupt-parent = <&ipic>;
+ interrupts = <19 0x8>;
+ reg = <0x1>;
+ device_type = "ethernet-phy";
+ };
+ phy4: ethernet-phy@4 {
+ interrupt-parent = <&ipic>;
+ interrupts = <20 0x8>;
+ reg = <0x4>;
+ device_type = "ethernet-phy";
+ };
+ };
};
enet1: ethernet@25000 {
@@ -231,6 +258,8 @@
interrupts = <34 0x8 33 0x8 32 0x8>;
interrupt-parent = <&ipic>;
phy-handle = < &phy4 >;
+ sleep = <&pmc 0x10000000>;
+ fsl,magic-packet;
};
serial0: serial@4500 {
@@ -253,17 +282,6 @@
interrupt-parent = <&ipic>;
};
- crypto@30000 {
- compatible = "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0";
- reg = <0x30000 0x10000>;
- interrupts = <11 0x8>;
- interrupt-parent = <&ipic>;
- fsl,num-channels = <1>;
- fsl,channel-fifo-len = <24>;
- fsl,exec-units-mask = <0x4c>;
- fsl,descriptor-types-mask = <0x0122003f>;
- };
-
/* IPIC
* interrupts cell = <intr #, sense>
* sense values match linux IORESOURCE_IRQ_* defines:
@@ -277,36 +295,119 @@
reg = <0x700 0x100>;
device_type = "ipic";
};
+
+ pmc: power@b00 {
+ compatible = "fsl,mpc8313-pmc", "fsl,mpc8349-pmc";
+ reg = <0xb00 0x100 0xa00 0x100>;
+ interrupts = <80 8>;
+ interrupt-parent = <&ipic>;
+ fsl,mpc8313-wakeup-timer = <>m1>;
+
+ /* Remove this (or change to "okay") if you have
+ * a REVA3 or later board, if you apply one of the
+ * workarounds listed in section 8.5 of the board
+ * manual, or if you are adapting this device tree
+ * to a different board.
+ */
+ status = "fail";
+ };
+
+ gtm1: timer@500 {
+ compatible = "fsl,mpc8313-gtm", "fsl,gtm";
+ reg = <0x500 0x100>;
+ interrupts = <90 8 78 8 84 8 72 8>;
+ interrupt-parent = <&ipic>;
+ };
+
+ timer@600 {
+ compatible = "fsl,mpc8313-gtm", "fsl,gtm";
+ reg = <0x600 0x100>;
+ interrupts = <91 8 79 8 85 8 73 8>;
+ interrupt-parent = <&ipic>;
+ };
};
- pci0: pci@e0008500 {
- cell-index = <1>;
- interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
- interrupt-map = <
-
- /* IDSEL 0x0E -mini PCI */
- 0x7000 0x0 0x0 0x1 &ipic 18 0x8
- 0x7000 0x0 0x0 0x2 &ipic 18 0x8
- 0x7000 0x0 0x0 0x3 &ipic 18 0x8
- 0x7000 0x0 0x0 0x4 &ipic 18 0x8
-
- /* IDSEL 0x0F - PCI slot */
- 0x7800 0x0 0x0 0x1 &ipic 17 0x8
- 0x7800 0x0 0x0 0x2 &ipic 18 0x8
- 0x7800 0x0 0x0 0x3 &ipic 17 0x8
- 0x7800 0x0 0x0 0x4 &ipic 18 0x8>;
- interrupt-parent = <&ipic>;
- interrupts = <66 0x8>;
- bus-range = <0x0 0x0>;
- ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000
- 0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000
- 0x01000000 0x0 0x00000000 0xe2000000 0x0 0x00100000>;
- clock-frequency = <66666666>;
- #interrupt-cells = <1>;
- #size-cells = <2>;
- #address-cells = <3>;
- reg = <0xe0008500 0x100>;
- compatible = "fsl,mpc8349-pci";
- device_type = "pci";
+ sleep-nexus {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ sleep = <&pmc 0x00010000>;
+ ranges;
+
+ pci0: pci@e0008500 {
+ cell-index = <1>;
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+ interrupt-map = <
+ /* IDSEL 0x0E -mini PCI */
+ 0x7000 0x0 0x0 0x1 &ipic 18 0x8
+ 0x7000 0x0 0x0 0x2 &ipic 18 0x8
+ 0x7000 0x0 0x0 0x3 &ipic 18 0x8
+ 0x7000 0x0 0x0 0x4 &ipic 18 0x8
+
+ /* IDSEL 0x0F - PCI slot */
+ 0x7800 0x0 0x0 0x1 &ipic 17 0x8
+ 0x7800 0x0 0x0 0x2 &ipic 18 0x8
+ 0x7800 0x0 0x0 0x3 &ipic 17 0x8
+ 0x7800 0x0 0x0 0x4 &ipic 18 0x8>;
+ interrupt-parent = <&ipic>;
+ interrupts = <66 0x8>;
+ bus-range = <0x0 0x0>;
+ ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000
+ 0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000
+ 0x01000000 0x0 0x00000000 0xe2000000 0x0 0x00100000>;
+ clock-frequency = <66666666>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0xe0008500 0x100>;
+ compatible = "fsl,mpc8349-pci";
+ device_type = "pci";
+ };
+
+ dma@82a8 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8313-dma", "fsl,elo-dma";
+ reg = <0xe00082a8 4>;
+ ranges = <0 0xe0008100 0x1a8>;
+ interrupt-parent = <&ipic>;
+ interrupts = <71 8>;
+
+ dma-channel@0 {
+ compatible = "fsl,mpc8313-dma-channel",
+ "fsl,elo-dma-channel";
+ reg = <0 0x28>;
+ interrupt-parent = <&ipic>;
+ interrupts = <71 8>;
+ cell-index = <0>;
+ };
+
+ dma-channel@80 {
+ compatible = "fsl,mpc8313-dma-channel",
+ "fsl,elo-dma-channel";
+ reg = <0x80 0x28>;
+ interrupt-parent = <&ipic>;
+ interrupts = <71 8>;
+ cell-index = <1>;
+ };
+
+ dma-channel@100 {
+ compatible = "fsl,mpc8313-dma-channel",
+ "fsl,elo-dma-channel";
+ reg = <0x100 0x28>;
+ interrupt-parent = <&ipic>;
+ interrupts = <71 8>;
+ cell-index = <2>;
+ };
+
+ dma-channel@180 {
+ compatible = "fsl,mpc8313-dma-channel",
+ "fsl,elo-dma-channel";
+ reg = <0x180 0x28>;
+ interrupt-parent = <&ipic>;
+ interrupts = <71 8>;
+ cell-index = <3>;
+ };
+ };
};
};
--
1.5.6.rc1.6.gc53ad.dirty
^ permalink raw reply related
* [PATCH 3/6] mpc83xx: Power Management support
From: Scott Wood @ 2008-07-11 23:04 UTC (permalink / raw)
To: galak; +Cc: linuxppc-dev
In-Reply-To: <20080711230328.GA3835@loki.buserror.net>
Basic PM support for 83xx. Standby is implemented as sleep.
Suspend-to-RAM is implemented as "deep sleep" (with the processor
turned off) on 831x.
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
arch/powerpc/Kconfig | 2 +-
arch/powerpc/platforms/83xx/Makefile | 1 +
arch/powerpc/platforms/83xx/suspend-asm.S | 533 +++++++++++++++++++++++++++++
arch/powerpc/platforms/83xx/suspend.c | 388 +++++++++++++++++++++
arch/powerpc/sysdev/fsl_soc.h | 1 +
arch/powerpc/sysdev/ipic.c | 71 ++++
include/asm-powerpc/reg.h | 4 +
include/linux/fsl_devices.h | 6 +
8 files changed, 1005 insertions(+), 1 deletions(-)
create mode 100644 arch/powerpc/platforms/83xx/suspend-asm.S
create mode 100644 arch/powerpc/platforms/83xx/suspend.c
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index f2a0f50..c22a7bf 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -192,7 +192,7 @@ config ARCH_HIBERNATION_POSSIBLE
config ARCH_SUSPEND_POSSIBLE
def_bool y
- depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200
+ depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx
config PPC_DCR_NATIVE
bool
diff --git a/arch/powerpc/platforms/83xx/Makefile b/arch/powerpc/platforms/83xx/Makefile
index f331fd7..32c7ad1 100644
--- a/arch/powerpc/platforms/83xx/Makefile
+++ b/arch/powerpc/platforms/83xx/Makefile
@@ -3,6 +3,7 @@
#
obj-y := misc.o usb.o
obj-$(CONFIG_PCI) += pci.o
+obj-$(CONFIG_SUSPEND) += suspend.o suspend-asm.o
obj-$(CONFIG_MPC831x_RDB) += mpc831x_rdb.o
obj-$(CONFIG_MPC832x_RDB) += mpc832x_rdb.o
obj-$(CONFIG_MPC834x_MDS) += mpc834x_mds.o
diff --git a/arch/powerpc/platforms/83xx/suspend-asm.S b/arch/powerpc/platforms/83xx/suspend-asm.S
new file mode 100644
index 0000000..1930543
--- /dev/null
+++ b/arch/powerpc/platforms/83xx/suspend-asm.S
@@ -0,0 +1,533 @@
+/*
+ * Enter and leave deep sleep state on MPC83xx
+ *
+ * Copyright (c) 2006-2008 Freescale Semiconductor, Inc.
+ * Author: Scott Wood <scottwood@freescale.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <asm/page.h>
+#include <asm/ppc_asm.h>
+#include <asm/reg.h>
+#include <asm/asm-offsets.h>
+
+#define SS_MEMSAVE 0x00 /* First 8 bytes of RAM */
+#define SS_HID 0x08 /* 3 HIDs */
+#define SS_IABR 0x14 /* 2 IABRs */
+#define SS_IBCR 0x1c
+#define SS_DABR 0x20 /* 2 DABRs */
+#define SS_DBCR 0x28
+#define SS_SP 0x2c
+#define SS_SR 0x30 /* 16 segment registers */
+#define SS_R2 0x70
+#define SS_MSR 0x74
+#define SS_SDR1 0x78
+#define SS_LR 0x7c
+#define SS_SPRG 0x80 /* 4 SPRGs */
+#define SS_DBAT 0x90 /* 8 DBATs */
+#define SS_IBAT 0xd0 /* 8 IBATs */
+#define SS_TB 0x110
+#define SS_CR 0x118
+#define SS_GPREG 0x11c /* r12-r31 */
+#define STATE_SAVE_SIZE 0x16c
+
+ .section .data
+ .align 5
+
+mpc83xx_sleep_save_area:
+ .space STATE_SAVE_SIZE
+immrbase:
+ .long 0
+
+ .section .text
+ .align 5
+
+ /* r3 = physical address of IMMR */
+_GLOBAL(mpc83xx_enter_deep_sleep)
+ lis r4, immrbase@ha
+ stw r3, immrbase@l(r4)
+
+ /* The first 2 words of memory are used to communicate with the
+ * bootloader, to tell it how to resume.
+ *
+ * The first word is the magic number 0xf5153ae5, and the second
+ * is the pointer to mpc83xx_deep_resume.
+ *
+ * The original content of these two words is saved in SS_MEMSAVE.
+ */
+
+ lis r3, mpc83xx_sleep_save_area@h
+ ori r3, r3, mpc83xx_sleep_save_area@l
+
+ lis r4, KERNELBASE@h
+ lwz r5, 0(r4)
+ lwz r6, 4(r4)
+
+ stw r5, SS_MEMSAVE+0(r3)
+ stw r6, SS_MEMSAVE+4(r3)
+
+ mfspr r5, SPRN_HID0
+ mfspr r6, SPRN_HID1
+ mfspr r7, SPRN_HID2
+
+ stw r5, SS_HID+0(r3)
+ stw r6, SS_HID+4(r3)
+ stw r7, SS_HID+8(r3)
+
+ mfspr r4, SPRN_IABR
+ mfspr r5, SPRN_IABR2
+ mfspr r6, SPRN_IBCR
+ mfspr r7, SPRN_DABR
+ mfspr r8, SPRN_DABR2
+ mfspr r9, SPRN_DBCR
+
+ stw r4, SS_IABR+0(r3)
+ stw r5, SS_IABR+4(r3)
+ stw r6, SS_IBCR(r3)
+ stw r7, SS_DABR+0(r3)
+ stw r8, SS_DABR+4(r3)
+ stw r9, SS_DBCR(r3)
+
+ mfspr r4, SPRN_SPRG0
+ mfspr r5, SPRN_SPRG1
+ mfspr r6, SPRN_SPRG2
+ mfspr r7, SPRN_SPRG3
+ mfsdr1 r8
+
+ stw r4, SS_SPRG+0(r3)
+ stw r5, SS_SPRG+4(r3)
+ stw r6, SS_SPRG+8(r3)
+ stw r7, SS_SPRG+12(r3)
+ stw r8, SS_SDR1(r3)
+
+ mfspr r4, SPRN_DBAT0U
+ mfspr r5, SPRN_DBAT0L
+ mfspr r6, SPRN_DBAT1U
+ mfspr r7, SPRN_DBAT1L
+
+ stw r4, SS_DBAT+0x00(r3)
+ stw r5, SS_DBAT+0x04(r3)
+ stw r6, SS_DBAT+0x08(r3)
+ stw r7, SS_DBAT+0x0c(r3)
+
+ mfspr r4, SPRN_DBAT2U
+ mfspr r5, SPRN_DBAT2L
+ mfspr r6, SPRN_DBAT3U
+ mfspr r7, SPRN_DBAT3L
+
+ stw r4, SS_DBAT+0x10(r3)
+ stw r5, SS_DBAT+0x14(r3)
+ stw r6, SS_DBAT+0x18(r3)
+ stw r7, SS_DBAT+0x1c(r3)
+
+ mfspr r4, SPRN_DBAT4U
+ mfspr r5, SPRN_DBAT4L
+ mfspr r6, SPRN_DBAT5U
+ mfspr r7, SPRN_DBAT5L
+
+ stw r4, SS_DBAT+0x20(r3)
+ stw r5, SS_DBAT+0x24(r3)
+ stw r6, SS_DBAT+0x28(r3)
+ stw r7, SS_DBAT+0x2c(r3)
+
+ mfspr r4, SPRN_DBAT6U
+ mfspr r5, SPRN_DBAT6L
+ mfspr r6, SPRN_DBAT7U
+ mfspr r7, SPRN_DBAT7L
+
+ stw r4, SS_DBAT+0x30(r3)
+ stw r5, SS_DBAT+0x34(r3)
+ stw r6, SS_DBAT+0x38(r3)
+ stw r7, SS_DBAT+0x3c(r3)
+
+ mfspr r4, SPRN_IBAT0U
+ mfspr r5, SPRN_IBAT0L
+ mfspr r6, SPRN_IBAT1U
+ mfspr r7, SPRN_IBAT1L
+
+ stw r4, SS_IBAT+0x00(r3)
+ stw r5, SS_IBAT+0x04(r3)
+ stw r6, SS_IBAT+0x08(r3)
+ stw r7, SS_IBAT+0x0c(r3)
+
+ mfspr r4, SPRN_IBAT2U
+ mfspr r5, SPRN_IBAT2L
+ mfspr r6, SPRN_IBAT3U
+ mfspr r7, SPRN_IBAT3L
+
+ stw r4, SS_IBAT+0x10(r3)
+ stw r5, SS_IBAT+0x14(r3)
+ stw r6, SS_IBAT+0x18(r3)
+ stw r7, SS_IBAT+0x1c(r3)
+
+ mfspr r4, SPRN_IBAT4U
+ mfspr r5, SPRN_IBAT4L
+ mfspr r6, SPRN_IBAT5U
+ mfspr r7, SPRN_IBAT5L
+
+ stw r4, SS_IBAT+0x20(r3)
+ stw r5, SS_IBAT+0x24(r3)
+ stw r6, SS_IBAT+0x28(r3)
+ stw r7, SS_IBAT+0x2c(r3)
+
+ mfspr r4, SPRN_IBAT6U
+ mfspr r5, SPRN_IBAT6L
+ mfspr r6, SPRN_IBAT7U
+ mfspr r7, SPRN_IBAT7L
+
+ stw r4, SS_IBAT+0x30(r3)
+ stw r5, SS_IBAT+0x34(r3)
+ stw r6, SS_IBAT+0x38(r3)
+ stw r7, SS_IBAT+0x3c(r3)
+
+ mfmsr r4
+ mflr r5
+ mfcr r6
+
+ stw r4, SS_MSR(r3)
+ stw r5, SS_LR(r3)
+ stw r6, SS_CR(r3)
+ stw r1, SS_SP(r3)
+ stw r2, SS_R2(r3)
+
+1: mftbu r4
+ mftb r5
+ mftbu r6
+ cmpw r4, r6
+ bne 1b
+
+ stw r4, SS_TB+0(r3)
+ stw r5, SS_TB+4(r3)
+
+ stmw r12, SS_GPREG(r3)
+
+ li r4, 0
+ addi r6, r3, SS_SR-4
+1: mfsrin r5, r4
+ stwu r5, 4(r6)
+ addis r4, r4, 0x1000
+ cmpwi r4, 0
+ bne 1b
+
+ /* Disable machine checks and critical exceptions */
+ mfmsr r4
+ rlwinm r4, r4, 0, ~MSR_CE
+ rlwinm r4, r4, 0, ~MSR_ME
+ mtmsr r4
+ isync
+
+#define TMP_VIRT_IMMR 0xf0000000
+#define DEFAULT_IMMR_VALUE 0xff400000
+#define IMMRBAR_BASE 0x0000
+
+ lis r4, immrbase@ha
+ lwz r4, immrbase@l(r4)
+
+ /* Use DBAT0 to address the current IMMR space */
+
+ ori r4, r4, 0x002a
+ mtspr SPRN_DBAT0L, r4
+ lis r8, TMP_VIRT_IMMR@h
+ ori r4, r8, 0x001e /* 1 MByte accessable from Kernel Space only */
+ mtspr SPRN_DBAT0U, r4
+ isync
+
+ /* Use DBAT1 to address the original IMMR space */
+
+ lis r4, DEFAULT_IMMR_VALUE@h
+ ori r4, r4, 0x002a
+ mtspr SPRN_DBAT1L, r4
+ lis r9, (TMP_VIRT_IMMR + 0x01000000)@h
+ ori r4, r9, 0x001e /* 1 MByte accessable from Kernel Space only */
+ mtspr SPRN_DBAT1U, r4
+ isync
+
+ /* Use DBAT2 to address the beginning of RAM. This isn't done
+ * using the normal virtual mapping, because with page debugging
+ * enabled it will be read-only.
+ */
+
+ li r4, 0x0002
+ mtspr SPRN_DBAT2L, r4
+ lis r4, KERNELBASE@h
+ ori r4, r4, 0x001e /* 1 MByte accessable from Kernel Space only */
+ mtspr SPRN_DBAT2U, r4
+ isync
+
+ /* Flush the cache with our BAT, as there will be TLB misses
+ * otherwise if page debugging is enabled, and these misses
+ * will disturb the PLRU algorithm.
+ */
+
+ bl __flush_disable_L1
+
+ /* Keep the i-cache enabled, so the hack below for low-boot
+ * flash will work.
+ */
+ mfspr r3, SPRN_HID0
+ ori r3, r3, HID0_ICE
+ mtspr SPRN_HID0, r3
+ isync
+
+ lis r6, 0xf515
+ ori r6, r6, 0x3ae5
+
+ lis r7, mpc83xx_deep_resume@h
+ ori r7, r7, mpc83xx_deep_resume@l
+ tophys(r7, r7)
+
+ lis r5, KERNELBASE@h
+ stw r6, 0(r5)
+ stw r7, 4(r5)
+
+ /* Reset BARs */
+
+ li r4, 0
+ stw r4, 0x0024(r8)
+ stw r4, 0x002c(r8)
+ stw r4, 0x0034(r8)
+ stw r4, 0x003c(r8)
+ stw r4, 0x0064(r8)
+ stw r4, 0x006c(r8)
+
+ /* Rev 1 of the 8313 has problems with wakeup events that are
+ * pending during the transition to deep sleep state (such as if
+ * the PCI host sets the state to D3 and then D0 in rapid
+ * succession). This check shrinks the race window somewhat.
+ *
+ * See erratum PCI23, though the problem is not limited
+ * to PCI.
+ */
+
+ lwz r3, 0x0b04(r8)
+ andi. r3, r3, 1
+ bne- mpc83xx_deep_resume
+
+ /* Move IMMR back to the default location, following the
+ * procedure specified in the MPC8313 manual.
+ */
+ lwz r4, IMMRBAR_BASE(r8)
+ isync
+ lis r4, DEFAULT_IMMR_VALUE@h
+ stw r4, IMMRBAR_BASE(r8)
+ lis r4, KERNELBASE@h
+ lwz r4, 0(r4)
+ isync
+ lwz r4, IMMRBAR_BASE(r9)
+ mr r8, r9
+ isync
+
+ /* Check the Reset Configuration Word to see whether flash needs
+ * to be mapped at a low address or a high address.
+ */
+
+ lwz r4, 0x0904(r8)
+ andis. r4, r4, 0x0400
+ li r4, 0
+ beq boot_low
+ lis r4, 0xff80
+boot_low:
+ stw r4, 0x0020(r8)
+ lis r7, 0x8000
+ ori r7, r7, 0x0016
+
+ mfspr r5, SPRN_HID0
+ rlwinm r5, r5, 0, ~(HID0_DOZE | HID0_NAP)
+ oris r5, r5, HID0_SLEEP@h
+ mtspr SPRN_HID0, r5
+ isync
+
+ mfmsr r5
+ oris r5, r5, MSR_POW@h
+
+ /* Enable the flash mapping at the appropriate address. This
+ * mapping will override the RAM mapping if booting low, so there's
+ * no need to disable the latter. This must be done inside the same
+ * cache line as setting MSR_POW, so that no instruction fetches
+ * from RAM happen after the flash mapping is turned on.
+ */
+
+ .align 5
+ stw r7, 0x0024(r8)
+ sync
+ isync
+ mtmsr r5
+ isync
+1: b 1b
+
+mpc83xx_deep_resume:
+ lis r4, 1f@h
+ ori r4, r4, 1f@l
+ tophys(r4, r4)
+ mtsrr0 r4
+
+ mfmsr r4
+ rlwinm r4, r4, 0, ~(MSR_IR | MSR_DR)
+ mtsrr1 r4
+
+ rfi
+
+1: tlbia
+ bl __inval_enable_L1
+
+ lis r3, mpc83xx_sleep_save_area@h
+ ori r3, r3, mpc83xx_sleep_save_area@l
+ tophys(r3, r3)
+
+ lwz r5, SS_MEMSAVE+0(r3)
+ lwz r6, SS_MEMSAVE+4(r3)
+
+ stw r5, 0(0)
+ stw r6, 4(0)
+
+ lwz r5, SS_HID+0(r3)
+ lwz r6, SS_HID+4(r3)
+ lwz r7, SS_HID+8(r3)
+
+ mtspr SPRN_HID0, r5
+ mtspr SPRN_HID1, r6
+ mtspr SPRN_HID2, r7
+
+ lwz r4, SS_IABR+0(r3)
+ lwz r5, SS_IABR+4(r3)
+ lwz r6, SS_IBCR(r3)
+ lwz r7, SS_DABR+0(r3)
+ lwz r8, SS_DABR+4(r3)
+ lwz r9, SS_DBCR(r3)
+
+ mtspr SPRN_IABR, r4
+ mtspr SPRN_IABR2, r5
+ mtspr SPRN_IBCR, r6
+ mtspr SPRN_DABR, r7
+ mtspr SPRN_DABR2, r8
+ mtspr SPRN_DBCR, r9
+
+ li r4, 0
+ addi r6, r3, SS_SR-4
+1: lwzu r5, 4(r6)
+ mtsrin r5, r4
+ addis r4, r4, 0x1000
+ cmpwi r4, 0
+ bne 1b
+
+ lwz r4, SS_DBAT+0x00(r3)
+ lwz r5, SS_DBAT+0x04(r3)
+ lwz r6, SS_DBAT+0x08(r3)
+ lwz r7, SS_DBAT+0x0c(r3)
+
+ mtspr SPRN_DBAT0U, r4
+ mtspr SPRN_DBAT0L, r5
+ mtspr SPRN_DBAT1U, r6
+ mtspr SPRN_DBAT1L, r7
+
+ lwz r4, SS_DBAT+0x10(r3)
+ lwz r5, SS_DBAT+0x14(r3)
+ lwz r6, SS_DBAT+0x18(r3)
+ lwz r7, SS_DBAT+0x1c(r3)
+
+ mtspr SPRN_DBAT2U, r4
+ mtspr SPRN_DBAT2L, r5
+ mtspr SPRN_DBAT3U, r6
+ mtspr SPRN_DBAT3L, r7
+
+ lwz r4, SS_DBAT+0x20(r3)
+ lwz r5, SS_DBAT+0x24(r3)
+ lwz r6, SS_DBAT+0x28(r3)
+ lwz r7, SS_DBAT+0x2c(r3)
+
+ mtspr SPRN_DBAT4U, r4
+ mtspr SPRN_DBAT4L, r5
+ mtspr SPRN_DBAT5U, r6
+ mtspr SPRN_DBAT5L, r7
+
+ lwz r4, SS_DBAT+0x30(r3)
+ lwz r5, SS_DBAT+0x34(r3)
+ lwz r6, SS_DBAT+0x38(r3)
+ lwz r7, SS_DBAT+0x3c(r3)
+
+ mtspr SPRN_DBAT6U, r4
+ mtspr SPRN_DBAT6L, r5
+ mtspr SPRN_DBAT7U, r6
+ mtspr SPRN_DBAT7L, r7
+
+ lwz r4, SS_IBAT+0x00(r3)
+ lwz r5, SS_IBAT+0x04(r3)
+ lwz r6, SS_IBAT+0x08(r3)
+ lwz r7, SS_IBAT+0x0c(r3)
+
+ mtspr SPRN_IBAT0U, r4
+ mtspr SPRN_IBAT0L, r5
+ mtspr SPRN_IBAT1U, r6
+ mtspr SPRN_IBAT1L, r7
+
+ lwz r4, SS_IBAT+0x10(r3)
+ lwz r5, SS_IBAT+0x14(r3)
+ lwz r6, SS_IBAT+0x18(r3)
+ lwz r7, SS_IBAT+0x1c(r3)
+
+ mtspr SPRN_IBAT2U, r4
+ mtspr SPRN_IBAT2L, r5
+ mtspr SPRN_IBAT3U, r6
+ mtspr SPRN_IBAT3L, r7
+
+ lwz r4, SS_IBAT+0x20(r3)
+ lwz r5, SS_IBAT+0x24(r3)
+ lwz r6, SS_IBAT+0x28(r3)
+ lwz r7, SS_IBAT+0x2c(r3)
+
+ mtspr SPRN_IBAT4U, r4
+ mtspr SPRN_IBAT4L, r5
+ mtspr SPRN_IBAT5U, r6
+ mtspr SPRN_IBAT5L, r7
+
+ lwz r4, SS_IBAT+0x30(r3)
+ lwz r5, SS_IBAT+0x34(r3)
+ lwz r6, SS_IBAT+0x38(r3)
+ lwz r7, SS_IBAT+0x3c(r3)
+
+ mtspr SPRN_IBAT6U, r4
+ mtspr SPRN_IBAT6L, r5
+ mtspr SPRN_IBAT7U, r6
+ mtspr SPRN_IBAT7L, r7
+
+ lwz r4, SS_SPRG+0(r3)
+ lwz r5, SS_SPRG+4(r3)
+ lwz r6, SS_SPRG+8(r3)
+ lwz r7, SS_SPRG+12(r3)
+ lwz r8, SS_SDR1(r3)
+
+ mtspr SPRN_SPRG0, r4
+ mtspr SPRN_SPRG1, r5
+ mtspr SPRN_SPRG2, r6
+ mtspr SPRN_SPRG3, r7
+ mtsdr1 r8
+
+ lwz r4, SS_MSR(r3)
+ lwz r5, SS_LR(r3)
+ lwz r6, SS_CR(r3)
+ lwz r1, SS_SP(r3)
+ lwz r2, SS_R2(r3)
+
+ mtsrr1 r4
+ mtsrr0 r5
+ mtcr r6
+
+ li r4, 0
+ mtspr SPRN_TBWL, r4
+
+ lwz r4, SS_TB+0(r3)
+ lwz r5, SS_TB+4(r3)
+
+ mtspr SPRN_TBWU, r4
+ mtspr SPRN_TBWL, r5
+
+ lmw r12, SS_GPREG(r3)
+
+ /* Kick decrementer */
+ li r0, 1
+ mtdec r0
+
+ rfi
diff --git a/arch/powerpc/platforms/83xx/suspend.c b/arch/powerpc/platforms/83xx/suspend.c
new file mode 100644
index 0000000..08e65fc
--- /dev/null
+++ b/arch/powerpc/platforms/83xx/suspend.c
@@ -0,0 +1,388 @@
+/*
+ * MPC83xx suspend support
+ *
+ * Author: Scott Wood <scottwood@freescale.com>
+ *
+ * Copyright (c) 2006-2007 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/pm.h>
+#include <linux/types.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/wait.h>
+#include <linux/kthread.h>
+#include <linux/freezer.h>
+#include <linux/suspend.h>
+#include <linux/fsl_devices.h>
+#include <linux/of_platform.h>
+
+#include <asm/reg.h>
+#include <asm/io.h>
+#include <asm/time.h>
+#include <asm/mpc6xx.h>
+
+#include <sysdev/fsl_soc.h>
+
+#define PMCCR1_NEXT_STATE 0x0C /* Next state for power management */
+#define PMCCR1_NEXT_STATE_SHIFT 2
+#define PMCCR1_CURR_STATE 0x03 /* Current state for power management*/
+#define IMMR_RCW_OFFSET 0x900
+#define RCW_PCI_HOST 0x80000000
+
+void mpc83xx_enter_deep_sleep(phys_addr_t immrbase);
+
+struct mpc83xx_pmc {
+ u32 config;
+#define PMCCR_DLPEN 2 /* DDR SDRAM low power enable */
+#define PMCCR_SLPEN 1 /* System low power enable */
+
+ u32 event;
+ u32 mask;
+/* All but PMCI are deep-sleep only */
+#define PMCER_GPIO 0x100
+#define PMCER_PCI 0x080
+#define PMCER_USB 0x040
+#define PMCER_ETSEC1 0x020
+#define PMCER_ETSEC2 0x010
+#define PMCER_TIMER 0x008
+#define PMCER_INT1 0x004
+#define PMCER_INT2 0x002
+#define PMCER_PMCI 0x001
+#define PMCER_ALL 0x1FF
+
+ /* deep-sleep only */
+ u32 config1;
+#define PMCCR1_USE_STATE 0x80000000
+#define PMCCR1_PME_EN 0x00000080
+#define PMCCR1_ASSERT_PME 0x00000040
+#define PMCCR1_POWER_OFF 0x00000020
+
+ /* deep-sleep only */
+ u32 config2;
+};
+
+struct mpc83xx_rcw {
+ u32 rcwlr;
+ u32 rcwhr;
+};
+
+struct mpc83xx_clock {
+ u32 spmr;
+ u32 occr;
+ u32 sccr;
+};
+
+struct pmc_type {
+ int has_deep_sleep;
+};
+
+static struct of_device *pmc_dev;
+static int has_deep_sleep, deep_sleeping;
+static int pmc_irq;
+static struct mpc83xx_pmc __iomem *pmc_regs;
+static struct mpc83xx_clock __iomem *clock_regs;
+static int is_pci_agent, wake_from_pci;
+static phys_addr_t immrbase;
+static int pci_pm_state;
+static DECLARE_WAIT_QUEUE_HEAD(agent_wq);
+
+int fsl_deep_sleep(void)
+{
+ return deep_sleeping;
+}
+
+static int mpc83xx_change_state(void)
+{
+ u32 curr_state;
+ u32 reg_cfg1 = in_be32(&pmc_regs->config1);
+
+ if (is_pci_agent) {
+ pci_pm_state = (reg_cfg1 & PMCCR1_NEXT_STATE) >>
+ PMCCR1_NEXT_STATE_SHIFT;
+ curr_state = reg_cfg1 & PMCCR1_CURR_STATE;
+
+ if (curr_state != pci_pm_state) {
+ reg_cfg1 &= ~PMCCR1_CURR_STATE;
+ reg_cfg1 |= pci_pm_state;
+ out_be32(&pmc_regs->config1, reg_cfg1);
+
+ wake_up(&agent_wq);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static irqreturn_t pmc_irq_handler(int irq, void *dev_id)
+{
+ u32 event = in_be32(&pmc_regs->event);
+ int ret = IRQ_NONE;
+
+ if (mpc83xx_change_state())
+ ret = IRQ_HANDLED;
+
+ if (event) {
+ out_be32(&pmc_regs->event, event);
+ ret = IRQ_HANDLED;
+ }
+
+ return ret;
+}
+
+static int mpc83xx_suspend_enter(suspend_state_t state)
+{
+ int ret = -EAGAIN;
+
+ /* Don't go to sleep if there's a race where pci_pm_state changes
+ * between the agent thread checking it and the PM code disabling
+ * interrupts.
+ */
+ if (wake_from_pci) {
+ if (pci_pm_state != (deep_sleeping ? 3 : 2))
+ goto out;
+
+ out_be32(&pmc_regs->config1,
+ in_be32(&pmc_regs->config1) | PMCCR1_PME_EN);
+ }
+
+ /* Put the system into low-power mode and the RAM
+ * into self-refresh mode once the core goes to
+ * sleep.
+ */
+
+ out_be32(&pmc_regs->config, PMCCR_SLPEN | PMCCR_DLPEN);
+
+ /* If it has deep sleep (i.e. it's an 831x or compatible),
+ * disable power to the core upon entering sleep mode. This will
+ * require going through the boot firmware upon a wakeup event.
+ */
+
+ if (deep_sleeping) {
+ out_be32(&pmc_regs->mask, PMCER_ALL);
+
+ out_be32(&pmc_regs->config1,
+ in_be32(&pmc_regs->config1) | PMCCR1_POWER_OFF);
+
+ enable_kernel_fp();
+
+ mpc83xx_enter_deep_sleep(immrbase);
+
+ out_be32(&pmc_regs->config1,
+ in_be32(&pmc_regs->config1) & ~PMCCR1_POWER_OFF);
+
+ out_be32(&pmc_regs->mask, PMCER_PMCI);
+ } else {
+ out_be32(&pmc_regs->mask, PMCER_PMCI);
+
+ mpc6xx_enter_standby();
+ }
+
+ ret = 0;
+
+out:
+ out_be32(&pmc_regs->config1,
+ in_be32(&pmc_regs->config1) & ~PMCCR1_PME_EN);
+
+ return ret;
+}
+
+static void mpc83xx_suspend_finish(void)
+{
+ deep_sleeping = 0;
+}
+
+static int mpc83xx_suspend_valid(suspend_state_t state)
+{
+ return state == PM_SUSPEND_STANDBY || state == PM_SUSPEND_MEM;
+}
+
+static int mpc83xx_suspend_begin(suspend_state_t state)
+{
+ switch (state) {
+ case PM_SUSPEND_STANDBY:
+ deep_sleeping = 0;
+ return 0;
+
+ case PM_SUSPEND_MEM:
+ if (has_deep_sleep)
+ deep_sleeping = 1;
+
+ return 0;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static int agent_thread_fn(void *data)
+{
+ while (1) {
+ wait_event_interruptible(agent_wq, pci_pm_state >= 2);
+ try_to_freeze();
+
+ if (signal_pending(current) || pci_pm_state < 2)
+ continue;
+
+ /* With a preemptible kernel (or SMP), this could race with
+ * a userspace-driven suspend request. It's probably best
+ * to avoid mixing the two with such a configuration (or
+ * else fix it by adding a mutex to state_store that we can
+ * synchronize with).
+ */
+
+ wake_from_pci = 1;
+
+ pm_suspend(pci_pm_state == 3 ? PM_SUSPEND_MEM :
+ PM_SUSPEND_STANDBY);
+
+ wake_from_pci = 0;
+ }
+
+ return 0;
+}
+
+static void mpc83xx_set_agent(void)
+{
+ out_be32(&pmc_regs->config1, PMCCR1_USE_STATE);
+ out_be32(&pmc_regs->mask, PMCER_PMCI);
+
+ kthread_run(agent_thread_fn, NULL, "PCI power mgt");
+}
+
+static int mpc83xx_is_pci_agent(void)
+{
+ struct mpc83xx_rcw __iomem *rcw_regs;
+ int ret;
+
+ rcw_regs = ioremap(get_immrbase() + IMMR_RCW_OFFSET,
+ sizeof(struct mpc83xx_rcw));
+
+ if (!rcw_regs)
+ return -ENOMEM;
+
+ ret = !(in_be32(&rcw_regs->rcwhr) & RCW_PCI_HOST);
+
+ iounmap(rcw_regs);
+ return ret;
+}
+
+static struct platform_suspend_ops mpc83xx_suspend_ops = {
+ .valid = mpc83xx_suspend_valid,
+ .begin = mpc83xx_suspend_begin,
+ .enter = mpc83xx_suspend_enter,
+ .finish = mpc83xx_suspend_finish,
+};
+
+static int pmc_probe(struct of_device *ofdev,
+ const struct of_device_id *match)
+{
+ struct device_node *np = ofdev->node;
+ struct resource res;
+ struct pmc_type *type = match->data;
+ int ret = 0;
+
+ if (!of_device_is_available(np))
+ return -ENODEV;
+
+ has_deep_sleep = type->has_deep_sleep;
+ immrbase = get_immrbase();
+ pmc_dev = ofdev;
+
+ is_pci_agent = mpc83xx_is_pci_agent();
+ if (is_pci_agent < 0)
+ return is_pci_agent;
+
+ ret = of_address_to_resource(np, 0, &res);
+ if (ret)
+ return -ENODEV;
+
+ pmc_irq = irq_of_parse_and_map(np, 0);
+ if (pmc_irq != NO_IRQ) {
+ ret = request_irq(pmc_irq, pmc_irq_handler, IRQF_SHARED,
+ "pmc", ofdev);
+
+ if (ret)
+ return -EBUSY;
+ }
+
+ pmc_regs = ioremap(res.start, sizeof(struct mpc83xx_pmc));
+
+ if (!pmc_regs) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = of_address_to_resource(np, 1, &res);
+ if (ret) {
+ ret = -ENODEV;
+ goto out_pmc;
+ }
+
+ clock_regs = ioremap(res.start, sizeof(struct mpc83xx_pmc));
+
+ if (!clock_regs) {
+ ret = -ENOMEM;
+ goto out_pmc;
+ }
+
+ if (is_pci_agent)
+ mpc83xx_set_agent();
+
+ suspend_set_ops(&mpc83xx_suspend_ops);
+ return 0;
+
+out_pmc:
+ iounmap(pmc_regs);
+out:
+ if (pmc_irq != NO_IRQ)
+ free_irq(pmc_irq, ofdev);
+
+ return ret;
+}
+
+static int pmc_remove(struct of_device *ofdev)
+{
+ return -EPERM;
+};
+
+static struct pmc_type pmc_types[] = {
+ {
+ .has_deep_sleep = 1,
+ },
+ {
+ .has_deep_sleep = 0,
+ }
+};
+
+static struct of_device_id pmc_match[] = {
+ {
+ .compatible = "fsl,mpc8313-pmc",
+ .data = &pmc_types[0],
+ },
+ {
+ .compatible = "fsl,mpc8349-pmc",
+ .data = &pmc_types[1],
+ },
+ {}
+};
+
+static struct of_platform_driver pmc_driver = {
+ .name = "mpc83xx-pmc",
+ .match_table = pmc_match,
+ .probe = pmc_probe,
+ .remove = pmc_remove
+};
+
+static int pmc_init(void)
+{
+ return of_register_platform_driver(&pmc_driver);
+}
+
+module_init(pmc_init);
diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h
index 52c831f..0242998 100644
--- a/arch/powerpc/sysdev/fsl_soc.h
+++ b/arch/powerpc/sysdev/fsl_soc.h
@@ -10,6 +10,7 @@ extern u32 get_baudrate(void);
extern u32 fsl_get_sys_freq(void);
struct spi_board_info;
+struct device_node;
extern int fsl_spi_init(struct spi_board_info *board_infos,
unsigned int num_board_infos,
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index caba1c0..88a983e 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -22,6 +22,7 @@
#include <linux/device.h>
#include <linux/bootmem.h>
#include <linux/spinlock.h>
+#include <linux/fsl_devices.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/prom.h>
@@ -889,8 +890,78 @@ unsigned int ipic_get_irq(void)
return irq_linear_revmap(primary_ipic->irqhost, irq);
}
+#ifdef CONFIG_PM
+static struct {
+ u32 sicfr;
+ u32 siprr[2];
+ u32 simsr[2];
+ u32 sicnr;
+ u32 smprr[2];
+ u32 semsr;
+ u32 secnr;
+ u32 sermr;
+ u32 sercr;
+} ipic_saved_state;
+
+static int ipic_suspend(struct sys_device *sdev, pm_message_t state)
+{
+ struct ipic *ipic = primary_ipic;
+
+ ipic_saved_state.sicfr = ipic_read(ipic->regs, IPIC_SICFR);
+ ipic_saved_state.siprr[0] = ipic_read(ipic->regs, IPIC_SIPRR_A);
+ ipic_saved_state.siprr[1] = ipic_read(ipic->regs, IPIC_SIPRR_D);
+ ipic_saved_state.simsr[0] = ipic_read(ipic->regs, IPIC_SIMSR_H);
+ ipic_saved_state.simsr[1] = ipic_read(ipic->regs, IPIC_SIMSR_L);
+ ipic_saved_state.sicnr = ipic_read(ipic->regs, IPIC_SICNR);
+ ipic_saved_state.smprr[0] = ipic_read(ipic->regs, IPIC_SMPRR_A);
+ ipic_saved_state.smprr[1] = ipic_read(ipic->regs, IPIC_SMPRR_B);
+ ipic_saved_state.semsr = ipic_read(ipic->regs, IPIC_SEMSR);
+ ipic_saved_state.secnr = ipic_read(ipic->regs, IPIC_SECNR);
+ ipic_saved_state.sermr = ipic_read(ipic->regs, IPIC_SERMR);
+ ipic_saved_state.sercr = ipic_read(ipic->regs, IPIC_SERCR);
+
+ if (fsl_deep_sleep()) {
+ /* In deep sleep, make sure there can be no
+ * pending interrupts, as this can cause
+ * problems on 831x.
+ */
+ ipic_write(ipic->regs, IPIC_SIMSR_H, 0);
+ ipic_write(ipic->regs, IPIC_SIMSR_L, 0);
+ ipic_write(ipic->regs, IPIC_SEMSR, 0);
+ ipic_write(ipic->regs, IPIC_SERMR, 0);
+ }
+
+ return 0;
+}
+
+static int ipic_resume(struct sys_device *sdev)
+{
+ struct ipic *ipic = primary_ipic;
+
+ ipic_write(ipic->regs, IPIC_SICFR, ipic_saved_state.sicfr);
+ ipic_write(ipic->regs, IPIC_SIPRR_A, ipic_saved_state.siprr[0]);
+ ipic_write(ipic->regs, IPIC_SIPRR_D, ipic_saved_state.siprr[1]);
+ ipic_write(ipic->regs, IPIC_SIMSR_H, ipic_saved_state.simsr[0]);
+ ipic_write(ipic->regs, IPIC_SIMSR_L, ipic_saved_state.simsr[1]);
+ ipic_write(ipic->regs, IPIC_SICNR, ipic_saved_state.sicnr);
+ ipic_write(ipic->regs, IPIC_SMPRR_A, ipic_saved_state.smprr[0]);
+ ipic_write(ipic->regs, IPIC_SMPRR_B, ipic_saved_state.smprr[1]);
+ ipic_write(ipic->regs, IPIC_SEMSR, ipic_saved_state.semsr);
+ ipic_write(ipic->regs, IPIC_SECNR, ipic_saved_state.secnr);
+ ipic_write(ipic->regs, IPIC_SERMR, ipic_saved_state.sermr);
+ ipic_write(ipic->regs, IPIC_SERCR, ipic_saved_state.sercr);
+
+ return 0;
+}
+#else
+#define ipic_suspend NULL
+#define ipic_resume NULL
+#endif
+
static struct sysdev_class ipic_sysclass = {
.name = "ipic",
+ .suspend = ipic_suspend,
+ .resume = ipic_resume,
};
static struct sys_device device_ipic = {
diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h
index bbccadf..c6d1ab6 100644
--- a/include/asm-powerpc/reg.h
+++ b/include/asm-powerpc/reg.h
@@ -155,10 +155,12 @@
#define CTRL_RUNLATCH 0x1
#define SPRN_DABR 0x3F5 /* Data Address Breakpoint Register */
#define DABR_TRANSLATION (1UL << 2)
+#define SPRN_DABR2 0x13D /* e300 */
#define SPRN_DABRX 0x3F7 /* Data Address Breakpoint Register Extension */
#define DABRX_USER (1UL << 0)
#define DABRX_KERNEL (1UL << 1)
#define SPRN_DAR 0x013 /* Data Address Register */
+#define SPRN_DBCR 0x136 /* e300 Data Breakpoint Control Reg */
#define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */
#define DSISR_NOHPTE 0x40000000 /* no translation found */
#define DSISR_PROTFAULT 0x08000000 /* protection fault */
@@ -264,6 +266,8 @@
#define HID1_PS (1<<16) /* 750FX PLL selection */
#define SPRN_HID2 0x3F8 /* Hardware Implementation Register 2 */
#define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */
+#define SPRN_IABR2 0x3FA /* 83xx */
+#define SPRN_IBCR 0x135 /* 83xx Insn Breakpoint Control Reg */
#define SPRN_HID4 0x3F4 /* 970 HID4 */
#define SPRN_HID5 0x3F6 /* 970 HID5 */
#define SPRN_HID6 0x3F9 /* BE HID 6 */
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
index c415a49..0472877 100644
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -125,4 +125,10 @@ struct mpc8xx_pcmcia_ops {
int(*voltage_set)(int slot, int vcc, int vpp);
};
+/* Returns non-zero if the current suspend operation would
+ * lead to a deep sleep (i.e. power removed from the core,
+ * instead of just the clock).
+ */
+int fsl_deep_sleep(void);
+
#endif /* _FSL_DEVICE_H_ */
--
1.5.6.rc1.6.gc53ad.dirty
^ permalink raw reply related
* Re: Updates to powerpc.git
From: Benjamin Herrenschmidt @ 2008-07-12 3:30 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev list, Andrew Morton
In-Reply-To: <7CAAEE49-56F0-4565-8F1B-374C5E2F9E42@kernel.crashing.org>
> What is your intent with the 'master' branch? I hope you do NOT plan
> on ever rebasing it. I assume if a patch gets into master and we drop
> it you'll do a git-revert of it?
I'll try as much as possible. But I'll keep the option open. "next" is
the one that should never be rebased I'd say.
Ben.
^ permalink raw reply
* Re: [PATCH] powerpc: Fix problems with 32bit PPC's running with more than 2GB of RAM
From: Benjamin Herrenschmidt @ 2008-07-12 3:33 UTC (permalink / raw)
To: Becky Bruce; +Cc: linuxppc-dev, Stefan Roese
In-Reply-To: <E87ABEE7-3CD0-45E5-9806-BE3BAAFCFE1C@freescale.com>
> Are you *sure* you can see all 4GB? I thought we lost some of the 32-
> bit PCI address space for PCI IO...... Disclaimer: I'm no expert on
> PCI :)
You are right. I didn't think that through when I replied. We do lose
some of it for MMIO (not IO). So we cannot really go all the way to 4G
because we can't DMA to all of it, right.
> FYI, I'm *very* close to having swiotlb fully functional on powerpc to
> support larger RAM - I am able to boot with 6GB on 8641 right now.
> There are some bugs that I'm still shaking out - I hope to push this
> out in the next couple of weeks.
That won't make .27 then ?
Cheers,
Ben.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox