* [PATCH 3/4] ppc32: Reorganize and complete MPC52xx initial cpu setup
From: Sylvain Munaut @ 2006-03-26 11:38 UTC (permalink / raw)
To: Linux PPC embedded; +Cc: Paul Mackerras
In-Reply-To: <0.20060326_133535_93e6_tnt@patchsend.246tNt.com>
ppc32: Reorganize and complete MPC52xx initial cpu setup
This patch splits up the CPU setup into a generic part and a
platform specific part. We also add a few missing init at the
same time.
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
---
commit 67015426ff51ba857b7678a993f4ffd6def1941e
tree cca92c1916ede8f67fe8d16987a54303c76f31f8
parent 37ffaaccad4fb48c8416e610aab4d3bed41dfc80
author Sylvain Munaut <tnt@246tNt.com> 1143311892 +0100
committer Sylvain Munaut <tnt@246tNt.com> 1143311892 +0100
arch/ppc/platforms/lite5200.c | 38 ++++++++-----------------------
arch/ppc/syslib/mpc52xx_setup.c | 48 ++++++++++++++++++++++++++++++++++++++++
include/asm-ppc/mpc52xx.h | 4 +++
3 files changed, 62 insertions(+), 28 deletions(-)
---
67015426ff51ba857b7678a993f4ffd6def1941e
diff --git a/arch/ppc/platforms/lite5200.c b/arch/ppc/platforms/lite5200.c
index d91efe1..fecbe9a 100644
--- a/arch/ppc/platforms/lite5200.c
+++ b/arch/ppc/platforms/lite5200.c
@@ -36,8 +36,6 @@
#include <asm/machdep.h>
#include <asm/pci-bridge.h>
-#include <syslib/mpc52xx_pci.h>
-
extern int powersave_nap;
@@ -99,34 +97,23 @@ lite5200_map_irq(struct pci_dev *dev, un
static void __init
lite5200_setup_cpu(void)
{
- struct mpc52xx_cdm __iomem *cdm;
struct mpc52xx_gpio __iomem *gpio;
struct mpc52xx_intr __iomem *intr;
- struct mpc52xx_xlb __iomem *xlb;
u32 port_config;
u32 intr_ctrl;
/* Map zones */
- cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
gpio = ioremap(MPC52xx_PA(MPC52xx_GPIO_OFFSET), MPC52xx_GPIO_SIZE);
- xlb = ioremap(MPC52xx_PA(MPC52xx_XLB_OFFSET), MPC52xx_XLB_SIZE);
intr = ioremap(MPC52xx_PA(MPC52xx_INTR_OFFSET), MPC52xx_INTR_SIZE);
- if (!cdm || !gpio || !xlb || !intr) {
- printk("lite5200.c: Error while mapping CDM/GPIO/XLB/INTR during"
- "lite5200_setup_cpu\n");
+ if (!gpio || !intr) {
+ printk(KERN_ERR __FILE__ ": "
+ "Error while mapping GPIO/INTR during "
+ "lite5200_setup_cpu\n");
goto unmap_regs;
}
- /* Use internal 48 Mhz */
- out_8(&cdm->ext_48mhz_en, 0x00);
- out_8(&cdm->fd_enable, 0x01);
- if (in_be32(&cdm->rstcfg) & 0x40) /* Assumes 33Mhz clock */
- out_be16(&cdm->fd_counters, 0x0001);
- else
- out_be16(&cdm->fd_counters, 0x5555);
-
/* Get port mux config */
port_config = in_be32(&gpio->port_config);
@@ -137,17 +124,13 @@ lite5200_setup_cpu(void)
port_config &= ~0x00007000; /* Differential mode - USB1 only */
port_config |= 0x00001000;
+ /* ATA CS is on csb_4/5 */
+ port_config &= ~0x03000000;
+ port_config |= 0x01000000;
+
/* Commit port config */
out_be32(&gpio->port_config, port_config);
- /* Configure the XLB Arbiter */
- out_be32(&xlb->master_pri_enable, 0xff);
- out_be32(&xlb->master_priority, 0x11111111);
-
- /* Enable ram snooping for 1GB window */
- out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_SNOOP);
- out_be32(&xlb->snoop_window, MPC52xx_PCI_TARGET_MEM | 0x1d);
-
/* IRQ[0-3] setup */
intr_ctrl = in_be32(&intr->ctrl);
intr_ctrl &= ~0x00ff0000;
@@ -163,9 +146,7 @@ lite5200_setup_cpu(void)
/* Unmap reg zone */
unmap_regs:
- if (cdm) iounmap(cdm);
if (gpio) iounmap(gpio);
- if (xlb) iounmap(xlb);
if (intr) iounmap(intr);
}
@@ -173,7 +154,8 @@ static void __init
lite5200_setup_arch(void)
{
/* CPU & Port mux setup */
- lite5200_setup_cpu();
+ mpc52xx_setup_cpu(); /* Generic */
+ lite5200_setup_cpu(); /* Platform specific */
#ifdef CONFIG_PCI
/* PCI Bridge setup */
diff --git a/arch/ppc/syslib/mpc52xx_setup.c b/arch/ppc/syslib/mpc52xx_setup.c
index 2ee48ce..ee6379b 100644
--- a/arch/ppc/syslib/mpc52xx_setup.c
+++ b/arch/ppc/syslib/mpc52xx_setup.c
@@ -24,6 +24,8 @@
#include <asm/pgtable.h>
#include <asm/ppcboot.h>
+#include <syslib/mpc52xx_pci.h>
+
extern bd_t __res;
static int core_mult[] = { /* CPU Frequency multiplier, taken */
@@ -216,6 +218,52 @@ mpc52xx_calibrate_decr(void)
tb_to_us = mulhwu_scale_factor(xlbfreq / divisor, 1000000);
}
+
+void __init
+mpc52xx_setup_cpu(void)
+{
+ struct mpc52xx_cdm __iomem *cdm;
+ struct mpc52xx_xlb __iomem *xlb;
+
+ /* Map zones */
+ cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
+ xlb = ioremap(MPC52xx_PA(MPC52xx_XLB_OFFSET), MPC52xx_XLB_SIZE);
+
+ if (!cdm || !xlb) {
+ printk(KERN_ERR __FILE__ ": "
+ "Error while mapping CDM/XLB during "
+ "mpc52xx_setup_cpu\n");
+ goto unmap_regs;
+ }
+
+ /* Use internal 48 Mhz */
+ out_8(&cdm->ext_48mhz_en, 0x00);
+ out_8(&cdm->fd_enable, 0x01);
+ if (in_be32(&cdm->rstcfg) & 0x40) /* Assumes 33Mhz clock */
+ out_be16(&cdm->fd_counters, 0x0001);
+ else
+ out_be16(&cdm->fd_counters, 0x5555);
+
+ /* Configure the XLB Arbiter priorities */
+ out_be32(&xlb->master_pri_enable, 0xff);
+ out_be32(&xlb->master_priority, 0x11111111);
+
+ /* Enable ram snooping for 1GB window */
+ out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_SNOOP);
+ out_be32(&xlb->snoop_window, MPC52xx_PCI_TARGET_MEM | 0x1d);
+
+ /* Disable XLB pipelining */
+ /* (cfr errate 292. We could do this only just before ATA PIO
+ transaction and re-enable it after ...) */
+ out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_PLDIS);
+
+ /* Unmap reg zone */
+unmap_regs:
+ if (cdm) iounmap(cdm);
+ if (xlb) iounmap(xlb);
+}
+
+
int mpc52xx_match_psc_function(int psc_idx, const char *func)
{
struct mpc52xx_psc_func *cf = mpc52xx_psc_functions;
diff --git a/include/asm-ppc/mpc52xx.h b/include/asm-ppc/mpc52xx.h
index 6167f74..7e98428 100644
--- a/include/asm-ppc/mpc52xx.h
+++ b/include/asm-ppc/mpc52xx.h
@@ -355,6 +355,7 @@ struct mpc52xx_xlb {
u32 snoop_window; /* XLB + 0x70 */
};
+#define MPC52xx_XLB_CFG_PLDIS (1 << 31)
#define MPC52xx_XLB_CFG_SNOOP (1 << 15)
/* Clock Distribution control */
@@ -427,6 +428,9 @@ extern void mpc52xx_calibrate_decr(void)
extern void mpc52xx_find_bridges(void);
+extern void mpc52xx_setup_cpu(void);
+
+
/* Matching of PSC function */
struct mpc52xx_psc_func {
^ permalink raw reply related
* [PATCH 2/4] ppc32: Adds support for the LITE5200B dev board
From: Sylvain Munaut @ 2006-03-26 11:37 UTC (permalink / raw)
To: Linux PPC embedded; +Cc: Paul Mackerras
In-Reply-To: <0.20060326_133535_93e6_tnt@patchsend.246tNt.com>
ppc32: Adds support for the LITE5200B dev board
This LITE5200B devboard is the new development board for the
Freescale MPC5200 processor. It has two PCI slots and so a
different PCI IRQ routing.
Signed-off-by: John Rigby <jrigby@freescale.com>
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
---
commit 37ffaaccad4fb48c8416e610aab4d3bed41dfc80
tree 3f7b1b661e3ea7c6830c020e42948c575e73d52f
parent d2c9f75189b6bd63b94cc78f8522a44c4476939a
author Sylvain Munaut <tnt@246tNt.com> 1138562427 +0100
committer Sylvain Munaut <tnt@246tNt.com> 1143311804 +0100
Kconfig | 7 +++++++
platforms/lite5200.c | 33 ++++++++++++++++++++++++++++++---
2 files changed, 37 insertions(+), 3 deletions(-)
---
37ffaaccad4fb48c8416e610aab4d3bed41dfc80
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index 54a0a9b..1c12da2 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -711,6 +711,13 @@ config LITE5200
much but it's only been tested on this board version. I think this
board is also known as IceCube.
+config LITE5200B
+ bool "Freescale LITE5200B"
+ depends LITE5200
+ help
+ Support for the LITE5200B dev board for the MPC5200 from Freescale.
+ This is the new board with 2 PCI slots.
+
config MPC834x_SYS
bool "Freescale MPC834x SYS"
help
diff --git a/arch/ppc/platforms/lite5200.c b/arch/ppc/platforms/lite5200.c
index 5171b53..d91efe1 100644
--- a/arch/ppc/platforms/lite5200.c
+++ b/arch/ppc/platforms/lite5200.c
@@ -34,6 +34,7 @@
#include <asm/mpc52xx.h>
#include <asm/ppc_sys.h>
#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
#include <syslib/mpc52xx_pci.h>
@@ -68,12 +69,32 @@ lite5200_show_cpuinfo(struct seq_file *m
}
#ifdef CONFIG_PCI
+#ifdef CONFIG_LITE5200B
+static int
+lite5200_map_irq(struct pci_dev *dev, unsigned char idsel,
+ unsigned char pin)
+{
+ static char pci_irq_table[][4] =
+ /*
+ * PCI IDSEL/INTPIN->INTLINE
+ * A B C D
+ */
+ {
+ {MPC52xx_IRQ0, MPC52xx_IRQ1, MPC52xx_IRQ2, MPC52xx_IRQ3},
+ {MPC52xx_IRQ1, MPC52xx_IRQ2, MPC52xx_IRQ3, MPC52xx_IRQ0},
+ };
+
+ const long min_idsel = 24, max_idsel = 25, irqs_per_slot = 4;
+ return PCI_IRQ_TABLE_LOOKUP;
+}
+#else /* Original Lite */
static int
lite5200_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
{
return (pin == 1) && (idsel==24) ? MPC52xx_IRQ0 : -1;
}
#endif
+#endif
static void __init
lite5200_setup_cpu(void)
@@ -127,11 +148,17 @@ lite5200_setup_cpu(void)
out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_SNOOP);
out_be32(&xlb->snoop_window, MPC52xx_PCI_TARGET_MEM | 0x1d);
- /* IRQ[0-3] setup : IRQ0 - Level Active Low */
- /* IRQ[1-3] - Level Active High */
+ /* IRQ[0-3] setup */
intr_ctrl = in_be32(&intr->ctrl);
intr_ctrl &= ~0x00ff0000;
- intr_ctrl |= 0x00c00000;
+#ifdef CONFIG_LITE5200B
+ /* IRQ[0-3] Level Active Low */
+ intr_ctrl |= 0x00ff0000;
+#else
+ /* IRQ0 Level Active Low
+ * IRQ[1-3] Level Active High */
+ intr_ctrl |= 0x00c00000;
+#endif
out_be32(&intr->ctrl, intr_ctrl);
/* Unmap reg zone */
^ permalink raw reply related
* [PATCH 1/4] ppc32: Adds support for the PCI hostbridge in MPC5200B
From: Sylvain Munaut @ 2006-03-26 11:37 UTC (permalink / raw)
To: Linux PPC embedded; +Cc: Paul Mackerras
In-Reply-To: <0.20060326_133535_93e6_tnt@patchsend.246tNt.com>
ppc32: Adds support for the PCI hostbridge in MPC5200B
Signed-off-by: John Rigby <jrigby@freescale.com>
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
---
commit d2c9f75189b6bd63b94cc78f8522a44c4476939a
tree 384ab1d358439be5cddbab68cfa542390ac784f4
parent 3cbb90a9cb7854b1110663919d5bc3da3f46d5e3
author Sylvain Munaut <tnt@246tNt.com> 1138559991 +0100
committer Sylvain Munaut <tnt@246tNt.com> 1143311787 +0100
arch/ppc/syslib/mpc52xx_pci.c | 3 ++-
include/linux/pci_ids.h | 1 +
2 files changed, 3 insertions(+), 1 deletion(-)
---
d2c9f75189b6bd63b94cc78f8522a44c4476939a
diff --git a/arch/ppc/syslib/mpc52xx_pci.c b/arch/ppc/syslib/mpc52xx_pci.c
index 9ec525f..5a5a7a9 100644
--- a/arch/ppc/syslib/mpc52xx_pci.c
+++ b/arch/ppc/syslib/mpc52xx_pci.c
@@ -225,7 +225,8 @@ mpc52xx_pci_fixup_resources(struct pci_d
/* The PCI Host bridge of MPC52xx has a prefetch memory resource
fixed to 1Gb. Doesn't fit in the resource system so we remove it */
if ( (dev->vendor == PCI_VENDOR_ID_MOTOROLA) &&
- (dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200) ) {
+ ( dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200
+ || dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200B) ) {
struct resource *res = &dev->resource[1];
res->start = res->end = res->flags = 0;
}
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 6f080ae..72d1b67 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -772,6 +772,7 @@
#define PCI_DEVICE_ID_MOTOROLA_HAWK 0x4803
#define PCI_DEVICE_ID_MOTOROLA_HARRIER 0x480b
#define PCI_DEVICE_ID_MOTOROLA_MPC5200 0x5803
+#define PCI_DEVICE_ID_MOTOROLA_MPC5200B 0x5809
#define PCI_VENDOR_ID_PROMISE 0x105a
#define PCI_DEVICE_ID_PROMISE_20265 0x0d30
^ permalink raw reply related
* [PATCH 0/4] MPC52xx updates : lite5200b + ide support
From: Sylvain Munaut @ 2006-03-26 11:36 UTC (permalink / raw)
To: Linux PPC embedded; +Cc: Paul Mackerras
Hi Paul,
Hi everyone,
This set of updates mainly adds support for the new lite5200B
devboard from Freescale and support for IDE.
Theses have been posted on the ppc-embedded mailing list some
time ago, they've been tested and reported working by a few people,
so Paul it'd be nice to get those merged upstream. If you were
not the one to cc about this, let me know, I'll forward those
to Andrew.
Thanks !
Regards,
Sylvain
^ permalink raw reply
* Re: [PATCH] powerpc: legacy_serial loop cleanup
From: Michael Neuling @ 2006-03-26 0:07 UTC (permalink / raw)
To: Stephen Rothwell; +Cc: michael, linuxppc-dev
In-Reply-To: <20060325180535.0a680b4d.sfr@canb.auug.org.au>
> > +static void __init setup_legacy_serial_console(int console)
> > +{
> > + struct legacy_serial_info *info =3D
> > + &legacy_serial_infos[legacy_serial_console];
>
> Except that you don't want to do that ^ (assuming you meant "console")
>
> > + void __iomem *addr;
> > +
> > + if (console < 0)
> > + return;
>
> before this ^ ... :-)
Indeed, thanks. Updated patch below. This time for sure! :-)
Mikey
We only ever execute the loop once, so let's move it to a function
making it more readable. Cleanup patch, no functional change.
Signed-off-by: Michael Neuling <mikey@neuling.org>
---
arch/powerpc/kernel/legacy_serial.c | 38 ++++++++++++++++++------------------
1 files changed, 19 insertions(+), 19 deletions(-)
Index: linux-2.6-powerpc-merge/arch/powerpc/kernel/legacy_serial.c
===================================================================
--- linux-2.6-powerpc-merge.orig/arch/powerpc/kernel/legacy_serial.c
+++ linux-2.6-powerpc-merge/arch/powerpc/kernel/legacy_serial.c
@@ -236,6 +236,23 @@ static int __init add_legacy_pci_port(st
}
#endif
+static void __init setup_legacy_serial_console(int console)
+{
+ struct legacy_serial_info *info =
+ &legacy_serial_infos[console];
+ void __iomem *addr;
+
+ if (info->taddr == 0)
+ return;
+ addr = ioremap(info->taddr, 0x1000);
+ if (addr == NULL)
+ return;
+ if (info->speed == 0)
+ info->speed = udbg_probe_uart_speed(addr, info->clock);
+ DBG("default console speed = %d\n", info->speed);
+ udbg_init_uart(addr, info->speed, info->clock);
+}
+
/*
* This is called very early, as part of setup_system() or eventually
* setup_arch(), basically before anything else in this file. This function
@@ -318,25 +335,8 @@ void __init find_legacy_serial_ports(voi
#endif
DBG("legacy_serial_console = %d\n", legacy_serial_console);
-
- /* udbg is 64 bits only for now, that will change soon though ... */
- while (legacy_serial_console >= 0) {
- struct legacy_serial_info *info =
- &legacy_serial_infos[legacy_serial_console];
- void __iomem *addr;
-
- if (info->taddr == 0)
- break;
- addr = ioremap(info->taddr, 0x1000);
- if (addr == NULL)
- break;
- if (info->speed == 0)
- info->speed = udbg_probe_uart_speed(addr, info->clock);
- DBG("default console speed = %d\n", info->speed);
- udbg_init_uart(addr, info->speed, info->clock);
- break;
- }
-
+ if (legacy_serial_console >= 0)
+ setup_legacy_serial_console(legacy_serial_console);
DBG(" <- find_legacy_serial_port()\n");
}
^ permalink raw reply
* Re: [PATCH] powerpc: Add FSL SEC node to documentation
From: Doug Maxey @ 2006-03-25 22:27 UTC (permalink / raw)
To: Paul Nasrat; +Cc: linuxppc-dev
In-Reply-To: <1142976221.2751.22.camel@enki.eridu>
On Tue, 21 Mar 2006 16:23:41 EST, Paul Nasrat wrote:
>On Tue, 2006-03-21 at 13:28 -0600, Hollis Blanchard wrote:
>> On Tue, 2006-03-21 at 12:25 -0600, Kumar Gala wrote:
>> > On Mar 20, 2006, at 8:14 PM, Hollis Blanchard wrote:
>
>> > > Have you consulted with any other vendors regarding these
>> > > properties? I know
>> > > there is no IEEE1275 binding for these sorts of devices, but we can
>> > > at least
>> > > attempt to standardize it (even in the absence of the Open Firmware
>> > > Working
>> > > Group)...
>> >
>> > Beyond the device_type, I'm not sure if there is much more one could
>> > standardize one. The other fields that Kim spec'd are either generic
>> > OF fields (reg, interrupts, etc.) or specific to the Freescale devices.
>>
>> The device_type and compatible properties are exactly what I'm talking
>> about.
>
>The Working Group lists still exist but are pretty dead. I agree we
>really want to ensure that both OF based and dtc based new hardware is
>consistent. I'm not sure how we want to do this, but we can document in
>Documentation and then use eg SLOF to mock out the OF interfaces and
>create proposals and kick some life into the OF working group.
Sorry for the delayed reply, my procmail filter was pumping mails to
the old list name without telling me. :)
Other than IBM, Motorola, and possibly Sun, what groups are using
OFW on new platforms anymore?
Power.org may be a vehicle to publish.
The Power TSC leader indicated a willingness to look into a process to
get out some purely internal bindings (at the moment) that _really_
need some fresh air to flourish.
++doug
^ permalink raw reply
* snd-aoa & rates
From: Benjamin Herrenschmidt @ 2006-03-25 22:06 UTC (permalink / raw)
To: Johannes Berg; +Cc: linuxppc-dev list
Hi Johannes
Current snd-aoa blew up on me at module load btw ... anyway, that's not
my point here :)
I wonder if you may be doing something a bit too complicated and maybe
not perfectly wanted for your bitrates thingy... you basically end up
with min/max limits and bit size limits, sort-of
assuming that on analog, any rates you have in your list that fits those
limits will be available on a given codec. That may not be the case for
all codecs no ? Then you end up with a similar list for digital but
since you need discrete bitrates, you end up with a list with min==max.
Why not do something much simpler which is to define the known bitrates
as a bitmask and have the codec expose a bitmask of supported analog and
digital rates ?
In fact, I would have been even nastier and only exposed the
intersection of the above so I don't have to bother about rates that
digital won't support :) But I suppose that if you really want to
support 8k or 96k it might make sense to support others.
Also, for the sample sizes, same comment. Number of bits are not that
useful. I'd rather have a bitmask of formats: 8 bits, 16 bits msb, 24
bits msb, maybe lsb versions if supported, ac3, floating point if
supported, etc... That or an array. I'm sure Alsa already have constants
defined for those no ? I would then have the codec have a function
returning the required clocks for a given bitrate/format combination...
That is all suggestions of course, if you feel that what you do is
better, then stick to it :)
Another thing I wouldn't have bothered with is again with whatever
digital supports or doesn't ... rather that trying to prevent some rates
from being useable by alsa based on a control that users will typically
not have means to set at the right time (what about a sound server
running all the time keeping the drier running, you want to block the
digital switch ?) what I would do is just "mute" the digital output if a
format is selected that isn't supported for digital. I would let the
user chose the formats they want at all time, and only clamp the digital
enable/disable switch. On this switch, btw, you should then remember the
user setting: if the user switches it off, remember off. If the user
switches it on, remember on, If the user sets it on but you have to mute
it, remember that so that when the sample size/format changes again,
unmute.
Sames goes for things that may be supported by the digital output and
not analog (ac3 ?). In this case, mute the analog outputs. The mutes of
these are controlled externally via the amps so it may be a bit
complicated, unless you define specific messages to the core for that,
or maybe just clamp the master volume down in the codec driver.
Ben.
^ permalink raw reply
* Re: [PATCH] powerpc: legacy_serial loop cleanup
From: Benjamin Herrenschmidt @ 2006-03-25 12:44 UTC (permalink / raw)
To: mikey; +Cc: michael, linuxppc-dev
In-Reply-To: <20060324041727.F131267B56@ozlabs.org>
> +static void __init setup_legacy_serial_console(int console)
> +{
> + if (console >= 0) {
> + struct legacy_serial_info *info =
> + &legacy_serial_infos[legacy_serial_console];
> + void __iomem *addr;
> +
> + if (info->taddr == 0)
> + return;
> + addr = ioremap(info->taddr, 0x1000);
> + if (addr == NULL)
> + return;
> + if (info->speed == 0)
> + info->speed = udbg_probe_uart_speed(addr, info->clock);
> + DBG("default console speed = %d\n", info->speed);
> + udbg_init_uart(addr, info->speed, info->clock);
> + }
> + return;
Hrm... What is the point of having a function ending with return; ?
What about, instead, something like:
if (consoles < 0)
return;
do shit ...
Ben.
^ permalink raw reply
* Re: [PATCH] powerpc: legacy_serial loop cleanup
From: Stephen Rothwell @ 2006-03-25 7:05 UTC (permalink / raw)
To: Michael Neuling; +Cc: michael, linuxppc-dev
In-Reply-To: <20060325044501.D32A267A58@ozlabs.org>
[-- Attachment #1: Type: text/plain, Size: 564 bytes --]
On Sat, 25 Mar 2006 15:45:11 +1100 Michael Neuling <mikey@neuling.org> wrote:
>
> Agreed. Updated patch below.
> .
> .
> +static void __init setup_legacy_serial_console(int console)
> +{
> + struct legacy_serial_info *info =
> + &legacy_serial_infos[legacy_serial_console];
Except that you don't want to do that ^ (assuming you meant "console")
> + void __iomem *addr;
> +
> + if (console < 0)
> + return;
before this ^ ... :-)
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 191 bytes --]
^ permalink raw reply
* [PATCH] powerpc: Compile warning in hvcs driver
From: Anton Blanchard @ 2006-03-25 6:31 UTC (permalink / raw)
To: linuxppc-dev; +Cc: paulus
We ended up with an unused variable after the tty updates went in. Fix it.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
Index: build/drivers/char/hvcs.c
===================================================================
--- build.orig/drivers/char/hvcs.c 2006-03-25 16:26:57.000000000 +1100
+++ build/drivers/char/hvcs.c 2006-03-25 16:27:10.000000000 +1100
@@ -439,7 +439,6 @@ static int hvcs_io(struct hvcs_struct *h
char buf[HVCS_BUFF_LEN] __ALIGNED__;
unsigned long flags;
int got = 0;
- int i;
spin_lock_irqsave(&hvcsd->lock, flags);
^ permalink raw reply
* [PATCH] HVC init race
From: Anton Blanchard @ 2006-03-25 6:30 UTC (permalink / raw)
To: linuxppc-dev; +Cc: mikey, paulus
From: Michael Neuling <mikey@neuling.org>
I've been hitting a crash on boot where tty_open is being called before the
hvc console driver setup is complete. Below patch fixes this problem.
Thanks to benh for his help on this.
Signed-off-by: Michael Neuling <mikey@neuling.org>
Acked-by: Anton Blanchard <anton@samba.org>
---
Index: build/drivers/char/hvc_console.c
===================================================================
--- build.orig/drivers/char/hvc_console.c 2006-03-25 16:49:20.000000000 +1100
+++ build/drivers/char/hvc_console.c 2006-03-25 16:49:44.000000000 +1100
@@ -823,34 +823,38 @@ EXPORT_SYMBOL(hvc_remove);
* interfaces start to become available. */
int __init hvc_init(void)
{
+ struct tty_driver *drv;
+
/* We need more than hvc_count adapters due to hotplug additions. */
- hvc_driver = alloc_tty_driver(HVC_ALLOC_TTY_ADAPTERS);
- if (!hvc_driver)
+ drv = alloc_tty_driver(HVC_ALLOC_TTY_ADAPTERS);
+ if (!drv)
return -ENOMEM;
- hvc_driver->owner = THIS_MODULE;
- hvc_driver->devfs_name = "hvc/";
- hvc_driver->driver_name = "hvc";
- hvc_driver->name = "hvc";
- hvc_driver->major = HVC_MAJOR;
- hvc_driver->minor_start = HVC_MINOR;
- hvc_driver->type = TTY_DRIVER_TYPE_SYSTEM;
- hvc_driver->init_termios = tty_std_termios;
- hvc_driver->flags = TTY_DRIVER_REAL_RAW;
- tty_set_operations(hvc_driver, &hvc_ops);
+ drv->owner = THIS_MODULE;
+ drv->devfs_name = "hvc/";
+ drv->driver_name = "hvc";
+ drv->name = "hvc";
+ drv->major = HVC_MAJOR;
+ drv->minor_start = HVC_MINOR;
+ drv->type = TTY_DRIVER_TYPE_SYSTEM;
+ drv->init_termios = tty_std_termios;
+ drv->flags = TTY_DRIVER_REAL_RAW;
+ tty_set_operations(drv, &hvc_ops);
/* Always start the kthread because there can be hotplug vty adapters
* added later. */
hvc_task = kthread_run(khvcd, NULL, "khvcd");
if (IS_ERR(hvc_task)) {
panic("Couldn't create kthread for console.\n");
- put_tty_driver(hvc_driver);
+ put_tty_driver(drv);
return -EIO;
}
- if (tty_register_driver(hvc_driver))
+ if (tty_register_driver(drv))
panic("Couldn't register hvc console driver\n");
+ mb();
+ hvc_driver = drv;
return 0;
}
module_init(hvc_init);
^ permalink raw reply
* [PATCH] powerpc: Consistent printing of node id
From: Anton Blanchard @ 2006-03-25 6:27 UTC (permalink / raw)
To: linuxppc-dev; +Cc: paulus
We were printing node ids in hex in one spot. Lets be consistent and
always print them in decimal.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
Index: build/arch/powerpc/mm/mem.c
===================================================================
--- build.orig/arch/powerpc/mm/mem.c 2006-03-24 15:51:18.000000000 +1100
+++ build/arch/powerpc/mm/mem.c 2006-03-24 16:13:26.000000000 +1100
@@ -342,7 +342,7 @@ void __init mem_init(void)
#ifdef CONFIG_NEED_MULTIPLE_NODES
for_each_online_node(nid) {
if (NODE_DATA(nid)->node_spanned_pages != 0) {
- printk("freeing bootmem node %x\n", nid);
+ printk("freeing bootmem node %d\n", nid);
totalram_pages +=
free_all_bootmem_node(NODE_DATA(nid));
}
^ permalink raw reply
* [PATCH] powerpc: Allow non zero boot cpuids
From: Anton Blanchard @ 2006-03-25 6:25 UTC (permalink / raw)
To: linuxppc-dev; +Cc: paulus
We currently have a hack to flip the boot cpu and its secondary thread
to logical cpuid 0 and 1. This means the logical - physical mapping will
differ depending on which cpu is boot cpu. This is most apparent on
kexec, where we might kexec on any cpu and therefore change the mapping
from boot to boot.
The patch below does a first pass early on to work out the logical cpuid
of the boot thread. We then fix up some paca structures to match.
Ive also removed the boot_cpuid_phys variable for ppc64, to be
consistent we use get_hard_smp_processor_id(boot_cpuid) everywhere.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
Index: build/arch/powerpc/kernel/setup-common.c
===================================================================
--- build.orig/arch/powerpc/kernel/setup-common.c 2006-03-24 15:51:18.000000000 +1100
+++ build/arch/powerpc/kernel/setup-common.c 2006-03-24 16:13:06.000000000 +1100
@@ -352,12 +352,13 @@ void __init check_for_initrd(void)
* must be called before using this.
*
* While we're here, we may as well set the "physical" cpu ids in the paca.
+ *
+ * NOTE: This must match the parsing done in early_init_dt_scan_cpus.
*/
void __init smp_setup_cpu_maps(void)
{
struct device_node *dn = NULL;
int cpu = 0;
- int swap_cpuid = 0;
while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) {
int *intserv;
@@ -376,24 +377,11 @@ void __init smp_setup_cpu_maps(void)
for (j = 0; j < nthreads && cpu < NR_CPUS; j++) {
cpu_set(cpu, cpu_present_map);
set_hard_smp_processor_id(cpu, intserv[j]);
-
- if (intserv[j] == boot_cpuid_phys)
- swap_cpuid = cpu;
cpu_set(cpu, cpu_possible_map);
cpu++;
}
}
- /* Swap CPU id 0 with boot_cpuid_phys, so we can always assume that
- * boot cpu is logical 0.
- */
- if (boot_cpuid_phys != get_hard_smp_processor_id(0)) {
- u32 tmp;
- tmp = get_hard_smp_processor_id(0);
- set_hard_smp_processor_id(0, boot_cpuid_phys);
- set_hard_smp_processor_id(swap_cpuid, tmp);
- }
-
#ifdef CONFIG_PPC64
/*
* On pSeries LPAR, we need to know how many cpus
Index: build/arch/powerpc/kernel/setup_64.c
===================================================================
--- build.orig/arch/powerpc/kernel/setup_64.c 2006-03-24 16:12:56.000000000 +1100
+++ build/arch/powerpc/kernel/setup_64.c 2006-03-24 16:13:06.000000000 +1100
@@ -73,7 +73,6 @@
int have_of = 1;
int boot_cpuid = 0;
-int boot_cpuid_phys = 0;
dev_t boot_dev;
u64 ppc64_pft_size;
@@ -208,7 +207,6 @@ static struct machdep_calls __initdata *
void __init early_setup(unsigned long dt_ptr)
{
- struct paca_struct *lpaca = get_paca();
static struct machdep_calls **mach;
/* Enable early debugging if any specified (see udbg.h) */
@@ -223,6 +221,14 @@ void __init early_setup(unsigned long dt
*/
early_init_devtree(__va(dt_ptr));
+ /* Now we know the logical id of our boot cpu, setup the paca. */
+ setup_boot_paca();
+
+ /* Fix up paca fields required for the boot cpu */
+ get_paca()->cpu_start = 1;
+ get_paca()->stab_real = __pa((u64)&initial_stab);
+ get_paca()->stab_addr = (u64)&initial_stab;
+
/*
* Iterate all ppc_md structures until we find the proper
* one for the current machine type
@@ -260,7 +266,7 @@ void __init early_setup(unsigned long dt
if (cpu_has_feature(CPU_FTR_SLB))
slb_initialize();
else
- stab_initialize(lpaca->stab_real);
+ stab_initialize(get_paca()->stab_real);
}
DBG(" <- early_setup()\n");
Index: build/arch/powerpc/platforms/pseries/xics.c
===================================================================
--- build.orig/arch/powerpc/platforms/pseries/xics.c 2006-03-24 15:51:18.000000000 +1100
+++ build/arch/powerpc/platforms/pseries/xics.c 2006-03-24 16:13:06.000000000 +1100
@@ -500,7 +500,7 @@ nextnode:
np;
np = of_find_node_by_type(np, "cpu")) {
ireg = (uint *)get_property(np, "reg", &ilen);
- if (ireg && ireg[0] == boot_cpuid_phys) {
+ if (ireg && ireg[0] == get_hard_smp_processor_id(boot_cpuid)) {
ireg = (uint *)get_property(np, "ibm,ppc-interrupt-gserver#s",
&ilen);
i = ilen / sizeof(int);
Index: build/include/asm-powerpc/smp.h
===================================================================
--- build.orig/include/asm-powerpc/smp.h 2006-03-24 15:31:30.000000000 +1100
+++ build/include/asm-powerpc/smp.h 2006-03-24 16:13:06.000000000 +1100
@@ -29,7 +29,6 @@
#endif
extern int boot_cpuid;
-extern int boot_cpuid_phys;
extern void cpu_die(void);
@@ -99,6 +98,7 @@ extern void smp_release_cpus(void);
#else
/* 32-bit */
#ifndef CONFIG_SMP
+extern int boot_cpuid_phys;
#define get_hard_smp_processor_id(cpu) boot_cpuid_phys
#define set_hard_smp_processor_id(cpu, phys)
#endif
Index: build/arch/powerpc/kernel/head_64.S
===================================================================
--- build.orig/arch/powerpc/kernel/head_64.S 2006-03-24 15:51:18.000000000 +1100
+++ build/arch/powerpc/kernel/head_64.S 2006-03-24 16:13:06.000000000 +1100
@@ -1847,21 +1847,6 @@ _STATIC(start_here_multiplatform)
bl .__save_cpu_setup
sync
- /* Setup a valid physical PACA pointer in SPRG3 for early_setup
- * note that boot_cpuid can always be 0 nowadays since there is
- * nowhere it can be initialized differently before we reach this
- * code
- */
- LOAD_REG_IMMEDIATE(r27, boot_cpuid)
- add r27,r27,r26
- lwz r27,0(r27)
-
- LOAD_REG_IMMEDIATE(r24, paca) /* Get base vaddr of paca array */
- mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */
- add r13,r13,r24 /* for this processor. */
- add r13,r13,r26 /* convert to physical addr */
- mtspr SPRN_SPRG3,r13
-
/* Do very early kernel initializations, including initial hash table,
* stab and slb setup before we turn on relocation. */
@@ -1930,6 +1915,17 @@ _STATIC(start_here_common)
/* Not reached */
BUG_OPCODE
+/* Put the paca pointer into r13 and SPRG3 */
+_GLOBAL(setup_boot_paca)
+ LOAD_REG_IMMEDIATE(r3, boot_cpuid)
+ lwz r3,0(r3)
+ LOAD_REG_IMMEDIATE(r4, paca) /* Get base vaddr of paca array */
+ mulli r3,r3,PACA_SIZE /* Calculate vaddr of right paca */
+ add r13,r3,r4 /* for this processor. */
+ mtspr SPRN_SPRG3,r13
+
+ blr
+
/*
* We put a few things here that have to be page-aligned.
* This stuff goes at the beginning of the bss, which is page-aligned.
Index: build/arch/powerpc/kernel/prom.c
===================================================================
--- build.orig/arch/powerpc/kernel/prom.c 2006-03-24 15:51:18.000000000 +1100
+++ build/arch/powerpc/kernel/prom.c 2006-03-24 16:13:06.000000000 +1100
@@ -854,35 +854,70 @@ void __init unflatten_device_tree(void)
DBG(" <- unflatten_device_tree()\n");
}
-
static int __init early_init_dt_scan_cpus(unsigned long node,
- const char *uname, int depth, void *data)
+ const char *uname, int depth,
+ void *data)
{
- u32 *prop;
- unsigned long size;
- char *type = of_get_flat_dt_prop(node, "device_type", &size);
+ static int logical_cpuid = 0;
+ char *type = of_get_flat_dt_prop(node, "device_type", NULL);
+ u32 *prop, *intserv;
+ int i, nthreads;
+ unsigned long len;
+ int found = 0;
/* We are scanning "cpu" nodes only */
if (type == NULL || strcmp(type, "cpu") != 0)
return 0;
- boot_cpuid = 0;
- boot_cpuid_phys = 0;
- if (initial_boot_params && initial_boot_params->version >= 2) {
- /* version 2 of the kexec param format adds the phys cpuid
- * of booted proc.
- */
- boot_cpuid_phys = initial_boot_params->boot_cpuid_phys;
+ /* Get physical cpuid */
+ intserv = of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s", &len);
+ if (intserv) {
+ nthreads = len / sizeof(int);
} else {
- /* Check if it's the boot-cpu, set it's hw index now */
- if (of_get_flat_dt_prop(node,
+ intserv = of_get_flat_dt_prop(node, "reg", NULL);
+ nthreads = 1;
+ }
+
+ /*
+ * Now see if any of these threads match our boot cpu.
+ * NOTE: This must match the parsing done in smp_setup_cpu_maps.
+ */
+ for (i = 0; i < nthreads; i++) {
+ /*
+ * version 2 of the kexec param format adds the phys cpuid of
+ * booted proc.
+ */
+ if (initial_boot_params && initial_boot_params->version >= 2) {
+ if (intserv[i] ==
+ initial_boot_params->boot_cpuid_phys) {
+ found = 1;
+ break;
+ }
+ } else {
+ /*
+ * Check if it's the boot-cpu, set it's hw index now,
+ * unfortunately this format did not support booting
+ * off secondary threads.
+ */
+ if (of_get_flat_dt_prop(node,
"linux,boot-cpu", NULL) != NULL) {
- prop = of_get_flat_dt_prop(node, "reg", NULL);
- if (prop != NULL)
- boot_cpuid_phys = *prop;
+ found = 1;
+ break;
+ }
}
+
+#ifdef CONFIG_SMP
+ /* logical cpu id is always 0 on UP kernels */
+ logical_cpuid++;
+#endif
+ }
+
+ if (found) {
+ DBG("boot cpu: logical %d physical %d\n", logical_cpuid,
+ intserv[i]);
+ boot_cpuid = logical_cpuid;
+ set_hard_smp_processor_id(boot_cpuid, intserv[i]);
}
- set_hard_smp_processor_id(0, boot_cpuid_phys);
#ifdef CONFIG_ALTIVEC
/* Check if we have a VMX and eventually update CPU features */
@@ -901,16 +936,10 @@ static int __init early_init_dt_scan_cpu
#endif /* CONFIG_ALTIVEC */
#ifdef CONFIG_PPC_PSERIES
- /*
- * Check for an SMT capable CPU and set the CPU feature. We do
- * this by looking at the size of the ibm,ppc-interrupt-server#s
- * property
- */
- prop = (u32 *)of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s",
- &size);
- cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT;
- if (prop && ((size / sizeof(u32)) > 1))
+ if (nthreads > 1)
cur_cpu_spec->cpu_features |= CPU_FTR_SMT;
+ else
+ cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT;
#endif
return 0;
Index: build/arch/powerpc/kernel/paca.c
===================================================================
--- build.orig/arch/powerpc/kernel/paca.c 2006-03-24 15:31:30.000000000 +1100
+++ build/arch/powerpc/kernel/paca.c 2006-03-24 16:13:06.000000000 +1100
@@ -56,14 +56,11 @@ struct lppaca lppaca[] = {
* processors. The processor VPD array needs one entry per physical
* processor (not thread).
*/
-#define PACA_INIT_COMMON(number, start, asrr, asrv) \
+#define PACA_INIT_COMMON(number) \
.lppaca_ptr = &lppaca[number], \
.lock_token = 0x8000, \
.paca_index = (number), /* Paca Index */ \
.kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \
- .stab_real = (asrr), /* Real pointer to segment table */ \
- .stab_addr = (asrv), /* Virt pointer to segment table */ \
- .cpu_start = (start), /* Processor start */ \
.hw_cpu_id = 0xffff,
#ifdef CONFIG_PPC_ISERIES
@@ -72,30 +69,20 @@ struct lppaca lppaca[] = {
#define PACA_INIT(number) \
{ \
- PACA_INIT_COMMON(number, 0, 0, 0) \
- PACA_INIT_ISERIES(number) \
-}
-
-#define BOOTCPU_PACA_INIT(number) \
-{ \
- PACA_INIT_COMMON(number, 1, 0, (u64)&initial_stab) \
+ PACA_INIT_COMMON(number) \
PACA_INIT_ISERIES(number) \
}
#else
#define PACA_INIT(number) \
{ \
- PACA_INIT_COMMON(number, 0, 0, 0) \
+ PACA_INIT_COMMON(number) \
}
-#define BOOTCPU_PACA_INIT(number) \
-{ \
- PACA_INIT_COMMON(number, 1, STAB0_PHYS_ADDR, (u64)&initial_stab) \
-}
#endif
struct paca_struct paca[] = {
- BOOTCPU_PACA_INIT(0),
+ PACA_INIT(0),
#if NR_CPUS > 1
PACA_INIT( 1), PACA_INIT( 2), PACA_INIT( 3),
#if NR_CPUS > 4
Index: build/include/asm-powerpc/paca.h
===================================================================
--- build.orig/include/asm-powerpc/paca.h 2006-03-24 15:51:22.000000000 +1100
+++ build/include/asm-powerpc/paca.h 2006-03-24 16:13:06.000000000 +1100
@@ -105,5 +105,7 @@ struct paca_struct {
extern struct paca_struct paca[];
+void setup_boot_paca(void);
+
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_PACA_H */
^ permalink raw reply
* Re: [PATCH] powerpc: legacy_serial loop cleanup
From: Michael Neuling @ 2006-03-25 4:45 UTC (permalink / raw)
To: Hollis Blanchard; +Cc: michael, linuxppc-dev
In-Reply-To: <200603241226.13171.hollis@penguinppc.org>
> I don't understand: it's only used once, so make it a function? Why not just
> change the "while" to an "if"?
Because you can't use a break statements inside an if. We could you
gotos, but the idea was to increase read ability :-)
> Regardless, two style issues:
> - remove the plain "return"
> - reduce indenting like so:
> if (console < 0)
> return;
> struct legacy_serial_info *info = ...
Agreed. Updated patch below.
Mikey
We only ever execute the loop once, so let's move it to a function
making it more readable. Cleanup patch, no functional change.
Signed-off-by: Michael Neuling <mikey@neuling.org>
---
arch/powerpc/kernel/legacy_serial.c | 38 ++++++++++++++++++------------------
1 files changed, 20 insertions(+), 18 deletions(-)
Index: linux-2.6-powerpc-merge/arch/powerpc/kernel/legacy_serial.c
===================================================================
--- linux-2.6-powerpc-merge.orig/arch/powerpc/kernel/legacy_serial.c
+++ linux-2.6-powerpc-merge/arch/powerpc/kernel/legacy_serial.c
@@ -236,6 +236,25 @@ static int __init add_legacy_pci_port(st
}
#endif
+static void __init setup_legacy_serial_console(int console)
+{
+ struct legacy_serial_info *info =
+ &legacy_serial_infos[legacy_serial_console];
+ void __iomem *addr;
+
+ if (console < 0)
+ return;
+ if (info->taddr == 0)
+ return;
+ addr = ioremap(info->taddr, 0x1000);
+ if (addr == NULL)
+ return;
+ if (info->speed == 0)
+ info->speed = udbg_probe_uart_speed(addr, info->clock);
+ DBG("default console speed = %d\n", info->speed);
+ udbg_init_uart(addr, info->speed, info->clock);
+}
+
/*
* This is called very early, as part of setup_system() or eventually
* setup_arch(), basically before anything else in this file. This function
@@ -319,24 +338,7 @@ void __init find_legacy_serial_ports(voi
DBG("legacy_serial_console = %d\n", legacy_serial_console);
- /* udbg is 64 bits only for now, that will change soon though ... */
- while (legacy_serial_console >= 0) {
- struct legacy_serial_info *info =
- &legacy_serial_infos[legacy_serial_console];
- void __iomem *addr;
-
- if (info->taddr == 0)
- break;
- addr = ioremap(info->taddr, 0x1000);
- if (addr == NULL)
- break;
- if (info->speed == 0)
- info->speed = udbg_probe_uart_speed(addr, info->clock);
- DBG("default console speed = %d\n", info->speed);
- udbg_init_uart(addr, info->speed, info->clock);
- break;
- }
-
+ setup_legacy_serial_console(legacy_serial_console);
DBG(" <- find_legacy_serial_port()\n");
}
^ permalink raw reply
* Re: [PATCH] PCI Error Recovery: e1000 network device driver
From: Linas Vepstas @ 2006-03-25 3:21 UTC (permalink / raw)
To: Greg KH
Cc: linux.nics, netdev, linux-kernel, jesse.brandeburg, linuxppc-dev,
john.ronciak, jeffrey.t.kirsher, linux-pci, Jeff Garzik
In-Reply-To: <20060325022206.GA6361@kroah.com>
On Fri, Mar 24, 2006 at 06:22:06PM -0800, Greg KH wrote:
> ... a bit
> different from the traditional kernel coding style.
Sorry, this is due to inattention on my part; I get cross-eyed
after staring at the same code for too long. The patch below should
fix things.
--linas
[PATCH] PCI Error Recovery: e1000 network device driver
Various PCI bus errors can be signaled by newer PCI controllers. This
patch adds the PCI error recovery callbacks to the intel gigabit
ethernet e1000 device driver. The patch has been tested, and appears
to work well.
Signed-off-by: Linas Vepstas <linas@linas.org>
Acked-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
----
drivers/net/e1000/e1000_main.c | 114 ++++++++++++++++++++++++++++++++++++++++-
1 files changed, 113 insertions(+), 1 deletion(-)
Index: linux-2.6.16-git6/drivers/net/e1000/e1000_main.c
===================================================================
--- linux-2.6.16-git6.orig/drivers/net/e1000/e1000_main.c 2006-03-23 15:48:01.000000000 -0600
+++ linux-2.6.16-git6/drivers/net/e1000/e1000_main.c 2006-03-24 15:14:40.431371705 -0600
@@ -226,6 +226,16 @@ static int e1000_resume(struct pci_dev *
static void e1000_netpoll (struct net_device *netdev);
#endif
+static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
+ pci_channel_state_t state);
+static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev);
+static void e1000_io_resume(struct pci_dev *pdev);
+
+static struct pci_error_handlers e1000_err_handler = {
+ .error_detected = e1000_io_error_detected,
+ .slot_reset = e1000_io_slot_reset,
+ .resume = e1000_io_resume,
+};
static struct pci_driver e1000_driver = {
.name = e1000_driver_name,
@@ -235,8 +245,9 @@ static struct pci_driver e1000_driver =
/* Power Managment Hooks */
#ifdef CONFIG_PM
.suspend = e1000_suspend,
- .resume = e1000_resume
+ .resume = e1000_resume,
#endif
+ .err_handler = &e1000_err_handler,
};
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
@@ -3063,6 +3074,10 @@ e1000_update_stats(struct e1000_adapter
#define PHY_IDLE_ERROR_COUNT_MASK 0x00FF
+ /* Prevent stats update while adapter is being reset */
+ if (adapter->link_speed == 0)
+ return;
+
spin_lock_irqsave(&adapter->stats_lock, flags);
/* these counters are modified from e1000_adjust_tbi_stats,
@@ -4631,4 +4646,101 @@ e1000_netpoll(struct net_device *netdev)
}
#endif
+/**
+ * e1000_io_error_detected - called when PCI error is detected
+ * @pdev: Pointer to PCI device
+ * @state: The current pci conneection state
+ *
+ * This function is called after a PCI bus error affecting
+ * this device has been detected.
+ */
+static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct e1000_adapter *adapter = netdev->priv;
+
+ netif_device_detach(netdev);
+
+ if (netif_running(netdev))
+ e1000_down(adapter);
+
+ /* Request a slot slot reset. */
+ return PCI_ERS_RESULT_NEED_RESET;
+}
+
+/**
+ * e1000_io_slot_reset - called after the pci bus has been reset.
+ * @pdev: Pointer to PCI device
+ *
+ * Restart the card from scratch, as if from a cold-boot. Implementation
+ * resembles the first-half of the e1000_resume routine.
+ */
+static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct e1000_adapter *adapter = netdev->priv;
+
+ if (pci_enable_device(pdev)) {
+ printk(KERN_ERR "e1000: Cannot re-enable PCI device after reset.\n");
+ return PCI_ERS_RESULT_DISCONNECT;
+ }
+ pci_set_master(pdev);
+
+ pci_enable_wake(pdev, 3, 0);
+ pci_enable_wake(pdev, 4, 0); /* 4 == D3 cold */
+
+ /* Perform card reset only on one instance of the card */
+ if (PCI_FUNC (pdev->devfn) != 0)
+ return PCI_ERS_RESULT_RECOVERED;
+
+ e1000_reset(adapter);
+ E1000_WRITE_REG(&adapter->hw, WUS, ~0);
+
+ return PCI_ERS_RESULT_RECOVERED;
+}
+
+/**
+ * e1000_io_resume - called when traffic can start flowing again.
+ * @pdev: Pointer to PCI device
+ *
+ * This callback is called when the error recovery driver tells us that
+ * its OK to resume normal operation. Implementation resembles the
+ * second-half of the e1000_resume routine.
+ */
+static void e1000_io_resume(struct pci_dev *pdev)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct e1000_adapter *adapter = netdev->priv;
+ uint32_t manc, swsm;
+
+ if (netif_running(netdev)) {
+ if (e1000_up(adapter)) {
+ printk("e1000: can't bring device back up after reset\n");
+ return;
+ }
+ }
+
+ netif_device_attach(netdev);
+
+ if (adapter->hw.mac_type >= e1000_82540 &&
+ adapter->hw.media_type == e1000_media_type_copper) {
+ manc = E1000_READ_REG(&adapter->hw, MANC);
+ manc &= ~(E1000_MANC_ARP_EN);
+ E1000_WRITE_REG(&adapter->hw, MANC, manc);
+ }
+
+ switch (adapter->hw.mac_type) {
+ case e1000_82573:
+ swsm = E1000_READ_REG(&adapter->hw, SWSM);
+ E1000_WRITE_REG(&adapter->hw, SWSM,
+ swsm | E1000_SWSM_DRV_LOAD);
+ break;
+ default:
+ break;
+ }
+
+ if (netif_running(netdev))
+ mod_timer(&adapter->watchdog_timer, jiffies);
+}
+
/* e1000_main.c */
^ permalink raw reply
* Re: [PATCH] PCI Error Recovery: e1000 network device driver
From: Greg KH @ 2006-03-25 2:22 UTC (permalink / raw)
To: Linas Vepstas
Cc: netdev, linux-kernel, jesse.brandeburg, linuxppc-dev,
john.ronciak, jeffrey.t.kirsher, linux-pci, Jeff Garzik
In-Reply-To: <20060324220002.GC26137@austin.ibm.com>
On Fri, Mar 24, 2006 at 04:00:02PM -0600, Linas Vepstas wrote:
> + /* Perform card reset only on one instance of the card */
> + if(0 != PCI_FUNC (pdev->devfn))
> + return PCI_ERS_RESULT_RECOVERED;
You seem to have forgotton to put a ' ' after the 'if' in a number of
different places in this patch. Also the (0 != foo) form is a bit
different from the traditional kernel coding style.
> + switch(adapter->hw.mac_type) {
And here too.
Remember, "if" and "switch" are not functions...
thanks,
greg k-h
^ permalink raw reply
* Re: memory with __get_free_pages and disabling caching
From: Matt Porter @ 2006-03-25 0:27 UTC (permalink / raw)
To: Kallol Biswas; +Cc: linuxppc-dev
In-Reply-To: <478F19F21671F04298A2116393EEC3D50A9C8D@sjc1exm08.pmc_nt.nt.pmc-sierra.bc.ca>
On Fri, Mar 24, 2006 at 03:44:42PM -0800, Kallol Biswas wrote:
> Thank you.
>
> I wonder how consistent ptes are used if all kernel memory is mapped with large tlb.
> In the __dma_alloc_coherent() routine pages are allocated with alloc_pages(), new virtual address is created in consistent region, then consistent ptes are populated. Looks like that the routine creates a new virtual mapping. The memory is addressed with the new address.
>
> Do we have two mappings in the TLB for the same physical address?
Yes, that's how it works. After being allocated by the dma api
routines, the direct map is never accessed. Accessing the same
physical address via the cached direct map would cause serious
problems but you aren't allowed to touch address space like
that unless it's been allocated through a kernel allocator for
your use.
-Matt
^ permalink raw reply
* Re: memory with __get_free_pages and disabling caching
From: Matt Porter @ 2006-03-25 1:25 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: Kallol Biswas, linuxppc-dev
In-Reply-To: <1143248571.3710.33.camel@localhost.localdomain>
On Sat, Mar 25, 2006 at 12:02:51PM +1100, Benjamin Herrenschmidt wrote:
>
> > Yes, that's how it works. After being allocated by the dma api
> > routines, the direct map is never accessed. Accessing the same
> > physical address via the cached direct map would cause serious
> > problems but you aren't allowed to touch address space like
> > that unless it's been allocated through a kernel allocator for
> > your use.
>
> That is still broken for at least 6xx CPUs ... they may well prefetch it
> and you die...
Right.
> For example, page A is a normal page allocated for kernel use, page B
> just a after A is used by the DMA allocator for uncacheable accesses
> (and is thus mapped twice). If something does a loop going through an
> array in page A, you have no guarantee that some smart prefetcher &
> speculative accesses will not bring bits of page B into the cache since
> it's mapped and cacheable...
We had a similar scenario on 4xx with the smart prefetching that is
used in copy_tofrom_user. It had to be modified not to prefetch
across pages for 4xx. Eugene first saw corruption due to adjacent
page prefetches into a dmaable page.
-Matt
^ permalink raw reply
* Re: memory with __get_free_pages and disabling caching
From: Benjamin Herrenschmidt @ 2006-03-25 1:02 UTC (permalink / raw)
To: Matt Porter; +Cc: Kallol Biswas, linuxppc-dev
In-Reply-To: <20060324172733.A20731@cox.net>
> Yes, that's how it works. After being allocated by the dma api
> routines, the direct map is never accessed. Accessing the same
> physical address via the cached direct map would cause serious
> problems but you aren't allowed to touch address space like
> that unless it's been allocated through a kernel allocator for
> your use.
That is still broken for at least 6xx CPUs ... they may well prefetch it
and you die...
For example, page A is a normal page allocated for kernel use, page B
just a after A is used by the DMA allocator for uncacheable accesses
(and is thus mapped twice). If something does a loop going through an
array in page A, you have no guarantee that some smart prefetcher &
speculative accesses will not bring bits of page B into the cache since
it's mapped and cacheable...
Ben.
^ permalink raw reply
* Re: memory with __get_free_pages and disabling caching
From: Matt Porter @ 2006-03-25 0:29 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: Kallol Biswas, linuxppc-dev
In-Reply-To: <1143246035.3710.29.camel@localhost.localdomain>
On Sat, Mar 25, 2006 at 11:20:34AM +1100, Benjamin Herrenschmidt wrote:
> On Fri, 2006-03-24 at 15:44 -0800, Kallol Biswas wrote:
> > Thank you.
> >
> > I wonder how consistent ptes are used if all kernel memory is mapped with large tlb.
> > In the __dma_alloc_coherent() routine pages are allocated with alloc_pages(), new virtual address is created in consistent region,
> > then consistent ptes are populated. Looks like that the routine creates a new virtual mapping. The memory is addressed with the new address.
> >
> > Do we have two mappings in the TLB for the same physical address?
>
> Yes, it seems like we do... the consistent DMA stuff assumes that is
> safe to do, which is not the case on 6xx CPUs but might be on 4xx.
It is safe on 4xx. The doomsday scenario on 4xx is two mapping in the
TBL for the same virtual address range. Operation at that point is
boundedly undefined. :)
-Matt
^ permalink raw reply
* RE: memory with __get_free_pages and disabling caching
From: Benjamin Herrenschmidt @ 2006-03-25 0:20 UTC (permalink / raw)
To: Kallol Biswas; +Cc: linuxppc-dev
In-Reply-To: <478F19F21671F04298A2116393EEC3D50A9C8D@sjc1exm08.pmc_nt.nt.pmc-sierra.bc.ca>
On Fri, 2006-03-24 at 15:44 -0800, Kallol Biswas wrote:
> Thank you.
>
> I wonder how consistent ptes are used if all kernel memory is mapped with large tlb.
> In the __dma_alloc_coherent() routine pages are allocated with alloc_pages(), new virtual address is created in consistent region,
> then consistent ptes are populated. Looks like that the routine creates a new virtual mapping. The memory is addressed with the new address.
>
> Do we have two mappings in the TLB for the same physical address?
Yes, it seems like we do... the consistent DMA stuff assumes that is
safe to do, which is not the case on 6xx CPUs but might be on 4xx.
> When I find it out, I will do a posting.
>
> -----Original Message-----
> From: Benjamin Herrenschmidt [mailto:benh@kernel.crashing.org]
> Sent: Friday, March 24, 2006 2:31 PM
> To: Kallol Biswas
> Cc: linuxppc-dev@ozlabs.org
> Subject: RE: memory with __get_free_pages and disabling caching
>
> On Fri, 2006-03-24 at 11:13 -0800, Kallol Biswas wrote:
> > We have a little endian device on a PPC 440GX based system.
> > The descriptors need to be swapped. With E bit turned on we can save swapping time.
> >
> > May be all the pages with _get_free_page already are mapped with large tlb entry.
> >
> > How about making a window (ptes) like consistent memory?
>
> If you allocate with consistent allocator on 4xx, you should be able to hack the PTEs to set the E bit, but I think it's not necessary. We've been swapping descriptor for ages without any noticeable performance loss since pretty much all network devices have little endian descriptor rings :) Look into using the {ld,st}_le{16,32} inlines, they use the native swapped load/store instructions of the CPU to store things in little endian format. They shouldn't cost more or at least not significantly more than normal load/stores.
>
> Ben.
>
> > -----Original Message-----
> > From: Benjamin Herrenschmidt [mailto:benh@kernel.crashing.org]
> > Sent: Thursday, March 23, 2006 7:06 PM
> > To: Kallol Biswas
> > Cc: linuxppc-dev@ozlabs.org
> > Subject: Re: memory with __get_free_pages and disabling caching
> >
> > On Thu, 2006-03-23 at 18:15 -0800, Kallol Biswas wrote:
> > > Hello,
> > > Is there an easy way to set page table attributes for the
> > > memory returned by __get_free_pages()?
> > >
> > > I need to be able to turn off caching and turn on E bit for these
> > > pages.
> >
> > The Evil bit ? heh ! what are you trying to do ? here ... you can always create a virtual mapping to those pages with different attributes but that's nor recommended as some processors will shoke pretty badly if you end up with both cacheable and non-cacheable mappings for the same page.
> > However, it's not always possible to unmap the initial mapping since it's common to use things like large pages, BATs, large TLB entries etc... to map kernel memory..
> >
> > > I tried to walk through the page tables data structures to get the
> > > pte, but it seems that the pmd is not present for the pages. If
> > > someone has done investigation on this before please send me a reply.
> > >
> > Kernel linear memory isn't necessarily mapped by the page tables. What are you trying to do and with what processor ?
> >
> >
> >
> > Ben.
> >
^ permalink raw reply
* Re: [BULK] Re: "transmit timed out" on FCC in MPC8260 as well as MPC8247
From: Wolfgang Denk @ 2006-03-25 0:10 UTC (permalink / raw)
To: Siju Viswanath K E; +Cc: linuxppc-embedded
In-Reply-To: <1143193658.22246.20.camel@Blaze>
In message <1143193658.22246.20.camel@Blaze> you wrote:
>
> the issue. My repository is patched upto
> "Patch by Wojciech Kromer, 06 Jan 2004" and later changes are only
> adding extra board support.
This is definitely *not* correct. A *long* list of bugs have been
fixed in the last two years.
Best regards,
Wolfgang Denk
--
Software Engineering: Embedded and Realtime Systems, Embedded Linux
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
Life is a game. Money is how we keep score. - Ted Turner
^ permalink raw reply
* Re: [PATCH] powerpc: dynamic probe - use ppc_md.pci_probe_mode()
From: Linas Vepstas @ 2006-03-24 23:03 UTC (permalink / raw)
To: John Rose; +Cc: External List, Paul Mackerras
In-Reply-To: <20060324224801.GD26137@austin.ibm.com>
On Fri, Mar 24, 2006 at 04:48:01PM -0600, Linas Vepstas wrote:
> On Fri, Mar 24, 2006 at 11:19:13AM -0600, John Rose wrote:
> > + if (mode == PCI_PROBE_DEVTREE) {
> > + printk("%s: jhr: new probe\n", __FUNCTION__);
>
> Did you intend to leave in this print statement? Its looks
> suspiciously like a debug print.
Never mind, I should have looked at the next eamil.
--linas
^ permalink raw reply
* RE: memory with __get_free_pages and disabling caching
From: Kallol Biswas @ 2006-03-24 23:44 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
Thank you.
I wonder how consistent ptes are used if all kernel memory is mapped with large tlb.
In the __dma_alloc_coherent() routine pages are allocated with alloc_pages(), new virtual address is created in consistent region, then consistent ptes are populated. Looks like that the routine creates a new virtual mapping. The memory is addressed with the new address.
Do we have two mappings in the TLB for the same physical address?
When I find it out, I will do a posting.
-----Original Message-----
From: Benjamin Herrenschmidt [mailto:benh@kernel.crashing.org]
Sent: Friday, March 24, 2006 2:31 PM
To: Kallol Biswas
Cc: linuxppc-dev@ozlabs.org
Subject: RE: memory with __get_free_pages and disabling caching
On Fri, 2006-03-24 at 11:13 -0800, Kallol Biswas wrote:
> We have a little endian device on a PPC 440GX based system.
> The descriptors need to be swapped. With E bit turned on we can save swapping time.
>
> May be all the pages with _get_free_page already are mapped with large tlb entry.
>
> How about making a window (ptes) like consistent memory?
If you allocate with consistent allocator on 4xx, you should be able to hack the PTEs to set the E bit, but I think it's not necessary. We've been swapping descriptor for ages without any noticeable performance loss since pretty much all network devices have little endian descriptor rings :) Look into using the {ld,st}_le{16,32} inlines, they use the native swapped load/store instructions of the CPU to store things in little endian format. They shouldn't cost more or at least not significantly more than normal load/stores.
Ben.
> -----Original Message-----
> From: Benjamin Herrenschmidt [mailto:benh@kernel.crashing.org]
> Sent: Thursday, March 23, 2006 7:06 PM
> To: Kallol Biswas
> Cc: linuxppc-dev@ozlabs.org
> Subject: Re: memory with __get_free_pages and disabling caching
>
> On Thu, 2006-03-23 at 18:15 -0800, Kallol Biswas wrote:
> > Hello,
> > Is there an easy way to set page table attributes for the
> > memory returned by __get_free_pages()?
> >
> > I need to be able to turn off caching and turn on E bit for these
> > pages.
>
> The Evil bit ? heh ! what are you trying to do ? here ... you can always create a virtual mapping to those pages with different attributes but that's nor recommended as some processors will shoke pretty badly if you end up with both cacheable and non-cacheable mappings for the same page.
> However, it's not always possible to unmap the initial mapping since it's common to use things like large pages, BATs, large TLB entries etc... to map kernel memory..
>
> > I tried to walk through the page tables data structures to get the
> > pte, but it seems that the pmd is not present for the pages. If
> > someone has done investigation on this before please send me a reply.
> >
> Kernel linear memory isn't necessarily mapped by the page tables. What are you trying to do and with what processor ?
>
>
>
> Ben.
>
^ permalink raw reply
* [PATCH] powerpc/pseries: Cleanup device name printing.
From: Linas Vepstas @ 2006-03-24 23:11 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, linux-kernel
Paul,
Please apply and forward.
--linas
[PATCH] powerpc/pseries: Cleanup device name printing.
This patch avoids printk'ing a NULL string.
Signed-off-by: Linas Vepstas <linas@linas.org>
----
arch/powerpc/platforms/pseries/eeh_driver.c | 16 ++++++++++------
1 files changed, 10 insertions(+), 6 deletions(-)
Index: linux-2.6.16-git6/arch/powerpc/platforms/pseries/eeh_driver.c
===================================================================
--- linux-2.6.16-git6.orig/arch/powerpc/platforms/pseries/eeh_driver.c 2006-03-24 16:46:25.836892186 -0600
+++ linux-2.6.16-git6/arch/powerpc/platforms/pseries/eeh_driver.c 2006-03-24 16:58:55.305489138 -0600
@@ -257,6 +257,7 @@ void handle_eeh_events (struct eeh_event
struct pci_bus *frozen_bus;
int rc = 0;
enum pci_ers_result result = PCI_ERS_RESULT_NONE;
+ const char *pci_str, *drv_str;
frozen_dn = find_device_pe(event->dn);
frozen_bus = pcibios_find_pci_bus(frozen_dn);
@@ -291,6 +292,13 @@ void handle_eeh_events (struct eeh_event
frozen_pdn = PCI_DN(frozen_dn);
frozen_pdn->eeh_freeze_count++;
+
+ pci_str = pci_name (frozen_pdn->pcidev);
+ drv_str = pcid_name (frozen_pdn->pcidev);
+ if (!pci_str) {
+ pci_str = pci_name (event->dev);
+ drv_str = pcid_name (event->dev);
+ }
if (frozen_pdn->eeh_freeze_count > EEH_MAX_ALLOWED_FREEZES)
goto hard_fail;
@@ -306,9 +314,7 @@ void handle_eeh_events (struct eeh_event
eeh_slot_error_detail(frozen_pdn, 1 /* Temporary Error */);
printk(KERN_WARNING
"EEH: This PCI device has failed %d times since last reboot: %s - %s\n",
- frozen_pdn->eeh_freeze_count,
- pci_name (frozen_pdn->pcidev),
- pcid_name(frozen_pdn->pcidev));
+ frozen_pdn->eeh_freeze_count, drv_str, pci_str);
/* Walk the various device drivers attached to this slot through
* a reset sequence, giving each an opportunity to do what it needs
@@ -360,9 +366,7 @@ hard_fail:
"EEH: PCI device %s - %s has failed %d times \n"
"and has been permanently disabled. Please try reseating\n"
"this device or replacing it.\n",
- pci_name (frozen_pdn->pcidev),
- pcid_name(frozen_pdn->pcidev),
- frozen_pdn->eeh_freeze_count);
+ drv_str, pci_str, frozen_pdn->eeh_freeze_count);
eeh_slot_error_detail(frozen_pdn, 2 /* Permanent Error */);
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox