* Re: [Patch 4/6] Modify process and processor handling code to recognise hardware debug registers
From: K.Prasad @ 2009-06-18 17:56 UTC (permalink / raw)
To: David Gibson
Cc: Michael Neuling, Benjamin Herrenschmidt, linuxppc-dev, paulus,
Alan Stern, Roland McGrath
In-Reply-To: <20090617041420.GK486@yookeroo.seuss>
On Wed, Jun 17, 2009 at 02:14:20PM +1000, David Gibson wrote:
> On Wed, Jun 10, 2009 at 02:38:18PM +0530, K.Prasad wrote:
> > Modify process handling code to recognise hardware debug registers during copy
> > and flush operations. Introduce a new TIF_DEBUG task flag to indicate a
> > process's use of debug register. Load the debug register values into a
> > new CPU during initialisation.
> >
> > Signed-off-by: K.Prasad <prasad@linux.vnet.ibm.com>
> > ---
> > arch/powerpc/kernel/process.c | 15 +++++++++++++++
> > arch/powerpc/kernel/smp.c | 2 ++
> > 2 files changed, 17 insertions(+)
> >
> > Index: linux-2.6-tip.hbkpt/arch/powerpc/kernel/process.c
> > ===================================================================
> > --- linux-2.6-tip.hbkpt.orig/arch/powerpc/kernel/process.c
> > +++ linux-2.6-tip.hbkpt/arch/powerpc/kernel/process.c
> > @@ -50,6 +50,7 @@
> > #include <asm/syscalls.h>
> > #ifdef CONFIG_PPC64
> > #include <asm/firmware.h>
> > +#include <asm/hw_breakpoint.h>
> > #endif
> > #include <linux/kprobes.h>
> > #include <linux/kdebug.h>
> > @@ -254,8 +255,10 @@ void do_dabr(struct pt_regs *regs, unsig
> > 11, SIGSEGV) == NOTIFY_STOP)
> > return;
> >
> > +#ifndef CONFIG_PPC64
> > if (debugger_dabr_match(regs))
> > return;
> > +#endif
>
> Won't this disable the check for breakpoints set by xmon - but I don't
> see anything in this patch series to convert xmon to use the new
> breakpoint interface instead.
>
As noted by me here:
http://lists.ozlabs.org/pipermail/linuxppc-dev/2009-May/071832.html the
Xmon integration is pending. When I tried to study and integrate Xmon, I
found that the HW Breakpoint triggering was broken as of 2.6.29 kernel
(tested on a Power5 box).
This would mean that if Xmon's hardware breakpoint infrastructure is
used in tandem with the given breakpoint interfaces, they would conflict
with each other resulting in difficult-to-predict behaviour (the last to
grab the register will use it).
I think that tidying up do_dabr() is best done along with Xmon
integration.
> --
> 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
Thanks,
K.Prasad
^ permalink raw reply
* killing use of ppc_md.init
From: Kumar Gala @ 2009-06-18 14:38 UTC (permalink / raw)
To: Gerhard Pircher, Benjamin Herrenschmidt; +Cc: linuxppc-dev list
ppc_md.init only exists on ppc32 and seems like its pretty useless
today. The users seem to fall into two classes:
1. called to do of_platform_bus_probe() - most platforms use
machine_device_initcall() for this
2. some platform init code which seems like it could move into
setup_arch().
The second one seems to only be on amigaone and chrp. Anyone know if
there is any harm in moving the amigaone_init() into
amigaone_setup_arch() and similarly on chrp chrp_init2() into
chrp_setup_arch().
- k
^ permalink raw reply
* Re: [spi-devel-general] [PATCH v4] powerpc/5200: Add mpc5200-spi (non-PSC) device driver
From: Wolfram Sang @ 2009-06-18 14:26 UTC (permalink / raw)
To: Grant Likely
Cc: linuxppc-dev, David Brownell, linux-kernel, spi-devel-general
In-Reply-To: <fa686aa40906180635g45724119x99cd4d1e4ede59f9@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 2272 bytes --]
Hi Grant,
> The double spaces at the end of sentences are intentional. It is
> perhaps a bit quaint and old fashioned, but it is my writing style.
Ah, okay.
> >> +
> >> + /* Statistics */
> >> + int msg_count;
> >> + int wcol_count;
> >> + int wcol_ticks;
> >> + u32 wcol_tx_timestamp;
> >> + int modf_count;
> >> + int byte_count;
> >
> > Hmm, there isn't even a debug-printout for those. Putting #ifdef DEBUG around
> > them will be ugly. Well, I can't make up if this is just overhead or useful
> > debugging aid, so no real objection :)
>
> There used to be a sysfs interface for dumping these, but it was an
> ugly misuse. I'd like to leave these in. I still have the sysfs bits
> in a private patch and I'm going to rework them for debugfs.
Okay. Maybe a comment stating the future use will be nice.
>
> > But I wonder more about the usage of the SS pin and if this chipsel is needed
> > at all (sadly I cannot test as I don't have any board with SPI connected to
> > that device). You define the SS-pin as output, but do not set the SSOE-bit.
> > More, you use the MODF-feature, so the SS-pin should be defined as input?
> > According to Table 17.3 in the PM, you have that pin defined as generic purpose
> > output.
>
> That's right. The SS handling by the SPI device is completely
> useless, so this driver uses it as a GPIO and asserts it manually.
That definately needs a comment :D (perhaps with some more details if you know them).
> The MODF irq is probably irrelevant, but I'd like to leave it in for
> completeness.
But it won't work if the pin is set to output, no? Are you sure there are no
side-effects?
> >> + /* initialize the device */
> >> + out_8(regs+SPI_CTRL1, SPI_CTRL1_SPIE | SPI_CTRL1_SPE | SPI_CTRL1_MSTR);
> >
> > spaces around operator.
>
> Intentional to keep from spilling past column 80; but I'll move the
> missing spaces to around the | operators. I think it is easier to
> read that way.
Ah, I remember, we had this topic a while ago :D
Regards,
Wolfram
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* Re: [PATCH] powerpc: Add configurable -Werror for arch/powerpc
From: Arnd Bergmann @ 2009-06-18 14:22 UTC (permalink / raw)
To: linuxppc-dev; +Cc: linuxppc-dev list, Timur Tabi
In-Reply-To: <ed82fe3e0906150754w125c6283q2468213b59c7f114@mail.gmail.com>
On Monday 15 June 2009, Timur Tabi wrote:
> On Mon, Jun 15, 2009 at 2:50 AM, Michael Ellerman<michael@ellerman.id.au> wrote:
> > arch/powerpc/platforms/chrp/setup.c:378: error: the frame size of 1040 bytes is larger than 1024 bytes
>
> What's so bad about a frame size larger than 1024?
>
It's not necessarily a bug, but all frame sizes in the call chain
combined must never exceed the kernel stack size. 1024 is an
arbitrary limit that we warn about for a single function, because
it's likely that things will break if you have more than one of these.
Arnd <><
^ permalink raw reply
* Re: [PATCH -mm][POWERPC] mpc8xxx : allow SPI without cs.
From: Kumar Gala @ 2009-06-18 14:04 UTC (permalink / raw)
To: avorontsov; +Cc: spi-devel-general, Rini van Zetten, linuxppc-dev list
In-Reply-To: <20090618130955.GA1369@oksana.dev.rtsoft.ru>
On Jun 18, 2009, at 8:09 AM, Anton Vorontsov wrote:
> On Thu, Jun 18, 2009 at 08:19:44AM +0200, Rini van Zetten wrote:
>> This patch adds the possibility to have a spi device without a cs.
>>
>> For example, the dts file should look something like this:
>>
>> spi-controller {
>> gpios = <&pio1 1 0 /* cs0 */
>> 0 /* cs1, no GPIO */
>> &pio2 2 0>; /* cs2 */
>>
>
> Interesting scheme. I guess this is for eSPI controllers that can
> do their own chip-selects, but we want GPIO chip selects in addition
> (or in place of built-in ones), correct?
That is a good question. What HW is this for (I don't think its for
eSPI but I could be wrong).
- k
^ permalink raw reply
* Re: [spi-devel-general] [PATCH v4] powerpc/5200: Add mpc5200-spi (non-PSC) device driver
From: Grant Likely @ 2009-06-18 13:35 UTC (permalink / raw)
To: Wolfram Sang
Cc: linuxppc-dev, David Brownell, linux-kernel, spi-devel-general
In-Reply-To: <20090618065814.GA12942@pengutronix.de>
On Thu, Jun 18, 2009 at 12:58 AM, Wolfram Sang<w.sang@pengutronix.de> wrote=
:
> Hi Grant,
>
> some comments below:
Hi Wolfram. Thanks for the review.
> On Wed, Jun 17, 2009 at 08:55:01PM -0600, Grant Likely wrote:
>> +#include <linux/spi/mpc52xx_spi.h>
>
> Is this still needed? See last comment...
No, not needed at all. Will remove.
>> +#include <linux/of_spi.h>
>> +#include <linux/io.h>
>> +#include <asm/time.h>
>
> Really asm?
Yes, really asm. Needed for get_tlb()
>> +#include <asm/mpc52xx.h>
>> +
>> +MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
>> +MODULE_DESCRIPTION("MPC52xx SPI (non-PSC) Driver");
>> +MODULE_LICENSE("GPL");
>> +
>> +/* Register offsets */
>> +#define SPI_CTRL1 =A0 =A00x00
>> +#define SPI_CTRL1_SPIE =A0 =A0 =A0 =A0 =A0 =A0 =A0 (1 << 7)
>> +#define SPI_CTRL1_SPE =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(1 << 6)
>> +#define SPI_CTRL1_MSTR =A0 =A0 =A0 =A0 =A0 =A0 =A0 (1 << 4)
>> +#define SPI_CTRL1_CPOL =A0 =A0 =A0 =A0 =A0 =A0 =A0 (1 << 3)
>> +#define SPI_CTRL1_CPHA =A0 =A0 =A0 =A0 =A0 =A0 =A0 (1 << 2)
>> +#define SPI_CTRL1_SSOE =A0 =A0 =A0 =A0 =A0 =A0 =A0 (1 << 1)
>> +#define SPI_CTRL1_LSBFE =A0 =A0 =A0 =A0 =A0 =A0 =A0(1 << 0)
>> +
>> +#define SPI_CTRL2 =A0 =A00x01
>> +#define SPI_BRR =A0 =A0 =A0 =A0 =A0 =A0 =A00x04
>> +
>> +#define SPI_STATUS =A0 0x05
>> +#define SPI_STATUS_SPIF =A0 =A0 =A0 =A0 =A0 =A0 =A0(1 << 7)
>> +#define SPI_STATUS_WCOL =A0 =A0 =A0 =A0 =A0 =A0 =A0(1 << 6)
>> +#define SPI_STATUS_MODF =A0 =A0 =A0 =A0 =A0 =A0 =A0(1 << 4)
>> +
>> +#define SPI_DATA =A0 =A0 0x09
>> +#define SPI_PORTDATA 0x0d
>> +#define SPI_DATADIR =A00x10
>> +
>> +/* FSM state return values */
>> +#define FSM_STOP =A0 =A0 0 =A0 =A0 =A0 /* Nothing more for the state ma=
chine to */
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* do. =A0If s=
omething interesting happens */
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* then and IR=
Q will be received */
>
> s/and/an/? Throughout the comments, there is sometimes a double space.
The double spaces at the end of sentences are intentional. It is
perhaps a bit quaint and old fashioned, but it is my writing style.
>
>> +#define FSM_POLL =A0 =A0 1 =A0 =A0 =A0 /* need to poll for completion, =
an IRQ is */
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* not expecte=
d */
>> +#define FSM_CONTINUE 2 =A0 =A0 =A0 /* Keep iterating the state machine =
*/
>> +
>> +/* Driver internal data */
>> +struct mpc52xx_spi {
>> + =A0 =A0 struct spi_master *master;
>> + =A0 =A0 u32 sysclk;
>
> unused?
yes, fixed.
>> + =A0 =A0 void __iomem *regs;
>> + =A0 =A0 int irq0; =A0 =A0 =A0 /* MODF irq */
>> + =A0 =A0 int irq1; =A0 =A0 =A0 /* SPIF irq */
>> + =A0 =A0 int ipb_freq;
>
> unsigned int will suit it better IMHO.
right.
>> +
>> + =A0 =A0 /* Statistics */
>> + =A0 =A0 int msg_count;
>> + =A0 =A0 int wcol_count;
>> + =A0 =A0 int wcol_ticks;
>> + =A0 =A0 u32 wcol_tx_timestamp;
>> + =A0 =A0 int modf_count;
>> + =A0 =A0 int byte_count;
>
> Hmm, there isn't even a debug-printout for those. Putting #ifdef DEBUG ar=
ound
> them will be ugly. Well, I can't make up if this is just overhead or usef=
ul
> debugging aid, so no real objection :)
There used to be a sysfs interface for dumping these, but it was an
ugly misuse. I'd like to leave these in. I still have the sysfs bits
in a private patch and I'm going to rework them for debugfs.
> But I wonder more about the usage of the SS pin and if this chipsel is ne=
eded
> at all (sadly I cannot test as I don't have any board with SPI connected =
to
> that device). You define the SS-pin as output, but do not set the SSOE-bi=
t.
> More, you use the MODF-feature, so the SS-pin should be defined as input?
> According to Table 17.3 in the PM, you have that pin defined as generic p=
urpose
> output.
That's right. The SS handling by the SPI device is completely
useless, so this driver uses it as a GPIO and asserts it manually.
The MODF irq is probably irrelevant, but I'd like to leave it in for
completeness.
>> + =A0 =A0 /* initialize the device */
>> + =A0 =A0 out_8(regs+SPI_CTRL1, SPI_CTRL1_SPIE | SPI_CTRL1_SPE | SPI_CTR=
L1_MSTR);
>
> spaces around operator.
Intentional to keep from spilling past column 80; but I'll move the
missing spaces to around the | operators. I think it is easier to
read that way.
>> diff --git a/include/linux/spi/mpc52xx_spi.h b/include/linux/spi/mpc52xx=
_spi.h
>> new file mode 100644
>> index 0000000..d1004cf
>> --- /dev/null
>> +++ b/include/linux/spi/mpc52xx_spi.h
>> @@ -0,0 +1,10 @@
>> +
>> +#ifndef INCLUDE_MPC5200_SPI_H
>> +#define INCLUDE_MPC5200_SPI_H
>> +
>> +extern void mpc52xx_spi_set_premessage_hook(struct spi_master *master,
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0 void (*hook)(struct spi_message *m,
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0void *context),
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0 void *hook_context);
>> +
>> +#endif
>
> This can be dropped for now and reintroduced when needed, I think.
Yeah, this is cruft. Removed.
Thanks!
g.
--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
* Re: [PATCH -mm][POWERPC] mpc8xxx : allow SPI without cs.
From: Anton Vorontsov @ 2009-06-18 13:09 UTC (permalink / raw)
To: Rini van Zetten; +Cc: spi-devel-general, linuxppc-dev list
In-Reply-To: <4A39DC80.7030906@arvoo.nl>
On Thu, Jun 18, 2009 at 08:19:44AM +0200, Rini van Zetten wrote:
> This patch adds the possibility to have a spi device without a cs.
>
> For example, the dts file should look something like this:
>
> spi-controller {
> gpios = <&pio1 1 0 /* cs0 */
> 0 /* cs1, no GPIO */
> &pio2 2 0>; /* cs2 */
>
Interesting scheme. I guess this is for eSPI controllers that can
do their own chip-selects, but we want GPIO chip selects in addition
(or in place of built-in ones), correct?
> Signed-off-by: Rini van Zetten <rini@arvoo.nl>
> ---
> Changes :
> patch against 2.6.30-rc8-mm1
I assume this is v2 already, and I overlooked v1, sorry.
Technically the patch looks OK, but please fix some cosmetics issues.
checkpatch reports:
WARNING: patch prefix 'drivers' exists, appears to be a -p0 patch
WARNING: line over 80 characters
#131: FILE: spi/spi_mpc8xxx.c:714:
+ dev_err(dev, "can't request gpio #%d: %d\n", i, ret);
WARNING: line over 80 characters
#141: FILE: spi/spi_mpc8xxx.c:724:
+ dev_err(dev, "can't set output direction for gpio "
> --- drivers/spi/spi_mpc8xxx.c.org 2009-06-12 10:45:21.000000000 +0200
> +++ drivers/spi/spi_mpc8xxx.c 2009-06-12 10:54:48.000000000 +0200
> @@ -666,9 +666,10 @@ static void mpc8xxx_spi_cs_control(struc
> struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(dev->platform_data);
> u16 cs = spi->chip_select;
> int gpio = pinfo->gpios[cs];
> - bool alow = pinfo->alow_flags[cs];
> -
> - gpio_set_value(gpio, on ^ alow);
> + if (gpio != -EEXIST) {
> + bool alow = pinfo->alow_flags[cs];
> + gpio_set_value(gpio, on ^ alow);
Please put an empty line after variable declaration.
Thanks!
--
Anton Vorontsov
email: cbouatmailru@gmail.com
irc://irc.freenode.net/bd2
^ permalink raw reply
* Re: [PATCH 5/6] perf_counter: powerpc: Add processor back-end for MPC7450 family
From: Kumar Gala @ 2009-06-18 12:50 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, Ingo Molnar, Peter Zijlstra, linux-kernel
In-Reply-To: <19001.31508.901222.288946@cargo.ozlabs.ibm.com>
On Jun 17, 2009, at 6:24 PM, Paul Mackerras wrote:
> Kumar Gala writes:
>
>> This should be something like:
>>
>> obj64-$(CONFIG_PPC_PERF_CTRS)-$(PPC_BOOK3S_64)
>>
>>> +obj32-$(CONFIG_PPC_PERF_CTRS) += mpc7450-pmu.o
>>
>> obj32-$(CONFIG_PPC_PERF_CTRS)-$(PPC_BOOK3S_32)
>>
>> Or use new Kconfig types as I suggested on patch 1/6
>
> Feel free to send a patch making those changes along with adding the
> code to support the Freescale embedded PMU. :)
>
> Paul.
In looking at doing this what suggestions do you have in implementing
perf_instruction_pointer() if we don't have the equivalent of SIAR.
Just use regs->nip ?
- k
^ permalink raw reply
* Re: [PATCH -mm][POWERPC] mpc8xxx : allow SPI without cs.
From: Kumar Gala @ 2009-06-18 12:42 UTC (permalink / raw)
To: Anton Vorontsov; +Cc: spi-devel-general, Rini van Zetten, linuxppc-dev list
In-Reply-To: <4A39DC80.7030906@arvoo.nl>
On Jun 18, 2009, at 1:19 AM, Rini van Zetten wrote:
> This patch adds the possibility to have a spi device without a cs.
>
> For example, the dts file should look something like this:
>
> spi-controller {
> gpios = <&pio1 1 0 /* cs0 */
> 0 /* cs1, no GPIO */
> &pio2 2 0>; /* cs2 */
>
>
>
> Signed-off-by: Rini van Zetten <rini@arvoo.nl>
> ---
> Changes :
> patch against 2.6.30-rc8-mm1
Anton,
Can you review and ack this if you are ok with it.
- k
>
>
> --- drivers/spi/spi_mpc8xxx.c.org 2009-06-12 10:45:21.000000000 +0200
> +++ drivers/spi/spi_mpc8xxx.c 2009-06-12 10:54:48.000000000 +0200
> @@ -666,9 +666,10 @@ static void mpc8xxx_spi_cs_control(struc
> struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(dev-
> >platform_data);
> u16 cs = spi->chip_select;
> int gpio = pinfo->gpios[cs];
> - bool alow = pinfo->alow_flags[cs];
> -
> - gpio_set_value(gpio, on ^ alow);
> + if (gpio != -EEXIST) {
> + bool alow = pinfo->alow_flags[cs];
> + gpio_set_value(gpio, on ^ alow);
> + }
> }
>
> static int of_mpc8xxx_spi_get_chipselects(struct device *dev)
> @@ -707,27 +708,29 @@ static int of_mpc8xxx_spi_get_chipselect
> enum of_gpio_flags flags;
>
> gpio = of_get_gpio_flags(np, i, &flags);
> - if (!gpio_is_valid(gpio)) {
> + if (gpio_is_valid(gpio)) {
> + ret = gpio_request(gpio, dev_name(dev));
> + if (ret) {
> + dev_err(dev, "can't request gpio #%d: %d\n", i, ret);
> + goto err_loop;
> + }
> +
> + pinfo->gpios[i] = gpio;
> + pinfo->alow_flags[i] = flags & OF_GPIO_ACTIVE_LOW;
> +
> + ret = gpio_direction_output(pinfo->gpios[i],
> + pinfo->alow_flags[i]);
> + if (ret) {
> + dev_err(dev, "can't set output direction for gpio "
> + "#%d: %d\n", i, ret);
> + goto err_loop;
> + }
> + } else if (gpio == -EEXIST) {
> + pinfo->gpios[i] = -EEXIST;
> + } else {
> dev_err(dev, "invalid gpio #%d: %d\n", i, gpio);
> goto err_loop;
> }
> -
> - ret = gpio_request(gpio, dev_name(dev));
> - if (ret) {
> - dev_err(dev, "can't request gpio #%d: %d\n", i, ret);
> - goto err_loop;
> - }
> -
> - pinfo->gpios[i] = gpio;
> - pinfo->alow_flags[i] = flags & OF_GPIO_ACTIVE_LOW;
> -
> - ret = gpio_direction_output(pinfo->gpios[i],
> - pinfo->alow_flags[i]);
> - if (ret) {
> - dev_err(dev, "can't set output direction for gpio "
> - "#%d: %d\n", i, ret);
> - goto err_loop;
> - }
> }
>
> pdata->max_chipselect = ngpios;
> --
>
>
> --
> Rini van Zetten
> Senior Software Engineer
>
> -------------------------
> ARVOO Engineering B.V.
> Tasveld 13
> 3417 XS Montfoort
> The Netherlands
>
> E-mail : <mailto:rini@arvoo.com> Rini van Zetten
>
> Web : www.arvoo.com
>
>
^ permalink raw reply
* [PowerPC] Badness at drivers/char/tty_ldisc.c:210 during shutdown
From: Sachin Sant @ 2009-06-18 12:03 UTC (permalink / raw)
To: linux-kernel; +Cc: linuxppc-dev, alan
I came across the following badness message during shutdown on a Power6 box.
This was with 2.6.30-git12(3fe0344faf7fdcb158bd5c1a9aec960a8d70c8e8)
------------[ cut here ]------------
Badness at drivers/char/tty_ldisc.c:210
NIP: c000000000409428 LR: c000000000409410 CTR: 0000000000000000
REGS: c0000000374f37f0 TRAP: 0700 Not tainted (2.6.30-git12)
MSR: 8000000000029032 <EE,ME,CE,IR,DR> CR: 24000484 XER: 00000001
TASK = c00000003d941ae0[8535] 'vhangup' THREAD: c0000000374f0000 CPU: 1
<6>GPR00: 0000000000000001 c0000000374f3a70 c000000000ef4550 0000000000000001
<6>GPR04: c000000000409410 c00000003e99f000 c000000000406ba0 0000000000000000
<6>GPR08: 0000000000000000 0000000000000000 0000000000000000 c0000000374f3a70
<6>GPR12: 0000000024000488 c000000001002600 00000000ffffffff ffffffffffffffff
<6>GPR16: 00000000320c8a50 0000000000000002 0000000000000000 00000000320b03b0
<6>GPR20: 0000000000000000 0000000000000000 c00000003e1d3d00 0000000000000001
<6>GPR24: 0000000000000000 0000000000000000 0000000000000001 c00000003d4a05e0
<6>GPR28: 0000000000000000 c0000000013ffd38 c000000000e7e610 c0000000374f3a70
NIP [c000000000409428] .tty_ldisc_put+0xbc/0xf4
LR [c000000000409410] .tty_ldisc_put+0xa4/0xf4
Call Trace:
[c0000000374f3a70] [c000000000409410] .tty_ldisc_put+0xa4/0xf4 (unreliable)
[c0000000374f3b10] [c000000000409808] .tty_ldisc_reinit+0x38/0x80
[c0000000374f3ba0] [c00000000040a218] .tty_ldisc_hangup+0x190/0x260
[c0000000374f3c40] [c0000000004000d0] .do_tty_hangup+0x188/0x4c0
[c0000000374f3d20] [c000000000400480] .tty_vhangup_self+0x34/0x54
[c0000000374f3db0] [c0000000001917c8] .sys_vhangup+0x38/0x58
[c0000000374f3e30] [c000000000008534] syscall_exit+0x0/0x40
Instruction dump:
912b0088 4bcd2201 60000000 e87e8008 7f44d378 481c0735 60000000 801b0008
7c09fe70 7d200278 7c004850 54000ffe <0b000000> 7f63db78 4bd7cf0d 60000000
Not sure if this is a new issue. I haven't really paid attention
to messages that are displayed during shutdown.
Line 210 corresponds to the following code.
static void tty_ldisc_put(struct tty_ldisc *ld)
{
......
spin_unlock_irqrestore(&tty_ldisc_lock, flags);
WARN_ON(ld->refcount); <<===
.......
Thanks
-Sachin
--
---------------------------------
Sachin Sant
IBM Linux Technology Center
India Systems and Technology Labs
Bangalore, India
---------------------------------
^ permalink raw reply
* Re: PowerPC PCI DMA issues (prefetch/coherency?)
From: Chris Pringle @ 2009-06-18 11:24 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev@ozlabs.org list, linux-kernel
In-Reply-To: <4A38ED31.9030705@oxtel.com>
Chris Pringle wrote:
> Chris Pringle wrote:
>>> You could enable CONFIG_NOT_COHERENT_CACHE.
>>>
>> I've just tried this (I had to edit Kconfig in power/platforms to
>> make the build system accept it), and interestingly it's making no
>> difference. I'm using streaming mappings, and are using the
>> pci_map_sg functions to ensure the memory is mapped/flushed
>> correctly. I've also explicitly put in a pci_dma_sync_sg_for_device,
>> however that's also not made any difference. Turning the cpu cache
>> snoop off has the same affect as it did without
>> CONFIG_NOT_COHERENT_CACHE; it gets much worse. Any other ideas?
>>
>> Will back off the low latency patches next, and give 2.6.30 a try -
>> see if that makes any difference.
>>
> Low latency patches made no difference. Tried it with 2.6.30 and it
> now works. There are a couple of commits contributing to the fix,
> including one introduced between 2.6.29-rc8 and 2.6.29 proper in
> powerpc/kernel/head_32.S (couple of commits with the name "Fix Respect
> _PAGE_COHERENT on classic ppc32 SW TLB load machines"). I've tried
> backporting this to 2.6.29-rc8 and it then worked. Backporting to
> 2.6.26 made no difference however, so I suspect there are other things
> fixed which are also contributing.
>
> I'm going to move to 2.6.29/2.6.30 which should resolve our issue.
>
> Thanks to all who have contributed to this thread.
>
The other part of the fix is in asm-powerpc/pgtable32.h. _PAGE_BASE
needs _PAGE_COHERENT in order to work correctly, and in fact there is
now a comment in there to that affect in 2.6.29. Backporting that change
has made it work on 2.6.26. Both this patch, and the fix to head_32.S
are needed for it to work correctly on older kernels.
Chris
--
______________________________
Chris Pringle
Software Engineer
Miranda Technologies Ltd.
Hithercroft Road
Wallingford
Oxfordshire OX10 9DG
UK
Tel. +44 1491 820206
Fax. +44 1491 820001
www.miranda.com
____________________________
Miranda Technologies Limited
Registered in England and Wales CN 02017053
Registered Office: James House, Mere Park, Dedmere Road, Marlow, Bucks, SL7 1FJ
^ permalink raw reply
* Re: [PATCH] powerpc: Add irqtrace support for 32-bit powerpc (v2)
From: Benjamin Herrenschmidt @ 2009-06-18 9:31 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <20090618034439.0854ADDDB2@ozlabs.org>
On Thu, 2009-06-18 at 13:43 +1000, Benjamin Herrenschmidt wrote:
> Index: linux-work/arch/powerpc/kernel/udbg.c
> ===================================================================
> --- linux-work.orig/arch/powerpc/kernel/udbg.c 2009-06-18
> 13:21:29.000000000 +1000
> +++ linux-work/arch/powerpc/kernel/udbg.c 2009-06-18
> 13:21:39.000000000 +1000
> @@ -65,6 +65,7 @@ void __init udbg_early_init(void)
> #ifdef CONFIG_PPC_EARLY_DEBUG
> console_loglevel = 10;
> #endif
> + register_early_udbg_console();
> }
And that bit of course have nothing to do in that patch :-)
No need for a respin for now though unless we find other problems.
Cheers,
Ben.
^ permalink raw reply
* Re: [PATCH 6/6] perf_counter: tools: Makefile tweaks for 64-bit powerpc
From: Ingo Molnar @ 2009-06-18 9:13 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, Peter Zijlstra, linux-kernel
In-Reply-To: <19000.55666.866148.559620@cargo.ozlabs.ibm.com>
* Paul Mackerras <paulus@samba.org> wrote:
> This also removes the -Werror flag when building on a 64-bit powerpc
> machine. The userspace definition of u64 is unsigned long rather
> than unsigned long long, meaning that gcc warns every time a u64
> is printed with %Lx or %llx (though that does work properly).
> In future we may use PRI64 etc. for printing 64-bit quantities,
> which would eliminate these warnings.
> +# Don't use -Werror on ppc64; we get warnings due to using
> +# %Lx formats on __u64, which is unsigned long.
> +Werror := -Werror
> +ifeq ($(uname_M),ppc64)
> + Werror :=
> +endif
Note, i left out this bit from the commit - we need to find a better
solution than to allow ugly warnings on PowerPC.
Could we use the kernel's u64 type directly perhaps? That would
allow us to change all __u64 to u64 in all of tools/perf/ which is a
nice clean-up in any case.
Ingo
^ permalink raw reply
* Re: [PATCH 1/6] perf_counter: powerpc: Enable use of software counters on 32-bit powerpc
From: Ingo Molnar @ 2009-06-18 9:04 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, Peter Zijlstra, linux-kernel
In-Reply-To: <19001.31734.428534.890844@cargo.ozlabs.ibm.com>
* Paul Mackerras <paulus@samba.org> wrote:
> Ingo Molnar writes:
>
> > Note, i've created a new branch, tip:perfcounters/powerpc, so we can
> > keep these things separate and Ben can pull them too. I see there
> > was some review feedback - do you want to send a v2 version perhaps?
>
> Kumar's comments seemed to me to be wanting changes to accommodate
> code that doesn't exist yet, so I think those changes should be
> done later when that code exists and we know exactly what is
> needed. So the current patches are fine as-is IMO.
ok - will queue them up.
Ingo
^ permalink raw reply
* Re: [spi-devel-general] [PATCH v4] powerpc/5200: Add mpc5200-spi (non-PSC) device driver
From: Wolfram Sang @ 2009-06-18 6:58 UTC (permalink / raw)
To: Grant Likely
Cc: linuxppc-dev, David Brownell, linux-kernel, spi-devel-general
In-Reply-To: <20090618025030.12363.69402.stgit@localhost.localdomain>
[-- Attachment #1: Type: text/plain, Size: 20824 bytes --]
Hi Grant,
some comments below:
(by the way, have you tested this patch on hardware? I wonder because of the
SSOE-issue, but maybe it works despite the documentation.)
On Wed, Jun 17, 2009 at 08:55:01PM -0600, Grant Likely wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
>
> Adds support for the dedicated SPI device on the Freescale MPC5200(b)
> SoC.
>
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> ---
>
> Hi David,
>
> It's been a while since I've posted this, but I believe I've addressed
> all the outstanding comments against v3, and people are asking me for it.
> The pre-message stuff is all gone and the error handling should be
> better now.
>
> BTW, the premessage stuff was to handle a platform I had where some of
> the CS lines were controlled with a separate SPI transaction to the
> same SPI controller. It almost looks like an SPI bridge. It requires
> more thought before I try again.
>
> Being a new driver, it would be nice to get it into 2.6.31, but
> definitely not critical.
>
> g.
>
> drivers/spi/Kconfig | 8 +
> drivers/spi/Makefile | 1
> drivers/spi/mpc52xx_spi.c | 520 +++++++++++++++++++++++++++++++++++++++
> include/linux/spi/mpc52xx_spi.h | 10 +
> 4 files changed, 539 insertions(+), 0 deletions(-)
> create mode 100644 drivers/spi/mpc52xx_spi.c
> create mode 100644 include/linux/spi/mpc52xx_spi.h
>
>
> diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
> index 83a185d..1994bcd 100644
> --- a/drivers/spi/Kconfig
> +++ b/drivers/spi/Kconfig
> @@ -132,6 +132,14 @@ config SPI_LM70_LLP
> which interfaces to an LM70 temperature sensor using
> a parallel port.
>
> +config SPI_MPC52xx
> + tristate "Freescale MPC52xx SPI (non-PSC) controller support"
> + depends on PPC_MPC52xx && SPI
> + select SPI_MASTER_OF
> + help
> + This drivers supports the MPC52xx SPI controller in master SPI
> + mode.
> +
> config SPI_MPC52xx_PSC
> tristate "Freescale MPC52xx PSC SPI controller"
> depends on PPC_MPC52xx && EXPERIMENTAL
> diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
> index 5d04519..8de32c7 100644
> --- a/drivers/spi/Makefile
> +++ b/drivers/spi/Makefile
> @@ -24,6 +24,7 @@ obj-$(CONFIG_SPI_OMAP_UWIRE) += omap_uwire.o
> obj-$(CONFIG_SPI_OMAP24XX) += omap2_mcspi.o
> obj-$(CONFIG_SPI_ORION) += orion_spi.o
> obj-$(CONFIG_SPI_MPC52xx_PSC) += mpc52xx_psc_spi.o
> +obj-$(CONFIG_SPI_MPC52xx) += mpc52xx_spi.o
> obj-$(CONFIG_SPI_MPC83xx) += spi_mpc83xx.o
> obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o
> obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o
> diff --git a/drivers/spi/mpc52xx_spi.c b/drivers/spi/mpc52xx_spi.c
> new file mode 100644
> index 0000000..ef8379b
> --- /dev/null
> +++ b/drivers/spi/mpc52xx_spi.c
> @@ -0,0 +1,520 @@
> +/*
> + * MPC52xx SPI bus driver.
> + *
> + * Copyright (C) 2008 Secret Lab Technologies Ltd.
> + *
> + * This file is released under the GPLv2
> + *
> + * This is the driver for the MPC5200's dedicated SPI controller.
> + *
> + * Note: this driver does not support the MPC5200 PSC in SPI mode. For
> + * that driver see drivers/spi/mpc52xx_psc_spi.c
> + */
> +
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/errno.h>
> +#include <linux/of_platform.h>
> +#include <linux/interrupt.h>
> +#include <linux/delay.h>
> +#include <linux/spi/spi.h>
> +#include <linux/spi/mpc52xx_spi.h>
Is this still needed? See last comment...
> +#include <linux/of_spi.h>
> +#include <linux/io.h>
> +#include <asm/time.h>
Really asm?
> +#include <asm/mpc52xx.h>
> +
> +MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
> +MODULE_DESCRIPTION("MPC52xx SPI (non-PSC) Driver");
> +MODULE_LICENSE("GPL");
> +
> +/* Register offsets */
> +#define SPI_CTRL1 0x00
> +#define SPI_CTRL1_SPIE (1 << 7)
> +#define SPI_CTRL1_SPE (1 << 6)
> +#define SPI_CTRL1_MSTR (1 << 4)
> +#define SPI_CTRL1_CPOL (1 << 3)
> +#define SPI_CTRL1_CPHA (1 << 2)
> +#define SPI_CTRL1_SSOE (1 << 1)
> +#define SPI_CTRL1_LSBFE (1 << 0)
> +
> +#define SPI_CTRL2 0x01
> +#define SPI_BRR 0x04
> +
> +#define SPI_STATUS 0x05
> +#define SPI_STATUS_SPIF (1 << 7)
> +#define SPI_STATUS_WCOL (1 << 6)
> +#define SPI_STATUS_MODF (1 << 4)
> +
> +#define SPI_DATA 0x09
> +#define SPI_PORTDATA 0x0d
> +#define SPI_DATADIR 0x10
> +
> +/* FSM state return values */
> +#define FSM_STOP 0 /* Nothing more for the state machine to */
> + /* do. If something interesting happens */
> + /* then and IRQ will be received */
s/and/an/? Throughout the comments, there is sometimes a double space.
> +#define FSM_POLL 1 /* need to poll for completion, an IRQ is */
> + /* not expected */
> +#define FSM_CONTINUE 2 /* Keep iterating the state machine */
> +
> +/* Driver internal data */
> +struct mpc52xx_spi {
> + struct spi_master *master;
> + u32 sysclk;
unused?
> + void __iomem *regs;
> + int irq0; /* MODF irq */
> + int irq1; /* SPIF irq */
> + int ipb_freq;
unsigned int will suit it better IMHO.
> +
> + /* Statistics */
> + int msg_count;
> + int wcol_count;
> + int wcol_ticks;
> + u32 wcol_tx_timestamp;
> + int modf_count;
> + int byte_count;
Hmm, there isn't even a debug-printout for those. Putting #ifdef DEBUG around
them will be ugly. Well, I can't make up if this is just overhead or useful
debugging aid, so no real objection :)
> +
> + struct list_head queue; /* queue of pending messages */
> + spinlock_t lock;
> + struct work_struct work;
> +
> +
> + /* Details of current transfer (length, and buffer pointers) */
> + struct spi_message *message; /* current message */
> + struct spi_transfer *transfer; /* current transfer */
> + int (*state)(int irq, struct mpc52xx_spi *ms, u8 status, u8 data);
> + int len;
> + int timestamp;
> + u8 *rx_buf;
> + const u8 *tx_buf;
> + int cs_change;
> +};
> +
> +/*
> + * CS control function
> + */
> +static void mpc52xx_spi_chipsel(struct mpc52xx_spi *ms, int value)
> +{
> + out_8(ms->regs + SPI_PORTDATA, value ? 0 : 0x08);
Magic value.
But I wonder more about the usage of the SS pin and if this chipsel is needed
at all (sadly I cannot test as I don't have any board with SPI connected to
that device). You define the SS-pin as output, but do not set the SSOE-bit.
More, you use the MODF-feature, so the SS-pin should be defined as input?
According to Table 17.3 in the PM, you have that pin defined as generic purpose
output.
> +}
> +
> +/*
> + * Start a new transfer. This is called both by the idle state
> + * for the first transfer in a message, and by the wait state when the
> + * previous transfer in a message is complete.
> + */
> +static void mpc52xx_spi_start_transfer(struct mpc52xx_spi *ms)
> +{
> + ms->rx_buf = ms->transfer->rx_buf;
> + ms->tx_buf = ms->transfer->tx_buf;
> + ms->len = ms->transfer->len;
> +
> + /* Activate the chip select */
> + if (ms->cs_change)
> + mpc52xx_spi_chipsel(ms, 1);
> + ms->cs_change = ms->transfer->cs_change;
> +
> + /* Write out the first byte */
> + ms->wcol_tx_timestamp = get_tbl();
> + if (ms->tx_buf)
> + out_8(ms->regs + SPI_DATA, *ms->tx_buf++);
> + else
> + out_8(ms->regs + SPI_DATA, 0);
> +}
> +
> +/* Forward declaration of state handlers */
> +static int mpc52xx_spi_fsmstate_transfer(int irq, struct mpc52xx_spi *ms,
> + u8 status, u8 data);
> +static int mpc52xx_spi_fsmstate_wait(int irq, struct mpc52xx_spi *ms,
> + u8 status, u8 data);
> +
> +/*
> + * IDLE state
> + *
> + * No transfers are in progress; if another transfer is pending then retrieve
> + * it and kick it off. Otherwise, stop processing the state machine
> + */
> +static int
> +mpc52xx_spi_fsmstate_idle(int irq, struct mpc52xx_spi *ms, u8 status, u8 data)
> +{
> + struct spi_device *spi;
> + int spr, sppr;
> + u8 ctrl1;
> +
> + if (status && (irq != NO_IRQ))
> + dev_err(&ms->master->dev, "spurious irq, status=0x%.2x\n",
> + status);
> +
> + /* Check if there is another transfer waiting. */
> + if (list_empty(&ms->queue))
> + return FSM_STOP;
> +
> + /* get the head of the queue */
> + ms->message = list_first_entry(&ms->queue, struct spi_message, queue);
> + list_del_init(&ms->message->queue);
> +
> + /* Setup the controller parameters */
> + ctrl1 = SPI_CTRL1_SPIE | SPI_CTRL1_SPE | SPI_CTRL1_MSTR;
> + spi = ms->message->spi;
> + if (spi->mode & SPI_CPHA)
> + ctrl1 |= SPI_CTRL1_CPHA;
> + if (spi->mode & SPI_CPOL)
> + ctrl1 |= SPI_CTRL1_CPOL;
> + if (spi->mode & SPI_LSB_FIRST)
> + ctrl1 |= SPI_CTRL1_LSBFE;
> + out_8(ms->regs + SPI_CTRL1, ctrl1);
> +
> + /* Setup the controller speed */
> + /* minimum divider is '2'. Also, add '1' to force rounding the
> + * divider up. */
> + sppr = ((ms->ipb_freq / ms->message->spi->max_speed_hz) + 1) >> 1;
> + spr = 0;
> + if (sppr < 1)
> + sppr = 1;
> + while (((sppr - 1) & ~0x7) != 0) {
> + sppr = (sppr + 1) >> 1; /* add '1' to force rounding up */
> + spr++;
> + }
> + sppr--; /* sppr quantity in register is offset by 1 */
> + if (spr > 7) {
> + /* Don't overrun limits of SPI baudrate register */
> + spr = 7;
> + sppr = 7;
> + }
> + out_8(ms->regs + SPI_BRR, sppr << 4 | spr); /* Set speed */
> +
> + ms->cs_change = 1;
> + ms->transfer = container_of(ms->message->transfers.next,
> + struct spi_transfer, transfer_list);
> +
> + mpc52xx_spi_start_transfer(ms);
> + ms->state = mpc52xx_spi_fsmstate_transfer;
> +
> + return FSM_CONTINUE;
> +}
> +
> +/*
> + * TRANSFER state
> + *
> + * In the middle of a transfer. If the SPI core has completed processing
> + * a byte, then read out the received data and write out the next byte
> + * (unless this transfer is finished; in which case go on to the wait
> + * state)
> + */
> +static int mpc52xx_spi_fsmstate_transfer(int irq, struct mpc52xx_spi *ms,
> + u8 status, u8 data)
> +{
> + if (!status)
> + return ms->irq0 ? FSM_STOP : FSM_POLL;
> +
> + if (status & SPI_STATUS_WCOL) {
> + /* The SPI controller is stoopid. At slower speeds, it may
> + * raise the SPIF flag before the state machine is actually
> + * finished, which causes a collision (internal to the state
> + * machine only). The manual recommends inserting a delay
> + * between receiving the interrupt and sending the next byte,
> + * but it can also be worked around simply by retrying the
> + * transfer which is what we do here. */
> + ms->wcol_count++;
> + ms->wcol_ticks += get_tbl() - ms->wcol_tx_timestamp;
> + ms->wcol_tx_timestamp = get_tbl();
> + data = 0;
> + if (ms->tx_buf)
> + data = *(ms->tx_buf-1);
spaces around operator.
> + out_8(ms->regs + SPI_DATA, data); /* try again */
> + return FSM_CONTINUE;
> + } else if (status & SPI_STATUS_MODF) {
> + ms->modf_count++;
> + dev_err(&ms->master->dev, "mode fault\n");
> + mpc52xx_spi_chipsel(ms, 0);
> + ms->message->status = -EIO;
> + ms->message->complete(ms->message->context);
> + ms->state = mpc52xx_spi_fsmstate_idle;
> + return FSM_CONTINUE;
> + }
> +
> + /* Read data out of the spi device */
> + ms->byte_count++;
> + if (ms->rx_buf)
> + *ms->rx_buf++ = data;
> +
> + /* Is the transfer complete? */
> + ms->len--;
> + if (ms->len == 0) {
> + ms->timestamp = get_tbl();
> + ms->timestamp += ms->transfer->delay_usecs * tb_ticks_per_usec;
> + ms->state = mpc52xx_spi_fsmstate_wait;
> + return FSM_CONTINUE;
> + }
> +
> + /* Write out the next byte */
> + ms->wcol_tx_timestamp = get_tbl();
> + if (ms->tx_buf)
> + out_8(ms->regs + SPI_DATA, *ms->tx_buf++);
> + else
> + out_8(ms->regs + SPI_DATA, 0);
> +
> + return FSM_CONTINUE;
> +}
> +
> +/*
> + * WAIT state
> + *
> + * A transfer has completed; need to wait for the delay period to complete
> + * before starting the next transfer
> + */
> +static int
> +mpc52xx_spi_fsmstate_wait(int irq, struct mpc52xx_spi *ms, u8 status, u8 data)
> +{
> + if (status && irq)
> + dev_err(&ms->master->dev, "spurious irq, status=0x%.2x\n",
> + status);
> +
> + if (((int)get_tbl()) - ms->timestamp < 0)
> + return FSM_POLL;
> +
> + ms->message->actual_length += ms->transfer->len;
> +
> + /* Check if there is another transfer in this message. If there
> + * aren't then deactivate CS, notify sender, and drop back to idle
> + * to start the next message. */
> + if (ms->transfer->transfer_list.next == &ms->message->transfers) {
> + ms->msg_count++;
> + mpc52xx_spi_chipsel(ms, 0);
> + ms->message->status = 0;
> + ms->message->complete(ms->message->context);
> + ms->state = mpc52xx_spi_fsmstate_idle;
> + return FSM_CONTINUE;
> + }
> +
> + /* There is another transfer; kick it off */
> +
> + if (ms->cs_change)
> + mpc52xx_spi_chipsel(ms, 0);
> +
> + ms->transfer = container_of(ms->transfer->transfer_list.next,
> + struct spi_transfer, transfer_list);
> + mpc52xx_spi_start_transfer(ms);
> + ms->state = mpc52xx_spi_fsmstate_transfer;
> + return FSM_CONTINUE;
> +}
> +
> +/**
> + * mpc52xx_spi_fsm_process - Finite State Machine iteration function
> + * @irq: irq number that triggered the FSM or 0 for polling
> + * @ms: pointer to mpc52xx_spi driver data
> + */
> +static void mpc52xx_spi_fsm_process(int irq, struct mpc52xx_spi *ms)
> +{
> + int rc = FSM_CONTINUE;
> + u8 status, data;
> +
> + while (rc == FSM_CONTINUE) {
> + /* Interrupt cleared by read of STATUS followed by
> + * read of DATA registers */
> + status = in_8(ms->regs + SPI_STATUS);
> + data = in_8(ms->regs + SPI_DATA);
> + rc = ms->state(irq, ms, status, data);
> + }
> +
> + if (rc == FSM_POLL)
> + schedule_work(&ms->work);
> +}
> +
> +/**
> + * mpc52xx_spi_irq - IRQ handler
> + */
> +static irqreturn_t mpc52xx_spi_irq(int irq, void *_ms)
> +{
> + struct mpc52xx_spi *ms = _ms;
> + spin_lock(&ms->lock);
> + mpc52xx_spi_fsm_process(irq, ms);
> + spin_unlock(&ms->lock);
> + return IRQ_HANDLED;
> +}
> +
> +/**
> + * mpc52xx_spi_wq - Workqueue function for polling the state machine
> + */
> +static void mpc52xx_spi_wq(struct work_struct *work)
> +{
> + struct mpc52xx_spi *ms = container_of(work, struct mpc52xx_spi, work);
> + unsigned long flags;
> +
> + spin_lock_irqsave(&ms->lock, flags);
> + mpc52xx_spi_fsm_process(0, ms);
> + spin_unlock_irqrestore(&ms->lock, flags);
> +}
> +
> +/*
> + * spi_master ops
> + */
> +
> +static int mpc52xx_spi_setup(struct spi_device *spi)
> +{
> + if (spi->bits_per_word % 8)
> + return -EINVAL;
> +
> + if (spi->mode & ~(SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST))
> + return -EINVAL;
> +
> + if (spi->chip_select >= spi->master->num_chipselect)
> + return -EINVAL;
> +
> + return 0;
> +}
> +
> +static int mpc52xx_spi_transfer(struct spi_device *spi, struct spi_message *m)
> +{
> + struct mpc52xx_spi *ms = spi_master_get_devdata(spi->master);
> + unsigned long flags;
> +
> + m->actual_length = 0;
> + m->status = -EINPROGRESS;
> +
> + spin_lock_irqsave(&ms->lock, flags);
> + list_add_tail(&m->queue, &ms->queue);
> + spin_unlock_irqrestore(&ms->lock, flags);
> + schedule_work(&ms->work);
> +
> + return 0;
> +}
> +
> +/*
> + * OF Platform Bus Binding
> + */
> +static int __devinit mpc52xx_spi_probe(struct of_device *op,
> + const struct of_device_id *match)
> +{
> + struct spi_master *master;
> + struct mpc52xx_spi *ms;
> + void __iomem *regs;
> + int rc;
> +
> + /* MMIO registers */
> + dev_dbg(&op->dev, "probing mpc5200 SPI device\n");
> + regs = of_iomap(op->node, 0);
> + if (!regs)
> + return -ENODEV;
> +
> + /* initialize the device */
> + out_8(regs+SPI_CTRL1, SPI_CTRL1_SPIE | SPI_CTRL1_SPE | SPI_CTRL1_MSTR);
spaces around operator.
> + out_8(regs + SPI_CTRL2, 0x0);
> + out_8(regs + SPI_DATADIR, 0xe); /* Set output pins */
> + out_8(regs + SPI_PORTDATA, 0x8); /* Deassert /SS signal */
> +
> + /* Clear the status register and re-read it to check for a MODF
> + * failure. This driver cannot currently handle multiple masters
> + * on the SPI bus. This fault will also occur if the SPI signals
> + * are not connected to any pins (port_config setting) */
> + in_8(regs + SPI_STATUS);
> + in_8(regs + SPI_DATA);
> + if (in_8(regs + SPI_STATUS) & SPI_STATUS_MODF) {
> + dev_err(&op->dev, "mode fault; is port_config correct?\n");
> + rc = -EIO;
> + goto err_init;
> + }
> +
> + dev_dbg(&op->dev, "allocating spi_master struct\n");
> + master = spi_alloc_master(&op->dev, sizeof *ms);
> + if (!master) {
> + rc = -ENOMEM;
> + goto err_alloc;
> + }
> + master->bus_num = -1;
> + master->num_chipselect = 1;
> + master->setup = mpc52xx_spi_setup;
> + master->transfer = mpc52xx_spi_transfer;
> + dev_set_drvdata(&op->dev, master);
> +
> + ms = spi_master_get_devdata(master);
> + ms->master = master;
> + ms->regs = regs;
> + ms->irq0 = irq_of_parse_and_map(op->node, 0);
> + ms->irq1 = irq_of_parse_and_map(op->node, 1);
> + ms->state = mpc52xx_spi_fsmstate_idle;
> + ms->ipb_freq = mpc5xxx_get_bus_frequency(op->node);
> + spin_lock_init(&ms->lock);
> + INIT_LIST_HEAD(&ms->queue);
> + INIT_WORK(&ms->work, mpc52xx_spi_wq);
> +
> + /* Decide if interrupts can be used */
> + if (ms->irq0 && ms->irq1) {
> + rc = request_irq(ms->irq0, mpc52xx_spi_irq, IRQF_SAMPLE_RANDOM,
> + "mpc5200-spi-modf", ms);
> + rc |= request_irq(ms->irq1, mpc52xx_spi_irq, IRQF_SAMPLE_RANDOM,
> + "mpc5200-spi-spiF", ms);
Capital 'F' wanted?
> + if (rc) {
> + free_irq(ms->irq0, ms);
> + free_irq(ms->irq1, ms);
> + ms->irq0 = ms->irq1 = 0;
> + }
> + } else {
> + /* operate in polled mode */
> + ms->irq0 = ms->irq1 = 0;
> + }
> +
> + if (!ms->irq0)
> + dev_info(&op->dev, "using polled mode\n");
> +
> + dev_dbg(&op->dev, "registering spi_master struct\n");
> + rc = spi_register_master(master);
> + if (rc)
> + goto err_register;
> +
> + of_register_spi_devices(master, op->node);
> + dev_info(&ms->master->dev, "registered MPC5200 SPI bus\n");
> +
> + return rc;
> +
> + err_register:
> + dev_err(&ms->master->dev, "initialization failed\n");
> + spi_master_put(master);
> + err_alloc:
> + err_init:
> + iounmap(regs);
> + return rc;
> +}
> +
> +static int __devexit mpc52xx_spi_remove(struct of_device *op)
> +{
> + struct spi_master *master = dev_get_drvdata(&op->dev);
> + struct mpc52xx_spi *ms = spi_master_get_devdata(master);
> +
> + free_irq(ms->irq0, ms);
> + free_irq(ms->irq1, ms);
> +
> + spi_unregister_master(master);
> + spi_master_put(master);
> + iounmap(ms->regs);
> +
> + return 0;
> +}
> +
> +static struct of_device_id mpc52xx_spi_match[] __devinitdata = {
> + { .compatible = "fsl,mpc5200-spi", },
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, mpc52xx_spi_match);
> +
> +static struct of_platform_driver mpc52xx_spi_of_driver = {
> + .owner = THIS_MODULE,
> + .name = "mpc52xx-spi",
> + .match_table = mpc52xx_spi_match,
> + .probe = mpc52xx_spi_probe,
> + .remove = __exit_p(mpc52xx_spi_remove),
> +};
> +
> +static int __init mpc52xx_spi_init(void)
> +{
> + return of_register_platform_driver(&mpc52xx_spi_of_driver);
> +}
> +module_init(mpc52xx_spi_init);
> +
> +static void __exit mpc52xx_spi_exit(void)
> +{
> + of_unregister_platform_driver(&mpc52xx_spi_of_driver);
> +}
> +module_exit(mpc52xx_spi_exit);
> +
> diff --git a/include/linux/spi/mpc52xx_spi.h b/include/linux/spi/mpc52xx_spi.h
> new file mode 100644
> index 0000000..d1004cf
> --- /dev/null
> +++ b/include/linux/spi/mpc52xx_spi.h
> @@ -0,0 +1,10 @@
> +
> +#ifndef INCLUDE_MPC5200_SPI_H
> +#define INCLUDE_MPC5200_SPI_H
> +
> +extern void mpc52xx_spi_set_premessage_hook(struct spi_master *master,
> + void (*hook)(struct spi_message *m,
> + void *context),
> + void *hook_context);
> +
> +#endif
This can be dropped for now and reintroduced when needed, I think.
>
>
> ------------------------------------------------------------------------------
> Crystal Reports - New Free Runtime and 30 Day Trial
> Check out the new simplified licensing option that enables unlimited
> royalty-free distribution of the report engine for externally facing
> server and web deployment.
> http://p.sf.net/sfu/businessobjects
> _______________________________________________
> spi-devel-general mailing list
> spi-devel-general@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/spi-devel-general
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* [PATCH -mm][POWERPC] mpc8xxx : allow SPI without cs.
From: Rini van Zetten @ 2009-06-18 6:19 UTC (permalink / raw)
To: Kumar Gala, spi-devel-general, linuxppc-dev list
This patch adds the possibility to have a spi device without a cs.
For example, the dts file should look something like this:
spi-controller {
gpios = <&pio1 1 0 /* cs0 */
0 /* cs1, no GPIO */
&pio2 2 0>; /* cs2 */
Signed-off-by: Rini van Zetten <rini@arvoo.nl>
---
Changes :
patch against 2.6.30-rc8-mm1
--- drivers/spi/spi_mpc8xxx.c.org 2009-06-12 10:45:21.000000000 +0200
+++ drivers/spi/spi_mpc8xxx.c 2009-06-12 10:54:48.000000000 +0200
@@ -666,9 +666,10 @@ static void mpc8xxx_spi_cs_control(struc
struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(dev->platform_data);
u16 cs = spi->chip_select;
int gpio = pinfo->gpios[cs];
- bool alow = pinfo->alow_flags[cs];
-
- gpio_set_value(gpio, on ^ alow);
+ if (gpio != -EEXIST) {
+ bool alow = pinfo->alow_flags[cs];
+ gpio_set_value(gpio, on ^ alow);
+ }
}
static int of_mpc8xxx_spi_get_chipselects(struct device *dev)
@@ -707,27 +708,29 @@ static int of_mpc8xxx_spi_get_chipselect
enum of_gpio_flags flags;
gpio = of_get_gpio_flags(np, i, &flags);
- if (!gpio_is_valid(gpio)) {
+ if (gpio_is_valid(gpio)) {
+ ret = gpio_request(gpio, dev_name(dev));
+ if (ret) {
+ dev_err(dev, "can't request gpio #%d: %d\n", i, ret);
+ goto err_loop;
+ }
+
+ pinfo->gpios[i] = gpio;
+ pinfo->alow_flags[i] = flags & OF_GPIO_ACTIVE_LOW;
+
+ ret = gpio_direction_output(pinfo->gpios[i],
+ pinfo->alow_flags[i]);
+ if (ret) {
+ dev_err(dev, "can't set output direction for gpio "
+ "#%d: %d\n", i, ret);
+ goto err_loop;
+ }
+ } else if (gpio == -EEXIST) {
+ pinfo->gpios[i] = -EEXIST;
+ } else {
dev_err(dev, "invalid gpio #%d: %d\n", i, gpio);
goto err_loop;
}
-
- ret = gpio_request(gpio, dev_name(dev));
- if (ret) {
- dev_err(dev, "can't request gpio #%d: %d\n", i, ret);
- goto err_loop;
- }
-
- pinfo->gpios[i] = gpio;
- pinfo->alow_flags[i] = flags & OF_GPIO_ACTIVE_LOW;
-
- ret = gpio_direction_output(pinfo->gpios[i],
- pinfo->alow_flags[i]);
- if (ret) {
- dev_err(dev, "can't set output direction for gpio "
- "#%d: %d\n", i, ret);
- goto err_loop;
- }
}
pdata->max_chipselect = ngpios;
--
--
Rini van Zetten
Senior Software Engineer
-------------------------
ARVOO Engineering B.V.
Tasveld 13
3417 XS Montfoort
The Netherlands
E-mail : <mailto:rini@arvoo.com> Rini van Zetten
Web : www.arvoo.com
^ permalink raw reply
* [PATCH 7/7] powerpc: Use pr_devel() in arch/powerpc/mm/mmu_context_nohash.c
From: Michael Ellerman @ 2009-06-18 4:13 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1fdc1f0bb73b6ff2db7f9b394331d5ef5dfc4cb5.1245298429.git.michael@ellerman.id.au>
pr_debug() can now result in code being generated even when DEBUG
is not defined. That's not really desirable in some places.
With CONFIG_DYNAMIC_DEBUG=y:
size before:
text data bss dec hex filename
1508 48 28 1584 630 powerpc/mm/mmu_context_nohash.o
size after:
text data bss dec hex filename
1088 0 28 1116 45c powerpc/mm/mmu_context_nohash.o
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/mm/mmu_context_nohash.c | 16 ++++++++--------
1 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/mm/mmu_context_nohash.c b/arch/powerpc/mm/mmu_context_nohash.c
index 8343986..92a1971 100644
--- a/arch/powerpc/mm/mmu_context_nohash.c
+++ b/arch/powerpc/mm/mmu_context_nohash.c
@@ -89,7 +89,7 @@ static unsigned int steal_context_smp(unsigned int id)
id = first_context;
continue;
}
- pr_debug("[%d] steal context %d from mm @%p\n",
+ pr_devel("[%d] steal context %d from mm @%p\n",
smp_processor_id(), id, mm);
/* Mark this mm has having no context anymore */
@@ -126,7 +126,7 @@ static unsigned int steal_context_up(unsigned int id)
/* Pick up the victim mm */
mm = context_mm[id];
- pr_debug("[%d] steal context %d from mm @%p\n", cpu, id, mm);
+ pr_devel("[%d] steal context %d from mm @%p\n", cpu, id, mm);
/* Flush the TLB for that context */
local_flush_tlb_mm(mm);
@@ -180,7 +180,7 @@ void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next)
spin_lock(&context_lock);
#ifndef DEBUG_STEAL_ONLY
- pr_debug("[%d] activating context for mm @%p, active=%d, id=%d\n",
+ pr_devel("[%d] activating context for mm @%p, active=%d, id=%d\n",
cpu, next, next->context.active, next->context.id);
#endif
@@ -189,7 +189,7 @@ void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next)
next->context.active++;
if (prev) {
#ifndef DEBUG_STEAL_ONLY
- pr_debug(" old context %p active was: %d\n",
+ pr_devel(" old context %p active was: %d\n",
prev, prev->context.active);
#endif
WARN_ON(prev->context.active < 1);
@@ -236,7 +236,7 @@ void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next)
next->context.id = id;
#ifndef DEBUG_STEAL_ONLY
- pr_debug("[%d] picked up new id %d, nrf is now %d\n",
+ pr_devel("[%d] picked up new id %d, nrf is now %d\n",
cpu, id, nr_free_contexts);
#endif
@@ -247,7 +247,7 @@ void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next)
* local TLB for it and unmark it before we use it
*/
if (test_bit(id, stale_map[cpu])) {
- pr_debug("[%d] flushing stale context %d for mm @%p !\n",
+ pr_devel("[%d] flushing stale context %d for mm @%p !\n",
cpu, id, next);
local_flush_tlb_mm(next);
@@ -314,13 +314,13 @@ static int __cpuinit mmu_context_cpu_notify(struct notifier_block *self,
switch (action) {
case CPU_ONLINE:
case CPU_ONLINE_FROZEN:
- pr_debug("MMU: Allocating stale context map for CPU %d\n", cpu);
+ pr_devel("MMU: Allocating stale context map for CPU %d\n", cpu);
stale_map[cpu] = kzalloc(CTX_MAP_SIZE, GFP_KERNEL);
break;
#ifdef CONFIG_HOTPLUG_CPU
case CPU_DEAD:
case CPU_DEAD_FROZEN:
- pr_debug("MMU: Freeing stale context map for CPU %d\n", cpu);
+ pr_devel("MMU: Freeing stale context map for CPU %d\n", cpu);
kfree(stale_map[cpu]);
stale_map[cpu] = NULL;
break;
--
1.6.2.1
^ permalink raw reply related
* [PATCH 6/7] powerpc/pseries: Use pr_devel() in xics.c
From: Michael Ellerman @ 2009-06-18 4:13 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1fdc1f0bb73b6ff2db7f9b394331d5ef5dfc4cb5.1245298429.git.michael@ellerman.id.au>
pr_debug() can now result in code being generated even when DEBUG
is not defined. That's not really desirable in some places.
With CONFIG_DYNAMIC_DEBUG=y:
size before:
text data bss dec hex filename
7720 5488 296 13504 34c0 platforms/pseries/xics.o
size after:
text data bss dec hex filename
7535 5456 296 13287 33e7 platforms/pseries/xics.o
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/pseries/xics.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index be3581a..419f8a6 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -190,10 +190,10 @@ static void xics_unmask_irq(unsigned int virq)
int call_status;
int server;
- pr_debug("xics: unmask virq %d\n", virq);
+ pr_devel("xics: unmask virq %d\n", virq);
irq = (unsigned int)irq_map[virq].hwirq;
- pr_debug(" -> map to hwirq 0x%x\n", irq);
+ pr_devel(" -> map to hwirq 0x%x\n", irq);
if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
return;
@@ -252,7 +252,7 @@ static void xics_mask_irq(unsigned int virq)
{
unsigned int irq;
- pr_debug("xics: mask virq %d\n", virq);
+ pr_devel("xics: mask virq %d\n", virq);
irq = (unsigned int)irq_map[virq].hwirq;
if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
@@ -414,7 +414,7 @@ static int xics_host_match(struct irq_host *h, struct device_node *node)
static int xics_host_map(struct irq_host *h, unsigned int virq,
irq_hw_number_t hw)
{
- pr_debug("xics: map virq %d, hwirq 0x%lx\n", virq, hw);
+ pr_devel("xics: map virq %d, hwirq 0x%lx\n", virq, hw);
/* Insert the interrupt mapping into the radix tree for fast lookup */
irq_radix_revmap_insert(xics_host, virq, hw);
--
1.6.2.1
^ permalink raw reply related
* [PATCH 5/7] powerpc/cell: Use pr_devel() in axon_msi.c
From: Michael Ellerman @ 2009-06-18 4:13 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1fdc1f0bb73b6ff2db7f9b394331d5ef5dfc4cb5.1245298429.git.michael@ellerman.id.au>
pr_debug() can now result in code being generated even when DEBUG
is not defined. That's not really desirable in some places.
With CONFIG_DYNAMIC_DEBUG=y:
size before:
text data bss dec hex filename
7083 1616 0 8699 21fb arch/powerpc/../axon_msi.o
size after:
text data bss dec hex filename
5772 1208 0 6980 1b44 arch/powerpc/../axon_msi.o
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/cell/axon_msi.c | 22 +++++++++++-----------
1 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index c71498d..aca5741 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -85,7 +85,7 @@ static inline void axon_msi_debug_setup(struct device_node *dn,
static void msic_dcr_write(struct axon_msic *msic, unsigned int dcr_n, u32 val)
{
- pr_debug("axon_msi: dcr_write(0x%x, 0x%x)\n", val, dcr_n);
+ pr_devel("axon_msi: dcr_write(0x%x, 0x%x)\n", val, dcr_n);
dcr_write(msic->dcr_host, dcr_n, val);
}
@@ -98,7 +98,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
int retry = 0;
write_offset = dcr_read(msic->dcr_host, MSIC_WRITE_OFFSET_REG);
- pr_debug("axon_msi: original write_offset 0x%x\n", write_offset);
+ pr_devel("axon_msi: original write_offset 0x%x\n", write_offset);
/* write_offset doesn't wrap properly, so we have to mask it */
write_offset &= MSIC_FIFO_SIZE_MASK;
@@ -108,7 +108,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
msi = le32_to_cpu(msic->fifo_virt[idx]);
msi &= 0xFFFF;
- pr_debug("axon_msi: woff %x roff %x msi %x\n",
+ pr_devel("axon_msi: woff %x roff %x msi %x\n",
write_offset, msic->read_offset, msi);
if (msi < NR_IRQS && irq_map[msi].host == msic->irq_host) {
@@ -123,12 +123,12 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
*/
udelay(1);
retry++;
- pr_debug("axon_msi: invalid irq 0x%x!\n", msi);
+ pr_devel("axon_msi: invalid irq 0x%x!\n", msi);
continue;
}
if (retry) {
- pr_debug("axon_msi: late irq 0x%x, retry %d\n",
+ pr_devel("axon_msi: late irq 0x%x, retry %d\n",
msi, retry);
retry = 0;
}
@@ -332,7 +332,7 @@ static int axon_msi_shutdown(struct of_device *device)
struct axon_msic *msic = dev_get_drvdata(&device->dev);
u32 tmp;
- pr_debug("axon_msi: disabling %s\n",
+ pr_devel("axon_msi: disabling %s\n",
msic->irq_host->of_node->full_name);
tmp = dcr_read(msic->dcr_host, MSIC_CTRL_REG);
tmp &= ~MSIC_CTRL_ENABLE & ~MSIC_CTRL_IRQ_ENABLE;
@@ -349,7 +349,7 @@ static int axon_msi_probe(struct of_device *device,
unsigned int virq;
int dcr_base, dcr_len;
- pr_debug("axon_msi: setting up dn %s\n", dn->full_name);
+ pr_devel("axon_msi: setting up dn %s\n", dn->full_name);
msic = kzalloc(sizeof(struct axon_msic), GFP_KERNEL);
if (!msic) {
@@ -403,7 +403,7 @@ static int axon_msi_probe(struct of_device *device,
set_irq_data(virq, msic);
set_irq_chained_handler(virq, axon_msi_cascade);
- pr_debug("axon_msi: irq 0x%x setup for axon_msi\n", virq);
+ pr_devel("axon_msi: irq 0x%x setup for axon_msi\n", virq);
/* Enable the MSIC hardware */
msic_dcr_write(msic, MSIC_BASE_ADDR_HI_REG, msic->fifo_phys >> 32);
@@ -484,13 +484,13 @@ void axon_msi_debug_setup(struct device_node *dn, struct axon_msic *msic)
addr = of_translate_address(dn, of_get_property(dn, "reg", NULL));
if (addr == OF_BAD_ADDR) {
- pr_debug("axon_msi: couldn't translate reg property\n");
+ pr_devel("axon_msi: couldn't translate reg property\n");
return;
}
msic->trigger = ioremap(addr, 0x4);
if (!msic->trigger) {
- pr_debug("axon_msi: ioremap failed\n");
+ pr_devel("axon_msi: ioremap failed\n");
return;
}
@@ -498,7 +498,7 @@ void axon_msi_debug_setup(struct device_node *dn, struct axon_msic *msic)
if (!debugfs_create_file(name, 0600, powerpc_debugfs_root,
msic, &fops_msic)) {
- pr_debug("axon_msi: debugfs_create_file failed!\n");
+ pr_devel("axon_msi: debugfs_create_file failed!\n");
return;
}
}
--
1.6.2.1
^ permalink raw reply related
* [PATCH 4/7] powerpc: Use pr_devel() in do_dcache_icache_coherency()
From: Michael Ellerman @ 2009-06-18 4:13 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1fdc1f0bb73b6ff2db7f9b394331d5ef5dfc4cb5.1245298429.git.michael@ellerman.id.au>
pr_debug() can now result in code being generated even when DEBUG
is not defined. That's not really desirable in some places.
With CONFIG_DYNAMIC_DEBUG=y:
size before:
text data bss dec hex filename
2036 368 8 2412 96c arch/powerpc/mm/pgtable.o
size after:
text data bss dec hex filename
1677 248 8 1933 78d arch/powerpc/mm/pgtable.o
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/mm/pgtable.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index ae1d67c..627767d 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -129,12 +129,12 @@ static pte_t do_dcache_icache_coherency(pte_t pte)
page = pfn_to_page(pfn);
if (!PageReserved(page) && !test_bit(PG_arch_1, &page->flags)) {
- pr_debug("do_dcache_icache_coherency... flushing\n");
+ pr_devel("do_dcache_icache_coherency... flushing\n");
flush_dcache_icache_page(page);
set_bit(PG_arch_1, &page->flags);
}
else
- pr_debug("do_dcache_icache_coherency... already clean\n");
+ pr_devel("do_dcache_icache_coherency... already clean\n");
return __pte(pte_val(pte) | _PAGE_HWEXEC);
}
--
1.6.2.1
^ permalink raw reply related
* [PATCH 3/7] powerpc: Cleanup & use pr_devel() in arch/powerpc/mm/slb.c
From: Michael Ellerman @ 2009-06-18 4:13 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1fdc1f0bb73b6ff2db7f9b394331d5ef5dfc4cb5.1245298429.git.michael@ellerman.id.au>
pr_debug() can now result in code being generated even when DEBUG
is not defined. That's not really desirable in some places.
With CONFIG_DYNAMIC_DEBUG=y:
size before:
text data bss dec hex filename
3261 416 4 3681 e61 arch/powerpc/mm/slb.o
size after:
text data bss dec hex filename
2861 248 4 3113 c29 arch/powerpc/mm/slb.o
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/mm/slb.c | 13 +++----------
1 files changed, 3 insertions(+), 10 deletions(-)
diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c
index 3b52c80..5b7038f 100644
--- a/arch/powerpc/mm/slb.c
+++ b/arch/powerpc/mm/slb.c
@@ -14,8 +14,6 @@
* 2 of the License, or (at your option) any later version.
*/
-#undef DEBUG
-
#include <asm/pgtable.h>
#include <asm/mmu.h>
#include <asm/mmu_context.h>
@@ -27,11 +25,6 @@
#include <linux/compiler.h>
#include <asm/udbg.h>
-#ifdef DEBUG
-#define DBG(fmt...) printk(fmt)
-#else
-#define DBG pr_debug
-#endif
extern void slb_allocate_realmode(unsigned long ea);
extern void slb_allocate_user(unsigned long ea);
@@ -285,13 +278,13 @@ void slb_initialize(void)
patch_slb_encoding(slb_compare_rr_to_size,
mmu_slb_size);
- DBG("SLB: linear LLP = %04lx\n", linear_llp);
- DBG("SLB: io LLP = %04lx\n", io_llp);
+ pr_devel("SLB: linear LLP = %04lx\n", linear_llp);
+ pr_devel("SLB: io LLP = %04lx\n", io_llp);
#ifdef CONFIG_SPARSEMEM_VMEMMAP
patch_slb_encoding(slb_miss_kernel_load_vmemmap,
SLB_VSID_KERNEL | vmemmap_llp);
- DBG("SLB: vmemmap LLP = %04lx\n", vmemmap_llp);
+ pr_devel("SLB: vmemmap LLP = %04lx\n", vmemmap_llp);
#endif
}
--
1.6.2.1
^ permalink raw reply related
* [PATCH 2/7] powerpc: Use pr_devel() in arch/powerpc/mm/gup.c
From: Michael Ellerman @ 2009-06-18 4:13 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1fdc1f0bb73b6ff2db7f9b394331d5ef5dfc4cb5.1245298429.git.michael@ellerman.id.au>
pr_debug() can now result in code being generated even when DEBUG
is not defined. That's not really desirable in some places.
With CONFIG_DYNAMIC_DEBUG=y:
size before:
text data bss dec hex filename
3252 384 0 3636 e34 arch/powerpc/mm/gup.o
size after:
text data bss dec hex filename
2576 96 0 2672 a70 arch/powerpc/mm/gup.o
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/mm/gup.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/mm/gup.c b/arch/powerpc/mm/gup.c
index bc400c7..bc122a1 100644
--- a/arch/powerpc/mm/gup.c
+++ b/arch/powerpc/mm/gup.c
@@ -159,7 +159,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
int psize;
#endif
- pr_debug("%s(%lx,%x,%s)\n", __func__, start, nr_pages, write ? "write" : "read");
+ pr_devel("%s(%lx,%x,%s)\n", __func__, start, nr_pages, write ? "write" : "read");
start &= PAGE_MASK;
addr = start;
@@ -170,7 +170,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
start, len)))
goto slow_irqon;
- pr_debug(" aligned: %lx .. %lx\n", start, end);
+ pr_devel(" aligned: %lx .. %lx\n", start, end);
#ifdef CONFIG_HUGETLB_PAGE
/* We bail out on slice boundary crossing when hugetlb is
@@ -234,7 +234,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
do {
VM_BUG_ON(shift != mmu_psize_defs[get_slice_psize(mm, a)].shift);
ptep = huge_pte_offset(mm, a);
- pr_debug(" %016lx: huge ptep %p\n", a, ptep);
+ pr_devel(" %016lx: huge ptep %p\n", a, ptep);
if (!ptep || !gup_huge_pte(ptep, hstate, &a, end, write, pages,
&nr))
goto slow;
@@ -249,7 +249,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
#ifdef CONFIG_PPC64
VM_BUG_ON(shift != mmu_psize_defs[get_slice_psize(mm, addr)].shift);
#endif
- pr_debug(" %016lx: normal pgd %p\n", addr,
+ pr_devel(" %016lx: normal pgd %p\n", addr,
(void *)pgd_val(pgd));
next = pgd_addr_end(addr, end);
if (pgd_none(pgd))
@@ -269,7 +269,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
slow:
local_irq_enable();
slow_irqon:
- pr_debug(" slow path ! nr = %d\n", nr);
+ pr_devel(" slow path ! nr = %d\n", nr);
/* Try to get the remaining pages with get_user_pages */
start += nr << PAGE_SHIFT;
--
1.6.2.1
^ permalink raw reply related
* [PATCH 1/7] powerpc/pseries: Use pr_devel() in pseries LPAR HPTE routines
From: Michael Ellerman @ 2009-06-18 4:13 UTC (permalink / raw)
To: linuxppc-dev
pr_debug() can now result in code being generated even when DEBUG
is not defined. That's not really desirable in some places.
In particular, pSeries_lpar_hpte_insert() goes from 185 instructions
to 77 instructions as a result of this patch. Luckily that code
isn't called very often ...
With CONFIG_DYNAMIC_DEBUG=y:
size before:
text data bss dec hex filename
7284 1552 296 9132 23ac platforms/pseries/lpar.o
size after:
text data bss dec hex filename
5806 1096 296 7198 1c1e platforms/pseries/lpar.o
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/platforms/pseries/lpar.c | 18 +++++++++---------
1 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index e3139fa..903eb9e 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -286,7 +286,7 @@ static long pSeries_lpar_hpte_insert(unsigned long hpte_group,
unsigned long hpte_v, hpte_r;
if (!(vflags & HPTE_V_BOLTED))
- pr_debug("hpte_insert(group=%lx, va=%016lx, pa=%016lx, "
+ pr_devel("hpte_insert(group=%lx, va=%016lx, pa=%016lx, "
"rflags=%lx, vflags=%lx, psize=%d)\n",
hpte_group, va, pa, rflags, vflags, psize);
@@ -294,7 +294,7 @@ static long pSeries_lpar_hpte_insert(unsigned long hpte_group,
hpte_r = hpte_encode_r(pa, psize) | rflags;
if (!(vflags & HPTE_V_BOLTED))
- pr_debug(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r);
+ pr_devel(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r);
/* Now fill in the actual HPTE */
/* Set CEC cookie to 0 */
@@ -311,7 +311,7 @@ static long pSeries_lpar_hpte_insert(unsigned long hpte_group,
lpar_rc = plpar_pte_enter(flags, hpte_group, hpte_v, hpte_r, &slot);
if (unlikely(lpar_rc == H_PTEG_FULL)) {
if (!(vflags & HPTE_V_BOLTED))
- pr_debug(" full\n");
+ pr_devel(" full\n");
return -1;
}
@@ -322,11 +322,11 @@ static long pSeries_lpar_hpte_insert(unsigned long hpte_group,
*/
if (unlikely(lpar_rc != H_SUCCESS)) {
if (!(vflags & HPTE_V_BOLTED))
- pr_debug(" lpar err %lu\n", lpar_rc);
+ pr_devel(" lpar err %lu\n", lpar_rc);
return -2;
}
if (!(vflags & HPTE_V_BOLTED))
- pr_debug(" -> slot: %lu\n", slot & 7);
+ pr_devel(" -> slot: %lu\n", slot & 7);
/* Because of iSeries, we have to pass down the secondary
* bucket bit here as well
@@ -418,17 +418,17 @@ static long pSeries_lpar_hpte_updatepp(unsigned long slot,
want_v = hpte_encode_avpn(va, psize, ssize);
- pr_debug(" update: avpnv=%016lx, hash=%016lx, f=%lx, psize: %d ...",
+ pr_devel(" update: avpnv=%016lx, hash=%016lx, f=%lx, psize: %d ...",
want_v, slot, flags, psize);
lpar_rc = plpar_pte_protect(flags, slot, want_v);
if (lpar_rc == H_NOT_FOUND) {
- pr_debug("not found !\n");
+ pr_devel("not found !\n");
return -1;
}
- pr_debug("ok\n");
+ pr_devel("ok\n");
BUG_ON(lpar_rc != H_SUCCESS);
@@ -503,7 +503,7 @@ static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
unsigned long lpar_rc;
unsigned long dummy1, dummy2;
- pr_debug(" inval : slot=%lx, va=%016lx, psize: %d, local: %d\n",
+ pr_devel(" inval : slot=%lx, va=%016lx, psize: %d, local: %d\n",
slot, va, psize, local);
want_v = hpte_encode_avpn(va, psize, ssize);
--
1.6.2.1
^ permalink raw reply related
* [PATCH] powerpc: Add irqtrace support for 32-bit powerpc (v2)
From: Benjamin Herrenschmidt @ 2009-06-18 3:43 UTC (permalink / raw)
To: linuxppc-dev
Based on initial work from: Dale Farnsworth <dale@farnsworth.org>
Add the low level irq tracing hooks for 32-bit powerpc needed
to enable full lockdep functionality.
The approach taken to deal with the code in entry_32.S is that
we don't trace all the transitions of MSR:EE when we just turn
it off to peek at TI_FLAGS without races. Only when we are
calling into C code or returning from exceptions with a state
that have changed from what lockdep thinks.
There's a little bugger though: If we take an exception that
keeps interrupts enabled (such as an alignment exception) while
interrupts are enabled, we will call trace_hardirqs_on() on the
way back spurriously. Not a big deal, but to get rid of it would
require remembering in pt_regs that the exception was one of the
type that kept interrupts enabled which we don't know at this
stage. (Well, we could test all cases for regs->trap but that
sucks too much).
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
This one fixes a bug, trace_hardirqs_on was too late in the
restore: code path and would clobber things. This boots fine
now on a PowerBook.
arch/powerpc/Kconfig | 1
arch/powerpc/include/asm/hw_irq.h | 20 ++---
arch/powerpc/kernel/entry_32.S | 127 ++++++++++++++++++++++++++++++++++++--
arch/powerpc/kernel/setup_32.c | 2
arch/powerpc/kernel/udbg.c | 1
5 files changed, 136 insertions(+), 15 deletions(-)
--- linux-work.orig/arch/powerpc/Kconfig 2009-06-18 13:21:29.000000000 +1000
+++ linux-work/arch/powerpc/Kconfig 2009-06-18 13:21:39.000000000 +1000
@@ -62,7 +62,6 @@ config HAVE_LATENCYTOP_SUPPORT
config TRACE_IRQFLAGS_SUPPORT
bool
- depends on PPC64
default y
config LOCKDEP_SUPPORT
Index: linux-work/arch/powerpc/kernel/entry_32.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/entry_32.S 2009-06-18 13:21:29.000000000 +1000
+++ linux-work/arch/powerpc/kernel/entry_32.S 2009-06-18 13:36:41.000000000 +1000
@@ -191,11 +191,49 @@ transfer_to_handler_cont:
mflr r9
lwz r11,0(r9) /* virtual address of handler */
lwz r9,4(r9) /* where to go when done */
+#ifdef CONFIG_TRACE_IRQFLAGS
+ lis r12,reenable_mmu@h
+ ori r12,r12,reenable_mmu@l
+ mtspr SPRN_SRR0,r12
+ mtspr SPRN_SRR1,r10
+ SYNC
+ RFI
+reenable_mmu: /* re-enable mmu so we can */
+ mfmsr r10
+ lwz r12,_MSR(r1)
+ xor r10,r10,r12
+ andi. r10,r10,MSR_EE /* Did EE change? */
+ beq 1f
+
+ /* Save handler and return address into the 2 unused words
+ * of the STACK_FRAME_OVERHEAD (sneak sneak sneak). Everything
+ * else can be recovered from the pt_regs except r3 which for
+ * normal interrupts has been set to pt_regs and for syscalls
+ * is an argument, so we temporarily use ORIG_GPR3 to save it
+ */
+ stw r9,8(r1)
+ stw r11,12(r1)
+ stw r3,ORIG_GPR3(r1)
+ bl trace_hardirqs_off
+ lwz r0,GPR0(r1)
+ lwz r3,ORIG_GPR3(r1)
+ lwz r4,GPR4(r1)
+ lwz r5,GPR5(r1)
+ lwz r6,GPR6(r1)
+ lwz r7,GPR7(r1)
+ lwz r8,GPR8(r1)
+ lwz r9,8(r1)
+ lwz r11,12(r1)
+1: mtctr r11
+ mtlr r9
+ bctr /* jump to handler */
+#else /* CONFIG_TRACE_IRQFLAGS */
mtspr SPRN_SRR0,r11
mtspr SPRN_SRR1,r10
mtlr r9
SYNC
RFI /* jump to handler, enable MMU */
+#endif /* CONFIG_TRACE_IRQFLAGS */
#if defined (CONFIG_6xx) || defined(CONFIG_E500)
4: rlwinm r12,r12,0,~_TLF_NAPPING
@@ -251,6 +289,31 @@ _GLOBAL(DoSyscall)
#ifdef SHOW_SYSCALLS
bl do_show_syscall
#endif /* SHOW_SYSCALLS */
+#ifdef CONFIG_TRACE_IRQFLAGS
+ /* Return from syscalls can (and generally will) hard enable
+ * interrupts. You aren't supposed to call a syscall with
+ * interrupts disabled in the first place. However, to ensure
+ * that we get it right vs. lockdep if it happens, we force
+ * that hard enable here with appropriate tracing if we see
+ * that we have been called with interrupts off
+ */
+ mfmsr r11
+ andi. r12,r11,MSR_EE
+ bne+ 1f
+ /* We came in with interrupts disabled, we enable them now */
+ bl trace_hardirqs_on
+ mfmsr r11
+ lwz r0,GPR0(r1)
+ lwz r3,GPR3(r1)
+ lwz r4,GPR4(r1)
+ ori r11,r11,MSR_EE
+ lwz r5,GPR5(r1)
+ lwz r6,GPR6(r1)
+ lwz r7,GPR7(r1)
+ lwz r8,GPR8(r1)
+ mtmsr r11
+1:
+#endif /* CONFIG_TRACE_IRQFLAGS */
rlwinm r10,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
lwz r11,TI_FLAGS(r10)
andi. r11,r11,_TIF_SYSCALL_T_OR_A
@@ -275,6 +338,7 @@ ret_from_syscall:
rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
/* disable interrupts so current_thread_info()->flags can't change */
LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */
+ /* Note: We don't bother telling lockdep about it */
SYNC
MTMSRD(r10)
lwz r9,TI_FLAGS(r12)
@@ -288,6 +352,19 @@ ret_from_syscall:
oris r11,r11,0x1000 /* Set SO bit in CR */
stw r11,_CCR(r1)
syscall_exit_cont:
+ lwz r8,_MSR(r1)
+#ifdef CONFIG_TRACE_IRQFLAGS
+ /* If we are going to return from the syscall with interrupts
+ * off, we trace that here. It shouldn't happen though but we
+ * want to catch the bugger if it does right ?
+ */
+ andi. r10,r8,MSR_EE
+ bne+ 1f
+ stw r3,GPR3(r1)
+ bl trace_hardirqs_off
+ lwz r3,GPR3(r1)
+1:
+#endif /* CONFIG_TRACE_IRQFLAGS */
#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
/* If the process has its own DBCR0 value, load it up. The internal
debug mode bit tells us that dbcr0 should be loaded. */
@@ -311,7 +388,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRE
mtlr r4
mtcr r5
lwz r7,_NIP(r1)
- lwz r8,_MSR(r1)
FIX_SRR1(r8, r0)
lwz r2,GPR2(r1)
lwz r1,GPR1(r1)
@@ -394,7 +470,9 @@ syscall_exit_work:
andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
beq ret_from_except
- /* Re-enable interrupts */
+ /* Re-enable interrupts. There is no need to trace that with
+ * lockdep as we are supposed to have IRQs on at this point
+ */
ori r10,r10,MSR_EE
SYNC
MTMSRD(r10)
@@ -705,6 +783,7 @@ ret_from_except:
/* Hard-disable interrupts so that current_thread_info()->flags
* can't change between when we test it and when we return
* from the interrupt. */
+ /* Note: We don't bother telling lockdep about it */
LOAD_MSR_KERNEL(r10,MSR_KERNEL)
SYNC /* Some chip revs have problems here... */
MTMSRD(r10) /* disable interrupts */
@@ -744,11 +823,24 @@ resume_kernel:
beq+ restore
andi. r0,r3,MSR_EE /* interrupts off? */
beq restore /* don't schedule if so */
+#ifdef CONFIG_TRACE_IRQFLAGS
+ /* Lockdep thinks irqs are enabled, we need to call
+ * preempt_schedule_irq with IRQs off, so we inform lockdep
+ * now that we -did- turn them off already
+ */
+ bl trace_hardirqs_off
+#endif
1: bl preempt_schedule_irq
rlwinm r9,r1,0,0,(31-THREAD_SHIFT)
lwz r3,TI_FLAGS(r9)
andi. r0,r3,_TIF_NEED_RESCHED
bne- 1b
+#ifdef CONFIG_TRACE_IRQFLAGS
+ /* And now, to properly rebalance the above, we tell lockdep they
+ * are being turned back on, which will happen when we return
+ */
+ bl trace_hardirqs_on
+#endif
#else
resume_kernel:
#endif /* CONFIG_PREEMPT */
@@ -765,6 +857,28 @@ restore:
stw r6,icache_44x_need_flush@l(r4)
1:
#endif /* CONFIG_44x */
+
+ lwz r9,_MSR(r1)
+#ifdef CONFIG_TRACE_IRQFLAGS
+ /* Lockdep doesn't know about the fact that IRQs are temporarily turned
+ * off in this assembly code while peeking at TI_FLAGS() and such. However
+ * we need to inform it if the exception turned interrupts off, and we
+ * are about to trun them back on.
+ *
+ * The problem here sadly is that we don't know whether the exceptions was
+ * one that turned interrupts off or not. So we always tell lockdep about
+ * turning them on here when we go back to wherever we came from with EE
+ * on, even if that may meen some redudant calls being tracked. Maybe later
+ * we could encode what the exception did somewhere or test the exception
+ * type in the pt_regs but that sounds overkill
+ */
+ andi. r10,r9,MSR_EE
+ beq 1f
+ bl trace_hardirqs_on
+ lwz r9,_MSR(r1)
+1:
+#endif /* CONFIG_TRACE_IRQFLAGS */
+
lwz r0,GPR0(r1)
lwz r2,GPR2(r1)
REST_4GPRS(3, r1)
@@ -782,7 +896,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRE
stwcx. r0,0,r1 /* to clear the reservation */
#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
- lwz r9,_MSR(r1)
andi. r10,r9,MSR_RI /* check if this exception occurred */
beql nonrecoverable /* at a bad place (MSR:RI = 0) */
@@ -805,7 +918,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRE
MTMSRD(r10) /* clear the RI bit */
.globl exc_exit_restart
exc_exit_restart:
- lwz r9,_MSR(r1)
lwz r12,_NIP(r1)
FIX_SRR1(r9,r10)
mtspr SPRN_SRR0,r12
@@ -1035,11 +1147,18 @@ do_work: /* r10 contains MSR_KERNEL he
beq do_user_signal
do_resched: /* r10 contains MSR_KERNEL here */
+ /* Note: We don't need to inform lockdep that we are enabling
+ * interrupts here. As far as it knows, they are already enabled
+ */
ori r10,r10,MSR_EE
SYNC
MTMSRD(r10) /* hard-enable interrupts */
bl schedule
recheck:
+ /* Note: And we don't tell it we are disabling them again
+ * neither. Those disable/enable cycles used to peek at
+ * TI_FLAGS aren't advertised.
+ */
LOAD_MSR_KERNEL(r10,MSR_KERNEL)
SYNC
MTMSRD(r10) /* disable interrupts */
Index: linux-work/arch/powerpc/kernel/setup_32.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/setup_32.c 2009-06-18 13:21:29.000000000 +1000
+++ linux-work/arch/powerpc/kernel/setup_32.c 2009-06-18 13:21:39.000000000 +1000
@@ -119,6 +119,8 @@ notrace unsigned long __init early_init(
*/
notrace void __init machine_init(unsigned long dt_ptr)
{
+ lockdep_init();
+
/* Enable early debugging if any specified (see udbg.h) */
udbg_early_init();
Index: linux-work/arch/powerpc/include/asm/hw_irq.h
===================================================================
--- linux-work.orig/arch/powerpc/include/asm/hw_irq.h 2009-06-18 13:21:29.000000000 +1000
+++ linux-work/arch/powerpc/include/asm/hw_irq.h 2009-06-18 13:21:39.000000000 +1000
@@ -68,13 +68,13 @@ static inline int irqs_disabled_flags(un
#if defined(CONFIG_BOOKE)
#define SET_MSR_EE(x) mtmsr(x)
-#define local_irq_restore(flags) __asm__ __volatile__("wrtee %0" : : "r" (flags) : "memory")
+#define raw_local_irq_restore(flags) __asm__ __volatile__("wrtee %0" : : "r" (flags) : "memory")
#else
#define SET_MSR_EE(x) mtmsr(x)
-#define local_irq_restore(flags) mtmsr(flags)
+#define raw_local_irq_restore(flags) mtmsr(flags)
#endif
-static inline void local_irq_disable(void)
+static inline void raw_local_irq_disable(void)
{
#ifdef CONFIG_BOOKE
__asm__ __volatile__("wrteei 0": : :"memory");
@@ -86,7 +86,7 @@ static inline void local_irq_disable(voi
#endif
}
-static inline void local_irq_enable(void)
+static inline void raw_local_irq_enable(void)
{
#ifdef CONFIG_BOOKE
__asm__ __volatile__("wrteei 1": : :"memory");
@@ -98,7 +98,7 @@ static inline void local_irq_enable(void
#endif
}
-static inline void local_irq_save_ptr(unsigned long *flags)
+static inline void raw_local_irq_save_ptr(unsigned long *flags)
{
unsigned long msr;
msr = mfmsr();
@@ -110,12 +110,12 @@ static inline void local_irq_save_ptr(un
#endif
}
-#define local_save_flags(flags) ((flags) = mfmsr())
-#define local_irq_save(flags) local_irq_save_ptr(&flags)
-#define irqs_disabled() ((mfmsr() & MSR_EE) == 0)
+#define raw_local_save_flags(flags) ((flags) = mfmsr())
+#define raw_local_irq_save(flags) raw_local_irq_save_ptr(&flags)
+#define raw_irqs_disabled() ((mfmsr() & MSR_EE) == 0)
+#define raw_irqs_disabled_flags(flags) (((flags) & MSR_EE) == 0)
-#define hard_irq_enable() local_irq_enable()
-#define hard_irq_disable() local_irq_disable()
+#define hard_irq_disable() raw_local_irq_disable()
static inline int irqs_disabled_flags(unsigned long flags)
{
Index: linux-work/arch/powerpc/kernel/udbg.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/udbg.c 2009-06-18 13:21:29.000000000 +1000
+++ linux-work/arch/powerpc/kernel/udbg.c 2009-06-18 13:21:39.000000000 +1000
@@ -65,6 +65,7 @@ void __init udbg_early_init(void)
#ifdef CONFIG_PPC_EARLY_DEBUG
console_loglevel = 10;
#endif
+ register_early_udbg_console();
}
/* udbg library, used by xmon et al */
^ permalink raw reply
* [PATCH] powerpc/mm: Make k(un)map_atomic out of line
From: Benjamin Herrenschmidt @ 2009-06-18 3:39 UTC (permalink / raw)
To: linuxppc-dev
Those functions are way too big to be inline, besides, kmap_atomic()
wants to call debug_kmap_atomic() which isn't exported for modules
and causes module link failures.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/include/asm/highmem.h | 55 +--------------------------
arch/powerpc/mm/Makefile | 1
arch/powerpc/mm/highmem.c | 75 +++++++++++++++++++++++++++++++++++++
3 files changed, 80 insertions(+), 51 deletions(-)
--- linux-work.orig/arch/powerpc/include/asm/highmem.h 2009-06-18 11:34:42.000000000 +1000
+++ linux-work/arch/powerpc/include/asm/highmem.h 2009-06-18 11:34:45.000000000 +1000
@@ -62,6 +62,9 @@ extern pte_t *pkmap_page_table;
extern void *kmap_high(struct page *page);
extern void kunmap_high(struct page *page);
+extern void *kmap_atomic_prot(struct page *page, enum km_type type,
+ pgprot_t prot);
+extern void kunmap_atomic(void *kvaddr, enum km_type type);
static inline void *kmap(struct page *page)
{
@@ -79,62 +82,11 @@ static inline void kunmap(struct page *p
kunmap_high(page);
}
-/*
- * The use of kmap_atomic/kunmap_atomic is discouraged - kmap/kunmap
- * gives a more generic (and caching) interface. But kmap_atomic can
- * be used in IRQ contexts, so in some (very limited) cases we need
- * it.
- */
-static inline void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot)
-{
- unsigned int idx;
- unsigned long vaddr;
-
- /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
- pagefault_disable();
- if (!PageHighMem(page))
- return page_address(page);
-
- debug_kmap_atomic(type);
- idx = type + KM_TYPE_NR*smp_processor_id();
- vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
-#ifdef CONFIG_DEBUG_HIGHMEM
- BUG_ON(!pte_none(*(kmap_pte-idx)));
-#endif
- __set_pte_at(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot), 1);
- local_flush_tlb_page(NULL, vaddr);
-
- return (void*) vaddr;
-}
-
static inline void *kmap_atomic(struct page *page, enum km_type type)
{
return kmap_atomic_prot(page, type, kmap_prot);
}
-static inline void kunmap_atomic(void *kvaddr, enum km_type type)
-{
-#ifdef CONFIG_DEBUG_HIGHMEM
- unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
- enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
-
- if (vaddr < __fix_to_virt(FIX_KMAP_END)) {
- pagefault_enable();
- return;
- }
-
- BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
-
- /*
- * force other mappings to Oops if they'll try to access
- * this pte without first remap it
- */
- pte_clear(&init_mm, vaddr, kmap_pte-idx);
- local_flush_tlb_page(NULL, vaddr);
-#endif
- pagefault_enable();
-}
-
static inline struct page *kmap_atomic_to_page(void *ptr)
{
unsigned long idx, vaddr = (unsigned long) ptr;
@@ -148,6 +100,7 @@ static inline struct page *kmap_atomic_t
return pte_page(*pte);
}
+
#define flush_cache_kmaps() flush_cache_all()
#endif /* __KERNEL__ */
Index: linux-work/arch/powerpc/mm/Makefile
===================================================================
--- linux-work.orig/arch/powerpc/mm/Makefile 2009-06-18 11:34:42.000000000 +1000
+++ linux-work/arch/powerpc/mm/Makefile 2009-06-18 11:34:45.000000000 +1000
@@ -30,3 +30,4 @@ obj-$(CONFIG_PPC_MM_SLICES) += slice.o
obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
obj-$(CONFIG_PPC_SUBPAGE_PROT) += subpage-prot.o
obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-noncoherent.o
+obj-$(CONFIG_HIGHMEM) += highmem.o
Index: linux-work/arch/powerpc/mm/highmem.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-work/arch/powerpc/mm/highmem.c 2009-06-18 11:35:51.000000000 +1000
@@ -0,0 +1,75 @@
+/*
+ * highmem.c: virtual kernel memory mappings for high memory
+ *
+ * PowerPC version, stolen from the i386 version.
+ *
+ * Used in CONFIG_HIGHMEM systems for memory pages which
+ * are not addressable by direct kernel virtual addresses.
+ *
+ * Copyright (C) 1999 Gerhard Wichert, Siemens AG
+ * Gerhard.Wichert@pdb.siemens.de
+ *
+ *
+ * Redesigned the x86 32-bit VM architecture to deal with
+ * up to 16 Terrabyte physical memory. With current x86 CPUs
+ * we now support up to 64 Gigabytes physical RAM.
+ *
+ * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
+ *
+ * Reworked for PowerPC by various contributors. Moved from
+ * highmem.h by Benjamin Herrenschmidt (c) 2009 IBM Corp.
+ */
+
+
+/*
+ * The use of kmap_atomic/kunmap_atomic is discouraged - kmap/kunmap
+ * gives a more generic (and caching) interface. But kmap_atomic can
+ * be used in IRQ contexts, so in some (very limited) cases we need
+ * it.
+ */
+void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot)
+{
+ unsigned int idx;
+ unsigned long vaddr;
+
+ /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
+ pagefault_disable();
+ if (!PageHighMem(page))
+ return page_address(page);
+
+ debug_kmap_atomic(type);
+ idx = type + KM_TYPE_NR*smp_processor_id();
+ vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+#ifdef CONFIG_DEBUG_HIGHMEM
+ BUG_ON(!pte_none(*(kmap_pte-idx)));
+#endif
+ __set_pte_at(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot), 1);
+ local_flush_tlb_page(NULL, vaddr);
+
+ return (void*) vaddr;
+}
+EXPORT_SYMBOL(kmap_atomic_prot);
+
+void kunmap_atomic(void *kvaddr, enum km_type type)
+{
+#ifdef CONFIG_DEBUG_HIGHMEM
+ unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
+ enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
+
+ if (vaddr < __fix_to_virt(FIX_KMAP_END)) {
+ pagefault_enable();
+ return;
+ }
+
+ BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
+
+ /*
+ * force other mappings to Oops if they'll try to access
+ * this pte without first remap it
+ */
+ pte_clear(&init_mm, vaddr, kmap_pte-idx);
+ local_flush_tlb_page(NULL, vaddr);
+#endif
+ pagefault_enable();
+}
+EXPORT_SYMBOL(kunmap_atomic);
^ 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