* Re: [PATCH] kbuild: Enable building defconfigs from Kconfig files
From: Linus Torvalds @ 2010-07-14 4:04 UTC (permalink / raw)
To: Grant Likely
Cc: Michal Marek, Stephen Rothwell, Catalin Marinas, LKML,
Russell King, Andrew Morton, ppc-dev, linux-arm-kernel
In-Reply-To: <AANLkTimC_vXCAOrfTSndZyk8lgkjTlILVSYVYeIg6cUt@mail.gmail.com>
On Tue, Jul 13, 2010 at 7:26 PM, Grant Likely <grant.likely@secretlab.ca> w=
rote:
>
> I chose to use -D /dev/null (defconfig from an empty file) instead of
> -n (allnoconfig) so that default values in Kconfig would get
> respected. =A0For the benefit of everyone else, here's an excerpt from
> our IRC conversation this afternoon:
>
> 19:49 < gcl> sfr: [...] Your patch and my patch are
> =A0 =A0 =A0 =A0 =A0 =A0 essentially doing exactly the same thing, except =
that I used '-d'
> =A0 =A0 =A0 =A0 =A0 =A0 and you used '-n'.
> 19:50 < gcl> s/-d/-D/
> 19:55 < sfr> right
> 19:55 < sfr> Linus wanted us to use -n
Just a note: Linus doesn't really care.
IOW, I used -n not because of any fundamental belief that it is
correct, but just because ti happened to be how I happened to decide
to solve it. It's entirely possible that starting from the Kconfig
defaults (rather than "no") is the right way to go.
I think either approach is likely fine. The -D /dev/null approach
would presumably give smaller Kconfig.xyz files, assuming our defaults
are sane (an maybe that could be at least a partial validation of the
defaults we do have). While the -n approach is in some ways more
stable, in that the resulting Kconfig.xyz entires would presumably be
more stand-alone, and there wouldn't be any subtle interactions when
somebody changes a default value int he Kconfig file.
So I can see advantages to either model. And either model clearly
would want the improvements to "select" that are independent (ie warn
about unsatisfied 'depends on' constraints, and select recursively.
Maybe we already fixed the recursive select thing, I forget).
I also think we need to allow setting of actual values. I don't know
what the syntax would be. A "set" statement that overrides a default
in the Kconfig file, so that you can do
set NODES_SHIFT 10
which would basically be equivalent to a "select" of a tristate
variable, but instead set the actual value? I dunno.
And quite frankly, maybe somebody comes up with a better model
entirely. I like the Kconfig.xyz model, in that it should be
human-readable/writable and shouldn't introduce any fundamentally new
concepts (except the fairly simple extensions to the Kconfig
language), but maybe there are better models.
Regardless, I don't have anything against either set of patches
(Grant's or Stephen's).
Linus
^ permalink raw reply
* Re: [PATCH 09/13] powerpc/book3e: Add generic 64-bit idle powersave support
From: Benjamin Herrenschmidt @ 2010-07-14 4:09 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1278656215-24705-9-git-send-email-benh@kernel.crashing.org>
On Fri, 2010-07-09 at 16:16 +1000, Benjamin Herrenschmidt wrote:
> We use a similar technique to ppc32: We set a thread local flag
> to indicate that we are about to enter or have entered the stop
> state, and have fixup code in the async interrupt entry code that
> reacts to this flag to make us return to a different location
> (sets NIP to LINK in our case).
.../...
Commenting on my own patch ... :-) This has issues:
> +_GLOBAL(book3e_idle)
> + /* Save LR for later */
> + mflr r0
> + std r0,16(r1)
> +
> + /* Hard disable interrupts */
> + wrteei 0
> +
> + /* Now check if an interrupt came in while we were soft disabled
> + * since we may otherwise lose it (doorbells etc...). We know
> + * that since PACAHARDIRQEN will have been cleared in that case.
> + */
> + lbz r3,PACAHARDIRQEN(r13)
> + cmpwi cr0,r3,0
> + beqlr
> +
> + /* Now we are going to mark ourselves as soft and hard enables in
> + * order to be able to take interrupts while asleep. We inform lockdep
> + * of that. We don't actually turn interrupts on just yet tho.
> + */
> +#ifdef CONFIG_TRACE_IRQFLAGS
> + bl .trace_hardirqs_on
Oops... we just clobbered our saved LR on the stack. Need a stackframe
> +#endif
> + li r0,1
> + stb r0,PACASOFTIRQEN(r13)
> + stb r0,PACAHARDIRQEN(r13)
> +
> + /* Interrupts will make use return to LR, so get something we want
> + * in there
> + */
> + bl 1f
We return here with IRQs enabled, we really need to turn them back off
or bad things will happen if an interrupt pops before we clear
TFL_NAPPING.
I'll send a respin.
Cheers,
Ben.
> + /* We are back from the interrupt, the caller will local_irq_enable()
> + * so to avoid stupid warning, let's turn them off here if irqtrace
> + * is enabled.
> + */
> +#ifdef CONFIG_TRACE_IRQFLAGS
> + li r0,0
> + stb r0,PACASOFTIRQEN(r13)
> + bl .trace_hardirqs_off
> +#endif
> + ld r0,16(r1)
> + mtlr r0
> + blr
> +
> +1: /* Let's set the _TLF_NAPPING flag so interrupts make us return
> + * to the right spot
> + */
> + clrrdi r11,r1,THREAD_SHIFT
> + ld r10,TI_LOCAL_FLAGS(r11)
> + ori r10,r10,_TLF_NAPPING
> + std r10,TI_LOCAL_FLAGS(r11)
> +
> + /* We can now re-enable hard interrupts and go to sleep */
> + wrteei 1
> +1: PPC_WAIT(0)
> + b 1b
> +
> +#endif /* CONFIG_PPC64 */
> \ No newline at end of file
^ permalink raw reply
* [PATCH v2] powerpc/book3e: Add generic 64-bit idle powersave
From: Benjamin Herrenschmidt @ 2010-07-14 4:15 UTC (permalink / raw)
To: linuxppc-dev
We use a similar technique to ppc32: We set a thread local flag
to indicate that we are about to enter or have entered the stop
state, and have fixup code in the async interrupt entry code that
reacts to this flag to make us return to a different location
(sets NIP to LINK in our case).
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
--
v2. Fix lockdep bug
Re-mask interrupts when coming back from idle
---
arch/powerpc/include/asm/machdep.h | 1 +
arch/powerpc/kernel/Makefile | 2 +-
arch/powerpc/kernel/exceptions-64e.S | 23 +++++++++
arch/powerpc/kernel/idle_book3e.S | 86 ++++++++++++++++++++++++++++++++++
4 files changed, 111 insertions(+), 1 deletions(-)
create mode 100644 arch/powerpc/kernel/idle_book3e.S
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index 2bad6e5..adc8e6c 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -278,6 +278,7 @@ extern void e500_idle(void);
extern void power4_idle(void);
extern void power4_cpu_offline_powersave(void);
extern void ppc6xx_idle(void);
+extern void book3e_idle(void);
/*
* ppc_md contains a copy of the machine description structure for the
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 8a33318..77d831a 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -37,7 +37,7 @@ obj-$(CONFIG_PPC64) += setup_64.o sys_ppc32.o \
obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_ppc970.o cpu_setup_pa6t.o
obj64-$(CONFIG_RELOCATABLE) += reloc_64.o
-obj-$(CONFIG_PPC_BOOK3E_64) += exceptions-64e.o
+obj-$(CONFIG_PPC_BOOK3E_64) += exceptions-64e.o idle_book3e.o
obj-$(CONFIG_PPC64) += vdso64/
obj-$(CONFIG_ALTIVEC) += vecemu.o
obj-$(CONFIG_PPC_970_NAP) += idle_power4.o
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S
index a42637c..316465a 100644
--- a/arch/powerpc/kernel/exceptions-64e.S
+++ b/arch/powerpc/kernel/exceptions-64e.S
@@ -204,11 +204,30 @@ exc_##n##_bad_stack: \
lis r,TSR_FIS@h; \
mtspr SPRN_TSR,r
+/* Used by asynchronous interrupt that may happen in the idle loop.
+ *
+ * This check if the thread was in the idle loop, and if yes, returns
+ * to the caller rather than the PC. This is to avoid a race if
+ * interrupts happen before the wait instruction.
+ */
+#define CHECK_NAPPING() \
+ clrrdi r11,r1,THREAD_SHIFT; \
+ ld r10,TI_LOCAL_FLAGS(r11); \
+ andi. r9,r10,_TLF_NAPPING; \
+ beq+ 1f; \
+ ld r8,_LINK(r1); \
+ rlwinm r7,r10,0,~_TLF_NAPPING; \
+ std r8,_NIP(r1); \
+ std r7,TI_LOCAL_FLAGS(r11); \
+1:
+
+
#define MASKABLE_EXCEPTION(trapnum, label, hdlr, ack) \
START_EXCEPTION(label); \
NORMAL_EXCEPTION_PROLOG(trapnum, PROLOG_ADDITION_MASKABLE) \
EXCEPTION_COMMON(trapnum, PACA_EXGEN, INTS_DISABLE_ALL) \
ack(r8); \
+ CHECK_NAPPING(); \
addi r3,r1,STACK_FRAME_OVERHEAD; \
bl hdlr; \
b .ret_from_except_lite;
@@ -257,6 +276,7 @@ interrupt_end_book3e:
CRIT_EXCEPTION_PROLOG(0x100, PROLOG_ADDITION_NONE)
// EXCEPTION_COMMON(0x100, PACA_EXCRIT, INTS_DISABLE_ALL)
// bl special_reg_save_crit
+// CHECK_NAPPING();
// addi r3,r1,STACK_FRAME_OVERHEAD
// bl .critical_exception
// b ret_from_crit_except
@@ -268,6 +288,7 @@ interrupt_end_book3e:
// EXCEPTION_COMMON(0x200, PACA_EXMC, INTS_DISABLE_ALL)
// bl special_reg_save_mc
// addi r3,r1,STACK_FRAME_OVERHEAD
+// CHECK_NAPPING();
// bl .machine_check_exception
// b ret_from_mc_except
b .
@@ -338,6 +359,7 @@ interrupt_end_book3e:
CRIT_EXCEPTION_PROLOG(0x9f0, PROLOG_ADDITION_NONE)
// EXCEPTION_COMMON(0x9f0, PACA_EXCRIT, INTS_DISABLE_ALL)
// bl special_reg_save_crit
+// CHECK_NAPPING();
// addi r3,r1,STACK_FRAME_OVERHEAD
// bl .unknown_exception
// b ret_from_crit_except
@@ -434,6 +456,7 @@ kernel_dbg_exc:
CRIT_EXCEPTION_PROLOG(0x2080, PROLOG_ADDITION_NONE)
// EXCEPTION_COMMON(0x2080, PACA_EXCRIT, INTS_DISABLE_ALL)
// bl special_reg_save_crit
+// CHECK_NAPPING();
// addi r3,r1,STACK_FRAME_OVERHEAD
// bl .doorbell_critical_exception
// b ret_from_crit_except
diff --git a/arch/powerpc/kernel/idle_book3e.S b/arch/powerpc/kernel/idle_book3e.S
new file mode 100644
index 0000000..16c002d
--- /dev/null
+++ b/arch/powerpc/kernel/idle_book3e.S
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2010 IBM Corp, Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ *
+ * Generic idle routine for Book3E processors
+ *
+ * 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.
+ */
+
+#include <linux/threads.h>
+#include <asm/reg.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/ppc-opcode.h>
+#include <asm/processor.h>
+#include <asm/thread_info.h>
+
+/* 64-bit version only for now */
+#ifdef CONFIG_PPC64
+
+_GLOBAL(book3e_idle)
+ /* Save LR for later */
+ mflr r0
+ std r0,16(r1)
+
+ /* Hard disable interrupts */
+ wrteei 0
+
+ /* Now check if an interrupt came in while we were soft disabled
+ * since we may otherwise lose it (doorbells etc...). We know
+ * that since PACAHARDIRQEN will have been cleared in that case.
+ */
+ lbz r3,PACAHARDIRQEN(r13)
+ cmpwi cr0,r3,0
+ beqlr
+
+ /* Now we are going to mark ourselves as soft and hard enables in
+ * order to be able to take interrupts while asleep. We inform lockdep
+ * of that. We don't actually turn interrupts on just yet tho.
+ */
+#ifdef CONFIG_TRACE_IRQFLAGS
+ stdu r1,-128(r1)
+ bl .trace_hardirqs_on
+#endif
+ li r0,1
+ stb r0,PACASOFTIRQEN(r13)
+ stb r0,PACAHARDIRQEN(r13)
+
+ /* Interrupts will make use return to LR, so get something we want
+ * in there
+ */
+ bl 1f
+
+ /* Hard disable interrupts again */
+ wrteei 0
+
+ /* Mark them off again in the PACA as well */
+ li r0,0
+ stb r0,PACASOFTIRQEN(r13)
+ stb r0,PACAHARDIRQEN(r13)
+
+ /* Tell lockdep about it */
+#ifdef CONFIG_TRACE_IRQFLAGS
+ bl .trace_hardirqs_off
+ addi r1,r1,128
+#endif
+ ld r0,16(r1)
+ mtlr r0
+ blr
+
+1: /* Let's set the _TLF_NAPPING flag so interrupts make us return
+ * to the right spot
+ */
+ clrrdi r11,r1,THREAD_SHIFT
+ ld r10,TI_LOCAL_FLAGS(r11)
+ ori r10,r10,_TLF_NAPPING
+ std r10,TI_LOCAL_FLAGS(r11)
+
+ /* We can now re-enable hard interrupts and go to sleep */
+ wrteei 1
+1: PPC_WAIT(0)
+ b 1b
+
+#endif /* CONFIG_PPC64 */
^ permalink raw reply related
* Re: [PATCH] kbuild: Enable building defconfigs from Kconfig files
From: Grant Likely @ 2010-07-14 5:47 UTC (permalink / raw)
To: Linus Torvalds
Cc: Michal Marek, Stephen Rothwell, Catalin Marinas, LKML,
Russell King, Andrew Morton, ppc-dev, linux-arm-kernel
In-Reply-To: <AANLkTik-QCXFnjma3J28B9h27uajOcDhthTGz99zKgVi@mail.gmail.com>
On Tue, Jul 13, 2010 at 10:04 PM, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
> On Tue, Jul 13, 2010 at 7:26 PM, Grant Likely <grant.likely@secretlab.ca>=
wrote:
>>
>> I chose to use -D /dev/null (defconfig from an empty file) instead of
>> -n (allnoconfig) so that default values in Kconfig would get
>> respected. =A0For the benefit of everyone else, here's an excerpt from
>> our IRC conversation this afternoon:
>>
>> 19:49 < gcl> sfr: [...] Your patch and my patch are
>> =A0 =A0 =A0 =A0 =A0 =A0 essentially doing exactly the same thing, except=
that I used '-d'
>> =A0 =A0 =A0 =A0 =A0 =A0 and you used '-n'.
>> 19:50 < gcl> s/-d/-D/
>> 19:55 < sfr> right
>> 19:55 < sfr> Linus wanted us to use -n
>
> Just a note: Linus doesn't really care.
>
> IOW, I used -n not because of any fundamental belief that it is
> correct, but just because ti happened to be how I happened to decide
> to solve it. It's entirely possible that starting from the Kconfig
> defaults (rather than "no") is the right way to go.
>
> I think either approach is likely fine. The -D /dev/null approach
> would presumably give smaller Kconfig.xyz files, assuming our defaults
> are sane (an maybe that could be at least a partial validation of the
> defaults we do have). While the -n approach is in some ways more
> stable, in that the resulting Kconfig.xyz entires would presumably be
> more stand-alone, and there wouldn't be any subtle interactions when
> somebody changes a default value int he Kconfig file.
Okay, well I advocate for the -D /dev/null approach then. I think
that validating our defaults, and looking for the subtle interactions
are exactly what we want to be doing when it comes to defconfigs. The
fact that a defconfig does *not* want the default value is exactly
what the defconfigs should be capturing.
> So I can see advantages to either model. And either model clearly
> would want the improvements to "select" that are independent (ie warn
> about unsatisfied 'depends on' constraints, and select recursively.
> Maybe we already fixed the recursive select thing, I forget).
>
> I also think we need to allow setting of actual values. I don't know
> what the syntax would be. A "set" statement that overrides a default
> in the Kconfig file, so that you can do
>
> =A0 =A0 =A0 =A0 =A0set NODES_SHIFT 10
>
> which would basically be equivalent to a "select" of a tristate
> variable, but instead set the actual value? I dunno.
I'm partial to extending select statements myself because it fits
nicely into the existing grammer; but I can see value in having a set
statement too. It would eliminate the temporary config options that
both my and Stephen's patch would add.
> And quite frankly, maybe somebody comes up with a better model
> entirely. I like the Kconfig.xyz model, in that it should be
> human-readable/writable and shouldn't introduce any fundamentally new
> concepts (except the fairly simple extensions to the Kconfig
> language), but maybe there are better models.
Perhaps, but I can't think of anything and this one is simple,
elegant, and easy to implement.
> Regardless, I don't have anything against either set of patches
> (Grant's or Stephen's).
I think we should run with this. Since the patch has been merged to
warn on unmet Kconfig dependences, the only major hole left is being
able to do negative selects and to select specific values. Stephen,
I'm happy to either keep working on this, or drop my patch in favor of
yours. Whichever you prefer. I'll try to find some time to look at
the Kconfig grammer.
The solver would also be useful and could further reduce the size of
the Kconfig fragments, but it isn't necessary so we don't need to wait
for it to get implemented to take this approach..
Cheers,
g.
--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
* [git pull] Please pull powerpc.git merge branch
From: Benjamin Herrenschmidt @ 2010-07-14 7:22 UTC (permalink / raw)
To: Linus Torvalds
Cc: linuxppc-dev list, Andrew Morton, Russell King, Linux Kernel list
Hi Linus !
Here are some late fixed for some freescale embedded platforms
for 2.6.35. A bit late but since it only touch their platform
code I don't really have an objection.
Cheers,
Ben.
The following changes since commit 1c5474a65bf15a4cb162dfff86d6d0b5a08a740c:
Linus Torvalds (1):
Linux 2.6.35-rc5
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git merge
Anton Vorontsov (3):
powerpc/cpm: Reintroduce global spi_pram struct (fixes build issue)
powerpc/cpm1: Fix build with various CONFIG_*_UCODE_PATCH combinations
powerpc/cpm1: Mark micropatch code/data static and __init
Matthew McClintock (1):
powerpc/fsl-booke: Fix address issue when using relocatable kernels
arch/powerpc/include/asm/cpm.h | 24 ++++++++++++++++++++
arch/powerpc/include/asm/cpm1.h | 3 +-
arch/powerpc/kernel/fsl_booke_entry_mapping.S | 4 +--
arch/powerpc/sysdev/micropatch.c | 30 +++++++++++++++----------
drivers/spi/spi_mpc8xxx.c | 22 ------------------
5 files changed, 45 insertions(+), 38 deletions(-)
^ permalink raw reply
* [git pull] Please pull powerpc.git lmb-to-memblock branch
From: Benjamin Herrenschmidt @ 2010-07-14 7:22 UTC (permalink / raw)
To: Linus Torvalds
Cc: linuxppc-dev list, Andrew Morton, Russell King, Linux Kernel list
Hi Linus !
As discussed, here's the lmb rename to memblock.
CCing Russell since I know he has some patches in -next for using lmb on ARM which
might need to be reworked on top of that.
BTW. There's another request coming your way for ppc stuff, it's not a
duplicate email :-)
Cheers,
Ben.
The following changes since commit 1c5474a65bf15a4cb162dfff86d6d0b5a08a740c:
Linus Torvalds (1):
Linux 2.6.35-rc5
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git lmb-to-memblock
Yinghai Lu (1):
lmb: rename to memblock
Documentation/kernel-parameters.txt | 2 +-
arch/microblaze/Kconfig | 2 +-
arch/microblaze/include/asm/{lmb.h => memblock.h} | 10 +-
arch/microblaze/kernel/prom.c | 14 +-
arch/microblaze/mm/init.c | 40 +-
arch/powerpc/Kconfig | 2 +-
arch/powerpc/include/asm/abs_addr.h | 2 +-
arch/powerpc/include/asm/lmb.h | 15 -
arch/powerpc/include/asm/memblock.h | 15 +
arch/powerpc/kernel/btext.c | 2 +-
arch/powerpc/kernel/crash.c | 2 +-
arch/powerpc/kernel/crash_dump.c | 4 +-
arch/powerpc/kernel/dma-swiotlb.c | 2 +-
arch/powerpc/kernel/dma.c | 4 +-
arch/powerpc/kernel/machine_kexec.c | 12 +-
arch/powerpc/kernel/paca.c | 8 +-
arch/powerpc/kernel/prom.c | 62 ++--
arch/powerpc/kernel/rtas.c | 6 +-
arch/powerpc/kernel/setup-common.c | 2 +-
arch/powerpc/kernel/setup_32.c | 16 +-
arch/powerpc/kernel/setup_64.c | 20 +-
arch/powerpc/kernel/vdso.c | 4 +-
arch/powerpc/mm/40x_mmu.c | 2 +-
arch/powerpc/mm/hash_utils_64.c | 26 +-
arch/powerpc/mm/init_32.c | 16 +-
arch/powerpc/mm/init_64.c | 2 +-
arch/powerpc/mm/mem.c | 78 ++--
arch/powerpc/mm/numa.c | 84 ++--
arch/powerpc/mm/pgtable_32.c | 6 +-
arch/powerpc/mm/pgtable_64.c | 4 +-
arch/powerpc/mm/ppc_mmu_32.c | 4 +-
arch/powerpc/mm/stab.c | 4 +-
arch/powerpc/mm/tlb_nohash.c | 4 +-
arch/powerpc/platforms/85xx/corenet_ds.c | 4 +-
arch/powerpc/platforms/85xx/mpc8536_ds.c | 4 +-
arch/powerpc/platforms/85xx/mpc85xx_ds.c | 4 +-
arch/powerpc/platforms/85xx/mpc85xx_mds.c | 4 +-
arch/powerpc/platforms/86xx/mpc86xx_hpcn.c | 4 +-
arch/powerpc/platforms/cell/iommu.c | 10 +-
arch/powerpc/platforms/embedded6xx/wii.c | 12 +-
arch/powerpc/platforms/maple/setup.c | 2 +-
arch/powerpc/platforms/pasemi/iommu.c | 4 +-
arch/powerpc/platforms/powermac/setup.c | 4 +-
arch/powerpc/platforms/ps3/htab.c | 2 +-
arch/powerpc/platforms/ps3/mm.c | 6 +-
arch/powerpc/platforms/ps3/os-area.c | 4 +-
arch/powerpc/platforms/pseries/hotplug-memory.c | 38 +-
arch/powerpc/platforms/pseries/iommu.c | 2 +-
arch/powerpc/platforms/pseries/phyp_dump.c | 4 +-
arch/powerpc/sysdev/dart_iommu.c | 8 +-
arch/powerpc/sysdev/fsl_pci.c | 4 +-
arch/sh/Kconfig | 2 +-
arch/sh/include/asm/lmb.h | 6 -
arch/sh/include/asm/memblock.h | 6 +
arch/sh/kernel/machine_kexec.c | 18 +-
arch/sh/kernel/setup.c | 8 +-
arch/sh/mm/init.c | 40 +-
arch/sh/mm/numa.c | 8 +-
arch/sparc/Kconfig | 2 +-
arch/sparc/include/asm/lmb.h | 10 -
arch/sparc/include/asm/memblock.h | 10 +
arch/sparc/kernel/mdesc.c | 16 +-
arch/sparc/kernel/prom_64.c | 4 +-
arch/sparc/mm/init_64.c | 54 +-
include/linux/lmb.h | 89 ----
include/linux/memblock.h | 89 ++++
lib/Kconfig | 3 -
lib/Makefile | 2 -
lib/lmb.c | 541 ---------------------
mm/Kconfig | 3 +
mm/Makefile | 2 +
mm/memblock.c | 541 +++++++++++++++++++++
72 files changed, 1025 insertions(+), 1025 deletions(-)
rename arch/microblaze/include/asm/{lmb.h => memblock.h} (57%)
delete mode 100644 arch/powerpc/include/asm/lmb.h
create mode 100644 arch/powerpc/include/asm/memblock.h
delete mode 100644 arch/sh/include/asm/lmb.h
create mode 100644 arch/sh/include/asm/memblock.h
delete mode 100644 arch/sparc/include/asm/lmb.h
create mode 100644 arch/sparc/include/asm/memblock.h
delete mode 100644 include/linux/lmb.h
create mode 100644 include/linux/memblock.h
delete mode 100644 lib/lmb.c
create mode 100644 mm/memblock.c
^ permalink raw reply
* Re: [PATCH v2]460EX on-chip SATA driver<resubmisison>
From: Jeff Garzik @ 2010-07-14 7:51 UTC (permalink / raw)
To: Rupjyoti Sarmah; +Cc: linux-ide, sr, rsarmah, linux-kernel, linuxppc-dev
In-Reply-To: <201007061106.o66B631f013777@amcc.com>
On 07/06/2010 07:06 AM, Rupjyoti Sarmah wrote:
> This patch enables the on-chip DWC SATA controller of the AppliedMicro processor 460EX.
>
> Signed-off-by: Rupjyoti Sarmah<rsarmah@appliedmicro.com>
> Signed-off-by: Mark Miesfeld<mmiesfeld@appliedmicro.com>
> Signed-off-by: Prodyut Hazarika<phazarika@appliedmicro.com>
>
> ---
> This patch incorporates the changes advised in the mailing list. The device
> tree changes were submitted as a seperate patch. Kconfig file is fixed in this version.
>
> drivers/ata/Kconfig | 9 +
> drivers/ata/Makefile | 1 +
> drivers/ata/sata_dwc_460ex.c | 1756 ++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 1766 insertions(+), 0 deletions(-)
> create mode 100644 drivers/ata/sata_dwc_460ex.c
applied
^ permalink raw reply
* Re: [PATCH 4/7] Allow sysfs memory directories to be split
From: KAMEZAWA Hiroyuki @ 2010-07-14 8:30 UTC (permalink / raw)
To: KAMEZAWA Hiroyuki; +Cc: linuxppc-dev, linux-kernel, Dave Hansen
In-Reply-To: <20100714122503.74f746a2.kamezawa.hiroyu@jp.fujitsu.com>
On Wed, 14 Jul 2010 12:25:03 +0900
KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> wrote:
> On Tue, 13 Jul 2010 22:18:03 -0500
> Nathan Fontenot <nfont@austin.ibm.com> wrote:
>
> > On 07/13/2010 07:35 PM, KAMEZAWA Hiroyuki wrote:
> > > On Tue, 13 Jul 2010 10:51:58 -0500
> > > Nathan Fontenot <nfont@austin.ibm.com> wrote:
> > >
> > >>>
> > >>> And for what purpose this interface is ? Does this split memory block into 2 pieces
> > >>> of the same size ?? sounds __very__ strange interface to me.
> > >>
> > >> Yes, this splits the memory_block into two blocks of the same size. This was
> > >> suggested as something we may want to do. From ppc perspective I am not sure we
> > >> would use this.
> > >>
> > >> The split functionality is not required. The main goal of the patch set is to
> > >> reduce the number of memory sysfs directories created. From a ppc perspective
> > >> the split functionality is not really needed.
> > >>
> > >
> > > Okay, this is an offer from me.
> > >
> > > 1. I think you can add an boot option as "don't create memory sysfs".
> > > please do.
> >
> > I posted a patch to do that a week or so ago, it didn't go over very well.
> >
> > >
> > > 2. I'd like to write a configfs module for handling memory hotplug even when
> > > sysfs directroy is not created.
> > > Because configfs support rmdir/mkdir, the user (ppc's daemon?) has to do
> > >
> > > When offlining section X.
> > > # insmod configfs_memory.ko
> > > # mount -t configfs none /configfs
> > > # mkdir /configfs/memoryX
> > > # echo offline > /configfs/memoryX/state
> > > # rmdir /configfs/memoryX
> > >
> > > And making this operation as the default bahavior for all arch's memory hotplug may
> > > be better...
> > >
> > > Dave, how do you think ? Because ppc guys uses "probe" interface already,
> > > this can be handled... no ?
> >
> > ppc would still require the existance of the 'probe' interface.
> >
> > Are you objecting to the 'split' functionality?
> yes.
>
> > If so I do not see any reason from ppc
> > perspective that it is needed. This was something Dave suggested, unless I am missing
> > something.
> >
> > Since ppc needs the 'probe' interface in sysfs, and for ppc having mutliple
> > memory_block_sections reside under a single memory_block makes memory hotplug
> > simpler. On ppc we do emory hotplug operations on an LMB size basis. With my
> > patches this now lets us set each memory_block to span an LMB's worth of
> > memory. Now we could do emory hotplug in a single operation instead of multiple
> > operations to offline/online all of the memory sections in an LMB.
> >
>
> Why per-section memory offlining is provided is for allowing good success-rate of
> memory offlining. Because memory-hotplug has to "migrate or free" all used page
> under a section, possibility of memory unplug depends on usage of memory.
> If a section contains unmovable page(kernel page), we can't offline sectin.
>
> For example, comparing
> 1. offlining 128MB of memory at once
> 2. offlining 8 chunks of 16MB memory
> "2" can get very good possibility and system-busy time can be much reduced.
>
> IIUC, ppc's 1st requirement is "resizing" not "hot-removing some memory device",
> "2" is much welcomed. So, some fine-grained interface to section_size is
> appreciated. So, "multiple operations" is much better than single operation.
>
> As I posted show/hide patch, I'm writing it in configfs. I think it meets IBM's
> requirements.
> _But_, it's IBM's issue not Fujitsu's. So, final decistion will depend on you guys.
>
> Anyway, I don't like a too fancy interface as "split".
>
This is a sample configfs for handling memory hotplug.
I wrote this just for my fun and study. code-duplication was not as
big as expected...most of codes are for configfs management.
you can ignore this. but please avoid changing existing interace in fancy way.
==
[root@bluextal kamezawa]# mount -t configfs none /configfs/
[root@bluextal kamezawa]# mkdir /configfs/memory/72
[root@bluextal kamezawa]# cat /configfs/memory/72/phys_index
00000048
[root@bluextal kamezawa]# cat /sys/devices/system/memory/memory72/phys_index
00000048
[root@bluextal kamezawa]# echo offline > /configfs/memory/72/state
[root@bluextal kamezawa]# cat /configfs/memory/72/state
offline
[root@bluextal kamezawa]# cat /sys/devices/system/memory/memory72/state
offline
[root@bluextal kamezawa]# echo online > /configfs/memory/72/state
[root@bluextal kamezawa]# cat /sys/devices/system/memory/memory72/state
online
No sign.
---
drivers/base/Makefile | 2
drivers/base/memory.c | 87 +++++++++++++++++--
drivers/base/memory_config.c | 192 +++++++++++++++++++++++++++++++++++++++++++
include/linux/memory.h | 10 ++
mm/Kconfig | 1
5 files changed, 280 insertions(+), 12 deletions(-)
Index: mmotm-2.6.35-0701/drivers/base/memory.c
===================================================================
--- mmotm-2.6.35-0701.orig/drivers/base/memory.c
+++ mmotm-2.6.35-0701/drivers/base/memory.c
@@ -23,12 +23,15 @@
#include <linux/mutex.h>
#include <linux/stat.h>
#include <linux/slab.h>
+#include <linux/radix-tree.h>
#include <asm/atomic.h>
#include <asm/uaccess.h>
#define MEMORY_CLASS_NAME "memory"
+
+
static struct sysdev_class memory_sysdev_class = {
.name = MEMORY_CLASS_NAME,
};
@@ -104,17 +107,57 @@ unregister_memory(struct memory_block *m
sysdev_unregister(&memory->sysdev);
}
+/* routine for remember memory's status when configs is not used. */
+
+RADIX_TREE(hidden_mems, GFP_KERNEL);
+DEFINE_MUTEX(hidden_mems_mutex);
+int record_memory_state(unsigned long section_nr, int status)
+{
+ int ret = -ENOMEM;
+ long lstat = status << 8; /* for avoid radix'trees special handling */
+ mutex_lock(&hidden_mems_mutex);
+ radix_tree_delete(&hidden_mems, section_nr);
+ if (radix_tree_preload(GFP_KERNEL))
+ goto out;
+ ret = radix_tree_insert(&hidden_mems, section_nr, (void*)lstat);
+ radix_tree_preload_end();
+out:
+ mutex_unlock(&hidden_mems_mutex);
+ return ret;
+}
+
+int lookup_memory_state(unsigned long section_nr)
+{
+ void *ptr;
+ /* we already have big mutex */
+ ptr= radix_tree_lookup(&hidden_mems, section_nr);
+ /* treate not-recorded mems'state as ONLINE...? */
+ return ((long)ptr) >> 8;
+}
+
+void forget_memory_state(unsigned long section_nr)
+{
+ radix_tree_delete(&hidden_mems, section_nr);
+}
+
+
/*
* use this as the physical section index that this memsection
* uses.
*/
+ssize_t show_memoryblock_phys_index(struct memory_block *mem,
+ char *buf)
+{
+ return sprintf(buf, "%08lx\n", mem->phys_index);
+}
+
static ssize_t show_mem_phys_index(struct sys_device *dev,
struct sysdev_attribute *attr, char *buf)
{
struct memory_block *mem =
container_of(dev, struct memory_block, sysdev);
- return sprintf(buf, "%08lx\n", mem->phys_index);
+ return show_memoryblock_phys_index(mem, buf);
}
/*
@@ -136,11 +179,8 @@ static ssize_t show_mem_removable(struct
/*
* online, offline, going offline, etc.
*/
-static ssize_t show_mem_state(struct sys_device *dev,
- struct sysdev_attribute *attr, char *buf)
+ssize_t show_memoryblock_state(struct memory_block *mem, char *buf)
{
- struct memory_block *mem =
- container_of(dev, struct memory_block, sysdev);
ssize_t len = 0;
/*
@@ -167,6 +207,15 @@ static ssize_t show_mem_state(struct sys
return len;
}
+ssize_t show_mem_state(struct sys_device *dev,
+ struct sysdev_attribute *attr, char *buf)
+{
+ struct memory_block *mem =
+ container_of(dev, struct memory_block, sysdev);
+ mem->state = lookup_memory_state(mem->phys_index);
+ return show_memoryblock_state(mem, buf);
+}
+
int memory_notify(unsigned long val, void *v)
{
return blocking_notifier_call_chain(&memory_chain, val, v);
@@ -218,11 +267,14 @@ memory_block_action(struct memory_block
break;
case MEM_OFFLINE:
mem->state = MEM_GOING_OFFLINE;
+ record_memory_state(mem->phys_index, mem->state);
start_paddr = page_to_pfn(first_page) << PAGE_SHIFT;
ret = remove_memory(start_paddr,
PAGES_PER_SECTION << PAGE_SHIFT);
if (ret) {
mem->state = old_state;
+ record_memory_state(mem->phys_index,
+ mem->state);
break;
}
break;
@@ -241,6 +293,8 @@ static int memory_block_change_state(str
int ret = 0;
mutex_lock(&mem->state_mutex);
+ mem->state = lookup_memory_state(mem->phys_index);
+
if (mem->state != from_state_req) {
ret = -EINVAL;
goto out;
@@ -249,21 +303,18 @@ static int memory_block_change_state(str
ret = memory_block_action(mem, to_state);
if (!ret)
mem->state = to_state;
-
+ record_memory_state(mem->phys_index, mem->state);
out:
mutex_unlock(&mem->state_mutex);
return ret;
}
-static ssize_t
-store_mem_state(struct sys_device *dev,
- struct sysdev_attribute *attr, const char *buf, size_t count)
+ssize_t store_memoryblock_state(struct memory_block *mem,
+ const char *buf, size_t count)
{
- struct memory_block *mem;
unsigned int phys_section_nr;
int ret = -EINVAL;
- mem = container_of(dev, struct memory_block, sysdev);
phys_section_nr = mem->phys_index;
if (!present_section_nr(phys_section_nr))
@@ -279,6 +330,16 @@ out:
return count;
}
+static ssize_t
+store_mem_state(struct sys_device *dev,
+ struct sysdev_attribute *attr, const char *buf, size_t count)
+{
+ struct memory_block *mem;
+
+ mem = container_of(dev, struct memory_block, sysdev);
+ return store_memoryblock_state(mem, buf, count);
+}
+
/*
* phys_device is a bad name for this. What I really want
* is a way to differentiate between memory ranges that
@@ -451,6 +512,8 @@ static int add_memory_block(int nid, str
start_pfn = section_nr_to_pfn(mem->phys_index);
mem->phys_device = arch_get_memory_phys_device(start_pfn);
+ record_memory_state(mem->phys_index, state);
+
ret = register_memory(mem, section);
if (!ret)
ret = mem_create_simple_file(mem, phys_index);
@@ -505,6 +568,7 @@ int remove_memory_block(unsigned long no
struct memory_block *mem;
mem = find_memory_block(section);
+ forget_memory_state(mem->phys_index);
unregister_mem_sect_under_nodes(mem);
mem_remove_simple_file(mem, phys_index);
mem_remove_simple_file(mem, state);
@@ -573,3 +637,4 @@ out:
printk(KERN_ERR "%s() failed: %d\n", __func__, ret);
return ret;
}
+
Index: mmotm-2.6.35-0701/drivers/base/memory_config.c
===================================================================
--- /dev/null
+++ mmotm-2.6.35-0701/drivers/base/memory_config.c
@@ -0,0 +1,192 @@
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/memory.h>
+#include <linux/slab.h>
+#include <linux/radix-tree.h>
+#include <linux/configfs.h>
+
+
+
+struct memory_hp_block {
+ struct config_group group;
+ struct memory_block mb;
+};
+struct memory_hp_attribute {
+ struct configfs_attribute attr;
+ ssize_t (*show)(struct memory_hp_block *, char *);
+ ssize_t (*store)(struct memory_hp_block *, const char *);
+};
+
+static struct memory_hp_block *to_mhp_block(struct config_item *item)
+{
+ if (!item)
+ return NULL;
+ return container_of(to_config_group(item),
+ struct memory_hp_block, group);
+}
+
+static ssize_t
+memory_hp_phys_index_read(struct memory_hp_block *mhb, char *page)
+{
+ return show_memoryblock_phys_index(&mhb->mb, page);
+}
+
+static struct memory_hp_attribute memory_hp_phys_index = {
+ .attr = { .ca_owner = THIS_MODULE,
+ .ca_name = "phys_index",
+ .ca_mode = S_IRUGO },
+ .show = memory_hp_phys_index_read,
+};
+
+static ssize_t
+memory_hp_state_read(struct memory_hp_block *mhb, char *page)
+{
+ /* synchronize */
+ printk("lookup section %ld\n", mhb->mb.phys_index);
+ mhb->mb.state = lookup_memory_state(mhb->mb.phys_index);
+ return show_memoryblock_state(&mhb->mb, page);
+}
+
+static ssize_t
+memory_hp_state_store(struct memory_hp_block *mhb, const char *page)
+{
+ int len = strnlen(page, 8);
+ printk("length %d str %s\n", len, page);
+ if (len > 8) /* online/offline */
+ return -EINVAL;
+ /* synchronize */
+ mhb->mb.state = lookup_memory_state(mhb->mb.phys_index);
+ return store_memoryblock_state(&mhb->mb, page, len);
+}
+
+static struct memory_hp_attribute memory_hp_state = {
+ .attr = { .ca_owner = THIS_MODULE,
+ .ca_name = "state",
+ .ca_mode = S_IRUGO|S_IWUSR },
+ .show = memory_hp_state_read,
+ .store = memory_hp_state_store,
+};
+
+static struct configfs_attribute *memory_hp_attrs[] = {
+ &memory_hp_phys_index.attr,
+ &memory_hp_state.attr,
+ NULL,
+};
+
+static ssize_t memory_hp_attr_show(struct config_item *item,
+ struct configfs_attribute *attr,
+ char *page)
+{
+ struct memory_hp_block *mhb = to_mhp_block(item);
+ struct memory_hp_attribute *memhp_attr =
+ container_of(attr, struct memory_hp_attribute, attr);
+ ssize_t ret = 0;
+
+ if (memhp_attr->show)
+ ret = memhp_attr->show(mhb, page);
+ return ret;
+}
+
+static ssize_t memory_hp_attr_store(struct config_item *item,
+ struct configfs_attribute *attr,
+ const char *page, size_t count)
+{
+ struct memory_hp_block *mhb = to_mhp_block(item);
+ struct memory_hp_attribute *memhp_attr =
+ container_of(attr, struct memory_hp_attribute, attr);
+ ssize_t ret = 0;
+
+ if (memhp_attr->store)
+ ret = memhp_attr->store(mhb, page);
+ else
+ ret = -EINVAL;
+ return ret;
+}
+
+static struct configfs_item_operations memory_hp_item_ops = {
+ .show_attribute = memory_hp_attr_show,
+ .store_attribute = memory_hp_attr_store,
+};
+
+static struct config_item_type memory_hp_type = {
+ .ct_item_ops = &memory_hp_item_ops,
+ .ct_attrs = memory_hp_attrs,
+ .ct_owner = THIS_MODULE,
+};
+
+static struct config_group *
+memory_hp_make_group(struct config_group *group, const char *name)
+{
+ struct memory_hp_block *mhb;
+ unsigned long long section_id;
+
+
+ if (strict_strtoull(name, 10, §ion_id))
+ return ERR_PTR(-EINVAL);
+
+ if (!valid_section_nr(section_id))
+ return ERR_PTR(-EINVAL);
+
+ mhb = kzalloc(sizeof(*mhb), GFP_KERNEL);
+ if (!mhb)
+ return NULL;
+
+ config_group_init_type_name(&mhb->group, name, &memory_hp_type);
+
+ mhb->mb.phys_index = section_id;
+ mutex_init(&mhb->mb.state_mutex);
+ mhb->mb.state = lookup_memory_state(section_id);
+
+ return &mhb->group;
+}
+
+static void memory_hp_drop_item(struct config_group *group,
+ struct config_item *item)
+{
+ struct memory_hp_block *mhb;
+
+ mhb = container_of(group, struct memory_hp_block, group);
+ config_item_put(item);
+}
+
+static struct configfs_group_operations memory_hp_group_ops = {
+ .make_group = memory_hp_make_group,
+ .drop_item = memory_hp_drop_item,
+};
+
+static struct config_item_type memory_hp_subsys_type = {
+ .ct_group_ops = &memory_hp_group_ops,
+ .ct_owner = THIS_MODULE,
+};
+
+static struct configfs_subsystem memory_hp_subsys = {
+ .su_group = {
+ .cg_item = {
+ .ci_namebuf = "memory",
+ .ci_type = &memory_hp_subsys_type,
+ },
+ },
+};
+
+static int __init memory_config_init(void)
+{
+ int ret;
+
+ config_group_init(&memory_hp_subsys.su_group);
+ mutex_init(&memory_hp_subsys.su_mutex);
+ ret = configfs_register_subsystem(&memory_hp_subsys);
+ if (ret) {
+ printk(KERN_ERR "Error %d while registering memory configfs\n", ret);
+ return ret;
+ }
+ return 0;
+}
+
+#if 0
+static void __exit memory_config_exit(void)
+{
+ configfs_unregister_subsystem(&memory_hp_subsys);
+}
+#endif
+late_initcall(memory_config_init);
Index: mmotm-2.6.35-0701/drivers/base/Makefile
===================================================================
--- mmotm-2.6.35-0701.orig/drivers/base/Makefile
+++ mmotm-2.6.35-0701/drivers/base/Makefile
@@ -11,7 +11,7 @@ obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT)
obj-$(CONFIG_ISA) += isa.o
obj-$(CONFIG_FW_LOADER) += firmware_class.o
obj-$(CONFIG_NUMA) += node.o
-obj-$(CONFIG_MEMORY_HOTPLUG_SPARSE) += memory.o
+obj-$(CONFIG_MEMORY_HOTPLUG_SPARSE) += memory.o memory_config.o
obj-$(CONFIG_SMP) += topology.o
obj-$(CONFIG_IOMMU_API) += iommu.o
ifeq ($(CONFIG_SYSFS),y)
Index: mmotm-2.6.35-0701/mm/Kconfig
===================================================================
--- mmotm-2.6.35-0701.orig/mm/Kconfig
+++ mmotm-2.6.35-0701/mm/Kconfig
@@ -138,6 +138,7 @@ config MEMORY_HOTPLUG
config MEMORY_HOTPLUG_SPARSE
def_bool y
depends on SPARSEMEM && MEMORY_HOTPLUG
+ select CONFIGFS_FS
config MEMORY_HOTREMOVE
bool "Allow for memory hot remove"
Index: mmotm-2.6.35-0701/include/linux/memory.h
===================================================================
--- mmotm-2.6.35-0701.orig/include/linux/memory.h
+++ mmotm-2.6.35-0701/include/linux/memory.h
@@ -68,6 +68,16 @@ struct memory_isolate_notify {
struct notifier_block;
struct mem_section;
+
+ssize_t show_memoryblock_phys_index(struct memory_block *mb, char *buf);
+ssize_t show_memoryblock_state(struct memory_block *mb, char *buf);
+ssize_t store_memoryblock_state(struct memory_block *mb,
+ const char *buf, size_t count);
+
+int record_memory_state(unsigned long section, int state);
+int lookup_memory_state(unsigned long section);
+void forget_memory_state(unsigned long section);
+
/*
* Priorities for the hotplug memory callback routines (stored in decreasing
* order in the callback chain)
^ permalink raw reply
* cpm_uart_console_write() stuck in waiting for transmitter fifo ready
From: Shawn Jin @ 2010-07-14 9:05 UTC (permalink / raw)
To: ppcdev, galak, panto, Scott Wood
Hi Gurus,
Please give me some hints and directions to debug this problem. I've
been scratching my head for quite a while.
The problem is that after/when the kernel switches to the real console
from the boot console, printk() calls cpm_uart_console_write() to
print the first (?) message using the cpm_uart driver. But the
transmitter buffer never becomes ready. It's shown below with the gdb
session.
Program received signal SIGSTOP, Stopped (signal).
0xc00f3510 in cpm_uart_console_write (co=3D<value optimized out>,
s=3D0xc017703e "console [ttyCPM0] enabled, bootconsole disabled\n",
count=3D0x30) at /home/code/linux-2.6.33.5/arch/powerpc/include/asm/io.h:15=
4
(gdb) next
(gdb) x/4h bdbase
0xfddfa020: 0xffff 0xffff 0xffff 0xffff
(gdb)
Why would the TxBD be filled with all 0xF? Would it be possible that
the bdbase actually points somewhere else other than the TxBD?
The kernel boot messages are copied below. My target is MPC870, using
SMC1 as UART. I'm porting the kernel based on adder875 board.
=3D> bootm 1000000
## Booting image at 01000000 ...
Image Name: Linux-2.6.33.5
Image Type: PowerPC Linux Kernel Image (gzip compressed)
Data Size: 706700 Bytes =3D 690.1 kB
Load Address: 00400000
Entry Point: 00400554
Verifying Checksum ... OK
Uncompressing Kernel Image ... OK
Memory <- <0x0 0x8000000> (128MB)
ENET0: local-mac-address <- 00:09:9b:01:58:64
CPU clock-frequency <- 0x7270e00 (120MHz)
CPU timebase-frequency <- 0x7270e0 (8MHz)
CPU bus-frequency <- 0x3938700 (60MHz)
zImage starting: loaded at 0x00400000 (sp: 0x07d1cbd0)
Allocating 0x186be5 bytes for kernel ...
gunzipping (0x00000000 <- 0x0040c000:0x005c1b78)...done 0x173b10 bytes
Linux/PowerPC load: root=3D/dev/ram
Finalizing device tree... flat tree at 0x5ce300
Probing machine type ...
My MPC870 ... match !
id mach(): done
MMU:enter
MMU:hw init
MMU:mapin
MMU:setio
MMU:exit
Using My MPC870 machine description
Linux version 2.6.33.5 (shawn@ubuntu) (gcc version 4.2.2) #17 Wed Jul
14 01:24:03 PDT 2010
bootconsole [udbg0] enabled
setup_arch: bootmem
arch: exit
Top of RAM: 0x8000000, Total RAM: 0x8000000
Memory hole size: 0MB
Zone PFN ranges:
DMA 0x00000000 -> 0x00008000
Normal 0x00008000 -> 0x00008000
Movable zone start PFN for each node
early_node_map[1] active PFN ranges
0: 0x00000000 -> 0x00008000
On node 0 totalpages: 32768
free_area_init_node: node 0, pgdat c016b5b0, node_mem_map c0189000
DMA zone: 256 pages used for memmap
DMA zone: 0 pages reserved
DMA zone: 32512 pages, LIFO batch:7
MMU: Allocated 72 bytes of context maps for 16 contexts
Built 1 zonelists in Zone order, mobility grouping on. Total pages: 32512
Kernel command line: root=3D/dev/ram
PID hash table entries: 512 (order: -1, 2048 bytes)
Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)
Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
Memory: 128096k/131072k available (1416k kernel code, 2836k reserved,
72k data, 74k bss, 76k init)
Kernel virtual memory layout:
* 0xfffdf000..0xfffff000 : fixmap
* 0xfde00000..0xfe000000 : consistent mem
* 0xfddfa000..0xfde00000 : early ioremap
* 0xc9000000..0xfddfa000 : vmalloc & ioremap
SLUB: Genslabs=3D12, HWalign=3D16, Order=3D0-3, MinObjects=3D0, CPUs=3D1, N=
odes=3D1
Hierarchical RCU implementation.
NR_IRQS:512 nr_irqs:512
irq: Allocated host of type 2 @0xc7804000
irq: irq_create_mapping(0xc7804000, 0x5)
irq: -> using host @c7804000
alloc irq_desc for 16 on node 0
alloc kstat_irqs on node 0
irq: irq 5 on host /soc@fa200000/interrupt-controller@0 mapped to virtual i=
rq 16
irq: Allocated host of type 2 @0xc7804200
irq: irq_create_mapping(0xc7804200, 0x0)
irq: -> using host @c7804200
alloc irq_desc for 17 on node 0
alloc kstat_irqs on node 0
irq: irq 0 on host /soc@fa200000/cpm@9c0/interrupt-controller@930
mapped to virtual irq 17
Decrementer Frequency =3D 0x7270e0
irq: irq_create_mapping(0xc7804000, 0xf)
irq: -> using host @c7804000
alloc irq_desc for 18 on node 0
alloc kstat_irqs on node 0
irq: irq 15 on host /soc@fa200000/interrupt-controller@0 mapped to
virtual irq 18
time_init: decrementer frequency =3D 7.500000 MHz
time_init: processor frequency =3D 120.000000 MHz
clocksource: timebase mult[21555555] shift[22] registered
clockevent: decrementer mult[1eb851e] shift[32] cpu[0]
irq: irq_create_mapping(0xc7804200, 0x4)
irq: -> using host @c7804200
alloc irq_desc for 19 on node 0
alloc kstat_irqs on node 0
irq: irq 4 on host /soc@fa200000/cpm@9c0/interrupt-controller@930
mapped to virtual irq 1=EF=BF=BD
Thanks a lot,
-Shawn.
^ permalink raw reply
* Re: [PATCH] powerpc:prom Export device tree physical address via proc
From: Segher Boessenkool @ 2010-07-14 12:51 UTC (permalink / raw)
To: Timur Tabi; +Cc: Matthew McClintock, linuxppc-dev
In-Reply-To: <4C3CB69D.4060400@freescale.com>
>> + if (prop)
>> + prom_remove_property(node, prop);
>> + prop = of_find_property(node, "linux,devietree-end", NULL);
>
> Either the indentation is wrong, or you're missing some braces here
You're missing a "c" as well (and a dash).
Segher
^ permalink raw reply
* [PATCH 0/8] sdhci: Move real work out of an atomic context
From: Anton Vorontsov @ 2010-07-14 13:07 UTC (permalink / raw)
To: Andrew Morton
Cc: Matt Fleming, Albert Herranz, linux-mmc, linux-kernel,
linuxppc-dev, Ben Dooks, Pierre Ossman
Hi all,
Currently the sdhci driver does everything in the atomic context.
And what is worse, PIO transfers are made from the IRQ handler.
This causes huge latencies (up to 120 ms). On some P2020 SOCs,
DMA and card detection is broken, which means that kernel polls
for the card via PIO transfers every second. Needless to say
that this is quite bad.
So, this patch set reworks sdhci code to avoid atomic context,
almost completely. We only do two device memory operations
in the atomic context, and all the rest is threaded.
I noticed no throughput drop neither with PIO transfers nor
with DMA (tested on MPC8569E CPU), while latencies should be
greatly improved.
Thanks,
--
Anton Vorontsov
email: cbouatmailru@gmail.com
irc://irc.freenode.net/bd2
^ permalink raw reply
* [PATCH 1/8] sdhci: Turn timeout timer into delayed work
From: Anton Vorontsov @ 2010-07-14 13:07 UTC (permalink / raw)
To: Andrew Morton
Cc: Matt Fleming, Albert Herranz, linux-mmc, linux-kernel,
linuxppc-dev, Ben Dooks, Pierre Ossman
In-Reply-To: <20100714130728.GA27339@oksana.dev.rtsoft.ru>
There is no need for the timeout handler to run in the atomic
context, so this patch turns timeout timeout into the delayed
work.
Note that the timeout handler still grabs an irqsave spinlock,
we'll deal with it in a separate patch.
Signed-off-by: Anton Vorontsov <avorontsov@mvista.com>
---
drivers/mmc/host/sdhci.c | 14 ++++++++------
drivers/mmc/host/sdhci.h | 3 ++-
2 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index c6d1bd8..dc6328c 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -13,6 +13,8 @@
* - JMicron (hardware and technical support)
*/
+#include <linux/kernel.h>
+#include <linux/workqueue.h>
#include <linux/delay.h>
#include <linux/highmem.h>
#include <linux/io.h>
@@ -906,7 +908,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
mdelay(1);
}
- mod_timer(&host->timer, jiffies + 10 * HZ);
+ schedule_delayed_work(&host->timeout_work, 10 * HZ);
host->cmd = cmd;
@@ -1280,7 +1282,7 @@ static void sdhci_tasklet_finish(unsigned long param)
spin_lock_irqsave(&host->lock, flags);
- del_timer(&host->timer);
+ __cancel_delayed_work(&host->timeout_work);
mrq = host->mrq;
@@ -1324,12 +1326,12 @@ static void sdhci_tasklet_finish(unsigned long param)
mmc_request_done(host->mmc, mrq);
}
-static void sdhci_timeout_timer(unsigned long data)
+static void sdhci_timeout_work(struct work_struct *wk)
{
struct sdhci_host *host;
unsigned long flags;
- host = (struct sdhci_host*)data;
+ host = container_of(wk, struct sdhci_host, timeout_work.work);
spin_lock_irqsave(&host->lock, flags);
@@ -1877,7 +1879,7 @@ int sdhci_add_host(struct sdhci_host *host)
tasklet_init(&host->finish_tasklet,
sdhci_tasklet_finish, (unsigned long)host);
- setup_timer(&host->timer, sdhci_timeout_timer, (unsigned long)host);
+ INIT_DELAYED_WORK(&host->timeout_work, sdhci_timeout_work);
ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
mmc_hostname(mmc), host);
@@ -1963,7 +1965,7 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
free_irq(host->irq, host);
- del_timer_sync(&host->timer);
+ flush_delayed_work(&host->timeout_work);
tasklet_kill(&host->card_tasklet);
tasklet_kill(&host->finish_tasklet);
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index c846813..55c114d 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -12,6 +12,7 @@
#define __SDHCI_H
#include <linux/scatterlist.h>
+#include <linux/workqueue.h>
#include <linux/compiler.h>
#include <linux/types.h>
#include <linux/io.h>
@@ -290,7 +291,7 @@ struct sdhci_host {
struct tasklet_struct card_tasklet; /* Tasklet structures */
struct tasklet_struct finish_tasklet;
- struct timer_list timer; /* Timer for timeouts */
+ struct delayed_work timeout_work; /* Work for timeouts */
unsigned long private[0] ____cacheline_aligned;
};
--
1.7.0.5
^ permalink raw reply related
* [PATCH 2/8] sdhci: Use work structs instead of tasklets
From: Anton Vorontsov @ 2010-07-14 13:07 UTC (permalink / raw)
To: Andrew Morton
Cc: Matt Fleming, Albert Herranz, linux-mmc, linux-kernel,
linuxppc-dev, Ben Dooks, Pierre Ossman
In-Reply-To: <20100714130728.GA27339@oksana.dev.rtsoft.ru>
The driver can happily live without an atomic context and tasklets,
so turn the tasklets into the work structs.
Tasklets handlers still grab irqsave spinlocks, but we'll deal
with it in a separate patch.
Signed-off-by: Anton Vorontsov <avorontsov@mvista.com>
---
drivers/mmc/host/sdhci.c | 48 ++++++++++++++++++++-------------------------
drivers/mmc/host/sdhci.h | 4 +-
2 files changed, 23 insertions(+), 29 deletions(-)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index dc6328c..748a2e3 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -872,7 +872,7 @@ static void sdhci_finish_data(struct sdhci_host *host)
sdhci_send_command(host, data->stop);
} else
- tasklet_schedule(&host->finish_tasklet);
+ schedule_work(&host->finish_work);
}
static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
@@ -901,7 +901,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
"inhibit bit(s).\n", mmc_hostname(host->mmc));
sdhci_dumpregs(host);
cmd->error = -EIO;
- tasklet_schedule(&host->finish_tasklet);
+ schedule_work(&host->finish_work);
return;
}
timeout--;
@@ -922,7 +922,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
printk(KERN_ERR "%s: Unsupported response type!\n",
mmc_hostname(host->mmc));
cmd->error = -EINVAL;
- tasklet_schedule(&host->finish_tasklet);
+ schedule_work(&host->finish_work);
return;
}
@@ -973,7 +973,7 @@ static void sdhci_finish_command(struct sdhci_host *host)
sdhci_finish_data(host);
if (!host->cmd->data)
- tasklet_schedule(&host->finish_tasklet);
+ schedule_work(&host->finish_work);
host->cmd = NULL;
}
@@ -1122,7 +1122,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
if (!present || host->flags & SDHCI_DEVICE_DEAD) {
host->mrq->cmd->error = -ENOMEDIUM;
- tasklet_schedule(&host->finish_tasklet);
+ schedule_work(&host->finish_work);
} else
sdhci_send_command(host, mrq->cmd);
@@ -1239,16 +1239,16 @@ static const struct mmc_host_ops sdhci_ops = {
/*****************************************************************************\
* *
- * Tasklets *
+ * Work handlers *
* *
\*****************************************************************************/
-static void sdhci_tasklet_card(unsigned long param)
+static void sdhci_card_detect_work(struct work_struct *wk)
{
struct sdhci_host *host;
unsigned long flags;
- host = (struct sdhci_host*)param;
+ host = container_of(wk, struct sdhci_host, card_detect_work);
spin_lock_irqsave(&host->lock, flags);
@@ -1263,7 +1263,7 @@ static void sdhci_tasklet_card(unsigned long param)
sdhci_reset(host, SDHCI_RESET_DATA);
host->mrq->cmd->error = -ENOMEDIUM;
- tasklet_schedule(&host->finish_tasklet);
+ schedule_work(&host->finish_work);
}
}
@@ -1272,13 +1272,13 @@ static void sdhci_tasklet_card(unsigned long param)
mmc_detect_change(host->mmc, msecs_to_jiffies(200));
}
-static void sdhci_tasklet_finish(unsigned long param)
+static void sdhci_finish_work(struct work_struct *wk)
{
struct sdhci_host *host;
unsigned long flags;
struct mmc_request *mrq;
- host = (struct sdhci_host*)param;
+ host = container_of(wk, struct sdhci_host, finish_work);
spin_lock_irqsave(&host->lock, flags);
@@ -1349,7 +1349,7 @@ static void sdhci_timeout_work(struct work_struct *wk)
else
host->mrq->cmd->error = -ETIMEDOUT;
- tasklet_schedule(&host->finish_tasklet);
+ schedule_work(&host->finish_work);
}
}
@@ -1382,7 +1382,7 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask)
host->cmd->error = -EILSEQ;
if (host->cmd->error) {
- tasklet_schedule(&host->finish_tasklet);
+ schedule_work(&host->finish_work);
return;
}
@@ -1528,7 +1528,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT |
SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS);
- tasklet_schedule(&host->card_tasklet);
+ schedule_work(&host->card_detect_work);
}
intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE);
@@ -1872,19 +1872,17 @@ int sdhci_add_host(struct sdhci_host *host)
mmc->max_blk_count = (host->quirks & SDHCI_QUIRK_NO_MULTIBLOCK) ? 1 : 65535;
/*
- * Init tasklets.
+ * Init work structs.
*/
- tasklet_init(&host->card_tasklet,
- sdhci_tasklet_card, (unsigned long)host);
- tasklet_init(&host->finish_tasklet,
- sdhci_tasklet_finish, (unsigned long)host);
+ INIT_WORK(&host->card_detect_work, sdhci_card_detect_work);
+ INIT_WORK(&host->finish_work, sdhci_finish_work);
INIT_DELAYED_WORK(&host->timeout_work, sdhci_timeout_work);
ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
mmc_hostname(mmc), host);
if (ret)
- goto untasklet;
+ return ret;
sdhci_init(host, 0);
@@ -1923,10 +1921,6 @@ reset:
sdhci_reset(host, SDHCI_RESET_ALL);
free_irq(host->irq, host);
#endif
-untasklet:
- tasklet_kill(&host->card_tasklet);
- tasklet_kill(&host->finish_tasklet);
-
return ret;
}
@@ -1946,7 +1940,7 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
" transfer!\n", mmc_hostname(host->mmc));
host->mrq->cmd->error = -ENOMEDIUM;
- tasklet_schedule(&host->finish_tasklet);
+ schedule_work(&host->finish_work);
}
spin_unlock_irqrestore(&host->lock, flags);
@@ -1967,8 +1961,8 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
flush_delayed_work(&host->timeout_work);
- tasklet_kill(&host->card_tasklet);
- tasklet_kill(&host->finish_tasklet);
+ flush_work(&host->card_detect_work);
+ flush_work(&host->finish_work);
kfree(host->adma_desc);
kfree(host->align_buffer);
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 55c114d..d96e4dd 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -288,8 +288,8 @@ struct sdhci_host {
dma_addr_t adma_addr; /* Mapped ADMA descr. table */
dma_addr_t align_addr; /* Mapped bounce buffer */
- struct tasklet_struct card_tasklet; /* Tasklet structures */
- struct tasklet_struct finish_tasklet;
+ struct work_struct card_detect_work;
+ struct work_struct finish_work;
struct delayed_work timeout_work; /* Work for timeouts */
--
1.7.0.5
^ permalink raw reply related
* [PATCH 3/8] sdhci: Clear interrupt status register just once
From: Anton Vorontsov @ 2010-07-14 13:08 UTC (permalink / raw)
To: Andrew Morton
Cc: Matt Fleming, Albert Herranz, linux-mmc, linux-kernel,
linuxppc-dev, Ben Dooks, Pierre Ossman
In-Reply-To: <20100714130728.GA27339@oksana.dev.rtsoft.ru>
There's no need to clear the interrupt status register bit-by-bit,
we can just clear it once. This simplifies irq handler.
Signed-off-by: Anton Vorontsov <avorontsov@mvista.com>
---
drivers/mmc/host/sdhci.c | 23 ++++++-----------------
1 files changed, 6 insertions(+), 17 deletions(-)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 748a2e3..9ec245c 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1522,38 +1522,29 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
goto out;
}
+ sdhci_writel(host, intmask, SDHCI_INT_STATUS);
+
DBG("*** %s got interrupt: 0x%08x\n",
mmc_hostname(host->mmc), intmask);
- if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
- sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT |
- SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS);
+ if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE))
schedule_work(&host->card_detect_work);
- }
intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE);
- if (intmask & SDHCI_INT_CMD_MASK) {
- sdhci_writel(host, intmask & SDHCI_INT_CMD_MASK,
- SDHCI_INT_STATUS);
+ if (intmask & SDHCI_INT_CMD_MASK)
sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
- }
- if (intmask & SDHCI_INT_DATA_MASK) {
- sdhci_writel(host, intmask & SDHCI_INT_DATA_MASK,
- SDHCI_INT_STATUS);
+ if (intmask & SDHCI_INT_DATA_MASK)
sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
- }
intmask &= ~(SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK);
intmask &= ~SDHCI_INT_ERROR;
- if (intmask & SDHCI_INT_BUS_POWER) {
+ if (intmask & SDHCI_INT_BUS_POWER)
printk(KERN_ERR "%s: Card is consuming too much power!\n",
mmc_hostname(host->mmc));
- sdhci_writel(host, SDHCI_INT_BUS_POWER, SDHCI_INT_STATUS);
- }
intmask &= ~SDHCI_INT_BUS_POWER;
@@ -1566,8 +1557,6 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
printk(KERN_ERR "%s: Unexpected interrupt 0x%08x.\n",
mmc_hostname(host->mmc), intmask);
sdhci_dumpregs(host);
-
- sdhci_writel(host, intmask, SDHCI_INT_STATUS);
}
result = IRQ_HANDLED;
--
1.7.0.5
^ permalink raw reply related
* [PATCH 4/8] sdhci: Use threaded IRQ handler
From: Anton Vorontsov @ 2010-07-14 13:08 UTC (permalink / raw)
To: Andrew Morton
Cc: Matt Fleming, Albert Herranz, linux-mmc, linux-kernel,
linuxppc-dev, Ben Dooks, Pierre Ossman
In-Reply-To: <20100714130728.GA27339@oksana.dev.rtsoft.ru>
We only need atomic context to disable SDHCI interrupts, after that
we can run in a kernel thread.
Note that irq handler still grabs an irqsave spinlock, we'll deal
with it in a subsequent patch.
Signed-off-by: Anton Vorontsov <avorontsov@mvista.com>
---
drivers/mmc/host/sdhci.c | 47 +++++++++++++++++++++++++++------------------
1 files changed, 28 insertions(+), 19 deletions(-)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 9ec245c..0358b35 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1506,9 +1506,8 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
}
}
-static irqreturn_t sdhci_irq(int irq, void *dev_id)
+static irqreturn_t sdhci_irq_thread(int irq, void *dev_id)
{
- irqreturn_t result;
struct sdhci_host* host = dev_id;
u32 intmask;
int cardint = 0;
@@ -1516,17 +1515,8 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
spin_lock(&host->lock);
intmask = sdhci_readl(host, SDHCI_INT_STATUS);
-
- if (!intmask || intmask == 0xffffffff) {
- result = IRQ_NONE;
- goto out;
- }
-
sdhci_writel(host, intmask, SDHCI_INT_STATUS);
- DBG("*** %s got interrupt: 0x%08x\n",
- mmc_hostname(host->mmc), intmask);
-
if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE))
schedule_work(&host->card_detect_work);
@@ -1559,10 +1549,8 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
sdhci_dumpregs(host);
}
- result = IRQ_HANDLED;
-
mmiowb();
-out:
+
spin_unlock(&host->lock);
/*
@@ -1571,7 +1559,28 @@ out:
if (cardint)
mmc_signal_sdio_irq(host->mmc);
- return result;
+ /* Restore interrupts */
+ intmask = sdhci_readl(host, SDHCI_INT_ENABLE);
+ sdhci_writel(host, intmask, SDHCI_SIGNAL_ENABLE);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t sdhci_irq(int irq, void *dev_id)
+{
+ struct sdhci_host *host = dev_id;
+ u32 intmask = sdhci_readl(host, SDHCI_INT_STATUS);
+
+ if (!intmask || intmask == 0xffffffff)
+ return IRQ_NONE;
+
+ /* Disable interrupts */
+ sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
+
+ DBG("*** %s got interrupt: 0x%08x\n",
+ mmc_hostname(host->mmc), intmask);
+
+ return IRQ_WAKE_THREAD;
}
/*****************************************************************************\
@@ -1608,8 +1617,8 @@ int sdhci_resume_host(struct sdhci_host *host)
host->ops->enable_dma(host);
}
- ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
- mmc_hostname(host->mmc), host);
+ ret = request_threaded_irq(host->irq, sdhci_irq, sdhci_irq_thread,
+ IRQF_SHARED, mmc_hostname(host->mmc), host);
if (ret)
return ret;
@@ -1868,8 +1877,8 @@ int sdhci_add_host(struct sdhci_host *host)
INIT_DELAYED_WORK(&host->timeout_work, sdhci_timeout_work);
- ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
- mmc_hostname(mmc), host);
+ ret = request_threaded_irq(host->irq, sdhci_irq, sdhci_irq_thread,
+ IRQF_SHARED, mmc_hostname(host->mmc), host);
if (ret)
return ret;
--
1.7.0.5
^ permalink raw reply related
* [PATCH 5/8] sdhci: Turn host->lock into a mutex
From: Anton Vorontsov @ 2010-07-14 13:08 UTC (permalink / raw)
To: Andrew Morton
Cc: Matt Fleming, Albert Herranz, linux-mmc, linux-kernel,
linuxppc-dev, Ben Dooks, Pierre Ossman
In-Reply-To: <20100714130728.GA27339@oksana.dev.rtsoft.ru>
Finally, we can get rid of the host->lock spinlock, and turn it
into a mutex.
This patch does just this.
Signed-off-by: Anton Vorontsov <avorontsov@mvista.com>
---
drivers/mmc/host/sdhci.c | 53 +++++++++++++++++++--------------------------
drivers/mmc/host/sdhci.h | 3 +-
2 files changed, 24 insertions(+), 32 deletions(-)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 0358b35..5eddbdb 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -20,6 +20,7 @@
#include <linux/io.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
+#include <linux/mutex.h>
#include <linux/scatterlist.h>
#include <linux/leds.h>
@@ -228,16 +229,15 @@ static void sdhci_led_control(struct led_classdev *led,
enum led_brightness brightness)
{
struct sdhci_host *host = container_of(led, struct sdhci_host, led);
- unsigned long flags;
- spin_lock_irqsave(&host->lock, flags);
+ mutex_lock(&host->lock);
if (brightness == LED_OFF)
sdhci_deactivate_led(host);
else
sdhci_activate_led(host);
- spin_unlock_irqrestore(&host->lock, flags);
+ mutex_unlock(&host->lock);
}
#endif
@@ -1099,11 +1099,10 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
{
struct sdhci_host *host;
bool present;
- unsigned long flags;
host = mmc_priv(mmc);
- spin_lock_irqsave(&host->lock, flags);
+ mutex_lock(&host->lock);
WARN_ON(host->mrq != NULL);
@@ -1127,18 +1126,17 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
sdhci_send_command(host, mrq->cmd);
mmiowb();
- spin_unlock_irqrestore(&host->lock, flags);
+ mutex_unlock(&host->lock);
}
static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
struct sdhci_host *host;
- unsigned long flags;
u8 ctrl;
host = mmc_priv(mmc);
- spin_lock_irqsave(&host->lock, flags);
+ mutex_lock(&host->lock);
if (host->flags & SDHCI_DEVICE_DEAD)
goto out;
@@ -1183,25 +1181,24 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
out:
mmiowb();
- spin_unlock_irqrestore(&host->lock, flags);
+ mutex_unlock(&host->lock);
}
static int sdhci_get_ro(struct mmc_host *mmc)
{
struct sdhci_host *host;
- unsigned long flags;
int present;
host = mmc_priv(mmc);
- spin_lock_irqsave(&host->lock, flags);
+ mutex_lock(&host->lock);
if (host->flags & SDHCI_DEVICE_DEAD)
present = 0;
else
present = sdhci_readl(host, SDHCI_PRESENT_STATE);
- spin_unlock_irqrestore(&host->lock, flags);
+ mutex_unlock(&host->lock);
if (host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT)
return !!(present & SDHCI_WRITE_PROTECT);
@@ -1211,11 +1208,10 @@ static int sdhci_get_ro(struct mmc_host *mmc)
static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
{
struct sdhci_host *host;
- unsigned long flags;
host = mmc_priv(mmc);
- spin_lock_irqsave(&host->lock, flags);
+ mutex_lock(&host->lock);
if (host->flags & SDHCI_DEVICE_DEAD)
goto out;
@@ -1227,7 +1223,7 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
out:
mmiowb();
- spin_unlock_irqrestore(&host->lock, flags);
+ mutex_unlock(&host->lock);
}
static const struct mmc_host_ops sdhci_ops = {
@@ -1246,11 +1242,10 @@ static const struct mmc_host_ops sdhci_ops = {
static void sdhci_card_detect_work(struct work_struct *wk)
{
struct sdhci_host *host;
- unsigned long flags;
host = container_of(wk, struct sdhci_host, card_detect_work);
- spin_lock_irqsave(&host->lock, flags);
+ mutex_lock(&host->lock);
if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
if (host->mrq) {
@@ -1267,7 +1262,7 @@ static void sdhci_card_detect_work(struct work_struct *wk)
}
}
- spin_unlock_irqrestore(&host->lock, flags);
+ mutex_unlock(&host->lock);
mmc_detect_change(host->mmc, msecs_to_jiffies(200));
}
@@ -1275,12 +1270,11 @@ static void sdhci_card_detect_work(struct work_struct *wk)
static void sdhci_finish_work(struct work_struct *wk)
{
struct sdhci_host *host;
- unsigned long flags;
struct mmc_request *mrq;
host = container_of(wk, struct sdhci_host, finish_work);
- spin_lock_irqsave(&host->lock, flags);
+ mutex_lock(&host->lock);
__cancel_delayed_work(&host->timeout_work);
@@ -1321,7 +1315,7 @@ static void sdhci_finish_work(struct work_struct *wk)
#endif
mmiowb();
- spin_unlock_irqrestore(&host->lock, flags);
+ mutex_unlock(&host->lock);
mmc_request_done(host->mmc, mrq);
}
@@ -1329,11 +1323,10 @@ static void sdhci_finish_work(struct work_struct *wk)
static void sdhci_timeout_work(struct work_struct *wk)
{
struct sdhci_host *host;
- unsigned long flags;
host = container_of(wk, struct sdhci_host, timeout_work.work);
- spin_lock_irqsave(&host->lock, flags);
+ mutex_lock(&host->lock);
if (host->mrq) {
printk(KERN_ERR "%s: Timeout waiting for hardware "
@@ -1354,7 +1347,7 @@ static void sdhci_timeout_work(struct work_struct *wk)
}
mmiowb();
- spin_unlock_irqrestore(&host->lock, flags);
+ mutex_unlock(&host->lock);
}
/*****************************************************************************\
@@ -1512,7 +1505,7 @@ static irqreturn_t sdhci_irq_thread(int irq, void *dev_id)
u32 intmask;
int cardint = 0;
- spin_lock(&host->lock);
+ mutex_lock(&host->lock);
intmask = sdhci_readl(host, SDHCI_INT_STATUS);
sdhci_writel(host, intmask, SDHCI_INT_STATUS);
@@ -1551,7 +1544,7 @@ static irqreturn_t sdhci_irq_thread(int irq, void *dev_id)
mmiowb();
- spin_unlock(&host->lock);
+ mutex_unlock(&host->lock);
/*
* We have to delay this as it calls back into the driver.
@@ -1816,7 +1809,7 @@ int sdhci_add_host(struct sdhci_host *host)
return -ENODEV;
}
- spin_lock_init(&host->lock);
+ mutex_init(&host->lock);
/*
* Maximum number of segments. Depends on if the hardware
@@ -1926,10 +1919,8 @@ EXPORT_SYMBOL_GPL(sdhci_add_host);
void sdhci_remove_host(struct sdhci_host *host, int dead)
{
- unsigned long flags;
-
if (dead) {
- spin_lock_irqsave(&host->lock, flags);
+ mutex_lock(&host->lock);
host->flags |= SDHCI_DEVICE_DEAD;
@@ -1941,7 +1932,7 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
schedule_work(&host->finish_work);
}
- spin_unlock_irqrestore(&host->lock, flags);
+ mutex_unlock(&host->lock);
}
sdhci_disable_card_detection(host);
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index d96e4dd..364d4e8 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -15,6 +15,7 @@
#include <linux/workqueue.h>
#include <linux/compiler.h>
#include <linux/types.h>
+#include <linux/mutex.h>
#include <linux/io.h>
/*
@@ -256,7 +257,7 @@ struct sdhci_host {
char led_name[32];
#endif
- spinlock_t lock; /* Mutex */
+ struct mutex lock; /* Mutex */
int flags; /* Host attributes */
#define SDHCI_USE_SDMA (1<<0) /* Host is SDMA capable */
--
1.7.0.5
^ permalink raw reply related
* [PATCH 6/8] sdhci: Get rid of card detect work
From: Anton Vorontsov @ 2010-07-14 13:08 UTC (permalink / raw)
To: Andrew Morton
Cc: Matt Fleming, Albert Herranz, linux-mmc, linux-kernel,
linuxppc-dev, Ben Dooks, Pierre Ossman
In-Reply-To: <20100714130728.GA27339@oksana.dev.rtsoft.ru>
Nowadays we can just call the card detection handler directly,
no need for the separate work struct.
We still need host->finish_work as sdhci_finish_work() calls
mmc_request_done(), which tries to re-enter the driver.
Signed-off-by: Anton Vorontsov <avorontsov@mvista.com>
---
drivers/mmc/host/sdhci.c | 14 ++------------
drivers/mmc/host/sdhci.h | 1 -
2 files changed, 2 insertions(+), 13 deletions(-)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 5eddbdb..56d5c56 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1239,14 +1239,8 @@ static const struct mmc_host_ops sdhci_ops = {
* *
\*****************************************************************************/
-static void sdhci_card_detect_work(struct work_struct *wk)
+static void sdhci_card_detect(struct sdhci_host *host)
{
- struct sdhci_host *host;
-
- host = container_of(wk, struct sdhci_host, card_detect_work);
-
- mutex_lock(&host->lock);
-
if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
if (host->mrq) {
printk(KERN_ERR "%s: Card removed during transfer!\n",
@@ -1262,8 +1256,6 @@ static void sdhci_card_detect_work(struct work_struct *wk)
}
}
- mutex_unlock(&host->lock);
-
mmc_detect_change(host->mmc, msecs_to_jiffies(200));
}
@@ -1511,7 +1503,7 @@ static irqreturn_t sdhci_irq_thread(int irq, void *dev_id)
sdhci_writel(host, intmask, SDHCI_INT_STATUS);
if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE))
- schedule_work(&host->card_detect_work);
+ sdhci_card_detect(host);
intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE);
@@ -1865,7 +1857,6 @@ int sdhci_add_host(struct sdhci_host *host)
/*
* Init work structs.
*/
- INIT_WORK(&host->card_detect_work, sdhci_card_detect_work);
INIT_WORK(&host->finish_work, sdhci_finish_work);
INIT_DELAYED_WORK(&host->timeout_work, sdhci_timeout_work);
@@ -1950,7 +1941,6 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
flush_delayed_work(&host->timeout_work);
- flush_work(&host->card_detect_work);
flush_work(&host->finish_work);
kfree(host->adma_desc);
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 364d4e8..5f7d649 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -289,7 +289,6 @@ struct sdhci_host {
dma_addr_t adma_addr; /* Mapped ADMA descr. table */
dma_addr_t align_addr; /* Mapped bounce buffer */
- struct work_struct card_detect_work;
struct work_struct finish_work;
struct delayed_work timeout_work; /* Work for timeouts */
--
1.7.0.5
^ permalink raw reply related
* [PATCH 7/8] sdhci: Get rid of mdelay()s where it is safe and makes sense
From: Anton Vorontsov @ 2010-07-14 13:08 UTC (permalink / raw)
To: Andrew Morton
Cc: Matt Fleming, Albert Herranz, linux-mmc, linux-kernel,
linuxppc-dev, Ben Dooks, Pierre Ossman
In-Reply-To: <20100714130728.GA27339@oksana.dev.rtsoft.ru>
Since we don't run in the atomic context any longer, we can
turn mdelay()s into msleep()s.
The only place where the driver is still using mdelay() is
sdhci_send_command(). There it is possible to use sleepable
delays too, but we don't actually want to force rescheduling
in a hot path.
Sure, we might end up calling msleep() there too, just not
via this safe patch.
Signed-off-by: Anton Vorontsov <avorontsov@mvista.com>
---
drivers/mmc/host/sdhci-of-esdhc.c | 2 +-
drivers/mmc/host/sdhci.c | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index c8623de..e9f99fe 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -94,7 +94,7 @@ static void esdhc_set_clock(struct sdhci_host *host, unsigned int clock)
setbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN |
ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN |
div << ESDHC_DIVIDER_SHIFT | pre_div << ESDHC_PREDIV_SHIFT);
- mdelay(100);
+ msleep(100);
out:
host->clock = clock;
}
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 56d5c56..e6adda8 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -171,7 +171,7 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask)
return;
}
timeout--;
- mdelay(1);
+ msleep(1);
}
if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
@@ -1019,7 +1019,7 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
return;
}
timeout--;
- mdelay(1);
+ msleep(1);
}
clk |= SDHCI_CLOCK_CARD_EN;
@@ -1086,7 +1086,7 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
* can apply clock after applying power
*/
if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER)
- mdelay(10);
+ msleep(10);
}
/*****************************************************************************\
--
1.7.0.5
^ permalink raw reply related
* [PATCH 8/8] sdhci: Use jiffies instead of a timeout counter
From: Anton Vorontsov @ 2010-07-14 13:08 UTC (permalink / raw)
To: Andrew Morton
Cc: Matt Fleming, Albert Herranz, linux-mmc, linux-kernel,
linuxppc-dev, Ben Dooks, Pierre Ossman
In-Reply-To: <20100714130728.GA27339@oksana.dev.rtsoft.ru>
Just a cosmetic change, should not affect functionality.
Signed-off-by: Anton Vorontsov <avorontsov@mvista.com>
---
drivers/mmc/host/sdhci.c | 11 +++++------
1 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index e6adda8..c754df1 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -22,6 +22,7 @@
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/scatterlist.h>
+#include <linux/jiffies.h>
#include <linux/leds.h>
@@ -160,17 +161,16 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask)
host->clock = 0;
/* Wait max 100 ms */
- timeout = 100;
+ timeout = jiffies + msecs_to_jiffies(100);
/* hw clears the bit when it's done */
while (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask) {
- if (timeout == 0) {
+ if (time_after(jiffies, timeout)) {
printk(KERN_ERR "%s: Reset 0x%x never completed.\n",
mmc_hostname(host->mmc), (int)mask);
sdhci_dumpregs(host);
return;
}
- timeout--;
msleep(1);
}
@@ -884,7 +884,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
WARN_ON(host->cmd);
/* Wait max 10 ms */
- timeout = 10;
+ timeout = jiffies + msecs_to_jiffies(10);
mask = SDHCI_CMD_INHIBIT;
if ((cmd->data != NULL) || (cmd->flags & MMC_RSP_BUSY))
@@ -896,7 +896,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
mask &= ~SDHCI_DATA_INHIBIT;
while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
- if (timeout == 0) {
+ if (time_after(jiffies, timeout)) {
printk(KERN_ERR "%s: Controller never released "
"inhibit bit(s).\n", mmc_hostname(host->mmc));
sdhci_dumpregs(host);
@@ -904,7 +904,6 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
schedule_work(&host->finish_work);
return;
}
- timeout--;
mdelay(1);
}
--
1.7.0.5
^ permalink raw reply related
* [PATCH 5/5] Remove REDWOOD_5 and REDWOOD_6 config options and conditional code
From: Christian Dietrich @ 2010-07-14 14:05 UTC (permalink / raw)
To: Josh Boyer, Matt Porter, Benjamin Herrenschmidt, Paul Mackerras,
Solomon Peachy, David Woodhouse, Mike Frysinger, Jiri Kosina,
Artem Bityutskiy, Alexander Kurz, David S. Miller, Randy Dunlap,
John Linn, Florian Fainelli, linuxppc-dev, linux-kernel,
linux-mtd, netdev
Cc: vamos-dev
In-Reply-To: <c3c850bed3f5714f1efcfad24ad4f8bfcb6b5b54.1279116162.git.qy03fugy@stud.informatik.uni-erlangen.de>
The config options for REDWOOD_[56] were commented out in the powerpc
Kconfig. The ifdefs referencing this options therefore are dead and all
references to this can be removed (Also dependencies in other KConfig
files).
Signed-off-by: Christian Dietrich <qy03fugy@stud.informatik.uni-erlangen.de>
---
arch/powerpc/platforms/40x/Kconfig | 16 -------------
drivers/mtd/maps/Kconfig | 2 +-
drivers/mtd/maps/redwood.c | 43 ------------------------------------
drivers/net/Kconfig | 2 +-
4 files changed, 2 insertions(+), 61 deletions(-)
diff --git a/arch/powerpc/platforms/40x/Kconfig b/arch/powerpc/platforms/40x/Kconfig
index ec64264..b721764 100644
--- a/arch/powerpc/platforms/40x/Kconfig
+++ b/arch/powerpc/platforms/40x/Kconfig
@@ -71,22 +71,6 @@ config MAKALU
help
This option enables support for the AMCC PPC405EX board.
-#config REDWOOD_5
-# bool "Redwood-5"
-# depends on 40x
-# default n
-# select STB03xxx
-# help
-# This option enables support for the IBM STB04 evaluation board.
-
-#config REDWOOD_6
-# bool "Redwood-6"
-# depends on 40x
-# default n
-# select STB03xxx
-# help
-# This option enables support for the IBM STBx25xx evaluation board.
-
#config SYCAMORE
# bool "Sycamore"
# depends on 40x
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index f22bc9f..b5ebb72 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -321,7 +321,7 @@ config MTD_CFI_FLAGADM
config MTD_REDWOOD
tristate "CFI Flash devices mapped on IBM Redwood"
- depends on MTD_CFI && ( REDWOOD_4 || REDWOOD_5 || REDWOOD_6 )
+ depends on MTD_CFI && REDWOOD_4
help
This enables access routines for the flash chips on the IBM
Redwood board. If you have one of these boards and would like to
diff --git a/drivers/mtd/maps/redwood.c b/drivers/mtd/maps/redwood.c
index 933c0b6..d2c9db0 100644
--- a/drivers/mtd/maps/redwood.c
+++ b/drivers/mtd/maps/redwood.c
@@ -22,8 +22,6 @@
#include <asm/io.h>
-#if !defined (CONFIG_REDWOOD_6)
-
#define WINDOW_ADDR 0xffc00000
#define WINDOW_SIZE 0x00400000
@@ -69,47 +67,6 @@ static struct mtd_partition redwood_flash_partitions[] = {
}
};
-#else /* CONFIG_REDWOOD_6 */
-/* FIXME: the window is bigger - armin */
-#define WINDOW_ADDR 0xff800000
-#define WINDOW_SIZE 0x00800000
-
-#define RW_PART0_OF 0
-#define RW_PART0_SZ 0x400000 /* 4 MiB data */
-#define RW_PART1_OF RW_PART0_OF + RW_PART0_SZ
-#define RW_PART1_SZ 0x10000 /* 64K VPD */
-#define RW_PART2_OF RW_PART1_OF + RW_PART1_SZ
-#define RW_PART2_SZ 0x400000 - (0x10000 + 0x20000)
-#define RW_PART3_OF RW_PART2_OF + RW_PART2_SZ
-#define RW_PART3_SZ 0x20000
-
-static struct mtd_partition redwood_flash_partitions[] = {
- {
- .name = "Redwood filesystem",
- .offset = RW_PART0_OF,
- .size = RW_PART0_SZ
- },
- {
- .name = "Redwood OpenBIOS Vital Product Data",
- .offset = RW_PART1_OF,
- .size = RW_PART1_SZ,
- .mask_flags = MTD_WRITEABLE /* force read-only */
- },
- {
- .name = "Redwood kernel",
- .offset = RW_PART2_OF,
- .size = RW_PART2_SZ
- },
- {
- .name = "Redwood OpenBIOS",
- .offset = RW_PART3_OF,
- .size = RW_PART3_SZ,
- .mask_flags = MTD_WRITEABLE /* force read-only */
- }
-};
-
-#endif /* CONFIG_REDWOOD_6 */
-
struct map_info redwood_flash_map = {
.name = "IBM Redwood",
.size = WINDOW_SIZE,
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index ce2fcdd..313d306 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -913,7 +913,7 @@ config SMC91X
tristate "SMC 91C9x/91C1xxx support"
select CRC32
select MII
- depends on ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || \
+ depends on ARM || M32R || SUPERH || \
MIPS || BLACKFIN || MN10300 || COLDFIRE
help
This is a driver for SMC's 91x series of Ethernet chipsets,
--
1.7.0.4
^ permalink raw reply related
* [PATCH V4] powerpc/prom: Export device tree physical address via proc
From: Matthew McClintock @ 2010-07-14 15:18 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Matthew McClintock, Kumar Gala, Timur Tabi
To build a proper flat device tree for kexec we need to know which
memreserve region was used for the device tree for the currently
running kernel, so we can remove it and replace it with the new
memreserve for the kexec'ed kernel
Signed-off-by: Matthew McClintock <msm@freescale.com>
---
V4: Fixed misspelling
V3: Remove unneeded cast, and fixed indentation screw up
V2: messed up changes
arch/powerpc/kernel/prom.c | 45 ++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 45 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index fd9359a..ff3e240 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -32,6 +32,7 @@
#include <linux/debugfs.h>
#include <linux/irq.h>
#include <linux/lmb.h>
+#include <linux/bootmem.h>
#include <asm/prom.h>
#include <asm/rtas.h>
@@ -911,3 +912,47 @@ static int __init export_flat_device_tree(void)
}
__initcall(export_flat_device_tree);
#endif
+
+#ifdef CONFIG_KEXEC
+static phys_addr_t flat_dt_start;
+static phys_addr_t flat_dt_end;
+
+static struct property flat_dt_start_prop = {
+ .name = "linux,devicetree-start",
+ .length = sizeof(phys_addr_t),
+ .value = &flat_dt_start,
+};
+
+static struct property flat_dt_end_prop = {
+ .name = "linux,devicetree-end",
+ .length = sizeof(phys_addr_t),
+ .value = &flat_dt_end,
+};
+
+static int __init export_flat_device_tree_phys_addr(void)
+{
+ struct property *prop;
+ struct device_node *node;
+
+ node = of_find_node_by_path("/chosen");
+ if (!node)
+ return -ENOENT;
+
+ prop = of_find_property(node, "linux,devicetree-start", NULL);
+ if (prop)
+ prom_remove_property(node, prop);
+
+ prop = of_find_property(node, "linux,devicetree-end", NULL);
+ if (prop)
+ prom_remove_property(node, prop);
+
+ flat_dt_start = virt_to_phys(initial_boot_params);
+ flat_dt_end = virt_to_phys(initial_boot_params)
+ + initial_boot_params->totalsize;
+ prom_add_property(node, &flat_dt_start_prop);
+ prom_add_property(node, &flat_dt_end_prop);
+
+ return 0;
+}
+__initcall(export_flat_device_tree_phys_addr);
+#endif
--
1.6.6.1
^ permalink raw reply related
* Re: [PATCH V4] powerpc/prom: Export device tree physical address via proc
From: Tabi Timur-B04825 @ 2010-07-14 15:33 UTC (permalink / raw)
To: McClintock Matthew-B29882; +Cc: Gala Kumar-B11780, linuxppc-dev
In-Reply-To: <1279120733-13584-1-git-send-email-msm@freescale.com>
[-- Attachment #1: Type: text/plain, Size: 1276 bytes --]
Matthew McClintock wrote:
> +static struct property flat_dt_start_prop = {
> + .name = "linux,devicetree-start",
> + .length = sizeof(phys_addr_t),
> + .value =&flat_dt_start,
> +};
> +
> +static struct property flat_dt_end_prop = {
> + .name = "linux,devicetree-end",
> + .length = sizeof(phys_addr_t),
> + .value =&flat_dt_end,
> +};
I think Segher was suggesting that you use "linux,device-tree-xxx".
> +
> +static int __init export_flat_device_tree_phys_addr(void)
> +{
> + struct property *prop;
> + struct device_node *node;
> +
> + node = of_find_node_by_path("/chosen");
> + if (!node)
> + return -ENOENT;
> +
> + prop = of_find_property(node, "linux,devicetree-start", NULL);
Does this work?
prop = of_find_property(node, flat_dt_start_prop.name, NULL);
> + if (prop)
> + prom_remove_property(node, prop);
> +
> + prop = of_find_property(node, "linux,devicetree-end", NULL);
> + if (prop)
> + prom_remove_property(node, prop);
> +
> + flat_dt_start = virt_to_phys(initial_boot_params);
> + flat_dt_end = virt_to_phys(initial_boot_params)
> + + initial_boot_params->totalsize;
This is better, I think:
flat_dt_end = flat_dt_start + initial_boot_params->totalsize;
--
Timur Tabi
Linux kernel developer
[-- Attachment #2: Type: text/html, Size: 2835 bytes --]
^ permalink raw reply
* Re: [PATCH V4] powerpc/prom: Export device tree physical address via proc
From: Segher Boessenkool @ 2010-07-14 15:35 UTC (permalink / raw)
To: Matthew McClintock; +Cc: Kumar Gala, linuxppc-dev, Timur Tabi
In-Reply-To: <1279120733-13584-1-git-send-email-msm@freescale.com>
> V4: Fixed misspelling
Any particular reason you fixed only one of the two
mispelings I pointed out? (device tree is two words,
not one).
> + prop = of_find_property(node, "linux,devicetree-start", NULL);
> + if (prop)
> + prom_remove_property(node, prop);
> +
> + prop = of_find_property(node, "linux,devicetree-end", NULL);
> + if (prop)
> + prom_remove_property(node, prop);
> +
> + flat_dt_start = virt_to_phys(initial_boot_params);
> + flat_dt_end = virt_to_phys(initial_boot_params)
> + + initial_boot_params->totalsize;
> + prom_add_property(node, &flat_dt_start_prop);
> + prom_add_property(node, &flat_dt_end_prop);
You could use one property instead of two; use addr+len
like every other property does.
You also should use a better name for the property; is this
the previous kernel's device tree? Just "device-tree" makes
no sense, it is not pointing to "the" device tree for sure!
Segher
^ permalink raw reply
* Re: [PATCH V4] powerpc/prom: Export device tree physical address via proc
From: Matthew McClintock @ 2010-07-14 15:42 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: Kumar Gala, linuxppc-dev, Timur Tabi
In-Reply-To: <C26140FB-4F77-4D8E-B6C4-63BC9C9EDD83@kernel.crashing.org>
On Wed, 2010-07-14 at 17:35 +0200, Segher Boessenkool wrote:
> > V4: Fixed misspelling
>
> Any particular reason you fixed only one of the two
> mispelings I pointed out? (device tree is two words,
> not one).
Ahh, my fault.
>
> > + prop = of_find_property(node, "linux,devicetree-start", NULL);
> > + if (prop)
> > + prom_remove_property(node, prop);
> > +
> > + prop = of_find_property(node, "linux,devicetree-end", NULL);
> > + if (prop)
> > + prom_remove_property(node, prop);
> > +
> > + flat_dt_start = virt_to_phys(initial_boot_params);
> > + flat_dt_end = virt_to_phys(initial_boot_params)
> > + + initial_boot_params->totalsize;
> > + prom_add_property(node, &flat_dt_start_prop);
> > + prom_add_property(node, &flat_dt_end_prop);
>
> You could use one property instead of two; use addr+len
> like every other property does.
>
> You also should use a better name for the property; is this
> the previous kernel's device tree? Just "device-tree" makes
> no sense, it is not pointing to "the" device tree for sure!
>
What about just one node called "flat-device-tree"?
-Matthew
^ permalink raw reply
* Re: [PATCH V4] powerpc/prom: Export device tree physical address via proc
From: Segher Boessenkool @ 2010-07-14 15:46 UTC (permalink / raw)
To: Matthew McClintock; +Cc: Kumar Gala, linuxppc-dev, Timur Tabi
In-Reply-To: <1279122163.13098.2.camel@localhost>
>> Any particular reason you fixed only one of the two
>> mispelings I pointed out? (device tree is two words,
>> not one).
>
> Ahh, my fault.
Well I wasn't terribly clear ;-)
>> You could use one property instead of two; use addr+len
>> like every other property does.
>>
>> You also should use a better name for the property; is this
>> the previous kernel's device tree? Just "device-tree" makes
>> no sense, it is not pointing to "the" device tree for sure!
>
> What about just one node called "flat-device-tree"?
But *what* flat device tree? It cannot be "the" flat device tree,
or it would be useless information, since we are already reading it!
Segher
^ 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