* Re: [PATCH 3/3] ppc64-specific memory notifier support
From: Nathan Lynch @ 2008-02-29 0:39 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev, Badari Pulavarty
In-Reply-To: <1204243875.7729.3.camel@concordia.ozlabs.ibm.com>
Michael Ellerman wrote:
> On Thu, 2008-02-28 at 08:46 -0800, Badari Pulavarty wrote:
> > Hotplug memory notifier for ppc64. This gets invoked by writing
> > the device-node that needs to be removed to /proc/ppc64/ofdt.
> > We need to adjust the sections and remove sysfs entries by
> > calling __remove_pages(). Then call arch specific code to
> > get rid of htab mappings for the section of memory.
> >
> > Signed-off-by: Badari Pulavarty <pbadari@us.ibm.com>
> > ---
> > arch/powerpc/platforms/pseries/Makefile | 1
> > arch/powerpc/platforms/pseries/hotplug-memory.c | 98 ++++++++++++++++++++++++
> > 2 files changed, 99 insertions(+)
> >
> > Index: linux-2.6.25-rc2/arch/powerpc/platforms/pseries/hotplug-memory.c
> > ===================================================================
> > --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> > +++ linux-2.6.25-rc2/arch/powerpc/platforms/pseries/hotplug-memory.c 2008-02-28 08:20:14.000000000 -0800
>
> > +
> > +static struct notifier_block pseries_smp_nb = {
> > + .notifier_call = pseries_memory_notifier,
> > +};
> > +
> > +static int __init pseries_memory_hotplug_init(void)
> > +{
> > + if (firmware_has_feature(FW_FEATURE_LPAR))
> > + pSeries_reconfig_notifier_register(&pseries_smp_nb);
> > +
> > + return 0;
> > +}
> > +arch_initcall(pseries_memory_hotplug_init);
>
> This is going to fire on non-pseries LPAR platforms, like iSeries and
> PS3. Which is not what you want I think.
Well, the notifier will be registered, yes, but it will never be
called because that path is reachable only from a write to
/proc/ppc64/ofdt, which is not created on non-pseries.
Maybe it should be
machine_device_initcall(pseries, pseries_memory_hotplug_init);
(and pseries_cpu_hotplug_init in hotplug-cpu.c should be changed to
machine_arch_initcall)
^ permalink raw reply
* Re: [PATCH 2/2 v2] [POWERPC] Ignore disabled serial ports
From: Arnd Bergmann @ 2008-03-04 0:42 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Scott Wood, Nathan Lynch, paulus
In-Reply-To: <20080303214028.GE4712@localdomain>
On Monday 03 March 2008, Nathan Lynch wrote:
> I agree. =A0Josh's patch is immediately useful to other code as-is.
>=20
> used-by-rtas is powerpc-specific and doesn't belong in drivers/of IMO.
Ok, makes sense, plus paulus looked at the PAPR spec with me and we found
that used-by-rtas doesn't necessarily mean "don't touch" in all
circumstances, so original patch
Acked-by: Arnd Bergmann <arnd@arndb.de>
^ permalink raw reply
* Re: Bamboo PCI interrupt issues
From: David Gibson @ 2008-03-04 0:59 UTC (permalink / raw)
To: Hollis Blanchard; +Cc: kvm-ppc-devel, linuxppc-dev
In-Reply-To: <1204588953.7921.13.camel@basalt>
On Mon, Mar 03, 2008 at 06:02:33PM -0600, Hollis Blanchard wrote:
> I'm having two problems with PCI interrupts as described in bamboo.dts.
> Here is are the properties in question:
>
> /* Bamboo has all 4 IRQ pins tied together per slot */
> interrupt-map-mask = <f800 0 0 0>;
> interrupt-map = <
> /* IDSEL 1 */
> 0800 0 0 0 &UIC0 1c 8
>
> /* IDSEL 2 */
> 1000 0 0 0 &UIC0 1b 8
>
> /* IDSEL 3 */
> 1800 0 0 0 &UIC0 1a 8
>
> /* IDSEL 4 */
> 2000 0 0 0 &UIC0 19 8
> >;
>
>
> First, the 440EP[1] and Bamboo[2] user manuals indicate that PCI IRQ 0-3
> -> board IRQ 2-5 -> UIC IRQ 25-28. However, the device tree has that
> reversed, so PCI IRQ 0 appears as UIC IRQ 28 (0x1c).
>
> Second, the sensitivity seems to be wrong. All these interrupts have the
> sensitivity encoded as 8, which means "high to low edge" in the OpenPIC
> binding. Now, 440EP has a UIC, rather than an OpenPIC, but there is no
> UIC binding AFAICS.
Uh.. there's no binding written down, it's just encoded into uic.c.
But UIC doesn't use OpenPIC sensitivity encoding. Like FSL's IPIC, it
uses Linux IRQ_TYPE values from include/linux/irq.h which makes 8
"level sensitive, active-low".
> When I change the 8 to a 4 ("active high level"), I see the proper
> values in the UIC polarity register, and PCI interrupts start working in
> KVM.
>
> Is anybody using Bamboo PCI support right now? Does it actually work?
>
> [1]
> https://www.amcc.com/MyAMCC/retrieveDocument/PowerPC/440EP/PPC440EP_UM2000.pdf
> [2] Seems to have been deleted from the web. Thanks, AMCC.
>
--
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
^ permalink raw reply
* Re: Bamboo PCI interrupt issues
From: Benjamin Herrenschmidt @ 2008-03-04 1:42 UTC (permalink / raw)
To: David Gibson; +Cc: kvm-ppc-devel, linuxppc-dev, Hollis Blanchard
In-Reply-To: <20080304005922.GB1393@localhost.localdomain>
On Tue, 2008-03-04 at 11:59 +1100, David Gibson wrote:
>
> Uh.. there's no binding written down, it's just encoded into uic.c.
> But UIC doesn't use OpenPIC sensitivity encoding. Like FSL's IPIC, it
> uses Linux IRQ_TYPE values from include/linux/irq.h which makes 8
> "level sensitive, active-low".
On a related note: aren't we taking a risk here of seeing those values
change in linux ?
Ben.
^ permalink raw reply
* DTC and Git and MontaVista
From: Jon Loeliger @ 2008-03-04 1:52 UTC (permalink / raw)
To: linuxppc-dev
Guys,
Sorry to bother everyone, but someone at MontaVista
who was trying to get the DTC today needs to update
their version of git to be something modern.
Thanks,
jdl
^ permalink raw reply
* Re: Bamboo PCI interrupt issues
From: David Gibson @ 2008-03-04 1:53 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: kvm-ppc-devel, linuxppc-dev, Hollis Blanchard
In-Reply-To: <1204594967.21545.46.camel@pasglop>
On Tue, Mar 04, 2008 at 12:42:47PM +1100, Benjamin Herrenschmidt wrote:
>
> On Tue, 2008-03-04 at 11:59 +1100, David Gibson wrote:
> >
> > Uh.. there's no binding written down, it's just encoded into uic.c.
> > But UIC doesn't use OpenPIC sensitivity encoding. Like FSL's IPIC, it
> > uses Linux IRQ_TYPE values from include/linux/irq.h which makes 8
> > "level sensitive, active-low".
>
> On a related note: aren't we taking a risk here of seeing those values
> change in linux ?
We've discussed this before. If that happens, the binding must remain
on the old values. It means the driver will then need a translation
which it doesn't now, but we can deal with it.
--
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
^ permalink raw reply
* Re: Bamboo PCI interrupt issues
From: Segher Boessenkool @ 2008-03-04 2:07 UTC (permalink / raw)
To: David Gibson; +Cc: kvm-ppc-devel, linuxppc-dev, Hollis Blanchard
In-Reply-To: <20080304015329.GE1393@localhost.localdomain>
>>> Uh.. there's no binding written down, it's just encoded into uic.c.
>>> But UIC doesn't use OpenPIC sensitivity encoding. Like FSL's IPIC,
>>> it
>>> uses Linux IRQ_TYPE values from include/linux/irq.h which makes 8
>>> "level sensitive, active-low".
>>
>> On a related note: aren't we taking a risk here of seeing those values
>> change in linux ?
>
> We've discussed this before. If that happens, the binding must remain
> on the old values. It means the driver will then need a translation
> which it doesn't now, but we can deal with it.
It also means it should be written down in the binding _already_.
Come on, how much work is that?
Segher
^ permalink raw reply
* Re: Bamboo PCI interrupt issues
From: David Gibson @ 2008-03-04 2:15 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: kvm-ppc-devel, linuxppc-dev, Hollis Blanchard
In-Reply-To: <08b18695c383fb829ecf3ab6c2822bd1@kernel.crashing.org>
On Tue, Mar 04, 2008 at 03:07:50AM +0100, Segher Boessenkool wrote:
> >>> Uh.. there's no binding written down, it's just encoded into uic.c.
> >>> But UIC doesn't use OpenPIC sensitivity encoding. Like FSL's IPIC,
> >>> it
> >>> uses Linux IRQ_TYPE values from include/linux/irq.h which makes 8
> >>> "level sensitive, active-low".
> >>
> >> On a related note: aren't we taking a risk here of seeing those values
> >> change in linux ?
> >
> > We've discussed this before. If that happens, the binding must remain
> > on the old values. It means the driver will then need a translation
> > which it doesn't now, but we can deal with it.
>
> It also means it should be written down in the binding _already_.
Well, yes, there should be, but isn't, a written binding for this,
amongst many other things.
> Come on, how much work is that?
Greater than zero.
--
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
^ permalink raw reply
* Re: Bamboo PCI interrupt issues
From: Josh Boyer @ 2008-03-04 3:37 UTC (permalink / raw)
To: Hollis Blanchard; +Cc: kvm-ppc-devel, linuxppc-dev
In-Reply-To: <1204588953.7921.13.camel@basalt>
On Mon, 03 Mar 2008 18:02:33 -0600
Hollis Blanchard <hollisb@us.ibm.com> wrote:
> I'm having two problems with PCI interrupts as described in bamboo.dts.
> Here is are the properties in question:
>
> /* Bamboo has all 4 IRQ pins tied together per slot */
> interrupt-map-mask = <f800 0 0 0>;
> interrupt-map = <
> /* IDSEL 1 */
> 0800 0 0 0 &UIC0 1c 8
>
> /* IDSEL 2 */
> 1000 0 0 0 &UIC0 1b 8
>
> /* IDSEL 3 */
> 1800 0 0 0 &UIC0 1a 8
>
> /* IDSEL 4 */
> 2000 0 0 0 &UIC0 19 8
> >;
>
>
> First, the 440EP[1] and Bamboo[2] user manuals indicate that PCI IRQ 0-3
> -> board IRQ 2-5 -> UIC IRQ 25-28. However, the device tree has that
> reversed, so PCI IRQ 0 appears as UIC IRQ 28 (0x1c).
Actually, the device tree is right. I got annoyed with myself for not
knowing how this works so I went and figured it out.
2000 0 0 0 is device #4. According to the specs, device #4 has AD(14)
asserted during type 0 configuration. Looking at the board schematics,
PCI slot 0 has it's IDSEL line tied to AD(14). So:
dev #4 -> PCI 0 -> board IRQ 2 -> UIC IRQ 25.
which is exactly what the device tree has.
> Second, the sensitivity seems to be wrong. All these interrupts have the
> sensitivity encoded as 8, which means "high to low edge" in the OpenPIC
> binding. Now, 440EP has a UIC, rather than an OpenPIC, but there is no
> UIC binding AFAICS.
There isn't. It uses the sense numbers from linux/irq.h. Which means
8 is level, low. This matches exactly what the board manual says for
IRQ2-5 on page 69.
> When I change the 8 to a 4 ("active high level"), I see the proper
> values in the UIC polarity register, and PCI interrupts start working in
> KVM.
That's odd.
> Is anybody using Bamboo PCI support right now? Does it actually work?
I plugged in an old 3Com ethernet card tonight. Slot 0. It was
assigned dev #4 IRQ 25. Using the device tree as-is, I could see
interrupts happening in /proc/interrupts but ethernet traffic failed.
Then I changed the sense level to 4 as you suggested, and my card hung
hard on the first ethernet traffic. I've no idea if we're dealing with
a crappy card or a crappy driver but the device tree seems to be
working ok. If I can find a different card to test with I will.
Ben, do you have any input here?
josh
^ permalink raw reply
* [PATCH] Correct a terrible scheduling error
From: Segher Boessenkool @ 2008-03-04 3:42 UTC (permalink / raw)
To: linuxppc-dev
It would be a pity if we can't all enjoy this.
Signed-off-by: Segher Boessenkool <segher@kernel.crashing.org>
---
Documentation/feature-removal-schedule.txt | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index c1d1fd0..78021bf 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -201,13 +201,13 @@ Who: Tejun Heo <htejun@gmail.com>
---------------------------
What: The arch/ppc and include/asm-ppc directories
-When: Jun 2008
+When: end of July 2008
Why: The arch/powerpc tree is the merged architecture for ppc32 and ppc64
platforms. Currently there are efforts underway to port the remaining
arch/ppc platforms to the merged tree. New submissions to the arch/ppc
tree have been frozen with the 2.6.22 kernel release and that tree will
remain in bug-fix only mode until its scheduled removal. Platforms
- that are not ported by June 2008 will be removed due to the lack of an
+ that are not ported by July 2008 will be removed due to the lack of an
interested maintainer.
Who: linuxppc-dev@ozlabs.org
--
1.5.3.4.208.g805a
^ permalink raw reply related
* dtc: Make some functions local to parser
From: David Gibson @ 2008-03-04 4:37 UTC (permalink / raw)
To: Jon Loeliger; +Cc: linuxppc-dev
* eval_literal() is defined and used only in the parser, so make it
static.
* The Bison documentation explicitly permits yyerror() to be a
variadic function, so fold yyerror() and yyerrorf() into a single
printf-style function. The combined function is defined and used
only in the parse, so make it static.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
dtc-parser.y | 14 +++++---------
srcpos.h | 3 ---
2 files changed, 5 insertions(+), 12 deletions(-)
Index: dtc/dtc-parser.y
===================================================================
--- dtc.orig/dtc-parser.y 2008-03-04 15:29:09.000000000 +1100
+++ dtc/dtc-parser.y 2008-03-04 15:31:32.000000000 +1100
@@ -24,12 +24,13 @@
#include "dtc.h"
#include "srcpos.h"
-int yylex(void);
-unsigned long long eval_literal(const char *s, int base, int bits);
+extern int yylex(void);
extern struct boot_info *the_boot_info;
extern int treesource_error;
+static void yyerror(char const *, ...) __attribute__((format(printf, 1, 2)));
+static unsigned long long eval_literal(const char *s, int base, int bits);
%}
%union {
@@ -308,7 +309,7 @@ label:
%%
-void yyerrorf(char const *s, ...)
+static void yyerror(char const *s, ...)
{
const char *fname = srcpos_file ? srcpos_file->name : "<no-file>";
va_list va;
@@ -325,12 +326,7 @@ void yyerrorf(char const *s, ...)
va_end(va);
}
-void yyerror (char const *s)
-{
- yyerrorf("%s", s);
-}
-
-unsigned long long eval_literal(const char *s, int base, int bits)
+static unsigned long long eval_literal(const char *s, int base, int bits)
{
unsigned long long val;
char *e;
Index: dtc/srcpos.h
===================================================================
--- dtc.orig/srcpos.h 2008-03-04 15:30:06.000000000 +1100
+++ dtc/srcpos.h 2008-03-04 15:30:09.000000000 +1100
@@ -70,9 +70,6 @@ typedef struct YYLTYPE {
-extern void yyerror(char const *);
-extern void yyerrorf(char const *, ...) __attribute__((format(printf, 1, 2)));
-
extern struct dtc_file *srcpos_file;
extern void push_input_file(const char *filename);
--
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
^ permalink raw reply
* dtc: Make dt_from_blob() open its own file
From: David Gibson @ 2008-03-04 5:10 UTC (permalink / raw)
To: Jon Loeliger; +Cc: linuxppc-dev
dt_from_source() and dt_from_fs() both take a filename (or directory
name) argument and open files as necessary themselves.
dt_from_blob(), however, expects the caller to open a file and pass it
in.
This patch makes dt_from_blob() take a filename and open its own
files, removing the inconsistency. In addition, dt_from_blob() now
correctly uses dtc_close_file() to close the file opened with
dtc_open_file(), rather than directly calling fclose() on the
contained FILE *.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
dtc.c | 11 +----------
dtc.h | 4 ++--
flattree.c | 10 +++++++++-
3 files changed, 12 insertions(+), 13 deletions(-)
Index: dtc/dtc.c
===================================================================
--- dtc.orig/dtc.c 2008-03-04 15:58:49.000000000 +1100
+++ dtc/dtc.c 2008-03-04 16:02:12.000000000 +1100
@@ -118,7 +118,6 @@ int main(int argc, char *argv[])
int force = 0, check = 0;
const char *arg;
int opt;
- struct dtc_file *inf = NULL;
FILE *outf = NULL;
int outversion = DEFAULT_FDT_VERSION;
int boot_cpuid_phys = 0xfeedbeef;
@@ -192,19 +191,11 @@ int main(int argc, char *argv[])
} else if (streq(inform, "fs")) {
bi = dt_from_fs(arg);
} else if(streq(inform, "dtb")) {
- inf = dtc_open_file(arg, NULL);
- if (!inf)
- die("Couldn't open \"%s\": %s\n", arg,
- strerror(errno));
-
- bi = dt_from_blob(inf->file);
+ bi = dt_from_blob(arg);
} else {
die("Unknown input format \"%s\"\n", inform);
}
- if (inf && inf->file != stdin)
- fclose(inf->file);
-
if (! bi || ! bi->dt || bi->error)
die("Couldn't read input tree\n");
Index: dtc/flattree.c
===================================================================
--- dtc.orig/flattree.c 2008-03-04 15:59:53.000000000 +1100
+++ dtc/flattree.c 2008-03-04 16:06:55.000000000 +1100
@@ -19,6 +19,7 @@
*/
#include "dtc.h"
+#include "srcpos.h"
#define FTF_FULLPATH 0x1
#define FTF_VARALIGN 0x2
@@ -780,8 +781,10 @@ static struct node *unflatten_tree(struc
}
-struct boot_info *dt_from_blob(FILE *f)
+struct boot_info *dt_from_blob(const char *fname)
{
+ struct dtc_file *dtcf;
+ FILE *f;
u32 magic, totalsize, version, size_dt;
u32 off_dt, off_str, off_mem_rsvmap;
int rc;
@@ -796,6 +799,9 @@ struct boot_info *dt_from_blob(FILE *f)
u32 val;
int flags = 0;
+ dtcf = dtc_open_file(fname, NULL);
+ f = dtcf->file;
+
rc = fread(&magic, sizeof(magic), 1, f);
if (ferror(f))
die("Error reading DT blob magic number: %s\n",
@@ -902,5 +908,7 @@ struct boot_info *dt_from_blob(FILE *f)
free(blob);
+ dtc_close_file(dtcf);
+
return build_boot_info(reservelist, tree);
}
Index: dtc/dtc.h
===================================================================
--- dtc.orig/dtc.h 2008-03-04 16:01:22.000000000 +1100
+++ dtc/dtc.h 2008-03-04 16:01:43.000000000 +1100
@@ -250,12 +250,12 @@ void dt_to_blob(FILE *f, struct boot_inf
void dt_to_asm(FILE *f, struct boot_info *bi, int version,
int boot_cpuid_phys);
-struct boot_info *dt_from_blob(FILE *f);
+struct boot_info *dt_from_blob(const char *fname);
/* Tree source */
void dt_to_source(FILE *f, struct boot_info *bi);
-struct boot_info *dt_from_source(const char *f);
+struct boot_info *dt_from_source(const char *fname);
/* FS trees */
--
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
^ permalink raw reply
* Re: dtc: Make dt_from_blob() open its own file
From: David Gibson @ 2008-03-04 5:15 UTC (permalink / raw)
To: Jon Loeliger, linuxppc-dev
In-Reply-To: <20080304051039.GC2757@localhost.localdomain>
On Tue, Mar 04, 2008 at 04:10:39PM +1100, David Gibson wrote:
> dt_from_source() and dt_from_fs() both take a filename (or directory
> name) argument and open files as necessary themselves.
> dt_from_blob(), however, expects the caller to open a file and pass it
> in.
>
> This patch makes dt_from_blob() take a filename and open its own
> files, removing the inconsistency. In addition, dt_from_blob() now
> correctly uses dtc_close_file() to close the file opened with
> dtc_open_file(), rather than directly calling fclose() on the
> contained FILE *.
>
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Sorry, ignore. There's a bug in this one, revised version coming.
--
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
^ permalink raw reply
* Re: Bamboo PCI interrupt issues
From: Stefan Roese @ 2008-03-04 6:15 UTC (permalink / raw)
To: linuxppc-dev; +Cc: kvm-ppc-devel, Hollis Blanchard
In-Reply-To: <20080303213718.12291eee@zod.rchland.ibm.com>
On Tuesday 04 March 2008, Josh Boyer wrote:
> > Is anybody using Bamboo PCI support right now? Does it actually work?
>
> I plugged in an old 3Com ethernet card tonight. Slot 0. It was
> assigned dev #4 IRQ 25. Using the device tree as-is, I could see
> interrupts happening in /proc/interrupts but ethernet traffic failed.
>
> Then I changed the sense level to 4 as you suggested, and my card hung
> hard on the first ethernet traffic.
Using '8' is correct. PCI interrupts are *always* level sensitive and active
low.
> I've no idea if we're dealing with
> a crappy card or a crappy driver but the device tree seems to be
> working ok. If I can find a different card to test with I will.
One thing always worth to check on 4xx IRQ problems is, if the external IRQ
pins are configured correctly for IRQ usage. Most of the times, the external
IRQ's are shared with other peripheral pins and/or GPIO pins. This
configuration is done in the GPIO core (and sometimes SDR PFCx registers).
This should be done correctly by the bootloader but sometimes the
configuration is wrong. I have to admit that I probably never tested PCI on
Bamboo. Just a thought.
Best regards,
Stefan
^ permalink raw reply
* Re: Bamboo PCI interrupt issues
From: Benjamin Herrenschmidt @ 2008-03-04 6:18 UTC (permalink / raw)
To: Josh Boyer; +Cc: kvm-ppc-devel, linuxppc-dev, Hollis Blanchard
In-Reply-To: <20080303213718.12291eee@zod.rchland.ibm.com>
On Mon, 2008-03-03 at 21:37 -0600, Josh Boyer wrote:
> I plugged in an old 3Com ethernet card tonight. Slot 0. It was
> assigned dev #4 IRQ 25. Using the device tree as-is, I could see
> interrupts happening in /proc/interrupts but ethernet traffic failed.
>
> Then I changed the sense level to 4 as you suggested, and my card hung
> hard on the first ethernet traffic. I've no idea if we're dealing
> with
> a crappy card or a crappy driver but the device tree seems to be
> working ok. If I can find a different card to test with I will.
>
> Ben, do you have any input here?
Other than bamboo has the weirdest combination of FPGA/CPLD/DIP switches
that I could never figure out if PCI was clocked properly ?
That might just be the problem :-)
I do remember having issues now that we talk about it. Though not
specifically what they were.
Ben.
^ permalink raw reply
* Re: Bamboo PCI interrupt issues
From: Benjamin Herrenschmidt @ 2008-03-04 6:33 UTC (permalink / raw)
To: Stefan Roese; +Cc: kvm-ppc-devel, linuxppc-dev, Hollis Blanchard
In-Reply-To: <200803040715.22301.sr@denx.de>
On Tue, 2008-03-04 at 07:15 +0100, Stefan Roese wrote:
>
> Using '8' is correct. PCI interrupts are *always* level sensitive and
> active
> low.
Unless you use one of those strange bridges that stick not gates on the
PCI IRQ inputs :-) But I don't think that's the case on the 440EP.
Ben.
^ permalink raw reply
* out of vmalloc
From: Alain.Cadillac @ 2008-03-04 7:44 UTC (permalink / raw)
To: linuxppc-embedded
[-- Attachment #1: Type: text/plain, Size: 316 bytes --]
Hi my name is Alain
I'm working on plateform MPC8541 with linux 2.6.14 kernel.
I must to increase the kernel space area (1GB) beacause I had an
"out of vmalloc message" when i tried to reserve 256 Mo of PCI area.
*Does anyone tell me where i can found some information on HOW to do it?*
Thanks for help.
[-- Attachment #2: Type: text/html, Size: 536 bytes --]
^ permalink raw reply
* Re: ARCH=ppc -> ARCH=powerpc : help needed for dts file
From: Philippe De Muyter @ 2008-03-04 8:08 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <47CC73CE.4080801@freescale.com>
Hi Scott,
On Mon, Mar 03, 2008 at 03:55:26PM -0600, Scott Wood wrote:
> Philippe De Muyter wrote:
>> The following seems important also :
>> /*
>> interrupts = <18 2>;
>> */
>> /* interrupts number are coded in hexa ! */
>> interrupts = <12 2 19 2 1a 2 1b 2 35 2 36 2 37 2>;
>> I have replaced the interrupts spec in comments by the longer interrupts
>> spec
>> below,
>
> Why?
because of the error message regarding unhandled interrupt. As I wrote I do
not know anything about dts files, just that it is needed to have one
for a non OF board if I want to use the ARCH=powerpc tree.
>
>> and it seems to have some positive effect,
>
> What kind of positive effect? I'd think the extra interrupts would just be
> ignored. The interrupts property for the PCI node itself is generally for
> error reporting.
My compact-flash device is discovered, but interrupts still do not work.
In the log, at the end of the boot,
this :
rtc-m41t80 0-0068: hctosys: invalid date/time
Waiting 3sec before mounting root device...
VFS: Cannot open root device "hda1" or unknown-block(0,0)
Please append a correct "root=" boot option; here are the
available partitions:
1f00 1920 mtdblock0 (driver?)
1f01 1920 mtdblock1 (driver?)
1f02 1920 mtdblock2 (driver?)
1f03 1920 mtdblock3 (driver?)
1f04 512 mtdblock4 (driver?)
Kernel panic - not syncing: VFS: Unable to mount root fs on
unknown-block(0,0)
Rebooting in 180 seconds..
is replaced by that :
hda: TRANSCEND, CFA DISK drive
ide0 at 0x000-0x007,0x00e on irq 18
hda: max request size: 128KiB
hda: 8077104 sectors (4135 MB) w/1KiB Cache, CHS=8013/16/63
hda:<4>hda: lost interrupt
[same message repeated]
hda: lost interrupt
hda1
ide-cs: hda: Vpp = 0.0
rtc-m41t80 0-0068: hctosys: invalid date/time
Waiting 3sec before mounting root device...
hda: lost interrupt
[same message repeated]
EXT2-fs warning (device hda1): ext2_fill_super: mounting ext3 filesystem as ext2
VFS: Mounted root (ext2 filesystem) readonly.
Freeing unused kernel memory: 116k init
hda: lost interrupt
[same message repeated]
>
>> I know that 25, 26, 27, 53, 54 and 55 decimal i(hence 19, 1a etc...) are
>> the
>> interrupts numbers that I had in the ARCH=ppc version. I added 18 because
>> of the error message, but it did not help.
>
> What ARCH=ppc version? There are no device trees for non-OF boards in
> arch/ppc.
With ARCH=ppc, all those interrupt's info's are hardcoded in the .c files.
But I expected I could fill the dts file for ARCH=powerpc from info's I
could collect in /proc on a running ARCH=ppc linux without dts file
for the same board.
Philippe
^ permalink raw reply
* Re: ARCH=ppc -> ARCH=powerpc : help needed for dts file
From: Philippe De Muyter @ 2008-03-04 8:19 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: Scott Wood, linuxppc-dev
In-Reply-To: <1204580493.21545.27.camel@pasglop>
Hi Ben,
On Tue, Mar 04, 2008 at 08:41:33AM +1100, Benjamin Herrenschmidt wrote:
>
> > Thanks
> >
> > The following seems important also :
> >
> > /*
> > interrupts = <18 2>;
> > */
> > /* interrupts number are coded in hexa ! */
> > interrupts = <12 2 19 2 1a 2 1b 2 35 2 36 2 37 2>;
> >
> > I have replaced the interrupts spec in comments by the longer interrupts spec
> > below, and it seems to have some positive effect, but I do not know
> > precisely what I have described there.
> >
> > I know that 25, 26, 27, 53, 54 and 55 decimal i(hence 19, 1a etc...) are the
> > interrupts numbers that I had in the ARCH=ppc version. I added 18 because
> > of the error message, but it did not help.
>
> Where is this ? (What node ?) The above looks like the interrupt spec
> for a single device with 7 interrupts, is that what you are trying to
> do ?
Well, the yenta device is a multi-function PCI peripheral that has two
pcmcia/pccard/compactflash slots and one ohci1394 interface.
Here's what uboot shows :
PCI Scan: Found Bus 0, Device 18, Function 0
00 12 104c ac46 0607 ff
PCI Scan: Found Bus 0, Device 18, Function 1
00 12 104c ac46 0607 ff
PCI Scan: Found Bus 0, Device 18, Function 2
00 12 104c 802a 0c00 00
and here is what /proc/interrupts shows in my ARCH=ppc dts-less running linux :
root:~# cat /proc/interrupts
CPU0
25: 0 OpenPIC Level gfar_interrupt
26: 245 OpenPIC Level serial
27: 0 OpenPIC Level i2c-mpc
55: 18797 OpenPIC Level yenta, ide0
54: 1 OpenPIC Level yenta
55: 79 OpenPIC Level ohci1394
BAD: 0
>
> If not, then it's incorrect, you have to figure the interrupt-map out
> (it's really not -that- hard).
If I knew where to look at, and what I must produce, I'd agree with you :)
Philippe
^ permalink raw reply
* Re: ARCH=ppc -> ARCH=powerpc : help needed for dts file
From: Benjamin Herrenschmidt @ 2008-03-04 8:22 UTC (permalink / raw)
To: Philippe De Muyter; +Cc: Scott Wood, linuxppc-dev
In-Reply-To: <20080304080828.GA18829@netgate.macqel>
On Tue, 2008-03-04 at 09:08 +0100, Philippe De Muyter wrote:
> With ARCH=ppc, all those interrupt's info's are hardcoded in the .c
> files.
> But I expected I could fill the dts file for ARCH=powerpc from info's
> I
> could collect in /proc on a running ARCH=ppc linux without dts file
> for the same board.
Rather, look at the C file. Send it and we can help figuring things out.
Ben.
^ permalink raw reply
* [PATCH 02/17] Add RapidIO option to kernel configuration.
From: Zhang Wei @ 2008-03-04 16:29 UTC (permalink / raw)
To: mporter, galak; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1204648202-5495-1-git-send-email-wei.zhang@freescale.com>
Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
---
arch/powerpc/Kconfig | 13 +++++++++++++
arch/powerpc/platforms/86xx/Kconfig | 1 +
2 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 485513c..70789e8 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -563,6 +563,19 @@ source "drivers/pcmcia/Kconfig"
source "drivers/pci/hotplug/Kconfig"
+config HAS_RAPIDIO
+ bool
+ default n
+
+config RAPIDIO
+ bool "RapidIO support"
+ depends on HAS_RAPIDIO
+ help
+ If you say Y here, the kernel will include drivers and
+ infrastructure code to support RapidIO interconnect devices.
+
+source "drivers/rapidio/Kconfig"
+
endmenu
menu "Advanced setup"
diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig
index 21d1135..8c7c5ff 100644
--- a/arch/powerpc/platforms/86xx/Kconfig
+++ b/arch/powerpc/platforms/86xx/Kconfig
@@ -8,6 +8,7 @@ config MPC8641_HPCN
select PPC_I8259
select DEFAULT_UIMAGE
select FSL_ULI1575
+ select HAS_RAPIDIO
help
This option enables support for the MPC8641 HPCN board.
--
1.5.4
^ permalink raw reply related
* [PATCH 01/17] Change RIO function mpc85xx_ to fsl_ .
From: Zhang Wei @ 2008-03-04 16:29 UTC (permalink / raw)
To: mporter, galak; +Cc: linuxppc-dev, linux-kernel
The driver is also fit for Freescale MPC8641 processor.
Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
---
arch/powerpc/sysdev/fsl_rio.c | 80 ++++++++++++++++++++--------------------
1 files changed, 40 insertions(+), 40 deletions(-)
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index af2425e..36c4be4 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -1,5 +1,5 @@
/*
- * MPC85xx RapidIO support
+ * Freescale MPC85xx/MPC86xx RapidIO support
*
* Copyright 2005 MontaVista Software, Inc.
* Matt Porter <mporter@kernel.crashing.org>
@@ -145,7 +145,7 @@ static struct rio_msg_rx_ring {
} msg_rx_ring;
/**
- * mpc85xx_rio_doorbell_send - Send a MPC85xx doorbell message
+ * fsl_rio_doorbell_send - Send a MPC85xx doorbell message
* @index: ID of RapidIO interface
* @destid: Destination ID of target device
* @data: 16-bit info field of RapidIO doorbell message
@@ -153,9 +153,9 @@ static struct rio_msg_rx_ring {
* Sends a MPC85xx doorbell message. Returns %0 on success or
* %-EINVAL on failure.
*/
-static int mpc85xx_rio_doorbell_send(int index, u16 destid, u16 data)
+static int fsl_rio_doorbell_send(int index, u16 destid, u16 data)
{
- pr_debug("mpc85xx_doorbell_send: index %d destid %4.4x data %4.4x\n",
+ pr_debug("fsl_doorbell_send: index %d destid %4.4x data %4.4x\n",
index, destid, data);
out_be32((void *)&dbell_atmu_regs->rowtar, destid << 22);
out_be16((void *)(dbell_win), data);
@@ -164,7 +164,7 @@ static int mpc85xx_rio_doorbell_send(int index, u16 destid, u16 data)
}
/**
- * mpc85xx_local_config_read - Generate a MPC85xx local config space read
+ * fsl_local_config_read - Generate a MPC85xx local config space read
* @index: ID of RapdiIO interface
* @offset: Offset into configuration space
* @len: Length (in bytes) of the maintenance transaction
@@ -173,9 +173,9 @@ static int mpc85xx_rio_doorbell_send(int index, u16 destid, u16 data)
* Generates a MPC85xx local configuration space read. Returns %0 on
* success or %-EINVAL on failure.
*/
-static int mpc85xx_local_config_read(int index, u32 offset, int len, u32 * data)
+static int fsl_local_config_read(int index, u32 offset, int len, u32 * data)
{
- pr_debug("mpc85xx_local_config_read: index %d offset %8.8x\n", index,
+ pr_debug("fsl_local_config_read: index %d offset %8.8x\n", index,
offset);
*data = in_be32((void *)(regs_win + offset));
@@ -183,7 +183,7 @@ static int mpc85xx_local_config_read(int index, u32 offset, int len, u32 * data)
}
/**
- * mpc85xx_local_config_write - Generate a MPC85xx local config space write
+ * fsl_local_config_write - Generate a MPC85xx local config space write
* @index: ID of RapdiIO interface
* @offset: Offset into configuration space
* @len: Length (in bytes) of the maintenance transaction
@@ -192,10 +192,10 @@ static int mpc85xx_local_config_read(int index, u32 offset, int len, u32 * data)
* Generates a MPC85xx local configuration space write. Returns %0 on
* success or %-EINVAL on failure.
*/
-static int mpc85xx_local_config_write(int index, u32 offset, int len, u32 data)
+static int fsl_local_config_write(int index, u32 offset, int len, u32 data)
{
pr_debug
- ("mpc85xx_local_config_write: index %d offset %8.8x data %8.8x\n",
+ ("fsl_local_config_write: index %d offset %8.8x data %8.8x\n",
index, offset, data);
out_be32((void *)(regs_win + offset), data);
@@ -203,7 +203,7 @@ static int mpc85xx_local_config_write(int index, u32 offset, int len, u32 data)
}
/**
- * mpc85xx_rio_config_read - Generate a MPC85xx read maintenance transaction
+ * fsl_rio_config_read - Generate a MPC85xx read maintenance transaction
* @index: ID of RapdiIO interface
* @destid: Destination ID of transaction
* @hopcount: Number of hops to target device
@@ -215,13 +215,13 @@ static int mpc85xx_local_config_write(int index, u32 offset, int len, u32 data)
* success or %-EINVAL on failure.
*/
static int
-mpc85xx_rio_config_read(int index, u16 destid, u8 hopcount, u32 offset, int len,
+fsl_rio_config_read(int index, u16 destid, u8 hopcount, u32 offset, int len,
u32 * val)
{
u8 *data;
pr_debug
- ("mpc85xx_rio_config_read: index %d destid %d hopcount %d offset %8.8x len %d\n",
+ ("fsl_rio_config_read: index %d destid %d hopcount %d offset %8.8x len %d\n",
index, destid, hopcount, offset, len);
out_be32((void *)&maint_atmu_regs->rowtar,
(destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9));
@@ -243,7 +243,7 @@ mpc85xx_rio_config_read(int index, u16 destid, u8 hopcount, u32 offset, int len,
}
/**
- * mpc85xx_rio_config_write - Generate a MPC85xx write maintenance transaction
+ * fsl_rio_config_write - Generate a MPC85xx write maintenance transaction
* @index: ID of RapdiIO interface
* @destid: Destination ID of transaction
* @hopcount: Number of hops to target device
@@ -255,12 +255,12 @@ mpc85xx_rio_config_read(int index, u16 destid, u8 hopcount, u32 offset, int len,
* success or %-EINVAL on failure.
*/
static int
-mpc85xx_rio_config_write(int index, u16 destid, u8 hopcount, u32 offset,
+fsl_rio_config_write(int index, u16 destid, u8 hopcount, u32 offset,
int len, u32 val)
{
u8 *data;
pr_debug
- ("mpc85xx_rio_config_write: index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n",
+ ("fsl_rio_config_write: index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n",
index, destid, hopcount, offset, len, val);
out_be32((void *)&maint_atmu_regs->rowtar,
(destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9));
@@ -344,7 +344,7 @@ rio_hw_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox,
EXPORT_SYMBOL_GPL(rio_hw_add_outb_message);
/**
- * mpc85xx_rio_tx_handler - MPC85xx outbound message interrupt handler
+ * fsl_rio_tx_handler - MPC85xx outbound message interrupt handler
* @irq: Linux interrupt number
* @dev_instance: Pointer to interrupt-specific data
*
@@ -352,7 +352,7 @@ EXPORT_SYMBOL_GPL(rio_hw_add_outb_message);
* mailbox event handler and acks the interrupt occurrence.
*/
static irqreturn_t
-mpc85xx_rio_tx_handler(int irq, void *dev_instance)
+fsl_rio_tx_handler(int irq, void *dev_instance)
{
int osr;
struct rio_mport *port = (struct rio_mport *)dev_instance;
@@ -452,7 +452,7 @@ int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entr
/* Hook up outbound message handler */
if ((rc =
- request_irq(MPC85xx_IRQ_RIO_TX, mpc85xx_rio_tx_handler, 0,
+ request_irq(MPC85xx_IRQ_RIO_TX, fsl_rio_tx_handler, 0,
"msg_tx", (void *)mport)) < 0)
goto out_irq;
@@ -511,7 +511,7 @@ void rio_close_outb_mbox(struct rio_mport *mport, int mbox)
}
/**
- * mpc85xx_rio_rx_handler - MPC85xx inbound message interrupt handler
+ * fsl_rio_rx_handler - MPC85xx inbound message interrupt handler
* @irq: Linux interrupt number
* @dev_instance: Pointer to interrupt-specific data
*
@@ -519,7 +519,7 @@ void rio_close_outb_mbox(struct rio_mport *mport, int mbox)
* mailbox event handler and acks the interrupt occurrence.
*/
static irqreturn_t
-mpc85xx_rio_rx_handler(int irq, void *dev_instance)
+fsl_rio_rx_handler(int irq, void *dev_instance)
{
int isr;
struct rio_mport *port = (struct rio_mport *)dev_instance;
@@ -597,7 +597,7 @@ int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entri
/* Hook up inbound message handler */
if ((rc =
- request_irq(MPC85xx_IRQ_RIO_RX, mpc85xx_rio_rx_handler, 0,
+ request_irq(MPC85xx_IRQ_RIO_RX, fsl_rio_rx_handler, 0,
"msg_rx", (void *)mport)) < 0) {
dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE,
msg_tx_ring.virt_buffer[i],
@@ -729,7 +729,7 @@ void *rio_hw_get_inb_message(struct rio_mport *mport, int mbox)
EXPORT_SYMBOL_GPL(rio_hw_get_inb_message);
/**
- * mpc85xx_rio_dbell_handler - MPC85xx doorbell interrupt handler
+ * fsl_rio_dbell_handler - MPC85xx doorbell interrupt handler
* @irq: Linux interrupt number
* @dev_instance: Pointer to interrupt-specific data
*
@@ -737,7 +737,7 @@ EXPORT_SYMBOL_GPL(rio_hw_get_inb_message);
* doorbell event handlers and executes a matching event handler.
*/
static irqreturn_t
-mpc85xx_rio_dbell_handler(int irq, void *dev_instance)
+fsl_rio_dbell_handler(int irq, void *dev_instance)
{
int dsr;
struct rio_mport *port = (struct rio_mport *)dev_instance;
@@ -794,14 +794,14 @@ mpc85xx_rio_dbell_handler(int irq, void *dev_instance)
}
/**
- * mpc85xx_rio_doorbell_init - MPC85xx doorbell interface init
+ * fsl_rio_doorbell_init - MPC85xx doorbell interface init
* @mport: Master port implementing the inbound doorbell unit
*
* Initializes doorbell unit hardware and inbound DMA buffer
- * ring. Called from mpc85xx_rio_setup(). Returns %0 on success
+ * ring. Called from fsl_rio_setup(). Returns %0 on success
* or %-ENOMEM on failure.
*/
-static int mpc85xx_rio_doorbell_init(struct rio_mport *mport)
+static int fsl_rio_doorbell_init(struct rio_mport *mport)
{
int rc = 0;
@@ -835,7 +835,7 @@ static int mpc85xx_rio_doorbell_init(struct rio_mport *mport)
/* Hook up doorbell handler */
if ((rc =
- request_irq(MPC85xx_IRQ_RIO_BELL, mpc85xx_rio_dbell_handler, 0,
+ request_irq(MPC85xx_IRQ_RIO_BELL, fsl_rio_dbell_handler, 0,
"dbell_rx", (void *)mport) < 0)) {
iounmap((void *)dbell_win);
dma_free_coherent(NULL, 512 * DOORBELL_MESSAGE_SIZE,
@@ -854,7 +854,7 @@ static int mpc85xx_rio_doorbell_init(struct rio_mport *mport)
static char *cmdline = NULL;
-static int mpc85xx_rio_get_hdid(int index)
+static int fsl_rio_get_hdid(int index)
{
/* XXX Need to parse multiple entries in some format */
if (!cmdline)
@@ -863,7 +863,7 @@ static int mpc85xx_rio_get_hdid(int index)
return simple_strtol(cmdline, NULL, 0);
}
-static int mpc85xx_rio_get_cmdline(char *s)
+static int fsl_rio_get_cmdline(char *s)
{
if (!s)
return 0;
@@ -872,10 +872,10 @@ static int mpc85xx_rio_get_cmdline(char *s)
return 1;
}
-__setup("riohdid=", mpc85xx_rio_get_cmdline);
+__setup("riohdid=", fsl_rio_get_cmdline);
/**
- * mpc85xx_rio_setup - Setup MPC85xx RapidIO interface
+ * fsl_rio_setup - Setup MPC85xx RapidIO interface
* @law_start: Starting physical address of RapidIO LAW
* @law_size: Size of RapidIO LAW
*
@@ -883,17 +883,17 @@ __setup("riohdid=", mpc85xx_rio_get_cmdline);
* master port with system-specific info, and registers the
* master port with the RapidIO subsystem.
*/
-void mpc85xx_rio_setup(int law_start, int law_size)
+void fsl_rio_setup(int law_start, int law_size)
{
struct rio_ops *ops;
struct rio_mport *port;
ops = kmalloc(sizeof(struct rio_ops), GFP_KERNEL);
- ops->lcread = mpc85xx_local_config_read;
- ops->lcwrite = mpc85xx_local_config_write;
- ops->cread = mpc85xx_rio_config_read;
- ops->cwrite = mpc85xx_rio_config_write;
- ops->dsend = mpc85xx_rio_doorbell_send;
+ ops->lcread = fsl_local_config_read;
+ ops->lcwrite = fsl_local_config_write;
+ ops->cread = fsl_rio_config_read;
+ ops->cwrite = fsl_rio_config_write;
+ ops->dsend = fsl_rio_doorbell_send;
port = kmalloc(sizeof(struct rio_mport), GFP_KERNEL);
port->id = 0;
@@ -909,7 +909,7 @@ void mpc85xx_rio_setup(int law_start, int law_size)
strcpy(port->name, "RIO0 mport");
port->ops = ops;
- port->host_deviceid = mpc85xx_rio_get_hdid(port->id);
+ port->host_deviceid = fsl_rio_get_hdid(port->id);
rio_register_mport(port);
@@ -928,5 +928,5 @@ void mpc85xx_rio_setup(int law_start, int law_size)
/* Configure outbound doorbell window */
out_be32((void *)&dbell_atmu_regs->rowbar, 0x000c0400);
out_be32((void *)&dbell_atmu_regs->rowar, 0x8004200b);
- mpc85xx_rio_doorbell_init(port);
+ fsl_rio_doorbell_init(port);
}
--
1.5.4
^ permalink raw reply related
* [PATCH 03/17] Move include/asm-ppc/rio.h to include/asm-powerpc/rio.h
From: Zhang Wei @ 2008-03-04 16:29 UTC (permalink / raw)
To: mporter, galak; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1204648202-5495-2-git-send-email-wei.zhang@freescale.com>
Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
---
include/asm-powerpc/rio.h | 18 ++++++++++++++++++
include/asm-ppc/rio.h | 18 ------------------
2 files changed, 18 insertions(+), 18 deletions(-)
create mode 100644 include/asm-powerpc/rio.h
delete mode 100644 include/asm-ppc/rio.h
diff --git a/include/asm-powerpc/rio.h b/include/asm-powerpc/rio.h
new file mode 100644
index 0000000..0018bf8
--- /dev/null
+++ b/include/asm-powerpc/rio.h
@@ -0,0 +1,18 @@
+/*
+ * RapidIO architecture support
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef ASM_PPC_RIO_H
+#define ASM_PPC_RIO_H
+
+extern void platform_rio_init(void);
+
+#endif /* ASM_PPC_RIO_H */
diff --git a/include/asm-ppc/rio.h b/include/asm-ppc/rio.h
deleted file mode 100644
index 0018bf8..0000000
--- a/include/asm-ppc/rio.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * RapidIO architecture support
- *
- * Copyright 2005 MontaVista Software, Inc.
- * Matt Porter <mporter@kernel.crashing.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#ifndef ASM_PPC_RIO_H
-#define ASM_PPC_RIO_H
-
-extern void platform_rio_init(void);
-
-#endif /* ASM_PPC_RIO_H */
--
1.5.4
^ permalink raw reply related
* [PATCH 04/17] Add RapidIO multi mport support.
From: Zhang Wei @ 2008-03-04 16:29 UTC (permalink / raw)
To: mporter, galak; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1204648202-5495-3-git-send-email-wei.zhang@freescale.com>
The original RapidIO driver suppose there is only one mpc85xx RIO
controller in system. So, some data structures are defined as
mpc85xx_rio global, such as 'regs_win', 'dbell_ring', 'msg_tx_ring'.
Now, I changed them to mport's private members. And you can define
multi RIO OF-nodes in dts file for multi RapidIO controller
in one processor, such as PCI/PCI-Ex host controllers
in Freescale's silicon. And the mport operation function declaration
should be changed to know which RapidIO controller is target.
Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
---
arch/powerpc/sysdev/fsl_rio.c | 355 +++++++++++++++++++++++------------------
drivers/rapidio/rio-access.c | 10 +-
include/linux/rio.h | 18 ++-
3 files changed, 219 insertions(+), 164 deletions(-)
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index 36c4be4..7eb6263 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -1,6 +1,9 @@
/*
* Freescale MPC85xx/MPC86xx RapidIO support
*
+ * Copyright (C) 2007, 2008 Freescale Semiconductor, Inc.
+ * Zhang Wei <wei.zhang@freescale.com>
+ *
* Copyright 2005 MontaVista Software, Inc.
* Matt Porter <mporter@kernel.crashing.org>
*
@@ -20,6 +23,11 @@
#include <asm/io.h>
+/* RapidIO definition irq, which read from OF-tree */
+#define IRQ_RIO_BELL(m) (((struct rio_priv *)(m->priv))->bellirq)
+#define IRQ_RIO_TX(m) (((struct rio_priv *)(m->priv))->txirq)
+#define IRQ_RIO_RX(m) (((struct rio_priv *)(m->priv))->rxirq)
+
#define RIO_REGS_BASE (CCSRBAR + 0xc0000)
#define RIO_ATMU_REGS_OFFSET 0x10c00
#define RIO_MSG_REGS_OFFSET 0x11000
@@ -112,20 +120,12 @@ struct rio_tx_desc {
u32 res4;
};
-static u32 regs_win;
-static struct rio_atmu_regs *atmu_regs;
-static struct rio_atmu_regs *maint_atmu_regs;
-static struct rio_atmu_regs *dbell_atmu_regs;
-static u32 dbell_win;
-static u32 maint_win;
-static struct rio_msg_regs *msg_regs;
-
-static struct rio_dbell_ring {
+struct rio_dbell_ring {
void *virt;
dma_addr_t phys;
-} dbell_ring;
+};
-static struct rio_msg_tx_ring {
+struct rio_msg_tx_ring {
void *virt;
dma_addr_t phys;
void *virt_buffer[RIO_MAX_TX_RING_SIZE];
@@ -133,16 +133,32 @@ static struct rio_msg_tx_ring {
int tx_slot;
int size;
void *dev_id;
-} msg_tx_ring;
+};
-static struct rio_msg_rx_ring {
+struct rio_msg_rx_ring {
void *virt;
dma_addr_t phys;
void *virt_buffer[RIO_MAX_RX_RING_SIZE];
int rx_slot;
int size;
void *dev_id;
-} msg_rx_ring;
+};
+
+struct rio_priv {
+ void __iomem *regs_win;
+ struct rio_atmu_regs __iomem *atmu_regs;
+ struct rio_atmu_regs __iomem *maint_atmu_regs;
+ struct rio_atmu_regs __iomem *dbell_atmu_regs;
+ void __iomem *dbell_win;
+ void __iomem *maint_win;
+ struct rio_msg_regs __iomem *msg_regs;
+ struct rio_dbell_ring dbell_ring;
+ struct rio_msg_tx_ring msg_tx_ring;
+ struct rio_msg_rx_ring msg_rx_ring;
+ int bellirq;
+ int txirq;
+ int rxirq;
+};
/**
* fsl_rio_doorbell_send - Send a MPC85xx doorbell message
@@ -153,12 +169,14 @@ static struct rio_msg_rx_ring {
* Sends a MPC85xx doorbell message. Returns %0 on success or
* %-EINVAL on failure.
*/
-static int fsl_rio_doorbell_send(int index, u16 destid, u16 data)
+static int fsl_rio_doorbell_send(struct rio_mport *mport,
+ int index, u16 destid, u16 data)
{
+ struct rio_priv *priv = mport->priv;
pr_debug("fsl_doorbell_send: index %d destid %4.4x data %4.4x\n",
index, destid, data);
- out_be32((void *)&dbell_atmu_regs->rowtar, destid << 22);
- out_be16((void *)(dbell_win), data);
+ out_be32(&priv->dbell_atmu_regs->rowtar, destid << 22);
+ out_be16(priv->dbell_win, data);
return 0;
}
@@ -173,11 +191,13 @@ static int fsl_rio_doorbell_send(int index, u16 destid, u16 data)
* Generates a MPC85xx local configuration space read. Returns %0 on
* success or %-EINVAL on failure.
*/
-static int fsl_local_config_read(int index, u32 offset, int len, u32 * data)
+static int fsl_local_config_read(struct rio_mport *mport,
+ int index, u32 offset, int len, u32 * data)
{
+ struct rio_priv *priv = mport->priv;
pr_debug("fsl_local_config_read: index %d offset %8.8x\n", index,
offset);
- *data = in_be32((void *)(regs_win + offset));
+ *data = in_be32(priv->regs_win + offset);
return 0;
}
@@ -192,12 +212,14 @@ static int fsl_local_config_read(int index, u32 offset, int len, u32 * data)
* Generates a MPC85xx local configuration space write. Returns %0 on
* success or %-EINVAL on failure.
*/
-static int fsl_local_config_write(int index, u32 offset, int len, u32 data)
+static int fsl_local_config_write(struct rio_mport *mport,
+ int index, u32 offset, int len, u32 data)
{
+ struct rio_priv *priv = mport->priv;
pr_debug
("fsl_local_config_write: index %d offset %8.8x data %8.8x\n",
index, offset, data);
- out_be32((void *)(regs_win + offset), data);
+ out_be32(priv->regs_win + offset, data);
return 0;
}
@@ -215,18 +237,19 @@ static int fsl_local_config_write(int index, u32 offset, int len, u32 data)
* success or %-EINVAL on failure.
*/
static int
-fsl_rio_config_read(int index, u16 destid, u8 hopcount, u32 offset, int len,
- u32 * val)
+fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid,
+ u8 hopcount, u32 offset, int len, u32 * val)
{
+ struct rio_priv *priv = mport->priv;
u8 *data;
pr_debug
("fsl_rio_config_read: index %d destid %d hopcount %d offset %8.8x len %d\n",
index, destid, hopcount, offset, len);
- out_be32((void *)&maint_atmu_regs->rowtar,
+ out_be32(&priv->maint_atmu_regs->rowtar,
(destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9));
- data = (u8 *) maint_win + offset;
+ data = (u8 *) priv->maint_win + offset;
switch (len) {
case 1:
*val = in_8((u8 *) data);
@@ -255,17 +278,18 @@ fsl_rio_config_read(int index, u16 destid, u8 hopcount, u32 offset, int len,
* success or %-EINVAL on failure.
*/
static int
-fsl_rio_config_write(int index, u16 destid, u8 hopcount, u32 offset,
- int len, u32 val)
+fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid,
+ u8 hopcount, u32 offset, int len, u32 val)
{
+ struct rio_priv *priv = mport->priv;
u8 *data;
pr_debug
("fsl_rio_config_write: index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n",
index, destid, hopcount, offset, len, val);
- out_be32((void *)&maint_atmu_regs->rowtar,
+ out_be32(&priv->maint_atmu_regs->rowtar,
(destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9));
- data = (u8 *) maint_win + offset;
+ data = (u8 *) priv->maint_win + offset;
switch (len) {
case 1:
out_8((u8 *) data, val);
@@ -296,9 +320,10 @@ int
rio_hw_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox,
void *buffer, size_t len)
{
+ struct rio_priv *priv = mport->priv;
u32 omr;
- struct rio_tx_desc *desc =
- (struct rio_tx_desc *)msg_tx_ring.virt + msg_tx_ring.tx_slot;
+ struct rio_tx_desc *desc = (struct rio_tx_desc *)priv->msg_tx_ring.virt
+ + priv->msg_tx_ring.tx_slot;
int ret = 0;
pr_debug
@@ -311,11 +336,11 @@ rio_hw_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox,
}
/* Copy and clear rest of buffer */
- memcpy(msg_tx_ring.virt_buffer[msg_tx_ring.tx_slot], buffer, len);
+ memcpy(priv->msg_tx_ring.virt_buffer[priv->msg_tx_ring.tx_slot], buffer,
+ len);
if (len < (RIO_MAX_MSG_SIZE - 4))
- memset((void *)((u32) msg_tx_ring.
- virt_buffer[msg_tx_ring.tx_slot] + len), 0,
- RIO_MAX_MSG_SIZE - len);
+ memset(priv->msg_tx_ring.virt_buffer[priv->msg_tx_ring.tx_slot]
+ + len, 0, RIO_MAX_MSG_SIZE - len);
/* Set mbox field for message */
desc->dport = mbox & 0x3;
@@ -327,15 +352,16 @@ rio_hw_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox,
desc->dwcnt = is_power_of_2(len) ? len : 1 << get_bitmask_order(len);
/* Set snooping and source buffer address */
- desc->saddr = 0x00000004 | msg_tx_ring.phys_buffer[msg_tx_ring.tx_slot];
+ desc->saddr = 0x00000004
+ | priv->msg_tx_ring.phys_buffer[priv->msg_tx_ring.tx_slot];
/* Increment enqueue pointer */
- omr = in_be32((void *)&msg_regs->omr);
- out_be32((void *)&msg_regs->omr, omr | RIO_MSG_OMR_MUI);
+ omr = in_be32(&priv->msg_regs->omr);
+ out_be32(&priv->msg_regs->omr, omr | RIO_MSG_OMR_MUI);
/* Go to next descriptor */
- if (++msg_tx_ring.tx_slot == msg_tx_ring.size)
- msg_tx_ring.tx_slot = 0;
+ if (++priv->msg_tx_ring.tx_slot == priv->msg_tx_ring.size)
+ priv->msg_tx_ring.tx_slot = 0;
out:
return ret;
@@ -356,28 +382,30 @@ fsl_rio_tx_handler(int irq, void *dev_instance)
{
int osr;
struct rio_mport *port = (struct rio_mport *)dev_instance;
+ struct rio_priv *priv = port->priv;
- osr = in_be32((void *)&msg_regs->osr);
+ osr = in_be32(&priv->msg_regs->osr);
if (osr & RIO_MSG_OSR_TE) {
pr_info("RIO: outbound message transmission error\n");
- out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_TE);
+ out_be32(&priv->msg_regs->osr, RIO_MSG_OSR_TE);
goto out;
}
if (osr & RIO_MSG_OSR_QOI) {
pr_info("RIO: outbound message queue overflow\n");
- out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_QOI);
+ out_be32(&priv->msg_regs->osr, RIO_MSG_OSR_QOI);
goto out;
}
if (osr & RIO_MSG_OSR_EOMI) {
- u32 dqp = in_be32((void *)&msg_regs->odqdpar);
- int slot = (dqp - msg_tx_ring.phys) >> 5;
- port->outb_msg[0].mcback(port, msg_tx_ring.dev_id, -1, slot);
+ u32 dqp = in_be32(&priv->msg_regs->odqdpar);
+ int slot = (dqp - priv->msg_tx_ring.phys) >> 5;
+ port->outb_msg[0].mcback(port, priv->msg_tx_ring.dev_id, -1,
+ slot);
/* Ack the end-of-message interrupt */
- out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_EOMI);
+ out_be32(&priv->msg_regs->osr, RIO_MSG_OSR_EOMI);
}
out:
@@ -398,6 +426,7 @@ fsl_rio_tx_handler(int irq, void *dev_instance)
int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries)
{
int i, j, rc = 0;
+ struct rio_priv *priv = mport->priv;
if ((entries < RIO_MIN_TX_RING_SIZE) ||
(entries > RIO_MAX_TX_RING_SIZE) || (!is_power_of_2(entries))) {
@@ -406,53 +435,54 @@ int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entr
}
/* Initialize shadow copy ring */
- msg_tx_ring.dev_id = dev_id;
- msg_tx_ring.size = entries;
+ priv->msg_tx_ring.dev_id = dev_id;
+ priv->msg_tx_ring.size = entries;
- for (i = 0; i < msg_tx_ring.size; i++) {
+ for (i = 0; i < priv->msg_tx_ring.size; i++) {
if (!
- (msg_tx_ring.virt_buffer[i] =
+ (priv->msg_tx_ring.virt_buffer[i] =
dma_alloc_coherent(NULL, RIO_MSG_BUFFER_SIZE,
- &msg_tx_ring.phys_buffer[i],
+ &priv->msg_tx_ring.phys_buffer[i],
GFP_KERNEL))) {
rc = -ENOMEM;
- for (j = 0; j < msg_tx_ring.size; j++)
- if (msg_tx_ring.virt_buffer[j])
+ for (j = 0; j < priv->msg_tx_ring.size; j++)
+ if (priv->msg_tx_ring.virt_buffer[j])
dma_free_coherent(NULL,
RIO_MSG_BUFFER_SIZE,
- msg_tx_ring.
+ priv->msg_tx_ring.
virt_buffer[j],
- msg_tx_ring.
+ priv->msg_tx_ring.
phys_buffer[j]);
goto out;
}
}
/* Initialize outbound message descriptor ring */
- if (!(msg_tx_ring.virt = dma_alloc_coherent(NULL,
- msg_tx_ring.size *
+ if (!(priv->msg_tx_ring.virt = dma_alloc_coherent(NULL,
+ priv->msg_tx_ring.size *
RIO_MSG_DESC_SIZE,
- &msg_tx_ring.phys,
+ &priv->msg_tx_ring.phys,
GFP_KERNEL))) {
rc = -ENOMEM;
goto out_dma;
}
- memset(msg_tx_ring.virt, 0, msg_tx_ring.size * RIO_MSG_DESC_SIZE);
- msg_tx_ring.tx_slot = 0;
+ memset(priv->msg_tx_ring.virt, 0,
+ priv->msg_tx_ring.size * RIO_MSG_DESC_SIZE);
+ priv->msg_tx_ring.tx_slot = 0;
/* Point dequeue/enqueue pointers at first entry in ring */
- out_be32((void *)&msg_regs->odqdpar, msg_tx_ring.phys);
- out_be32((void *)&msg_regs->odqepar, msg_tx_ring.phys);
+ out_be32(&priv->msg_regs->odqdpar, priv->msg_tx_ring.phys);
+ out_be32(&priv->msg_regs->odqepar, priv->msg_tx_ring.phys);
/* Configure for snooping */
- out_be32((void *)&msg_regs->osar, 0x00000004);
+ out_be32(&priv->msg_regs->osar, 0x00000004);
/* Clear interrupt status */
- out_be32((void *)&msg_regs->osr, 0x000000b3);
+ out_be32(&priv->msg_regs->osr, 0x000000b3);
/* Hook up outbound message handler */
if ((rc =
- request_irq(MPC85xx_IRQ_RIO_TX, fsl_rio_tx_handler, 0,
+ request_irq(IRQ_RIO_TX(mport), fsl_rio_tx_handler, 0,
"msg_tx", (void *)mport)) < 0)
goto out_irq;
@@ -463,28 +493,28 @@ int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entr
* Chaining mode
* Disable
*/
- out_be32((void *)&msg_regs->omr, 0x00100220);
+ out_be32(&priv->msg_regs->omr, 0x00100220);
/* Set number of entries */
- out_be32((void *)&msg_regs->omr,
- in_be32((void *)&msg_regs->omr) |
+ out_be32(&priv->msg_regs->omr,
+ in_be32(&priv->msg_regs->omr) |
((get_bitmask_order(entries) - 2) << 12));
/* Now enable the unit */
- out_be32((void *)&msg_regs->omr, in_be32((void *)&msg_regs->omr) | 0x1);
+ out_be32(&priv->msg_regs->omr, in_be32(&priv->msg_regs->omr) | 0x1);
out:
return rc;
out_irq:
- dma_free_coherent(NULL, msg_tx_ring.size * RIO_MSG_DESC_SIZE,
- msg_tx_ring.virt, msg_tx_ring.phys);
+ dma_free_coherent(NULL, priv->msg_tx_ring.size * RIO_MSG_DESC_SIZE,
+ priv->msg_tx_ring.virt, priv->msg_tx_ring.phys);
out_dma:
- for (i = 0; i < msg_tx_ring.size; i++)
+ for (i = 0; i < priv->msg_tx_ring.size; i++)
dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE,
- msg_tx_ring.virt_buffer[i],
- msg_tx_ring.phys_buffer[i]);
+ priv->msg_tx_ring.virt_buffer[i],
+ priv->msg_tx_ring.phys_buffer[i]);
return rc;
}
@@ -499,15 +529,16 @@ int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entr
*/
void rio_close_outb_mbox(struct rio_mport *mport, int mbox)
{
+ struct rio_priv *priv = mport->priv;
/* Disable inbound message unit */
- out_be32((void *)&msg_regs->omr, 0);
+ out_be32(&priv->msg_regs->omr, 0);
/* Free ring */
- dma_free_coherent(NULL, msg_tx_ring.size * RIO_MSG_DESC_SIZE,
- msg_tx_ring.virt, msg_tx_ring.phys);
+ dma_free_coherent(NULL, priv->msg_tx_ring.size * RIO_MSG_DESC_SIZE,
+ priv->msg_tx_ring.virt, priv->msg_tx_ring.phys);
/* Free interrupt */
- free_irq(MPC85xx_IRQ_RIO_TX, (void *)mport);
+ free_irq(IRQ_RIO_TX(mport), (void *)mport);
}
/**
@@ -523,12 +554,13 @@ fsl_rio_rx_handler(int irq, void *dev_instance)
{
int isr;
struct rio_mport *port = (struct rio_mport *)dev_instance;
+ struct rio_priv *priv = port->priv;
- isr = in_be32((void *)&msg_regs->isr);
+ isr = in_be32(&priv->msg_regs->isr);
if (isr & RIO_MSG_ISR_TE) {
pr_info("RIO: inbound message reception error\n");
- out_be32((void *)&msg_regs->isr, RIO_MSG_ISR_TE);
+ out_be32((void *)&priv->msg_regs->isr, RIO_MSG_ISR_TE);
goto out;
}
@@ -540,10 +572,10 @@ fsl_rio_rx_handler(int irq, void *dev_instance)
* make the callback with an unknown/invalid mailbox number
* argument.
*/
- port->inb_msg[0].mcback(port, msg_rx_ring.dev_id, -1, -1);
+ port->inb_msg[0].mcback(port, priv->msg_rx_ring.dev_id, -1, -1);
/* Ack the queueing interrupt */
- out_be32((void *)&msg_regs->isr, RIO_MSG_ISR_DIQI);
+ out_be32(&priv->msg_regs->isr, RIO_MSG_ISR_DIQI);
}
out:
@@ -564,6 +596,7 @@ fsl_rio_rx_handler(int irq, void *dev_instance)
int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries)
{
int i, rc = 0;
+ struct rio_priv *priv = mport->priv;
if ((entries < RIO_MIN_RX_RING_SIZE) ||
(entries > RIO_MAX_RX_RING_SIZE) || (!is_power_of_2(entries))) {
@@ -572,36 +605,36 @@ int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entri
}
/* Initialize client buffer ring */
- msg_rx_ring.dev_id = dev_id;
- msg_rx_ring.size = entries;
- msg_rx_ring.rx_slot = 0;
- for (i = 0; i < msg_rx_ring.size; i++)
- msg_rx_ring.virt_buffer[i] = NULL;
+ priv->msg_rx_ring.dev_id = dev_id;
+ priv->msg_rx_ring.size = entries;
+ priv->msg_rx_ring.rx_slot = 0;
+ for (i = 0; i < priv->msg_rx_ring.size; i++)
+ priv->msg_rx_ring.virt_buffer[i] = NULL;
/* Initialize inbound message ring */
- if (!(msg_rx_ring.virt = dma_alloc_coherent(NULL,
- msg_rx_ring.size *
+ if (!(priv->msg_rx_ring.virt = dma_alloc_coherent(NULL,
+ priv->msg_rx_ring.size *
RIO_MAX_MSG_SIZE,
- &msg_rx_ring.phys,
+ &priv->msg_rx_ring.phys,
GFP_KERNEL))) {
rc = -ENOMEM;
goto out;
}
/* Point dequeue/enqueue pointers at first entry in ring */
- out_be32((void *)&msg_regs->ifqdpar, (u32) msg_rx_ring.phys);
- out_be32((void *)&msg_regs->ifqepar, (u32) msg_rx_ring.phys);
+ out_be32(&priv->msg_regs->ifqdpar, (u32) priv->msg_rx_ring.phys);
+ out_be32(&priv->msg_regs->ifqepar, (u32) priv->msg_rx_ring.phys);
/* Clear interrupt status */
- out_be32((void *)&msg_regs->isr, 0x00000091);
+ out_be32(&priv->msg_regs->isr, 0x00000091);
/* Hook up inbound message handler */
if ((rc =
- request_irq(MPC85xx_IRQ_RIO_RX, fsl_rio_rx_handler, 0,
+ request_irq(IRQ_RIO_RX(mport), fsl_rio_rx_handler, 0,
"msg_rx", (void *)mport)) < 0) {
dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE,
- msg_tx_ring.virt_buffer[i],
- msg_tx_ring.phys_buffer[i]);
+ priv->msg_tx_ring.virt_buffer[i],
+ priv->msg_tx_ring.phys_buffer[i]);
goto out;
}
@@ -612,15 +645,13 @@ int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entri
* Unmask all interrupt sources
* Disable
*/
- out_be32((void *)&msg_regs->imr, 0x001b0060);
+ out_be32(&priv->msg_regs->imr, 0x001b0060);
/* Set number of queue entries */
- out_be32((void *)&msg_regs->imr,
- in_be32((void *)&msg_regs->imr) |
- ((get_bitmask_order(entries) - 2) << 12));
+ setbits32(&priv->msg_regs->imr, (get_bitmask_order(entries) - 2) << 12);
/* Now enable the unit */
- out_be32((void *)&msg_regs->imr, in_be32((void *)&msg_regs->imr) | 0x1);
+ setbits32(&priv->msg_regs->imr, 0x1);
out:
return rc;
@@ -636,15 +667,16 @@ int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entri
*/
void rio_close_inb_mbox(struct rio_mport *mport, int mbox)
{
+ struct rio_priv *priv = mport->priv;
/* Disable inbound message unit */
- out_be32((void *)&msg_regs->imr, 0);
+ out_be32(&priv->msg_regs->imr, 0);
/* Free ring */
- dma_free_coherent(NULL, msg_rx_ring.size * RIO_MAX_MSG_SIZE,
- msg_rx_ring.virt, msg_rx_ring.phys);
+ dma_free_coherent(NULL, priv->msg_rx_ring.size * RIO_MAX_MSG_SIZE,
+ priv->msg_rx_ring.virt, priv->msg_rx_ring.phys);
/* Free interrupt */
- free_irq(MPC85xx_IRQ_RIO_RX, (void *)mport);
+ free_irq(IRQ_RIO_RX(mport), (void *)mport);
}
/**
@@ -659,21 +691,22 @@ void rio_close_inb_mbox(struct rio_mport *mport, int mbox)
int rio_hw_add_inb_buffer(struct rio_mport *mport, int mbox, void *buf)
{
int rc = 0;
+ struct rio_priv *priv = mport->priv;
pr_debug("RIO: rio_hw_add_inb_buffer(), msg_rx_ring.rx_slot %d\n",
- msg_rx_ring.rx_slot);
+ priv->msg_rx_ring.rx_slot);
- if (msg_rx_ring.virt_buffer[msg_rx_ring.rx_slot]) {
+ if (priv->msg_rx_ring.virt_buffer[priv->msg_rx_ring.rx_slot]) {
printk(KERN_ERR
"RIO: error adding inbound buffer %d, buffer exists\n",
- msg_rx_ring.rx_slot);
+ priv->msg_rx_ring.rx_slot);
rc = -EINVAL;
goto out;
}
- msg_rx_ring.virt_buffer[msg_rx_ring.rx_slot] = buf;
- if (++msg_rx_ring.rx_slot == msg_rx_ring.size)
- msg_rx_ring.rx_slot = 0;
+ priv->msg_rx_ring.virt_buffer[priv->msg_rx_ring.rx_slot] = buf;
+ if (++priv->msg_rx_ring.rx_slot == priv->msg_rx_ring.size)
+ priv->msg_rx_ring.rx_slot = 0;
out:
return rc;
@@ -691,20 +724,20 @@ EXPORT_SYMBOL_GPL(rio_hw_add_inb_buffer);
*/
void *rio_hw_get_inb_message(struct rio_mport *mport, int mbox)
{
- u32 imr;
+ struct rio_priv *priv = mport->priv;
u32 phys_buf, virt_buf;
void *buf = NULL;
int buf_idx;
- phys_buf = in_be32((void *)&msg_regs->ifqdpar);
+ phys_buf = in_be32(&priv->msg_regs->ifqdpar);
/* If no more messages, then bail out */
- if (phys_buf == in_be32((void *)&msg_regs->ifqepar))
+ if (phys_buf == in_be32(&priv->msg_regs->ifqepar))
goto out2;
- virt_buf = (u32) msg_rx_ring.virt + (phys_buf - msg_rx_ring.phys);
- buf_idx = (phys_buf - msg_rx_ring.phys) / RIO_MAX_MSG_SIZE;
- buf = msg_rx_ring.virt_buffer[buf_idx];
+ virt_buf = (u32) priv->msg_rx_ring.virt + (phys_buf - priv->msg_rx_ring.phys);
+ buf_idx = (phys_buf - priv->msg_rx_ring.phys) / RIO_MAX_MSG_SIZE;
+ buf = priv->msg_rx_ring.virt_buffer[buf_idx];
if (!buf) {
printk(KERN_ERR
@@ -716,11 +749,10 @@ void *rio_hw_get_inb_message(struct rio_mport *mport, int mbox)
memcpy(buf, (void *)virt_buf, RIO_MAX_MSG_SIZE);
/* Clear the available buffer */
- msg_rx_ring.virt_buffer[buf_idx] = NULL;
+ priv->msg_rx_ring.virt_buffer[buf_idx] = NULL;
out1:
- imr = in_be32((void *)&msg_regs->imr);
- out_be32((void *)&msg_regs->imr, imr | RIO_MSG_IMR_MI);
+ setbits32(&priv->msg_regs->imr, RIO_MSG_IMR_MI);
out2:
return buf;
@@ -741,27 +773,27 @@ fsl_rio_dbell_handler(int irq, void *dev_instance)
{
int dsr;
struct rio_mport *port = (struct rio_mport *)dev_instance;
+ struct rio_priv *priv = port->priv;
- dsr = in_be32((void *)&msg_regs->dsr);
+ dsr = in_be32(&priv->msg_regs->dsr);
if (dsr & DOORBELL_DSR_TE) {
pr_info("RIO: doorbell reception error\n");
- out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_TE);
+ out_be32(&priv->msg_regs->dsr, DOORBELL_DSR_TE);
goto out;
}
if (dsr & DOORBELL_DSR_QFI) {
pr_info("RIO: doorbell queue full\n");
- out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_QFI);
+ out_be32(&priv->msg_regs->dsr, DOORBELL_DSR_QFI);
goto out;
}
/* XXX Need to check/dispatch until queue empty */
if (dsr & DOORBELL_DSR_DIQI) {
u32 dmsg =
- (u32) dbell_ring.virt +
- (in_be32((void *)&msg_regs->dqdpar) & 0xfff);
- u32 dmr;
+ (u32) priv->dbell_ring.virt +
+ (in_be32(&priv->msg_regs->dqdpar) & 0xfff);
struct rio_dbell *dbell;
int found = 0;
@@ -784,9 +816,8 @@ fsl_rio_dbell_handler(int irq, void *dev_instance)
("RIO: spurious doorbell, sid %2.2x tid %2.2x info %4.4x\n",
DBELL_SID(dmsg), DBELL_TID(dmsg), DBELL_INF(dmsg));
}
- dmr = in_be32((void *)&msg_regs->dmr);
- out_be32((void *)&msg_regs->dmr, dmr | DOORBELL_DMR_DI);
- out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_DIQI);
+ setbits32(&priv->msg_regs->dmr, DOORBELL_DMR_DI);
+ out_be32(&priv->msg_regs->dsr, DOORBELL_DSR_DIQI);
}
out:
@@ -803,10 +834,11 @@ fsl_rio_dbell_handler(int irq, void *dev_instance)
*/
static int fsl_rio_doorbell_init(struct rio_mport *mport)
{
+ struct rio_priv *priv = mport->priv;
int rc = 0;
/* Map outbound doorbell window immediately after maintenance window */
- if (!(dbell_win =
+ if (!(priv->dbell_win =
(u32) ioremap(mport->iores.start + RIO_MAINT_WIN_SIZE,
RIO_DBELL_WIN_SIZE))) {
printk(KERN_ERR
@@ -816,37 +848,37 @@ static int fsl_rio_doorbell_init(struct rio_mport *mport)
}
/* Initialize inbound doorbells */
- if (!(dbell_ring.virt = dma_alloc_coherent(NULL,
+ if (!(priv->dbell_ring.virt = dma_alloc_coherent(NULL,
512 * DOORBELL_MESSAGE_SIZE,
- &dbell_ring.phys,
+ &priv->dbell_ring.phys,
GFP_KERNEL))) {
printk(KERN_ERR "RIO: unable allocate inbound doorbell ring\n");
rc = -ENOMEM;
- iounmap((void *)dbell_win);
+ iounmap(priv->dbell_win);
goto out;
}
/* Point dequeue/enqueue pointers at first entry in ring */
- out_be32((void *)&msg_regs->dqdpar, (u32) dbell_ring.phys);
- out_be32((void *)&msg_regs->dqepar, (u32) dbell_ring.phys);
+ out_be32(&priv->msg_regs->dqdpar, (u32) priv->dbell_ring.phys);
+ out_be32(&priv->msg_regs->dqepar, (u32) priv->dbell_ring.phys);
/* Clear interrupt status */
- out_be32((void *)&msg_regs->dsr, 0x00000091);
+ out_be32(&priv->msg_regs->dsr, 0x00000091);
/* Hook up doorbell handler */
if ((rc =
- request_irq(MPC85xx_IRQ_RIO_BELL, fsl_rio_dbell_handler, 0,
+ request_irq(IRQ_RIO_BELL(mport), fsl_rio_dbell_handler, 0,
"dbell_rx", (void *)mport) < 0)) {
- iounmap((void *)dbell_win);
+ iounmap(priv->dbell_win);
dma_free_coherent(NULL, 512 * DOORBELL_MESSAGE_SIZE,
- dbell_ring.virt, dbell_ring.phys);
+ priv->dbell_ring.virt, priv->dbell_ring.phys);
printk(KERN_ERR
"MPC85xx RIO: unable to request inbound doorbell irq");
goto out;
}
/* Configure doorbells for snooping, 512 entries, and enable */
- out_be32((void *)&msg_regs->dmr, 0x00108161);
+ out_be32(&priv->msg_regs->dmr, 0x00108161);
out:
return rc;
@@ -887,6 +919,8 @@ void fsl_rio_setup(int law_start, int law_size)
{
struct rio_ops *ops;
struct rio_mport *port;
+ struct rio_priv *priv = NULL;
+ int rc;
ops = kmalloc(sizeof(struct rio_ops), GFP_KERNEL);
ops->lcread = fsl_local_config_read;
@@ -895,9 +929,17 @@ void fsl_rio_setup(int law_start, int law_size)
ops->cwrite = fsl_rio_config_write;
ops->dsend = fsl_rio_doorbell_send;
- port = kmalloc(sizeof(struct rio_mport), GFP_KERNEL);
+ port = kzalloc(sizeof(struct rio_mport), GFP_KERNEL);
port->id = 0;
port->index = 0;
+
+ priv = kzalloc(sizeof(struct rio_priv), GFP_KERNEL);
+ if (!priv) {
+ printk(KERN_ERR "Can't alloc memory for 'priv'\n");
+ rc = -ENOMEM;
+ goto err;
+ }
+
INIT_LIST_HEAD(&port->dbells);
port->iores.start = law_start;
port->iores.end = law_start + law_size;
@@ -911,22 +953,31 @@ void fsl_rio_setup(int law_start, int law_size)
port->ops = ops;
port->host_deviceid = fsl_rio_get_hdid(port->id);
+ port->priv = priv;
rio_register_mport(port);
- regs_win = (u32) ioremap(RIO_REGS_BASE, 0x20000);
- atmu_regs = (struct rio_atmu_regs *)(regs_win + RIO_ATMU_REGS_OFFSET);
- maint_atmu_regs = atmu_regs + 1;
- dbell_atmu_regs = atmu_regs + 2;
- msg_regs = (struct rio_msg_regs *)(regs_win + RIO_MSG_REGS_OFFSET);
+ priv->regs_win = (u32) ioremap(RIO_REGS_BASE, 0x20000);
+ priv->atmu_regs = (struct rio_atmu_regs *)(priv->regs_win
+ + RIO_ATMU_REGS_OFFSET);
+ priv->maint_atmu_regs = priv->atmu_regs + 1;
+ priv->dbell_atmu_regs = priv->atmu_regs + 2;
+ priv->msg_regs = (struct rio_msg_regs *)(priv->regs_win + RIO_MSG_REGS_OFFSET);
/* Configure maintenance transaction window */
- out_be32((void *)&maint_atmu_regs->rowbar, 0x000c0000);
- out_be32((void *)&maint_atmu_regs->rowar, 0x80077015);
+ out_be32(&priv->maint_atmu_regs->rowbar, 0x000c0000);
+ out_be32(&priv->maint_atmu_regs->rowar, 0x80077015);
- maint_win = (u32) ioremap(law_start, RIO_MAINT_WIN_SIZE);
+ priv->maint_win = (u32) ioremap(law_start, RIO_MAINT_WIN_SIZE);
/* Configure outbound doorbell window */
- out_be32((void *)&dbell_atmu_regs->rowbar, 0x000c0400);
- out_be32((void *)&dbell_atmu_regs->rowar, 0x8004200b);
+ out_be32(&priv->dbell_atmu_regs->rowbar, 0x000c0400);
+ out_be32(&priv->dbell_atmu_regs->rowar, 0x8004200b);
fsl_rio_doorbell_init(port);
+
+ return;
+err:
+ if (priv)
+ iounmap(priv->regs_win);
+ kfree(priv);
+ kfree(port);
}
diff --git a/drivers/rapidio/rio-access.c b/drivers/rapidio/rio-access.c
index 8b56bbd..a3824ba 100644
--- a/drivers/rapidio/rio-access.c
+++ b/drivers/rapidio/rio-access.c
@@ -48,7 +48,7 @@ int __rio_local_read_config_##size \
u32 data = 0; \
if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
spin_lock_irqsave(&rio_config_lock, flags); \
- res = mport->ops->lcread(mport->id, offset, len, &data); \
+ res = mport->ops->lcread(mport, mport->id, offset, len, &data); \
*value = (type)data; \
spin_unlock_irqrestore(&rio_config_lock, flags); \
return res; \
@@ -71,7 +71,7 @@ int __rio_local_write_config_##size \
unsigned long flags; \
if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
spin_lock_irqsave(&rio_config_lock, flags); \
- res = mport->ops->lcwrite(mport->id, offset, len, value); \
+ res = mport->ops->lcwrite(mport, mport->id, offset, len, value);\
spin_unlock_irqrestore(&rio_config_lock, flags); \
return res; \
}
@@ -108,7 +108,7 @@ int rio_mport_read_config_##size \
u32 data = 0; \
if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
spin_lock_irqsave(&rio_config_lock, flags); \
- res = mport->ops->cread(mport->id, destid, hopcount, offset, len, &data); \
+ res = mport->ops->cread(mport, mport->id, destid, hopcount, offset, len, &data); \
*value = (type)data; \
spin_unlock_irqrestore(&rio_config_lock, flags); \
return res; \
@@ -131,7 +131,7 @@ int rio_mport_write_config_##size \
unsigned long flags; \
if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
spin_lock_irqsave(&rio_config_lock, flags); \
- res = mport->ops->cwrite(mport->id, destid, hopcount, offset, len, value); \
+ res = mport->ops->cwrite(mport, mport->id, destid, hopcount, offset, len, value); \
spin_unlock_irqrestore(&rio_config_lock, flags); \
return res; \
}
@@ -166,7 +166,7 @@ int rio_mport_send_doorbell(struct rio_mport *mport, u16 destid, u16 data)
unsigned long flags;
spin_lock_irqsave(&rio_doorbell_lock, flags);
- res = mport->ops->dsend(mport->id, destid, data);
+ res = mport->ops->dsend(mport, mport->id, destid, data);
spin_unlock_irqrestore(&rio_doorbell_lock, flags);
return res;
diff --git a/include/linux/rio.h b/include/linux/rio.h
index 68e3f68..9ed78dc 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -163,6 +163,7 @@ struct rio_dbell {
* @id: Port ID, unique among all ports
* @index: Port index, unique among all port interfaces of the same type
* @name: Port name string
+ * @priv: Master port private data
*/
struct rio_mport {
struct list_head dbells; /* list of doorbell events */
@@ -178,6 +179,7 @@ struct rio_mport {
unsigned char index; /* port index, unique among all port
interfaces of the same type */
unsigned char name[40];
+ void *priv; /* Master port private data */
};
/**
@@ -229,13 +231,15 @@ struct rio_switch {
* @dsend: Callback to send a doorbell message.
*/
struct rio_ops {
- int (*lcread) (int index, u32 offset, int len, u32 * data);
- int (*lcwrite) (int index, u32 offset, int len, u32 data);
- int (*cread) (int index, u16 destid, u8 hopcount, u32 offset, int len,
- u32 * data);
- int (*cwrite) (int index, u16 destid, u8 hopcount, u32 offset, int len,
- u32 data);
- int (*dsend) (int index, u16 destid, u16 data);
+ int (*lcread) (struct rio_mport *mport, int index, u32 offset, int len,
+ u32 * data);
+ int (*lcwrite) (struct rio_mport *mport, int index, u32 offset, int len,
+ u32 data);
+ int (*cread) (struct rio_mport *mport, int index, u16 destid,
+ u8 hopcount, u32 offset, int len, u32 * data);
+ int (*cwrite) (struct rio_mport *mport, int index, u16 destid,
+ u8 hopcount, u32 offset, int len, u32 data);
+ int (*dsend) (struct rio_mport *mport, int index, u16 destid, u16 data);
};
#define RIO_RESOURCE_MEM 0x00000100
--
1.5.4
^ permalink raw reply related
* [PATCH 06/17] Change the kernel configurated RapidIO system size to auto-probing.
From: Zhang Wei @ 2008-03-04 16:29 UTC (permalink / raw)
To: mporter, galak; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1204648202-5495-5-git-send-email-wei.zhang@freescale.com>
The RapidIO system size will auto probe in RIO setup. The route
table and rionet_active in rionet.c are changed to be allocated
dynamically according the system size.
Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
---
arch/powerpc/sysdev/fsl_rio.c | 6 +++++
drivers/net/rionet.c | 16 +++++++++++-
drivers/rapidio/Kconfig | 8 ------
drivers/rapidio/rio-scan.c | 51 +++++++++++++++++++++++++++++------------
drivers/rapidio/rio-sysfs.c | 3 +-
drivers/rapidio/rio.c | 2 +-
drivers/rapidio/rio.h | 9 +-----
include/linux/rio.h | 14 +++++-----
8 files changed, 68 insertions(+), 41 deletions(-)
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index 5c9af4f..9dae418 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -1010,6 +1010,12 @@ int fsl_rio_setup(struct of_device *dev)
rio_register_mport(port);
priv->regs_win = (u32) ioremap(regs.start, regs.end - regs.start + 1);
+
+ port->sys_size = (in_be32((priv->regs_win + RIO_PEF_CAR))
+ & RIO_PEF_CTLS) >> 4;
+ dev_info(&dev->dev, "RapidIO Common Transport System size: %d\n",
+ port->sys_size ? 65536 : 256);
+
priv->atmu_regs = (struct rio_atmu_regs *)(priv->regs_win
+ RIO_ATMU_REGS_OFFSET);
priv->maint_atmu_regs = priv->atmu_regs + 1;
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index e7fd08a..6aa9731 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -77,7 +77,7 @@ static int rionet_capable = 1;
* could be made into a hash table to save memory depending
* on system trade-offs.
*/
-static struct rio_dev *rionet_active[RIO_MAX_ROUTE_ENTRIES];
+static struct rio_dev **rionet_active;
#define is_rionet_capable(pef, src_ops, dst_ops) \
((pef & RIO_PEF_INB_MBOX) && \
@@ -195,7 +195,8 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
}
if (eth->h_dest[0] & 0x01) {
- for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++)
+ for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rnet->mport->sys_size);
+ i++)
if (rionet_active[i])
rionet_queue_tx_msg(skb, ndev,
rionet_active[i]);
@@ -385,6 +386,8 @@ static void rionet_remove(struct rio_dev *rdev)
struct net_device *ndev = NULL;
struct rionet_peer *peer, *tmp;
+ free_pages((unsigned long)rionet_active, rdev->net->hport->sys_size ?
+ __ilog2(sizeof(void *)) + 4 : 0);
unregister_netdev(ndev);
kfree(ndev);
@@ -443,6 +446,15 @@ static int rionet_setup_netdev(struct rio_mport *mport)
goto out;
}
+ if (!(rionet_active = (struct rio_dev **)__get_free_pages(GFP_KERNEL,
+ mport->sys_size ? __ilog2(sizeof(void *)) + 4
+ : 0))) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ memset((void *)rionet_active, 0, sizeof(void *) *
+ RIO_MAX_ROUTE_ENTRIES(mport->sys_size));
+
/* Set up private area */
rnet = (struct rionet_private *)ndev->priv;
rnet->mport = mport;
diff --git a/drivers/rapidio/Kconfig b/drivers/rapidio/Kconfig
index 4142115..c32822a 100644
--- a/drivers/rapidio/Kconfig
+++ b/drivers/rapidio/Kconfig
@@ -1,14 +1,6 @@
#
# RapidIO configuration
#
-config RAPIDIO_8_BIT_TRANSPORT
- bool "8-bit transport addressing"
- depends on RAPIDIO
- ---help---
- By default, the kernel assumes a 16-bit addressed RapidIO
- network. By selecting this option, the kernel will support
- an 8-bit addressed network.
-
config RAPIDIO_DISC_TIMEOUT
int "Discovery timeout duration (seconds)"
depends on RAPIDIO
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 4442072..ca895d1 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -73,7 +73,7 @@ static u16 rio_get_device_id(struct rio_mport *port, u16 destid, u8 hopcount)
rio_mport_read_config_32(port, destid, hopcount, RIO_DID_CSR, &result);
- return RIO_GET_DID(result);
+ return RIO_GET_DID(port->sys_size, result);
}
/**
@@ -88,7 +88,7 @@ static u16 rio_get_device_id(struct rio_mport *port, u16 destid, u8 hopcount)
static void rio_set_device_id(struct rio_mport *port, u16 destid, u8 hopcount, u16 did)
{
rio_mport_write_config_32(port, destid, hopcount, RIO_DID_CSR,
- RIO_SET_DID(did));
+ RIO_SET_DID(port->sys_size, did));
}
/**
@@ -100,7 +100,8 @@ static void rio_set_device_id(struct rio_mport *port, u16 destid, u8 hopcount, u
*/
static void rio_local_set_device_id(struct rio_mport *port, u16 did)
{
- rio_local_write_config_32(port, RIO_DID_CSR, RIO_SET_DID(did));
+ rio_local_write_config_32(port, RIO_DID_CSR, RIO_SET_DID(port->sys_size,
+ did));
}
/**
@@ -350,8 +351,17 @@ static struct rio_dev *rio_setup_device(struct rio_net *net,
rswitch->switchid = next_switchid;
rswitch->hopcount = hopcount;
rswitch->destid = destid;
+ if (!(rswitch->route_table = kzalloc(sizeof(u8)*
+ RIO_MAX_ROUTE_ENTRIES(port->sys_size),
+ GFP_KERNEL))) {
+ kfree(rdev);
+ rdev = NULL;
+ kfree(rswitch);
+ goto out;
+ }
/* Initialize switch route table */
- for (rdid = 0; rdid < RIO_MAX_ROUTE_ENTRIES; rdid++)
+ for (rdid = 0; rdid < RIO_MAX_ROUTE_ENTRIES(port->sys_size);
+ rdid++)
rswitch->route_table[rdid] = RIO_INVALID_ROUTE;
rdev->rswitch = rswitch;
sprintf(rio_name(rdev), "%02x:s:%04x", rdev->net->id,
@@ -480,7 +490,7 @@ static u16 rio_get_host_deviceid_lock(struct rio_mport *port, u8 hopcount)
{
u32 result;
- rio_mport_read_config_32(port, RIO_ANY_DESTID, hopcount,
+ rio_mport_read_config_32(port, RIO_ANY_DESTID(port->sys_size), hopcount,
RIO_HOST_DID_LOCK_CSR, &result);
return (u16) (result & 0xffff);
@@ -571,14 +581,16 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
}
/* Attempt to acquire device lock */
- rio_mport_write_config_32(port, RIO_ANY_DESTID, hopcount,
+ rio_mport_write_config_32(port, RIO_ANY_DESTID(port->sys_size),
+ hopcount,
RIO_HOST_DID_LOCK_CSR, port->host_deviceid);
while ((tmp = rio_get_host_deviceid_lock(port, hopcount))
< port->host_deviceid) {
/* Delay a bit */
mdelay(1);
/* Attempt to acquire device lock again */
- rio_mport_write_config_32(port, RIO_ANY_DESTID, hopcount,
+ rio_mport_write_config_32(port, RIO_ANY_DESTID(port->sys_size),
+ hopcount,
RIO_HOST_DID_LOCK_CSR,
port->host_deviceid);
}
@@ -590,7 +602,8 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
}
/* Setup new RIO device */
- if ((rdev = rio_setup_device(net, port, RIO_ANY_DESTID, hopcount, 1))) {
+ if ((rdev = rio_setup_device(net, port, RIO_ANY_DESTID(port->sys_size),
+ hopcount, 1))) {
/* Add device to the global and bus/net specific list. */
list_add_tail(&rdev->net_list, &net->devices);
} else
@@ -598,7 +611,8 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
if (rio_is_switch(rdev)) {
next_switchid++;
- sw_inport = rio_get_swpinfo_inport(port, RIO_ANY_DESTID, hopcount);
+ sw_inport = rio_get_swpinfo_inport(port,
+ RIO_ANY_DESTID(port->sys_size), hopcount);
rio_route_add_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE,
port->host_deviceid, sw_inport);
rdev->rswitch->route_table[port->host_deviceid] = sw_inport;
@@ -612,7 +626,8 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
}
num_ports =
- rio_get_swpinfo_tports(port, RIO_ANY_DESTID, hopcount);
+ rio_get_swpinfo_tports(port, RIO_ANY_DESTID(port->sys_size),
+ hopcount);
pr_debug(
"RIO: found %s (vid %4.4x did %4.4x) with %d ports\n",
rio_name(rdev), rdev->vid, rdev->did, num_ports);
@@ -624,13 +639,15 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
cur_destid = next_destid;
if (rio_sport_is_active
- (port, RIO_ANY_DESTID, hopcount, port_num)) {
+ (port, RIO_ANY_DESTID(port->sys_size), hopcount,
+ port_num)) {
pr_debug(
"RIO: scanning device on port %d\n",
port_num);
rio_route_add_entry(port, rdev->rswitch,
RIO_GLOBAL_TABLE,
- RIO_ANY_DESTID, port_num);
+ RIO_ANY_DESTID(port->sys_size),
+ port_num);
if (rio_enum_peer(net, port, hopcount + 1) < 0)
return -1;
@@ -735,7 +752,8 @@ rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid,
pr_debug(
"RIO: scanning device on port %d\n",
port_num);
- for (ndestid = 0; ndestid < RIO_ANY_DESTID;
+ for (ndestid = 0;
+ ndestid < RIO_ANY_DESTID(port->sys_size);
ndestid++) {
rio_route_get_entry(port, rdev->rswitch,
RIO_GLOBAL_TABLE,
@@ -917,7 +935,9 @@ static void rio_build_route_tables(void)
list_for_each_entry(rdev, &rio_devices, global_list)
if (rio_is_switch(rdev))
- for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++) {
+ for (i = 0;
+ i < RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size);
+ i++) {
if (rio_route_get_entry
(rdev->net->hport, rdev->rswitch, RIO_GLOBAL_TABLE,
i, &sport) < 0)
@@ -981,7 +1001,8 @@ int rio_disc_mport(struct rio_mport *mport)
del_timer_sync(&rio_enum_timer);
pr_debug("done\n");
- if (rio_disc_peer(net, mport, RIO_ANY_DESTID, 0) < 0) {
+ if (rio_disc_peer(net, mport, RIO_ANY_DESTID(mport->sys_size),
+ 0) < 0) {
printk(KERN_INFO
"RIO: master port %d device has failed discovery\n",
mport->id);
diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c
index 659e311..97a147f 100644
--- a/drivers/rapidio/rio-sysfs.c
+++ b/drivers/rapidio/rio-sysfs.c
@@ -43,7 +43,8 @@ static ssize_t routes_show(struct device *dev, struct device_attribute *attr, ch
if (!rdev->rswitch)
goto out;
- for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++) {
+ for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size);
+ i++) {
if (rdev->rswitch->route_table[i] == RIO_INVALID_ROUTE)
continue;
str +=
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index 80c5f1b..680661a 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -43,7 +43,7 @@ u16 rio_local_get_device_id(struct rio_mport *port)
rio_local_read_config_32(port, RIO_DID_CSR, &result);
- return (RIO_GET_DID(result));
+ return (RIO_GET_DID(port->sys_size, result));
}
/**
diff --git a/drivers/rapidio/rio.h b/drivers/rapidio/rio.h
index 80e3f03..7786d02 100644
--- a/drivers/rapidio/rio.h
+++ b/drivers/rapidio/rio.h
@@ -51,10 +51,5 @@ extern struct rio_route_ops __end_rio_route_ops[];
DECLARE_RIO_ROUTE_SECTION(.rio_route_ops, \
vid, did, add_hook, get_hook)
-#ifdef CONFIG_RAPIDIO_8_BIT_TRANSPORT
-#define RIO_GET_DID(x) ((x & 0x00ff0000) >> 16)
-#define RIO_SET_DID(x) ((x & 0x000000ff) << 16)
-#else
-#define RIO_GET_DID(x) (x & 0xffff)
-#define RIO_SET_DID(x) (x & 0xffff)
-#endif
+#define RIO_GET_DID(size, x) (size ? (x & 0xffff) : ((x & 0x00ff0000) >> 16))
+#define RIO_SET_DID(size, x) (size ? (x & 0xffff) : ((x & 0x000000ff) << 16))
diff --git a/include/linux/rio.h b/include/linux/rio.h
index 9ed78dc..4b0156d 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -23,7 +23,6 @@
#include <linux/device.h>
#include <linux/rio_regs.h>
-#define RIO_ANY_DESTID 0xff
#define RIO_NO_HOPCOUNT -1
#define RIO_INVALID_DESTID 0xffff
@@ -39,11 +38,8 @@
entry is invalid (no route
exists for the device ID) */
-#ifdef CONFIG_RAPIDIO_8_BIT_TRANSPORT
-#define RIO_MAX_ROUTE_ENTRIES (1 << 8)
-#else
-#define RIO_MAX_ROUTE_ENTRIES (1 << 16)
-#endif
+#define RIO_MAX_ROUTE_ENTRIES(size) (size ? (1 << 16) : (1 << 8))
+#define RIO_ANY_DESTID(size) (size ? 0xffff : 0xff)
#define RIO_MAX_MBOX 4
#define RIO_MAX_MSG_SIZE 0x1000
@@ -178,6 +174,10 @@ struct rio_mport {
unsigned char id; /* port ID, unique among all ports */
unsigned char index; /* port index, unique among all port
interfaces of the same type */
+ unsigned int sys_size; /* RapidIO common transport system size.
+ * 0 - Small size. 256 devices.
+ * 1 - Large size, 65536 devices.
+ */
unsigned char name[40];
void *priv; /* Master port private data */
};
@@ -213,7 +213,7 @@ struct rio_switch {
u16 switchid;
u16 hopcount;
u16 destid;
- u8 route_table[RIO_MAX_ROUTE_ENTRIES];
+ u8 *route_table;
int (*add_entry) (struct rio_mport * mport, u16 destid, u8 hopcount,
u16 table, u16 route_destid, u8 route_port);
int (*get_entry) (struct rio_mport * mport, u16 destid, u8 hopcount,
--
1.5.4
^ 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