Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* alignment faults in 3.6
From: Russell King - ARM Linux @ 2012-10-12 11:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <yw1x8vbcndlb.fsf@unicorn.mansr.com>

On Fri, Oct 12, 2012 at 12:18:08PM +0100, M?ns Rullg?rd wrote:
> Russell King - ARM Linux <linux@arm.linux.org.uk> writes:
> > Well, I get the last word here and it's no.
> 
> Sadly, yes.

It's not "sadly" - it's a matter of fact that the kernel does from time
to time generate misaligned accesses and they are _not_ bugs.  If they
were bugs, then the code to fix up misaligned accesses would not have
been developed, and we'd instead take the fault and panic or something
like that.

> >> >> If all alignment faults in the kernel are caused by broken drivers,
> >> >> that would at least give us some hope of finding those drivers while
> >> >> at the same time not causing much overhead in the case where we need
> >> >> to do the fixup in the meantime.
> >> >
> >> > No.  It is my understanding that various IP option processing can also
> >> > cause the alignment fault handler to be invoked, even when the packet is
> >> > properly aligned, and then there's jffs2/mtd which also relies upon
> >> > alignment faults being fixed up.
> >> 
> >> As far as I'm concerned, this is all hearsay, and I've only ever heard
> >> it from you.  Why can't you let those who care fix these bugs instead?
> >
> > You know, I'm giving you the benefit of my _knowledge_ which has been
> > built over the course of the last 20 years.
> 
> How proud you sound.  Now could you say something of substance instead?

You're proving yourself to be idiot?  There, that's substance.

> > I've been in these discussions with networking people before.  I ended
> > up having to develop the alignment fault handler because of those
> > discussions.  And oh look, Eric confirmed that the networking code
> > isn't going to get "fixed" as you were demanding, which is exactly
> > what I said.
> 
> Funny, I saw him say the exact opposite:
> 
>   So if you find an offender, please report a bug, because I can
>   guarantee you we will _fix_ it.

No, let's go back.

- You were demanding that the ipv4 header structure should be packed.
  I said that wasn't going to happen because the networking people
  wouldn't allow it, and it seems that's been proven correct.
- You were demanding that the ipv4 code used the unaligned accessors.
  I said that networking people wouldn't allow it either, and that's
  also been proven correct.

Both these points have been proven correct because Eric has said that the
core networking code is _not_ going to be changed to suit this.

What Eric _has_ said is that networking people consider packets supplied
to the networking layer where the IPv4 header is not aligned on architectures
where misaligned accesses are a problem to be a bug in the network driver,
not the network code, and proposed a solution.

That's entirely different from all your claims that the core networking
code needs fixing to avoid these misaligned accesses.

> > I've been in discussions with MTD people over these issues before, I've
> > discussed this with David Woodhouse when it came up in JFFS2.  I *KNOW*
> > these things.
> 
> In the same way you "know" the networking people won't fix their code,
> despite them _clearly_ stating the opposite?

I'll tell you exactly how I *KNOW* this.  The issue came up because of
noMMU, which does not have any way to fix up alignment faults.  JFFS2
passes randomly aligned buffers to the MTD drivers, and the MTD drivers
assume that they're aligned and they do word accesses on them.

See the thread http://lists.arm.linux.org.uk/lurker/thread/20021204.191632.4473796b.en.html

See: http://lists.arm.linux.org.uk/lurker/message/20020225.195925.02bdbd47.en.html
and: http://lists.arm.linux.org.uk/lurker/message/20020313.150932.081a7592.en.html

There's several other threads where it's also discussed.

And while you're there, note the date.  There is nothing recent about this
issue.  It's well known, and well understood by those who have a grasp of
the issues that alignment faults are a part of normal operation by the
ARM kernel - and is one of the penalties of being tied into architecture
independent code.

Compromises have to be sought, and that's the compromise we get to live
with.

> > You can call it hearsay if you wish, but it seems to be more accurate
> > than your wild outlandish and pathetic statements.
> 
> So you're resorting to name-calling.  Not taking that bait.

Sorry?  So what you're saying is that it's fine for you to call my
comments hearsay, but I'm not allowed to express a view on your comments.
How arrogant of you.

^ permalink raw reply

* ARM: hw_breakpoint: silent EPERM when setting ARM_DSCR_MDBGEN on ARM_DEBUG_ARCH_V7_ECP14
From: Dietmar Eggemann @ 2012-10-12 11:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAPfQmKJAvd2R8Je-uRdKkkhgQRodZFxP1N_QzbjKm8q7q1HgaQ@mail.gmail.com>

On 09/10/12 18:05, Valentin Pistol wrote:
> Will,
>
> On Tue, Sep 18, 2012 at 3:04 AM, Will Deacon <will.deacon@arm.com> wrote:
>>
>> On Fri, Sep 14, 2012 at 09:08:24AM +0100, Valentin Pistol wrote:
>>> Is there a reliable way to determine that they are locked down?
>>> Any particular register/bit I can check to confirm?
>>
>> You can take a look at the DBGAUTHSTATUS register and try to determine the
>> signal values for SPNIDEN, DBGEN and NIDEN.
>
> DBGAUTHSTATUS=0xaa confirming DBGEN is LOW. Since then I found out
> that there are two types of OMAP devices:
> GP (General Purpose) and HS (High Security) and supposedly Debug
> Capabilities are only available on GP devices.
> Thus, I ordered a Pandaboard ES with OMAP4460 and tested it with a
> prebuilt Ubuntu 12.04 image.
> After boot monitor mode is still not set, the DSCR reads the same
> 0x01030002 just as with the previous Galaxy Nexus.
>
> I contacted TI and they seem to say hw breakpoints/watchpoints are
> available on Pandaboard but they are confused about monitor mode,
> saying it's not available on Pandaboard GP.
> See http://e2e.ti.com/support/omap/f/849/p/216276/770995.aspx for the
> discussion.
> Isn't monitor mode and DBGEN on HIGH required for access to
> breakpoints/watchpoints?
> Maybe they are thinking about Secure Monitor Mode and TrustZone which
> is not related?
>
> Have you used a Pandaboard and can comment on how to enable the
> breakpoints/watchpoints?
> Could you also mention a specific development board that you are using
> and recommend for access to these features?

I'm running Linaro 12.08 on Pandaboard (Rev A1) and on this board 
DBGAUTHSTATUS.NSNE and DBGAUTHSTATUS.NSE are set.

With additional logs in enable_monitor_mode() 
[arch/arm/kernel/hw_breakpoint.c]:

root at linaro-nano:~# dmesg | grep hw-break
[    0.321380] hw-breakpoint: arch_hw_breakpoint_init cpu0 debug_arch=3
[    0.321441] hw-breakpoint: enable_monitor_mode cpu1 
DBGDSCR=03070002
[    0.321441] hw-breakpoint: enable_monitor_mode cpu1 
DBGAUTHSTATUS=000000af
[    0.321502] hw-breakpoint: enable_monitor_mode cpu0 
DBGDSCR=03070002
[    0.321533] hw-breakpoint: enable_monitor_mode cpu0 
DBGAUTHSTATUS=000000af
[    0.321533] hw-breakpoint: found 5 (+1 reserved) breakpoint and 1 
watchpoint registers.
[    0.321563] hw-breakpoint: maximum watchpoint size is 4 bytes.

-- Dietmar

>
>>
>>>> Completely untested patch below, please let me know how you get on...
>>>
>>> Looks good, I'll give it a try.
>>
>> Great. Let me know if it helps and, if so, I'll merge it.
>
> Sorry I wasn't able to directly apply your patch to the specific
> Android kernel version I was using.
> Manually merging the code seems to perform as expected.
>
> Thanks a lot for your help,
> Valentin
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>

^ permalink raw reply

* [PATCH 2/3] dmaengine: dw_dmac: Enhance device tree support
From: Andy Shevchenko @ 2012-10-12 11:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAKohponxbjTTDMOA_0=MT36wRh1NpzTAH4LdkaE=Z-ahup4BFg@mail.gmail.com>

On Fri, Oct 12, 2012 at 2:01 PM, Viresh Kumar <viresh.kumar@linaro.org> wrote:
> On 12 October 2012 16:10, Andy Shevchenko <andy.shevchenko@gmail.com> wrote:
>>>>> +     if (!found) {
>>>>> +             last_dw = dw;
>>>>> +             last_bus_id = param;
>>>>> +             return false;
>>>> Because of return here you could eliminate 'found' flag at all.
>
> Here is the stuff copied from you ;)
>
>
> diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
> index a4ff04c..c24859e 100644
> --- a/drivers/dma/dw_dmac.c
> +++ b/drivers/dma/dw_dmac.c
> @@ -1184,7 +1184,7 @@ bool dw_generic_filter(struct dma_chan *chan, void *param)
>         struct dw_dma *dw = to_dw_dma(chan->device);
>         static struct dw_dma *last_dw;
>         static char *last_bus_id;
> -       int found = 0, i = -1;
> +       int i = -1;
>
>         /*
>          * dmaengine framework calls this routine for all channels of all dma
> @@ -1212,22 +1212,17 @@ bool dw_generic_filter(struct dma_chan *chan,
> void *param)
>
>         while (++i < dw->sd_count) {
>                 if (!strcmp(dw->sd[i].bus_id, param)) {
> -                       found = 1;
> -                       break;
> -               }
> -       }
> +                       chan->private = &dw->sd[i];
> +                       last_dw = NULL;
> +                       last_bus_id = NULL;
>
> -       if (!found) {
> -               last_dw = dw;
> -               last_bus_id = param;
> -               return false;
> +                       return true;
> +               }
>         }
>
> -       chan->private = &dw->sd[i];
> -       last_dw = NULL;
> -       last_bus_id = NULL;
> -
> -       return true;
> +       last_dw = dw;
> +       last_bus_id = param;
> +       return false;
>  }
Yes, that what I refer to.

>  EXPORT_SYMBOL(dw_generic_filter);
Could we change a name to be more precise, like dw_dma_generic_filter ?


-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply

* alignment faults in 3.6
From: Russell King - ARM Linux @ 2012-10-12 11:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121012110750.GE21164@n2100.arm.linux.org.uk>

On Fri, Oct 12, 2012 at 12:07:50PM +0100, Russell King - ARM Linux wrote:
> On Fri, Oct 12, 2012 at 12:00:03PM +0100, M?ns Rullg?rd wrote:
> > Russell King - ARM Linux <linux@arm.linux.org.uk> writes:
> > 
> > > On Fri, Oct 12, 2012 at 08:11:42AM +0000, Arnd Bergmann wrote:
> > >> On Thursday 11 October 2012, M?ns Rullg?rd wrote:
> > >> > > But, the IP header is expected to be aligned.
> > >> > 
> > >> > Everything tells the compiler the struct is perfectly aligned.  When the
> > >> > buggy driver passes a misaligned pointer, bad things happen.
> > >> 
> > >> Would it be appropriate to add a WARN_ON_ONCE() in the alignment fault path
> > >> then?
> > 
> > I think that's an excellent idea.
> 
> Well, I get the last word here and it's no.
> 
> > >> If all alignment faults in the kernel are caused by broken drivers,
> > >> that would at least give us some hope of finding those drivers while
> > >> at the same time not causing much overhead in the case where we need
> > >> to do the fixup in the meantime.
> > >
> > > No.  It is my understanding that various IP option processing can also
> > > cause the alignment fault handler to be invoked, even when the packet is
> > > properly aligned, and then there's jffs2/mtd which also relies upon
> > > alignment faults being fixed up.
> > 
> > As far as I'm concerned, this is all hearsay, and I've only ever heard
> > it from you.  Why can't you let those who care fix these bugs instead?
> 
> You know, I'm giving you the benefit of my _knowledge_ which has been
> built over the course of the last 20 years.  I've been in these
> discussions with networking people before.  I ended up having to develop
> the alignment fault handler because of those discussions.

Correction: San Mehat at Corel Inc had to develop it, but I was involved
in those discussions over it nevertheless, as I was the person who merged
the code and then subsequently maintained it.

^ permalink raw reply

* alignment faults in 3.6
From: Måns Rullgård @ 2012-10-12 11:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121012110750.GE21164@n2100.arm.linux.org.uk>

Russell King - ARM Linux <linux@arm.linux.org.uk> writes:

> On Fri, Oct 12, 2012 at 12:00:03PM +0100, M?ns Rullg?rd wrote:
>> Russell King - ARM Linux <linux@arm.linux.org.uk> writes:
>> 
>> > On Fri, Oct 12, 2012 at 08:11:42AM +0000, Arnd Bergmann wrote:
>> >> On Thursday 11 October 2012, M?ns Rullg?rd wrote:
>> >> > > But, the IP header is expected to be aligned.
>> >> > 
>> >> > Everything tells the compiler the struct is perfectly aligned.  When the
>> >> > buggy driver passes a misaligned pointer, bad things happen.
>> >> 
>> >> Would it be appropriate to add a WARN_ON_ONCE() in the alignment
>> >> fault path then?
>> 
>> I think that's an excellent idea.
>
> Well, I get the last word here and it's no.

Sadly, yes.

>> >> If all alignment faults in the kernel are caused by broken drivers,
>> >> that would at least give us some hope of finding those drivers while
>> >> at the same time not causing much overhead in the case where we need
>> >> to do the fixup in the meantime.
>> >
>> > No.  It is my understanding that various IP option processing can also
>> > cause the alignment fault handler to be invoked, even when the packet is
>> > properly aligned, and then there's jffs2/mtd which also relies upon
>> > alignment faults being fixed up.
>> 
>> As far as I'm concerned, this is all hearsay, and I've only ever heard
>> it from you.  Why can't you let those who care fix these bugs instead?
>
> You know, I'm giving you the benefit of my _knowledge_ which has been
> built over the course of the last 20 years.

How proud you sound.  Now could you say something of substance instead?

> I've been in these discussions with networking people before.  I ended
> up having to develop the alignment fault handler because of those
> discussions.  And oh look, Eric confirmed that the networking code
> isn't going to get "fixed" as you were demanding, which is exactly
> what I said.

Funny, I saw him say the exact opposite:

  So if you find an offender, please report a bug, because I can
  guarantee you we will _fix_ it.

> I've been in discussions with MTD people over these issues before, I've
> discussed this with David Woodhouse when it came up in JFFS2.  I *KNOW*
> these things.

In the same way you "know" the networking people won't fix their code,
despite them _clearly_ stating the opposite?

> You can call it hearsay if you wish, but it seems to be more accurate
> than your wild outlandish and pathetic statements.

So you're resorting to name-calling.  Not taking that bait.

-- 
M?ns Rullg?rd
mans at mansr.com

^ permalink raw reply

* [PATCH 1/6] ARM: bcm476x: Add infrastructure
From: Arnd Bergmann @ 2012-10-12 11:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121012130139.6c3079c5@skate>

On Friday 12 October 2012, Thomas Petazzoni wrote:
> On Fri, 12 Oct 2012 10:48:24 +0000, Arnd Bergmann wrote:
> 
> > The main thing to watch out for are mappings that are not for MMIO,
> > such as the call to create_mapping() in map_lowmem() or in
> > devicemaps_init().
> > 
> > I would suggest making struct map_desc specific to callers of
> > iotable_init() and changing the prototype for create_mapping() to
> > 
> > void __init create_mapping(unsigned long virtual, unsigned long pfn,
> >                          size_t length, unsigned int type);
> 
> Yes, this is exactly what I've done. I'll rebase my work, test and send
> it.

Ok, looking forward to it. FWIW, I have a branch called
testing/defconfig-warnings in the arm-soc tree that shuts up all known
build warnings. If you pull that in for testing, you can see if any
warnings were added by your patches.

	Arnd

^ permalink raw reply

* [PATCH] ARM: s3c: mark s3c2440_clk_add as __init_refok
From: Arnd Bergmann @ 2012-10-12 11:14 UTC (permalink / raw)
  To: linux-arm-kernel

s3c2440_clk_add is a subsys_interface method and calls clkdev_add_table,
which is marked as __init. The modpost script complains about this
because we must not call an __init function from a function in the .text
section, and we cannot reference an __init function from a subsys_interface
pointer.

I have verified that the only code path into s3c2440_clk_add() is
from "int __init s3c2440_init(void)", so s3c2440_clk_add can be marked
__init_refok instead.

Without this patch, building mini2440_defconfig results in:

WARNING: vmlinux.o(.text+0x9848): Section mismatch in reference from the function s3c2440_clk_add() to the function .init.text:clkdev_add_table()
The function s3c2440_clk_add() references
the function __init clkdev_add_table().
This is often because s3c2440_clk_add lacks a __init
annotation or the annotation of clkdev_add_table is wrong.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Mike Turquette <mturquette@linaro.org>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Cc: Ben Dooks <ben-linux@fluff.org>
---

I'll put this into arm-soc/fixes unless I hear objections. This replaces the
earlier "clk: don't mark clkdev_add_table as init" as suggested by Russell.

diff --git a/arch/arm/mach-s3c24xx/clock-s3c2440.c b/arch/arm/mach-s3c24xx/clock-s3c2440.c
index 749220f..4407b17 100644
--- a/arch/arm/mach-s3c24xx/clock-s3c2440.c
+++ b/arch/arm/mach-s3c24xx/clock-s3c2440.c
@@ -163,7 +163,7 @@ static struct clk_lookup s3c2440_clk_lookup[] = {
 	CLKDEV_INIT(NULL, "clk_uart_baud3", &s3c2440_clk_fclk_n),
 };
 
-static int s3c2440_clk_add(struct device *dev, struct subsys_interface *sif)
+static int __init_refok s3c2440_clk_add(struct device *dev, struct subsys_interface *sif)
 {
 	struct clk *clock_upll;
 	struct clk *clock_h;

^ permalink raw reply related

* alignment faults in 3.6
From: Russell King - ARM Linux @ 2012-10-12 11:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <yw1xhaq0nefg.fsf@unicorn.mansr.com>

On Fri, Oct 12, 2012 at 12:00:03PM +0100, M?ns Rullg?rd wrote:
> Russell King - ARM Linux <linux@arm.linux.org.uk> writes:
> 
> > On Fri, Oct 12, 2012 at 08:11:42AM +0000, Arnd Bergmann wrote:
> >> On Thursday 11 October 2012, M?ns Rullg?rd wrote:
> >> > > But, the IP header is expected to be aligned.
> >> > 
> >> > Everything tells the compiler the struct is perfectly aligned.  When the
> >> > buggy driver passes a misaligned pointer, bad things happen.
> >> 
> >> Would it be appropriate to add a WARN_ON_ONCE() in the alignment fault path
> >> then?
> 
> I think that's an excellent idea.

Well, I get the last word here and it's no.

> >> If all alignment faults in the kernel are caused by broken drivers,
> >> that would at least give us some hope of finding those drivers while
> >> at the same time not causing much overhead in the case where we need
> >> to do the fixup in the meantime.
> >
> > No.  It is my understanding that various IP option processing can also
> > cause the alignment fault handler to be invoked, even when the packet is
> > properly aligned, and then there's jffs2/mtd which also relies upon
> > alignment faults being fixed up.
> 
> As far as I'm concerned, this is all hearsay, and I've only ever heard
> it from you.  Why can't you let those who care fix these bugs instead?

You know, I'm giving you the benefit of my _knowledge_ which has been
built over the course of the last 20 years.  I've been in these
discussions with networking people before.  I ended up having to develop
the alignment fault handler because of those discussions.  And oh look,
Eric confirmed that the networking code isn't going to get "fixed" as
you were demanding, which is exactly what I said.

I've been in discussions with MTD people over these issues before, I've
discussed this with David Woodhouse when it came up in JFFS2.  I *KNOW*
these things.

You can call it hearsay if you wish, but it seems to be more accurate
than your wild outlandish and pathetic statements.

^ permalink raw reply

* [PATCH v2 5/8] clk: don't mark clkdev_add_table as init
From: Arnd Bergmann @ 2012-10-12 11:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121012091535.GD21164@n2100.arm.linux.org.uk>

On Friday 12 October 2012, Russell King - ARM Linux wrote:
> On Tue, Oct 09, 2012 at 10:13:55PM +0200, Arnd Bergmann wrote:
> > s3c2440_clk_add is a subsys_interface method and calls clkdev_add_table,
> > which means we might be calling it after the __init section is
> > discarded.
> > 
> > Without this patch, building mini2440_defconfig results in:
> > 
> > WARNING: vmlinux.o(.text+0x9848): Section mismatch in reference from the function s3c2440_clk_add() to the function .init.text:clkdev_add_table()
> > The function s3c2440_clk_add() references
> > the function __init clkdev_add_table().
> > This is often because s3c2440_clk_add lacks a __init
> > annotation or the annotation of clkdev_add_table is wrong.
> 
> I'm not sure this is the right thing to do.  I suspect this comes from the
> stupidly complex samsung code, and that this is actually safe - I suspect
> that s3c2440_clk_add() needs to be appropriately marked, but then you end
> up having to trace its call path through various structures etc.

Yes, you are right. I have verified now that the only code path into
s3c2440_clk_add() is from "int __init s3c2440_init(void)", so 
s3c2440_clk_add can be marked __init_refok.

I'll follow up with a new patch to replace this one.

	Arnd

^ permalink raw reply

* [PATCH 1/6] ARM: bcm476x: Add infrastructure
From: Thomas Petazzoni @ 2012-10-12 11:01 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <201210121048.24998.arnd@arndb.de>

Dear Arnd Bergmann,

On Fri, 12 Oct 2012 10:48:24 +0000, Arnd Bergmann wrote:

> The main thing to watch out for are mappings that are not for MMIO,
> such as the call to create_mapping() in map_lowmem() or in
> devicemaps_init().
> 
> I would suggest making struct map_desc specific to callers of
> iotable_init() and changing the prototype for create_mapping() to
> 
> void __init create_mapping(unsigned long virtual, unsigned long pfn,
> 			   size_t length, unsigned int type);

Yes, this is exactly what I've done. I'll rebase my work, test and send
it.

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

^ permalink raw reply

* [PATCH 2/3] dmaengine: dw_dmac: Enhance device tree support
From: Viresh Kumar @ 2012-10-12 11:01 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAHp75VffAwZjfQLf=wS+nBhiRoMFOoyPeUCfrzF1G=+Kh7HHTA@mail.gmail.com>

On 12 October 2012 16:10, Andy Shevchenko <andy.shevchenko@gmail.com> wrote:
>>>> +     if (!found) {
>>>> +             last_dw = dw;
>>>> +             last_bus_id = param;
>>>> +             return false;
>>> Because of return here you could eliminate 'found' flag at all.

Here is the stuff copied from you ;)


diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index a4ff04c..c24859e 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -1184,7 +1184,7 @@ bool dw_generic_filter(struct dma_chan *chan, void *param)
        struct dw_dma *dw = to_dw_dma(chan->device);
        static struct dw_dma *last_dw;
        static char *last_bus_id;
-       int found = 0, i = -1;
+       int i = -1;

        /*
         * dmaengine framework calls this routine for all channels of all dma
@@ -1212,22 +1212,17 @@ bool dw_generic_filter(struct dma_chan *chan,
void *param)

        while (++i < dw->sd_count) {
                if (!strcmp(dw->sd[i].bus_id, param)) {
-                       found = 1;
-                       break;
-               }
-       }
+                       chan->private = &dw->sd[i];
+                       last_dw = NULL;
+                       last_bus_id = NULL;

-       if (!found) {
-               last_dw = dw;
-               last_bus_id = param;
-               return false;
+                       return true;
+               }
        }

-       chan->private = &dw->sd[i];
-       last_dw = NULL;
-       last_bus_id = NULL;
-
-       return true;
+       last_dw = dw;
+       last_bus_id = param;
+       return false;
 }
 EXPORT_SYMBOL(dw_generic_filter);

^ permalink raw reply related

* alignment faults in 3.6
From: Måns Rullgård @ 2012-10-12 11:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121012090321.GA21164@n2100.arm.linux.org.uk>

Russell King - ARM Linux <linux@arm.linux.org.uk> writes:

> On Fri, Oct 12, 2012 at 08:11:42AM +0000, Arnd Bergmann wrote:
>> On Thursday 11 October 2012, M?ns Rullg?rd wrote:
>> > > But, the IP header is expected to be aligned.
>> > 
>> > Everything tells the compiler the struct is perfectly aligned.  When the
>> > buggy driver passes a misaligned pointer, bad things happen.
>> 
>> Would it be appropriate to add a WARN_ON_ONCE() in the alignment fault path
>> then?

I think that's an excellent idea.

>> If all alignment faults in the kernel are caused by broken drivers,
>> that would at least give us some hope of finding those drivers while
>> at the same time not causing much overhead in the case where we need
>> to do the fixup in the meantime.
>
> No.  It is my understanding that various IP option processing can also
> cause the alignment fault handler to be invoked, even when the packet is
> properly aligned, and then there's jffs2/mtd which also relies upon
> alignment faults being fixed up.

As far as I'm concerned, this is all hearsay, and I've only ever heard
it from you.  Why can't you let those who care fix these bugs instead?

-- 
M?ns Rullg?rd
mans at mansr.com

^ permalink raw reply

* When flush all dcache, why the increasing step is 2?
From: Li Haifeng @ 2012-10-12 10:51 UTC (permalink / raw)
  To: linux-arm-kernel

For flush all data cache, the flush action begins from Level 0, then
increase cache level by 1.

But in function v7_flush_dcache_all, the step is 2. IOW, it will just flush
0,2,4,6 level cache.
As the following code, the step is stored in r10, and the increase line is
"add     r10, r10, #2".

Is my wrong understanding?

+ENTRY(v7_flush_dcache_all)
+       mrc     p15, 1, r0, c0, c0, 1           @ read clidr
+       ands    r3, r0, #0x7000000              @ extract loc from clidr
+       mov     r3, r3, lsr #23                 @ left align loc bit field
+       beq     finished                        @ if loc is 0, then no need
to clean
+       mov     r10, #0                         @ start clean at cache
level 0
+loop1:
+       add     r2, r10, r10, lsr #1            @ work out 3x current cache
level
+       mov     r1, r0, lsr r2                  @ extract cache type bits
from clidr
+       and     r1, r1, #7                      @ mask of the bits for
current cache only
+       cmp     r1, #2                          @ see what cache we have at
this level
+       blt     skip                            @ skip if no cache, or just
i-cache
+       mcr     p15, 2, r10, c0, c0, 0          @ select current cache
level in cssr
+       isb                                     @ isb to sych the new
cssr&csidr
+       mrc     p15, 1, r1, c0, c0, 0           @ read the new csidr
+       and     r2, r1, #7                      @ extract the length of the
cache lines
+       add     r2, r2, #4                      @ add 4 (line length offset)
+       ldr     r4, =0x3ff
+       ands    r4, r4, r1, lsr #3              @ find maximum number on
the way size
+       clz     r5, r4                          @ find bit position of way
size increment
+       ldr     r7, =0x7fff
+       ands    r7, r7, r1, lsr #13             @ extract max number of the
index size
+loop2:
+       mov     r9, r4                          @ create working copy of
max way size
+loop3:
+       orr     r11, r10, r9, lsl r5            @ factor way and cache
number into r11
+       orr     r11, r11, r7, lsl r2            @ factor index number into
r11
+       mcr     p15, 0, r11, c7, c14, 2         @ clean & invalidate by
set/way
+       subs    r9, r9, #1                      @ decrement the way
+       bge     loop3
+       subs    r7, r7, #1                      @ decrement the index
+       bge     loop2
+skip:
+       add     r10, r10, #2                    @ increment cache number
+       cmp     r3, r10
+       bgt     loop1
+finished:
+       mov     r10, #0                         @ swith back to cache level
0
+       mcr     p15, 2, r10, c0, c0, 0          @ select current cache
level in cssr
+       isb
+       mov     pc, lr
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121012/7d08905b/attachment.html>

^ permalink raw reply

* [PATCH 2/3] dmaengine: dw_dmac: Enhance device tree support
From: Viresh Kumar @ 2012-10-12 10:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAHp75VffAwZjfQLf=wS+nBhiRoMFOoyPeUCfrzF1G=+Kh7HHTA@mail.gmail.com>

On 12 October 2012 16:10, Andy Shevchenko <andy.shevchenko@gmail.com> wrote:
> On Fri, Oct 12, 2012 at 1:36 PM, viresh kumar <viresh.kumar@linaro.org> wrote:
>> On Fri, Oct 12, 2012 at 1:53 PM, Andy Shevchenko
>> <andriy.shevchenko@linux.intel.com> wrote:
>>> On Fri, 2012-10-12 at 11:14 +0530, Viresh Kumar wrote:
>>
>>>> +     while (++i < dw->sd_count) {
>>>> +             if (!strcmp(dw->sd[i].bus_id, param)) {
>>>> +                     found = 1;
>>>> +                     break;

I was just not looking at this place.

>>>> +             }
>>>> +     }
>>>> +
>>>> +     if (!found) {
>>>> +             last_dw = dw;
>>>> +             last_bus_id = param;
>>>> +             return false;
>>> Because of return here you could eliminate 'found' flag at all.
>> how?

And was looking here only.

> while (++i < dw->sd_count) {
>                if (!strcmp(dw->sd[i].bus_id, param)) {
>        chan->private = &dw->sd[i];
>        last_dw = NULL;
>        last_bus_id = NULL;
>
>        return true;
>                }
>        }
>
>                last_dw = dw;
>                last_bus_id = param;
>                return false;

will be done.

^ permalink raw reply

* [PATCH 1/6] ARM: bcm476x: Add infrastructure
From: Arnd Bergmann @ 2012-10-12 10:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121012101252.6c3b7dce@skate>

On Friday 12 October 2012, Thomas Petazzoni wrote:
> On Fri, 12 Oct 2012 08:03:54 +0000, Arnd Bergmann wrote:
> 
> > I would certainly like to see this, yes. I had a patch for it ages
> > ago, but would start over again if I did this now.
> > 
> > I don't have time to do the conversion at the moment, but I would
> > certainly welcome a patch that does it. I can give some details about
> > the problems with that and how I think they should be solved.
> 
> I did start working on such a patch a few weeks ago, but converting all
> the platforms to use IOMEM() was really boring. But now you did that, I
> can try to revive my patch, see if it works, and post it if you're
> interested.

Ok, cool!

The main thing to watch out for are mappings that are not for MMIO,
such as the call to create_mapping() in map_lowmem() or in
devicemaps_init().

I would suggest making struct map_desc specific to callers of
iotable_init() and changing the prototype for create_mapping() to

void __init create_mapping(unsigned long virtual, unsigned long pfn,
			   size_t length, unsigned int type);

That means we still need to add one type cast in iotable_init(), but
everything else should become simpler. There are a few instances in
platform code that use MT_MEMORY rather MT_DEVICE. At least the TCM
one should not really be __iomem, but I'm not sure about the various
TI SRAM locations. Probably doesn't matter all that much for those.

	Arnd

^ permalink raw reply

* [PATCH v2 09/13] ARM: davinci - update the dm644x soc code to use common clk drivers
From: Sekhar Nori @ 2012-10-12 10:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <3E54258959B69E4282D79E01AB1F32B7041FDB5B@DFLE12.ent.ti.com>

Hi Murali,

On 10/11/2012 8:28 PM, Karicheri, Muralidharan wrote:
>>> -----Original Message-----
>>> From: Nori, Sekhar
>>> Sent: Thursday, October 11, 2012 8:25 AM
>>> To: Karicheri, Muralidharan
>>> Cc: mturquette at linaro.org; arnd at arndb.de; akpm at linux-foundation.org;
>>> shawn.guo at linaro.org; rob.herring at calxeda.com; linus.walleij at linaro.org;
>>> viresh.linux at gmail.com; linux-kernel at vger.kernel.org; Hilman, Kevin;
>>> linux at arm.linux.org.uk; davinci-linux-open-source at linux.davincidsp.com; linux-arm-
>>> kernel at lists.infradead.org; linux-keystone at list.ti.com - Linux developers for Keystone
>>> family of devices (May contain non-TIers); linux-c6x-dev at linux-c6x.org; Chemparathy,
>>> Cyril
>>> Subject: Re: [PATCH v2 09/13] ARM: davinci - update the dm644x soc code to use
>>> common clk drivers
>>>
>>> Murali,
>>>
>>> On 9/26/2012 11:40 PM, Murali Karicheri wrote:
>>>> The clock tree for dm644x is defined using the new structure davinci_clk.
>>>> The SoC specific code re-uses clk-fixed-rate, clk-divider and clk-mux
>>>> drivers in addition to the davinci specific clk drivers,
>>>> clk-davinci-pll and clk-davinci-psc. Macros are defined to define the
>>>> various clocks in the SoC.
>>>>
>>>> Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
>>>
>>> You have chosen to keep all clock related data in platform files while using the common
>>> clock framework to provide just the infrastructure. If you look at how mxs and spear
>>> have been migrated, they have migrated the soc specific clock data to drivers/clk as well.
>>> See "drivers/clk/spear/spear3xx_clock.c" or "drivers/clk/mxs/clk-imx23.c 
> 
> I have to disagree on this one. I had investigated these code already and came
> up with a way that we can re-use code across all of the davinci platforms as 
> well as other architectures that re-uses the clk hardware IPs.

Which code you are talking about here? Even if you introduce
clk-dm644x.c, clk-keystone.c etc in drivers/clk/davinci/ you can reuse
the code you introduce in patches 1-3. I cant see how that will be
prevented.

> spear3xx_clock.c has initialization code for each of the platforms
> and so is the case with imx23.c.

By each of the platforms, you mean they all cater to a family of
devices? This depends on how close together the family of devices are.
Otherwise, there would be a file per soc. DM644x also represents a
family for that matter.

> By using platform_data approach, we are able to define clks for each of the SoC and then use davinci_common_clk_init() to do initialize the clk drivers based on platform data.

You need to define and register the clocks present on each SoC either
which way. I don't see why just the platform_data approach allows this.
And looking closely, you have defined platform data, but don't actually
have a platform device, making things more confusing.

> Later once we migrate to device tree, davinci_common_clk_init() will go way and also the clk structures defined in the SoC file. I have prototyped this on one of the device that I am working on. davinci_common_clk_init() will be replaced with a of_davinci_clk_init() that will use device tree to get all of the platform data for the clk providers and do the initialization based on that. See highbank_clocks_init() in clk-highbank.c. I have used this model for device
> tree based clk initialization.

I don't think we should wait till DT migration to get rid of clock data
from platform code. For many of the older DaVinci platforms, DT
migration is a big if and when. This approach you gave above might work
for newer DT-only platforms, but even if there is one board that is not
migrated to DT, the entire clock data will have to stay. I have very
less hope this will happen for DaVinci (at least in the near term). So,
I would rather take the opportunity of common clock tree migration to
move clock data out of mach-davinci.

Also, just moving soc-specific clk data to drivers/clk/davinci/* does
not impede a future DT conversion, no?

> So it make sense to keep the design the way it is. Otherwise we will end up writing dm644x_clk_init(), dm355_clk_init(), etc for each of the platforms and these code will get thrown away once we migrate to
> device tree. 

I still don't see why davinci/keystone cannot follow the same approach
taken by multiple other socs - spear, mxs and ux500. I am unconvinced
that we have a significantly different case.

>>> ". I feel the
>>> latter way is better and I also think it will simplify some of the look-up infrastructure you
>>> had to build. This will also help some real code reduction from arch/arm/mach-davinci/.
>>>
> 
> The look-up infrastructure is pretty much re-use of the existing code base in SoC specific file.

Yes, but that's no reason to keep maintaining it.

> About code reduction, I can't say I agree, as we need to add platform_specific clock initialization code if we follow spear3xx_clock.c model and end up probably adding more code.
> SoC specific file (for example dm644x.c) has only data structures and all of SoC will re-use davinci_common_clk_init() to do the initialization. So I am not sure how you conclude we will have code reduction?

Is about code reduction from arch/arm/. That's what ARM community is
working towards.

Thanks,
Sekhar

PS: When replying, can you please hit an enter after every 70 or so
characters. Otherwise quoting from your mails is becoming very
difficult. I tried manually adjusting it but finally gave up.

^ permalink raw reply

* [PATCH 2/3] dmaengine: dw_dmac: Enhance device tree support
From: Andy Shevchenko @ 2012-10-12 10:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAOh2x=m8OVNfMm5Fn+cr9Gxuh6oyt+8d4n-bkG8Xiw5zGncLiA@mail.gmail.com>

On Fri, Oct 12, 2012 at 1:36 PM, viresh kumar <viresh.kumar@linaro.org> wrote:
> On Fri, Oct 12, 2012 at 1:53 PM, Andy Shevchenko
> <andriy.shevchenko@linux.intel.com> wrote:
>> On Fri, 2012-10-12 at 11:14 +0530, Viresh Kumar wrote:
>
>>> +     while (++i < dw->sd_count) {
>>> +             if (!strcmp(dw->sd[i].bus_id, param)) {
>>> +                     found = 1;
>>> +                     break;
>>> +             }
>>> +     }
>>> +
>>> +     if (!found) {
>>> +             last_dw = dw;
>>> +             last_bus_id = param;
>>> +             return false;
>> Because of return here you could eliminate 'found' flag at all.
> how?

while (++i < dw->sd_count) {
               if (!strcmp(dw->sd[i].bus_id, param)) {
       chan->private = &dw->sd[i];
       last_dw = NULL;
       last_bus_id = NULL;

       return true;
               }
       }

               last_dw = dw;
               last_bus_id = param;
               return false;

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply

* [PATCH 2/3] dmaengine: dw_dmac: Enhance device tree support
From: viresh kumar @ 2012-10-12 10:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350030203.10584.139.camel@smile>

On Fri, Oct 12, 2012 at 1:53 PM, Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
> On Fri, 2012-10-12 at 11:14 +0530, Viresh Kumar wrote:

>> +     while (++i < dw->sd_count) {
>> +             if (!strcmp(dw->sd[i].bus_id, param)) {
>> +                     found = 1;
>> +                     break;
>> +             }
>> +     }
>> +
>> +     if (!found) {
>> +             last_dw = dw;
>> +             last_bus_id = param;
>> +             return false;
> Because of return here you could eliminate 'found' flag at all.

how?

Fixed the other issue as:

Author: Viresh Kumar <viresh.kumar@linaro.org>
Date:   Fri Oct 12 16:06:32 2012 +0530

    fixup! dmaengine: dw_dmac: Enhance device tree support
---
 drivers/dma/dw_dmac.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index 9a7d084..a4ff04c 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -1598,9 +1598,10 @@ __devinit dw_dma_parse_dt(struct platform_device *pdev)
        return pdata;
 }
 #else
-static inline int dw_dma_parse_dt(struct platform_device *pdev)
+static inline struct dw_dma_platform_data *
+dw_dma_parse_dt(struct platform_device *pdev)
 {
-       return -ENOSYS;
+       return NULL;
 }
 #endif

--
viresh

^ permalink raw reply related

* [PATCH] usb: phy: samsung: Introducing usb phy driver for hsotg
From: Praveen Paneri @ 2012-10-12 10:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1349256393-11741-1-git-send-email-p.paneri@samsung.com>

platform_set_drvdata() required for driver's remove function, so adding
it back.

>From v6:
Added TODO for phy bindings with controller
Dropped platform_set_drvdata() from driver probe

This driver uses usb_phy interface to interact with s3c-hsotg. Supports
phy_init and phy_shutdown functions to enable/disable phy. Tested with
smdk6410 and smdkv310. More SoCs can be brought under later.

Signed-off-by: Praveen Paneri <p.paneri@samsung.com>
Acked-by: Heiko Stuebner <heiko@sntech.de>
---
 .../devicetree/bindings/usb/samsung-usbphy.txt     |   11 +
 drivers/usb/phy/Kconfig                            |    8 +
 drivers/usb/phy/Makefile                           |    1 +
 drivers/usb/phy/samsung-usbphy.c                   |  357 ++++++++++++++++++++
 include/linux/platform_data/samsung-usbphy.h       |   27 ++
 5 files changed, 404 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/usb/samsung-usbphy.txt
 create mode 100644 drivers/usb/phy/samsung-usbphy.c
 create mode 100644 include/linux/platform_data/samsung-usbphy.h

diff --git a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
new file mode 100644
index 0000000..7b26e2d
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
@@ -0,0 +1,11 @@
+* Samsung's usb phy transceiver
+
+The Samsung's phy transceiver is used for controlling usb otg phy for
+s3c-hsotg usb device controller.
+TODO: Adding the PHY binding with controller(s) according to the under
+developement generic PHY driver.
+
+Required properties:
+- compatible : should be "samsung,exynos4210-usbphy"
+- reg : base physical address of the phy registers and length of memory mapped
+	region.
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
index 63c339b..313685f 100644
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -32,3 +32,11 @@ config MV_U3D_PHY
 	help
 	  Enable this to support Marvell USB 3.0 phy controller for Marvell
 	  SoC.
+
+config SAMSUNG_USBPHY
+	bool "Samsung USB PHY controller Driver"
+	depends on USB_S3C_HSOTG
+	select USB_OTG_UTILS
+	help
+	  Enable this to support Samsung USB phy controller for samsung
+	  SoCs.
diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
index b069f29..55dcfc1 100644
--- a/drivers/usb/phy/Makefile
+++ b/drivers/usb/phy/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_OMAP_USB2)			+= omap-usb2.o
 obj-$(CONFIG_USB_ISP1301)		+= isp1301.o
 obj-$(CONFIG_MV_U3D_PHY)		+= mv_u3d_phy.o
 obj-$(CONFIG_USB_EHCI_TEGRA)	+= tegra_usb_phy.o
+obj-$(CONFIG_SAMSUNG_USBPHY)		+= samsung-usbphy.o
diff --git a/drivers/usb/phy/samsung-usbphy.c b/drivers/usb/phy/samsung-usbphy.c
new file mode 100644
index 0000000..14c182f
--- /dev/null
+++ b/drivers/usb/phy/samsung-usbphy.c
@@ -0,0 +1,357 @@
+/* linux/drivers/usb/phy/samsung-usbphy.c
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *              http://www.samsung.com
+ *
+ * Author: Praveen Paneri <p.paneri@samsung.com>
+ *
+ * Samsung USB2.0 High-speed OTG transceiver, talks to S3C HS OTG controller
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/usb/otg.h>
+#include <linux/platform_data/samsung-usbphy.h>
+
+/* Register definitions */
+
+#define S3C_PHYPWR				(0x00)
+
+#define S3C_PHYPWR_NORMAL_MASK			(0x19 << 0)
+#define S3C_PHYPWR_OTG_DISABLE			(1 << 4)
+#define S3C_PHYPWR_ANALOG_POWERDOWN		(1 << 3)
+#define S3C_PHYPWR_FORCE_SUSPEND		(1 << 1)
+/* For Exynos4 */
+#define EXYNOS4_PHYPWR_NORMAL_MASK		(0x39 << 0)
+#define EXYNOS4_PHYPWR_SLEEP			(1 << 5)
+
+#define S3C_PHYCLK				(0x04)
+
+#define S3C_PHYCLK_MODE_SERIAL			(1 << 6)
+#define S3C_PHYCLK_EXT_OSC			(1 << 5)
+#define S3C_PHYCLK_COMMON_ON_N			(1 << 4)
+#define S3C_PHYCLK_ID_PULL			(1 << 2)
+#define S3C_PHYCLK_CLKSEL_MASK			(0x3 << 0)
+#define S3C_PHYCLK_CLKSEL_SHIFT			(0)
+#define S3C_PHYCLK_CLKSEL_48M			(0x0 << 0)
+#define S3C_PHYCLK_CLKSEL_12M			(0x2 << 0)
+#define S3C_PHYCLK_CLKSEL_24M			(0x3 << 0)
+
+#define S3C_RSTCON				(0x08)
+
+#define S3C_RSTCON_PHYCLK			(1 << 2)
+#define S3C_RSTCON_HCLK				(1 << 1)
+#define S3C_RSTCON_PHY				(1 << 0)
+
+#ifndef MHZ
+#define MHZ (1000*1000)
+#endif
+
+enum samsung_cpu_type {
+	TYPE_S3C64XX,
+	TYPE_EXYNOS4210,
+};
+
+/*
+ * struct samsung_usbphy - transceiver driver state
+ * @phy: transceiver structure
+ * @plat: platform data
+ * @dev: The parent device supplied to the probe function
+ * @clk: usb phy clock
+ * @regs: usb phy register memory base
+ * @ref_clk_freq: reference clock frequency selection
+ * @cpu_type: machine identifier
+ */
+struct samsung_usbphy {
+	struct usb_phy	phy;
+	struct samsung_usbphy_data *plat;
+	struct device	*dev;
+	struct clk	*clk;
+	void __iomem	*regs;
+	int		ref_clk_freq;
+	int		cpu_type;
+};
+
+#define phy_to_sphy(x)		container_of((x), struct samsung_usbphy, phy)
+
+/*
+ * Returns reference clock frequency selection value
+ */
+static int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy)
+{
+	struct clk *ref_clk;
+	int refclk_freq = 0;
+
+	ref_clk = clk_get(sphy->dev, "xusbxti");
+	if (IS_ERR(ref_clk)) {
+		dev_err(sphy->dev, "Failed to get reference clock\n");
+		return PTR_ERR(ref_clk);
+	}
+
+	switch (clk_get_rate(ref_clk)) {
+	case 12 * MHZ:
+		refclk_freq |= S3C_PHYCLK_CLKSEL_12M;
+		break;
+	case 24 * MHZ:
+		refclk_freq |= S3C_PHYCLK_CLKSEL_24M;
+		break;
+	default:
+	case 48 * MHZ:
+		/* default reference clock */
+		refclk_freq |= S3C_PHYCLK_CLKSEL_48M;
+		break;
+	}
+	clk_put(ref_clk);
+
+	return refclk_freq;
+}
+
+static void samsung_usbphy_enable(struct samsung_usbphy *sphy)
+{
+	void __iomem *regs = sphy->regs;
+	u32 phypwr;
+	u32 phyclk;
+	u32 rstcon;
+
+	/* set clock frequency for PLL */
+	phyclk = sphy->ref_clk_freq;
+	phypwr = readl(regs + S3C_PHYPWR);
+	rstcon = readl(regs + S3C_RSTCON);
+
+	switch (sphy->cpu_type) {
+	case TYPE_S3C64XX:
+		phyclk &= ~(S3C_PHYCLK_COMMON_ON_N);
+		phypwr &= ~S3C_PHYPWR_NORMAL_MASK;
+		rstcon |= S3C_RSTCON_PHY;
+		break;
+	case TYPE_EXYNOS4210:
+		phypwr &= ~EXYNOS4_PHYPWR_NORMAL_MASK;
+		rstcon |= S3C_RSTCON_PHY;
+	default:
+		break;
+	}
+
+	writel(phyclk, regs + S3C_PHYCLK);
+	/* set to normal of PHY0 */
+	writel(phypwr, regs + S3C_PHYPWR);
+	/* reset all ports of PHY and Link */
+	writel(rstcon, regs + S3C_RSTCON);
+	udelay(10);
+	rstcon &= ~S3C_RSTCON_PHY;
+	writel(rstcon, regs + S3C_RSTCON);
+}
+
+static void samsung_usbphy_disable(struct samsung_usbphy *sphy)
+{
+	void __iomem *regs = sphy->regs;
+	u32 phypwr;
+
+	phypwr = readl(regs + S3C_PHYPWR);
+
+	switch (sphy->cpu_type) {
+	case TYPE_S3C64XX:
+		phypwr |= S3C_PHYPWR_NORMAL_MASK;
+		break;
+	case TYPE_EXYNOS4210:
+		phypwr |= EXYNOS4_PHYPWR_NORMAL_MASK;
+	default:
+		break;
+	}
+
+	/* unset to normal of PHY0 */
+	writel(phypwr, regs + S3C_PHYPWR);
+}
+
+/*
+ * The function passed to the usb driver for phy initialization
+ */
+static int samsung_usbphy_init(struct usb_phy *phy)
+{
+	struct samsung_usbphy *sphy;
+	int ret = 0;
+
+	sphy = phy_to_sphy(phy);
+
+	/* Enable the phy clock */
+	ret = clk_prepare_enable(sphy->clk);
+	if (ret) {
+		dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__);
+		return ret;
+	}
+
+	/* Disable phy isolation */
+	if (sphy->plat && sphy->plat->pmu_isolation)
+		sphy->plat->pmu_isolation(false);
+
+	/* Initialize usb phy registers */
+	samsung_usbphy_enable(sphy);
+
+	/* Disable the phy clock */
+	clk_disable_unprepare(sphy->clk);
+	return ret;
+}
+
+/*
+ * The function passed to the usb driver for phy shutdown
+ */
+static void samsung_usbphy_shutdown(struct usb_phy *phy)
+{
+	struct samsung_usbphy *sphy;
+
+	sphy = phy_to_sphy(phy);
+
+	if (clk_prepare_enable(sphy->clk)) {
+		dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__);
+		return;
+	}
+
+	/* De-initialize usb phy registers */
+	samsung_usbphy_disable(sphy);
+
+	/* Enable phy isolation */
+	if (sphy->plat && sphy->plat->pmu_isolation)
+		sphy->plat->pmu_isolation(true);
+
+	clk_disable_unprepare(sphy->clk);
+}
+
+static const struct of_device_id samsung_usbphy_dt_match[];
+
+static inline int samsung_usbphy_get_driver_data(struct platform_device *pdev)
+{
+	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
+		int data;
+		const struct of_device_id *match;
+		match = of_match_node(samsung_usbphy_dt_match,
+							pdev->dev.of_node);
+		data = (int) match->data;
+		return data;
+	}
+
+	return platform_get_device_id(pdev)->driver_data;
+}
+
+static int __devinit samsung_usbphy_probe(struct platform_device *pdev)
+{
+	struct samsung_usbphy *sphy;
+	struct samsung_usbphy_data *pdata;
+	struct device *dev = &pdev->dev;
+	struct resource *phy_mem;
+	void __iomem	*phy_base;
+	struct clk *clk;
+	int	ret = 0;
+
+	pdata = pdev->dev.platform_data;
+	if (!pdata) {
+		dev_err(&pdev->dev, "%s: no platform data defined\n", __func__);
+		return -EINVAL;
+	}
+
+	phy_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!phy_mem) {
+		dev_err(dev, "%s: missing mem resource\n", __func__);
+		return -ENODEV;
+	}
+
+	phy_base = devm_request_and_ioremap(dev, phy_mem);
+	if (!phy_base) {
+		dev_err(dev, "%s: register mapping failed\n", __func__);
+		return -ENXIO;
+	}
+
+	sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL);
+	if (!sphy)
+		return -ENOMEM;
+
+	clk = devm_clk_get(dev, "otg");
+	if (IS_ERR(clk)) {
+		dev_err(dev, "Failed to get otg clock\n");
+		return PTR_ERR(clk);
+	}
+
+	sphy->dev		= &pdev->dev;
+	sphy->plat		= pdata;
+	sphy->regs		= phy_base;
+	sphy->clk		= clk;
+	sphy->phy.dev		= sphy->dev;
+	sphy->phy.label		= "samsung-usbphy";
+	sphy->phy.init		= samsung_usbphy_init;
+	sphy->phy.shutdown	= samsung_usbphy_shutdown;
+	sphy->cpu_type		= samsung_usbphy_get_driver_data(pdev);
+	sphy->ref_clk_freq	= samsung_usbphy_get_refclk_freq(sphy);
+
+	platform_set_drvdata(pdev, sphy);
+
+	ret = usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2);
+	return ret;
+}
+
+static int __exit samsung_usbphy_remove(struct platform_device *pdev)
+{
+	struct samsung_usbphy *sphy = platform_get_drvdata(pdev);
+
+	usb_remove_phy(&sphy->phy);
+
+	return 0;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id samsung_usbphy_dt_match[] = {
+	{
+		.compatible = "samsung,s3c64xx-usbphy",
+		.data = (void *)TYPE_S3C64XX,
+	}, {
+		.compatible = "samsung,exynos4210-usbphy",
+		.data = (void *)TYPE_EXYNOS4210,
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, samsung_usbphy_dt_match);
+#else
+#define samsung_usbphy_dt_match NULL
+#endif
+
+static struct platform_device_id samsung_usbphy_driver_ids[] = {
+	{
+		.name		= "s3c64xx-usbphy",
+		.driver_data	= TYPE_S3C64XX,
+	}, {
+		.name		= "exynos4210-usbphy",
+		.driver_data	= TYPE_EXYNOS4210,
+	},
+	{},
+};
+
+MODULE_DEVICE_TABLE(platform, samsung_usbphy_driver_ids);
+
+static struct platform_driver samsung_usbphy_driver = {
+	.probe		= samsung_usbphy_probe,
+	.remove		= __devexit_p(samsung_usbphy_remove),
+	.id_table	= samsung_usbphy_driver_ids,
+	.driver		= {
+		.name	= "samsung-usbphy",
+		.owner	= THIS_MODULE,
+		.of_match_table = samsung_usbphy_dt_match,
+	},
+};
+
+module_platform_driver(samsung_usbphy_driver);
+
+MODULE_DESCRIPTION("Samsung USB phy controller");
+MODULE_AUTHOR("Praveen Paneri <p.paneri@samsung.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:samsung-usbphy");
diff --git a/include/linux/platform_data/samsung-usbphy.h b/include/linux/platform_data/samsung-usbphy.h
new file mode 100644
index 0000000..1bd24cb
--- /dev/null
+++ b/include/linux/platform_data/samsung-usbphy.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics Co.Ltd
+ *		http://www.samsung.com/
+ * Author: Praveen Paneri <p.paneri@samsung.com>
+ *
+ * Defines platform data for samsung usb phy driver.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __SAMSUNG_USBPHY_PLATFORM_H
+#define __SAMSUNG_USBPHY_PLATFORM_H
+
+/**
+ * samsung_usbphy_data - Platform data for USB PHY driver.
+ * @pmu_isolation: Function to control usb phy isolation in PMU.
+ */
+struct samsung_usbphy_data {
+	void (*pmu_isolation)(int on);
+};
+
+extern void samsung_usbphy_set_pdata(struct samsung_usbphy_data *pd);
+
+#endif /* __SAMSUNG_USBPHY_PLATFORM_H */
-- 
1.7.1

^ permalink raw reply related

* alignment faults in 3.6
From: Eric Dumazet @ 2012-10-12 10:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121012090321.GA21164@n2100.arm.linux.org.uk>

On Fri, 2012-10-12 at 10:03 +0100, Russell King - ARM Linux wrote:

> No.  It is my understanding that various IP option processing can also
> cause the alignment fault handler to be invoked, even when the packet is
> properly aligned, and then there's jffs2/mtd which also relies upon
> alignment faults being fixed up.

Oh well.

We normally make sure we dont have alignment faults on arches that dont
have CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS (or a non null NET_IP_ALIGN)

So if you find an offender, please report a bug, because I can guarantee
you we will _fix_ it.

One example of a fix was the following subtle one.

commit 117632e64d2a5f464e491fe221d7169a3814a77b
tcp: take care of misalignments
    
We discovered that TCP stack could retransmit misaligned skbs if a
malicious peer acknowledged sub MSS frame. This currently can happen
only if output interface is non SG enabled : If SG is enabled, tcp
builds headless skbs (all payload is included in fragments), so the tcp
trimming process only removes parts of skb fragments, header stay
aligned.
    
Some arches cant handle misalignments, so force a head reallocation and
shrink headroom to MAX_TCP_HEADER.

Dont care about misaligments on x86 and PPC (or other arches setting
NET_IP_ALIGN to 0)

This patch introduces __pskb_copy() which can specify the headroom of
new head, and pskb_copy() becomes a wrapper on top of __pskb_copy()

^ permalink raw reply

* [PATCH 2/2] ARM: unwind: enable dumping stacks for SMP && ARM_UNWIND
From: Dave Martin @ 2012-10-12 10:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121012090807.GB21164@n2100.arm.linux.org.uk>

On Fri, Oct 12, 2012 at 10:08:07AM +0100, Russell King - ARM Linux wrote:
> On Sun, Aug 26, 2012 at 03:46:56PM -0700, Colin Cross wrote:
> > Unwinding with CONFIG_ARM_UNWIND is much more complicated than
> > unwinding with CONFIG_FRAME_POINTER, but there are only a few points
> > that require validation in order to avoid faults or infinite loops.
> > Avoiding faults is easy by adding checks to verify that all accesses
> > relative to the frame's stack pointer remain inside the stack.
> > 
> > When CONFIG_FRAME_POINTER is not set it is possible for two frames to
> > have the same SP, so there is no way to avoid repeated calls to
> > unwind_frame continuing forever.
> 
> So here you admit that this patch can cause the unwinder to loop forever,
> which would provide no way out of that.  Why do you think this patch is
> suitable for mainline with such a problem?

With CONFIG_FRAME_POINTER we have a straightforward definition of
progress: the sp must increase per frame, and cannot increase beyond the
limit of the tasks stack.  We get this property from the fact that
each frame record consumes actual space on the stack.  If we parse a
frame record which does not both increase the sp and provide a frame
address greater than that sp, we know that frame is garbage and we must
stop.


With CONFIG_ARM_UNWIND, we have no straightforward definition of
progress.  However, sp must _normally_ still increase, because compiler-
generated non-leaf functions must store the lr somewhere, and the
compiler always uses the stack.  Even if lr is stashed in r4, an ABI
compliant would then have needed to save r4 on the stack beforehand.

We can assume that we will never parse a garbage unwind table because of
the way the table lookup works (though we may parse a valid table which
has nothing whatever to do with the code that was executing in the case
of a corrupted stack).  So we only need to worry about what the unwind
tables will look like for valid functions.

Nonetheless, tail-call-optimised and manually-annotated functions may
have unusual frames which don't consume any stack.  Stackless tail-
call-optimised functions shouldn't be a problem, since their frames
are completely missing from the backtrace and won't dump us into a loop.
Stackless assembler functions are overwhelmingly likely to be leaf
functions, giving us just one stackless frame.


Would it make sense if we place some small sanity limit on the number
of frames the unwinder will process with the same sp before giving up?

Cheers
---Dave

^ permalink raw reply

* [PATCH v2] i2c: change the id to let the i2c-gpio work
From: Jean Delvare @ 2012-10-12  9:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350034971-1050-1-git-send-email-voice.shen@atmel.com>

On Fri, 12 Oct 2012 17:42:51 +0800, Bo Shen wrote:
> The i2c-gpio driver will turn the platform device ID to busnum.
> When using platfrom device ID as -1, it means dynamically assigned
> the busnum. When writing code, we need to make sure the busnum,
> and call i2c_register_board_info(int busnum, ...) to register device
> if using -1, we do not know the value of busnum. 
> 
> In order to solve this issue, set the platform device ID as a fix number
> Here using 0 to match the busnum used in i2c_regsiter_board_info().
> 
> Signed-off-by: Bo Shen <voice.shen@atmel.com>
> ---
> Change since v1
>   Make the commit message more clear
> ---
>  arch/arm/mach-at91/at91sam9260_devices.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
> index 0f24cfb..805ef95 100644
> --- a/arch/arm/mach-at91/at91sam9260_devices.c
> +++ b/arch/arm/mach-at91/at91sam9260_devices.c
> @@ -389,7 +389,7 @@ static struct i2c_gpio_platform_data pdata = {
>  
>  static struct platform_device at91sam9260_twi_device = {
>  	.name			= "i2c-gpio",
> -	.id			= -1,
> +	.id			= 0,
>  	.dev.platform_data	= &pdata,
>  };
>  

Acked-by: Jean Delvare <khali@linux-fr.org>

-- 
Jean Delvare

^ permalink raw reply

* [PATCH] Boottime: A tool for automatic measurement of kernel/bootloader boot time
From: Lee Jones @ 2012-10-12  9:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121011201735.GA15313@kahuna>

Okay, please disgard the last patch. Lots of fixups since.

Author: Lee Jones <lee.jones@linaro.org>
Date:   Wed Jun 30 14:00:40 2010 +0200

    Boottime: A tool for automatic measurement of kernel/bootloader boot time
    
    The overhead is very low and the results will be found under
    sysfs/bootime, as well as detailed results in debugfs under
    boottime/. The bootgraph* files are compatible with
    scripts/bootgraph.pl. The reason for this patch is to provide
    data (sysfs/boottime) suitable for automatic test-cases as
    well as help for developers to reduce the boot time (debugfs).
    
    Based heavily on the original driver by Jonas Aaberg.
    
    Cc: Russell King <linux@arm.linux.org.uk>
    Cc: Will Deacon <will.deacon@arm.com>
    Signed-off-by: Jonas Aaberg <jonas.aberg@stericsson.com>
    Signed-off-by: Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>
    Signed-off-by: Lee Jones <lee.jones@linaro.org>
    Reviewed-by: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com>
    Tested-by: Mian Yousaf KAUKAB <mian.yousaf.kaukab@stericsson.com>

diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
index e8a4e58..8522356 100644
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_SHARP_PARAM)	+= sharpsl_param.o
 obj-$(CONFIG_SHARP_SCOOP)	+= scoop.o
 obj-$(CONFIG_PCI_HOST_ITE8152)  += it8152.o
 obj-$(CONFIG_ARM_TIMER_SP804)	+= timer-sp.o
+obj-$(CONFIG_BOOTTIME)		+= boottime.o
diff --git a/arch/arm/common/boottime.c b/arch/arm/common/boottime.c
new file mode 100644
index 0000000..73e9e04
--- /dev/null
+++ b/arch/arm/common/boottime.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009-2010
+ *
+ * Author: Jonas Aaberg <jonas.aberg@stericsson.com> for ST-Ericsson
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ *
+ * Store boot times measured during for example u-boot startup.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/boottime.h>
+#include <linux/string.h>
+#include <asm/setup.h>
+
+static u32 bootloader_idle;
+static u32 bootloader_total;
+
+static int __init boottime_parse_tag(const struct tag *tag)
+{
+	int i;
+	char buff[BOOTTIME_MAX_NAME_LEN];
+
+	bootloader_idle = tag->u.boottime.idle;
+	bootloader_total = tag->u.boottime.total;
+
+	for (i = 0; i < tag->u.boottime.num; i++) {
+		snprintf(buff, BOOTTIME_MAX_NAME_LEN, "%s+0x0/0x0",
+			 tag->u.boottime.entry[i].name);
+		buff[BOOTTIME_MAX_NAME_LEN - 1] = '\0';
+		boottime_mark_wtime(buff, tag->u.boottime.entry[i].time);
+	}
+
+	return 0;
+}
+
+__tagtable(ATAG_BOOTTIME,  boottime_parse_tag);
+
+int boottime_bootloader_idle(void)
+{
+	if (bootloader_total == 0)
+		return 0;
+
+	return (int) ((bootloader_idle) / (bootloader_total / 100));
+}
diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h
index 24d284a..e8da062 100644
--- a/arch/arm/include/asm/setup.h
+++ b/arch/arm/include/asm/setup.h
@@ -143,6 +143,23 @@ struct tag_memclk {
 	__u32 fmemclk;
 };
 
+/* for automatic boot timing testcases */
+#define ATAG_BOOTTIME  0x41000403
+#define BOOTTIME_MAX_NAME_LEN 64
+#define BOOTTIME_MAX 10
+
+struct boottime_entry {
+	u32 time; /* in us */
+	u8  name[BOOTTIME_MAX_NAME_LEN];
+};
+
+struct tag_boottime {
+	struct boottime_entry entry[BOOTTIME_MAX];
+	u32 idle;  /* in us */
+	u32 total; /* in us */
+	u8 num;
+};
+
 struct tag {
 	struct tag_header hdr;
 	union {
@@ -165,6 +182,10 @@ struct tag {
 		 * DC21285 specific
 		 */
 		struct tag_memclk	memclk;
+		/*
+		 * Boot time
+		 */
+		struct tag_boottime	boottime;
 	} u;
 };
 
diff --git a/include/linux/boottime.h b/include/linux/boottime.h
new file mode 100644
index 0000000..d330ecd
--- /dev/null
+++ b/include/linux/boottime.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009-2010
+ *
+ * Author: Jonas Aaberg <jonas.aberg@stericsson.com> for ST-Ericsson
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ *
+ * boottime is a tool for collecting start-up timing
+ * information and can together with boot loader support
+ * display a total system start-up time.
+ *
+ */
+
+#ifndef LINUX_BOOTTIME_H
+#define LINUX_BOOTTIME_H
+
+#ifdef CONFIG_BOOTTIME
+#include <linux/kernel.h>
+
+/**
+ * struct boottime_timer - Callbacks for generic timer.
+ * @init: Function to call at boottime initialization
+ * @get_time: Returns the number of us since start-up
+ *            Preferable this is based upon a free running timer.
+ *            This is the only required entry.
+ * @finalize: Called before init is executed and boottime is done.
+ */
+struct boottime_timer {
+	int (*init)(void);
+	unsigned long (*get_time)(void);
+	void (*finalize)(void);
+};
+
+/**
+ * boottime_mark_wtime()
+ * Add a sample point with a given time. Useful for adding data collected
+ * by for example a boot loader.
+ * @name: The name of the sample point
+ * @time: The time in us when this point was reached
+ */
+void __init boottime_mark_wtime(char *name, unsigned long time);
+
+/**
+ * boottime_mark()
+ * Add a sample point with the current time.
+ * @name: The name of this sample point
+ */
+void boottime_mark(char *name);
+
+/**
+ * boottime_mark_symbolic()
+ * Add a sample point where the name is a symbolic function
+ * and %pF is needed to get the correct function name.
+ * @name: function name.
+ */
+void __init boottime_mark_symbolic(void *name);
+
+/**
+ * boottime_activate()
+ * Activates boottime and register callbacks.
+ * @bt: struct with callbacks.
+ */
+void __ref boottime_activate(struct boottime_timer *bt);
+
+/**
+ * boottime_deactivate()
+ * This function is called when the kernel boot is done.
+ * (before "free init memory" is called)
+ */
+void boottime_deactivate(void);
+
+/**
+ * boottime_system_up()
+ * A function is called when the basics of the kernel
+ * is up and running.
+ */
+void __init boottime_system_up(void);
+
+#else
+
+#define boottime_mark_wtime(name, time)
+#define boottime_mark(name)
+#define boottime_mark_symbolic(name)
+#define boottime_activate(bt)
+#define boottime_deactivate()
+#define boottime_system_up()
+#endif
+
+#endif /* LINUX_BOOTTIME_H */
diff --git a/init/Kconfig b/init/Kconfig
index 4c93533..d0df8ff 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1464,6 +1464,15 @@ config PROFILING
 	  Say Y here to enable the extended profiling support mechanisms used
 	  by profilers such as OProfile.
 
+config BOOTTIME
+	bool "Boot time measurements"
+	default n
+	help
+		Adds sysfs entries (boottime/) with start-up timing information.
+		If CONFIG_DEBUG_FS is enabled, detailed information about the
+		boot time, including system load during boot can be extracted.
+		This information can be visualised with help of the bootgraph script.
+
 #
 # Place an empty function call at each tracepoint site. Can be
 # dynamically changed for a probe function.
diff --git a/init/Makefile b/init/Makefile
index 7bc47ee..356d529 100644
--- a/init/Makefile
+++ b/init/Makefile
@@ -9,6 +9,7 @@ else
 obj-$(CONFIG_BLK_DEV_INITRD)   += initramfs.o
 endif
 obj-$(CONFIG_GENERIC_CALIBRATE_DELAY) += calibrate.o
+obj-$(CONFIG_BOOTTIME)		      += boottime.o
 
 ifneq ($(CONFIG_ARCH_INIT_TASK),y)
 obj-y                          += init_task.o
diff --git a/init/boottime.c b/init/boottime.c
new file mode 100644
index 0000000..793c184
--- /dev/null
+++ b/init/boottime.c
@@ -0,0 +1,475 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009-2010
+ *
+ * Author: Jonas Aaberg <jonas.aberg@stericsson.com> for ST-Ericsson
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ *
+ * boottime is a tool for collecting start-up timing
+ * information and can together with boot loader support
+ * display a total system start-up time.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/seq_file.h>
+#include <linux/debugfs.h>
+#include <linux/spinlock.h>
+#include <linux/boottime.h>
+#include <linux/kernel_stat.h>
+#include <linux/kobject.h>
+#include <linux/device.h>
+#include <linux/sysfs.h>
+#include <linux/slab.h>
+
+/*
+ * BOOTTIME_MAX_NAME_LEN is defined in arch/arm/include/asm/setup.h to 64.
+ * No crisis if they don't match.
+ */
+#ifndef BOOTTIME_MAX_NAME_LEN
+#define BOOTTIME_MAX_NAME_LEN 64
+#endif
+
+/*
+ * We have a few static entries, since it is good to have measure points
+ * before the system is up and running properly
+ */
+#define NUM_STATIC_BOOTTIME_ENTRIES 32
+
+struct boottime_list {
+	struct list_head list;
+	char name[BOOTTIME_MAX_NAME_LEN];
+	/* Time in us since power on, possible including boot loader. */
+	unsigned long time;
+	bool cpu_load;
+	struct kernel_cpustat cpu_usage[NR_CPUS];
+};
+
+enum boottime_filter_type {
+	BOOTTIME_FILTER_OUT_ZERO,
+	BOOTTIME_FILTER_OUT_LESS_100,
+	BOOTTIME_FILTER_NOTHING,
+};
+
+enum boottime_symbolic_print {
+	BOOTTIME_SYMBOLIC_PRINT,
+	BOOTTIME_NORMAL_PRINT,
+};
+
+enum boottime_cpu_load {
+	BOOTTIME_CPU_LOAD,
+	BOOTTIME_NO_CPU_LOAD,
+};
+
+static LIST_HEAD(boottime_list);
+static DEFINE_SPINLOCK(boottime_list_lock);
+static struct boottime_timer boottime_timer;
+static int num_const_boottime_list;
+static struct boottime_list const_boottime_list[NUM_STATIC_BOOTTIME_ENTRIES];
+static unsigned long time_kernel_done;
+static unsigned long time_bootloader_done;
+static bool system_up;
+static bool boottime_done;
+
+int __attribute__((weak)) boottime_arch_startup(void)
+{
+	return 0;
+}
+
+int __attribute__((weak)) boottime_bootloader_idle(void)
+{
+	return 0;
+}
+
+static void boottime_mark_core(char *name,
+				      unsigned long time,
+				      enum boottime_symbolic_print symbolic,
+				      enum boottime_cpu_load cpu_load)
+{
+	struct boottime_list *b;
+	unsigned long flags = 0;
+	int i;
+
+	if (system_up) {
+		b = kmalloc(sizeof(struct boottime_list), GFP_KERNEL);
+		if (!b) {
+			printk(KERN_ERR
+			       "boottime: failed to allocate memory!\n");
+			return;
+		}
+
+	} else {
+		if (num_const_boottime_list < NUM_STATIC_BOOTTIME_ENTRIES) {
+			b = &const_boottime_list[num_const_boottime_list];
+			num_const_boottime_list++;
+		} else {
+			printk(KERN_ERR
+			       "boottime: too many early measure points!\n");
+			return;
+		}
+	}
+
+	INIT_LIST_HEAD(&b->list);
+
+	if (symbolic == BOOTTIME_SYMBOLIC_PRINT)
+		snprintf(b->name, BOOTTIME_MAX_NAME_LEN, "%pF", name);
+	else
+		strncpy(b->name, name, BOOTTIME_MAX_NAME_LEN);
+
+	b->name[BOOTTIME_MAX_NAME_LEN - 1] = '\0';
+	b->time = time;
+	b->cpu_load = cpu_load;
+
+	if (cpu_load == BOOTTIME_CPU_LOAD && system_up)
+		for_each_possible_cpu(i) {
+			b->cpu_usage[i].cpustat[CPUTIME_SYSTEM] =
+				kcpustat_cpu(i).cpustat[CPUTIME_SYSTEM];
+			b->cpu_usage[i].cpustat[CPUTIME_IDLE] =
+				kcpustat_cpu(i).cpustat[CPUTIME_IDLE];
+			b->cpu_usage[i].cpustat[CPUTIME_IOWAIT] =
+				kcpustat_cpu(i).cpustat[CPUTIME_IOWAIT];
+			b->cpu_usage[i].cpustat[CPUTIME_IRQ] =
+				kcpustat_cpu(i).cpustat[CPUTIME_IRQ];
+			/*
+			 * TODO: Make sure that user, nice, softirq, steal
+			 * and guest are not used during boot
+			 */
+		}
+	else
+		b->cpu_load = BOOTTIME_NO_CPU_LOAD;
+
+	if (system_up) {
+		spin_lock_irqsave(&boottime_list_lock, flags);
+		list_add(&b->list, &boottime_list);
+		spin_unlock_irqrestore(&boottime_list_lock, flags);
+	} else {
+		list_add(&b->list, &boottime_list);
+	}
+}
+
+void __init boottime_mark_wtime(char *name, unsigned long time)
+{
+	boottime_mark_core(name, time,
+			   BOOTTIME_NORMAL_PRINT,
+			   BOOTTIME_NO_CPU_LOAD);
+}
+
+void __ref boottime_mark_symbolic(void *name)
+{
+
+	if (boottime_done)
+		return;
+
+	if (boottime_timer.get_time)
+		boottime_mark_core((char *) name,
+				   boottime_timer.get_time(),
+				   BOOTTIME_SYMBOLIC_PRINT,
+				   BOOTTIME_CPU_LOAD);
+}
+
+void boottime_mark(char *name)
+{
+	if (boottime_timer.get_time)
+		boottime_mark_core(name,
+				   boottime_timer.get_time(),
+				   BOOTTIME_NORMAL_PRINT,
+				   BOOTTIME_CPU_LOAD);
+}
+
+void __init boottime_activate(struct boottime_timer *bt)
+{
+	struct boottime_list *b;
+	int res = 0;
+	unsigned long flags;
+
+	if (bt == NULL) {
+		printk(KERN_ERR
+		       "boottime: error: bad configured\n");
+		return;
+	}
+
+	if (bt->get_time == NULL) {
+		printk(KERN_ERR
+		       "boottime: error: you must provide a get_time() function\n");
+		return;
+	}
+	memcpy(&boottime_timer, bt, sizeof(struct boottime_timer));
+
+	if (boottime_timer.init)
+		res = boottime_timer.init();
+
+	if (res) {
+		printk(KERN_ERR "boottime: initialization failed\n");
+		return;
+	}
+
+	if (boottime_arch_startup())
+		printk(KERN_ERR
+		       "boottime: arch specfic initialization failed\n");
+
+	spin_lock_irqsave(&boottime_list_lock, flags);
+
+	if (!list_empty(&boottime_list)) {
+
+		b = list_first_entry(&boottime_list, struct boottime_list,
+				     list);
+		if (b)
+			time_bootloader_done = b->time;
+	}
+
+	spin_unlock_irqrestore(&boottime_list_lock, flags);
+}
+
+void __init boottime_system_up(void)
+{
+	system_up = true;
+}
+
+void boottime_deactivate(void)
+{
+	struct boottime_list *b;
+	unsigned long flags;
+
+	boottime_mark("execute_init+0x0/0x0");
+
+	boottime_done = true;
+
+	spin_lock_irqsave(&boottime_list_lock, flags);
+	b = list_first_entry(&boottime_list, struct boottime_list, list);
+	spin_unlock_irqrestore(&boottime_list_lock, flags);
+
+	time_kernel_done = b->time;
+
+	if (boottime_timer.finalize)
+		boottime_timer.finalize();
+}
+
+#ifdef CONFIG_DEBUG_FS
+static void boottime_debugfs_load(struct seq_file *s,
+				  struct boottime_list *b,
+				  struct boottime_list *p)
+{
+	int i;
+	unsigned long total_p, total_b;
+	unsigned long system_total, idle_total, irq_total, iowait_total;
+	unsigned long system_load, idle_load, irq_load, iowait_load;
+
+	for_each_possible_cpu(i) {
+		total_b = (b->cpu_usage[i].cpustat[CPUTIME_SYSTEM] +
+			   b->cpu_usage[i].cpustat[CPUTIME_IDLE] +
+			   b->cpu_usage[i].cpustat[CPUTIME_IOWAIT] +
+			   b->cpu_usage[i].cpustat[CPUTIME_IRQ]);
+
+		total_p = (p->cpu_usage[i].cpustat[CPUTIME_SYSTEM] +
+			   p->cpu_usage[i].cpustat[CPUTIME_IDLE] +
+			   p->cpu_usage[i].cpustat[CPUTIME_IOWAIT] +
+			   p->cpu_usage[i].cpustat[CPUTIME_IRQ]);
+
+		if (total_b == total_p)
+			continue;
+
+		system_total = b->cpu_usage[i].cpustat[CPUTIME_SYSTEM]
+			- p->cpu_usage[i].cpustat[CPUTIME_SYSTEM];
+		idle_total = b->cpu_usage[i].cpustat[CPUTIME_IDLE]
+			- p->cpu_usage[i].cpustat[CPUTIME_IDLE];
+		irq_total = b->cpu_usage[i].cpustat[CPUTIME_IRQ]
+			- p->cpu_usage[i].cpustat[CPUTIME_IRQ];
+		iowait_total = b->cpu_usage[i].cpustat[CPUTIME_IOWAIT]
+			- p->cpu_usage[i].cpustat[CPUTIME_IOWAIT];
+
+		system_load = (100 * system_total / (total_b - total_p));
+		idle_load = (100 * idle_total / (total_b - total_p));
+		irq_load = (100 * irq_total / (total_b - total_p));
+		iowait_load = (100 * iowait_total / (total_b - total_p));
+
+		seq_printf(s,
+			   " cpu%d system: %lu%% idle: %lu%% iowait: %lu%% irq: %lu%%",
+			   i,
+			   system_load,
+			   idle_load,
+			   iowait_load,
+			   irq_load);
+	}
+	seq_printf(s, "\n");
+}
+
+static void boottime_debugfs_print(struct seq_file *s,
+				   struct boottime_list *b,
+				   struct boottime_list *p)
+{
+	seq_printf(s, "[%5lu.%06lu] calling  %s\n",
+		   p->time / 1000000,
+		   (p->time  % 1000000),
+		   p->name);
+	seq_printf(s, "[%5lu.%06lu] initcall %s returned 0 after %ld msecs.",
+		   b->time / 1000000,
+		   (b->time  % 1000000),
+		   p->name, (b->time - p->time) / 1000);
+
+	if (p->cpu_load == BOOTTIME_NO_CPU_LOAD ||
+	    b->cpu_load == BOOTTIME_NO_CPU_LOAD) {
+		seq_printf(s, "\n");
+		return;
+	}
+
+	boottime_debugfs_load(s, b, p);
+}
+
+static int boottime_debugfs_bootgraph_show(struct seq_file *s, void *iter)
+{
+	struct boottime_list *b, *p = NULL, *old_p = NULL;
+	enum boottime_filter_type filter = (int)s->private;
+
+	list_for_each_entry_reverse(b, &boottime_list, list) {
+		if (p) {
+			if (!(filter == BOOTTIME_FILTER_OUT_ZERO &&
+			     (b->time - p->time) / 1000 == 0)
+			   && !(filter == BOOTTIME_FILTER_OUT_LESS_100 &&
+				(b->time - p->time) < 100 * 1000))
+				boottime_debugfs_print(s, b, p);
+			old_p = p;
+		}
+		p = b;
+	}
+
+	if (filter == BOOTTIME_FILTER_NOTHING && p)
+		boottime_debugfs_print(s, p, p);
+
+	if (p)
+		seq_printf(s, "[%5lu.%06lu] Freeing init memory: 0K\n",
+			   p->time / 1000000, p->time  % 1000000);
+	return 0;
+}
+
+static int boottime_debugfs_summary_show(struct seq_file *s, void *data)
+{
+	struct boottime_list *b, b_zero;
+
+	if (time_bootloader_done)
+		seq_printf(s, "bootloader: %ld msecs\n",
+			   time_bootloader_done / 1000);
+
+	seq_printf(s, "kernel: %ld msecs\ntotal: %ld msecs\n",
+		   (time_kernel_done - time_bootloader_done) / 1000,
+		   time_kernel_done / 1000);
+	seq_printf(s, "kernel:");
+	b = list_first_entry(&boottime_list,
+			     struct boottime_list, list);
+	memset(&b_zero, 0, sizeof(struct boottime_list));
+	boottime_debugfs_load(s, b, &b_zero);
+
+	if (time_bootloader_done)
+		seq_printf(s,
+			   "bootloader: cpu0 system: %d%% idle: %d%% iowait: 0%% irq: 0%%\n",
+			   100 - boottime_bootloader_idle(),
+			   boottime_bootloader_idle());
+	return 0;
+}
+
+static int boottime_debugfs_bootgraph_open(struct inode *inode,
+					   struct file *file)
+{
+	return single_open(file,
+			   boottime_debugfs_bootgraph_show,
+			   inode->i_private);
+}
+
+static int boottime_debugfs_summary_open(struct inode *inode,
+					 struct file *file)
+{
+	return single_open(file,
+			   boottime_debugfs_summary_show,
+			   inode->i_private);
+}
+
+static const struct file_operations boottime_debugfs_bootgraph_operations = {
+	.open		= boottime_debugfs_bootgraph_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static const struct file_operations boottime_debugfs_summary_operations = {
+	.open		= boottime_debugfs_summary_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+void boottime_debugfs_init(void)
+{
+	struct dentry *dir;
+
+	dir = debugfs_create_dir("boottime", NULL);
+
+	(void) debugfs_create_file("bootgraph", S_IFREG | S_IRUGO,
+				   dir, (void *)BOOTTIME_FILTER_NOTHING,
+				   &boottime_debugfs_bootgraph_operations);
+	(void) debugfs_create_file("bootgraph_all_except0", S_IFREG | S_IRUGO,
+				   dir, (void *)BOOTTIME_FILTER_OUT_ZERO,
+				   &boottime_debugfs_bootgraph_operations);
+	(void) debugfs_create_file("bootgraph_larger100",
+				   S_IFREG | S_IRUGO,
+				   dir, (void *)BOOTTIME_FILTER_OUT_LESS_100,
+				   &boottime_debugfs_bootgraph_operations);
+	(void) debugfs_create_file("summary", S_IFREG | S_IRUGO,
+				   dir, NULL,
+				   &boottime_debugfs_summary_operations);
+}
+#else
+#define boottime_debugfs_init(x)
+#endif
+
+static ssize_t show_bootloader(struct device *dev,
+			       struct device_attribute *attr,
+			       char *buf)
+{
+	return sprintf(buf, "%ld\n", time_bootloader_done / 1000);
+}
+
+static ssize_t show_kernel(struct device *dev,
+			   struct device_attribute *attr,
+			   char *buf)
+{
+	return sprintf(buf, "%ld\n",
+		       (time_kernel_done - time_bootloader_done) / 1000);
+}
+
+DEVICE_ATTR(kernel, 0444, show_kernel, NULL);
+DEVICE_ATTR(bootloader, 0444, show_bootloader, NULL);
+
+static struct attribute *boottime_sysfs_entries[] = {
+	&dev_attr_kernel.attr,
+	&dev_attr_bootloader.attr,
+	NULL
+};
+
+static struct attribute_group boottime_attr_grp = {
+	.name = NULL,
+	.attrs = boottime_sysfs_entries,
+};
+
+static int __init boottime_init(void)
+{
+	struct kobject *boottime_kobj;
+
+	boottime_kobj = kobject_create_and_add("boottime", NULL);
+	if (!boottime_kobj) {
+		printk(KERN_ERR "boottime: out of memory!\n");
+		return -ENOMEM;
+	}
+
+	if (sysfs_create_group(boottime_kobj, &boottime_attr_grp) < 0) {
+		kobject_put(boottime_kobj);
+		printk(KERN_ERR "boottime: Failed creating sysfs group\n");
+		return -ENOMEM;
+	}
+
+	boottime_debugfs_init();
+
+	return 0;
+}
+
+late_initcall(boottime_init);
diff --git a/init/main.c b/init/main.c
index 313360f..c06afd0 100644
--- a/init/main.c
+++ b/init/main.c
@@ -69,6 +69,7 @@
 #include <linux/slab.h>
 #include <linux/perf_event.h>
 #include <linux/file.h>
+#include <linux/boottime.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
@@ -679,6 +680,8 @@ int __init_or_module do_one_initcall(initcall_t fn)
 	int count = preempt_count();
 	int ret;
 
+	boottime_mark_symbolic(fn);
+
 	if (initcall_debug)
 		ret = do_one_initcall_debug(fn);
 	else
@@ -804,6 +807,7 @@ static noinline int init_post(void)
 {
 	/* need to finish all async __init code before freeing the memory */
 	async_synchronize_full();
+	boottime_deactivate();
 	free_initmem();
 	mark_rodata_ro();
 	system_state = SYSTEM_RUNNING;
@@ -863,6 +867,7 @@ static int __init kernel_init(void * unused)
 
 	do_pre_smp_initcalls();
 	lockup_detector_init();
+	boottime_system_up();
 
 	smp_init();
 	sched_init_smp();
@@ -885,6 +890,7 @@ static int __init kernel_init(void * unused)
 
 	if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
 		ramdisk_execute_command = NULL;
+		boottime_mark("mount+0x0/0x0");
 		prepare_namespace();
 	}

^ permalink raw reply related

* [PATCH] ARM: EXYNOS: exynos4-dt: Set .smp field of machine descriptor
From: Tomasz Figa @ 2012-10-12  9:49 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds missing initializer of .smp field of machine descriptor
of Exynos 4 DT machine.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
---
 arch/arm/mach-exynos/mach-exynos4-dt.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-exynos/mach-exynos4-dt.c b/arch/arm/mach-exynos/mach-exynos4-dt.c
index 7222e3c..d6bdcfb 100644
--- a/arch/arm/mach-exynos/mach-exynos4-dt.c
+++ b/arch/arm/mach-exynos/mach-exynos4-dt.c
@@ -119,6 +119,7 @@ static char const *exynos4_dt_compat[] __initdata = {
 
 DT_MACHINE_START(EXYNOS4210_DT, "Samsung Exynos4 (Flattened Device Tree)")
 	/* Maintainer: Thomas Abraham <thomas.abraham@linaro.org> */
+	.smp		= smp_ops(exynos_smp_ops),
 	.init_irq	= exynos4_init_irq,
 	.map_io		= exynos4_dt_map_io,
 	.handle_irq	= gic_handle_irq,
-- 
1.7.12

^ permalink raw reply related

* [PATCH v2] i2c: change the id to let the i2c-gpio work
From: Bo Shen @ 2012-10-12  9:42 UTC (permalink / raw)
  To: linux-arm-kernel

The i2c-gpio driver will turn the platform device ID to busnum.
When using platfrom device ID as -1, it means dynamically assigned
the busnum. When writing code, we need to make sure the busnum,
and call i2c_register_board_info(int busnum, ...) to register device
if using -1, we do not know the value of busnum. 

In order to solve this issue, set the platform device ID as a fix number
Here using 0 to match the busnum used in i2c_regsiter_board_info().

Signed-off-by: Bo Shen <voice.shen@atmel.com>
---
Change since v1
  Make the commit message more clear
---
 arch/arm/mach-at91/at91sam9260_devices.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
index 0f24cfb..805ef95 100644
--- a/arch/arm/mach-at91/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -389,7 +389,7 @@ static struct i2c_gpio_platform_data pdata = {
 
 static struct platform_device at91sam9260_twi_device = {
 	.name			= "i2c-gpio",
-	.id			= -1,
+	.id			= 0,
 	.dev.platform_data	= &pdata,
 };
 
-- 
1.7.9.5

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox