* Re: [PATCH v2 2/2] spi: fsl-spi: Allow dynamic allocation of CPM1 parameter RAM
From: Scott Wood @ 2014-10-03 19:51 UTC (permalink / raw)
To: Christophe Leroy; +Cc: Mark Brown, linuxppc-dev, linux-kernel, linux-spi
In-Reply-To: <20141003164917.397871AB276@localhost.localdomain>
On Fri, 2014-10-03 at 18:49 +0200, Christophe Leroy wrote:
> On CPM1, the SPI parameter RAM has a default location. In order to use SPI while
> using SCC2 with features like QMC or Ethernet, it is necessary to relocate SPI
> parameter RAM in a free location in the CPM dual port RAM.
Please explain in more detail why it's necessary.
> With this patch,
> when "fsl,cpm1-spi-reloc" instead of "fsl,cpm1-spi" compatible is set in the
> device tree, the parameter RAM for SPI is dynamically allocated
> with cpm_muram_alloc().
>
> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
>
> ---
> Changes from v1 to v2: using OF compatible instead of compile time option
>
> drivers/spi/spi-fsl-cpm.c | 3 +++
> drivers/spi/spi-fsl-lib.c | 2 ++
> include/linux/fsl_devices.h | 1 +
> 3 files changed, 6 insertions(+)
>
> diff --git a/drivers/spi/spi-fsl-cpm.c b/drivers/spi/spi-fsl-cpm.c
> index 0f3a912..048ca5f 100644
> --- a/drivers/spi/spi-fsl-cpm.c
> +++ b/drivers/spi/spi-fsl-cpm.c
> @@ -261,6 +261,9 @@ static unsigned long fsl_spi_cpm_get_pram(struct mpc8xxx_spi *mspi)
> if (mspi->flags & SPI_CPM2) {
> pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 64);
> out_be16(spi_base, pram_ofs);
> + } else if (mspi->flags & SPI_CPM1_RELOC) {
> + pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 32);
> + out_be16(spi_base, pram_ofs);
> } else {
> u16 rpbase = in_be16(spi_base);
>
> diff --git a/drivers/spi/spi-fsl-lib.c b/drivers/spi/spi-fsl-lib.c
> index c3f7802..e9db4c5 100644
> --- a/drivers/spi/spi-fsl-lib.c
> +++ b/drivers/spi/spi-fsl-lib.c
> @@ -227,6 +227,8 @@ int of_mpc8xxx_spi_probe(struct platform_device *ofdev)
> pdata->flags = SPI_CPM_MODE | SPI_CPM2;
> else if (of_device_is_compatible(np, "fsl,cpm1-spi"))
> pdata->flags = SPI_CPM_MODE | SPI_CPM1;
> + else if (of_device_is_compatible(np, "fsl,cpm1-spi-reloc"))
> + pdata->flags = SPI_CPM_MODE | SPI_CPM1 | SPI_CPM1_RELOC;
Where's the binding and device tree update for this? What specific
aspect of hardware does it describe?
-Scott
^ permalink raw reply
* Re: Pull request: scottwood/linux.git next
From: Scott Wood @ 2014-10-03 19:52 UTC (permalink / raw)
To: benh; +Cc: linuxppc-dev
In-Reply-To: <20140922222142.GA8525@home.buserror.net>
On Mon, 2014-09-22 at 17:21 -0500, Scott Wood wrote:
> Highlights include DMA32 zone support (SATA, USB, etc now works on 64-bit
> FSL kernels), MSI changes, 8xx optimizations and cleanup, t104x board
> support, and PrPMC PCI enumeration.
>
> The following changes since commit 78eb9094ca08a40b8f9d3e113a2b88e0b7dbad1d:
>
> powerpc/t2080rdb: Add T2080RDB board support (2014-07-31 00:11:10 -0500)
>
> are available in the git repository at:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/scottwood/linux.git next
>
> for you to fetch changes up to cb0446c1b625326682ec4f9d1dd10779433646bc:
>
> Revert "powerpc/fsl_msi: spread msi ints across different MSIRs" (2014-09-19 15:20:42 -0500)
ping
-Scott
^ permalink raw reply
* Re: [PATCH 2/2] spi: fsl-spi: Allow dynamic allocation of CPM1 parameter RAM
From: christophe leroy @ 2014-10-03 20:15 UTC (permalink / raw)
To: Mark Brown
Cc: Marcelo Tosatti, linux-kernel, linux-spi, Paul Mackerras,
scottwood, linuxppc-dev
In-Reply-To: <20141003144420.GC24441@sirena.org.uk>
Le 03/10/2014 16:44, Mark Brown a écrit :
> On Fri, Oct 03, 2014 at 02:56:09PM +0200, Christophe Leroy wrote:
>
>> +config CPM1_RELOCSPI
>> + bool "Dynamic SPI relocation"
>> + default n
>> + help
>> + On recent MPC8xx (at least MPC866 and MPC885) SPI can be relocated
>> + without micropatch. This activates relocation to a dynamically
>> + allocated area in the CPM Dual port RAM.
>> + When combined with SPI relocation patch (for older MPC8xx) it avoids
>> + the "loss" of additional Dual port RAM space just above the patch,
>> + which might be needed for example when using the CPM QMC.
> Something like this shouldn't be a compile time option. Either it
> should be unconditional or it should be triggered in some system
> specific manner (from DT, from knowing about other users or similar).
Can't be unconditional as older versions of mpc8xx (eg MPC860) don't
support relocation without a micropatch.
I have therefore submitted a v2 based on a DTS compatible property.
---
Ce courrier électronique ne contient aucun virus ou logiciel malveillant parce que la protection avast! Antivirus est active.
http://www.avast.com
^ permalink raw reply
* Re: [PATCH 2/2] spi: fsl-spi: Allow dynamic allocation of CPM1 parameter RAM
From: Scott Wood @ 2014-10-03 20:24 UTC (permalink / raw)
To: christophe leroy
Cc: Marcelo Tosatti, linux-kernel, linux-spi, Mark Brown,
Paul Mackerras, linuxppc-dev
In-Reply-To: <542F03CF.8010900@c-s.fr>
On Fri, 2014-10-03 at 22:15 +0200, christophe leroy wrote:
> Le 03/10/2014 16:44, Mark Brown a écrit :
> > On Fri, Oct 03, 2014 at 02:56:09PM +0200, Christophe Leroy wrote:
> >
> >> +config CPM1_RELOCSPI
> >> + bool "Dynamic SPI relocation"
> >> + default n
> >> + help
> >> + On recent MPC8xx (at least MPC866 and MPC885) SPI can be relocated
> >> + without micropatch. This activates relocation to a dynamically
> >> + allocated area in the CPM Dual port RAM.
> >> + When combined with SPI relocation patch (for older MPC8xx) it avoids
> >> + the "loss" of additional Dual port RAM space just above the patch,
> >> + which might be needed for example when using the CPM QMC.
> > Something like this shouldn't be a compile time option. Either it
> > should be unconditional or it should be triggered in some system
> > specific manner (from DT, from knowing about other users or similar).
> Can't be unconditional as older versions of mpc8xx (eg MPC860) don't
> support relocation without a micropatch.
> I have therefore submitted a v2 based on a DTS compatible property.
So the device tree change is about whether relocation is supported, not
whether it is required? Is this specific to SPI or does the relocation
mechanism work for other things?
How about checking for the existing specific-SoC compatibles?
-Scott
^ permalink raw reply
* Re: [PATCH v2 1/2] spi: fsl-spi: Fix parameter ram offset setup for CPM1
From: Scott Wood @ 2014-10-03 20:29 UTC (permalink / raw)
To: Christophe Leroy; +Cc: Mark Brown, linuxppc-dev, linux-kernel, linux-spi
In-Reply-To: <20141003164916.DBD631AAFA2@localhost.localdomain>
On Fri, 2014-10-03 at 18:49 +0200, Christophe Leroy wrote:
> On CPM1, the SPI parameter RAM has a default location. In fsl_spi_cpm_get_pram()
> there was a confusion between the SPI_BASE register and the base of the SPI
> parameter RAM. Fortunatly, it was working properly with MPC866 and MPC885
> because they do set SPI_BASE, but on MPC860 and other old MPC8xx that doesn't
> set SPI_BASE, pram_ofs was not properly set. This patch fixes this confusion.
>
> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
>
> ---
> Changes from v1 to v2: none
>
> drivers/spi/spi-fsl-cpm.c | 9 ++++-----
> 1 file changed, 4 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/spi/spi-fsl-cpm.c b/drivers/spi/spi-fsl-cpm.c
> index 54b0637..0f3a912 100644
> --- a/drivers/spi/spi-fsl-cpm.c
> +++ b/drivers/spi/spi-fsl-cpm.c
> @@ -262,15 +262,14 @@ static unsigned long fsl_spi_cpm_get_pram(struct mpc8xxx_spi *mspi)
> pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 64);
> out_be16(spi_base, pram_ofs);
> } else {
> - struct spi_pram __iomem *pram = spi_base;
> - u16 rpbase = in_be16(&pram->rpbase);
> + u16 rpbase = in_be16(spi_base);
>
> - /* Microcode relocation patch applied? */
> + /* Microcode relocation patch applied | rpbase set by default */
> if (rpbase) {
> pram_ofs = rpbase;
> } else {
> - pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 64);
> - out_be16(spi_base, pram_ofs);
> + pram_ofs = offsetof(cpm8xx_t, cp_dparam[PROFF_SPI]) -
> + offsetof(cpm8xx_t, cp_dpmem[0]);
> }
> }
Why is PROFF_SPI not coming from the device tree? Why don't I see any
cpm spi in any device tree nor any binding for it?
-Scott
^ permalink raw reply
* Re: Pull request: scottwood/linux.git next
From: Stephen Rothwell @ 2014-10-03 23:06 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <1412365973.13320.430.camel@snotra.buserror.net>
[-- Attachment #1: Type: text/plain, Size: 1034 bytes --]
Hi Scott,
On Fri, 3 Oct 2014 14:52:53 -0500 Scott Wood <scottwood@freescale.com> wrote:
>
> On Mon, 2014-09-22 at 17:21 -0500, Scott Wood wrote:
> > Highlights include DMA32 zone support (SATA, USB, etc now works on 64-bit
> > FSL kernels), MSI changes, 8xx optimizations and cleanup, t104x board
> > support, and PrPMC PCI enumeration.
> >
> > The following changes since commit 78eb9094ca08a40b8f9d3e113a2b88e0b7dbad1d:
> >
> > powerpc/t2080rdb: Add T2080RDB board support (2014-07-31 00:11:10 -0500)
> >
> > are available in the git repository at:
> >
> > git://git.kernel.org/pub/scm/linux/kernel/git/scottwood/linux.git next
> >
> > for you to fetch changes up to cb0446c1b625326682ec4f9d1dd10779433646bc:
> >
> > Revert "powerpc/fsl_msi: spread msi ints across different MSIRs" (2014-09-19 15:20:42 -0500)
>
> ping
Probably worth explicitly pinging Michael (cc'd) as he is doing this
merge window's collection ...
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* Re: [RFC PATCH v3 1/3] powerpc: Fix warning reported by verify_cpu_node_mapping()
From: Nishanth Aravamudan @ 2014-10-03 23:26 UTC (permalink / raw)
To: Michael Ellerman; +Cc: paulus, linuxppc-dev, Li Zhong, Nathan Fontenot
In-Reply-To: <1412297420.2783.3.camel@concordia>
On 03.10.2014 [10:50:20 +1000], Michael Ellerman wrote:
> On Thu, 2014-10-02 at 14:13 -0700, Nishanth Aravamudan wrote:
> > Ben & Michael,
> >
> > What's the status of these patches?
>
> Been in my next for a week :)
>
> https://git.kernel.org/cgit/linux/kernel/git/mpe/linux.git/log/?h=next
Ah ok, thanks -- I wasn't following your tree, my fault. Do we want
these to go back to 3.17-stable, as they fix some annoying splats during
boot (non-fatal afaict, though)?
-Nish
^ permalink raw reply
* Re: [PATCH v2 2/2] spi: fsl-spi: Allow dynamic allocation of CPM1 parameter RAM
From: christophe leroy @ 2014-10-04 10:07 UTC (permalink / raw)
To: Scott Wood; +Cc: Mark Brown, linuxppc-dev, linux-kernel, linux-spi
In-Reply-To: <1412365908.13320.429.camel@snotra.buserror.net>
Le 03/10/2014 21:51, Scott Wood a écrit :
> On Fri, 2014-10-03 at 18:49 +0200, Christophe Leroy wrote:
>> On CPM1, the SPI parameter RAM has a default location. In order to use SPI while
>> using SCC2 with features like QMC or Ethernet, it is necessary to relocate SPI
>> parameter RAM in a free location in the CPM dual port RAM.
> Please explain in more detail why it's necessary.
SCC2 parameter RAM is located at offset 0x1D00 inside the CPM dual port RAM.
SPI parameter RAM is located at offset 0x1D80.
When using SCC2 in Ethernet Mode, the parameter RAM size is 0xA4.
When using SCC2 in QMC mode, the parameter RAM size is 0xAC.
Therefore in both case, it overlaps the SPI parameter RAM which shall
then be relocated.
On MPC860 this can only be done using an additional microcode.
Therefore, the relocation configuration is managed within
arch/powerpc/sysdep/micropatch.c
On MPC866 and MPC885 (at least) no microcode is needed. Therefore, if we
want to relocate the SPI param, we must handle that outside of micropatch.c
Since the SPI driver already handle dynamic parameter RAM allocation for
CPM2, I though it was the good place to do it also for CPM1.
>
>> With this patch,
>> when "fsl,cpm1-spi-reloc" instead of "fsl,cpm1-spi" compatible is set in the
>> device tree, the parameter RAM for SPI is dynamically allocated
>> with cpm_muram_alloc().
>>
>> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
>>
>> ---
>> Changes from v1 to v2: using OF compatible instead of compile time option
>>
>> drivers/spi/spi-fsl-cpm.c | 3 +++
>> drivers/spi/spi-fsl-lib.c | 2 ++
>> include/linux/fsl_devices.h | 1 +
>> 3 files changed, 6 insertions(+)
>>
>> diff --git a/drivers/spi/spi-fsl-cpm.c b/drivers/spi/spi-fsl-cpm.c
>> index 0f3a912..048ca5f 100644
>> --- a/drivers/spi/spi-fsl-cpm.c
>> +++ b/drivers/spi/spi-fsl-cpm.c
>> @@ -261,6 +261,9 @@ static unsigned long fsl_spi_cpm_get_pram(struct mpc8xxx_spi *mspi)
>> if (mspi->flags & SPI_CPM2) {
>> pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 64);
>> out_be16(spi_base, pram_ofs);
>> + } else if (mspi->flags & SPI_CPM1_RELOC) {
>> + pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 32);
>> + out_be16(spi_base, pram_ofs);
>> } else {
>> u16 rpbase = in_be16(spi_base);
>>
>> diff --git a/drivers/spi/spi-fsl-lib.c b/drivers/spi/spi-fsl-lib.c
>> index c3f7802..e9db4c5 100644
>> --- a/drivers/spi/spi-fsl-lib.c
>> +++ b/drivers/spi/spi-fsl-lib.c
>> @@ -227,6 +227,8 @@ int of_mpc8xxx_spi_probe(struct platform_device *ofdev)
>> pdata->flags = SPI_CPM_MODE | SPI_CPM2;
>> else if (of_device_is_compatible(np, "fsl,cpm1-spi"))
>> pdata->flags = SPI_CPM_MODE | SPI_CPM1;
>> + else if (of_device_is_compatible(np, "fsl,cpm1-spi-reloc"))
>> + pdata->flags = SPI_CPM_MODE | SPI_CPM1 | SPI_CPM1_RELOC;
> Where's the binding and device tree update for this? What specific
> aspect of hardware does it describe?
Well, the intension was not really to describe any specific aspect of
hardware, but to provide an easy way to tell the driver that we want
dynamic reallocation of the parameter RAM.
On CPM2, dynamic allocation of parameter RAM is the only way.
On CPM1:
* The parameter RAM has a default location.
* When the SPI relocation micropatch is applied, the kernel reallocate
it just after the patch, when loading the patch. This is not good for
using QMC, because it is within the part of dual port RAM used by the
QMC, therefore it reduce even more the number of channels that the QMC
can use.
The bindings for that driver are described in
Documentation/devicetree/bindings/spi/fsl-spi.txt. But it seems that it
doesn't describe anything related to those compatibles. The driver has a
match on "fsl,fsl-spi" only, and for using it with CPM you have to add
"fsl,cpm1-spi" or "fsl,cpm2-spi" to tell the driver that it is CPM
(existing code below).
prop = of_get_property(np, "mode", NULL);
if (prop && !strcmp(prop, "cpu-qe"))
pdata->flags = SPI_QE_CPU_MODE;
else if (prop && !strcmp(prop, "qe"))
pdata->flags = SPI_CPM_MODE | SPI_QE;
else if (of_device_is_compatible(np, "fsl,cpm2-spi"))
pdata->flags = SPI_CPM_MODE | SPI_CPM2;
else if (of_device_is_compatible(np, "fsl,cpm1-spi"))
pdata->flags = SPI_CPM_MODE | SPI_CPM1;
Christophe
---
Ce courrier électronique ne contient aucun virus ou logiciel malveillant parce que la protection avast! Antivirus est active.
http://www.avast.com
^ permalink raw reply
* Re: [PATCH 2/2] spi: fsl-spi: Allow dynamic allocation of CPM1 parameter RAM
From: christophe leroy @ 2014-10-04 10:15 UTC (permalink / raw)
To: Scott Wood
Cc: Marcelo Tosatti, linux-kernel, linux-spi, Mark Brown,
Paul Mackerras, linuxppc-dev
In-Reply-To: <1412367858.13320.432.camel@snotra.buserror.net>
Le 03/10/2014 22:24, Scott Wood a écrit :
> On Fri, 2014-10-03 at 22:15 +0200, christophe leroy wrote:
>> Le 03/10/2014 16:44, Mark Brown a écrit :
>>> On Fri, Oct 03, 2014 at 02:56:09PM +0200, Christophe Leroy wrote:
>>>
>>>> +config CPM1_RELOCSPI
>>>> + bool "Dynamic SPI relocation"
>>>> + default n
>>>> + help
>>>> + On recent MPC8xx (at least MPC866 and MPC885) SPI can be relocated
>>>> + without micropatch. This activates relocation to a dynamically
>>>> + allocated area in the CPM Dual port RAM.
>>>> + When combined with SPI relocation patch (for older MPC8xx) it avoids
>>>> + the "loss" of additional Dual port RAM space just above the patch,
>>>> + which might be needed for example when using the CPM QMC.
>>> Something like this shouldn't be a compile time option. Either it
>>> should be unconditional or it should be triggered in some system
>>> specific manner (from DT, from knowing about other users or similar).
>> Can't be unconditional as older versions of mpc8xx (eg MPC860) don't
>> support relocation without a micropatch.
>> I have therefore submitted a v2 based on a DTS compatible property.
> So the device tree change is about whether relocation is supported, not
> whether it is required?
Indeed no, my intension is to say that relocation is requested. Do you
mean that it should then not use a compatible ?
> Is this specific to SPI or does the relocation
> mechanism work for other things?
Relocation is the same for I2C.
It is also possible to relocate SMC1 and SMC2 parameter RAM but only
with a micropatch.
Today, the kernel only implements relocation of SMC1, and it relocates
it at a fixed address just after SMC2 at offset 0x1FC0.
>
> How about checking for the existing specific-SoC compatibles?
What do you mean ?
Christophe
---
Ce courrier électronique ne contient aucun virus ou logiciel malveillant parce que la protection avast! Antivirus est active.
http://www.avast.com
^ permalink raw reply
* Re: [PATCH v2 1/2] spi: fsl-spi: Fix parameter ram offset setup for CPM1
From: christophe leroy @ 2014-10-04 12:02 UTC (permalink / raw)
To: Scott Wood; +Cc: Mark Brown, linuxppc-dev, linux-kernel, linux-spi
In-Reply-To: <1412368198.13320.434.camel@snotra.buserror.net>
Le 03/10/2014 22:29, Scott Wood a écrit :
> On Fri, 2014-10-03 at 18:49 +0200, Christophe Leroy wrote:
>> On CPM1, the SPI parameter RAM has a default location. In fsl_spi_cpm_get_pram()
>> there was a confusion between the SPI_BASE register and the base of the SPI
>> parameter RAM. Fortunatly, it was working properly with MPC866 and MPC885
>> because they do set SPI_BASE, but on MPC860 and other old MPC8xx that doesn't
>> set SPI_BASE, pram_ofs was not properly set. This patch fixes this confusion.
>>
>> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
>>
>> ---
>> Changes from v1 to v2: none
>>
>> drivers/spi/spi-fsl-cpm.c | 9 ++++-----
>> 1 file changed, 4 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/spi/spi-fsl-cpm.c b/drivers/spi/spi-fsl-cpm.c
>> index 54b0637..0f3a912 100644
>> --- a/drivers/spi/spi-fsl-cpm.c
>> +++ b/drivers/spi/spi-fsl-cpm.c
>> @@ -262,15 +262,14 @@ static unsigned long fsl_spi_cpm_get_pram(struct mpc8xxx_spi *mspi)
>> pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 64);
>> out_be16(spi_base, pram_ofs);
>> } else {
>> - struct spi_pram __iomem *pram = spi_base;
>> - u16 rpbase = in_be16(&pram->rpbase);
>> + u16 rpbase = in_be16(spi_base);
>>
>> - /* Microcode relocation patch applied? */
>> + /* Microcode relocation patch applied | rpbase set by default */
>> if (rpbase) {
>> pram_ofs = rpbase;
>> } else {
>> - pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 64);
>> - out_be16(spi_base, pram_ofs);
>> + pram_ofs = offsetof(cpm8xx_t, cp_dparam[PROFF_SPI]) -
>> + offsetof(cpm8xx_t, cp_dpmem[0]);
>> }
>> }
> Why is PROFF_SPI not coming from the device tree?
That's where it starts to become tricky.
PROFF_SPI is defined in cpm1.h which is included by the driver already.
It provides the default offset from the start of the parameter RAM.
Previously I had the following in my device tree, and the last part of
the source above (the one for rpbase == 0) could not work.
spi: spi@a80 {
cell-index = <0>;
compatible = "fsl,spi", "fsl,cpm1-spi";
reg = <0xa80 0x30 0x3d80 0x30>;
First reg area was the area for SPI registers. Second area was the
parameter RAM zone, which was just mapped to get access to the SPI_BASE
pointer (rpbase)
Now I have
compatible = "fsl,spi", "fsl,cpm1-spi-reloc";
reg = <0xa80 0x30 0x3dac 0x2>;
First reg area is the area for SPI registers. Second area is the
SPI_BASE, as for the CPM2.
On recent 8xx (885 and 866 at least) it contains the offset (=0x1D80) of
the parameter RAM. But on old ones (860, ...) it contains 0. Therefore
we have to get the default index in another way.
What I wanted was to keep something similar to what's done with CPM2.
What should it look like if that offset had to be in the device tree ?
> Why don't I see any
> cpm spi in any device tree nor any binding for it?
There's one in mgcoge.dts:
spi@11aa0 {
cell-index = <0>;
compatible = "fsl,spi", "fsl,cpm2-spi";
reg = <0x11a80 0x40 0x89fc 0x2>;
Christophe
---
Ce courrier électronique ne contient aucun virus ou logiciel malveillant parce que la protection avast! Antivirus est active.
http://www.avast.com
^ permalink raw reply
* Re: [PATCH 03/20] powerpc/47x: Use pm_power_off rather than ppc_md.power_off
From: Segher Boessenkool @ 2014-10-05 0:39 UTC (permalink / raw)
To: Alexander Graf
Cc: Arnd Bergmann, Geoff Levand, Alistair Popple, Scott Wood,
Anatolij Gustschin, linuxppc-dev
In-Reply-To: <1412170086-57971-4-git-send-email-agraf@suse.de>
On Wed, Oct 01, 2014 at 03:27:49PM +0200, Alexander Graf wrote:
> diff --git a/arch/powerpc/platforms/44x/ppc476.c b/arch/powerpc/platforms/44x/ppc476.c
> index 33986c1..7027015 100644
> --- a/arch/powerpc/platforms/44x/ppc476.c
> +++ b/arch/powerpc/platforms/44x/ppc476.c
> @@ -94,7 +94,7 @@ static int avr_probe(struct i2c_client *client,
> {
> avr_i2c_client = client;
> ppc_md.restart = avr_reset_system;
> - ppc_md.power_off = avr_power_off_system;
> + pm_power_off = avr_power_off_system
> return 0;
> }
That doesn't compile afaics?
Segher
^ permalink raw reply
* Re: [PATCH v2] rtc/tpo: Driver to support rtc and wakeup on PowerNV platform
From: Neelesh Gupta @ 2014-10-06 5:25 UTC (permalink / raw)
To: devicetree, tglx, linuxppc-dev, rtc-linux, a.zummo; +Cc: benh
In-Reply-To: <20140930101448.9310.32342.stgit@localhost.localdomain>
On 09/30/2014 03:46 PM, Neelesh Gupta wrote:
> The patch implements the OPAL rtc driver that binds with the rtc
> driver subsystem. The driver uses the platform device infrastructure
> to probe the rtc device and register it to rtc class framework. The
> 'wakeup' is supported depending upon the property 'has-tpo' present
> in the OF node. It provides a way to load the generic rtc driver in
> in the absence of an OPAL driver.
>
> The patch also moves the existing OPAL rtc get/set time interfaces to the
> new driver and exposes the necessary OPAL calls using EXPORT_SYMBOL_GPL.
>
> Test results:
> -------------
> Host:
> [root@tul163p1 ~]# ls -l /sys/class/rtc/
> total 0
> lrwxrwxrwx 1 root root 0 Sep 30 04:58 rtc0 -> ../../devices/opal-rtc/rtc/rtc0
> [root@tul163p1 ~]# cat /sys/devices/opal-rtc/rtc/rtc0/time
> 10:01:51
> [root@tul163p1 ~]# cat /sys/devices/opal-rtc/rtc/rtc0/time
> 10:02:07
> [root@tul163p1 ~]# echo `date '+%s' -d '+ 3 minutes'` > /sys/class/rtc/rtc0/wakealarm
> [root@tul163p1 ~]# cat /sys/class/rtc/rtc0/wakealarm
> 1412071532
> [root@tul163p1 ~]#
>
> FSP:
> $ smgr mfgState
> standby
> $ smgr mfgState
> ipling
> $
>
> Signed-off-by: Neelesh Gupta <neelegup@linux.vnet.ibm.com>
> ---
>
> Changes in v2
> =============
> - Added Documentation/devicetree/bindings/rtc/rtc-opal.txt
> - Explicitly turn off RTC_UIE mode by setting 'rtc->uie_unsupported'
>
> Dependency
> ==========
> This patch depends upon the below patch posted on 'linuxppc-dev@lists.ozlabs.org'
> [PATCH 1/4] powerpc/powernv: Add OPAL check token call
> Signed-off-by: Michael Neuling <mikey@neuling.org>
>
> Documentation/devicetree/bindings/rtc/rtc-opal.txt | 16 +
> arch/powerpc/include/asm/opal.h | 7 -
> arch/powerpc/kernel/time.c | 1
> arch/powerpc/platforms/powernv/opal-async.c | 3
> arch/powerpc/platforms/powernv/opal-rtc.c | 63 +----
> arch/powerpc/platforms/powernv/opal-wrappers.S | 2
> arch/powerpc/platforms/powernv/opal.c | 6
> arch/powerpc/platforms/powernv/setup.c | 2
> drivers/rtc/Kconfig | 11 +
> drivers/rtc/Makefile | 1
> drivers/rtc/rtc-opal.c | 261 ++++++++++++++++++++
> 11 files changed, 325 insertions(+), 48 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/rtc/rtc-opal.txt
> create mode 100644 drivers/rtc/rtc-opal.c
Hi Alessandro,
The patch depends upon few things in powerpc tree so could you please
Ack the
patch so that we can take it through the powerpc tree?
Thanks,
- Neelesh
^ permalink raw reply
* [PATCH V2] powerpc, powernv: Add OPAL platform event driver
From: Anshuman Khandual @ 2014-10-06 5:31 UTC (permalink / raw)
To: linuxppc-dev; +Cc: neelegup, paulus
This patch creates a new OPAL platform event character driver
which will give userspace clients the access to these events
and process them effectively. Following platforms events are
currently supported with this platform driver.
(1) Environmental and Power Warning (EPOW)
(2) Delayed Power Off (DPO)
The user interface for this driver is /dev/opal_event character
device file where the user space clients can poll and read for
new opal platform events. The expected sequence of events driven
from user space should be like the following.
(1) Open the character device file
(2) Poll on the file for POLLIN event
(3) When unblocked, must attempt to read PLAT_EVENT_MAX_SIZE size
(4) Kernel driver will pass at most one opal_plat_event structure
(5) Poll again for more new events
The driver registers for OPAL messages notifications corresponding to
individual OPAL events. When any of those event messages arrive in the
kernel, the callbacks are called to process them which in turn unblocks
the polling thread on the character device file. The driver also registers
a timer function which will be called after a threshold amount of time to
shutdown the system. The user space client receives the timeout value for
all individual OPAL platform events and hence must prepare the system and
eventually shutdown. In case the user client does not shutdown the system,
the timer function will be called after the threshold and shutdown the
system explicitly.
Reviewed-by: Neelesh Gupta <neelegup@linux.vnet.ibm.com>
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
Changes in V2:
- Changed the function fetch_dpo_timeout
- Export opal_platform_events.h for user space consumption
arch/powerpc/include/asm/opal.h | 45 +-
arch/powerpc/include/uapi/asm/Kbuild | 1 +
.../include/uapi/asm/opal_platform_events.h | 90 +++
arch/powerpc/platforms/powernv/Makefile | 2 +-
.../platforms/powernv/opal-platform-events.c | 736 +++++++++++++++++++++
arch/powerpc/platforms/powernv/opal-wrappers.S | 1 +
arch/powerpc/platforms/powernv/opal.c | 8 +-
7 files changed, 880 insertions(+), 3 deletions(-)
create mode 100644 arch/powerpc/include/uapi/asm/opal_platform_events.h
create mode 100644 arch/powerpc/platforms/powernv/opal-platform-events.c
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 86055e5..c134137 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -151,6 +151,7 @@ struct opal_sg_list {
#define OPAL_HANDLE_HMI 98
#define OPAL_REGISTER_DUMP_REGION 101
#define OPAL_UNREGISTER_DUMP_REGION 102
+#define OPAL_GET_DPO_STATUS 105
#ifndef __ASSEMBLY__
@@ -249,6 +250,7 @@ enum OpalMessageType {
OPAL_MSG_EPOW,
OPAL_MSG_SHUTDOWN,
OPAL_MSG_HMI_EVT,
+ OPAL_MSG_DPO,
OPAL_MSG_TYPE_MAX,
};
@@ -417,6 +419,46 @@ struct opal_msg {
__be64 params[8];
};
+/*
+ * EPOW status sharing (OPAL and the host)
+ *
+ * The host will pass on OPAL, a buffer of length OPAL_SYSEPOW_MAX
+ * with individual elements being 16 bits wide to fetch the system
+ * wide EPOW status. Each element in the buffer will contain the
+ * EPOW status in it's bit representation for a particular EPOW sub
+ * class as defiend here. So multiple detailed EPOW status bits
+ * specific for any sub class can be represented in a single buffer
+ * element as it's bit representation.
+ */
+
+/* System EPOW type */
+enum OpalSysEpow {
+ OPAL_SYSEPOW_POWER = 0, /* Power EPOW */
+ OPAL_SYSEPOW_TEMP = 1, /* Temperature EPOW */
+ OPAL_SYSEPOW_COOLING = 2, /* Cooling EPOW */
+ OPAL_SYSEPOW_MAX = 3, /* Max EPOW categories */
+};
+
+/* Power EPOW */
+enum OpalSysPower {
+ OPAL_SYSPOWER_UPS = 0x0001, /* System on UPS power */
+ OPAL_SYSPOWER_CHNG = 0x0002, /* System power config change */
+ OPAL_SYSPOWER_FAIL = 0x0004, /* System impending power failure */
+ OPAL_SYSPOWER_INCL = 0x0008, /* System incomplete power */
+};
+
+/* Temperature EPOW */
+enum OpalSysTemp {
+ OPAL_SYSTEMP_AMB = 0x0001, /* System over ambient temperature */
+ OPAL_SYSTEMP_INT = 0x0002, /* System over internal temperature */
+ OPAL_SYSTEMP_HMD = 0x0004, /* System over ambient humidity */
+};
+
+/* Cooling EPOW */
+enum OpalSysCooling {
+ OPAL_SYSCOOL_INSF = 0x0001, /* System insufficient cooling */
+};
+
struct opal_machine_check_event {
enum OpalMCE_Version version:8; /* 0x00 */
uint8_t in_use; /* 0x01 */
@@ -881,7 +923,7 @@ int64_t opal_pci_fence_phb(uint64_t phb_id);
int64_t opal_pci_reinit(uint64_t phb_id, uint64_t reinit_scope, uint64_t data);
int64_t opal_pci_mask_pe_error(uint64_t phb_id, uint16_t pe_number, uint8_t error_type, uint8_t mask_action);
int64_t opal_set_slot_led_status(uint64_t phb_id, uint64_t slot_id, uint8_t led_type, uint8_t led_action);
-int64_t opal_get_epow_status(__be64 *status);
+int64_t opal_get_epow_status(uint16_t *status, uint16_t *length);
int64_t opal_set_system_attention_led(uint8_t led_action);
int64_t opal_pci_next_error(uint64_t phb_id, __be64 *first_frozen_pe,
__be16 *pci_error_type, __be16 *severity);
@@ -924,6 +966,7 @@ int64_t opal_sensor_read(uint32_t sensor_hndl, int token, __be32 *sensor_data);
int64_t opal_handle_hmi(void);
int64_t opal_register_dump_region(uint32_t id, uint64_t start, uint64_t end);
int64_t opal_unregister_dump_region(uint32_t id);
+int64_t opal_get_dpo_status(int64_t *dpo_timeout);
/* Internal functions */
extern int early_init_dt_scan_opal(unsigned long node, const char *uname,
diff --git a/arch/powerpc/include/uapi/asm/Kbuild b/arch/powerpc/include/uapi/asm/Kbuild
index 7a3f795..d20970b 100644
--- a/arch/powerpc/include/uapi/asm/Kbuild
+++ b/arch/powerpc/include/uapi/asm/Kbuild
@@ -44,3 +44,4 @@ header-y += tm.h
header-y += types.h
header-y += ucontext.h
header-y += unistd.h
+header-y += opal_platform_events.h
diff --git a/arch/powerpc/include/uapi/asm/opal_platform_events.h b/arch/powerpc/include/uapi/asm/opal_platform_events.h
new file mode 100644
index 0000000..6d2e13e
--- /dev/null
+++ b/arch/powerpc/include/uapi/asm/opal_platform_events.h
@@ -0,0 +1,90 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright IBM Corp. 2014
+ *
+ * Author: Anshuman Khandual <khandual@linux.vnet.ibm.com>
+ */
+#ifndef __LINUX_OPAL_PLATFORM_EVENTS_H
+#define __LINUX_OPAL_PLATFORM_EVENTS_H
+
+#include <linux/types.h>
+
+/* EPOW classification */
+enum epow_condition {
+ EPOW_SYSPOWER_CHNG = 0, /* Power */
+ EPOW_SYSPOWER_FAIL = 1,
+ EPOW_SYSPOWER_INCL = 2,
+ EPOW_SYSPOWER_UPS = 3,
+ EPOW_SYSTEMP_AMB = 4, /* Temperature */
+ EPOW_SYSTEMP_INT = 5,
+ EPOW_SYSTEMP_HMD = 6,
+ EPOW_SYSCOOL_INSF = 7, /* Cooling */
+ EPOW_MAX = 8,
+};
+
+/* OPAL EPOW event */
+struct epow_event {
+ __u64 epow[EPOW_MAX]; /* Detailed system EPOW status */
+ __u64 timeout; /* Timeout to shutdown in secs */
+};
+
+/* OPAL DPO event */
+struct dpo_event {
+ __u64 orig_timeout; /* Platform provided timeout in secs */
+ __u64 remain_timeout; /* Timeout to shutdown in secs */
+};
+
+/* OPAL event */
+struct opal_plat_event {
+ __u32 type; /* Type of OPAL platform event */
+#define OPAL_PLAT_EVENT_TYPE_EPOW 0
+#define OPAL_PLAT_EVENT_TYPE_DPO 1
+#define OPAL_PLAT_EVENT_TYPE_MAX 2
+ __u32 size; /* Size of OPAL platform event */
+ union {
+ struct epow_event epow; /* EPOW platform event */
+ struct dpo_event dpo; /* DPO platform event */
+ };
+};
+
+/*
+ * Suggested read size
+ *
+ * The user space client should attempt to read OPAL_PLAT_EVENT_READ_SIZE
+ * amount of data from the character device file '/dev/opal_event' at any
+ * point of time. The kernel driver will pass an entire opal_plat_event
+ * structure in every read. This ensures that minium data the user space
+ * client gets from the kernel is one opal_plat_event structure.
+ */
+#define PLAT_EVENT_MAX_SIZE 4096
+
+/*
+ * Suggested user operation
+ *
+ * The user space client must follow these steps in order to be able to
+ * exploit the features exported through the OPAL platform event driver.
+ *
+ * (1) Open the character device file
+ * (2) Poll on the file for POLLIN
+ * (3) When unblocked, must attempt to read PLAT_EVENT_MAX_SIZE size
+ * (4) Kernel driver will pass one opal_plat_event structure
+ * (5) Poll again for more new events
+ *
+ * The character device file (/dev/opal_event) must be opened and operated by
+ * only one user space client at any point of time. Other attempts to open the
+ * file will be returned by the driver as EBUSY.
+ */
+
+#endif /* __LINUX_OPAL_PLATFORM_EVENTS_H */
diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile
index f241acc..c4b3b9b 100644
--- a/arch/powerpc/platforms/powernv/Makefile
+++ b/arch/powerpc/platforms/powernv/Makefile
@@ -1,7 +1,7 @@
obj-y += setup.o opal-wrappers.o opal.o opal-async.o
obj-y += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o
obj-y += rng.o opal-elog.o opal-dump.o opal-sysparam.o opal-sensor.o
-obj-y += opal-msglog.o opal-hmi.o
+obj-y += opal-msglog.o opal-hmi.o opal-platform-events.o
obj-$(CONFIG_SMP) += smp.o subcore.o subcore-asm.o
obj-$(CONFIG_PCI) += pci.o pci-p5ioc2.o pci-ioda.o
diff --git a/arch/powerpc/platforms/powernv/opal-platform-events.c b/arch/powerpc/platforms/powernv/opal-platform-events.c
new file mode 100644
index 0000000..cea2a378e
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/opal-platform-events.c
@@ -0,0 +1,736 @@
+/*
+ * IBM PowerNV OPAL platform events driver
+ *
+ * Copyright IBM Corporation 2014
+ *
+ * Author: Anshuman Khandual <khandual@linux.vnet.ibm.com>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#define PREFIX "OPAL_EVENT"
+#define pr_fmt(fmt) PREFIX ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/cdev.h>
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/timer.h>
+#include <linux/reboot.h>
+#include <asm/uaccess.h>
+#include <asm/opal.h>
+#include <asm/opal_platform_events.h>
+
+/* Platform events driver */
+static dev_t opal_event_dev;
+static struct cdev opal_event_cdev;
+static struct class *opal_event_class;
+static bool opal_event_open_flag;
+
+#define OPAL_EVENT_MAX_DEVS 1
+
+/* Platform events timers */
+static struct timer_list opal_event_timer;
+
+static DECLARE_WAIT_QUEUE_HEAD(opal_plat_evt_wait);
+static DECLARE_WAIT_QUEUE_HEAD(opal_plat_open_wait);
+static DEFINE_SPINLOCK(opal_plat_evt_spinlock);
+static DEFINE_SPINLOCK(opal_plat_timer_spinlock);
+static DEFINE_MUTEX(opal_plat_evt_mutex);
+
+/*
+ * Platform timeout values
+ *
+ * XXX: The default timeout value is 5 minutes. In future this
+ * should be communicated from the platform firmware through
+ * device tree attributes.
+ */
+#define OPAL_EPOW_TIMEOUT 300
+
+struct opal_platform_evt {
+ struct opal_plat_event opal_event;
+ struct list_head link;
+};
+static LIST_HEAD(opal_event_queue);
+static unsigned long opal_dpo_target;
+static bool opal_event_probe_finished;
+
+/*
+ * OPAL event map
+ *
+ * Converts OPAL event type into it's description.
+ */
+static const char *opal_event_map[OPAL_PLAT_EVENT_TYPE_MAX] = {
+ "OPAL_PLAT_EVENT_TYPE_EPOW", "OPAL_PLAT_EVENT_TYPE_DPO"
+};
+
+/*
+ * opal_event_timeout
+ *
+ * This is the actual timer handler. If the any of the timers
+ * expire, this function will be called to shutdown the system
+ * gracefully.
+ */
+static void opal_event_timeout(unsigned long data)
+{
+ orderly_poweroff(1);
+}
+
+/*
+ * opal_event_start_timer
+ *
+ * This will start opal event timer with given timeout value as the expiry
+ * if either the timer is not active or the expiry value of the already
+ * activated timer is at a later point of time in the future compared to the
+ * timeout value for this given new event. The function mod_timer takes care
+ * all the cases whether the opal event timer is already active or not.
+ */
+static void opal_event_start_timer(unsigned long event, u64 timeout)
+{
+ unsigned long flags;
+
+ /* Timer active with earlier timeout */
+ spin_lock_irqsave(&opal_plat_timer_spinlock, flags);
+ if (timer_pending(&opal_event_timer) &&
+ (opal_event_timer.expires < (jiffies + timeout * HZ))) {
+ spin_unlock_irqrestore(&opal_plat_timer_spinlock, flags);
+ pr_info("Timer for %s event active with an earlier timeout\n",
+ opal_event_map[opal_event_timer.data]);
+ return;
+ }
+ opal_event_timer.data = event;
+ mod_timer(&opal_event_timer, jiffies + timeout * HZ);
+ spin_unlock_irqrestore(&opal_plat_timer_spinlock, flags);
+ pr_info("Timer activated for %s event\n", opal_event_map[event]);
+}
+
+/*
+ * opal_event_stop_timer
+ *
+ * This will attempt to stop opal_event_timer if it is already enabled.
+ */
+static void opal_event_stop_timer(void)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&opal_plat_timer_spinlock, flags);
+ del_timer_sync(&opal_event_timer);
+ spin_unlock_irqrestore(&opal_plat_timer_spinlock, flags);
+ pr_info("Timer deactivated\n");
+}
+
+/*
+ * opal_event_read
+ *
+ * User client needs to attempt to read PLAT_EVENT_MAX_SIZE amount of data
+ * from the file descriptor at a time. The driver will pass a single node
+ * from the list if available at a time and then delete the node from the list.
+ */
+static ssize_t opal_event_read(struct file *filep,
+ char __user *buf, size_t len, loff_t *off)
+{
+ struct opal_platform_evt *evt;
+ unsigned long flags;
+
+ if (len < sizeof(struct opal_plat_event))
+ return -EINVAL;
+
+ /* Fetch the first node on the list */
+ spin_lock_irqsave(&opal_plat_evt_spinlock, flags);
+ if (list_empty(&opal_event_queue)) {
+ spin_unlock_irqrestore(&opal_plat_evt_spinlock, flags);
+ return 0;
+ }
+
+ /* Fetch and delete from the list */
+ evt = list_first_entry(&opal_event_queue,
+ struct opal_platform_evt, link);
+ list_del(&evt->link);
+
+ /*
+ * Update the remaining timeout for DPO event.
+ * This can only be updated during the read time.
+ */
+ if (evt->opal_event.type == OPAL_PLAT_EVENT_TYPE_DPO) {
+ unsigned long timeout;
+
+ if (opal_dpo_target &&
+ evt->opal_event.dpo.orig_timeout) {
+ timeout = (opal_dpo_target - jiffies) / HZ;
+ evt->opal_event.dpo.remain_timeout = timeout;
+ }
+ }
+ spin_unlock_irqrestore(&opal_plat_evt_spinlock, flags);
+
+ if (copy_to_user(buf, &evt->opal_event,
+ sizeof(struct opal_plat_event))) {
+
+ /*
+ * Copy to user has failed. The event node had
+ * been deleted from the list. Lets add it back
+ * there.
+ */
+ spin_lock_irqsave(&opal_plat_evt_spinlock, flags);
+ list_add_tail(&evt->link, &opal_event_queue);
+ spin_unlock_irqrestore(&opal_plat_evt_spinlock, flags);
+ return -EFAULT;
+ }
+
+ kfree(evt);
+ return sizeof(struct opal_plat_event);
+}
+
+/*
+ * opal_event_poll
+ *
+ * Poll is unblocked right away with POLLIN when data is available.
+ * When data is not available, the process will have to block till
+ * it gets waked up and data is available to read.
+ */
+static unsigned int opal_event_poll(struct file *file, poll_table *wait)
+{
+ poll_wait(file, &opal_plat_evt_wait, wait);
+ if (!list_empty(&opal_event_queue))
+ return POLLIN;
+ return 0;
+}
+
+/*
+ * opal_event_open
+ *
+ * This makes sure that only one process can open the
+ * character device file at any point of time. Others
+ * attempting to open the file descriptor will either
+ * get EBUSY (with O_NONBLOCK flag) or wait for the
+ * other process to close the file descriptor.
+ */
+static int opal_event_open(struct inode *inode, struct file *file)
+{
+ int err;
+
+ mutex_lock(&opal_plat_evt_mutex);
+ while (opal_event_open_flag) {
+ mutex_unlock(&opal_plat_evt_mutex);
+ if (file->f_flags & O_NONBLOCK)
+ return -EBUSY;
+ err = wait_event_interruptible(opal_plat_open_wait,
+ !opal_event_open_flag);
+ if (err)
+ return -ERESTARTSYS;
+ mutex_lock(&opal_plat_evt_mutex);
+ }
+ opal_event_open_flag = true;
+ mutex_unlock(&opal_plat_evt_mutex);
+ return 0;
+}
+
+/*
+ * opal_event_release
+ *
+ * Releases the file descriptor for the device file.
+ */
+static int opal_event_release(struct inode *inode, struct file *file)
+{
+ mutex_lock(&opal_plat_evt_mutex);
+ if (opal_event_open_flag) {
+ opal_event_open_flag = false;
+ wake_up_interruptible(&opal_plat_open_wait);
+ }
+ mutex_unlock(&opal_plat_evt_mutex);
+ return 0;
+}
+
+/* Defined file operation */
+static const struct file_operations fops = {
+ .owner = THIS_MODULE,
+ .open = opal_event_open,
+ .release = opal_event_release,
+ .read = opal_event_read,
+ .poll = opal_event_poll,
+};
+
+/* Process the received EPOW information */
+void process_epow(__u64 *epow, int16_t *epow_status, int max_epow_class)
+{
+ /*
+ * Platform might have returned less number of EPOW
+ * subclass status than asked for. This situation
+ * happens when the platform firmware is older compared
+ * to the kernel.
+ */
+
+ if (!max_epow_class) {
+ pr_warn("EPOW: OPAL_SYSEPOW_POWER subclass not present\n");
+ return;
+ }
+
+ /* Power */
+ max_epow_class--;
+ if (epow_status[OPAL_SYSEPOW_POWER] & OPAL_SYSPOWER_CHNG) {
+ pr_info("EPOW: Power configuration changed\n");
+ epow[EPOW_SYSPOWER_CHNG] = 1;
+ }
+
+ if (epow_status[OPAL_SYSEPOW_POWER] & OPAL_SYSPOWER_FAIL) {
+ pr_info("EPOW: Impending system power failure\n");
+ epow[EPOW_SYSPOWER_FAIL] = 1;
+ }
+
+ if (epow_status[OPAL_SYSEPOW_POWER] & OPAL_SYSPOWER_INCL) {
+ pr_info("EPOW: Incomplete system power\n");
+ epow[EPOW_SYSPOWER_INCL] = 1;
+ }
+
+ if (epow_status[OPAL_SYSEPOW_POWER] & OPAL_SYSPOWER_UPS) {
+ pr_info("EPOW: System on UPS power\n");
+ epow[EPOW_SYSPOWER_UPS] = 1;
+ }
+
+ if (!max_epow_class) {
+ pr_warn("EPOW: OPAL_SYSEPOW_TEMP subclass not present\n");
+ return;
+ }
+
+ /* Temperature */
+ max_epow_class--;
+ if (epow_status[OPAL_SYSEPOW_TEMP] & OPAL_SYSTEMP_AMB) {
+ pr_info("EPOW: Over ambient temperature\n");
+ epow[EPOW_SYSTEMP_AMB] = 1;
+ }
+
+ if (epow_status[OPAL_SYSEPOW_TEMP] & OPAL_SYSTEMP_INT) {
+ pr_info("EPOW: Over internal temperature\n");
+ epow[EPOW_SYSTEMP_INT] = 1;
+ }
+
+ if (epow_status[OPAL_SYSEPOW_TEMP] & OPAL_SYSTEMP_HMD) {
+ pr_info("EPOW: Over internal humidity\n");
+ epow[EPOW_SYSTEMP_HMD] = 1;
+ }
+
+ if (!max_epow_class) {
+ pr_warn("EPOW: OPAL_SYSEPOW_COOLING subclass not present\n");
+ return;
+ }
+
+ /* Cooling */
+ max_epow_class--;
+ if (epow_status[OPAL_SYSEPOW_COOLING] & OPAL_SYSCOOL_INSF) {
+ pr_info("EPOW: Insufficient cooling\n");
+ epow[EPOW_SYSCOOL_INSF] = 1;
+ }
+}
+
+/*
+ * fetch_epow_status
+ *
+ * Fetch the system EPOW status through an OPAL call and
+ * validate the number of EPOW sub class status received.
+ */
+static void fetch_epow_status(int16_t *epow_status, int16_t *n_epow)
+{
+ int rc;
+
+ memset(epow_status, 0, sizeof(int16_t) * OPAL_SYSEPOW_MAX);
+ *n_epow = OPAL_SYSEPOW_MAX;
+ rc = opal_get_epow_status(epow_status, n_epow);
+ if (rc != OPAL_SUCCESS) {
+ pr_err("EPOW: OPAL call failed\n");
+ memset(epow_status, 0, sizeof(int16_t) * OPAL_SYSEPOW_MAX);
+ *n_epow = 0;
+ return;
+ }
+ if (!(*n_epow))
+ pr_err("EPOW: No subclass status received\n");
+}
+
+/*
+ * fetch_dpo_timeout
+ *
+ * Fetch the system DPO timeout status through an OPAL call.
+ */
+static void fetch_dpo_timeout(int64_t *dpo_timeout)
+{
+ int rc;
+
+ rc = opal_get_dpo_status(dpo_timeout);
+ if (rc == OPAL_WRONG_STATE) {
+ pr_info("DPO: Not initiated by OPAL\n");
+ *dpo_timeout = 0;
+ }
+}
+
+/*
+ * valid_epow
+ *
+ * Validate the received EPOW event status. This ensures
+ * that there are valid status for various EPOW sub classes
+ * and their individual events.
+ */
+static bool valid_epow(int16_t *epow_status, int16_t n_epow)
+{
+ int i;
+
+ /* EPOW sub classes present */
+ if (!n_epow)
+ return false;
+
+ /* EPOW events present */
+ for (i = 0; i < n_epow; i++) {
+ if (epow_status[i])
+ return true;
+ }
+ return false;
+}
+
+/*
+ * epow_exclude
+ *
+ * XXX: EPOW events on the action exclude list. System shutdown
+ * would not be scheduled for all these platform events. In future
+ * this should be communicated from the platform firmware through
+ * device tree attributes.
+ */
+static bool epow_exclude(int epow_event)
+{
+ switch (epow_event) {
+ case EPOW_SYSPOWER_CHNG:
+ return true;
+ case EPOW_SYSPOWER_INCL:
+ return true;
+ case EPOW_SYSPOWER_UPS:
+ return true;
+ case EPOW_SYSTEMP_HMD:
+ return true;
+ case EPOW_SYSCOOL_INSF:
+ return true;
+ default:
+ return false;
+ }
+}
+
+/*
+ * actionable_epow
+ *
+ * There are some EPOW events for which the user client must receive
+ * their status but the driver would not schedule a timer for that
+ * event as the platform would not force shutdown the system because
+ * of this event. This filters only the actionable EPOW events for
+ * which shutdown timer need to be scheduled.
+ */
+static bool actionable_epow(__u64 *epow)
+{
+ int i;
+
+ for (i = 0; i < EPOW_MAX; i++) {
+ if (!epow_exclude(i) && epow[i])
+ return true;
+ }
+ return false;
+}
+
+/*
+ * opal_event_handle_basic
+ *
+ * Sets up the basic information for an opal platform event,
+ * activates the timer, adds to the list and wakes up waiting
+ * threads on the character device.
+ */
+static void opal_event_handle_basic(struct opal_platform_evt *evt,
+ unsigned long type, unsigned long timeout)
+{
+ unsigned long flags;
+
+ evt->opal_event.type = type;
+ switch (type) {
+ case OPAL_PLAT_EVENT_TYPE_EPOW:
+ evt->opal_event.size = sizeof(struct epow_event);
+ evt->opal_event.epow.timeout = timeout;
+ if (actionable_epow(evt->opal_event.epow.epow))
+ opal_event_start_timer(OPAL_PLAT_EVENT_TYPE_EPOW,
+ OPAL_EPOW_TIMEOUT);
+ break;
+ case OPAL_PLAT_EVENT_TYPE_DPO:
+ evt->opal_event.size = sizeof(struct dpo_event);
+ evt->opal_event.dpo.orig_timeout = timeout;
+ opal_event_start_timer(OPAL_PLAT_EVENT_TYPE_DPO, timeout);
+ break;
+ default:
+ pr_err("Unknown event type\n");
+ break;
+ }
+ spin_lock_irqsave(&opal_plat_evt_spinlock, flags);
+ list_add_tail(&evt->link, &opal_event_queue);
+ spin_unlock_irqrestore(&opal_plat_evt_spinlock, flags);
+ wake_up_interruptible(&opal_plat_evt_wait);
+}
+
+/*
+ * opal_event_existing_status
+ *
+ * Fetch and process existing opal platform event conditions
+ * present on the system. If events detected, add them to the
+ * list which can be consumed by the user space right away.
+ */
+static void opal_event_existing_status(void)
+{
+ struct opal_platform_evt *evt;
+ int64_t dpo_timeout;
+ int16_t epow_status[OPAL_SYSEPOW_MAX], n_epow;
+
+ fetch_epow_status(epow_status, &n_epow);
+ if (valid_epow(epow_status, n_epow)) {
+ evt = kzalloc(sizeof(struct opal_platform_evt), GFP_KERNEL);
+ if (!evt) {
+ pr_err("EPOW: Memory allocation for event failed\n");
+ return;
+ }
+ process_epow(evt->opal_event.epow.epow, epow_status, n_epow);
+ opal_event_handle_basic(evt, OPAL_PLAT_EVENT_TYPE_EPOW,
+ OPAL_EPOW_TIMEOUT);
+ }
+
+ fetch_dpo_timeout(&dpo_timeout);
+ if (dpo_timeout) {
+ evt = kzalloc(sizeof(struct opal_platform_evt), GFP_KERNEL);
+ if (!evt) {
+ pr_err("DPO: Memory allocation for event failed\n");
+ return;
+ }
+ opal_dpo_target = jiffies + dpo_timeout * HZ;
+ opal_event_handle_basic(evt, OPAL_PLAT_EVENT_TYPE_DPO,
+ dpo_timeout);
+ }
+}
+
+/* Platform EPOW message received */
+static int opal_epow_event(struct notifier_block *nb,
+ unsigned long msg_type, void *msg)
+{
+ struct opal_platform_evt *evt;
+ int16_t epow_status[OPAL_SYSEPOW_MAX], n_epow;
+
+ if (msg_type != OPAL_MSG_EPOW)
+ return 0;
+
+ fetch_epow_status(epow_status, &n_epow);
+ if (!valid_epow(epow_status, n_epow))
+ return -EINVAL;
+
+ pr_debug("EPOW event: Power(%x) Thermal(%x) Cooling(%x)\n",
+ epow_status[0], epow_status[1], epow_status[2]);
+ evt = kzalloc(sizeof(struct opal_platform_evt), GFP_KERNEL);
+ if (!evt) {
+ pr_err("EPOW: Memory allocation for event failed\n");
+ return -ENOMEM;
+ }
+ process_epow(evt->opal_event.epow.epow, epow_status, n_epow);
+ opal_event_handle_basic(evt,
+ OPAL_PLAT_EVENT_TYPE_EPOW, OPAL_EPOW_TIMEOUT);
+ return 0;
+}
+
+/* Platform DPO message received */
+static int opal_dpo_event(struct notifier_block *nb,
+ unsigned long msg_type, void *msg)
+{
+ struct opal_platform_evt *evt;
+ int64_t dpo_timeout;
+
+ if (msg_type != OPAL_MSG_DPO)
+ return 0;
+
+ fetch_dpo_timeout(&dpo_timeout);
+ if (!dpo_timeout)
+ return -EINVAL;
+
+ pr_debug("DPO event: Timeout:%llu\n", dpo_timeout);
+ evt = kzalloc(sizeof(struct opal_platform_evt), GFP_KERNEL);
+ if (!evt) {
+ pr_err("DPO: Memory allocation for event failed\n");
+ return -ENOMEM;
+ }
+ opal_dpo_target = jiffies + dpo_timeout * HZ;
+ opal_event_handle_basic(evt, OPAL_PLAT_EVENT_TYPE_DPO, dpo_timeout);
+ return 0;
+}
+
+/* OPAL EPOW event notifier block */
+static struct notifier_block opal_epow_nb = {
+ .notifier_call = opal_epow_event,
+ .next = NULL,
+ .priority = 0,
+};
+
+/* OPAL DPO event notifier block */
+static struct notifier_block opal_dpo_nb = {
+ .notifier_call = opal_dpo_event,
+ .next = NULL,
+ .priority = 0,
+};
+
+/* Platform driver probe */
+static int opal_event_probe(struct platform_device *pdev)
+{
+ struct device *dev;
+ int ret;
+
+ if (opal_event_probe_finished) {
+ pr_err("%s getting called once again\n", __func__);
+ return 0;
+ }
+ opal_event_probe_finished = true;
+
+ init_timer(&opal_event_timer);
+ opal_event_timer.function = opal_event_timeout;
+ opal_event_open_flag = false;
+ opal_dpo_target = 0;
+
+ ret = alloc_chrdev_region(&opal_event_dev, 0,
+ OPAL_EVENT_MAX_DEVS, "opal_event");
+ if (ret < 0) {
+ dev_err(&pdev->dev, "aloc_chrdev_region failed\n");
+ return ret;
+ }
+
+ opal_event_class = class_create(THIS_MODULE, "opal_event");
+ if (IS_ERR(opal_event_class)) {
+ ret = PTR_ERR(opal_event_class);
+ dev_err(&pdev->dev, "class_create failed with %d\n", ret);
+ goto fail_chrdev;
+ }
+
+ dev = device_create(opal_event_class, &pdev->dev,
+ opal_event_dev, NULL, "opal_event");
+ if (IS_ERR(dev)) {
+ ret = PTR_ERR(dev);
+ dev_err(&pdev->dev, "device_create failed with %d\n", ret);
+ goto fail_class;
+ }
+
+ cdev_init(&opal_event_cdev, &fops);
+ ret = cdev_add(&opal_event_cdev, opal_event_dev, OPAL_EVENT_MAX_DEVS);
+ if (ret < 0) {
+ dev_err(dev, "cdev_add failed\n");
+ ret = -EINVAL;
+ goto fail_device;
+ }
+
+ ret = opal_message_notifier_register(OPAL_MSG_EPOW, &opal_epow_nb);
+ if (ret) {
+ pr_err("EPOW: Platform event message notifier failed\n");
+ goto fail_cdev;
+ }
+
+ ret = opal_message_notifier_register(OPAL_MSG_DPO, &opal_dpo_nb);
+ if (ret) {
+ pr_err("DPO: Platform event message notifier failed\n");
+ opal_notifier_unregister(&opal_epow_nb);
+ goto fail_cdev;
+ }
+
+ /*
+ * During the system boot, reboot and kexecs, the host can miss
+ * some of the EPOW or DPO messages sent from OPAL. This ensures
+ * that the current status of EPOW or DPO if any, is fetched and
+ * then updated correctly. The user space needs to first read the
+ * existing system status before entering into the poll/read loop.
+ *
+ */
+ opal_event_existing_status();
+ pr_info("OPAL platform event driver initialized\n");
+ return 0;
+fail_cdev:
+ cdev_del(&opal_event_cdev);
+fail_device:
+ device_destroy(opal_event_class, opal_event_dev);
+fail_class:
+ class_destroy(opal_event_class);
+fail_chrdev:
+ unregister_chrdev_region(opal_event_dev, OPAL_EVENT_MAX_DEVS);
+ return ret;
+}
+
+/* Platform driver remove */
+static int opal_event_remove(struct platform_device *pdev)
+{
+ struct opal_platform_evt *evt;
+
+ /* OPAL notifiers */
+ opal_notifier_unregister(&opal_dpo_nb);
+ opal_notifier_unregister(&opal_epow_nb);
+
+ /* Devices */
+ cdev_del(&opal_event_cdev);
+ device_destroy(opal_event_class, opal_event_dev);
+ class_destroy(opal_event_class);
+ unregister_chrdev_region(opal_event_dev, OPAL_EVENT_MAX_DEVS);
+
+ /* Timers */
+ opal_event_stop_timer();
+
+ /* Flush the list */
+ while (!list_empty(&opal_event_queue)) {
+ evt = list_first_entry(&opal_event_queue,
+ struct opal_platform_evt, link);
+ list_del(&evt->link);
+ kfree(evt);
+ }
+
+ pr_info("OPAL platform event driver exited\n");
+ return 0;
+}
+
+/* Platform driver property match */
+static struct of_device_id opal_event_match[] = {
+ {
+ .compatible = "ibm,opal-v3-epow",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, opal_event_match);
+
+static struct platform_driver opal_event_driver = {
+ .probe = opal_event_probe,
+ .remove = opal_event_remove,
+ .driver = {
+ .name = "opal-platform-event-driver",
+ .owner = THIS_MODULE,
+ .of_match_table = opal_event_match,
+ },
+};
+
+static int __init opal_platform_event_init(void)
+{
+ opal_event_probe_finished = false;
+ return platform_driver_register(&opal_event_driver);
+}
+
+static void __exit opal_platform_event_exit(void)
+{
+ platform_driver_unregister(&opal_event_driver);
+}
+module_init(opal_platform_event_init);
+module_exit(opal_platform_event_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Anshuman Khandual <khandual@linux.vnet.ibm.com>");
+MODULE_DESCRIPTION("PowerNV OPAL platform events driver");
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S
index 2e6ce1b..2d1dc99 100644
--- a/arch/powerpc/platforms/powernv/opal-wrappers.S
+++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
@@ -247,3 +247,4 @@ OPAL_CALL(opal_set_param, OPAL_SET_PARAM);
OPAL_CALL(opal_handle_hmi, OPAL_HANDLE_HMI);
OPAL_CALL(opal_register_dump_region, OPAL_REGISTER_DUMP_REGION);
OPAL_CALL(opal_unregister_dump_region, OPAL_UNREGISTER_DUMP_REGION);
+OPAL_CALL(opal_get_dpo_status, OPAL_GET_DPO_STATUS);
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index b44eec3..869dd45 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -625,7 +625,7 @@ static void __init opal_dump_region_init(void)
}
static int __init opal_init(void)
{
- struct device_node *np, *consoles;
+ struct device_node *np, *consoles, *epow;
const __be32 *irqs;
int rc, i, irqlen;
@@ -649,6 +649,12 @@ static int __init opal_init(void)
of_node_put(consoles);
}
+ epow = of_find_node_by_path("/ibm,opal/epow");
+ if (epow) {
+ of_platform_device_create(epow, "opal_event", NULL);
+ of_node_put(epow);
+ }
+
/* Find all OPAL interrupts and request them */
irqs = of_get_property(opal_node, "opal-interrupts", &irqlen);
pr_debug("opal: Found %d interrupts reserved for OPAL\n",
--
1.9.3
^ permalink raw reply related
* [PATCH] powerpc/powernv: Fallback to old HMI handling behavior for old firmware
From: Mahesh J Salgaonkar @ 2014-10-06 9:34 UTC (permalink / raw)
To: Michael Ellerman, linuxppc-dev, Benjamin Herrenschmidt; +Cc: Paul Mackerras
From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
Recently we moved HMI handling into Linux kernel instead of taking
HMI directly in OPAL. This new change is dependent on new OPAL call
for HMI recovery which was introduced in newer firmware. While this new
change works fine with latest OPAL firmware, we broke the HMI handling
if we run newer kernel on old OPAL firmware that results in system hang.
This patch fixes this issue by falling back to old HMI behavior on older
OPAL firmware.
This patch introduces a check for opal token OPAL_HANDLE_HMI to see
if we are running on newer firmware or old firmware. On newer firmware
this check would return OPAL_TOKEN_PRESENT, otherwise we are running on
old firmware and fallback to old HMI behavior.
This patch depends on opal check token patch posted at ppc-devel
https://lists.ozlabs.org/pipermail/linuxppc-dev/2014-August/120224.html
Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
---
arch/powerpc/platforms/powernv/opal.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index b44eec3..2768cd3 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -194,6 +194,24 @@ static int __init opal_register_exception_handlers(void)
* fwnmi area at 0x7000 to provide the glue space to OPAL
*/
glue = 0x7000;
+
+ /* Check if we are running on newer firmware that exports
+ * OPAL_HANDLE_HMI token. If yes, then don't ask opal to patch
+ * HMI interrupt and we catch it directly in Linux kernel.
+ *
+ * For older firmware we will fallback to old behavior and
+ * let OPAL patch the HMI vector and handle it inside OPAL
+ * firmware.
+ */
+ if (opal_check_token(OPAL_HANDLE_HMI) != OPAL_TOKEN_PRESENT) {
+ /* We are on old firmware. fallback to old behavior. */
+ pr_info("%s: Falling back to old HMI handling behavior.\n",
+ __func__);
+ opal_register_exception_handler(
+ OPAL_HYPERVISOR_MAINTENANCE_HANDLER,
+ 0, glue);
+ glue += 128;
+ }
opal_register_exception_handler(OPAL_SOFTPATCH_HANDLER, 0, glue);
#endif
^ permalink raw reply related
* Re: [PATCH 00/20] powerpc: Convert power off logic to pm_power_off
From: Alexander Graf @ 2014-10-06 10:00 UTC (permalink / raw)
To: Michael Ellerman
Cc: Arnd Bergmann, Geoff Levand, Alistair Popple, Scott Wood,
Anatolij Gustschin, linuxppc-dev
In-Reply-To: <1412311350.2783.4.camel@concordia>
On 03.10.14 06:42, Michael Ellerman wrote:
> On Wed, 2014-10-01 at 15:27 +0200, Alexander Graf wrote:
>> The generic Linux framework to power off the machine is a function pointer
>> called pm_power_off. The trick about this pointer is that device drivers can
>> potentially implement it rather than board files.
>>
>> Today on PowerPC we set pm_power_off to invoke our generic full machine power
>> off logic which then calls ppc_md.power_off to invoke machine specific power
>> off.
>>
>> To fix this up, let's get rid of the ppc_md.power_off logic and just always use
>> pm_power_off as was intended. Then individual drivers such as the GPIO power off
>> driver can implement power off logic via that function pointer.
>
> This looks OK to me with one caveat.
>
> In several of the patches you're replacing a static initialisation with a
> runtime one, and you're doing the runtime initialisation in xxx_setup_arch().
> That's reasonably late, so I'd prefer you did it in xxx_probe().
Heh, I had it in xxx_probe() originally and then realized that
a) the power off function is basically a driver. Driver initialization
happens in xxx_setup_arch() and
b) the maple target already does overwrite its power_off callback in
xxx_setup_arch and
c) on all targets xxx_probe() is very slim and doesn't do much
but I'll happily change it back to put the bits in xxx_probe() instead.
Alex
^ permalink raw reply
* Re: [PATCH 03/20] powerpc/47x: Use pm_power_off rather than ppc_md.power_off
From: Alexander Graf @ 2014-10-06 10:02 UTC (permalink / raw)
To: Segher Boessenkool
Cc: Arnd Bergmann, Geoff Levand, Alistair Popple, Scott Wood,
Anatolij Gustschin, linuxppc-dev
In-Reply-To: <20141005003925.GA26256@gate.crashing.org>
On 05.10.14 02:39, Segher Boessenkool wrote:
> On Wed, Oct 01, 2014 at 03:27:49PM +0200, Alexander Graf wrote:
>> diff --git a/arch/powerpc/platforms/44x/ppc476.c b/arch/powerpc/platforms/44x/ppc476.c
>> index 33986c1..7027015 100644
>> --- a/arch/powerpc/platforms/44x/ppc476.c
>> +++ b/arch/powerpc/platforms/44x/ppc476.c
>> @@ -94,7 +94,7 @@ static int avr_probe(struct i2c_client *client,
>> {
>> avr_i2c_client = client;
>> ppc_md.restart = avr_reset_system;
>> - ppc_md.power_off = avr_power_off_system;
>> + pm_power_off = avr_power_off_system
>> return 0;
>> }
>
> That doesn't compile afaics?
Oops :(. Is there any easy way to test compile all targets?
Alex
^ permalink raw reply
* Re: [PATCH 1/5] kexec: Fix make headers_check
From: Paul Bolle @ 2014-10-06 14:12 UTC (permalink / raw)
To: Geoff Levand
Cc: maximilian attems, kexec, linux-kernel, Eric Biederman,
H. Peter Anvin, Andrew Morton, linuxppc-dev, Vivek Goyal
In-Reply-To: <1409402838.21896.99.camel@x220>
Hi Geoff,
On Sat, 2014-08-30 at 14:47 +0200, Paul Bolle wrote:
> [Added Peter Anvin.]
>
> On Mon, 2014-08-25 at 13:22 -0400, Vivek Goyal wrote:
> > On Fri, Aug 22, 2014 at 06:39:47PM +0000, Geoff Levand wrote:
> > > Remove the unneded declaration for a kexec_load() routine.
> > >
> > > Fixes errors like these when running 'make headers_check':
> > >
> > > include/uapi/linux/kexec.h: userspace cannot reference function or variable defined in the kernel
> > >
> > > Signed-off-by: Geoff Levand <geoff@infradead.org>
> >
> > I think Paul Bolle tried to remove this in the past and maximilian
> > had objections.
> >
> > http://lists.infradead.org/pipermail/kexec/2014-January/010902.html
>
> I've wanted to resend my patch, perhaps with a new commit explanation,
> for quite some time now. I never got around doing that.
>
> > I can't see that how exporting kernel prototype helps here.
>
> It doesn't, for the reasons I've set out in
> http://lists.infradead.org/pipermail/kexec/2014-January/010900.html . In
> short: why bother using this prototype if one still needs to define the
> matching function oneself?
>
> > kexec-tools
> > seems to be using syscall(__NR_kexec_load) directly for non-xen case. So
> > I would be fine with removing this definition. Just trying to make sure
> > that it does not break any other library or users of this declaration.
>
> Obviously, this can only break compiling those libraries, or other
> users. It can't break already compiled binaries. Besides I don't think
> those libraries, etc actually exist. Maximilian mentioned klibc in
> January, but I wasn't able to find a version of klibc that cared about
> this prototype. No one pointed me at a version that does (or any other
> library, etc., for that matter).
>
> (If we do decide to keep this prototype, we should special case this
> prototype in headers_check.pl just to silence the build.)
>
> The above can be summarized like this:
> Acked-by: Paul Bolle <pebolle@tiscali.nl>
It seems not much happened after I added my Acked-by. I assume you still
want to get this merged. Is that correct?
Paul Bolle
^ permalink raw reply
* Re: [PATCH 1/5] kexec: Fix make headers_check
From: Geoff Levand @ 2014-10-06 17:34 UTC (permalink / raw)
To: Paul Bolle, Andrew Morton
Cc: maximilian attems, kexec, linux-kernel, Eric Biederman,
H. Peter Anvin, Andrew Morton, linuxppc-dev, Vivek Goyal
In-Reply-To: <1412604734.4054.72.camel@x220>
Hi,
On Mon, 2014-10-06 at 16:12 +0200, Paul Bolle wrote:
> On Sat, 2014-08-30 at 14:47 +0200, Paul Bolle wrote:
> > [Added Peter Anvin.]
> >
> > On Mon, 2014-08-25 at 13:22 -0400, Vivek Goyal wrote:
> > > On Fri, Aug 22, 2014 at 06:39:47PM +0000, Geoff Levand wrote:
> > > > Remove the unneded declaration for a kexec_load() routine.
> > > >
> > > > Fixes errors like these when running 'make headers_check':
> > > >
> > > > include/uapi/linux/kexec.h: userspace cannot reference function or variable defined in the kernel
> > > >
> > > > Signed-off-by: Geoff Levand <geoff@infradead.org>
> > >
> > > I think Paul Bolle tried to remove this in the past and maximilian
> > > had objections.
> > >
> > > http://lists.infradead.org/pipermail/kexec/2014-January/010902.html
> >
> > I've wanted to resend my patch, perhaps with a new commit explanation,
> > for quite some time now. I never got around doing that.
> >
> > > I can't see that how exporting kernel prototype helps here.
> >
> > It doesn't, for the reasons I've set out in
> > http://lists.infradead.org/pipermail/kexec/2014-January/010900.html . In
> > short: why bother using this prototype if one still needs to define the
> > matching function oneself?
> >
> > > kexec-tools
> > > seems to be using syscall(__NR_kexec_load) directly for non-xen case. So
> > > I would be fine with removing this definition. Just trying to make sure
> > > that it does not break any other library or users of this declaration.
> >
> > Obviously, this can only break compiling those libraries, or other
> > users. It can't break already compiled binaries. Besides I don't think
> > those libraries, etc actually exist. Maximilian mentioned klibc in
> > January, but I wasn't able to find a version of klibc that cared about
> > this prototype. No one pointed me at a version that does (or any other
> > library, etc., for that matter).
> >
> > (If we do decide to keep this prototype, we should special case this
> > prototype in headers_check.pl just to silence the build.)
> >
> > The above can be summarized like this:
> > Acked-by: Paul Bolle <pebolle@tiscali.nl>
>
> It seems not much happened after I added my Acked-by. I assume you still
> want to get this merged. Is that correct?
Yes, I think we concluded there are no real users of this kexec_load()
ptototype, and so it can be removed.
-Geoff
^ permalink raw reply
* Re: [PATCH 1/5] kexec: Fix make headers_check
From: H. Peter Anvin @ 2014-10-06 17:44 UTC (permalink / raw)
To: Paul Bolle, Vivek Goyal
Cc: maximilian attems, Geoff Levand, kexec, linux-kernel,
Eric Biederman, Andrew Morton, linuxppc-dev
In-Reply-To: <1409402838.21896.99.camel@x220>
On 08/30/2014 05:47 AM, Paul Bolle wrote:
>
> Obviously, this can only break compiling those libraries, or other
> users. It can't break already compiled binaries. Besides I don't think
> those libraries, etc actually exist. Maximilian mentioned klibc in
> January, but I wasn't able to find a version of klibc that cared about
> this prototype. No one pointed me at a version that does (or any other
> library, etc., for that matter).
>
... and that would be a klibc bug and we'd just fix it.
-hpa
^ permalink raw reply
* Re: [PATCH 1/5] kexec: Fix make headers_check
From: Paul Bolle @ 2014-10-06 18:21 UTC (permalink / raw)
To: Geoff Levand
Cc: maximilian attems, kexec, linux-kernel, Eric Biederman,
H. Peter Anvin, Andrew Morton, linuxppc-dev, Vivek Goyal
In-Reply-To: <1412616877.32313.55.camel@smoke>
On Mon, 2014-10-06 at 10:34 -0700, Geoff Levand wrote:
> On Mon, 2014-10-06 at 16:12 +0200, Paul Bolle wrote:
> > It seems not much happened after I added my Acked-by. I assume you still
> > want to get this merged. Is that correct?
>
> Yes, I think we concluded there are no real users of this kexec_load()
> ptototype, and so it can be removed.
What would be the quickest way to get this finally resolved? Who's in
charge of this stuff? Would resending your patch, with my Ack added,
speed up things? The vain side of my personality does think it would
help.
Paul Bolle
^ permalink raw reply
* Re: [PATCH 1/5] kexec: Fix make headers_check
From: Geoff Levand @ 2014-10-06 19:28 UTC (permalink / raw)
To: Paul Bolle
Cc: maximilian attems, kexec, linux-kernel, Eric Biederman,
H. Peter Anvin, Andrew Morton, linuxppc-dev, Vivek Goyal
In-Reply-To: <1412619708.14236.2.camel@x220>
On Mon, 2014-10-06 at 20:21 +0200, Paul Bolle wrote:
> On Mon, 2014-10-06 at 10:34 -0700, Geoff Levand wrote:
> > On Mon, 2014-10-06 at 16:12 +0200, Paul Bolle wrote:
> > > It seems not much happened after I added my Acked-by. I assume you still
> > > want to get this merged. Is that correct?
> >
> > Yes, I think we concluded there are no real users of this kexec_load()
> > ptototype, and so it can be removed.
>
> What would be the quickest way to get this finally resolved? Who's in
> charge of this stuff? Would resending your patch, with my Ack added,
> speed up things? The vain side of my personality does think it would
> help.
I'll prepare a V2 set of the this series with the various acks and ask
Andrew to merge it.
-Geoff
^ permalink raw reply
* Re: [PATCH v2] powerpc/vphn: fix endian issue in NUMA device node code
From: Nishanth Aravamudan @ 2014-10-06 22:36 UTC (permalink / raw)
To: Greg Kurz; +Cc: linuxppc-dev
In-Reply-To: <20141003091250.28354.13766.stgit@bahia.local>
On 03.10.2014 [11:13:17 +0200], Greg Kurz wrote:
> The associativity domain numbers are obtained from the hypervisor through
> registers and written into memory by the guest: the packed array passed to
> vphn_unpack_associativity() is then native-endian, unlike what was assumed
> in the following commit:
>
> commit b08a2a12e44eaec5024b2b969f4fcb98169d1ca3
> Author: Alistair Popple <alistair@popple.id.au>
> Date: Wed Aug 7 02:01:44 2013 +1000
>
> powerpc: Make NUMA device node code endian safe
>
> If a CPU home node changes, the topology gets filled with
> bogus values. This leads to severe performance breakdowns.
>
> This patch does two things:
> - extract values from the packed array with shifts, in order to be endian
> neutral
> - convert the resulting values to be32 as expected
>
> Suggested-by: Anton Blanchard <anton@samba.org>
> Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Reviewed-by: Nishanth Aravamudan <nacc@linux.vnet.ibm.com>
Tested-by: Nishanth Aravamudan <nacc@linux.vnet.ibm.com>
> ---
>
> Changes in v2:
> - removed the left out __be16 *field declaration
> - removed the left out be16_to_cpup() call
> - updated the comment of the magic formula
>
> Thanks again Nish... the two left outs probably explain why PowerVM wasn't
> happy that patch. :P
Yep, I've tested this v2 patch successfully now!
-Nish
^ permalink raw reply
* Re: [PATCH v2 1/2] spi: fsl-spi: Fix parameter ram offset setup for CPM1
From: Scott Wood @ 2014-10-07 0:15 UTC (permalink / raw)
To: christophe leroy; +Cc: Mark Brown, linuxppc-dev, linux-kernel, linux-spi
In-Reply-To: <542FE1C4.7000403@c-s.fr>
On Sat, 2014-10-04 at 14:02 +0200, christophe leroy wrote:
> Le 03/10/2014 22:29, Scott Wood a écrit :
> > On Fri, 2014-10-03 at 18:49 +0200, Christophe Leroy wrote:
> >> On CPM1, the SPI parameter RAM has a default location. In fsl_spi_cpm_get_pram()
> >> there was a confusion between the SPI_BASE register and the base of the SPI
> >> parameter RAM. Fortunatly, it was working properly with MPC866 and MPC885
> >> because they do set SPI_BASE, but on MPC860 and other old MPC8xx that doesn't
> >> set SPI_BASE, pram_ofs was not properly set. This patch fixes this confusion.
> >>
> >> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
> >>
> >> ---
> >> Changes from v1 to v2: none
> >>
> >> drivers/spi/spi-fsl-cpm.c | 9 ++++-----
> >> 1 file changed, 4 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/drivers/spi/spi-fsl-cpm.c b/drivers/spi/spi-fsl-cpm.c
> >> index 54b0637..0f3a912 100644
> >> --- a/drivers/spi/spi-fsl-cpm.c
> >> +++ b/drivers/spi/spi-fsl-cpm.c
> >> @@ -262,15 +262,14 @@ static unsigned long fsl_spi_cpm_get_pram(struct mpc8xxx_spi *mspi)
> >> pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 64);
> >> out_be16(spi_base, pram_ofs);
> >> } else {
> >> - struct spi_pram __iomem *pram = spi_base;
> >> - u16 rpbase = in_be16(&pram->rpbase);
> >> + u16 rpbase = in_be16(spi_base);
> >>
> >> - /* Microcode relocation patch applied? */
> >> + /* Microcode relocation patch applied | rpbase set by default */
> >> if (rpbase) {
> >> pram_ofs = rpbase;
> >> } else {
> >> - pram_ofs = cpm_muram_alloc(SPI_PRAM_SIZE, 64);
> >> - out_be16(spi_base, pram_ofs);
> >> + pram_ofs = offsetof(cpm8xx_t, cp_dparam[PROFF_SPI]) -
> >> + offsetof(cpm8xx_t, cp_dpmem[0]);
> >> }
> >> }
> > Why is PROFF_SPI not coming from the device tree?
> That's where it starts to become tricky.
>
> PROFF_SPI is defined in cpm1.h which is included by the driver already.
Yes, but those values shouldn't be used. It's a leftover from the old
way of hardcoding things and describing the hardware with kconfig rather
than the device tree.
> It provides the default offset from the start of the parameter RAM.
> Previously I had the following in my device tree, and the last part of
> the source above (the one for rpbase == 0) could not work.
>
> spi: spi@a80 {
> cell-index = <0>;
> compatible = "fsl,spi", "fsl,cpm1-spi";
> reg = <0xa80 0x30 0x3d80 0x30>;
>
> First reg area was the area for SPI registers. Second area was the
> parameter RAM zone, which was just mapped to get access to the SPI_BASE
> pointer (rpbase)
>
> Now I have
>
> compatible = "fsl,spi", "fsl,cpm1-spi-reloc";
> reg = <0xa80 0x30 0x3dac 0x2>;
>
> First reg area is the area for SPI registers. Second area is the
> SPI_BASE, as for the CPM2.
>
> On recent 8xx (885 and 866 at least) it contains the offset (=0x1D80) of
> the parameter RAM. But on old ones (860, ...) it contains 0. Therefore
> we have to get the default index in another way.
> What I wanted was to keep something similar to what's done with CPM2.
>
> What should it look like if that offset had to be in the device tree ?
If the offset is not relocatable or discoverable, it should stay in the
device tree. If you have an old chip you wouldn't have
fsl,cpm1-spi-reloc and thus you'd still have "0x3d80 0x30" in reg.
> > Why don't I see any
> > cpm spi in any device tree nor any binding for it?
> There's one in mgcoge.dts:
>
> spi@11aa0 {
> cell-index = <0>;
> compatible = "fsl,spi", "fsl,cpm2-spi";
> reg = <0x11a80 0x40 0x89fc 0x2>;
I'm not sure why I missed that, but this patch is for cpm1-spi, not
cpm2-spi...
Even if you insist on keeping your board dts out-of-tree, there should
at least be a binding in-tree.
BTW, more specific compatibles should come first.
-Scott
^ permalink raw reply
* Re: [PATCH 2/2] spi: fsl-spi: Allow dynamic allocation of CPM1 parameter RAM
From: Scott Wood @ 2014-10-07 0:19 UTC (permalink / raw)
To: christophe leroy
Cc: Marcelo Tosatti, linux-kernel, linux-spi, Mark Brown,
Paul Mackerras, linuxppc-dev
In-Reply-To: <542FC8C1.1000707@c-s.fr>
On Sat, 2014-10-04 at 12:15 +0200, christophe leroy wrote:
> Le 03/10/2014 22:24, Scott Wood a écrit :
> > On Fri, 2014-10-03 at 22:15 +0200, christophe leroy wrote:
> >> Le 03/10/2014 16:44, Mark Brown a écrit :
> >>> On Fri, Oct 03, 2014 at 02:56:09PM +0200, Christophe Leroy wrote:
> >>>
> >>>> +config CPM1_RELOCSPI
> >>>> + bool "Dynamic SPI relocation"
> >>>> + default n
> >>>> + help
> >>>> + On recent MPC8xx (at least MPC866 and MPC885) SPI can be relocated
> >>>> + without micropatch. This activates relocation to a dynamically
> >>>> + allocated area in the CPM Dual port RAM.
> >>>> + When combined with SPI relocation patch (for older MPC8xx) it avoids
> >>>> + the "loss" of additional Dual port RAM space just above the patch,
> >>>> + which might be needed for example when using the CPM QMC.
> >>> Something like this shouldn't be a compile time option. Either it
> >>> should be unconditional or it should be triggered in some system
> >>> specific manner (from DT, from knowing about other users or similar).
> >> Can't be unconditional as older versions of mpc8xx (eg MPC860) don't
> >> support relocation without a micropatch.
> >> I have therefore submitted a v2 based on a DTS compatible property.
> > So the device tree change is about whether relocation is supported, not
> > whether it is required?
> Indeed no, my intension is to say that relocation is requested. Do you
> mean that it should then not use a compatible ?
The device tree describes hardware. It doesn't tell software how to use
that hardware.
Based on one of your other e-mails, I think what you want to say here is
that the old binding didn't describe the registers needed for
relocation, so the new compatible describes the new binding, rather than
requesting that software do a relocation. Software that sees the new
binding could choose to relocate, or just choose to read the current
offset from the register.
> > How about checking for the existing specific-SoC compatibles?
> What do you mean ?
Look for "fsl,mpc885-cpm-i2c" etc. Or, if you didn't follow that
pattern (remember, I can't see your device tree!), look for
"fsl,mpc885-cpm" or "fsl,mpc866-cpm" in the parent node. It's moot
though, if the device tree also needs to be modified to describe the
register used to relocate.
-Scott
^ permalink raw reply
* [PATCH V21/5] kexec: Fix make headers_check
From: Geoff Levand @ 2014-10-07 0:21 UTC (permalink / raw)
To: Andrew Morton; +Cc: linuxppc-dev, kexec, Eric Biederman, linux-kernel
In-Reply-To: <cover.1412640584.git.geoff@infradead.org>
Remove the unneded declaration for a kexec_load() routine.
Fixes errors like these when running 'make headers_check':
include/uapi/linux/kexec.h: userspace cannot reference function or variable defined in the kernel
Signed-off-by: Geoff Levand <geoff@infradead.org>
Acked-by: Paul Bolle <pebolle@tiscali.nl>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Vivek Goyal <vgoyal@redhat.com>
---
include/uapi/linux/kexec.h | 6 ------
1 file changed, 6 deletions(-)
diff --git a/include/uapi/linux/kexec.h b/include/uapi/linux/kexec.h
index 6925f5b..99048e5 100644
--- a/include/uapi/linux/kexec.h
+++ b/include/uapi/linux/kexec.h
@@ -55,12 +55,6 @@ struct kexec_segment {
size_t memsz;
};
-/* Load a new kernel image as described by the kexec_segment array
- * consisting of passed number of segments at the entry-point address.
- * The flags allow different useage types.
- */
-extern int kexec_load(void *, size_t, struct kexec_segment *,
- unsigned long int);
#endif /* __KERNEL__ */
#endif /* _UAPILINUX_KEXEC_H */
--
1.9.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox