* Re: [PATCH v2] powerpc 8xx: Loading kernels over 8Mbytes without CONFIG_PIN_TLB
From: leroy christophe @ 2013-12-17 5:54 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev, Paul Mackerras, linux-kernel
In-Reply-To: <1387234621.10013.408.camel@snotra.buserror.net>
Le 16/12/2013 23:57, Scott Wood a écrit :
> On Wed, 2013-12-11 at 00:36 +0100, leroy christophe wrote:
>> Le 11/12/2013 00:18, Scott Wood a écrit :
>>> There wasn't previously an ifdef specifically around the setting of
>>> SPRN_MD_CTR. That's new. There was an ifdef around the entire block,
>>> which has gone away because you are now trying to map more than 8M
>>> regardless of CONFIG_PIN_TLB, but that has nothing to do with whether
>>> there should be an ifdef around SPRN_MD_CTR.
>>>
>>>
>> Euh, ok, but then we have to fix it in the whole function, not only in
>> this block. Do you think it is worth doing it ?
> Fix what in the whole function? I was asking what harm there would be
> if you just remove all the CONFIG_PIN_TLB ifdefs except around the
> actual RSV4I setting -- do we really care what value goes in MD_CTR for
> the non-pinned case, as long as it's different for each entry?
>
>
MD_CTR is decremented after each entry added.
However, the function populates entry 28, then 29, then 30, then 31. At
the end MD_CTR has then value 30, ready to overide entry 30 then 29 then
28 then 27 .....
So I will remove all the CONFIG_PIN_TLB, but I'll also have to fix the
value set in MD_CTR to start from 31, won't I ?
Do you have any comment/recommendation on my tentative v3 patch where I
have tried to implement based on the use of r7 as you recommended ?
Christophe
^ permalink raw reply
* Re: [PATCH 0/4] Minor fixes and improvements for kexec
From: WANG Chao @ 2013-12-17 5:37 UTC (permalink / raw)
To: Geoff Levand
Cc: linux-sh, kexec, Paul Mundt, Paul Mackerras, Eric Biederman,
linuxppc-dev
In-Reply-To: <cover.1386807069.git.geoff@infradead.org>
On 12/12/13 at 12:18am, Geoff Levand wrote:
> Hi Eric,
>
> Here are a few minor fixes and improvements for kexec. Please consider.
>
> -Geoff
>
> The following changes since commit 374b105797c3d4f29c685f3be535c35f5689b30e:
>
> Linux 3.13-rc3 (2013-12-06 09:34:04 -0800)
>
> are available in the git repository at:
>
> git://git.linaro.org/people/geoff.levand/linux-kexec.git for-kexec
>
> for you to fetch changes up to 594a3d26aac66e9668edc81d7bfb4e801575514f:
>
> sh/kexec: Fix kexec build warning (2013-12-11 16:03:27 -0800)
>
> ----------------------------------------------------------------
> Geoff Levand (4):
> kexec: Simplify conditional
> kexec: Add IND_FLAGS macro
> powerpc/kexec: Use global IND_FLAGS macro
> sh/kexec: Fix kexec build warning
For this series (besides 4/4 v2):
Acked-by: WANG Chao <chaowang@redhat.com>
>
> arch/powerpc/kernel/machine_kexec_64.c | 2 --
> arch/sh/kernel/machine_kexec.c | 2 +-
> include/linux/kexec.h | 1 +
> kernel/kexec.c | 17 ++++++++++-------
> 4 files changed, 12 insertions(+), 10 deletions(-)
>
> --
> 1.8.1.2
>
>
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply
* Re: [PATCH 6/9] powerpc/pci: Use dev_is_pci() to check whether it is pci device
From: Wei Yang @ 2013-12-17 2:02 UTC (permalink / raw)
To: Yijing Wang
Cc: Wei Yang, Hanjun Guo, linux-kernel, Scott Wood, Paul Mackerras,
linux-pci, Bjorn Helgaas, linuxppc-dev
In-Reply-To: <52AEC241.1040507@huawei.com>
On Mon, Dec 16, 2013 at 05:05:05PM +0800, Yijing Wang wrote:
>On 2013/12/16 15:13, Wei Yang wrote:
>> Yijing,
>>
>> This one looks good.
>>
>> While I take a look at the source code, there are around 20 places with
>> similar style. Do you think it would be good to change all these places
>> in one patch?
>
>I sent the other similar changes to related maillist, some of them (David, Greg )has been accepted,
>and other is not. :)
>
>eg.
>http://article.gmane.org/gmane.linux.kernel/1608341/match=dev_is_pci
Ah, I see. Thanks :-)
>
>Thanks!
>Yijing.
>
>>
>> On Thu, Dec 05, 2013 at 08:01:20PM +0800, Yijing Wang wrote:
>>> Use PCI standard marco dev_is_pci() instead of directly compare
>>> pci_bus_type to check whether it is pci device.
>>>
>>> Signed-off-by: Yijing Wang <wangyijing@huawei.com>
>>> ---
>>> arch/powerpc/sysdev/fsl_pci.c | 2 +-
>>> 1 files changed, 1 insertions(+), 1 deletions(-)
>>>
>>> diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
>>> index 4dfd61d..7066e52 100644
>>> --- a/arch/powerpc/sysdev/fsl_pci.c
>>> +++ b/arch/powerpc/sysdev/fsl_pci.c
>>> @@ -122,7 +122,7 @@ static int fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask)
>>> * address width of the SoC such that we can address any internal
>>> * SoC address from across PCI if needed
>>> */
>>> - if ((dev->bus == &pci_bus_type) &&
>>> + if ((dev_is_pci(dev)) &&
>>> dma_mask >= DMA_BIT_MASK(MAX_PHYS_ADDR_BITS)) {
>>> set_dma_ops(dev, &dma_direct_ops);
>>> set_dma_offset(dev, pci64_dma_offset);
>>> --
>>> 1.7.1
>>>
>>>
>>> _______________________________________________
>>> Linuxppc-dev mailing list
>>> Linuxppc-dev@lists.ozlabs.org
>>> https://lists.ozlabs.org/listinfo/linuxppc-dev
>>
>
>
>--
>Thanks!
>Yijing
--
Richard Yang
Help you, Help me
^ permalink raw reply
* Re: [PATCH 2/8] IBM Akebono: Add a SDHCI platform driver
From: Alistair Popple @ 2013-12-17 1:11 UTC (permalink / raw)
To: linuxppc-dev, Chris Ball, linux-mmc; +Cc: linuxppc-dev
In-Reply-To: <1385086116-10972-2-git-send-email-alistair@popple.id.au>
Hi,
I originally sent this to the linuxppc-dev list thinking Ben H might ta=
ke it,=20
however it should go through the appropriate subsystem. Can someone ple=
ase=20
merge it into the appropriate tree (unless the are problems with it)?
Thanks.
Regards,
Alistair
On Fri, 22 Nov 2013 13:08:30 Alistair Popple wrote:
> This patch adds a SDHCI platform driver for the new IBM PPC476GTR SoC=
> which is on the Akebono board.
>=20
> Signed-off-by: Alistair Popple <alistair@popple.id.au>
> Cc: Chris Ball <cjb@laptop.org>
> Cc: linux-mmc@vger.kernel.org
> ---
> drivers/mmc/host/Kconfig | 12 ++++++++
> drivers/mmc/host/Makefile | 1 +
> drivers/mmc/host/sdhci-of-476gtr.c | 60
> ++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+=
)
> create mode 100644 drivers/mmc/host/sdhci-of-476gtr.c
>=20
> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> index 7fc5099..14210df 100644
> --- a/drivers/mmc/host/Kconfig
> +++ b/drivers/mmc/host/Kconfig
> @@ -130,6 +130,18 @@ config MMC_SDHCI_OF_HLWD
>=20
> =09 If unsure, say N.
>=20
> +config MMC_SDHCI_OF_476GTR
> +=09tristate "SDHCI OF support for the IBM PPC476GTR SoC"
> +=09depends on MMC_SDHCI_PLTFM
> +=09depends on PPC_OF
> +=09help
> +=09 This selects the Secure Digital Host Controller Interface (SDHC=
I)
> +=09 found on the PPC476GTR SoC.
> +
> +=09 If you have a controller with this interface, say Y or M here.
> +
> +=09 If unsure, say N.
> +
> config MMC_SDHCI_CNS3XXX
> =09tristate "SDHCI support on the Cavium Networks CNS3xxx SoC"
> =09depends on ARCH_CNS3XXX
> diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
> index c41d0c3..92beff3 100644
> --- a/drivers/mmc/host/Makefile
> +++ b/drivers/mmc/host/Makefile
> @@ -59,6 +59,7 @@ obj-$(CONFIG_MMC_SDHCI_DOVE)=09=09+=3D sdhci-dove.o=
> obj-$(CONFIG_MMC_SDHCI_TEGRA)=09=09+=3D sdhci-tegra.o
> obj-$(CONFIG_MMC_SDHCI_OF_ESDHC)=09+=3D sdhci-of-esdhc.o
> obj-$(CONFIG_MMC_SDHCI_OF_HLWD)=09=09+=3D sdhci-of-hlwd.o
> +obj-$(CONFIG_MMC_SDHCI_OF_476GTR)=09+=3D sdhci-of-476gtr.o
> obj-$(CONFIG_MMC_SDHCI_BCM_KONA)=09+=3D sdhci-bcm-kona.o
> obj-$(CONFIG_MMC_SDHCI_BCM2835)=09=09+=3D sdhci-bcm2835.o
>=20
> diff --git a/drivers/mmc/host/sdhci-of-476gtr.c
> b/drivers/mmc/host/sdhci-of-476gtr.c new file mode 100644
> index 0000000..1310f8c
> --- /dev/null
> +++ b/drivers/mmc/host/sdhci-of-476gtr.c
> @@ -0,0 +1,60 @@
> +/*
> + * drivers/mmc/host/sdhci-of-476gtr.c
> + *
> + * Copyright =A9 2013 Alistair Popple <alistair@popple.id.au> IBM Co=
rporation
> + *
> + * Based on sdhci-of-hlwd.c
> + *
> + * Copyright (C) 2009 The GameCube Linux Team
> + * Copyright (C) 2009 Albert Herranz
> + *
> + * This program is free software; you can redistribute it and/or mod=
ify
> + * it under the terms of the GNU General Public License as published=
by
> + * the Free Software Foundation; either version 2 of the License, or=
(at
> + * your option) any later version.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/module.h>
> +#include <linux/mmc/host.h>
> +#include "sdhci-pltfm.h"
> +
> +static const struct sdhci_ops sdhci_476gtr_ops =3D {
> +};
> +
> +static const struct sdhci_pltfm_data sdhci_476gtr_pdata =3D {
> +=09.ops =3D &sdhci_476gtr_ops,
> +};
> +
> +static int sdhci_476gtr_probe(struct platform_device *pdev)
> +{
> +=09return sdhci_pltfm_register(pdev, &sdhci_476gtr_pdata, 0);
> +}
> +
> +static int sdhci_476gtr_remove(struct platform_device *pdev)
> +{
> +=09return sdhci_pltfm_unregister(pdev);
> +}
> +
> +static const struct of_device_id sdhci_476gtr_of_match[] =3D {
> +=09{ .compatible =3D "ibm,476gtr-sdhci" },
> +=09{ }
> +};
> +MODULE_DEVICE_TABLE(of, sdhci_476gtr_of_match);
> +
> +static struct platform_driver sdhci_476gtr_driver =3D {
> +=09.driver =3D {
> +=09=09.name =3D "sdhci-476gtr",
> +=09=09.owner =3D THIS_MODULE,
> +=09=09.of_match_table =3D sdhci_476gtr_of_match,
> +=09=09.pm =3D SDHCI_PLTFM_PMOPS,
> +=09},
> +=09.probe =3D sdhci_476gtr_probe,
> +=09.remove =3D sdhci_476gtr_remove,
> +};
> +
> +module_platform_driver(sdhci_476gtr_driver);
> +
> +MODULE_DESCRIPTION("PPC476GTR SDHCI OF driver");
> +MODULE_AUTHOR("Alistair Popple");
> +MODULE_LICENSE("GPL v2");
^ permalink raw reply
* Re: [PATCH v2] powerpc 8xx: Loading kernels over 8Mbytes without CONFIG_PIN_TLB
From: Scott Wood @ 2013-12-16 22:57 UTC (permalink / raw)
To: leroy christophe; +Cc: linuxppc-dev, Paul Mackerras, linux-kernel
In-Reply-To: <52A7A58F.8090705@c-s.fr>
On Wed, 2013-12-11 at 00:36 +0100, leroy christophe wrote:
> Le 11/12/2013 00:18, Scott Wood a écrit :
> > There wasn't previously an ifdef specifically around the setting of
> > SPRN_MD_CTR. That's new. There was an ifdef around the entire block,
> > which has gone away because you are now trying to map more than 8M
> > regardless of CONFIG_PIN_TLB, but that has nothing to do with whether
> > there should be an ifdef around SPRN_MD_CTR.
> >
> >
> Euh, ok, but then we have to fix it in the whole function, not only in
> this block. Do you think it is worth doing it ?
Fix what in the whole function? I was asking what harm there would be
if you just remove all the CONFIG_PIN_TLB ifdefs except around the
actual RSV4I setting -- do we really care what value goes in MD_CTR for
the non-pinned case, as long as it's different for each entry?
-Scott
^ permalink raw reply
* Re: [PATCH 1/5] powerpc/85xx/dts: add third elo3 dma component
From: Scott Wood @ 2013-12-16 18:37 UTC (permalink / raw)
To: Hongbo Zhang; +Cc: linuxppc-dev@lists.ozlabs.org, Liu Shengzhou-B36685
In-Reply-To: <52AEC40C.6000008@freescale.com>
On Mon, 2013-12-16 at 17:12 +0800, Hongbo Zhang wrote:
> On 12/13/2013 01:43 PM, Liu Shengzhou-B36685 wrote:
> >
> >> -----Original Message-----
> >> From: Hongbo Zhang [mailto:hongbo.zhang@freescale.com]
> >> Sent: Thursday, December 12, 2013 5:57 PM
> >> To: Liu Shengzhou-B36685; linuxppc-dev@lists.ozlabs.org; Wood Scott-
> >> B07421
> >> Subject: Re: [PATCH 1/5] powerpc/85xx/dts: add third elo3 dma component
> >>
> >> Shengzhou,
> >> I canceled my patch http://patchwork.ozlabs.org/patch/295157/ because the
> >> original wrong elo3-dma-2.dtsi hadn't been merged.
> >> But please pay attention to comments from Scott about my changes of
> >> adding 208 for some interrupts, and take some actions if needed, or
> >> further discussions.
> >>
> >> Below comments form Scott:
> >> "The FSL MPIC binding should be updated to point out how this works.
> >> Technically it's not a change to the binding itself, since it's defined
> >> in terms of register offset, but the explanatory text says "So interrupt
> >> 0 is at offset 0x0, interrupt 1 is at offset 0x20, and so on." which is
> >> not accurate for these new high interrupt numbers."
> >>
> > Hongbo,
> > Could you update FSL MPIC binding as Scott pointed out?
>
> We only need to add more explanatory text after the sentence Scott
> pointed out, like:
> "But for some hardwares, the MPIC registers for interrupts are not
> continuous in address, in such cases, an offset can be added to the
> interrupt number to skip the registers which is not for interrupts."
>
> Scott, is that OK?
Actually, I misread what that sentence actually says, and it's correct
as is -- but not as helpful as it could be.
I'd add this new paragraph instead:
For example, internal interrupt 0 is at offset 0x200 and thus is
interrupt 16 in the device tree. MSI bank A interrupt 0 is at offset
0x1c00, and thus is interrupt 224. MPIC v4.3 adds a new discontiguous
address range for internal interrupts, so internal interrupt 160 is at
offset 0x3000, and thus is interrupt 384.
-Scott
^ permalink raw reply
* Re: [PATCH v5 4/4] powerpc/85xx: add sysfs for pw20 state and altivec idle
From: Scott Wood @ 2013-12-16 18:26 UTC (permalink / raw)
To: Wang Dongsheng-B40534
Cc: Bhushan Bharat-R65777, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <0ba4966fa6b54478b2885a0b97f4c2bf@BY2PR03MB191.namprd03.prod.outlook.com>
On Sun, 2013-12-15 at 23:53 -0600, Wang Dongsheng-B40534 wrote:
>
> > -----Original Message-----
> > From: Bhushan Bharat-R65777
> > Sent: Monday, November 11, 2013 12:11 PM
> > To: Wang Dongsheng-B40534; Wood Scott-B07421
> > Cc: linuxppc-dev@lists.ozlabs.org
> > Subject: RE: [PATCH v5 4/4] powerpc/85xx: add sysfs for pw20 state and altivec
> > idle
> >
> > > > Those codes just for discuss with Bharat. He want to make one flow at
> > > > "show_pw20_wait_time"/" show_altivec_idle_wait_time" function. If we
> > > > do that, we need to initialize pw20_wt/altivec_idle_wt.
> > > >
> > > I will keep this stuff at "show_pw20_wait_time"/"show_altivec_idle_wait_time"
> > > and add a comment before our discussion.
> > >
> > > /*
> > > * If the "value" less than 10, this will overflow.
> > > * From benchmark test, the default wait bit will not be set less than 10bit.
> > > * Because 10 bit corresponds to the wait entry time is 439375573401999609(ns),
> > > * for wait-entry-idle time this value looks too long, and we cannot use those
> > > * "long" time as a default wait-entry time. So overflow could not have
> > happened
> > > * and we use this calculation method to get wait-entry-idle time.
> > > */
> >
> > I think now we will use same calculation code for default value and user set
> > value, so adding the comment is not sufficient, we should error out from the
> > code if value is less than 10. As default value is not less than 10 so this will
> > always work with default value but if user tries to set less than 10 then error
> > out and ask user to try more than 9.
> >
> Again, once the user has set up a time, the code will go to another branch.
>
> else {
> time = pw20_wt;
> }
>
> We do so much for this a little function processing is not worth it. If we can't
> agree on this sys interface. I will change this sys interface to show_pw20_wait_bit. :)
Please don't change it.
-Scott
^ permalink raw reply
* Re: [PATCH 10/10] Kconfig: cleanup SERIO_I8042 dependencies
From: Ralf Baechle @ 2013-12-16 16:23 UTC (permalink / raw)
To: Mark Salter
Cc: linux-mips, linux-ia64, linux-sh, Paul Mackerras, H. Peter Anvin,
sparclinux, Guan Xuetao, Russell King, x86, Ingo Molnar,
Fenghua Yu, Thomas Gleixner, linux-arm-kernel, Richard Henderson,
Tony Luck, Dmitry Torokhov, linux-kernel, Paul Mundt, linux-alpha,
linuxppc-dev, David S. Miller
In-Reply-To: <1387040376-26906-11-git-send-email-msalter@redhat.com>
On Sat, Dec 14, 2013 at 11:59:36AM -0500, Mark Salter wrote:
> - depends on !PARISC && (!ARM || FOOTBRIDGE_HOST) && \
> - (!SUPERH || SH_CAYMAN) && !M68K && !BLACKFIN && !S390 && \
> - !ARC
> + depends on ARCH_MIGHT_HAVE_PC_SERIO
Most dependencies on an architecture's kconfig symbol outside arch/
should probably be treated as a bug.
Acked-by: Ralf Baechle <ralf@linux-mips.org>
Ralf
^ permalink raw reply
* [PATCH v2] powerpc/powernv: Framework to log critical errors on powernv.
From: Deepthi Dharwar @ 2013-12-16 12:30 UTC (permalink / raw)
To: PowerPC email list
This patch provides error logging interfaces to report critical
powernv error to FSP.
All the required information to dump the error is collected
at POWERNV level through error log interfaces
and then pushed on to FSP.
This also supports synchronous error logging in cases of
PANIC, by passing OPAL_ERROR_PANIC as severity in
elog_create() call.
Signed-off-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/opal.h | 125 ++++++++++++++++++++++++
arch/powerpc/platforms/powernv/opal-elog.c | 60 +++++++++++-
arch/powerpc/platforms/powernv/opal-wrappers.S | 1
3 files changed, 185 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 0f01308..1c5440a 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -168,6 +168,7 @@ extern int opal_enter_rtas(struct rtas_args *args,
#define OPAL_GET_MSG 85
#define OPAL_CHECK_ASYNC_COMPLETION 86
#define OPAL_SYNC_HOST_REBOOT 87
+#define OPAL_ELOG_SEND 88
#ifndef __ASSEMBLY__
@@ -260,6 +261,122 @@ enum OpalMessageType {
OPAL_MSG_TYPE_MAX,
};
+/* Classification of Error/Events reporting type classification
+ * Platform Events/Errors: Report Machine Check Interrupt
+ * INPUT_OUTPUT: Report all I/O related events/errors
+ * RESOURCE_DEALLOC: Hotplug events and errors
+ * MISC: Miscellanous error
+ * Field: error_events_type
+ */
+enum error_events {
+ OPAL_PLATFORM,
+ OPAL_INPUT_OUTPUT,
+ OPAL_RESOURCE_DEALLOC,
+ OPAL_MISC,
+};
+
+/* OPAL Subsystem IDs listed for reporting events/errors
+ * Field: subsystem_id
+ */
+
+#define OPAL_PROCESSOR_SUBSYSTEM 0x10
+#define OPAL_MEMORY_SUBSYSTEM 0x20
+#define OPAL_IO_SUBSYSTEM 0x30
+#define OPAL_IO_DEVICES 0x40
+#define OPAL_CEC_HARDWARE 0x50
+#define OPAL_POWER_COOLING 0x60
+#define OPAL_MISC_SUBSYSTEM 0x70
+#define OPAL_SURVEILLANCE_ERR 0x7A
+#define OPAL_PLATFORM_FIRMWARE 0x80
+#define OPAL_SOFTWARE 0x90
+#define OPAL_EXTERNAL_ENV 0xA0
+
+/* During reporting an event/error the following represents
+ * how serious the logged event/error is. (Severity)
+ * Field: event_sev
+ */
+#define OPAL_INFO 0x00
+#define OPAL_RECOVERED_ERR_GENERAL 0x10
+
+/* 0x2X series is to denote set of Predictive Error
+ * 0x20 Generic predictive error
+ * 0x21 Predictive error, degraded performance
+ * 0x22 Predictive error, fault may be corrected after reboot
+ * 0x23 Predictive error, fault may be corrected after reboot,
+ * degraded performance
+ * 0x24 Predictive error, loss of redundancy
+ */
+#define OPAL_PREDICTIVE_ERR_GENERAL 0x20
+#define OPAL_PREDICTIVE_ERR_DEGRADED_PERF 0x21
+#define OPAL_PREDICTIVE_ERR_FAULT_RECTIFY_REBOOT 0x22
+#define OPAL_PREDICTIVE_ERR_FAULT_RECTIFY_BOOT_DEGRADE_PERF 0x23
+#define OPAL_PREDICTIVE_ERR_LOSS_OF_REDUNDANCY 0x24
+
+/* 0x4X series for Unrecoverable Error
+ * 0x40 Generic Unrecoverable error
+ * 0x41 Unrecoverable error bypassed with degraded performance
+ * 0x44 Unrecoverable error bypassed with loss of redundancy
+ * 0x45 Unrecoverable error bypassed with loss of redundancy and performance
+ * 0x48 Unrecoverable error bypassed with loss of function
+ */
+#define OPAL_UNRECOVERABLE_ERR_GENERAL 0x40
+#define OPAL_UNRECOVERABLE_ERR_DEGRADE_PERF 0x41
+#define OPAL_UNRECOVERABLE_ERR_LOSS_REDUNDANCY 0x44
+#define OPAL_UNRECOVERABLE_ERR_LOSS_REDUNDANCY_PERF 0x45
+#define OPAL_UNRECOVERABLE_ERR_LOSS_OF_FUNCTION 0x48
+#define OPAL_ERROR_PANIC 0x50
+
+/* Event Sub-type
+ * This field provides additional information on the non-error
+ * event type
+ * Field: event_subtype
+ */
+#define OPAL_NA 0x00
+#define OPAL_MISCELLANEOUS_INFO_ONLY 0x01
+#define OPAL_PREV_REPORTED_ERR_RECTIFIED 0x10
+#define OPAL_SYS_RESOURCES_DECONFIG_BY_USER 0x20
+#define OPAL_SYS_RESOURCE_DECONFIG_PRIOR_ERR 0x21
+#define OPAL_RESOURCE_DEALLOC_EVENT_NOTIFY 0x22
+#define OPAL_CONCURRENT_MAINTENANCE_EVENT 0x40
+#define OPAL_CAPACITY_UPGRADE_EVENT 0x60
+#define OPAL_RESOURCE_SPARING_EVENT 0x70
+#define OPAL_DYNAMIC_RECONFIG_EVENT 0x80
+#define OPAL_NORMAL_SYS_PLATFORM_SHUTDOWN 0xD0
+#define OPAL_ABNORMAL_POWER_OFF 0xE0
+
+/* Max user dump size is 14K */
+#define OPAL_LOG_MAX_DUMP 14336
+
+/* Multiple user data sections */
+struct opal_usr_data_scn {
+ uint32_t tag;
+ uint16_t size;
+ uint16_t component_id;
+ char data_dump[4];
+};
+
+/* All the information regarding an error/event to be reported
+ * needs to populate this structure using pre-defined interfaces
+ * only
+ */
+struct opal_errorlog {
+
+ uint16_t component_id;
+ uint8_t error_events_type:3;
+ uint8_t subsystem_id;
+
+ uint8_t event_sev;
+ uint8_t event_subtype;
+ uint8_t usr_scn_count; /* User section count */
+ uint8_t elog_origin;
+
+ uint32_t usr_scn_size; /* User section size */
+ uint32_t reason_code;
+ uint32_t additional_info[4];
+
+ char usr_data_dump[OPAL_LOG_MAX_DUMP];
+};
+
/* Machine check related definitions */
enum OpalMCE_Version {
OpalMCE_V1 = 1,
@@ -853,6 +970,14 @@ int64_t opal_dump_ack(uint32_t dump_id);
int64_t opal_get_msg(uint64_t buffer, size_t size);
int64_t opal_check_completion(uint64_t buffer, size_t size, uint64_t token);
int64_t opal_sync_host_reboot(void);
+struct opal_errorlog *elog_create(uint8_t err_evt_type, uint16_t component_id,
+ uint8_t subsystem_id, uint8_t event_sev, uint8_t event_subtype,
+ uint32_t reason_code, uint32_t info0, uint32_t info1,
+ uint32_t info2, uint32_t info3);
+int update_user_dump(struct opal_errorlog *buf, unsigned char *data,
+ uint32_t tag, uint16_t size);
+void commit_errorlog_to_fsp(struct opal_errorlog *buf);
+int opal_commit_log_to_fsp(void *buf);
/* Internal functions */
extern int early_init_dt_scan_opal(unsigned long node, const char *uname, int depth, void *data);
diff --git a/arch/powerpc/platforms/powernv/opal-elog.c b/arch/powerpc/platforms/powernv/opal-elog.c
index 58849d0..ade1e58 100644
--- a/arch/powerpc/platforms/powernv/opal-elog.c
+++ b/arch/powerpc/platforms/powernv/opal-elog.c
@@ -15,6 +15,7 @@
#include <linux/sysfs.h>
#include <linux/fs.h>
#include <linux/vmalloc.h>
+#include <linux/mm.h>
#include <linux/fcntl.h>
#include <asm/uaccess.h>
#include <asm/opal.h>
@@ -22,7 +23,9 @@
/* Maximum size of a single log on FSP is 16KB */
#define OPAL_MAX_ERRLOG_SIZE 16384
-/* maximu number of records powernv can hold */
+#define USR_CHAR_ARRAY_FIXED_SIZE 4
+
+/* Maximum number of records powernv can hold */
#define MAX_NUM_RECORD 128
struct opal_err_log {
@@ -272,6 +275,61 @@ static int init_err_log_buffer(void)
return 0;
}
+/* Interface to be used by POWERNV to push the logs to FSP via Sapphire */
+struct opal_errorlog *elog_create(uint8_t err_evt_type, uint16_t component_id,
+ uint8_t subsystem_id, uint8_t event_sev, uint8_t event_subtype,
+ uint32_t reason_code, uint32_t info0, uint32_t info1,
+ uint32_t info2, uint32_t info3)
+{
+ struct opal_errorlog *buf;
+
+ buf = kzalloc(sizeof(struct opal_errorlog), GFP_KERNEL);
+ if (!buf) {
+ printk(KERN_ERR "ELOG: failed to allocate memory.\n");
+ return NULL;
+ }
+
+ buf->error_events_type = err_evt_type;
+ buf->component_id = component_id;
+ buf->subsystem_id = subsystem_id;
+ buf->event_sev = event_sev;
+ buf->event_subtype = event_subtype;
+ buf->reason_code = reason_code;
+ buf->additional_info[0] = info0;
+ buf->additional_info[1] = info1;
+ buf->additional_info[2] = info2;
+ buf->additional_info[3] = info3;
+ return buf;
+}
+
+int update_user_dump(struct opal_errorlog *buf, unsigned char *data,
+ uint32_t tag, uint16_t size)
+{
+ char *buffer = (char *)buf->usr_data_dump + buf->usr_scn_size;
+ struct opal_usr_data_scn *tmp;
+
+ if ((buf->usr_scn_size + size) > OPAL_LOG_MAX_DUMP) {
+ printk(KERN_ERR "ELOG: Size of dump data overruns buffer");
+ return -1;
+ }
+
+ tmp = (struct opal_usr_data_scn *)buffer;
+ tmp->tag = tag;
+ tmp->size = size + sizeof(struct opal_usr_data_scn)
+ - USR_CHAR_ARRAY_FIXED_SIZE;
+ memcpy(tmp->data_dump, data, size);
+
+ buf->usr_scn_size += tmp->size;
+ buf->usr_scn_count++;
+ return 0;
+}
+
+void commit_errorlog_to_fsp(struct opal_errorlog *buf)
+{
+ opal_commit_log_to_fsp((void *)(vmalloc_to_pfn(buf) << PAGE_SHIFT));
+ kfree(buf);
+}
+
/* Initialize error logging */
static int __init opal_elog_init(void)
{
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S
index ad318d8..821d8a2 100644
--- a/arch/powerpc/platforms/powernv/opal-wrappers.S
+++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
@@ -133,3 +133,4 @@ OPAL_CALL(opal_dump_ack, OPAL_DUMP_ACK);
OPAL_CALL(opal_get_msg, OPAL_GET_MSG);
OPAL_CALL(opal_check_completion, OPAL_CHECK_ASYNC_COMPLETION);
OPAL_CALL(opal_sync_host_reboot, OPAL_SYNC_HOST_REBOOT);
+OPAL_CALL(opal_commit_log_to_fsp, OPAL_ELOG_SEND);
Regards,
Deepthi
^ permalink raw reply related
* Re: [PATCH 2/2] drivers: tty: Mark the function hvc_poll_init() as static in hvc_console.c
From: Josh Triplett @ 2013-12-16 11:11 UTC (permalink / raw)
To: Rashika Kheria
Cc: Greg Kroah-Hartman, Hendrik Brueckner, Jiri Slaby, linux-kernel,
linuxppc-dev
In-Reply-To: <0dc41f5b30bf9b5c94e658387ffaf092736c26b2.1387191158.git.rashika.kheria@gmail.com>
On Mon, Dec 16, 2013 at 04:31:28PM +0530, Rashika Kheria wrote:
> Mark the function hvc_poll_init() as static in hvc/hvc_console.c becaus=
e
> it is not used outside this file.
>=20
> This eliminates the following warning in hvc/hvc_console.c:
> drivers/tty/hvc/hvc_console.c:791:5: warning: no previous prototype for=
=E2=80=98hvc_poll_init=E2=80=99 [-Wmissing-prototypes]
>=20
> Signed-off-by: Rashika Kheria <rashika.kheria@gmail.com>
Reviewed-by: Josh Triplett <josh@joshtriplett.org>
> drivers/tty/hvc/hvc_console.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>=20
> diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_consol=
e.c
> index 9eba119..50b4688 100644
> --- a/drivers/tty/hvc/hvc_console.c
> +++ b/drivers/tty/hvc/hvc_console.c
> @@ -788,7 +788,7 @@ static int hvc_tiocmset(struct tty_struct *tty,
> }
> =20
> #ifdef CONFIG_CONSOLE_POLL
> -int hvc_poll_init(struct tty_driver *driver, int line, char *options)
> +static int hvc_poll_init(struct tty_driver *driver, int line, char *op=
tions)
> {
> return 0;
> }
> --=20
> 1.7.9.5
>=20
^ permalink raw reply
* [PATCH 2/2] drivers: tty: Mark the function hvc_poll_init() as static in hvc_console.c
From: Rashika Kheria @ 2013-12-16 11:01 UTC (permalink / raw)
To: linux-kernel
Cc: Greg Kroah-Hartman, linuxppc-dev, josh, Rashika Kheria,
Hendrik Brueckner, Jiri Slaby
In-Reply-To: <0d40902c95942d272a70b1d85b4e311d0cc7afa4.1387191158.git.rashika.kheria@gmail.com>
Mark the function hvc_poll_init() as static in hvc/hvc_console.c because
it is not used outside this file.
This eliminates the following warning in hvc/hvc_console.c:
drivers/tty/hvc/hvc_console.c:791:5: warning: no previous prototype for ‘hvc_poll_init’ [-Wmissing-prototypes]
Signed-off-by: Rashika Kheria <rashika.kheria@gmail.com>
---
drivers/tty/hvc/hvc_console.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c
index 9eba119..50b4688 100644
--- a/drivers/tty/hvc/hvc_console.c
+++ b/drivers/tty/hvc/hvc_console.c
@@ -788,7 +788,7 @@ static int hvc_tiocmset(struct tty_struct *tty,
}
#ifdef CONFIG_CONSOLE_POLL
-int hvc_poll_init(struct tty_driver *driver, int line, char *options)
+static int hvc_poll_init(struct tty_driver *driver, int line, char *options)
{
return 0;
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH] powerpc/powernv: Read opal error log and export it through sysfs interface.
From: Mahesh J Salgaonkar @ 2013-12-16 9:58 UTC (permalink / raw)
To: linuxppc-dev, Benjamin Herrenschmidt; +Cc: Vasant Hegde, Mamatha Inamdar
From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
This patch adds support to read error logs from OPAL and export them
to userspace through sysfs interface /sys/firmware/opa/opal-elog.
This patch buffers 128 error log records until it is consumed by userspace
tool. This patch provides an sysfs interface '/sys/firmware/opa/opal-elog-ack'
to user to receive an acknowledgement of successful log consumption.
This is what user space tool would do:
- Read error log from /sys/firmware/opa/opal-elog.
- Save it to the disk.
- Send an acknowledgement on successful consumption by writing error log
id to /sys/firmware/opa/opal-elog-ack.
Signed-off-by: Mamatha Inamdar <mamatha4@linux.vnet.ibm.com>
Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/opal.h | 11 +
arch/powerpc/platforms/powernv/Makefile | 2
arch/powerpc/platforms/powernv/opal-elog.c | 309 ++++++++++++++++++++++++
arch/powerpc/platforms/powernv/opal-wrappers.S | 5
arch/powerpc/platforms/powernv/opal.c | 2
5 files changed, 328 insertions(+), 1 deletion(-)
create mode 100644 arch/powerpc/platforms/powernv/opal-elog.c
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 5462fa7..723a7db 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -129,6 +129,11 @@ extern int opal_enter_rtas(struct rtas_args *args,
#define OPAL_LPC_READ 67
#define OPAL_LPC_WRITE 68
#define OPAL_RETURN_CPU 69
+#define OPAL_ELOG_READ 71
+#define OPAL_ELOG_WRITE 72
+#define OPAL_ELOG_ACK 73
+#define OPAL_ELOG_RESEND 74
+#define OPAL_ELOG_SIZE 75
#define OPAL_FLASH_VALIDATE 76
#define OPAL_FLASH_MANAGE 77
#define OPAL_FLASH_UPDATE 78
@@ -727,6 +732,11 @@ int64_t opal_lpc_write(uint32_t chip_id, enum OpalLPCAddressType addr_type,
uint32_t addr, uint32_t data, uint32_t sz);
int64_t opal_lpc_read(uint32_t chip_id, enum OpalLPCAddressType addr_type,
uint32_t addr, uint32_t *data, uint32_t sz);
+int64_t opal_read_elog(uint64_t buffer, size_t size, uint64_t log_id);
+int64_t opal_get_elog_size(uint64_t *log_id, size_t *size, uint64_t *elog_type);
+int64_t opal_write_elog(uint64_t buffer, uint64_t size, uint64_t offset);
+int64_t opal_send_ack_elog(uint64_t log_id);
+void opal_resend_pending_logs(void);
int64_t opal_validate_flash(uint64_t buffer, uint32_t *size, uint32_t *result);
int64_t opal_manage_flash(uint8_t op);
int64_t opal_update_flash(uint64_t blk_list);
@@ -761,6 +771,7 @@ extern void opal_get_rtc_time(struct rtc_time *tm);
extern unsigned long opal_get_boot_time(void);
extern void opal_nvram_init(void);
extern void opal_flash_init(void);
+extern int opal_elog_init(void);
extern int opal_machine_check(struct pt_regs *regs);
extern bool opal_mce_check_early_recovery(struct pt_regs *regs);
diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile
index 873fa13..0f692eb 100644
--- a/arch/powerpc/platforms/powernv/Makefile
+++ b/arch/powerpc/platforms/powernv/Makefile
@@ -1,6 +1,6 @@
obj-y += setup.o opal-takeover.o opal-wrappers.o opal.o
obj-y += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o
-obj-y += rng.o
+obj-y += rng.o opal-elog.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_PCI) += pci.o pci-p5ioc2.o pci-ioda.o
diff --git a/arch/powerpc/platforms/powernv/opal-elog.c b/arch/powerpc/platforms/powernv/opal-elog.c
new file mode 100644
index 0000000..fc891ae
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/opal-elog.c
@@ -0,0 +1,309 @@
+/*
+ * Error log support on PowerNV.
+ *
+ * Copyright 2013 IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/fs.h>
+#include <linux/vmalloc.h>
+#include <linux/fcntl.h>
+#include <asm/uaccess.h>
+#include <asm/opal.h>
+
+/* Maximum size of a single log on FSP is 16KB */
+#define OPAL_MAX_ERRLOG_SIZE 16384
+
+/* maximu number of records powernv can hold */
+#define MAX_NUM_RECORD 128
+
+struct opal_err_log {
+ struct list_head link;
+ uint64_t opal_log_id;
+ size_t opal_log_size;
+ uint8_t data[OPAL_MAX_ERRLOG_SIZE];
+};
+
+/* Pre-allocated temp buffer to pull error log from opal. */
+static uint8_t err_log_data[OPAL_MAX_ERRLOG_SIZE];
+/* Protect err_log_data buf */
+static DEFINE_MUTEX(err_log_data_mutex);
+
+static uint64_t total_log_size;
+static bool opal_log_available;
+static LIST_HEAD(elog_list);
+static LIST_HEAD(elog_ack_list);
+
+/* lock to protect elog_list and elog-ack_list. */
+static DEFINE_SPINLOCK(opal_elog_lock);
+
+static DECLARE_WAIT_QUEUE_HEAD(opal_log_wait);
+
+/*
+ * Interface for user to acknowledge the error log.
+ *
+ * Once user acknowledge the log, we delete that record entry from the
+ * list and move it ack list.
+ */
+void opal_elog_ack(uint64_t ack_id)
+{
+ unsigned long flags;
+ struct opal_err_log *record, *next;
+ bool found = false;
+
+ printk(KERN_INFO "OPAL Log ACK=%llx", ack_id);
+
+ /* once user acknowledge a log delete record from list */
+ spin_lock_irqsave(&opal_elog_lock, flags);
+ list_for_each_entry_safe(record, next, &elog_list, link) {
+ if (ack_id == record->opal_log_id) {
+ list_del(&record->link);
+ list_add(&record->link, &elog_ack_list);
+ total_log_size -= OPAL_MAX_ERRLOG_SIZE;
+ found = true;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&opal_elog_lock, flags);
+
+ /* Send acknowledgement to FSP */
+ if (found)
+ opal_send_ack_elog(ack_id);
+ return;
+}
+
+
+static ssize_t elog_ack_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ uint32_t log_ack_id;
+ log_ack_id = *(uint32_t *) buf;
+
+ /* send acknowledgment to FSP */
+ opal_elog_ack(log_ack_id);
+ return 0;
+}
+
+/*
+ * Show error log records to user.
+ */
+static ssize_t opal_elog_show(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf,
+ loff_t pos, size_t count)
+{
+ unsigned long flags;
+ struct opal_err_log *record, *next;
+ size_t size = 0;
+ size_t data_to_copy = 0;
+ int error = 0;
+
+ /* Display one log at a time. */
+ if (count > OPAL_MAX_ERRLOG_SIZE)
+ count = OPAL_MAX_ERRLOG_SIZE;
+
+ spin_lock_irqsave(&opal_elog_lock, flags);
+ /* Align the pos to point within total errlog size. */
+ if (total_log_size && pos > total_log_size)
+ pos = pos % total_log_size;
+
+ /*
+ * if pos goes beyond total_log_size then we know we don't have any
+ * new record to show.
+ */
+ if (total_log_size == 0 || pos >= total_log_size) {
+ opal_log_available = 0;
+ if (filp->f_flags & O_NONBLOCK) {
+ spin_unlock_irqrestore(&opal_elog_lock, flags);
+ error = -EAGAIN;
+ goto out;
+ }
+ spin_unlock_irqrestore(&opal_elog_lock, flags);
+ pos = 0;
+
+ /* Wait until we get log from sapphire */
+ error = wait_event_interruptible(opal_log_wait,
+ opal_log_available);
+ if (error)
+ goto out;
+ spin_lock_irqsave(&opal_elog_lock, flags);
+ }
+
+ /*
+ * Show log record one by one through /sys/firmware/opal/opal_elog
+ */
+ list_for_each_entry_safe(record, next, &elog_list, link) {
+ if ((pos >= size) && (pos < (size + OPAL_MAX_ERRLOG_SIZE))) {
+ data_to_copy = OPAL_MAX_ERRLOG_SIZE - (pos - size);
+ if (count > data_to_copy)
+ count = data_to_copy;
+ memcpy(buf, record->data + (pos - size), count);
+ error = count;
+ break;
+ }
+ size += OPAL_MAX_ERRLOG_SIZE;
+ }
+ spin_unlock_irqrestore(&opal_elog_lock, flags);
+out:
+ return error;
+}
+
+/* Interface to read log from OPAL */
+static void opal_elog_read(void)
+{
+ struct opal_err_log *record;
+ size_t elog_size;
+ uint64_t log_id;
+ uint64_t elog_type;
+
+ unsigned long flags;
+ int rc = 0;
+
+ spin_lock_irqsave(&opal_elog_lock, flags);
+ if (list_empty(&elog_ack_list)) {
+ /*
+ * We have no more room to read logs. Ignore it for now,
+ * will read it later when we have enough space.
+ */
+ spin_unlock_irqrestore(&opal_elog_lock, flags);
+ return;
+ }
+
+ /* Pull out the free node. */
+ record = list_entry(elog_ack_list.next, struct opal_err_log, link);
+ list_del(&record->link);
+ spin_unlock_irqrestore(&opal_elog_lock, flags);
+
+ /* read log size and log ID from OPAL */
+ rc = opal_get_elog_size(&log_id, &elog_size, &elog_type);
+ if (rc != OPAL_SUCCESS) {
+ pr_err("ELOG: Opal log read failed\n");
+ return;
+ }
+ if (elog_size >= OPAL_MAX_ERRLOG_SIZE)
+ elog_size = OPAL_MAX_ERRLOG_SIZE;
+
+ record->opal_log_id = log_id;
+ record->opal_log_size = elog_size;
+ memset(record->data, 0, sizeof(record->data));
+
+ mutex_lock(&err_log_data_mutex);
+ rc = opal_read_elog(__pa(err_log_data), elog_size, log_id);
+ if (rc != OPAL_SUCCESS) {
+ mutex_unlock(&err_log_data_mutex);
+ pr_err("ELOG: log read failed for log-id=%llx\n", log_id);
+ /* put back the free node. */
+ spin_lock_irqsave(&opal_elog_lock, flags);
+ list_add(&record->link, &elog_ack_list);
+ spin_unlock_irqrestore(&opal_elog_lock, flags);
+ return;
+ }
+ memcpy(record->data, err_log_data, elog_size);
+ mutex_unlock(&err_log_data_mutex);
+
+ spin_lock_irqsave(&opal_elog_lock, flags);
+ list_add_tail(&record->link, &elog_list);
+ total_log_size += OPAL_MAX_ERRLOG_SIZE;
+ spin_unlock_irqrestore(&opal_elog_lock, flags);
+
+ opal_log_available = 1;
+ wake_up_interruptible(&opal_log_wait);
+ return;
+}
+
+static void elog_work_fn(struct work_struct *work)
+{
+ opal_elog_read();
+}
+
+static DECLARE_WORK(elog_work, elog_work_fn);
+
+static int elog_event(struct notifier_block *nb,
+ unsigned long events, void *change)
+{
+ /* check for error log event */
+ if (events & OPAL_EVENT_ERROR_LOG_AVAIL)
+ schedule_work(&elog_work);
+ return 0;
+}
+
+/* Initialize sysfs file */
+static struct kobj_attribute opal_elog_ack_attr = __ATTR(opal_elog_ack,
+ 0200, NULL, elog_ack_store);
+
+static struct notifier_block elog_nb = {
+ .notifier_call = elog_event,
+ .next = NULL,
+ .priority = 0
+};
+
+static struct bin_attribute opal_elog_attr = {
+ .attr = {.name = "opal_elog", .mode = 0400},
+ .read = opal_elog_show,
+};
+
+/*
+ * Pre-allocate a buffer to hold handful of error logs until user space
+ * consumes it.
+ */
+static int init_err_log_buffer(void)
+{
+ int i = 0;
+ struct opal_err_log *buf_ptr;
+
+ buf_ptr = vmalloc(sizeof(struct opal_err_log) * MAX_NUM_RECORD);
+ if (!buf_ptr) {
+ printk(KERN_ERR "ELOG: failed to allocate memory.\n");
+ return -ENOMEM;
+ }
+ memset(buf_ptr, 0, sizeof(struct opal_err_log) * MAX_NUM_RECORD);
+
+ /* Initialize ack list will all free nodes. */
+ for (i = 0; i < MAX_NUM_RECORD; i++, buf_ptr++)
+ list_add(&buf_ptr->link, &elog_ack_list);
+ return 0;
+}
+
+/* Initialize error logging */
+int __init opal_elog_init(void)
+{
+ int rc = 0;
+
+ rc = init_err_log_buffer();
+ if (rc)
+ return rc;
+
+ rc = sysfs_create_bin_file(opal_kobj, &opal_elog_attr);
+ if (rc) {
+ printk(KERN_ERR "ELOG: unable to create sysfs file"
+ "opal_elog (%d)\n", rc);
+ return rc;
+ }
+
+ rc = sysfs_create_file(opal_kobj, &opal_elog_ack_attr.attr);
+ if (rc) {
+ printk(KERN_ERR "ELOG: unable to create sysfs file"
+ " opal_elog_ack (%d)\n", rc);
+ return rc;
+ }
+
+ rc = opal_notifier_register(&elog_nb);
+ if (rc) {
+ pr_err("%s: Can't register OPAL event notifier (%d)\n",
+ __func__, rc);
+ return rc;
+ }
+
+ /* We are now ready to pull error logs from opal. */
+ opal_resend_pending_logs();
+
+ return 0;
+}
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S
index e780650..a040b02 100644
--- a/arch/powerpc/platforms/powernv/opal-wrappers.S
+++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
@@ -123,6 +123,11 @@ OPAL_CALL(opal_xscom_write, OPAL_XSCOM_WRITE);
OPAL_CALL(opal_lpc_read, OPAL_LPC_READ);
OPAL_CALL(opal_lpc_write, OPAL_LPC_WRITE);
OPAL_CALL(opal_return_cpu, OPAL_RETURN_CPU);
+OPAL_CALL(opal_read_elog, OPAL_ELOG_READ);
+OPAL_CALL(opal_send_ack_elog, OPAL_ELOG_ACK);
+OPAL_CALL(opal_get_elog_size, OPAL_ELOG_SIZE);
+OPAL_CALL(opal_resend_pending_logs, OPAL_ELOG_RESEND);
+OPAL_CALL(opal_write_elog, OPAL_ELOG_WRITE);
OPAL_CALL(opal_validate_flash, OPAL_FLASH_VALIDATE);
OPAL_CALL(opal_manage_flash, OPAL_FLASH_MANAGE);
OPAL_CALL(opal_update_flash, OPAL_FLASH_UPDATE);
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index 31053be..20e1834 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -475,6 +475,8 @@ static int __init opal_init(void)
/* Create "opal" kobject under /sys/firmware */
rc = opal_sysfs_init();
if (rc == 0) {
+ /* Setup error log interface */
+ rc = opal_elog_init();
/* Setup code update interface */
opal_flash_init();
}
^ permalink raw reply related
* Re: [PATCH] This patch adds support to read error logs from OPAL and export them
From: Mahesh Jagannath Salgaonkar @ 2013-12-16 9:56 UTC (permalink / raw)
To: linuxppc-dev, Benjamin Herrenschmidt; +Cc: Vasant Hegde, Mamatha Inamdar
In-Reply-To: <20131216051720.30807.40785.stgit@mars.in.ibm.com>
On 12/16/2013 10:47 AM, Mahesh J Salgaonkar wrote:
> From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
>
> to userspace through sysfs interface /sys/firmware/opa/opal-elog.
>
> This patch buffers 128 error log records until it is consumed by userspace
> tool. This patch provides an sysfs interface '/sys/firmware/opa/opal-elog-ack'
> to user to receive an acknowledgement of successful log consumption.
>
> This is what user space tool would do:
> - Read error log from /sys/firmware/opa/opal-elog.
> - Save it to the disk.
> - Send an acknowledgement on successful consumption by writing error log
> id to /sys/firmware/opa/opal-elog-ack.
>
> Signed-off-by: Mamatha Inamdar <mamatha4@linux.vnet.ibm.com>
> Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Please ignore this patch. I messed up the subject line, I dunno how.. My
bad. I will resend this patch with correct subject.
Thanks,
-Mahesh.
^ permalink raw reply
* Re: [PATCH 1/5] powerpc/85xx/dts: add third elo3 dma component
From: Hongbo Zhang @ 2013-12-16 9:12 UTC (permalink / raw)
To: Liu Shengzhou-B36685, linuxppc-dev@lists.ozlabs.org,
Wood Scott-B07421
In-Reply-To: <ae3fab730b4a45c0812d3ca5a89fce52@DM2PR03MB398.namprd03.prod.outlook.com>
On 12/13/2013 01:43 PM, Liu Shengzhou-B36685 wrote:
>
>> -----Original Message-----
>> From: Hongbo Zhang [mailto:hongbo.zhang@freescale.com]
>> Sent: Thursday, December 12, 2013 5:57 PM
>> To: Liu Shengzhou-B36685; linuxppc-dev@lists.ozlabs.org; Wood Scott-
>> B07421
>> Subject: Re: [PATCH 1/5] powerpc/85xx/dts: add third elo3 dma component
>>
>> Shengzhou,
>> I canceled my patch http://patchwork.ozlabs.org/patch/295157/ because the
>> original wrong elo3-dma-2.dtsi hadn't been merged.
>> But please pay attention to comments from Scott about my changes of
>> adding 208 for some interrupts, and take some actions if needed, or
>> further discussions.
>>
>> Below comments form Scott:
>> "The FSL MPIC binding should be updated to point out how this works.
>> Technically it's not a change to the binding itself, since it's defined
>> in terms of register offset, but the explanatory text says "So interrupt
>> 0 is at offset 0x0, interrupt 1 is at offset 0x20, and so on." which is
>> not accurate for these new high interrupt numbers."
>>
> Hongbo,
> Could you update FSL MPIC binding as Scott pointed out?
We only need to add more explanatory text after the sentence Scott
pointed out, like:
"But for some hardwares, the MPIC registers for interrupts are not
continuous in address, in such cases, an offset can be added to the
interrupt number to skip the registers which is not for interrupts."
Scott, is that OK?
Thanks.
> thanks,
> Shengzhou
^ permalink raw reply
* Re: [PATCH 6/9] powerpc/pci: Use dev_is_pci() to check whether it is pci device
From: Yijing Wang @ 2013-12-16 9:05 UTC (permalink / raw)
To: Wei Yang
Cc: linux-pci, linux-kernel, Scott Wood, Paul Mackerras, Hanjun Guo,
Bjorn Helgaas, linuxppc-dev
In-Reply-To: <20131216071305.GA16842@weiyang.vnet.ibm.com>
On 2013/12/16 15:13, Wei Yang wrote:
> Yijing,
>
> This one looks good.
>
> While I take a look at the source code, there are around 20 places with
> similar style. Do you think it would be good to change all these places
> in one patch?
I sent the other similar changes to related maillist, some of them (David, Greg )has been accepted,
and other is not. :)
eg.
http://article.gmane.org/gmane.linux.kernel/1608341/match=dev_is_pci
Thanks!
Yijing.
>
> On Thu, Dec 05, 2013 at 08:01:20PM +0800, Yijing Wang wrote:
>> Use PCI standard marco dev_is_pci() instead of directly compare
>> pci_bus_type to check whether it is pci device.
>>
>> Signed-off-by: Yijing Wang <wangyijing@huawei.com>
>> ---
>> arch/powerpc/sysdev/fsl_pci.c | 2 +-
>> 1 files changed, 1 insertions(+), 1 deletions(-)
>>
>> diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
>> index 4dfd61d..7066e52 100644
>> --- a/arch/powerpc/sysdev/fsl_pci.c
>> +++ b/arch/powerpc/sysdev/fsl_pci.c
>> @@ -122,7 +122,7 @@ static int fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask)
>> * address width of the SoC such that we can address any internal
>> * SoC address from across PCI if needed
>> */
>> - if ((dev->bus == &pci_bus_type) &&
>> + if ((dev_is_pci(dev)) &&
>> dma_mask >= DMA_BIT_MASK(MAX_PHYS_ADDR_BITS)) {
>> set_dma_ops(dev, &dma_direct_ops);
>> set_dma_offset(dev, pci64_dma_offset);
>> --
>> 1.7.1
>>
>>
>> _______________________________________________
>> Linuxppc-dev mailing list
>> Linuxppc-dev@lists.ozlabs.org
>> https://lists.ozlabs.org/listinfo/linuxppc-dev
>
--
Thanks!
Yijing
^ permalink raw reply
* [PATCH] powerpc: Make unaligned accesses endian-safe for powerpc
From: Anton Blanchard @ 2013-12-16 7:58 UTC (permalink / raw)
To: Rajesh B Prathipati, benh, paulus; +Cc: linuxppc-dev
In-Reply-To: <52A9DA34.40905@linux.vnet.ibm.com>
From: Rajesh B Prathipati <rprathip@linux.vnet.ibm.com>
The generic put_unaligned/get_unaligned macros were made endian-safe by
calling the appropriate endian dependent macros based on the endian type
of the powerpc processor.
Signed-off-by: Rajesh B Prathipati <rprathip@linux.vnet.ibm.com>
Signed-off-by: Anton Blanchard <anton@samba.org>
---
diff --git a/arch/powerpc/include/asm/unaligned.h b/arch/powerpc/include/asm/unaligned.h
index 5f1b1e3..8296381 100644
--- a/arch/powerpc/include/asm/unaligned.h
+++ b/arch/powerpc/include/asm/unaligned.h
@@ -4,13 +4,18 @@
#ifdef __KERNEL__
/*
- * The PowerPC can do unaligned accesses itself in big endian mode.
+ * The PowerPC can do unaligned accesses itself based on its endian mode.
*/
#include <linux/unaligned/access_ok.h>
#include <linux/unaligned/generic.h>
+#ifdef __LITTLE_ENDIAN__
+#define get_unaligned __get_unaligned_le
+#define put_unaligned __put_unaligned_le
+#else
#define get_unaligned __get_unaligned_be
#define put_unaligned __put_unaligned_be
+#endif
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_UNALIGNED_H */
^ permalink raw reply related
* Re: [PATCH 6/9] powerpc/pci: Use dev_is_pci() to check whether it is pci device
From: Wei Yang @ 2013-12-16 7:13 UTC (permalink / raw)
To: Yijing Wang
Cc: linux-pci, linux-kernel, Scott Wood, Paul Mackerras, Hanjun Guo,
Bjorn Helgaas, linuxppc-dev
In-Reply-To: <1386244880-22300-1-git-send-email-wangyijing@huawei.com>
Yijing,
This one looks good.
While I take a look at the source code, there are around 20 places with
similar style. Do you think it would be good to change all these places
in one patch?
On Thu, Dec 05, 2013 at 08:01:20PM +0800, Yijing Wang wrote:
>Use PCI standard marco dev_is_pci() instead of directly compare
>pci_bus_type to check whether it is pci device.
>
>Signed-off-by: Yijing Wang <wangyijing@huawei.com>
>---
> arch/powerpc/sysdev/fsl_pci.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
>diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
>index 4dfd61d..7066e52 100644
>--- a/arch/powerpc/sysdev/fsl_pci.c
>+++ b/arch/powerpc/sysdev/fsl_pci.c
>@@ -122,7 +122,7 @@ static int fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask)
> * address width of the SoC such that we can address any internal
> * SoC address from across PCI if needed
> */
>- if ((dev->bus == &pci_bus_type) &&
>+ if ((dev_is_pci(dev)) &&
> dma_mask >= DMA_BIT_MASK(MAX_PHYS_ADDR_BITS)) {
> set_dma_ops(dev, &dma_direct_ops);
> set_dma_offset(dev, pci64_dma_offset);
>--
>1.7.1
>
>
>_______________________________________________
>Linuxppc-dev mailing list
>Linuxppc-dev@lists.ozlabs.org
>https://lists.ozlabs.org/listinfo/linuxppc-dev
--
Richard Yang
Help you, Help me
^ permalink raw reply
* RE: [PATCH v5 4/4] powerpc/85xx: add sysfs for pw20 state and altivec idle
From: Dongsheng.Wang @ 2013-12-16 5:53 UTC (permalink / raw)
To: Bharat.Bhushan@freescale.com, Scott Wood
Cc: linuxppc-dev@lists.ozlabs.org, Dongsheng.Wang@freescale.com
In-Reply-To: <6A3DF150A5B70D4F9B66A25E3F7C888D071EEABB@039-SN2MPN1-013.039d.mgd.msft.net>
DQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogQmh1c2hhbiBCaGFyYXQt
UjY1Nzc3DQo+IFNlbnQ6IE1vbmRheSwgTm92ZW1iZXIgMTEsIDIwMTMgMTI6MTEgUE0NCj4gVG86
IFdhbmcgRG9uZ3NoZW5nLUI0MDUzNDsgV29vZCBTY290dC1CMDc0MjENCj4gQ2M6IGxpbnV4cHBj
LWRldkBsaXN0cy5vemxhYnMub3JnDQo+IFN1YmplY3Q6IFJFOiBbUEFUQ0ggdjUgNC80XSBwb3dl
cnBjLzg1eHg6IGFkZCBzeXNmcyBmb3IgcHcyMCBzdGF0ZSBhbmQgYWx0aXZlYw0KPiBpZGxlDQo+
IA0KPiA+ID4gVGhvc2UgY29kZXMganVzdCBmb3IgZGlzY3VzcyB3aXRoIEJoYXJhdC4gSGUgd2Fu
dCB0byBtYWtlIG9uZSBmbG93IGF0DQo+ID4gPiAic2hvd19wdzIwX3dhaXRfdGltZSIvIiBzaG93
X2FsdGl2ZWNfaWRsZV93YWl0X3RpbWUiIGZ1bmN0aW9uLiBJZiB3ZQ0KPiA+ID4gZG8gdGhhdCwg
d2UgbmVlZCB0byBpbml0aWFsaXplIHB3MjBfd3QvYWx0aXZlY19pZGxlX3d0Lg0KPiA+ID4NCj4g
PiBJIHdpbGwga2VlcCB0aGlzIHN0dWZmIGF0ICJzaG93X3B3MjBfd2FpdF90aW1lIi8ic2hvd19h
bHRpdmVjX2lkbGVfd2FpdF90aW1lIg0KPiA+IGFuZCBhZGQgYSBjb21tZW50IGJlZm9yZSBvdXIg
ZGlzY3Vzc2lvbi4NCj4gPg0KPiA+IC8qDQo+ID4gICogSWYgdGhlICJ2YWx1ZSIgbGVzcyB0aGFu
IDEwLCB0aGlzIHdpbGwgb3ZlcmZsb3cuDQo+ID4gICogRnJvbSBiZW5jaG1hcmsgdGVzdCwgdGhl
IGRlZmF1bHQgd2FpdCBiaXQgd2lsbCBub3QgYmUgc2V0IGxlc3MgdGhhbiAxMGJpdC4NCj4gPiAg
KiBCZWNhdXNlIDEwIGJpdCBjb3JyZXNwb25kcyB0byB0aGUgd2FpdCBlbnRyeSB0aW1lIGlzIDQz
OTM3NTU3MzQwMTk5OTYwOShucyksDQo+ID4gICogZm9yIHdhaXQtZW50cnktaWRsZSB0aW1lIHRo
aXMgdmFsdWUgbG9va3MgdG9vIGxvbmcsIGFuZCB3ZSBjYW5ub3QgdXNlIHRob3NlDQo+ID4gICog
ImxvbmciIHRpbWUgYXMgYSBkZWZhdWx0IHdhaXQtZW50cnkgdGltZS4gU28gb3ZlcmZsb3cgY291
bGQgbm90IGhhdmUNCj4gaGFwcGVuZWQNCj4gPiAgKiBhbmQgd2UgdXNlIHRoaXMgY2FsY3VsYXRp
b24gbWV0aG9kIHRvIGdldCB3YWl0LWVudHJ5LWlkbGUgdGltZS4NCj4gPiAgKi8NCj4gDQo+IEkg
dGhpbmsgbm93IHdlIHdpbGwgdXNlIHNhbWUgY2FsY3VsYXRpb24gY29kZSBmb3IgZGVmYXVsdCB2
YWx1ZSBhbmQgdXNlciBzZXQNCj4gdmFsdWUsIHNvIGFkZGluZyB0aGUgY29tbWVudCBpcyBub3Qg
c3VmZmljaWVudCwgd2Ugc2hvdWxkIGVycm9yIG91dCBmcm9tIHRoZQ0KPiBjb2RlIGlmIHZhbHVl
IGlzIGxlc3MgdGhhbiAxMC4gQXMgZGVmYXVsdCB2YWx1ZSBpcyBub3QgbGVzcyB0aGFuIDEwIHNv
IHRoaXMgd2lsbA0KPiBhbHdheXMgd29yayB3aXRoIGRlZmF1bHQgdmFsdWUgYnV0IGlmIHVzZXIg
dHJpZXMgdG8gc2V0IGxlc3MgdGhhbiAxMCB0aGVuIGVycm9yDQo+IG91dCBhbmQgYXNrIHVzZXIg
dG8gdHJ5IG1vcmUgdGhhbiA5Lg0KPiANCkFnYWluLCBvbmNlIHRoZSB1c2VyIGhhcyBzZXQgdXAg
YSB0aW1lLCB0aGUgY29kZSB3aWxsIGdvIHRvIGFub3RoZXIgYnJhbmNoLg0KDQplbHNlIHsNCgl0
aW1lID0gcHcyMF93dDsNCn0NCg0KV2UgZG8gc28gbXVjaCBmb3IgdGhpcyBhIGxpdHRsZSBmdW5j
dGlvbiBwcm9jZXNzaW5nIGlzIG5vdCB3b3J0aCBpdC4gSWYgd2UgY2FuJ3QNCmFncmVlIG9uIHRo
aXMgc3lzIGludGVyZmFjZS4gSSB3aWxsIGNoYW5nZSB0aGlzIHN5cyBpbnRlcmZhY2UgdG8gc2hv
d19wdzIwX3dhaXRfYml0LiA6KQ0KDQpjb2RlIGUuZzoNCnN0YXRpYyBzc2l6ZV90IHNob3dfcHcy
MF93YWl0X2JpdChzdHJ1Y3QgZGV2aWNlICpkZXYsDQogICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgIHN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLCBjaGFyICpidWYpDQp7DQogICAg
ICAgIHUzMiBlbnRyeV9iaXQ7DQogICAgICAgIHVuc2lnbmVkIGludCBjcHUgPSBkZXYtPmlkOw0K
DQogICAgICAgIHNtcF9jYWxsX2Z1bmN0aW9uX3NpbmdsZShjcHUsIGRvX3Nob3dfcHdybWd0Y3Iw
LCAmZW50cnlfYml0LCAxKTsNCiAgICAgICAgZW50cnlfYml0ID0gKGVudHJ5X2JpdCAmIFBXUk1H
VENSMF9QVzIwX0VOVCkgPj4NCiAgICAgICAgICAgICAgICBQV1JNR1RDUjBfUFcyMF9FTlRfU0hJ
RlQ7DQoNCiAgICAgICAgcmV0dXJuIHNwcmludGYoYnVmLCAiJXVcbiIsIGVudHJ5X2JpdCk7DQp9
DQoNCi1kb25nc2hlbmcNCg0KPiAtQmhhcmF0DQo=
^ permalink raw reply
* [PATCH] powerpc/book3s: Recover from MC in sapphire on SCOM read via MMIO.
From: Mahesh J Salgaonkar @ 2013-12-16 5:16 UTC (permalink / raw)
To: linuxppc-dev, Benjamin Herrenschmidt
From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
Detect and recover from machine check when inside opal on a special
scom load instructions. On specific SCOM read via MMIO we may get a machine
check exception with SRR0 pointing inside opal. To recover from MC
in this scenario, get a recovery instruction address and return to it from
MC.
OPAL will export the machine check recoverable ranges through
device tree node mcheck-recoverable-ranges under ibm,opal:
# hexdump /proc/device-tree/ibm,opal/mcheck-recoverable-ranges
0000000 0000 0000 3000 2804 0000 000c 0000 0000
0000010 3000 2814 0000 0000 3000 27f0 0000 000c
0000020 0000 0000 3000 2814 xxxx xxxx xxxx xxxx
0000030 llll llll yyyy yyyy yyyy yyyy
...
...
#
where:
xxxx xxxx xxxx xxxx = Starting instruction address
llll llll = Length of the address range.
yyyy yyyy yyyy yyyy = recovery address
Each recoverable address range entry is (start address, len,
recovery address), 2 cells each for start and recovery address, 1 cell for
len, totalling 5 cells per entry. During kernel boot time, build up the
recovery table with the list of recovery ranges from device-tree node which
will be used during machine check exception to recover from MMIO SCOM UE.
Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/machdep.h | 3 +
arch/powerpc/include/asm/mce.h | 3 +
arch/powerpc/include/asm/opal.h | 3 +
arch/powerpc/kernel/mce.c | 4 +
arch/powerpc/kernel/mce_power.c | 37 +++++++++++-
arch/powerpc/kernel/prom.c | 5 ++
arch/powerpc/platforms/powernv/opal.c | 100 +++++++++++++++++++++++++++++++-
arch/powerpc/platforms/powernv/setup.c | 1
8 files changed, 146 insertions(+), 10 deletions(-)
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index ad3025d..4da6574 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -170,6 +170,9 @@ struct machdep_calls {
int (*system_reset_exception)(struct pt_regs *regs);
int (*machine_check_exception)(struct pt_regs *regs);
+ /* Called during machine check exception to retrive fixup address. */
+ bool (*mce_check_early_recovery)(struct pt_regs *regs);
+
/* Motherboard/chipset features. This is a kind of general purpose
* hook used to control some machine specific features (like reset
* lines, chip power control, etc...).
diff --git a/arch/powerpc/include/asm/mce.h b/arch/powerpc/include/asm/mce.h
index a2b8c7b..2257d1e 100644
--- a/arch/powerpc/include/asm/mce.h
+++ b/arch/powerpc/include/asm/mce.h
@@ -187,7 +187,8 @@ struct mce_error_info {
#define MCE_EVENT_DONTRELEASE false
extern void save_mce_event(struct pt_regs *regs, long handled,
- struct mce_error_info *mce_err, uint64_t addr);
+ struct mce_error_info *mce_err, uint64_t nip,
+ uint64_t addr);
extern int get_mce_event(struct machine_check_event *mce, bool release);
extern void release_mce_event(void);
extern void machine_check_queue_event(void);
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 033c06b..5462fa7 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -733,6 +733,8 @@ int64_t opal_update_flash(uint64_t blk_list);
/* Internal functions */
extern int early_init_dt_scan_opal(unsigned long node, const char *uname, int depth, void *data);
+extern int early_init_dt_scan_recoverable_ranges(unsigned long node,
+ const char *uname, int depth, void *data);
extern int opal_get_chars(uint32_t vtermno, char *buf, int count);
extern int opal_put_chars(uint32_t vtermno, const char *buf, int total_len);
@@ -761,6 +763,7 @@ extern void opal_nvram_init(void);
extern void opal_flash_init(void);
extern int opal_machine_check(struct pt_regs *regs);
+extern bool opal_mce_check_early_recovery(struct pt_regs *regs);
extern void opal_shutdown(void);
diff --git a/arch/powerpc/kernel/mce.c b/arch/powerpc/kernel/mce.c
index c0c52ec..d6edf2b 100644
--- a/arch/powerpc/kernel/mce.c
+++ b/arch/powerpc/kernel/mce.c
@@ -64,7 +64,7 @@ static void mce_set_error_info(struct machine_check_event *mce,
*/
void save_mce_event(struct pt_regs *regs, long handled,
struct mce_error_info *mce_err,
- uint64_t addr)
+ uint64_t nip, uint64_t addr)
{
uint64_t srr1;
int index = __get_cpu_var(mce_nest_count)++;
@@ -80,7 +80,7 @@ void save_mce_event(struct pt_regs *regs, long handled,
/* Populate generic machine check info */
mce->version = MCE_V1;
- mce->srr0 = regs->nip;
+ mce->srr0 = nip;
mce->srr1 = regs->msr;
mce->gpr3 = regs->gpr[3];
mce->in_use = 1;
diff --git a/arch/powerpc/kernel/mce_power.c b/arch/powerpc/kernel/mce_power.c
index b36e777..4317194 100644
--- a/arch/powerpc/kernel/mce_power.c
+++ b/arch/powerpc/kernel/mce_power.c
@@ -26,6 +26,7 @@
#include <linux/ptrace.h>
#include <asm/mmu.h>
#include <asm/mce.h>
+#include <asm/machdep.h>
/* flush SLBs and reload */
static void flush_and_reload_slb(void)
@@ -197,13 +198,32 @@ static void mce_get_derror_p7(struct mce_error_info *mce_err, uint64_t dsisr)
}
}
+static long mce_handle_ue_error(struct pt_regs *regs)
+{
+ long handled = 0;
+
+ /*
+ * On specific SCOM read via MMIO we may get a machine check
+ * exception with SRR0 pointing inside opal. If that is the
+ * case OPAL may have recovery address to re-read SCOM data in
+ * different way and hence we can recover from this MC.
+ */
+
+ if (ppc_md.mce_check_early_recovery) {
+ if (ppc_md.mce_check_early_recovery(regs))
+ handled = 1;
+ }
+ return handled;
+}
+
long __machine_check_early_realmode_p7(struct pt_regs *regs)
{
- uint64_t srr1, addr;
+ uint64_t srr1, nip, addr;
long handled = 1;
struct mce_error_info mce_error_info = { 0 };
srr1 = regs->msr;
+ nip = regs->nip;
/*
* Handle memory errors depending whether this was a load/store or
@@ -221,7 +241,11 @@ long __machine_check_early_realmode_p7(struct pt_regs *regs)
addr = regs->nip;
}
- save_mce_event(regs, handled, &mce_error_info, addr);
+ /* Handle UE error. */
+ if (mce_error_info.error_type == MCE_ERROR_TYPE_UE)
+ handled = mce_handle_ue_error(regs);
+
+ save_mce_event(regs, handled, &mce_error_info, nip, addr);
return handled;
}
@@ -263,11 +287,12 @@ static long mce_handle_derror_p8(uint64_t dsisr)
long __machine_check_early_realmode_p8(struct pt_regs *regs)
{
- uint64_t srr1, addr;
+ uint64_t srr1, nip, addr;
long handled = 1;
struct mce_error_info mce_error_info = { 0 };
srr1 = regs->msr;
+ nip = regs->nip;
if (P7_SRR1_MC_LOADSTORE(srr1)) {
handled = mce_handle_derror_p8(regs->dsisr);
@@ -279,6 +304,10 @@ long __machine_check_early_realmode_p8(struct pt_regs *regs)
addr = regs->nip;
}
- save_mce_event(regs, handled, &mce_error_info, addr);
+ /* Handle UE error. */
+ if (mce_error_info.error_type == MCE_ERROR_TYPE_UE)
+ handled = mce_handle_ue_error(regs);
+
+ save_mce_event(regs, handled, &mce_error_info, nip, addr);
return handled;
}
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index fa0ad8a..bcd84f0 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -737,6 +737,11 @@ void __init early_init_devtree(void *params)
spinning_secondaries = boot_cpu_count - 1;
#endif
+#ifdef CONFIG_PPC_POWERNV
+ /* Scan and build the list of machine check recoverable ranges */
+ of_scan_flat_dt(early_init_dt_scan_recoverable_ranges, NULL);
+#endif
+
DBG(" <- early_init_devtree()\n");
}
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index 01e74cb..31053be 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -20,6 +20,7 @@
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/kobject.h>
+#include <linux/memblock.h>
#include <asm/opal.h>
#include <asm/firmware.h>
#include <asm/mce.h>
@@ -32,8 +33,18 @@ struct kobject *opal_kobj;
struct opal {
u64 base;
u64 entry;
+ u64 size;
} opal;
+struct mcheck_recoverable_range {
+ u64 start_addr;
+ u64 end_addr;
+ u64 recover_addr;
+};
+
+static struct mcheck_recoverable_range *mc_recoverable_range;
+static int mc_recoverable_range_len;
+
static struct device_node *opal_node;
static DEFINE_SPINLOCK(opal_write_lock);
extern u64 opal_mc_secondary_handler[];
@@ -47,25 +58,29 @@ static atomic_t opal_notifier_hold = ATOMIC_INIT(0);
int __init early_init_dt_scan_opal(unsigned long node,
const char *uname, int depth, void *data)
{
- const void *basep, *entryp;
- unsigned long basesz, entrysz;
+ const void *basep, *entryp, *sizep;
+ unsigned long basesz, entrysz, runtimesz;
if (depth != 1 || strcmp(uname, "ibm,opal") != 0)
return 0;
basep = of_get_flat_dt_prop(node, "opal-base-address", &basesz);
entryp = of_get_flat_dt_prop(node, "opal-entry-address", &entrysz);
+ sizep = of_get_flat_dt_prop(node, "opal-runtime-size", &runtimesz);
- if (!basep || !entryp)
+ if (!basep || !entryp || !sizep)
return 1;
opal.base = of_read_number(basep, basesz/4);
opal.entry = of_read_number(entryp, entrysz/4);
+ opal.size = of_read_number(sizep, runtimesz/4);
pr_debug("OPAL Base = 0x%llx (basep=%p basesz=%ld)\n",
opal.base, basep, basesz);
pr_debug("OPAL Entry = 0x%llx (entryp=%p basesz=%ld)\n",
opal.entry, entryp, entrysz);
+ pr_debug("OPAL Entry = 0x%llx (sizep=%p runtimesz=%ld)\n",
+ opal.size, sizep, runtimesz);
powerpc_firmware_features |= FW_FEATURE_OPAL;
if (of_flat_dt_is_compatible(node, "ibm,opal-v3")) {
@@ -82,6 +97,53 @@ int __init early_init_dt_scan_opal(unsigned long node,
return 1;
}
+int __init early_init_dt_scan_recoverable_ranges(unsigned long node,
+ const char *uname, int depth, void *data)
+{
+ unsigned long i, size;
+ const __be32 *prop;
+
+ if (depth != 1 || strcmp(uname, "ibm,opal") != 0)
+ return 0;
+
+ prop = of_get_flat_dt_prop(node, "mcheck-recoverable-ranges", &size);
+
+ if (!prop)
+ return 1;
+
+ pr_debug("Found machine check recoverable ranges.\n");
+
+ /*
+ * Allocate a buffer to hold the MC recoverable ranges. We would be
+ * accessing them in real mode, hence it needs to be within
+ * RMO region.
+ */
+ mc_recoverable_range =__va(memblock_alloc_base(size, __alignof__(u64),
+ ppc64_rma_size));
+ memset(mc_recoverable_range, 0, size);
+
+ /*
+ * Each recoverable address entry is an (start address,len,
+ * recover address) pair, * 2 cells each, totalling 4 cells per entry.
+ */
+ for (i = 0; i < size / (sizeof(*prop) * 5); i++) {
+ mc_recoverable_range[i].start_addr =
+ of_read_number(prop + (i * 5) + 0, 2);
+ mc_recoverable_range[i].end_addr =
+ mc_recoverable_range[i].start_addr +
+ of_read_number(prop + (i * 5) + 2, 1);
+ mc_recoverable_range[i].recover_addr =
+ of_read_number(prop + (i * 5) + 3, 2);
+
+ pr_debug("Machine check recoverable range: %llx..%llx: %llx\n",
+ mc_recoverable_range[i].start_addr,
+ mc_recoverable_range[i].end_addr,
+ mc_recoverable_range[i].recover_addr);
+ }
+ mc_recoverable_range_len = i;
+ return 1;
+}
+
static int __init opal_register_exception_handlers(void)
{
#ifdef __BIG_ENDIAN__
@@ -310,6 +372,38 @@ int opal_machine_check(struct pt_regs *regs)
return 0;
}
+static uint64_t find_recovery_address(uint64_t nip)
+{
+ int i;
+
+ for (i = 0; i < mc_recoverable_range_len; i++)
+ if ((nip >= mc_recoverable_range[i].start_addr) &&
+ (nip < mc_recoverable_range[i].end_addr))
+ return mc_recoverable_range[i].recover_addr;
+ return 0;
+}
+
+bool opal_mce_check_early_recovery(struct pt_regs *regs)
+{
+ uint64_t recover_addr = 0;
+
+ if (!opal.base || !opal.size)
+ goto out;
+
+ if ((regs->nip >= opal.base) &&
+ (regs->nip <= (opal.base + opal.size)))
+ recover_addr = find_recovery_address(regs->nip);
+
+ /*
+ * Setup regs->nip to rfi into fixup address.
+ */
+ if (recover_addr)
+ regs->nip = recover_addr;
+
+out:
+ return !!recover_addr;
+}
+
static irqreturn_t opal_interrupt(int irq, void *data)
{
__be64 events;
diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c
index 19884b2..96b737f 100644
--- a/arch/powerpc/platforms/powernv/setup.c
+++ b/arch/powerpc/platforms/powernv/setup.c
@@ -177,6 +177,7 @@ static void __init pnv_setup_machdep_opal(void)
ppc_md.power_off = pnv_power_off;
ppc_md.halt = pnv_halt;
ppc_md.machine_check_exception = opal_machine_check;
+ ppc_md.mce_check_early_recovery = opal_mce_check_early_recovery;
}
#ifdef CONFIG_PPC_POWERNV_RTAS
^ permalink raw reply related
* [PATCH] This patch adds support to read error logs from OPAL and export them
From: Mahesh J Salgaonkar @ 2013-12-16 5:17 UTC (permalink / raw)
To: linuxppc-dev, Benjamin Herrenschmidt; +Cc: Vasant Hegde, Mamatha Inamdar
From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
to userspace through sysfs interface /sys/firmware/opa/opal-elog.
This patch buffers 128 error log records until it is consumed by userspace
tool. This patch provides an sysfs interface '/sys/firmware/opa/opal-elog-ack'
to user to receive an acknowledgement of successful log consumption.
This is what user space tool would do:
- Read error log from /sys/firmware/opa/opal-elog.
- Save it to the disk.
- Send an acknowledgement on successful consumption by writing error log
id to /sys/firmware/opa/opal-elog-ack.
Signed-off-by: Mamatha Inamdar <mamatha4@linux.vnet.ibm.com>
Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/opal.h | 11 +
arch/powerpc/platforms/powernv/Makefile | 2
arch/powerpc/platforms/powernv/opal-elog.c | 309 ++++++++++++++++++++++++
arch/powerpc/platforms/powernv/opal-wrappers.S | 5
arch/powerpc/platforms/powernv/opal.c | 2
5 files changed, 328 insertions(+), 1 deletion(-)
create mode 100644 arch/powerpc/platforms/powernv/opal-elog.c
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 5462fa7..723a7db 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -129,6 +129,11 @@ extern int opal_enter_rtas(struct rtas_args *args,
#define OPAL_LPC_READ 67
#define OPAL_LPC_WRITE 68
#define OPAL_RETURN_CPU 69
+#define OPAL_ELOG_READ 71
+#define OPAL_ELOG_WRITE 72
+#define OPAL_ELOG_ACK 73
+#define OPAL_ELOG_RESEND 74
+#define OPAL_ELOG_SIZE 75
#define OPAL_FLASH_VALIDATE 76
#define OPAL_FLASH_MANAGE 77
#define OPAL_FLASH_UPDATE 78
@@ -727,6 +732,11 @@ int64_t opal_lpc_write(uint32_t chip_id, enum OpalLPCAddressType addr_type,
uint32_t addr, uint32_t data, uint32_t sz);
int64_t opal_lpc_read(uint32_t chip_id, enum OpalLPCAddressType addr_type,
uint32_t addr, uint32_t *data, uint32_t sz);
+int64_t opal_read_elog(uint64_t buffer, size_t size, uint64_t log_id);
+int64_t opal_get_elog_size(uint64_t *log_id, size_t *size, uint64_t *elog_type);
+int64_t opal_write_elog(uint64_t buffer, uint64_t size, uint64_t offset);
+int64_t opal_send_ack_elog(uint64_t log_id);
+void opal_resend_pending_logs(void);
int64_t opal_validate_flash(uint64_t buffer, uint32_t *size, uint32_t *result);
int64_t opal_manage_flash(uint8_t op);
int64_t opal_update_flash(uint64_t blk_list);
@@ -761,6 +771,7 @@ extern void opal_get_rtc_time(struct rtc_time *tm);
extern unsigned long opal_get_boot_time(void);
extern void opal_nvram_init(void);
extern void opal_flash_init(void);
+extern int opal_elog_init(void);
extern int opal_machine_check(struct pt_regs *regs);
extern bool opal_mce_check_early_recovery(struct pt_regs *regs);
diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile
index 873fa13..0f692eb 100644
--- a/arch/powerpc/platforms/powernv/Makefile
+++ b/arch/powerpc/platforms/powernv/Makefile
@@ -1,6 +1,6 @@
obj-y += setup.o opal-takeover.o opal-wrappers.o opal.o
obj-y += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o
-obj-y += rng.o
+obj-y += rng.o opal-elog.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_PCI) += pci.o pci-p5ioc2.o pci-ioda.o
diff --git a/arch/powerpc/platforms/powernv/opal-elog.c b/arch/powerpc/platforms/powernv/opal-elog.c
new file mode 100644
index 0000000..fc891ae
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/opal-elog.c
@@ -0,0 +1,309 @@
+/*
+ * Error log support on PowerNV.
+ *
+ * Copyright 2013 IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/fs.h>
+#include <linux/vmalloc.h>
+#include <linux/fcntl.h>
+#include <asm/uaccess.h>
+#include <asm/opal.h>
+
+/* Maximum size of a single log on FSP is 16KB */
+#define OPAL_MAX_ERRLOG_SIZE 16384
+
+/* maximu number of records powernv can hold */
+#define MAX_NUM_RECORD 128
+
+struct opal_err_log {
+ struct list_head link;
+ uint64_t opal_log_id;
+ size_t opal_log_size;
+ uint8_t data[OPAL_MAX_ERRLOG_SIZE];
+};
+
+/* Pre-allocated temp buffer to pull error log from opal. */
+static uint8_t err_log_data[OPAL_MAX_ERRLOG_SIZE];
+/* Protect err_log_data buf */
+static DEFINE_MUTEX(err_log_data_mutex);
+
+static uint64_t total_log_size;
+static bool opal_log_available;
+static LIST_HEAD(elog_list);
+static LIST_HEAD(elog_ack_list);
+
+/* lock to protect elog_list and elog-ack_list. */
+static DEFINE_SPINLOCK(opal_elog_lock);
+
+static DECLARE_WAIT_QUEUE_HEAD(opal_log_wait);
+
+/*
+ * Interface for user to acknowledge the error log.
+ *
+ * Once user acknowledge the log, we delete that record entry from the
+ * list and move it ack list.
+ */
+void opal_elog_ack(uint64_t ack_id)
+{
+ unsigned long flags;
+ struct opal_err_log *record, *next;
+ bool found = false;
+
+ printk(KERN_INFO "OPAL Log ACK=%llx", ack_id);
+
+ /* once user acknowledge a log delete record from list */
+ spin_lock_irqsave(&opal_elog_lock, flags);
+ list_for_each_entry_safe(record, next, &elog_list, link) {
+ if (ack_id == record->opal_log_id) {
+ list_del(&record->link);
+ list_add(&record->link, &elog_ack_list);
+ total_log_size -= OPAL_MAX_ERRLOG_SIZE;
+ found = true;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&opal_elog_lock, flags);
+
+ /* Send acknowledgement to FSP */
+ if (found)
+ opal_send_ack_elog(ack_id);
+ return;
+}
+
+
+static ssize_t elog_ack_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ uint32_t log_ack_id;
+ log_ack_id = *(uint32_t *) buf;
+
+ /* send acknowledgment to FSP */
+ opal_elog_ack(log_ack_id);
+ return 0;
+}
+
+/*
+ * Show error log records to user.
+ */
+static ssize_t opal_elog_show(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf,
+ loff_t pos, size_t count)
+{
+ unsigned long flags;
+ struct opal_err_log *record, *next;
+ size_t size = 0;
+ size_t data_to_copy = 0;
+ int error = 0;
+
+ /* Display one log at a time. */
+ if (count > OPAL_MAX_ERRLOG_SIZE)
+ count = OPAL_MAX_ERRLOG_SIZE;
+
+ spin_lock_irqsave(&opal_elog_lock, flags);
+ /* Align the pos to point within total errlog size. */
+ if (total_log_size && pos > total_log_size)
+ pos = pos % total_log_size;
+
+ /*
+ * if pos goes beyond total_log_size then we know we don't have any
+ * new record to show.
+ */
+ if (total_log_size == 0 || pos >= total_log_size) {
+ opal_log_available = 0;
+ if (filp->f_flags & O_NONBLOCK) {
+ spin_unlock_irqrestore(&opal_elog_lock, flags);
+ error = -EAGAIN;
+ goto out;
+ }
+ spin_unlock_irqrestore(&opal_elog_lock, flags);
+ pos = 0;
+
+ /* Wait until we get log from sapphire */
+ error = wait_event_interruptible(opal_log_wait,
+ opal_log_available);
+ if (error)
+ goto out;
+ spin_lock_irqsave(&opal_elog_lock, flags);
+ }
+
+ /*
+ * Show log record one by one through /sys/firmware/opal/opal_elog
+ */
+ list_for_each_entry_safe(record, next, &elog_list, link) {
+ if ((pos >= size) && (pos < (size + OPAL_MAX_ERRLOG_SIZE))) {
+ data_to_copy = OPAL_MAX_ERRLOG_SIZE - (pos - size);
+ if (count > data_to_copy)
+ count = data_to_copy;
+ memcpy(buf, record->data + (pos - size), count);
+ error = count;
+ break;
+ }
+ size += OPAL_MAX_ERRLOG_SIZE;
+ }
+ spin_unlock_irqrestore(&opal_elog_lock, flags);
+out:
+ return error;
+}
+
+/* Interface to read log from OPAL */
+static void opal_elog_read(void)
+{
+ struct opal_err_log *record;
+ size_t elog_size;
+ uint64_t log_id;
+ uint64_t elog_type;
+
+ unsigned long flags;
+ int rc = 0;
+
+ spin_lock_irqsave(&opal_elog_lock, flags);
+ if (list_empty(&elog_ack_list)) {
+ /*
+ * We have no more room to read logs. Ignore it for now,
+ * will read it later when we have enough space.
+ */
+ spin_unlock_irqrestore(&opal_elog_lock, flags);
+ return;
+ }
+
+ /* Pull out the free node. */
+ record = list_entry(elog_ack_list.next, struct opal_err_log, link);
+ list_del(&record->link);
+ spin_unlock_irqrestore(&opal_elog_lock, flags);
+
+ /* read log size and log ID from OPAL */
+ rc = opal_get_elog_size(&log_id, &elog_size, &elog_type);
+ if (rc != OPAL_SUCCESS) {
+ pr_err("ELOG: Opal log read failed\n");
+ return;
+ }
+ if (elog_size >= OPAL_MAX_ERRLOG_SIZE)
+ elog_size = OPAL_MAX_ERRLOG_SIZE;
+
+ record->opal_log_id = log_id;
+ record->opal_log_size = elog_size;
+ memset(record->data, 0, sizeof(record->data));
+
+ mutex_lock(&err_log_data_mutex);
+ rc = opal_read_elog(__pa(err_log_data), elog_size, log_id);
+ if (rc != OPAL_SUCCESS) {
+ mutex_unlock(&err_log_data_mutex);
+ pr_err("ELOG: log read failed for log-id=%llx\n", log_id);
+ /* put back the free node. */
+ spin_lock_irqsave(&opal_elog_lock, flags);
+ list_add(&record->link, &elog_ack_list);
+ spin_unlock_irqrestore(&opal_elog_lock, flags);
+ return;
+ }
+ memcpy(record->data, err_log_data, elog_size);
+ mutex_unlock(&err_log_data_mutex);
+
+ spin_lock_irqsave(&opal_elog_lock, flags);
+ list_add_tail(&record->link, &elog_list);
+ total_log_size += OPAL_MAX_ERRLOG_SIZE;
+ spin_unlock_irqrestore(&opal_elog_lock, flags);
+
+ opal_log_available = 1;
+ wake_up_interruptible(&opal_log_wait);
+ return;
+}
+
+static void elog_work_fn(struct work_struct *work)
+{
+ opal_elog_read();
+}
+
+static DECLARE_WORK(elog_work, elog_work_fn);
+
+static int elog_event(struct notifier_block *nb,
+ unsigned long events, void *change)
+{
+ /* check for error log event */
+ if (events & OPAL_EVENT_ERROR_LOG_AVAIL)
+ schedule_work(&elog_work);
+ return 0;
+}
+
+/* Initialize sysfs file */
+static struct kobj_attribute opal_elog_ack_attr = __ATTR(opal_elog_ack,
+ 0200, NULL, elog_ack_store);
+
+static struct notifier_block elog_nb = {
+ .notifier_call = elog_event,
+ .next = NULL,
+ .priority = 0
+};
+
+static struct bin_attribute opal_elog_attr = {
+ .attr = {.name = "opal_elog", .mode = 0400},
+ .read = opal_elog_show,
+};
+
+/*
+ * Pre-allocate a buffer to hold handful of error logs until user space
+ * consumes it.
+ */
+static int init_err_log_buffer(void)
+{
+ int i = 0;
+ struct opal_err_log *buf_ptr;
+
+ buf_ptr = vmalloc(sizeof(struct opal_err_log) * MAX_NUM_RECORD);
+ if (!buf_ptr) {
+ printk(KERN_ERR "ELOG: failed to allocate memory.\n");
+ return -ENOMEM;
+ }
+ memset(buf_ptr, 0, sizeof(struct opal_err_log) * MAX_NUM_RECORD);
+
+ /* Initialize ack list will all free nodes. */
+ for (i = 0; i < MAX_NUM_RECORD; i++, buf_ptr++)
+ list_add(&buf_ptr->link, &elog_ack_list);
+ return 0;
+}
+
+/* Initialize error logging */
+int __init opal_elog_init(void)
+{
+ int rc = 0;
+
+ rc = init_err_log_buffer();
+ if (rc)
+ return rc;
+
+ rc = sysfs_create_bin_file(opal_kobj, &opal_elog_attr);
+ if (rc) {
+ printk(KERN_ERR "ELOG: unable to create sysfs file"
+ "opal_elog (%d)\n", rc);
+ return rc;
+ }
+
+ rc = sysfs_create_file(opal_kobj, &opal_elog_ack_attr.attr);
+ if (rc) {
+ printk(KERN_ERR "ELOG: unable to create sysfs file"
+ " opal_elog_ack (%d)\n", rc);
+ return rc;
+ }
+
+ rc = opal_notifier_register(&elog_nb);
+ if (rc) {
+ pr_err("%s: Can't register OPAL event notifier (%d)\n",
+ __func__, rc);
+ return rc;
+ }
+
+ /* We are now ready to pull error logs from opal. */
+ opal_resend_pending_logs();
+
+ return 0;
+}
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S
index e780650..a040b02 100644
--- a/arch/powerpc/platforms/powernv/opal-wrappers.S
+++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
@@ -123,6 +123,11 @@ OPAL_CALL(opal_xscom_write, OPAL_XSCOM_WRITE);
OPAL_CALL(opal_lpc_read, OPAL_LPC_READ);
OPAL_CALL(opal_lpc_write, OPAL_LPC_WRITE);
OPAL_CALL(opal_return_cpu, OPAL_RETURN_CPU);
+OPAL_CALL(opal_read_elog, OPAL_ELOG_READ);
+OPAL_CALL(opal_send_ack_elog, OPAL_ELOG_ACK);
+OPAL_CALL(opal_get_elog_size, OPAL_ELOG_SIZE);
+OPAL_CALL(opal_resend_pending_logs, OPAL_ELOG_RESEND);
+OPAL_CALL(opal_write_elog, OPAL_ELOG_WRITE);
OPAL_CALL(opal_validate_flash, OPAL_FLASH_VALIDATE);
OPAL_CALL(opal_manage_flash, OPAL_FLASH_MANAGE);
OPAL_CALL(opal_update_flash, OPAL_FLASH_UPDATE);
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index 31053be..20e1834 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -475,6 +475,8 @@ static int __init opal_init(void)
/* Create "opal" kobject under /sys/firmware */
rc = opal_sysfs_init();
if (rc == 0) {
+ /* Setup error log interface */
+ rc = opal_elog_init();
/* Setup code update interface */
opal_flash_init();
}
^ permalink raw reply related
* Re: [PATCH 10/10] Kconfig: cleanup SERIO_I8042 dependencies
From: Dmitry Torokhov @ 2013-12-16 4:59 UTC (permalink / raw)
To: David Miller
Cc: linux-mips, linux-ia64, linux-sh, paulus, hpa, sparclinux, gxt,
linux, x86, mingo, msalter, fenghua.yu, tglx, linux-arm-kernel,
rth, tony.luck, linux-kernel, ralf, lethal, linux-alpha,
linuxppc-dev
In-Reply-To: <20131215.202725.1549146673897801643.davem@davemloft.net>
On Sun, Dec 15, 2013 at 08:27:25PM -0500, David Miller wrote:
> From: Mark Salter <msalter@redhat.com>
> Date: Sun, 15 Dec 2013 10:50:26 -0500
>
> > On Sun, 2013-12-15 at 02:36 -0800, Dmitry Torokhov wrote:
> >> How are we going to merge this? In bulk through input tree or peacemeal
> >> through all arches first?
> >
> > They should all go together to eliminate the chance of bisect breakage.
> > Either the input tree or maybe akpm tree.
>
> This sounds good to me.
OK, then I'll pick it up once I collect more acks from the arch
maintainers.
--
Dmitry
^ permalink raw reply
* Re: [RFC PATCH] time: Support in tick broadcast framework for archs without an external wakeup source
From: Preeti U Murthy @ 2013-12-16 4:36 UTC (permalink / raw)
To: peterz, fweisbec, paul.gortmaker, paulus, mingo, shangw,
rafael.j.wysocki, galak, benh, paulmck, arnd, linux-pm, rostedt,
michael, john.stultz, tglx, chenhui.zhao, deepthi, r58472, geoff,
linux-kernel, srivatsa.bhat, schwidefsky, svaidy, linuxppc-dev
In-Reply-To: <20131213041901.17199.37383.stgit@preeti.in.ibm.com>
Hi,
The patch had some compile time fixes to be done. It was accidentally mailed
out before doing so. Below is the right patch. Apologies for the same.
Thanks
Regards
Preeti U Murthy
-----------------------------------------------------------------------------
time: Support in tick broadcast framework for archs without an external wakeup source
From: Preeti U Murthy <preeti@linux.vnet.ibm.com>
On some architectures, in certain CPU deep idle states the local timers stop.
An external clock device is used to wakeup these CPUs. The kernel support for the
wakeup of these CPUs is provided by the tick broadcast framework by using the
external clock device as the wakeup source.
However on architectures like PowerPC there is no external clock device. This
patch includes support in the broadcast framework to handle the wakeup of the
CPUs in deep idle states on such architectures by queuing a hrtimer on one of
the CPUs, meant to handle the wakeup of CPUs in deep idle states. This CPU is
identified as the bc_cpu.
Each time the hrtimer expires, it is reprogrammed for the next wakeup of the
CPUs in deep idle state after handling broadcast. However when a CPU is about
to enter deep idle state with its wakeup time earlier than the time at which
the hrtimer is currently programmed, it *becomes the new bc_cpu* and restarts
the hrtimer on itself. This way the job of doing broadcast is handed around to
the CPUs that ask for the earliest wakeup just before entering deep idle
state. This is consistent with what happens in cases where an external clock
device is present. The smp affinity of this clock device is set to the CPU
with the earliest wakeup.
The important point here is that the bc_cpu cannot enter deep idle state
since it has a hrtimer queued to wakeup the other CPUs in deep idle. Hence it
cannot have its local timer stopped. Therefore for such a CPU, the
BROADCAST_ENTER notification has to fail implying that it cannot enter deep
idle state. On architectures where an external clock device is present, all
CPUs can enter deep idle.
During hotplug of the bc_cpu, the job of doing a broadcast is assigned to the
first cpu in the broadcast mask. This newly nominated bc_cpu is woken up by
an IPI so as to queue the above mentioned hrtimer on itself.
This patch is compile tested only.
Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
---
include/linux/clockchips.h | 4 +
kernel/time/clockevents.c | 8 +-
kernel/time/tick-broadcast.c | 161 +++++++++++++++++++++++++++++++++++++-----
kernel/time/tick-internal.h | 8 +-
4 files changed, 155 insertions(+), 26 deletions(-)
diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
index 493aa02..bbda37b 100644
--- a/include/linux/clockchips.h
+++ b/include/linux/clockchips.h
@@ -186,9 +186,9 @@ static inline int tick_check_broadcast_expired(void) { return 0; }
#endif
#ifdef CONFIG_GENERIC_CLOCKEVENTS
-extern void clockevents_notify(unsigned long reason, void *arg);
+extern int clockevents_notify(unsigned long reason, void *arg);
#else
-static inline void clockevents_notify(unsigned long reason, void *arg) {}
+static inline int clockevents_notify(unsigned long reason, void *arg) {}
#endif
#else /* CONFIG_GENERIC_CLOCKEVENTS_BUILD */
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
index 086ad60..bbbd671 100644
--- a/kernel/time/clockevents.c
+++ b/kernel/time/clockevents.c
@@ -525,11 +525,11 @@ void clockevents_resume(void)
/**
* clockevents_notify - notification about relevant events
*/
-void clockevents_notify(unsigned long reason, void *arg)
+int clockevents_notify(unsigned long reason, void *arg)
{
struct clock_event_device *dev, *tmp;
unsigned long flags;
- int cpu;
+ int cpu, ret = 0;
raw_spin_lock_irqsave(&clockevents_lock, flags);
@@ -542,11 +542,12 @@ void clockevents_notify(unsigned long reason, void *arg)
case CLOCK_EVT_NOTIFY_BROADCAST_ENTER:
case CLOCK_EVT_NOTIFY_BROADCAST_EXIT:
- tick_broadcast_oneshot_control(reason);
+ ret = tick_broadcast_oneshot_control(reason);
break;
case CLOCK_EVT_NOTIFY_CPU_DYING:
tick_handover_do_timer(arg);
+ tick_handover_bc_cpu(arg);
break;
case CLOCK_EVT_NOTIFY_SUSPEND:
@@ -585,6 +586,7 @@ void clockevents_notify(unsigned long reason, void *arg)
break;
}
raw_spin_unlock_irqrestore(&clockevents_lock, flags);
+ return ret;
}
EXPORT_SYMBOL_GPL(clockevents_notify);
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
index 9532690..4ba8abb 100644
--- a/kernel/time/tick-broadcast.c
+++ b/kernel/time/tick-broadcast.c
@@ -20,6 +20,7 @@
#include <linux/sched.h>
#include <linux/smp.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include "tick-internal.h"
@@ -35,6 +36,10 @@ static cpumask_var_t tmpmask;
static DEFINE_RAW_SPINLOCK(tick_broadcast_lock);
static int tick_broadcast_force;
+static struct hrtimer *bc_hrtimer;
+static int bc_cpu = -1;
+static ktime_t bc_next_wakeup;
+
#ifdef CONFIG_TICK_ONESHOT
static void tick_broadcast_clear_oneshot(int cpu);
#else
@@ -528,6 +533,20 @@ static int tick_broadcast_set_event(struct clock_event_device *bc, int cpu,
return ret;
}
+static void tick_broadcast_set_next_wakeup(int cpu, ktime_t expires, int force)
+{
+ struct clock_event_device *bc;
+
+ bc = tick_broadcast_device.evtdev;
+
+ if (bc) {
+ tick_broadcast_set_event(bc, cpu, expires, force);
+ } else {
+ hrtimer_start(bc_hrtimer, expires, HRTIMER_MODE_ABS_PINNED);
+ bc_cpu = cpu;
+ }
+}
+
int tick_resume_broadcast_oneshot(struct clock_event_device *bc)
{
clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT);
@@ -558,15 +577,13 @@ void tick_check_oneshot_broadcast(int cpu)
/*
* Handle oneshot mode broadcasting
*/
-static void tick_handle_oneshot_broadcast(struct clock_event_device *dev)
+static int tick_oneshot_broadcast(void)
{
struct tick_device *td;
ktime_t now, next_event;
int cpu, next_cpu = 0;
- raw_spin_lock(&tick_broadcast_lock);
-again:
- dev->next_event.tv64 = KTIME_MAX;
+ bc_next_wakeup.tv64 = KTIME_MAX;
next_event.tv64 = KTIME_MAX;
cpumask_clear(tmpmask);
now = ktime_get();
@@ -620,34 +637,89 @@ again:
* in the event mask
*/
if (next_event.tv64 != KTIME_MAX) {
- /*
- * Rearm the broadcast device. If event expired,
- * repeat the above
- */
- if (tick_broadcast_set_event(dev, next_cpu, next_event, 0))
+ bc_next_wakeup = next_event;
+ }
+
+ return next_cpu;
+}
+
+/*
+ * Handler in oneshot mode for the external clock device
+ */
+static void tick_handle_oneshot_broadcast(struct clock_event_device *dev)
+{
+ int next_cpu;
+
+ raw_spin_lock(&tick_broadcast_lock);
+
+again: next_cpu = tick_oneshot_broadcast();
+ /*
+ * Rearm the broadcast device. If event expired,
+ * repeat the above
+ */
+ if (bc_next_wakeup.tv64 != KTIME_MAX)
+ if (tick_broadcast_set_event(dev, next_cpu, bc_next_wakeup, 0))
goto again;
+
+ raw_spin_unlock(&tick_broadcast_lock);
+}
+
+/*
+ * Handler in oneshot mode for the hrtimer queued when there is no external
+ * clock device.
+ */
+static enum hrtimer_restart handle_broadcast(struct hrtimer *hrtmr)
+{
+ ktime_t now, interval;
+
+ raw_spin_lock(&tick_broadcast_lock);
+ tick_oneshot_broadcast();
+
+ now = ktime_get();
+
+ if (bc_next_wakeup.tv64 != KTIME_MAX) {
+ interval = ktime_sub(bc_next_wakeup, now);
+ hrtimer_forward_now(bc_hrtimer, interval);
+ raw_spin_unlock(&tick_broadcast_lock);
+ return HRTIMER_RESTART;
}
raw_spin_unlock(&tick_broadcast_lock);
+ return HRTIMER_NORESTART;
+}
+
+/* The CPU could be asked to take over from the previous bc_cpu,
+ * if it is being hotplugged out.
+ */
+static void tick_broadcast_exit_check(int cpu)
+{
+ if (cpu == bc_cpu)
+ hrtimer_start(bc_hrtimer, bc_next_wakeup,
+ HRTIMER_MODE_ABS_PINNED);
+}
+
+static int can_enter_broadcast(int cpu)
+{
+ return cpu != bc_cpu;
}
/*
* Powerstate information: The system enters/leaves a state, where
* affected devices might stop
*/
-void tick_broadcast_oneshot_control(unsigned long reason)
+int tick_broadcast_oneshot_control(unsigned long reason)
{
- struct clock_event_device *bc, *dev;
+ struct clock_event_device *dev;
struct tick_device *td;
unsigned long flags;
ktime_t now;
- int cpu;
+ int cpu, ret = 0;
/*
* Periodic mode does not care about the enter/exit of power
* states
*/
if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC)
- return;
+ return ret;
/*
* We are called with preemtion disabled from the depth of the
@@ -658,9 +730,8 @@ void tick_broadcast_oneshot_control(unsigned long reason)
dev = td->evtdev;
if (!(dev->features & CLOCK_EVT_FEAT_C3STOP))
- return;
+ return ret;
- bc = tick_broadcast_device.evtdev;
raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
if (reason == CLOCK_EVT_NOTIFY_BROADCAST_ENTER) {
@@ -676,12 +747,21 @@ void tick_broadcast_oneshot_control(unsigned long reason)
* woken by the IPI right away.
*/
if (!cpumask_test_cpu(cpu, tick_broadcast_force_mask) &&
- dev->next_event.tv64 < bc->next_event.tv64)
- tick_broadcast_set_event(bc, cpu, dev->next_event, 1);
+ dev->next_event.tv64 < bc_next_wakeup.tv64)
+ bc_next_wakeup = dev->next_event;
+ tick_broadcast_set_next_wakeup(cpu, dev->next_event, 1);
+
+ if (!can_enter_broadcast(cpu)) {
+ cpumask_test_and_clear_cpu(cpu, tick_broadcast_oneshot_mask);
+ clockevents_set_mode(dev, CLOCK_EVT_MODE_ONESHOT);
+ ret = 1;
+ }
}
} else {
if (cpumask_test_and_clear_cpu(cpu, tick_broadcast_oneshot_mask)) {
clockevents_set_mode(dev, CLOCK_EVT_MODE_ONESHOT);
+
+ tick_broadcast_exit_check(cpu);
/*
* The cpu which was handling the broadcast
* timer marked this cpu in the broadcast
@@ -746,6 +826,7 @@ void tick_broadcast_oneshot_control(unsigned long reason)
}
out:
raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
+ return ret;
}
/*
@@ -821,18 +902,62 @@ void tick_broadcast_switch_to_oneshot(void)
{
struct clock_event_device *bc;
unsigned long flags;
+ int cpu = smp_processor_id();
raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
+ bc_next_wakeup.tv64 = KTIME_MAX;
+
tick_broadcast_device.mode = TICKDEV_MODE_ONESHOT;
bc = tick_broadcast_device.evtdev;
- if (bc)
+ if (bc) {
tick_broadcast_setup_oneshot(bc);
+ bc_next_wakeup = bc->next_event;
+ } else {
+ /* An alternative to tick_broadcast_device on archs which do not have
+ * an external device
+ */
+ bc_hrtimer = kmalloc(sizeof(*bc_hrtimer), GFP_NOWAIT);
+ hrtimer_init(bc_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED);
+ bc_hrtimer->function = handle_broadcast;
+
+ /*
+ * There may be CPUs waiting for periodic broadcast. We need
+ * to set the oneshot bits for those and program the hrtimer
+ * to fire at the next tick period.
+ */
+ cpumask_copy(tmpmask, tick_broadcast_mask);
+ cpumask_clear_cpu(cpu, tmpmask);
+ cpumask_or(tick_broadcast_oneshot_mask,
+ tick_broadcast_oneshot_mask, tmpmask);
+
+ if (!cpumask_empty(tmpmask)) {
+ tick_broadcast_init_next_event(tmpmask,
+ tick_next_period);
+ hrtimer_start(bc_hrtimer, tick_next_period, HRTIMER_MODE_ABS_PINNED);
+ bc_next_wakeup = tick_next_period;
+ }
+ }
raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
}
+void tick_handover_bc_cpu(int *cpup)
+{
+ struct tick_device *td;
+
+ if (*cpup == bc_cpu) {
+ int cpu = cpumask_first(tick_broadcast_oneshot_mask);
+
+ bc_cpu = (cpu < nr_cpu_ids) ? cpu : -1;
+ if (bc_cpu != -1) {
+ td = &per_cpu(tick_cpu_device, bc_cpu);
+ td->evtdev->broadcast(cpumask_of(bc_cpu));
+ }
+ }
+}
+
/*
* Remove a dead CPU from broadcasting
*/
diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h
index 18e71f7..1f73032 100644
--- a/kernel/time/tick-internal.h
+++ b/kernel/time/tick-internal.h
@@ -46,23 +46,25 @@ extern int tick_switch_to_oneshot(void (*handler)(struct clock_event_device *));
extern void tick_resume_oneshot(void);
# ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
extern void tick_broadcast_setup_oneshot(struct clock_event_device *bc);
-extern void tick_broadcast_oneshot_control(unsigned long reason);
+extern int tick_broadcast_oneshot_control(unsigned long reason);
extern void tick_broadcast_switch_to_oneshot(void);
extern void tick_shutdown_broadcast_oneshot(unsigned int *cpup);
extern int tick_resume_broadcast_oneshot(struct clock_event_device *bc);
extern int tick_broadcast_oneshot_active(void);
extern void tick_check_oneshot_broadcast(int cpu);
+extern void tick_handover_bc_cpu(int *cpup);
bool tick_broadcast_oneshot_available(void);
# else /* BROADCAST */
static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
{
BUG();
}
-static inline void tick_broadcast_oneshot_control(unsigned long reason) { }
+static inline int tick_broadcast_oneshot_control(unsigned long reason) { }
static inline void tick_broadcast_switch_to_oneshot(void) { }
static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { }
static inline int tick_broadcast_oneshot_active(void) { return 0; }
static inline void tick_check_oneshot_broadcast(int cpu) { }
+static inline void tick_handover_bc_cpu(int *cpup) {}
static inline bool tick_broadcast_oneshot_available(void) { return true; }
# endif /* !BROADCAST */
@@ -87,7 +89,7 @@ static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
{
BUG();
}
-static inline void tick_broadcast_oneshot_control(unsigned long reason) { }
+static inline int tick_broadcast_oneshot_control(unsigned long reason) { }
static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { }
static inline int tick_resume_broadcast_oneshot(struct clock_event_device *bc)
{
^ permalink raw reply related
* [PATCH] powerpc: Fix bad stack check in exception entry
From: Michael Neuling @ 2013-12-16 4:12 UTC (permalink / raw)
To: benh; +Cc: Linux PPC dev, Paul Mackerras, anton
In EXCEPTION_PROLOG_COMMON() we check to see if the stack pointer (r1)
is valid when coming from the kernel. If it's not valid, we die but
with a nice oops message.
Currently we allocate a stack frame (subtract INT_FRAME_SIZE) before we
check to see if the stack pointer is negative. Unfortunately, this
won't detect a bad stack where r1 is less than INT_FRAME_SIZE.
This patch fixes the check to compare the modified r1 with
-INT_FRAME_SIZE. With this, bad kernel stack pointers (including NULL
pointers) are correctly detected again.
Kudos to Paulus for finding this.
Signed-off-by: Michael Neuling <mikey@neuling.org>
cc: stable@vger.kernel.org
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
index 894662a..243ce69 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -284,7 +284,7 @@ do_kvm_##n: \
subi r1,r1,INT_FRAME_SIZE; /* alloc frame on kernel stack */ \
beq- 1f; \
ld r1,PACAKSAVE(r13); /* kernel stack to use */ \
-1: cmpdi cr1,r1,0; /* check if r1 is in userspace */ \
+1: cmpdi cr1,r1,-INT_FRAME_SIZE; /* check if r1 is in userspace */ \
blt+ cr1,3f; /* abort if it is */ \
li r1,(n); /* will be reloaded later */ \
sth r1,PACA_TRAP_SAVE(r13); \
^ permalink raw reply related
* Re: [PATCH 10/10] Kconfig: cleanup SERIO_I8042 dependencies
From: David Miller @ 2013-12-16 1:27 UTC (permalink / raw)
To: msalter
Cc: linux-mips, linux-ia64, linux-sh, paulus, hpa, sparclinux, gxt,
linux, x86, mingo, fenghua.yu, tglx, linux-arm-kernel, rth,
tony.luck, dmitry.torokhov, linux-kernel, ralf, lethal,
linux-alpha, linuxppc-dev
In-Reply-To: <1387122626.1979.136.camel@deneb.redhat.com>
From: Mark Salter <msalter@redhat.com>
Date: Sun, 15 Dec 2013 10:50:26 -0500
> On Sun, 2013-12-15 at 02:36 -0800, Dmitry Torokhov wrote:
>> How are we going to merge this? In bulk through input tree or peacemeal
>> through all arches first?
>
> They should all go together to eliminate the chance of bisect breakage.
> Either the input tree or maybe akpm tree.
This sounds good to me.
^ permalink raw reply
* [git pull] Please pull powerpc.git merge branch
From: Benjamin Herrenschmidt @ 2013-12-16 0:57 UTC (permalink / raw)
To: Linus Torvalds; +Cc: linuxppc-dev list, Linux Kernel list
Hi Linus !
Here are some more powerpc fixes for 3.13.
Uli's patch fixes a regression in ptrace caused by a mis-merge of
a previous LE patch. The rest are all more endian fixes, all fairly
trivial, found during testing of 3.13-rc's.
Cheers,
Ben.
The following changes since commit e641eb03ab2b0f065fa5e64b4202fb5b0441b427:
powerpc: Fix up the kdump base cap to 128M (2013-12-10 11:28:39 +1100)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git merge
for you to fetch changes up to 803c2d2f84da9dc2619449994af34d27148ab20d:
powerpc/powernv: Fix OPAL LPC access in Little Endian (2013-12-13 15:55:15 +1100)
----------------------------------------------------------------
Anton Blanchard (8):
powerpc: Fix endian issue in setup-common.c
powerpc: Fix topology core_id endian issue on LE builds
powerpc/pseries: Fix endian issues in /proc/ppc64/lparcfg
powerpc/pseries: Fix endian issues in nvram code
powerpc/pseries: Fix PCIE link speed endian issue
powerpc/pseries: Fix endian issues in MSI code
powerpc: Fix endian issues in crash dump code
powerpc/powernv: Fix endian issue in opal_xscom_read
Benjamin Herrenschmidt (1):
powerpc/powernv: Fix OPAL LPC access in Little Endian
Ulrich Weigand (1):
powerpc: PTRACE_PEEKUSR always returns FPR0
arch/powerpc/include/asm/opal.h | 4 +--
arch/powerpc/kernel/crash_dump.c | 6 ++--
arch/powerpc/kernel/ptrace.c | 4 +--
arch/powerpc/kernel/setup-common.c | 4 +--
arch/powerpc/kernel/smp.c | 4 +--
arch/powerpc/platforms/powernv/opal-lpc.c | 12 ++++----
arch/powerpc/platforms/powernv/opal-xscom.c | 4 ++-
arch/powerpc/platforms/pseries/lparcfg.c | 12 ++++----
arch/powerpc/platforms/pseries/msi.c | 28 ++++++++++--------
arch/powerpc/platforms/pseries/nvram.c | 46 ++++++++++++++---------------
arch/powerpc/platforms/pseries/pci.c | 8 ++---
11 files changed, 68 insertions(+), 64 deletions(-)
^ 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