* Re: [PATCH] powerpc: fix usage of setup_pci_atmu()
From: Stephen Rothwell @ 2013-04-29 23:06 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev, Michael Neuling, linux-next
In-Reply-To: <5881.1366004521@ale.ozlabs.ibm.com>
[-- Attachment #1: Type: text/plain, Size: 1209 bytes --]
Hi Kumar,
On Mon, 15 Apr 2013 15:42:01 +1000 Michael Neuling <mikey@neuling.org> wrote:
>
> Linux next is currently failing to compile mpc85xx_defconfig with:
> arch/powerpc/sysdev/fsl_pci.c:944:2: error: too many arguments to function 'setup_pci_atmu'
>
> This is caused by (from Kumar's next branch):
> commit 34642bbb3d12121333efcf4ea7dfe66685e403a1
> Author: Kumar Gala <galak@kernel.crashing.org>
> powerpc/fsl-pci: Keep PCI SoC controller registers in pci_controller
>
> Which changed definition of setup_pci_atmu() but didn't update one of
> the callers. Below fixes this.
>
> Signed-off-by: Michael Neuling <mikey@neuling.org>
> ---
> Kumar: this is for your next tree
>
> diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
> index 83918c3..a10a036 100644
> --- a/arch/powerpc/sysdev/fsl_pci.c
> +++ b/arch/powerpc/sysdev/fsl_pci.c
> @@ -941,7 +941,7 @@ static int fsl_pci_resume(struct device *dev)
> return -ENODEV;
> }
>
> - setup_pci_atmu(hose, &pci_rsrc);
> + setup_pci_atmu(hose);
>
> return 0;
> }
>
This is still not in your tree ...
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH] powerpc: fix usage of setup_pci_atmu()
From: Benjamin Herrenschmidt @ 2013-04-30 1:08 UTC (permalink / raw)
To: Stephen Rothwell; +Cc: linuxppc-dev, Michael Neuling, linux-next
In-Reply-To: <20130430090636.5e06bbfc6db472e1e677cb0b@canb.auug.org.au>
On Tue, 2013-04-30 at 09:06 +1000, Stephen Rothwell wrote:
>
> This is still not in your tree ...
I'll apply it after I merge kumar stuff.
Cheers,
Ben.
^ permalink raw reply
* Re: linux-next: build failure after merge of the cgroup tree
From: Benjamin Herrenschmidt @ 2013-04-30 1:51 UTC (permalink / raw)
To: Tejun Heo
Cc: Stephen Rothwell, linux-kernel, Li Zefan, linux-next,
Nathan Fontenot, linuxppc-dev
In-Reply-To: <20130429225513.GG2395@htj.dyndns.org>
On Mon, 2013-04-29 at 15:55 -0700, Tejun Heo wrote:
> Benjamin, can you please pick this up?
>
> Thanks a lot and sorry about the trouble.
Done.
Cheers,
Ben.
^ permalink raw reply
* Re: [PATCH -V7 01/18] mm/THP: HPAGE_SHIFT is not a #define on some arch
From: David Gibson @ 2013-04-30 2:21 UTC (permalink / raw)
To: Aneesh Kumar K.V; +Cc: paulus, linuxppc-dev, linux-mm
In-Reply-To: <1367177859-7893-2-git-send-email-aneesh.kumar@linux.vnet.ibm.com>
[-- Attachment #1: Type: text/plain, Size: 999 bytes --]
On Mon, Apr 29, 2013 at 01:07:22AM +0530, Aneesh Kumar K.V wrote:
> From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
>
> On archs like powerpc that support different hugepage sizes, HPAGE_SHIFT
> and other derived values like HPAGE_PMD_ORDER are not constants. So move
> that to hugepage_init
These seems to miss the point. Those variables may be defined in
terms of HPAGE_SHIFT right now, but that is of itself kind of broken.
The transparent hugepage mechanism only works if the hugepage size is
equal to the PMD size - and PMD_SHIFT remains a compile time constant.
There's no reason having transparent hugepage should force the PMD
size of hugepage to be the default for other purposes - it should be
possible to do THP as long as PMD-sized is a possible hugepage size.
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply
* Re: [PATCH -V7 01/18] mm/THP: HPAGE_SHIFT is not a #define on some arch
From: David Gibson @ 2013-04-30 2:24 UTC (permalink / raw)
To: Aneesh Kumar K.V; +Cc: paulus, linuxppc-dev, linux-mm
In-Reply-To: <20130430022149.GU20202@truffula.fritz.box>
[-- Attachment #1: Type: text/plain, Size: 1254 bytes --]
On Tue, Apr 30, 2013 at 12:21:49PM +1000, David Gibson wrote:
> On Mon, Apr 29, 2013 at 01:07:22AM +0530, Aneesh Kumar K.V wrote:
> > From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
> >
> > On archs like powerpc that support different hugepage sizes, HPAGE_SHIFT
> > and other derived values like HPAGE_PMD_ORDER are not constants. So move
> > that to hugepage_init
>
> These seems to miss the point. Those variables may be defined in
> terms of HPAGE_SHIFT right now, but that is of itself kind of broken.
> The transparent hugepage mechanism only works if the hugepage size is
> equal to the PMD size - and PMD_SHIFT remains a compile time constant.
>
> There's no reason having transparent hugepage should force the PMD
> size of hugepage to be the default for other purposes - it should be
> possible to do THP as long as PMD-sized is a possible hugepage size.
Oh, also, I'm pretty sure I said something similar on the last
posting. Receiving review comments and then ignoring them does not
count as "Reviewed-by"...
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply
* Re: [PATCH -V7 01/18] mm/THP: HPAGE_SHIFT is not a #define on some arch
From: Aneesh Kumar K.V @ 2013-04-30 3:42 UTC (permalink / raw)
To: David Gibson; +Cc: paulus, linuxppc-dev, linux-mm
In-Reply-To: <20130430022149.GU20202@truffula.fritz.box>
David Gibson <dwg@au1.ibm.com> writes:
> On Mon, Apr 29, 2013 at 01:07:22AM +0530, Aneesh Kumar K.V wrote:
>> From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
>>
>> On archs like powerpc that support different hugepage sizes, HPAGE_SHIFT
>> and other derived values like HPAGE_PMD_ORDER are not constants. So move
>> that to hugepage_init
>
> These seems to miss the point. Those variables may be defined in
> terms of HPAGE_SHIFT right now, but that is of itself kind of broken.
> The transparent hugepage mechanism only works if the hugepage size is
> equal to the PMD size - and PMD_SHIFT remains a compile time constant.
>
> There's no reason having transparent hugepage should force the PMD
> size of hugepage to be the default for other purposes - it should be
> possible to do THP as long as PMD-sized is a possible hugepage size.
>
THP code does
#define HPAGE_PMD_SHIFT HPAGE_SHIFT
#define HPAGE_PMD_MASK HPAGE_MASK
#define HPAGE_PMD_SIZE HPAGE_SIZE
I had two options, one to move all those in terms of PMD_SHIFT or switch
ppc64 to not use HPAGE_SHIFT the way it use now. Both would involve large
code changes. Hence I end up moving some of the checks to runtime
checks. Actual HPAGE_SHIFT == PMD_SHIFT check happens in the has_transparent_hugepage()
https://lists.ozlabs.org/pipermail/linuxppc-dev/2013-April/106002.html
IMHO what the patch is checking is that, HPAGE_SHIFT
value is not resulting in a page order higher than MAX_ORDER.
Related to Reviewed-by: that came from V5 patchset
https://lists.ozlabs.org/pipermail/linuxppc-dev/2013-April/105299.html
Your review suggestion to move that runtime check back to macro happened
in V6. I missed dropping reviewed-by after that.
-aneesh
^ permalink raw reply
* [PATCH v2] powerpc: Add an in memory udbg console
From: Alistair Popple @ 2013-04-30 4:07 UTC (permalink / raw)
To: linuxppc-dev
This patch adds a new udbg early debug console which utilises
statically defined input and output buffers stored within the kernel
BSS. It is primarily designed to assist with bring up of new hardware
which may not have a working console but which has a method of
reading/writing kernel memory.
This version incorporates comments made by Ben H (thanks!).
Changes from v1:
- Add memory barriers.
- Ensure updating of read/write positions is atomic.
Signed-off-by: Alistair Popple <alistair@popple.id.au>
---
arch/powerpc/Kconfig.debug | 23 ++++++++
arch/powerpc/include/asm/udbg.h | 1 +
arch/powerpc/kernel/udbg.c | 3 ++
arch/powerpc/sysdev/Makefile | 2 +
arch/powerpc/sysdev/udbg_memcons.c | 105 ++++++++++++++++++++++++++++++++++++
5 files changed, 134 insertions(+)
create mode 100644 arch/powerpc/sysdev/udbg_memcons.c
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 5416e28..863d877 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -262,8 +262,31 @@ config PPC_EARLY_DEBUG_OPAL_HVSI
Select this to enable early debugging for the PowerNV platform
using an "hvsi" console
+config PPC_EARLY_DEBUG_MEMCONS
+ bool "In memory console"
+ help
+ Select this to enable early debugging using an in memory console.
+ This console provides input and output buffers stored within the
+ kernel BSS and should be safe to select on any system. A debugger
+ can then be used to read kernel output or send input to the console.
endchoice
+config PPC_MEMCONS_OUTPUT_SIZE
+ int "In memory console output buffer size"
+ depends on PPC_EARLY_DEBUG_MEMCONS
+ default 4096
+ help
+ Selects the size of the output buffer (in bytes) of the in memory
+ console.
+
+config PPC_MEMCONS_INPUT_SIZE
+ int "In memory console input buffer size"
+ depends on PPC_EARLY_DEBUG_MEMCONS
+ default 128
+ help
+ Selects the size of the input buffer (in bytes) of the in memory
+ console.
+
config PPC_EARLY_DEBUG_OPAL
def_bool y
depends on PPC_EARLY_DEBUG_OPAL_RAW || PPC_EARLY_DEBUG_OPAL_HVSI
diff --git a/arch/powerpc/include/asm/udbg.h b/arch/powerpc/include/asm/udbg.h
index 5a7510e..dc59091 100644
--- a/arch/powerpc/include/asm/udbg.h
+++ b/arch/powerpc/include/asm/udbg.h
@@ -52,6 +52,7 @@ extern void __init udbg_init_40x_realmode(void);
extern void __init udbg_init_cpm(void);
extern void __init udbg_init_usbgecko(void);
extern void __init udbg_init_wsp(void);
+extern void __init udbg_init_memcons(void);
extern void __init udbg_init_ehv_bc(void);
extern void __init udbg_init_ps3gelic(void);
extern void __init udbg_init_debug_opal_raw(void);
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c
index f974849..efa5c93 100644
--- a/arch/powerpc/kernel/udbg.c
+++ b/arch/powerpc/kernel/udbg.c
@@ -64,6 +64,9 @@ void __init udbg_early_init(void)
udbg_init_usbgecko();
#elif defined(CONFIG_PPC_EARLY_DEBUG_WSP)
udbg_init_wsp();
+#elif defined(CONFIG_PPC_EARLY_DEBUG_MEMCONS)
+ /* In memory console */
+ udbg_init_memcons();
#elif defined(CONFIG_PPC_EARLY_DEBUG_EHV_BC)
udbg_init_ehv_bc();
#elif defined(CONFIG_PPC_EARLY_DEBUG_PS3GELIC)
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index b0a518e..99464a7 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -64,6 +64,8 @@ endif
obj-$(CONFIG_PPC_SCOM) += scom.o
+obj-$(CONFIG_PPC_EARLY_DEBUG_MEMCONS) += udbg_memcons.o
+
subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
obj-$(CONFIG_PPC_XICS) += xics/
diff --git a/arch/powerpc/sysdev/udbg_memcons.c b/arch/powerpc/sysdev/udbg_memcons.c
new file mode 100644
index 0000000..ce5a7b4
--- /dev/null
+++ b/arch/powerpc/sysdev/udbg_memcons.c
@@ -0,0 +1,105 @@
+/*
+ * A udbg backend which logs messages and reads input from in memory
+ * buffers.
+ *
+ * The console output can be read from memcons_output which is a
+ * circular buffer whose next write position is stored in memcons.output_pos.
+ *
+ * Input may be passed by writing into the memcons_input buffer when it is
+ * empty. The input buffer is empty when both input_pos == input_start and
+ * *input_start == '\0'.
+ *
+ * Copyright (C) 2003-2005 Anton Blanchard and Milton Miller, IBM Corp
+ * Copyright (C) 2013 Alistair Popple, IBM Corp
+ *
+ * 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/init.h>
+#include <linux/kernel.h>
+#include <asm/barrier.h>
+#include <asm/page.h>
+#include <asm/processor.h>
+#include <asm/udbg.h>
+
+struct memcons {
+ char *output_start;
+ char *output_pos;
+ char *output_end;
+ char *input_start;
+ char *input_pos;
+ char *input_end;
+};
+
+static char memcons_output[CONFIG_PPC_MEMCONS_OUTPUT_SIZE];
+static char memcons_input[CONFIG_PPC_MEMCONS_INPUT_SIZE];
+
+struct memcons memcons = {
+ .output_start = memcons_output,
+ .output_pos = memcons_output,
+ .output_end = &memcons_output[CONFIG_PPC_MEMCONS_OUTPUT_SIZE],
+ .input_start = memcons_input,
+ .input_pos = memcons_input,
+ .input_end = &memcons_input[CONFIG_PPC_MEMCONS_INPUT_SIZE],
+};
+
+void memcons_putc(char c)
+{
+ char *new_output_pos;
+
+ *memcons.output_pos = c;
+ wmb();
+ new_output_pos = memcons.output_pos + 1;
+ if (new_output_pos >= memcons.output_end)
+ new_output_pos = memcons.output_start;
+
+ memcons.output_pos = new_output_pos;
+}
+
+int memcons_getc_poll(void)
+{
+ char c;
+ char *new_input_pos;
+
+ if (*memcons.input_pos) {
+ c = *memcons.input_pos;
+
+ new_input_pos = memcons.input_pos + 1;
+ if (new_input_pos >= memcons.input_end)
+ new_input_pos = memcons.input_start;
+ else if (*new_input_pos == '\0')
+ new_input_pos = memcons.input_start;
+
+ *memcons.input_pos = '\0';
+ wmb();
+ memcons.input_pos = new_input_pos;
+ return c;
+ }
+
+ return -1;
+}
+
+int memcons_getc(void)
+{
+ int c;
+
+ while (1) {
+ c = memcons_getc_poll();
+ if (c == -1)
+ cpu_relax();
+ else
+ break;
+ }
+
+ return c;
+}
+
+void udbg_init_memcons(void)
+{
+ udbg_putc = memcons_putc;
+ udbg_getc = memcons_getc;
+ udbg_getc_poll = memcons_getc_poll;
+}
--
1.7.10.4
^ permalink raw reply related
* Re: [PATCH -V7 01/18] mm/THP: HPAGE_SHIFT is not a #define on some arch
From: David Gibson @ 2013-04-30 5:01 UTC (permalink / raw)
To: Aneesh Kumar K.V; +Cc: linuxppc-dev, paulus, linux-mm
In-Reply-To: <871u9sfzvy.fsf@linux.vnet.ibm.com>
[-- Attachment #1: Type: text/plain, Size: 2663 bytes --]
On Tue, Apr 30, 2013 at 09:12:09AM +0530, Aneesh Kumar K.V wrote:
> David Gibson <dwg@au1.ibm.com> writes:
>
> > On Mon, Apr 29, 2013 at 01:07:22AM +0530, Aneesh Kumar K.V wrote:
> >> From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
> >>
> >> On archs like powerpc that support different hugepage sizes, HPAGE_SHIFT
> >> and other derived values like HPAGE_PMD_ORDER are not constants. So move
> >> that to hugepage_init
> >
> > These seems to miss the point. Those variables may be defined in
> > terms of HPAGE_SHIFT right now, but that is of itself kind of broken.
> > The transparent hugepage mechanism only works if the hugepage size is
> > equal to the PMD size - and PMD_SHIFT remains a compile time constant.
> >
> > There's no reason having transparent hugepage should force the PMD
> > size of hugepage to be the default for other purposes - it should be
> > possible to do THP as long as PMD-sized is a possible hugepage size.
> >
>
> THP code does
>
> #define HPAGE_PMD_SHIFT HPAGE_SHIFT
> #define HPAGE_PMD_MASK HPAGE_MASK
> #define HPAGE_PMD_SIZE HPAGE_SIZE
>
> I had two options, one to move all those in terms of PMD_SHIFT
This is a much better option that you've taken now, and really
shouldn't be that hard. The THP code is much more strongly tied to
the fact that it is a PMD than the fact that it's the same size as
explicit huge pages.
> or switch
> ppc64 to not use HPAGE_SHIFT the way it use now. Both would involve large
> code changes. Hence I end up moving some of the checks to runtime
> checks. Actual HPAGE_SHIFT == PMD_SHIFT check happens in the has_transparent_hugepage()
>
> https://lists.ozlabs.org/pipermail/linuxppc-dev/2013-April/106002.html
And my other point is that this is also wrong. All you should need to
check is that HPAGE_PMD_SHIFT (== PMD_SHIFT) is a supported hugepage
size, not that it is equal to HPAGE_SHIFT the default explicit
hugepage size.
> IMHO what the patch is checking is that, HPAGE_SHIFT
> value is not resulting in a page order higher than MAX_ORDER.
Which you don't actually care about in THP - you only care that
HPAGE_PMD_SHIFT doesn't exceed MAX_ORDER.
> Related to Reviewed-by: that came from V5 patchset
> https://lists.ozlabs.org/pipermail/linuxppc-dev/2013-April/105299.html
>
> Your review suggestion to move that runtime check back to macro happened
> in V6. I missed dropping reviewed-by after that.
Ok.
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply
* Re: [PATCH -V7 09/18] powerpc: Switch 16GB and 16MB explicit hugepages to a different page table format
From: David Gibson @ 2013-04-30 5:17 UTC (permalink / raw)
To: Aneesh Kumar K.V; +Cc: paulus, linuxppc-dev, linux-mm
In-Reply-To: <1367177859-7893-10-git-send-email-aneesh.kumar@linux.vnet.ibm.com>
[-- Attachment #1: Type: text/plain, Size: 1523 bytes --]
On Mon, Apr 29, 2013 at 01:07:30AM +0530, Aneesh Kumar K.V wrote:
> From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
>
> We will be switching PMD_SHIFT to 24 bits to facilitate THP impmenetation.
> With PMD_SHIFT set to 24, we now have 16MB huge pages allocated at PGD level.
> That means with 32 bit process we cannot allocate normal pages at
> all, because we cover the entire address space with one pgd entry. Fix this
> by switching to a new page table format for hugepages. With the new page table
> format for 16GB and 16MB hugepages we won't allocate hugepage directory. Instead
> we encode the PTE information directly at the directory level. This forces 16MB
> hugepage at PMD level. This will also make the page take walk much simpler later
> when we add the THP support.
>
> With the new table format we have 4 cases for pgds and pmds:
> (1) invalid (all zeroes)
> (2) pointer to next table, as normal; bottom 6 bits == 0
> (3) leaf pte for huge page, bottom two bits != 00
> (4) hugepd pointer, bottom two bits == 00, next 4 bits indicate size
> of table
>
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Mostly ok, except that in several pages your comments imply you have
16M and 16M page directory levels, but you haven't actually made that
change yet.
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply
* Re: [PATCH -V7 08/18] powerpc: New hugepage directory format
From: David Gibson @ 2013-04-30 5:16 UTC (permalink / raw)
To: Aneesh Kumar K.V; +Cc: paulus, linuxppc-dev, linux-mm
In-Reply-To: <1367177859-7893-9-git-send-email-aneesh.kumar@linux.vnet.ibm.com>
[-- Attachment #1: Type: text/plain, Size: 1005 bytes --]
On Mon, Apr 29, 2013 at 01:07:29AM +0530, Aneesh Kumar K.V wrote:
> From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
>
> Change the hugepage directory format so that we can have leaf ptes directly
> at page directory avoiding the allocation of hugepage directory.
>
> With the new table format we have 3 cases for pgds and pmds:
> (1) invalid (all zeroes)
> (2) pointer to next table, as normal; bottom 6 bits == 0
> (4) hugepd pointer, bottom two bits == 00, next 4 bits indicate size of table
>
> Instead of storing shift value in hugepd pointer we use mmu_psize_def index
> so that we can fit all the supported hugepage size in 4 bits
>
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Looks ok.
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply
* Re: [PATCH -V7 18/18] powerpc: Update tlbie/tlbiel as per ISA doc
From: David Gibson @ 2013-04-30 6:15 UTC (permalink / raw)
To: Aneesh Kumar K.V; +Cc: paulus, linuxppc-dev, linux-mm
In-Reply-To: <1367177859-7893-19-git-send-email-aneesh.kumar@linux.vnet.ibm.com>
[-- Attachment #1: Type: text/plain, Size: 3684 bytes --]
On Mon, Apr 29, 2013 at 01:07:39AM +0530, Aneesh Kumar K.V wrote:
> From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
>
> Encode the actual page correctly in tlbie/tlbiel. This make sure we handle
> multiple page size segment correctly.
As mentioned in previous comments, this commit message needs to give
much more detail about what precisely the existing implementation is
doing wrong.
>
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
> ---
> arch/powerpc/mm/hash_native_64.c | 32 ++++++++++++++++++++++++++++++--
> 1 file changed, 30 insertions(+), 2 deletions(-)
>
> diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c
> index bb920ee..6a2aead 100644
> --- a/arch/powerpc/mm/hash_native_64.c
> +++ b/arch/powerpc/mm/hash_native_64.c
> @@ -61,7 +61,10 @@ static inline void __tlbie(unsigned long vpn, int psize, int apsize, int ssize)
>
> switch (psize) {
> case MMU_PAGE_4K:
> + /* clear out bits after (52) [0....52.....63] */
> + va &= ~((1ul << (64 - 52)) - 1);
> va |= ssize << 8;
> + va |= mmu_psize_defs[apsize].sllp << 6;
> asm volatile(ASM_FTR_IFCLR("tlbie %0,0", PPC_TLBIE(%1,%0), %2)
> : : "r" (va), "r"(0), "i" (CPU_FTR_ARCH_206)
> : "memory");
> @@ -69,9 +72,20 @@ static inline void __tlbie(unsigned long vpn, int psize, int apsize, int ssize)
> default:
> /* We need 14 to 14 + i bits of va */
> penc = mmu_psize_defs[psize].penc[apsize];
> - va &= ~((1ul << mmu_psize_defs[psize].shift) - 1);
> + va &= ~((1ul << mmu_psize_defs[apsize].shift) - 1);
> va |= penc << 12;
> va |= ssize << 8;
> + /* Add AVAL part */
> + if (psize != apsize) {
> + /*
> + * MPSS, 64K base page size and 16MB parge page size
> + * We don't need all the bits, but rest of the bits
> + * must be ignored by the processor.
> + * vpn cover upto 65 bits of va. (0...65) and we need
> + * 58..64 bits of va.
I can't understand what this comment is saying. Why do we need to do
something different in the psize != apsize case?
> + */
> + va |= (vpn & 0xfe);
> + }
> va |= 1; /* L */
> asm volatile(ASM_FTR_IFCLR("tlbie %0,1", PPC_TLBIE(%1,%0), %2)
> : : "r" (va), "r"(0), "i" (CPU_FTR_ARCH_206)
> @@ -96,16 +110,30 @@ static inline void __tlbiel(unsigned long vpn, int psize, int apsize, int ssize)
>
> switch (psize) {
> case MMU_PAGE_4K:
> + /* clear out bits after(52) [0....52.....63] */
> + va &= ~((1ul << (64 - 52)) - 1);
> va |= ssize << 8;
> + va |= mmu_psize_defs[apsize].sllp << 6;
> asm volatile(".long 0x7c000224 | (%0 << 11) | (0 << 21)"
> : : "r"(va) : "memory");
> break;
> default:
> /* We need 14 to 14 + i bits of va */
> penc = mmu_psize_defs[psize].penc[apsize];
> - va &= ~((1ul << mmu_psize_defs[psize].shift) - 1);
> + va &= ~((1ul << mmu_psize_defs[apsize].shift) - 1);
> va |= penc << 12;
> va |= ssize << 8;
> + /* Add AVAL part */
> + if (psize != apsize) {
> + /*
> + * MPSS, 64K base page size and 16MB parge page size
> + * We don't need all the bits, but rest of the bits
> + * must be ignored by the processor.
> + * vpn cover upto 65 bits of va. (0...65) and we need
> + * 58..64 bits of va.
> + */
> + va |= (vpn & 0xfe);
> + }
> va |= 1; /* L */
> asm volatile(".long 0x7c000224 | (%0 << 11) | (1 << 21)"
> : : "r"(va) : "memory");
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply
* Re: ppc/sata-fsl: orphan config value: CONFIG_MPC8315_DS
From: Anthony Foiani @ 2013-04-30 6:41 UTC (permalink / raw)
To: Anthony Foiani
Cc: Li Yang-R58472, Jeff Garzik, Adrian Bunk, Scott Wood,
Robert P.J.Day, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <gd35lbf55.fsf@dworkin.scrye.com>
[-- Attachment #1: Type: text/plain, Size: 664 bytes --]
Apologies for resurrecting a very old thread, but...
On 05/30/2012 02:14 PM, Anthony Foiani wrote:
>
> Maybe someone who knows devtree really well could crank that out in a
> few minutes... but I'm not that person. :)
Well, I wasn't last year, but this year I decided that I didn't care.
Took me about an hour, not a minute, but...
Having been bitten by this config symbol disappearing one more time,
please find attached my attempt at using information out of the device
tree to enable this hack.
Patch is against 3.4.36 or so; hopefully upstream hasn't diverged very much.
Tested by me, so feel free to add that tag if required.
Thanks,
Anthony Foiani
[-- Attachment #2: 0001-sata-fsl-allow-device-tree-to-limit-sata-speed.patch --]
[-- Type: text/x-patch, Size: 4114 bytes --]
>From c0a85758a669b430c0a6af825e71d18a54ef88d0 Mon Sep 17 00:00:00 2001
From: Anthony Foiani <anthony.foiani@gmail.com>
Date: Mon, 29 Apr 2013 23:44:14 -0600
Subject: [PATCH] sata: fsl: allow device tree to limit sata speed.
There used to be an "orphan" config symbol (CONFIG_MPC8315_DS) that
would artificially limit SATA speed to generation 1 (1.5Gbps).
Since that config symbol got lost whenever any sort of configuration
was done, we instead extract the limitation from the device tree.
Signed-off-by: Anthony Foiani <anthony.foiani@gmail.com>
---
.../devicetree/bindings/powerpc/fsl/board.txt | 23 +++++++++++
drivers/ata/sata_fsl.c | 44 ++++++++++++++++++----
2 files changed, 59 insertions(+), 8 deletions(-)
diff --git a/Documentation/devicetree/bindings/powerpc/fsl/board.txt b/Documentation/devicetree/bindings/powerpc/fsl/board.txt
index 380914e..6a30398 100644
--- a/Documentation/devicetree/bindings/powerpc/fsl/board.txt
+++ b/Documentation/devicetree/bindings/powerpc/fsl/board.txt
@@ -67,3 +67,26 @@ Example:
gpio-controller;
};
};
+
+* Maximum SATA Generation workaround
+
+Some boards advertise SATA speeds that they cannot actually achieve.
+Previously, this was dealt with via the orphaned config symbol
+CONFIG_MPC8315_DS. We now have a device tree property
+"fsl,sata-max-gen" to control this. It should live within the "sata"
+block.
+
+Example:
+
+ sata@18000 {
+ compatible = "fsl,mpc8315-sata", "fsl,pq-sata";
+ reg = <0x18000 0x1000>;
+ cell-index = <1>;
+ interrupts = <44 0x8>;
+ interrupt-parent = <&ipic>;
+ fsl,sata-max-gen = <1>;
+ };
+
+By default, there is no limitation; if a value is given, it indicates
+the maximum "generation" that should be negotiated. Gen 1 is 1.5Gbps,
+Gen 2 is 3.0Gbps.
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
index d6577b9..6d3ec47 100644
--- a/drivers/ata/sata_fsl.c
+++ b/drivers/ata/sata_fsl.c
@@ -274,6 +274,17 @@ struct sata_fsl_port_priv {
};
/*
+ * speed negotiation.
+ */
+
+enum {
+ SCR_SPEED_NEG_MASK = 0xf0,
+ SCR_SPEED_NEG_UNLIMITED = 0x00,
+ SCR_SPEED_NEG_GEN_1 = 0x10, /* 1.5Gbps max */
+ SCR_SPEED_NEG_GEN_2 = 0x20 /* 3.0Gbps max */
+};
+
+/*
* ata_port->host_set private data
*/
struct sata_fsl_host_priv {
@@ -282,6 +293,7 @@ struct sata_fsl_host_priv {
void __iomem *csr_base;
int irq;
int data_snoop;
+ u32 speed_neg;
struct device_attribute intr_coalescing;
};
@@ -726,19 +738,23 @@ static int sata_fsl_port_start(struct ata_port *ap)
VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
VPRINTK("CHBA = 0x%x\n", ioread32(hcr_base + CHBA));
-#ifdef CONFIG_MPC8315_DS
/*
* Workaround for 8315DS board 3gbps link-up issue,
* currently limit SATA port to GEN1 speed
*/
- sata_fsl_scr_read(&ap->link, SCR_CONTROL, &temp);
- temp &= ~(0xF << 4);
- temp |= (0x1 << 4);
- sata_fsl_scr_write(&ap->link, SCR_CONTROL, temp);
+ if ( host_priv->speed_neg != SCR_SPEED_NEG_UNLIMITED )
+ {
- sata_fsl_scr_read(&ap->link, SCR_CONTROL, &temp);
- dev_warn(dev, "scr_control, speed limited to %x\n", temp);
-#endif
+ u32 orig;
+ sata_fsl_scr_read(&ap->link, SCR_CONTROL, &orig);
+ temp = ( ( orig & ~SCR_SPEED_NEG_MASK ) |
+ ( host_priv->speed_neg & SCR_SPEED_NEG_MASK ) );
+ sata_fsl_scr_write(&ap->link, SCR_CONTROL, temp);
+
+ sata_fsl_scr_read(&ap->link, SCR_CONTROL, &temp);
+ dev_warn(dev, "speed limited, scr_control 0x%x -> 0x%x\n",
+ orig, temp);
+ }
return 0;
}
@@ -1437,6 +1453,18 @@ static int sata_fsl_probe(struct platform_device *ofdev)
else
host_priv->data_snoop = DATA_SNOOP_ENABLE_V1;
+ if (!of_property_read_u32(ofdev->dev.of_node, "fsl,sata-max-gen",
+ &temp))
+ {
+ switch (temp)
+ {
+ case 1: host_priv->speed_neg = SCR_SPEED_NEG_GEN_1; break;
+ case 2: host_priv->speed_neg = SCR_SPEED_NEG_GEN_2; break;
+ }
+ dev_warn(&ofdev->dev, "speed limit set to gen %u (0x%x)\n",
+ temp, host_priv->speed_neg);
+ }
+
/* allocate host structure */
host = ata_host_alloc_pinfo(&ofdev->dev, ppi, SATA_FSL_MAX_PORTS);
if (!host) {
--
1.8.1.4
^ permalink raw reply related
* [PATCH] powerpc: Fix interrupt range check on debug exception
From: Bharat Bhushan @ 2013-04-30 8:18 UTC (permalink / raw)
To: galak, linuxppc-dev, benh, agraf, scottwood, stuart.yoder; +Cc: Bharat Bhushan
We do not want to take single step and branch-taken debug exception
in kernel exception code. But the address range check was not covering
all kernel exception handlers address range.
With this patch we defined the interrupt_end label which defines the
end on kernel exception code. So now we check interrupt_base to
interrupt_end range for not handling debug exception in kernel
exception entry.
Signed-off-by: Bharat Bhushan <bharat.bhushan@freescale.com>
---
arch/powerpc/kernel/head_44x.S | 2 ++
arch/powerpc/kernel/head_booke.h | 16 ++++++++--------
arch/powerpc/kernel/head_fsl_booke.S | 2 ++
3 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
index 7a2e5e4..97e2671 100644
--- a/arch/powerpc/kernel/head_44x.S
+++ b/arch/powerpc/kernel/head_44x.S
@@ -769,6 +769,8 @@ finish_tlb_load_47x:
*/
DEBUG_CRIT_EXCEPTION
+interrupt_end:
+
/*
* Global functions
*/
diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h
index 5f051ee..df564e9 100644
--- a/arch/powerpc/kernel/head_booke.h
+++ b/arch/powerpc/kernel/head_booke.h
@@ -286,13 +286,13 @@ label:
andis. r10,r10,(DBSR_IC|DBSR_BT)@h; \
beq+ 2f; \
\
- lis r10,KERNELBASE@h; /* check if exception in vectors */ \
- ori r10,r10,KERNELBASE@l; \
+ lis r10,interrupt_base@h; /* check if exception in vectors */ \
+ ori r10,r10,interrupt_base@l; \
cmplw r12,r10; \
blt+ 2f; /* addr below exception vectors */ \
\
- lis r10,DebugDebug@h; \
- ori r10,r10,DebugDebug@l; \
+ lis r10,interrupt_end@h; \
+ ori r10,r10,interrupt_end@l; \
cmplw r12,r10; \
bgt+ 2f; /* addr above exception vectors */ \
\
@@ -339,13 +339,13 @@ label:
andis. r10,r10,(DBSR_IC|DBSR_BT)@h; \
beq+ 2f; \
\
- lis r10,KERNELBASE@h; /* check if exception in vectors */ \
- ori r10,r10,KERNELBASE@l; \
+ lis r10,interrupt_base@h; /* check if exception in vectors */ \
+ ori r10,r10,interrupt_base@l; \
cmplw r12,r10; \
blt+ 2f; /* addr below exception vectors */ \
\
- lis r10,DebugCrit@h; \
- ori r10,r10,DebugCrit@l; \
+ lis r10,interrupt_end@h; \
+ ori r10,r10,interrupt_end@l; \
cmplw r12,r10; \
bgt+ 2f; /* addr above exception vectors */ \
\
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index 6f62a73..d10a7ca 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -605,6 +605,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
/* Embedded Hypervisor Privilege */
EXCEPTION(0, HV_PRIV, Ehvpriv, unknown_exception, EXC_XFER_EE)
+interrupt_end:
+
/*
* Local functions
*/
--
1.5.6.5
^ permalink raw reply related
* flush_icache_range on AMCC 44x targets
From: Mike @ 2013-04-30 12:17 UTC (permalink / raw)
To: linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 1525 bytes --]
Hi,
i was reading trough arch/powerpc/kernel/misc32.S looking at the icbi and
iccci instructions, from whats on print in
http://s.eeweb.com/members/kvks_kumar/answers/1356585717-PPC440_UM2013.pdf(page
272) iccci should be used once in the power-on / reset routine, and
as far as flush_icache_range goes presumably before icbi is called?
So should not flush_icache_range go
#ifdef CONFIG_44x
iccci 0, r0
#endif
icbi 0,r6
arch/powerpc/kernel/misc32.S:
/*
* Write any modified data cache blocks out to memory
* and invalidate the corresponding instruction cache blocks.
* This is a no-op on the 601.
*
* flush_icache_range(unsigned long start, unsigned long stop)
*/
_KPROBE(__flush_icache_range)
BEGIN_FTR_SECTION
blr /* for 601, do nothing */
END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
li r5,L1_CACHE_BYTES-1
andc r3,r3,r5
subf r4,r3,r4
add r4,r4,r5
srwi. r4,r4,L1_CACHE_SHIFT
beqlr
mtctr r4
mr r6,r3
1: dcbst 0,r3
addi r3,r3,L1_CACHE_BYTES
bdnz 1b
sync /* wait for dcbst's to get to ram */
#ifndef CONFIG_44x
mtctr r4
2: icbi 0,r6
addi r6,r6,L1_CACHE_BYTES
bdnz 2b
#else
/* Flash invalidate on 44x because we are passed kmapped addresses and
this doesn't work for userspace pages due to the virtually tagged
icache. Sigh. */
iccci 0, r0
#endif
sync /* additional sync needed on g4 */
isync
blr
Best regards
-Mike
[-- Attachment #2: Type: text/html, Size: 1935 bytes --]
^ permalink raw reply
* RE: [PATCH 1/2 v15] iommu/fsl: Add additional iommu attributes required by the PAMU driver.
From: Sethi Varun-B16395 @ 2013-04-30 17:09 UTC (permalink / raw)
To: joro@8bytes.org, iommu@lists.linux-foundation.org,
linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org,
galak@kernel.crashing.org, benh@kernel.crashing.org,
Yoder Stuart-B08248, Wood Scott-B07421
In-Reply-To: <1366803351-17429-1-git-send-email-Varun.Sethi@freescale.com>
Hi Joerg,
Would you take this patchset for 3.10 merge?
Regards
Varun
> -----Original Message-----
> From: Sethi Varun-B16395
> Sent: Wednesday, April 24, 2013 5:06 PM
> To: joro@8bytes.org; iommu@lists.linux-foundation.org; linuxppc-
> dev@lists.ozlabs.org; linux-kernel@vger.kernel.org;
> galak@kernel.crashing.org; benh@kernel.crashing.org; Yoder Stuart-B08248;
> Wood Scott-B07421
> Cc: Sethi Varun-B16395
> Subject: [PATCH 1/2 v15] iommu/fsl: Add additional iommu attributes
> required by the PAMU driver.
>=20
> Added the following domain attributes for the FSL PAMU driver:
> 1. Added new iommu stash attribute, which allows setting of the
> LIODN specific stash id parameter through IOMMU API.
> 2. Added an attribute for enabling/disabling DMA to a particular
> memory window.
> 3. Added domain attribute to check for PAMUV1 specific constraints.
>=20
> Signed-off-by: Varun Sethi <Varun.Sethi@freescale.com>
> ---
> v15 changes:
> - Moved fsl_pamu_stash.h under arch/powerpc/include/asm.
> v14 changes:
> - Add FSL prefix to PAMU attributes.
> v13 changes:
> - created a new file include/linux/fsl_pamu_stash.h for stash attributes.
> v12 changes:
> - Moved PAMU specifc stash ids and structures to PAMU header file.
> - no change in v11.
> - no change in v10.
> arch/powerpc/include/asm/fsl_pamu_stash.h | 39
> +++++++++++++++++++++++++++++
> include/linux/iommu.h | 16 ++++++++++++
> 2 files changed, 55 insertions(+), 0 deletions(-) create mode 100644
> arch/powerpc/include/asm/fsl_pamu_stash.h
>=20
> diff --git a/arch/powerpc/include/asm/fsl_pamu_stash.h
> b/arch/powerpc/include/asm/fsl_pamu_stash.h
> new file mode 100644
> index 0000000..caa1b21
> --- /dev/null
> +++ b/arch/powerpc/include/asm/fsl_pamu_stash.h
> @@ -0,0 +1,39 @@
> +/*
> + * 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.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
> USA.
> + *
> + * Copyright (C) 2013 Freescale Semiconductor, Inc.
> + *
> + */
> +
> +#ifndef __FSL_PAMU_STASH_H
> +#define __FSL_PAMU_STASH_H
> +
> +/* cache stash targets */
> +enum pamu_stash_target {
> + PAMU_ATTR_CACHE_L1 =3D 1,
> + PAMU_ATTR_CACHE_L2,
> + PAMU_ATTR_CACHE_L3,
> +};
> +
> +/*
> + * This attribute allows configuring stashig specific parameters
> + * in the PAMU hardware.
> + */
> +
> +struct pamu_stash_attribute {
> + u32 cpu; /* cpu number */
> + u32 cache; /* cache to stash to: L1,L2,L3 */
> +};
> +
> +#endif /* __FSL_PAMU_STASH_H */
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h index
> 2727810..313d17a 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -57,10 +57,26 @@ struct iommu_domain {
> #define IOMMU_CAP_CACHE_COHERENCY 0x1
> #define IOMMU_CAP_INTR_REMAP 0x2 /* isolates device intrs */
>=20
> +/*
> + * Following constraints are specifc to FSL_PAMUV1:
> + * -aperture must be power of 2, and naturally aligned
> + * -number of windows must be power of 2, and address space size
> + * of each window is determined by aperture size / # of windows
> + * -the actual size of the mapped region of a window must be power
> + * of 2 starting with 4KB and physical address must be naturally
> + * aligned.
> + * DOMAIN_ATTR_FSL_PAMUV1 corresponds to the above mentioned contraints.
> + * The caller can invoke iommu_domain_get_attr to check if the
> +underlying
> + * iommu implementation supports these constraints.
> + */
> +
> enum iommu_attr {
> DOMAIN_ATTR_GEOMETRY,
> DOMAIN_ATTR_PAGING,
> DOMAIN_ATTR_WINDOWS,
> + DOMAIN_ATTR_FSL_PAMU_STASH,
> + DOMAIN_ATTR_FSL_PAMU_ENABLE,
> + DOMAIN_ATTR_FSL_PAMUV1,
> DOMAIN_ATTR_MAX,
> };
>=20
> --
> 1.7.4.1
^ permalink raw reply
* Re: [PATCH -V7 18/18] powerpc: Update tlbie/tlbiel as per ISA doc
From: Aneesh Kumar K.V @ 2013-04-30 17:21 UTC (permalink / raw)
To: David Gibson; +Cc: paulus, linuxppc-dev, linux-mm
In-Reply-To: <20130430061522.GC20202@truffula.fritz.box>
David Gibson <dwg@au1.ibm.com> writes:
> On Mon, Apr 29, 2013 at 01:07:39AM +0530, Aneesh Kumar K.V wrote:
>> From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
>>
>> Encode the actual page correctly in tlbie/tlbiel. This make sure we handle
>> multiple page size segment correctly.
>
> As mentioned in previous comments, this commit message needs to give
> much more detail about what precisely the existing implementation is
> doing wrong.
>
>>
>> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
>> ---
>> arch/powerpc/mm/hash_native_64.c | 32 ++++++++++++++++++++++++++++++--
>> 1 file changed, 30 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c
>> index bb920ee..6a2aead 100644
>> --- a/arch/powerpc/mm/hash_native_64.c
>> +++ b/arch/powerpc/mm/hash_native_64.c
>> @@ -61,7 +61,10 @@ static inline void __tlbie(unsigned long vpn, int psize, int apsize, int ssize)
>>
>> switch (psize) {
>> case MMU_PAGE_4K:
>> + /* clear out bits after (52) [0....52.....63] */
>> + va &= ~((1ul << (64 - 52)) - 1);
>> va |= ssize << 8;
>> + va |= mmu_psize_defs[apsize].sllp << 6;
>> asm volatile(ASM_FTR_IFCLR("tlbie %0,0", PPC_TLBIE(%1,%0), %2)
>> : : "r" (va), "r"(0), "i" (CPU_FTR_ARCH_206)
>> : "memory");
>> @@ -69,9 +72,20 @@ static inline void __tlbie(unsigned long vpn, int psize, int apsize, int ssize)
>> default:
>> /* We need 14 to 14 + i bits of va */
>> penc = mmu_psize_defs[psize].penc[apsize];
>> - va &= ~((1ul << mmu_psize_defs[psize].shift) - 1);
>> + va &= ~((1ul << mmu_psize_defs[apsize].shift) - 1);
>> va |= penc << 12;
>> va |= ssize << 8;
>> + /* Add AVAL part */
>> + if (psize != apsize) {
>> + /*
>> + * MPSS, 64K base page size and 16MB parge page size
>> + * We don't need all the bits, but rest of the bits
>> + * must be ignored by the processor.
>> + * vpn cover upto 65 bits of va. (0...65) and we need
>> + * 58..64 bits of va.
>
> I can't understand what this comment is saying. Why do we need to do
> something different in the psize != apsize case?
>
>> + */
>> + va |= (vpn & 0xfe);
>> + }
That is as per ISA doc. It says if base page size == actual page size,
(RB)56:62 must be zeros, which must be ignored by the processor.
Otherwise it should be filled with the selected bits of VA as explained above.
We only support MPSS with base page size = 64K and actual page size = 16MB.
-aneesh
^ permalink raw reply
* Re: ppc/sata-fsl: orphan config value: CONFIG_MPC8315_DS
From: Scott Wood @ 2013-04-30 18:15 UTC (permalink / raw)
To: Anthony Foiani
Cc: Li Yang-R58472, Jeff Garzik, Adrian Bunk, Anthony Foiani,
Robert P.J.Day, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <517F67AD.2010101@scrye.com>
On 04/30/2013 01:41:49 AM, Anthony Foiani wrote:
> Apologies for resurrecting a very old thread, but...
>=20
> On 05/30/2012 02:14 PM, Anthony Foiani wrote:
>>=20
>> Maybe someone who knows devtree really well could crank that out in a
>> few minutes... but I'm not that person. :)
> Well, I wasn't last year, but this year I decided that I didn't =20
> care. Took me about an hour, not a minute, but...
>=20
> Having been bitten by this config symbol disappearing one more time, =20
> please find attached my attempt at using information out of the =20
> device tree to enable this hack.
>=20
> Patch is against 3.4.36 or so; hopefully upstream hasn't diverged =20
> very much.
>=20
> Tested by me, so feel free to add that tag if required.
>=20
> Thanks,
> Anthony Foiani
------quoted attachment =20
"0001-sata-fsl-allow-device-tree-to-limit-sata-speed.patch"------
> >From c0a85758a669b430c0a6af825e71d18a54ef88d0 Mon Sep 17 00:00:00 =20
> 2001
> From: Anthony Foiani <anthony.foiani@gmail.com>
> Date: Mon, 29 Apr 2013 23:44:14 -0600
> Subject: [PATCH] sata: fsl: allow device tree to limit sata speed.
>=20
> There used to be an "orphan" config symbol (CONFIG_MPC8315_DS) that
> would artificially limit SATA speed to generation 1 (1.5Gbps).
>=20
> Since that config symbol got lost whenever any sort of configuration
> was done, we instead extract the limitation from the device tree.
>=20
> Signed-off-by: Anthony Foiani <anthony.foiani@gmail.com>
> ---
> .../devicetree/bindings/powerpc/fsl/board.txt | 23 +++++++++++
> drivers/ata/sata_fsl.c | 44 =20
> ++++++++++++++++++----
> 2 files changed, 59 insertions(+), 8 deletions(-)
>=20
> diff --git a/Documentation/devicetree/bindings/powerpc/fsl/board.txt =20
> b/Documentation/devicetree/bindings/powerpc/fsl/board.txt
> index 380914e..6a30398 100644
> --- a/Documentation/devicetree/bindings/powerpc/fsl/board.txt
> +++ b/Documentation/devicetree/bindings/powerpc/fsl/board.txt
> @@ -67,3 +67,26 @@ Example:
> gpio-controller;
> };
> };
> +
> +* Maximum SATA Generation workaround
> +
> +Some boards advertise SATA speeds that they cannot actually achieve.
> +Previously, this was dealt with via the orphaned config symbol
> +CONFIG_MPC8315_DS. We now have a device tree property
> +"fsl,sata-max-gen" to control this. It should live within the "sata"
> +block.
> +
> +Example:
> +
> + sata@18000 {
> + compatible =3D "fsl,mpc8315-sata", "fsl,pq-sata";
> + reg =3D <0x18000 0x1000>;
> + cell-index =3D <1>;
> + interrupts =3D <44 0x8>;
> + interrupt-parent =3D <&ipic>;
> + fsl,sata-max-gen =3D <1>;
> + };
> +
This might be OK for a new board, but adding it now means that people =20
using existing device trees won't get the workaround. It might be =20
better to just put the knowledge in platform code.
> +By default, there is no limitation; if a value is given, it indicates
> +the maximum "generation" that should be negotiated. Gen 1 is =20
> 1.5Gbps,
> +Gen 2 is 3.0Gbps.
> diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
> index d6577b9..6d3ec47 100644
> --- a/drivers/ata/sata_fsl.c
> +++ b/drivers/ata/sata_fsl.c
> @@ -274,6 +274,17 @@ struct sata_fsl_port_priv {
> };
>=20
> /*
> + * speed negotiation.
> + */
> +
> +enum {
> + SCR_SPEED_NEG_MASK =3D 0xf0,
> + SCR_SPEED_NEG_UNLIMITED =3D 0x00,
> + SCR_SPEED_NEG_GEN_1 =3D 0x10, /* 1.5Gbps max */
> + SCR_SPEED_NEG_GEN_2 =3D 0x20 /* 3.0Gbps max */
> +};
> +
> +/*
> * ata_port->host_set private data
> */
> struct sata_fsl_host_priv {
> @@ -282,6 +293,7 @@ struct sata_fsl_host_priv {
> void __iomem *csr_base;
> int irq;
> int data_snoop;
> + u32 speed_neg;
> struct device_attribute intr_coalescing;
> };
>=20
> @@ -726,19 +738,23 @@ static int sata_fsl_port_start(struct ata_port =20
> *ap)
> VPRINTK("HControl =3D 0x%x\n", ioread32(hcr_base + HCONTROL));
> VPRINTK("CHBA =3D 0x%x\n", ioread32(hcr_base + CHBA));
>=20
> -#ifdef CONFIG_MPC8315_DS
> /*
> * Workaround for 8315DS board 3gbps link-up issue,
> * currently limit SATA port to GEN1 speed
> */
> - sata_fsl_scr_read(&ap->link, SCR_CONTROL, &temp);
> - temp &=3D ~(0xF << 4);
> - temp |=3D (0x1 << 4);
> - sata_fsl_scr_write(&ap->link, SCR_CONTROL, temp);
> + if ( host_priv->speed_neg !=3D SCR_SPEED_NEG_UNLIMITED )
> + {
>=20
> - sata_fsl_scr_read(&ap->link, SCR_CONTROL, &temp);
> - dev_warn(dev, "scr_control, speed limited to %x\n", temp);
> -#endif
> + u32 orig;
> + sata_fsl_scr_read(&ap->link, SCR_CONTROL, &orig);
> + temp =3D ( ( orig & ~SCR_SPEED_NEG_MASK ) =20
> |
> + ( host_priv->speed_neg & SCR_SPEED_NEG_MASK ) =20
> );
> + sata_fsl_scr_write(&ap->link, SCR_CONTROL, temp);
> +
> + sata_fsl_scr_read(&ap->link, SCR_CONTROL, &temp);
> + dev_warn(dev, "speed limited, scr_control 0x%x -> =20
> 0x%x\n",
> + orig, temp);
> + }
>=20
> return 0;
> }
> @@ -1437,6 +1453,18 @@ static int sata_fsl_probe(struct =20
> platform_device *ofdev)
> else
> host_priv->data_snoop =3D DATA_SNOOP_ENABLE_V1;
>=20
> + if (!of_property_read_u32(ofdev->dev.of_node, =20
> "fsl,sata-max-gen",
> + &temp))
> + {
> + switch (temp)
> + {
> + case 1: host_priv->speed_neg =3D SCR_SPEED_NEG_GEN_1; =20
> break;
> + case 2: host_priv->speed_neg =3D SCR_SPEED_NEG_GEN_2; =20
> break;
> + }
> + dev_warn(&ofdev->dev, "speed limit set to gen %u =20
> (0x%x)\n",
> + temp, host_priv->speed_neg);
> + }
> +
> /* allocate host structure */
> host =3D ata_host_alloc_pinfo(&ofdev->dev, ppi, =20
> SATA_FSL_MAX_PORTS);
> if (!host) {
Please use standard Linux coding style, and submit the patch inline =20
rather than as an attachment (e.g. use git send-email).
-Scott=
^ permalink raw reply
* [PATCH v2 0/3] rapidio: changes to enumeration/discovery
From: Alexandre Bounine @ 2013-04-30 21:25 UTC (permalink / raw)
To: Andrew Morton, linux-kernel, linuxppc-dev
Cc: Micha Nelissen, Andre van Herk, Alexandre Bounine
Systems that use RapidIO fabric may need to implement their own enumeration
and discovery methods which are better suitable for needs of a target
application.
The following set of patches is intended to simplify process of introduction of
new RapidIO fabric enumeration/discovery methods.
The first patch offers ability to add new RapidIO enumeration/discovery methods
using kernel configuration options. This new configuration option mechanism
allows to select statically linked or modular enumeration/discovery method(s)
from the list of existing methods or use external module(s).
This patch also updates the currently existing enumeration/discovery code to be
used as a statically linked or modular method. The corresponding configuration
option is named "Basic enumeration/discovery" method. This is the only one
configuration option available today but new methods are expected to be
introduced after adoption of provided patches.
The second patch address a long time complaint of RapidIO subsystem users
regarding fabric enumeration/discovery start sequence. Existing implementation
offers only a boot-time enumeration/discovery start which requires synchronized
boot of all endpoints in RapidIO network. While it works for small closed
configurations with limited number of endpoints, using this approach in systems
with large number of endpoints is quite challenging.
To eliminate requirement for synchronized start the second patch introduces
RapidIO enumeration/discovery start from user space.
For compatibility with the existing RapidIO subsystem implementation, automatic
boot time enumeration/discovery start can be configured in by specifying
"rio-scan.scan=1" command line parameter if statically linked basic enumeration
method is selected.
Changes since v1:
(1) Addressed comments made by Andrew Morton for v1:
- reworked enumeration/discovery module initialization
- added locking for list of mport devices
- made mport list static
- removed CONFIG_RAPIDIO_ENUM_AUTO option: not needed with new
module initialization
- added default value for "Enumeration method" choice in Kconfig
Cc: Matt Porter <mporter@kernel.crashing.org>
Cc: Li Yang <leoli@freescale.com>
Cc: Kumar Gala <galak@kernel.crashing.org>
Cc: Andre van Herk <andre.van.herk@Prodrive.nl>
Cc: Micha Nelissen <micha.nelissen@Prodrive.nl>
Alexandre Bounine (3):
rapidio: make enumeration/discovery configurable
rapidio: add enumeration/discovery start from user space
rapidio: documentation update for enumeration changes
Documentation/rapidio/rapidio.txt | 128 ++++++++++++++++++--
Documentation/rapidio/sysfs.txt | 17 +++
drivers/rapidio/Kconfig | 20 +++
drivers/rapidio/Makefile | 3 +-
drivers/rapidio/rio-driver.c | 8 ++
drivers/rapidio/rio-scan.c | 190 +++++++++-------------------
drivers/rapidio/rio-sysfs.c | 45 +++++++
drivers/rapidio/rio.c | 246 +++++++++++++++++++++++++++++++++++-
drivers/rapidio/rio.h | 13 ++-
include/linux/rio.h | 18 +++-
include/linux/rio_drv.h | 1 +
11 files changed, 536 insertions(+), 153 deletions(-)
--
1.7.8.4
^ permalink raw reply
* [PATCH v2 3/3] rapidio: documentation update for enumeration changes
From: Alexandre Bounine @ 2013-04-30 21:25 UTC (permalink / raw)
To: Andrew Morton, linux-kernel, linuxppc-dev
Cc: Micha Nelissen, Andre van Herk, Alexandre Bounine
In-Reply-To: <1367357155-11586-1-git-send-email-alexandre.bounine@idt.com>
Update RapidIO documentation to reflect changes made to enumeration/discovery
build configuration and user space triggering mechanism.
Signed-off-by: Alexandre Bounine <alexandre.bounine@idt.com>
Cc: Matt Porter <mporter@kernel.crashing.org>
Cc: Li Yang <leoli@freescale.com>
Cc: Kumar Gala <galak@kernel.crashing.org>
Cc: Andre van Herk <andre.van.herk@Prodrive.nl>
Cc: Micha Nelissen <micha.nelissen@Prodrive.nl>
---
Documentation/rapidio/rapidio.txt | 128 +++++++++++++++++++++++++++++++++---
Documentation/rapidio/sysfs.txt | 17 +++++
2 files changed, 134 insertions(+), 11 deletions(-)
diff --git a/Documentation/rapidio/rapidio.txt b/Documentation/rapidio/rapidio.txt
index c75694b..a9c16c9 100644
--- a/Documentation/rapidio/rapidio.txt
+++ b/Documentation/rapidio/rapidio.txt
@@ -79,20 +79,63 @@ master port that is used to communicate with devices within the network.
In order to initialize the RapidIO subsystem, a platform must initialize and
register at least one master port within the RapidIO network. To register mport
within the subsystem controller driver initialization code calls function
-rio_register_mport() for each available master port. After all active master
-ports are registered with a RapidIO subsystem, the rio_init_mports() routine
-is called to perform enumeration and discovery.
+rio_register_mport() for each available master port.
-In the current PowerPC-based implementation a subsys_initcall() is specified to
-perform controller initialization and mport registration. At the end it directly
-calls rio_init_mports() to execute RapidIO enumeration and discovery.
+RapidIO subsystem uses subsys_initcall() or device_initcall() to perform
+controller initialization (depending on controller device type).
+
+After all active master ports are registered with a RapidIO subsystem,
+an enumeration and/or discovery routine may be called automatically or
+by user-space command.
4. Enumeration and Discovery
----------------------------
-When rio_init_mports() is called it scans a list of registered master ports and
-calls an enumeration or discovery routine depending on the configured role of a
-master port: host or agent.
+4.1 Overview
+------------
+
+RapidIO subsystem configuration options allow users to specify enumeration and
+discovery methods as statically linked components or loadable modules.
+An enumeration/discovery method implementation and available input parameters
+define how any given method can be attached to available RapidIO mports:
+simply to all available mports OR individually to the specified mport device.
+
+Depending on selected enumeration/discovery build configuration, there are
+several methods to initiate an enumeration and/or discovery process:
+
+ (a) Statically linked enumeration and discovery process can be started
+ automatically during kernel initialization time using corresponding module
+ parameters. This was the original method used since introduction of RapidIO
+ subsystem. Now this method relies on enumerator module parameter which is
+ 'rio-scan.scan' for existing basic enumeration/discovery method.
+ When automatic start of enumeration/discovery is used a user has to ensure
+ that all discovering endpoints are started before the enumerating endpoint
+ and are waiting for enumeration to be completed.
+ Configuration option CONFIG_RAPIDIO_DISC_TIMEOUT defines time that discovering
+ endpoint waits for enumeration to be completed. If the specified timeout
+ expires the discovery process is terminated without obtaining RapidIO network
+ information. NOTE: a timed out discovery process may be restarted later using
+ a user-space command as it is described later if the given endpoint was
+ enumerated successfully.
+
+ (b) Statically linked enumeration and discovery process can be started by
+ a command from user space. This initiation method provides more flexibility
+ for a system startup compared to the option (a) above. After all participating
+ endpoints have been successfully booted, an enumeration process shall be
+ started first by issuing a user-space command, after an enumeration is
+ completed a discovery process can be started on all remaining endpoints.
+
+ (c) Modular enumeration and discovery process can be started by a command from
+ user space. After an enumeration/discovery module is loaded, a network scan
+ process can be started by issuing a user-space command.
+ Similar to the option (b) above, an enumerator has to be started first.
+
+ (d) Modular enumeration and discovery process can be started by a module
+ initialization routine. In this case an enumerating module shall be loaded
+ first.
+
+When a network scan process is started it calls an enumeration or discovery
+routine depending on the configured role of a master port: host or agent.
Enumeration is performed by a master port if it is configured as a host port by
assigning a host device ID greater than or equal to zero. A host device ID is
@@ -104,8 +147,58 @@ for it.
The enumeration and discovery routines use RapidIO maintenance transactions
to access the configuration space of devices.
-The enumeration process is implemented according to the enumeration algorithm
-outlined in the RapidIO Interconnect Specification: Annex I [1].
+4.2 Automatic Start of Enumeration and Discovery
+------------------------------------------------
+
+Automatic enumeration/discovery start method is applicable only to built-in
+enumeration/discovery RapidIO configuration selection. To enable automatic
+enumeration/discovery start by existing basic enumerator method set use boot
+command line parameter "rio-scan.scan=1".
+
+This configuration requires synchronized start of all RapidIO endpoints that
+form a network which will be enumerated/discovered. Discovering endpoints have
+to be started before an enumeration starts to ensure that all RapidIO
+controllers have been initialized and are ready to be discovered. Configuration
+parameter CONFIG_RAPIDIO_DISC_TIMEOUT defines time (in seconds) which
+a discovering endpoint will wait for enumeration to be completed.
+
+When automatic enumeration/discovery start is selected, basic method's
+initialization routine calls rio_init_mports() to perform enumeration or
+discovery for all known mport devices.
+
+Depending on RapidIO network size and configuration this automatic
+enumeration/discovery start method may be difficult to use due to the
+requirement for synchronized start of all endpoints.
+
+4.3 User-space Start of Enumeration and Discovery
+-------------------------------------------------
+
+User-space start of enumeration and discovery can be used with built-in and
+modular build configurations. For user-space controlled start RapidIO subsystem
+creates the sysfs write-only attribute file '/sys/bus/rapidio/scan'. To initiate
+an enumeration or discovery process on specific mport device, a user needs to
+write mport_ID (not RapidIO destination ID) into that file. The mport_ID is a
+sequential number (0 ... RIO_MAX_MPORTS) assigned during mport device
+registration. For example for machine with single RapidIO controller, mport_ID
+for that controller always will be 0.
+
+To initiate RapidIO enumeration/discovery on all available mports a user may
+write '-1' (or RIO_MPORT_ANY) into the scan attribute file.
+
+4.4 Basic Enumeration Method
+----------------------------
+
+This is an original enumeration/discovery method which is available since
+first release of RapidIO subsystem code. The enumeration process is
+implemented according to the enumeration algorithm outlined in the RapidIO
+Interconnect Specification: Annex I [1].
+
+This method can be configured as statically linked or loadable module.
+The method's single parameter "scan" allows to trigger the enumeration/discovery
+process from module initialization routine.
+
+This enumeration/discovery method can be started only once and does not support
+unloading if it is built as a module.
The enumeration process traverses the network using a recursive depth-first
algorithm. When a new device is found, the enumerator takes ownership of that
@@ -160,6 +253,19 @@ time period. If this wait time period expires before enumeration is completed,
an agent skips RapidIO discovery and continues with remaining kernel
initialization.
+4.5 Adding New Enumeration/Discovery Method
+-------------------------------------------
+
+RapidIO subsystem code organization allows addition of new enumeration/discovery
+methods as new configuration options without significant impact to to the core
+RapidIO code.
+
+A new enumeration/discovery method has to be attached to one or more mport
+devices before an enumeration/discovery process can be started. Normally,
+method's module initialization routine calls rio_register_scan() to attach
+an enumerator to a specified mport device (or devices). The basic enumerator
+implementation demonstrates this process.
+
5. References
-------------
diff --git a/Documentation/rapidio/sysfs.txt b/Documentation/rapidio/sysfs.txt
index 97f71ce..1987817 100644
--- a/Documentation/rapidio/sysfs.txt
+++ b/Documentation/rapidio/sysfs.txt
@@ -88,3 +88,20 @@ that exports additional attributes.
IDT_GEN2:
errlog - reads contents of device error log until it is empty.
+
+
+5. RapidIO Bus Attributes
+-------------------------
+
+RapidIO bus subdirectory /sys/bus/rapidio implements the following bus-specific
+attribute:
+
+ scan - allows to trigger enumeration discovery process from user space. This
+ is a write-only attribute. To initiate an enumeration or discovery
+ process on specific mport device, a user needs to write mport_ID (not
+ RapidIO destination ID) into this file. The mport_ID is a sequential
+ number (0 ... RIO_MAX_MPORTS) assigned to the mport device.
+ For example, for a machine with a single RapidIO controller, mport_ID
+ for that controller always will be 0.
+ To initiate RapidIO enumeration/discovery on all available mports
+ a user must write '-1' (or RIO_MPORT_ANY) into this attribute file.
--
1.7.8.4
^ permalink raw reply related
* [PATCH v2 2/3] rapidio: add enumeration/discovery start from user space
From: Alexandre Bounine @ 2013-04-30 21:25 UTC (permalink / raw)
To: Andrew Morton, linux-kernel, linuxppc-dev
Cc: Micha Nelissen, Andre van Herk, Alexandre Bounine
In-Reply-To: <1367357155-11586-1-git-send-email-alexandre.bounine@idt.com>
Add RapidIO enumeration/discovery start from user space.
User space start allows to defer RapidIO fabric scan until the moment when all
participating endpoints are initialized avoiding mandatory synchronized start
of all endpoints (which may be challenging in systems with large number of
RapidIO endpoints).
Signed-off-by: Alexandre Bounine <alexandre.bounine@idt.com>
Cc: Matt Porter <mporter@kernel.crashing.org>
Cc: Li Yang <leoli@freescale.com>
Cc: Kumar Gala <galak@kernel.crashing.org>
Cc: Andre van Herk <andre.van.herk@Prodrive.nl>
Cc: Micha Nelissen <micha.nelissen@Prodrive.nl>
---
drivers/rapidio/rio-driver.c | 1 +
drivers/rapidio/rio-scan.c | 24 +++++++++++++++++++--
drivers/rapidio/rio-sysfs.c | 45 ++++++++++++++++++++++++++++++++++++++++++
drivers/rapidio/rio.c | 28 ++++++++++++++++++++++++-
drivers/rapidio/rio.h | 2 +
include/linux/rio.h | 9 ++++++-
6 files changed, 102 insertions(+), 7 deletions(-)
diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c
index 55850bb..a0c8755 100644
--- a/drivers/rapidio/rio-driver.c
+++ b/drivers/rapidio/rio-driver.c
@@ -207,6 +207,7 @@ struct bus_type rio_bus_type = {
.name = "rapidio",
.match = rio_match_bus,
.dev_attrs = rio_dev_attrs,
+ .bus_attrs = rio_bus_attrs,
.probe = rio_device_probe,
.remove = rio_device_remove,
};
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 7bdc674..4c15dbf 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -1134,19 +1134,30 @@ static void rio_pw_enable(struct rio_mport *port, int enable)
/**
* rio_enum_mport- Start enumeration through a master port
* @mport: Master port to send transactions
+ * @flags: Enumeration control flags
*
* Starts the enumeration process. If somebody has enumerated our
* master port device, then give up. If not and we have an active
* link, then start recursive peer enumeration. Returns %0 if
* enumeration succeeds or %-EBUSY if enumeration fails.
*/
-int rio_enum_mport(struct rio_mport *mport)
+int rio_enum_mport(struct rio_mport *mport, u32 flags)
{
struct rio_net *net = NULL;
int rc = 0;
printk(KERN_INFO "RIO: enumerate master port %d, %s\n", mport->id,
mport->name);
+
+ /*
+ * To avoid multiple start requests (repeat enumeration is not supported
+ * by this method) check if enumeration/discovery was performed for this
+ * mport: if mport was added into the list of mports for a net exit
+ * with error.
+ */
+ if (mport->nnode.next || mport->nnode.prev)
+ return -EBUSY;
+
/* If somebody else enumerated our master port device, bail. */
if (rio_enum_host(mport) < 0) {
printk(KERN_INFO
@@ -1236,14 +1247,16 @@ static void rio_build_route_tables(struct rio_net *net)
/**
* rio_disc_mport- Start discovery through a master port
* @mport: Master port to send transactions
+ * @flags: discovery control flags
*
* Starts the discovery process. If we have an active link,
- * then wait for the signal that enumeration is complete.
+ * then wait for the signal that enumeration is complete (if wait
+ * is allowed).
* When enumeration completion is signaled, start recursive
* peer discovery. Returns %0 if discovery succeeds or %-EBUSY
* on failure.
*/
-int rio_disc_mport(struct rio_mport *mport)
+int rio_disc_mport(struct rio_mport *mport, u32 flags)
{
struct rio_net *net = NULL;
unsigned long to_end;
@@ -1253,6 +1266,11 @@ int rio_disc_mport(struct rio_mport *mport)
/* If master port has an active link, allocate net and discover peers */
if (rio_mport_is_active(mport)) {
+ if (rio_enum_complete(mport))
+ goto enum_done;
+ else if (flags & RIO_SCAN_ENUM_NO_WAIT)
+ return -EAGAIN;
+
pr_debug("RIO: wait for enumeration to complete...\n");
to_end = jiffies + CONFIG_RAPIDIO_DISC_TIMEOUT * HZ;
diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c
index 4dbe360..66d4acd 100644
--- a/drivers/rapidio/rio-sysfs.c
+++ b/drivers/rapidio/rio-sysfs.c
@@ -285,3 +285,48 @@ void rio_remove_sysfs_dev_files(struct rio_dev *rdev)
rdev->rswitch->sw_sysfs(rdev, RIO_SW_SYSFS_REMOVE);
}
}
+
+static ssize_t bus_scan_store(struct bus_type *bus, const char *buf,
+ size_t count)
+{
+ long val;
+ struct rio_mport *port = NULL;
+ int rc;
+
+ if (kstrtol(buf, 0, &val) < 0)
+ return -EINVAL;
+
+ if (val == RIO_MPORT_ANY) {
+ rc = rio_init_mports();
+ goto exit;
+ }
+
+ if (val < 0 || val >= RIO_MAX_MPORTS)
+ return -EINVAL;
+
+ port = rio_find_mport((int)val);
+
+ if (!port) {
+ pr_debug("RIO: %s: mport_%d not available\n",
+ __func__, (int)val);
+ return -EINVAL;
+ }
+
+ if (!port->nscan)
+ return -EINVAL;
+
+ if (port->host_deviceid >= 0)
+ rc = port->nscan->enumerate(port, 0);
+ else
+ rc = port->nscan->discover(port, RIO_SCAN_ENUM_NO_WAIT);
+exit:
+ if (!rc)
+ rc = count;
+
+ return rc;
+}
+
+struct bus_attribute rio_bus_attrs[] = {
+ __ATTR(scan, (S_IWUSR|S_IWGRP), NULL, bus_scan_store),
+ __ATTR_NULL
+};
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index 6e75dda..cb1c089 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -1383,6 +1383,30 @@ EXPORT_SYMBOL_GPL(rio_dma_prep_slave_sg);
#endif /* CONFIG_RAPIDIO_DMA_ENGINE */
/**
+ * rio_find_mport - find RIO mport by its ID
+ * @mport_id: number (ID) of mport device
+ *
+ * Given a RIO mport number, the desired mport is located
+ * in the global list of mports. If the mport is found, a pointer to its
+ * data structure is returned. If no mport is found, %NULL is returned.
+ */
+struct rio_mport *rio_find_mport(int mport_id)
+{
+ struct rio_mport *port;
+
+ mutex_lock(&rio_mport_list_lock);
+ list_for_each_entry(port, &rio_mports, node) {
+ if (port->id == mport_id)
+ goto found;
+ }
+ port = NULL;
+found:
+ mutex_unlock(&rio_mport_list_lock);
+
+ return port;
+}
+
+/**
* rio_register_scan - enumeration/discovery method registration interface
* @mport_id: mport device ID for which fabric scan routine has to be set
* (RIO_MPORT_ANY = set for all available mports)
@@ -1475,7 +1499,7 @@ static void disc_work_handler(struct work_struct *_work)
work = container_of(_work, struct rio_disc_work, work);
pr_debug("RIO: discovery work for mport %d %s\n",
work->mport->id, work->mport->name);
- work->mport->nscan->discover(work->mport);
+ work->mport->nscan->discover(work->mport, 0);
}
int rio_init_mports(void)
@@ -1495,7 +1519,7 @@ int rio_init_mports(void)
list_for_each_entry(port, &rio_mports, node) {
if (port->host_deviceid >= 0) {
if (port->nscan)
- port->nscan->enumerate(port);
+ port->nscan->enumerate(port, 0);
} else
n++;
}
diff --git a/drivers/rapidio/rio.h b/drivers/rapidio/rio.h
index 0afdf48..c14f864 100644
--- a/drivers/rapidio/rio.h
+++ b/drivers/rapidio/rio.h
@@ -45,9 +45,11 @@ extern int rio_enable_rx_tx_port(struct rio_mport *port, int local, u16 destid,
extern int rio_register_scan(int mport_id, struct rio_scan *scan_ops);
extern int rio_unregister_scan(int mport_id);
extern void rio_attach_device(struct rio_dev *rdev);
+extern struct rio_mport *rio_find_mport(int mport_id);
/* Structures internal to the RIO core code */
extern struct device_attribute rio_dev_attrs[];
+extern struct bus_attribute rio_bus_attrs[];
extern struct rio_switch_ops __start_rio_switch_ops[];
extern struct rio_switch_ops __end_rio_switch_ops[];
diff --git a/include/linux/rio.h b/include/linux/rio.h
index cd3796e..18e0993 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -265,6 +265,11 @@ struct rio_mport {
struct rio_scan *nscan;
};
+/*
+ * Enumeration/discovery control flags
+ */
+#define RIO_SCAN_ENUM_NO_WAIT 0x00000001 /* Do not wait for enum completed */
+
struct rio_id_table {
u16 start; /* logical minimal id */
u32 max; /* max number of IDs in table */
@@ -467,8 +472,8 @@ static inline struct rio_mport *dma_to_mport(struct dma_device *ddev)
* @discover: Callback to perform RapidIO fabric discovery.
*/
struct rio_scan {
- int (*enumerate)(struct rio_mport *mport);
- int (*discover)(struct rio_mport *mport);
+ int (*enumerate)(struct rio_mport *mport, u32 flags);
+ int (*discover)(struct rio_mport *mport, u32 flags);
};
/* Architecture and hardware-specific functions */
--
1.7.8.4
^ permalink raw reply related
* [PATCH v2 1/3] rapidio: make enumeration/discovery configurable
From: Alexandre Bounine @ 2013-04-30 21:25 UTC (permalink / raw)
To: Andrew Morton, linux-kernel, linuxppc-dev
Cc: Micha Nelissen, Andre van Herk, Alexandre Bounine
In-Reply-To: <1367357155-11586-1-git-send-email-alexandre.bounine@idt.com>
Rework to implement RapidIO enumeration/discovery method selection
combined with ability to use enumeration/discovery as a kernel module.
This patch adds ability to introduce new RapidIO enumeration/discovery methods
using kernel configuration options. Configuration option mechanism allows to select
statically linked or modular enumeration/discovery method from the list of existing
methods or use external modules.
If a modular enumeration/discovery is selected each RapidIO mport device can
have its own method attached to it.
The existing enumeration/discovery code was updated to be used as statically
linked or modular method. This configuration option is named "Basic
enumeration/discovery" method.
Several common routines have been moved from rio-scan.c to make them available
to other enumeration methods and reduce number of exported symbols.
Signed-off-by: Alexandre Bounine <alexandre.bounine@idt.com>
Cc: Matt Porter <mporter@kernel.crashing.org>
Cc: Li Yang <leoli@freescale.com>
Cc: Kumar Gala <galak@kernel.crashing.org>
Cc: Andre van Herk <andre.van.herk@Prodrive.nl>
Cc: Micha Nelissen <micha.nelissen@Prodrive.nl>
---
drivers/rapidio/Kconfig | 20 ++++
drivers/rapidio/Makefile | 3 +-
drivers/rapidio/rio-driver.c | 7 ++
drivers/rapidio/rio-scan.c | 166 ++++++++------------------------
drivers/rapidio/rio.c | 222 ++++++++++++++++++++++++++++++++++++++++--
drivers/rapidio/rio.h | 11 ++-
include/linux/rio.h | 13 +++-
include/linux/rio_drv.h | 1 +
8 files changed, 304 insertions(+), 139 deletions(-)
diff --git a/drivers/rapidio/Kconfig b/drivers/rapidio/Kconfig
index 6194d35..5ab0564 100644
--- a/drivers/rapidio/Kconfig
+++ b/drivers/rapidio/Kconfig
@@ -47,4 +47,24 @@ config RAPIDIO_DEBUG
If you are unsure about this, say N here.
+choice
+ prompt "Enumeration method"
+ depends on RAPIDIO
+ default RAPIDIO_ENUM_BASIC
+ help
+ There are different enumeration and discovery mechanisms offered
+ for RapidIO subsystem. You may select single built-in method or
+ or any number of methods to be built as modules.
+ Selecting a built-in method disables use of loadable methods.
+
+ If unsure, select Basic built-in.
+
+config RAPIDIO_ENUM_BASIC
+ tristate "Basic"
+ help
+ This option includes basic RapidIO fabric enumeration and discovery
+ mechanism similar to one described in RapidIO specification Annex 1.
+
+endchoice
+
source "drivers/rapidio/switches/Kconfig"
diff --git a/drivers/rapidio/Makefile b/drivers/rapidio/Makefile
index ec3fb81..3036702 100644
--- a/drivers/rapidio/Makefile
+++ b/drivers/rapidio/Makefile
@@ -1,7 +1,8 @@
#
# Makefile for RapidIO interconnect services
#
-obj-y += rio.o rio-access.o rio-driver.o rio-scan.o rio-sysfs.o
+obj-y += rio.o rio-access.o rio-driver.o rio-sysfs.o
+obj-$(CONFIG_RAPIDIO_ENUM_BASIC) += rio-scan.o
obj-$(CONFIG_RAPIDIO) += switches/
obj-$(CONFIG_RAPIDIO) += devices/
diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c
index 0f4a53b..55850bb 100644
--- a/drivers/rapidio/rio-driver.c
+++ b/drivers/rapidio/rio-driver.c
@@ -164,6 +164,13 @@ void rio_unregister_driver(struct rio_driver *rdrv)
driver_unregister(&rdrv->driver);
}
+void rio_attach_device(struct rio_dev *rdev)
+{
+ rdev->dev.bus = &rio_bus_type;
+ rdev->dev.parent = &rio_bus;
+}
+EXPORT_SYMBOL_GPL(rio_attach_device);
+
/**
* rio_match_bus - Tell if a RIO device structure has a matching RIO driver device id structure
* @dev: the standard device structure to match against
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index a965acd..7bdc674 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -37,12 +37,8 @@
#include "rio.h"
-LIST_HEAD(rio_devices);
-
static void rio_init_em(struct rio_dev *rdev);
-DEFINE_SPINLOCK(rio_global_list_lock);
-
static int next_destid = 0;
static int next_comptag = 1;
@@ -327,127 +323,6 @@ static int rio_is_switch(struct rio_dev *rdev)
}
/**
- * rio_switch_init - Sets switch operations for a particular vendor switch
- * @rdev: RIO device
- * @do_enum: Enumeration/Discovery mode flag
- *
- * Searches the RIO switch ops table for known switch types. If the vid
- * and did match a switch table entry, then call switch initialization
- * routine to setup switch-specific routines.
- */
-static void rio_switch_init(struct rio_dev *rdev, int do_enum)
-{
- struct rio_switch_ops *cur = __start_rio_switch_ops;
- struct rio_switch_ops *end = __end_rio_switch_ops;
-
- while (cur < end) {
- if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) {
- pr_debug("RIO: calling init routine for %s\n",
- rio_name(rdev));
- cur->init_hook(rdev, do_enum);
- break;
- }
- cur++;
- }
-
- if ((cur >= end) && (rdev->pef & RIO_PEF_STD_RT)) {
- pr_debug("RIO: adding STD routing ops for %s\n",
- rio_name(rdev));
- rdev->rswitch->add_entry = rio_std_route_add_entry;
- rdev->rswitch->get_entry = rio_std_route_get_entry;
- rdev->rswitch->clr_table = rio_std_route_clr_table;
- }
-
- if (!rdev->rswitch->add_entry || !rdev->rswitch->get_entry)
- printk(KERN_ERR "RIO: missing routing ops for %s\n",
- rio_name(rdev));
-}
-
-/**
- * rio_add_device- Adds a RIO device to the device model
- * @rdev: RIO device
- *
- * Adds the RIO device to the global device list and adds the RIO
- * device to the RIO device list. Creates the generic sysfs nodes
- * for an RIO device.
- */
-static int rio_add_device(struct rio_dev *rdev)
-{
- int err;
-
- err = device_add(&rdev->dev);
- if (err)
- return err;
-
- spin_lock(&rio_global_list_lock);
- list_add_tail(&rdev->global_list, &rio_devices);
- spin_unlock(&rio_global_list_lock);
-
- rio_create_sysfs_dev_files(rdev);
-
- return 0;
-}
-
-/**
- * rio_enable_rx_tx_port - enable input receiver and output transmitter of
- * given port
- * @port: Master port associated with the RIO network
- * @local: local=1 select local port otherwise a far device is reached
- * @destid: Destination ID of the device to check host bit
- * @hopcount: Number of hops to reach the target
- * @port_num: Port (-number on switch) to enable on a far end device
- *
- * Returns 0 or 1 from on General Control Command and Status Register
- * (EXT_PTR+0x3C)
- */
-inline int rio_enable_rx_tx_port(struct rio_mport *port,
- int local, u16 destid,
- u8 hopcount, u8 port_num) {
-#ifdef CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS
- u32 regval;
- u32 ext_ftr_ptr;
-
- /*
- * enable rx input tx output port
- */
- pr_debug("rio_enable_rx_tx_port(local = %d, destid = %d, hopcount = "
- "%d, port_num = %d)\n", local, destid, hopcount, port_num);
-
- ext_ftr_ptr = rio_mport_get_physefb(port, local, destid, hopcount);
-
- if (local) {
- rio_local_read_config_32(port, ext_ftr_ptr +
- RIO_PORT_N_CTL_CSR(0),
- ®val);
- } else {
- if (rio_mport_read_config_32(port, destid, hopcount,
- ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), ®val) < 0)
- return -EIO;
- }
-
- if (regval & RIO_PORT_N_CTL_P_TYP_SER) {
- /* serial */
- regval = regval | RIO_PORT_N_CTL_EN_RX_SER
- | RIO_PORT_N_CTL_EN_TX_SER;
- } else {
- /* parallel */
- regval = regval | RIO_PORT_N_CTL_EN_RX_PAR
- | RIO_PORT_N_CTL_EN_TX_PAR;
- }
-
- if (local) {
- rio_local_write_config_32(port, ext_ftr_ptr +
- RIO_PORT_N_CTL_CSR(0), regval);
- } else {
- if (rio_mport_write_config_32(port, destid, hopcount,
- ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), regval) < 0)
- return -EIO;
- }
-#endif
- return 0;
-}
-
-/**
* rio_setup_device- Allocates and sets up a RIO device
* @net: RIO network
* @port: Master port to send transactions
@@ -587,8 +462,7 @@ static struct rio_dev *rio_setup_device(struct rio_net *net,
rdev->destid);
}
- rdev->dev.bus = &rio_bus_type;
- rdev->dev.parent = &rio_bus;
+ rio_attach_device(rdev);
device_initialize(&rdev->dev);
rdev->dev.release = rio_release_dev;
@@ -1421,3 +1295,41 @@ enum_done:
bail:
return -EBUSY;
}
+
+static struct rio_scan rio_scan_ops = {
+ .enumerate = rio_enum_mport,
+ .discover = rio_disc_mport,
+};
+
+static bool scan;
+module_param(scan, bool, 0);
+MODULE_PARM_DESC(scan, "Start RapidIO network enumeration/discovery "
+ "(default = 0)");
+
+/**
+ * rio_basic_attach:
+ *
+ * When this enumeration/discovery method is loaded as a module this function
+ * registers its specific enumeration and discover routines for all available
+ * RapidIO mport devices. The "scan" command line parameter controls ability of
+ * the module to start RapidIO enumeration/discovery automatically.
+ *
+ * Returns 0 for success or -EIO if unable to register itself.
+ *
+ * This enumeration/discovery method cannot be unloaded and therefore does not
+ * provide a matching cleanup_module routine.
+ */
+
+static int __init rio_basic_attach(void)
+{
+ if (rio_register_scan(RIO_MPORT_ANY, &rio_scan_ops))
+ return -EIO;
+ if (scan)
+ rio_init_mports();
+ return 0;
+}
+
+late_initcall(rio_basic_attach);
+
+MODULE_DESCRIPTION("Basic RapidIO enumeration/discovery");
+MODULE_LICENSE("GPL");
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index d553b5d..6e75dda 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -31,7 +31,11 @@
#include "rio.h"
+static LIST_HEAD(rio_devices);
+static DEFINE_SPINLOCK(rio_global_list_lock);
+
static LIST_HEAD(rio_mports);
+static DEFINE_MUTEX(rio_mport_list_lock);
static unsigned char next_portid;
static DEFINE_SPINLOCK(rio_mmap_lock);
@@ -53,6 +57,32 @@ u16 rio_local_get_device_id(struct rio_mport *port)
}
/**
+ * rio_add_device- Adds a RIO device to the device model
+ * @rdev: RIO device
+ *
+ * Adds the RIO device to the global device list and adds the RIO
+ * device to the RIO device list. Creates the generic sysfs nodes
+ * for an RIO device.
+ */
+int rio_add_device(struct rio_dev *rdev)
+{
+ int err;
+
+ err = device_add(&rdev->dev);
+ if (err)
+ return err;
+
+ spin_lock(&rio_global_list_lock);
+ list_add_tail(&rdev->global_list, &rio_devices);
+ spin_unlock(&rio_global_list_lock);
+
+ rio_create_sysfs_dev_files(rdev);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rio_add_device);
+
+/**
* rio_request_inb_mbox - request inbound mailbox service
* @mport: RIO master port from which to allocate the mailbox resource
* @dev_id: Device specific pointer to pass on event
@@ -489,6 +519,7 @@ rio_mport_get_physefb(struct rio_mport *port, int local,
return ext_ftr_ptr;
}
+EXPORT_SYMBOL_GPL(rio_mport_get_physefb);
/**
* rio_get_comptag - Begin or continue searching for a RIO device by component tag
@@ -521,6 +552,7 @@ exit:
spin_unlock(&rio_global_list_lock);
return rdev;
}
+EXPORT_SYMBOL_GPL(rio_get_comptag);
/**
* rio_set_port_lockout - Sets/clears LOCKOUT bit (RIO EM 1.3) for a switch port.
@@ -545,6 +577,107 @@ int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock)
regval);
return 0;
}
+EXPORT_SYMBOL_GPL(rio_set_port_lockout);
+
+/**
+ * rio_switch_init - Sets switch operations for a particular vendor switch
+ * @rdev: RIO device
+ * @do_enum: Enumeration/Discovery mode flag
+ *
+ * Searches the RIO switch ops table for known switch types. If the vid
+ * and did match a switch table entry, then call switch initialization
+ * routine to setup switch-specific routines.
+ */
+void rio_switch_init(struct rio_dev *rdev, int do_enum)
+{
+ struct rio_switch_ops *cur = __start_rio_switch_ops;
+ struct rio_switch_ops *end = __end_rio_switch_ops;
+
+ while (cur < end) {
+ if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) {
+ pr_debug("RIO: calling init routine for %s\n",
+ rio_name(rdev));
+ cur->init_hook(rdev, do_enum);
+ break;
+ }
+ cur++;
+ }
+
+ if ((cur >= end) && (rdev->pef & RIO_PEF_STD_RT)) {
+ pr_debug("RIO: adding STD routing ops for %s\n",
+ rio_name(rdev));
+ rdev->rswitch->add_entry = rio_std_route_add_entry;
+ rdev->rswitch->get_entry = rio_std_route_get_entry;
+ rdev->rswitch->clr_table = rio_std_route_clr_table;
+ }
+
+ if (!rdev->rswitch->add_entry || !rdev->rswitch->get_entry)
+ printk(KERN_ERR "RIO: missing routing ops for %s\n",
+ rio_name(rdev));
+}
+EXPORT_SYMBOL_GPL(rio_switch_init);
+
+/**
+ * rio_enable_rx_tx_port - enable input receiver and output transmitter of
+ * given port
+ * @port: Master port associated with the RIO network
+ * @local: local=1 select local port otherwise a far device is reached
+ * @destid: Destination ID of the device to check host bit
+ * @hopcount: Number of hops to reach the target
+ * @port_num: Port (-number on switch) to enable on a far end device
+ *
+ * Returns 0 or 1 from on General Control Command and Status Register
+ * (EXT_PTR+0x3C)
+ */
+int rio_enable_rx_tx_port(struct rio_mport *port,
+ int local, u16 destid,
+ u8 hopcount, u8 port_num)
+{
+#ifdef CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS
+ u32 regval;
+ u32 ext_ftr_ptr;
+
+ /*
+ * enable rx input tx output port
+ */
+ pr_debug("rio_enable_rx_tx_port(local = %d, destid = %d, hopcount = "
+ "%d, port_num = %d)\n", local, destid, hopcount, port_num);
+
+ ext_ftr_ptr = rio_mport_get_physefb(port, local, destid, hopcount);
+
+ if (local) {
+ rio_local_read_config_32(port, ext_ftr_ptr +
+ RIO_PORT_N_CTL_CSR(0),
+ ®val);
+ } else {
+ if (rio_mport_read_config_32(port, destid, hopcount,
+ ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), ®val) < 0)
+ return -EIO;
+ }
+
+ if (regval & RIO_PORT_N_CTL_P_TYP_SER) {
+ /* serial */
+ regval = regval | RIO_PORT_N_CTL_EN_RX_SER
+ | RIO_PORT_N_CTL_EN_TX_SER;
+ } else {
+ /* parallel */
+ regval = regval | RIO_PORT_N_CTL_EN_RX_PAR
+ | RIO_PORT_N_CTL_EN_TX_PAR;
+ }
+
+ if (local) {
+ rio_local_write_config_32(port, ext_ftr_ptr +
+ RIO_PORT_N_CTL_CSR(0), regval);
+ } else {
+ if (rio_mport_write_config_32(port, destid, hopcount,
+ ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), regval) < 0)
+ return -EIO;
+ }
+#endif
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rio_enable_rx_tx_port);
+
/**
* rio_chk_dev_route - Validate route to the specified device.
@@ -610,6 +743,7 @@ rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid, u8 hopcount)
return 0;
}
+EXPORT_SYMBOL_GPL(rio_mport_chk_dev_access);
/**
* rio_chk_dev_access - Validate access to the specified device.
@@ -941,6 +1075,7 @@ rio_mport_get_efb(struct rio_mport *port, int local, u16 destid,
return RIO_GET_BLOCK_ID(reg_val);
}
}
+EXPORT_SYMBOL_GPL(rio_mport_get_efb);
/**
* rio_mport_get_feature - query for devices' extended features
@@ -997,6 +1132,7 @@ rio_mport_get_feature(struct rio_mport * port, int local, u16 destid,
return 0;
}
+EXPORT_SYMBOL_GPL(rio_mport_get_feature);
/**
* rio_get_asm - Begin or continue searching for a RIO device by vid/did/asm_vid/asm_did
@@ -1246,6 +1382,71 @@ EXPORT_SYMBOL_GPL(rio_dma_prep_slave_sg);
#endif /* CONFIG_RAPIDIO_DMA_ENGINE */
+/**
+ * rio_register_scan - enumeration/discovery method registration interface
+ * @mport_id: mport device ID for which fabric scan routine has to be set
+ * (RIO_MPORT_ANY = set for all available mports)
+ * @scan_ops: enumeration/discovery control structure
+ *
+ * Assigns enumeration or discovery method to the specified mport device (or all
+ * available mports if RIO_MPORT_ANY is specified).
+ * Returns error if the mport already has an enumerator attached to it.
+ * In case of RIO_MPORT_ANY ignores ports with valid scan routines and returns
+ * an error if was unable to find at least one available mport.
+ */
+int rio_register_scan(int mport_id, struct rio_scan *scan_ops)
+{
+ struct rio_mport *port;
+ int rc = -EBUSY;
+
+ mutex_lock(&rio_mport_list_lock);
+ list_for_each_entry(port, &rio_mports, node) {
+ if (port->id == mport_id || mport_id == RIO_MPORT_ANY) {
+ if (port->nscan && mport_id == RIO_MPORT_ANY)
+ continue;
+ else if (port->nscan)
+ break;
+
+ port->nscan = scan_ops;
+ rc = 0;
+
+ if (mport_id != RIO_MPORT_ANY)
+ break;
+ }
+ }
+ mutex_unlock(&rio_mport_list_lock);
+
+ return rc;
+}
+EXPORT_SYMBOL_GPL(rio_register_scan);
+
+/**
+ * rio_unregister_scan - removes enumeration/discovery method from mport
+ * @mport_id: mport device ID for which fabric scan routine has to be
+ * unregistered (RIO_MPORT_ANY = set for all available mports)
+ *
+ * Removes enumeration or discovery method assigned to the specified mport
+ * device (or all available mports if RIO_MPORT_ANY is specified).
+ */
+int rio_unregister_scan(int mport_id)
+{
+ struct rio_mport *port;
+
+ mutex_lock(&rio_mport_list_lock);
+ list_for_each_entry(port, &rio_mports, node) {
+ if (port->id == mport_id || mport_id == RIO_MPORT_ANY) {
+ if (port->nscan)
+ port->nscan = NULL;
+ if (mport_id != RIO_MPORT_ANY)
+ break;
+ }
+ }
+ mutex_unlock(&rio_mport_list_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rio_unregister_scan);
+
static void rio_fixup_device(struct rio_dev *dev)
{
}
@@ -1274,7 +1475,7 @@ static void disc_work_handler(struct work_struct *_work)
work = container_of(_work, struct rio_disc_work, work);
pr_debug("RIO: discovery work for mport %d %s\n",
work->mport->id, work->mport->name);
- rio_disc_mport(work->mport);
+ work->mport->nscan->discover(work->mport);
}
int rio_init_mports(void)
@@ -1290,12 +1491,15 @@ int rio_init_mports(void)
* First, run enumerations and check if we need to perform discovery
* on any of the registered mports.
*/
+ mutex_lock(&rio_mport_list_lock);
list_for_each_entry(port, &rio_mports, node) {
- if (port->host_deviceid >= 0)
- rio_enum_mport(port);
- else
+ if (port->host_deviceid >= 0) {
+ if (port->nscan)
+ port->nscan->enumerate(port);
+ } else
n++;
}
+ mutex_unlock(&rio_mport_list_lock);
if (!n)
goto no_disc;
@@ -1322,14 +1526,16 @@ int rio_init_mports(void)
}
n = 0;
+ mutex_lock(&rio_mport_list_lock);
list_for_each_entry(port, &rio_mports, node) {
- if (port->host_deviceid < 0) {
+ if (port->host_deviceid < 0 && port->nscan) {
work[n].mport = port;
INIT_WORK(&work[n].work, disc_work_handler);
queue_work(rio_wq, &work[n].work);
n++;
}
}
+ mutex_unlock(&rio_mport_list_lock);
flush_workqueue(rio_wq);
pr_debug("RIO: destroy discovery workqueue\n");
@@ -1342,8 +1548,6 @@ no_disc:
return 0;
}
-device_initcall_sync(rio_init_mports);
-
static int hdids[RIO_MAX_MPORTS + 1];
static int rio_get_hdid(int index)
@@ -1371,7 +1575,10 @@ int rio_register_mport(struct rio_mport *port)
port->id = next_portid++;
port->host_deviceid = rio_get_hdid(port->id);
+ port->nscan = NULL;
+ mutex_lock(&rio_mport_list_lock);
list_add_tail(&port->node, &rio_mports);
+ mutex_unlock(&rio_mport_list_lock);
return 0;
}
@@ -1386,3 +1593,4 @@ EXPORT_SYMBOL_GPL(rio_request_inb_mbox);
EXPORT_SYMBOL_GPL(rio_release_inb_mbox);
EXPORT_SYMBOL_GPL(rio_request_outb_mbox);
EXPORT_SYMBOL_GPL(rio_release_outb_mbox);
+EXPORT_SYMBOL_GPL(rio_init_mports);
diff --git a/drivers/rapidio/rio.h b/drivers/rapidio/rio.h
index b1af414..0afdf48 100644
--- a/drivers/rapidio/rio.h
+++ b/drivers/rapidio/rio.h
@@ -15,6 +15,7 @@
#include <linux/rio.h>
#define RIO_MAX_CHK_RETRY 3
+#define RIO_MPORT_ANY (-1)
/* Functions internal to the RIO core code */
@@ -27,8 +28,6 @@ extern u32 rio_mport_get_efb(struct rio_mport *port, int local, u16 destid,
extern int rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid,
u8 hopcount);
extern int rio_create_sysfs_dev_files(struct rio_dev *rdev);
-extern int rio_enum_mport(struct rio_mport *mport);
-extern int rio_disc_mport(struct rio_mport *mport);
extern int rio_std_route_add_entry(struct rio_mport *mport, u16 destid,
u8 hopcount, u16 table, u16 route_destid,
u8 route_port);
@@ -39,10 +38,16 @@ extern int rio_std_route_clr_table(struct rio_mport *mport, u16 destid,
u8 hopcount, u16 table);
extern int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock);
extern struct rio_dev *rio_get_comptag(u32 comp_tag, struct rio_dev *from);
+extern int rio_add_device(struct rio_dev *rdev);
+extern void rio_switch_init(struct rio_dev *rdev, int do_enum);
+extern int rio_enable_rx_tx_port(struct rio_mport *port, int local, u16 destid,
+ u8 hopcount, u8 port_num);
+extern int rio_register_scan(int mport_id, struct rio_scan *scan_ops);
+extern int rio_unregister_scan(int mport_id);
+extern void rio_attach_device(struct rio_dev *rdev);
/* Structures internal to the RIO core code */
extern struct device_attribute rio_dev_attrs[];
-extern spinlock_t rio_global_list_lock;
extern struct rio_switch_ops __start_rio_switch_ops[];
extern struct rio_switch_ops __end_rio_switch_ops[];
diff --git a/include/linux/rio.h b/include/linux/rio.h
index a3e7842..cd3796e 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -83,7 +83,6 @@
extern struct bus_type rio_bus_type;
extern struct device rio_bus;
-extern struct list_head rio_devices; /* list of all devices */
struct rio_mport;
struct rio_dev;
@@ -237,6 +236,7 @@ enum rio_phy_type {
* @name: Port name string
* @priv: Master port private data
* @dma: DMA device associated with mport
+ * @nscan: RapidIO network enumeration/discovery operations
*/
struct rio_mport {
struct list_head dbells; /* list of doorbell events */
@@ -262,6 +262,7 @@ struct rio_mport {
#ifdef CONFIG_RAPIDIO_DMA_ENGINE
struct dma_device dma;
#endif
+ struct rio_scan *nscan;
};
struct rio_id_table {
@@ -460,6 +461,16 @@ static inline struct rio_mport *dma_to_mport(struct dma_device *ddev)
}
#endif /* CONFIG_RAPIDIO_DMA_ENGINE */
+/**
+ * struct rio_scan - RIO enumeration and discovery operations
+ * @enumerate: Callback to perform RapidIO fabric enumeration.
+ * @discover: Callback to perform RapidIO fabric discovery.
+ */
+struct rio_scan {
+ int (*enumerate)(struct rio_mport *mport);
+ int (*discover)(struct rio_mport *mport);
+};
+
/* Architecture and hardware-specific functions */
extern int rio_register_mport(struct rio_mport *);
extern int rio_open_inb_mbox(struct rio_mport *, void *, int, int);
diff --git a/include/linux/rio_drv.h b/include/linux/rio_drv.h
index b75c059..5059994 100644
--- a/include/linux/rio_drv.h
+++ b/include/linux/rio_drv.h
@@ -433,5 +433,6 @@ extern u16 rio_local_get_device_id(struct rio_mport *port);
extern struct rio_dev *rio_get_device(u16 vid, u16 did, struct rio_dev *from);
extern struct rio_dev *rio_get_asm(u16 vid, u16 did, u16 asm_vid, u16 asm_did,
struct rio_dev *from);
+extern int rio_init_mports(void);
#endif /* LINUX_RIO_DRV_H */
--
1.7.8.4
^ permalink raw reply related
* Re: ppc/sata-fsl: orphan config value: CONFIG_MPC8315_DS
From: Jeff Garzik @ 2013-04-30 21:35 UTC (permalink / raw)
To: Anthony Foiani
Cc: Li Yang-R58472, Jeff Garzik, Adrian Bunk, Scott Wood,
Robert P.J.Day, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <517F67AD.2010101@scrye.com>
On 04/30/2013 02:41 AM, Anthony Foiani wrote:
> Apologies for resurrecting a very old thread, but...
>
> On 05/30/2012 02:14 PM, Anthony Foiani wrote:
>>
>> Maybe someone who knows devtree really well could crank that out in a
>> few minutes... but I'm not that person. :)
> Well, I wasn't last year, but this year I decided that I didn't care.
> Took me about an hour, not a minute, but...
>
> Having been bitten by this config symbol disappearing one more time,
> please find attached my attempt at using information out of the device
> tree to enable this hack.
>
> Patch is against 3.4.36 or so; hopefully upstream hasn't diverged very
> much.
>
> Tested by me, so feel free to add that tag if required.
Regarding this patch: Search for "sata_spd_limit" and xxx_spd* functions
Jeff
^ permalink raw reply
* Re: ppc/sata-fsl: orphan config value: CONFIG_MPC8315_DS
From: Anthony Foiani @ 2013-05-01 0:34 UTC (permalink / raw)
To: Scott Wood
Cc: Robert P.J.Day, linuxppc-dev@lists.ozlabs.org, Li Yang-R58472,
Jeff Garzik, Adrian Bunk
In-Reply-To: <1367345751.24133.0@snotra>
Scott --
Thanks for the quick reply / review!
On 04/30/2013 12:15 PM, Scott Wood wrote:
> [The devtree approach] might be OK for a new board, but adding it now
> means that people using existing device trees won't get the
> workaround. It might be better to just put the knowledge in platform
> code.
That would be fantastic, if I knew what to test.
If you look at the thread from last year, it seems that even there in
Freescale, nobody knows exactly what triggers this.
There was the "orphan" config value, and I simply turned that into a
devtree switch.
If you can find an answer inside Freescale, I can try to respin the
patch to accommodate that knowledge. But until then, this is the best I
can do.
(And it's not a new board -- it's based on the 8315ERDB, and the
orphaned symbol is apparently related to another 8315 board that never
got released?)
> Please use standard Linux coding style,
Huh. I thought I had. I'll double-check.
> and submit the patch inline rather than as an attachment (e.g. use git
> send-email).
Will see if I can do so. I don't actually have any sort of MTA set up
on this machine, hence these Thunderbirded messages.
Thanks again,
Anthony Foiani
^ permalink raw reply
* Re: ppc/sata-fsl: orphan config value: CONFIG_MPC8315_DS
From: Scott Wood @ 2013-05-01 0:42 UTC (permalink / raw)
To: Anthony Foiani
Cc: Robert P.J.Day, linuxppc-dev@lists.ozlabs.org, Li Yang-R58472,
Jeff Garzik, Adrian Bunk
In-Reply-To: <5180631F.6080106@scrye.com>
On 04/30/2013 07:34:39 PM, Anthony Foiani wrote:
> Scott --
>=20
> Thanks for the quick reply / review!
>=20
> On 04/30/2013 12:15 PM, Scott Wood wrote:
>> [The devtree approach] might be OK for a new board, but adding it =20
>> now means that people using existing device trees won't get the =20
>> workaround. It might be better to just put the knowledge in =20
>> platform code.
>=20
> That would be fantastic, if I knew what to test.
>=20
> If you look at the thread from last year, it seems that even there in =20
> Freescale, nobody knows exactly what triggers this.
>=20
> There was the "orphan" config value, and I simply turned that into a =20
> devtree switch.
>=20
> If you can find an answer inside Freescale, I can try to respin the =20
> patch to accommodate that knowledge. But until then, this is the =20
> best I can do.
>=20
> (And it's not a new board -- it's based on the 8315ERDB, and the =20
> orphaned symbol is apparently related to another 8315 board that =20
> never got released?)
I just meant that, for whatever boards you would have put this in the =20
device tree, put it in platform code instead (if the platform file =20
supports more than one board type, then check the compatible at the top =20
of the device tree). Or do you mean that you would not set this on any =20
board's device tree by default, and instead have users set it if they =20
encounter problems? Is this a custom board you're seeing it on?
>> and submit the patch inline rather than as an attachment (e.g. use =20
>> git send-email).
>=20
> Will see if I can do so. I don't actually have any sort of MTA set =20
> up on this machine, hence these Thunderbirded messages.
git send-email can connect directly to an SMTP server.
-Scott=
^ permalink raw reply
* [PATCH net-next] af_unix: fix a fatal race with bit fields
From: Eric Dumazet @ 2013-05-01 1:12 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linuxppc-dev, Paul Mackerras, Ambrose Feinstein
From: Eric Dumazet <edumazet@google.com>
Using bit fields is dangerous on ppc64, as the compiler uses 64bit
instructions to manipulate them. If the 64bit word includes any
atomic_t or spinlock_t, we can lose critical concurrent changes.
This is happening in af_unix, where unix_sk(sk)->gc_candidate/
gc_maybe_cycle/lock share the same 64bit word.
This leads to fatal deadlock, as one/several cpus spin forever
on a spinlock that will never be available again.
Reported-by: Ambrose Feinstein <ambrose@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
---
Could ppc64 experts confirm using byte is safe, or should we really add
a 32bit hole after the spinlock ? If so, I wonder how many other places
need a change...
include/net/af_unix.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index a8836e8..4520a23f 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -57,8 +57,8 @@ struct unix_sock {
struct list_head link;
atomic_long_t inflight;
spinlock_t lock;
- unsigned int gc_candidate : 1;
- unsigned int gc_maybe_cycle : 1;
+ unsigned char gc_candidate;
+ unsigned char gc_maybe_cycle;
unsigned char recursion_level;
struct socket_wq peer_wq;
};
^ permalink raw reply related
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