* Re: [PATCH 4/4] KVM: PPC: Bookehv: Get vcpu's last instruction for emulation
From: Scott Wood @ 2014-04-01 16:58 UTC (permalink / raw)
To: Alexander Graf
Cc: Mihai Caraman, <linuxppc-dev@lists.ozlabs.org>,
<kvm@vger.kernel.org>, <kvm-ppc@vger.kernel.org>
In-Reply-To: <9EA94FFE-EC8B-40BE-A6BE-1D0FCF81F2E9@suse.de>
On Tue, 2014-04-01 at 07:47 +0200, Alexander Graf wrote:
>
> > Am 01.04.2014 um 01:03 schrieb Scott Wood <scottwood@freescale.com>:
> >
> >> On Mon, 2014-03-31 at 15:41 +0200, Alexander Graf wrote:
> >>> On 03/26/2014 10:17 PM, Scott Wood wrote:
> >>>> On Thu, 2014-02-20 at 18:30 +0200, Mihai Caraman wrote:
> >>>> + /*
> >>>> + * Another thread may rewrite the TLB entry in parallel, don't
> >>>> + * execute from the address if the execute permission is not set
> >>>> + */
> >>
> >> What happens when another thread rewrites the TLB entry in parallel?
> >> Does tlbsx succeed? Does it fail? Do we see failure indicated somehow?
> >> Are the contents of the MAS registers consistent at this point or
> >> inconsistent?
> >
> > If another thread rewrites the TLB entry, then we use the new TLB entry,
> > just as if it had raced in hardware. This check ensures that we don't
> > execute from the new TLB entry if it doesn't have execute permissions
> > (just as hardware would).
> >
> > What happens if the new TLB entry is valid and executable, and the
> > instruction pointed to is valid, but doesn't trap (and thus we don't
> > have emulation for it)?
> >
> >> There has to be a good way to detect such a race and deal with it, no?
> >
> > How would you detect it? We don't get any information from the trap
> > about what physical address the instruction was fetched from, or what
> > the instruction was.
>
> Ah, this is a guest race where the guest modifies exactly the TLB in question. I see.
>
> Why would this ever happen in practice (in a case where we're not executing malicious code)?
I don't know. It probably wouldn't. But it seems wrong to not check
the exec bit.
-Scott
^ permalink raw reply
* Re: [PATCH bisect 2/2] ASoC: fsl_sai: Separately enable interrupts for Tx and Rx streams
From: Mark Brown @ 2014-04-01 16:42 UTC (permalink / raw)
To: Nicolin Chen; +Cc: alsa-devel, Li.Xiubo, linuxppc-dev, linux-kernel, timur
In-Reply-To: <20140401132156.GB27586@MrMyself>
[-- Attachment #1: Type: text/plain, Size: 511 bytes --]
On Tue, Apr 01, 2014 at 09:21:57PM +0800, Nicolin Chen wrote:
> Sir, I just rebased my for-next branch again and found that it's missing
> two applied patches: "ASoC: fsl_sai: Add isr to deal with error flag" and
> "ASoC: fsl_sai: Improve fsl_sai_isr()", so that's why this PATCH-2 could
> not be applied against it as it needs the macro that's included in the
> patch "ASoC: fsl_sai: Add isr to deal with error flag".
Ah, those dropped out of -next due to the merge window. I've applied
your new patch now.
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH 15/33] powerpc: Fix ABIv2 issues with stack offsets in assembly code
From: Philippe Bergheaud @ 2014-04-01 13:54 UTC (permalink / raw)
To: Anton Blanchard
Cc: mikey, amodra, rusty, ulrich.weigand, paulus, mjw, linuxppc-dev
In-Reply-To: <1395747879-5948-16-git-send-email-anton@samba.org>
Anton Blanchard wrote:
> diff --git a/arch/powerpc/lib/memcpy_64.S b/arch/powerpc/lib/memcpy_64.S
> index 72ad055..01da956 100644
> --- a/arch/powerpc/lib/memcpy_64.S
> +++ b/arch/powerpc/lib/memcpy_64.S
> @@ -12,7 +12,7 @@
> .align 7
> _GLOBAL(memcpy)
> BEGIN_FTR_SECTION
> - std r3,48(r1) /* save destination pointer for return value */
> + std r3,STK_PARAM(R3)(r1) /* save destination pointer for return value */
> FTR_SECTION_ELSE
> #ifndef SELFTEST
> b memcpy_power7
This chunk is rejected when applied to linux-3.14, because of the reference to SELTEST.
The last three context lines should rather read:
FTR_SECTION_ELSE
b memcpy_power7
ALT_FTR_SECTION_END_IFCLR(CPU_FTR_VMX_COPY)
Same issue with [PATCH 16/33] powerpc: Fix unsafe accesses to parameter area in ELFv2.
Philippe
^ permalink raw reply
* [PATCH] powerpc: Use 64k io pages when we never see an HEA
From: Alexander Graf @ 2014-04-01 13:46 UTC (permalink / raw)
To: linuxppc-dev
When we never get around to seeing an HEA ethernet adapter, there's
no point in restricting ourselves to 4k IO page size.
This speeds up IO maps when CONFIG_IBMEBUS is disabled.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
arch/powerpc/mm/hash_utils_64.c | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index d766d6e..c0ef976 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -445,6 +445,20 @@ static void mmu_psize_set_default_penc(void)
mmu_psize_defs[bpsize].penc[apsize] = -1;
}
+static bool might_have_hea(void)
+{
+ /*
+ * The HEA ethernet adapter requires awareness of the
+ * GX bus. Without that awareness we can easily assume
+ * we will never see an HEA ethernet device.
+ */
+#ifdef CONFIG_IBMEBUS
+ return true;
+#else
+ return false;
+#endif
+}
+
static void __init htab_init_page_sizes(void)
{
int rc;
@@ -499,10 +513,11 @@ static void __init htab_init_page_sizes(void)
mmu_linear_psize = MMU_PAGE_64K;
if (mmu_has_feature(MMU_FTR_CI_LARGE_PAGE)) {
/*
- * Don't use 64k pages for ioremap on pSeries, since
- * that would stop us accessing the HEA ethernet.
+ * When running on pSeries using 64k pages for ioremap
+ * would stop us accessing the HEA ethernet. So if we
+ * have the chance of ever seeing one, stay at 4k.
*/
- if (!machine_is(pseries))
+ if (!might_have_hea() || !machine_is(pseries))
mmu_io_psize = MMU_PAGE_64K;
} else
mmu_ci_restrictions = 1;
--
1.8.1.4
^ permalink raw reply related
* Re: [PATCH bisect 2/2] ASoC: fsl_sai: Separately enable interrupts for Tx and Rx streams
From: Nicolin Chen @ 2014-04-01 13:21 UTC (permalink / raw)
To: Mark Brown; +Cc: alsa-devel, Li.Xiubo, linuxppc-dev, linux-kernel, timur
In-Reply-To: <20140401120715.GR2269@sirena.org.uk>
On Tue, Apr 01, 2014 at 01:07:15PM +0100, Mark Brown wrote:
> On Tue, Apr 01, 2014 at 11:17:07AM +0800, Nicolin Chen wrote:
> > We only enable one side interrupt for each stream since over/underrun
> > on the opposite stream would be resulted from what we previously did,
> > enabling TERE but remaining FRDE disabled, even though the xrun on the
> > opposite direction will not break the current stream.
>
> This still doesn't apply against fsl-sai (nor for-next).
Sir, I just rebased my for-next branch again and found that it's missing
two applied patches: "ASoC: fsl_sai: Add isr to deal with error flag" and
"ASoC: fsl_sai: Improve fsl_sai_isr()", so that's why this PATCH-2 could
not be applied against it as it needs the macro that's included in the
patch "ASoC: fsl_sai: Add isr to deal with error flag".
What should I do now?
Thank you,
Nicolin
^ permalink raw reply
* Re: [PATCH bisect 2/2] ASoC: fsl_sai: Separately enable interrupts for Tx and Rx streams
From: Mark Brown @ 2014-04-01 12:07 UTC (permalink / raw)
To: Nicolin Chen; +Cc: alsa-devel, Li.Xiubo, linuxppc-dev, linux-kernel, timur
In-Reply-To: <1396322227-482-3-git-send-email-Guangyu.Chen@freescale.com>
[-- Attachment #1: Type: text/plain, Size: 393 bytes --]
On Tue, Apr 01, 2014 at 11:17:07AM +0800, Nicolin Chen wrote:
> We only enable one side interrupt for each stream since over/underrun
> on the opposite stream would be resulted from what we previously did,
> enabling TERE but remaining FRDE disabled, even though the xrun on the
> opposite direction will not break the current stream.
This still doesn't apply against fsl-sai (nor for-next).
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH bisect 1/2] ASoC: fsl_sai: Fix buggy configurations in trigger()
From: Mark Brown @ 2014-04-01 11:56 UTC (permalink / raw)
To: Nicolin Chen; +Cc: alsa-devel, Li.Xiubo, linuxppc-dev, linux-kernel, timur
In-Reply-To: <1396322227-482-2-git-send-email-Guangyu.Chen@freescale.com>
[-- Attachment #1: Type: text/plain, Size: 498 bytes --]
On Tue, Apr 01, 2014 at 11:17:06AM +0800, Nicolin Chen wrote:
> The current trigger() has two crucial problems:
> 1) The DMA request enabling operations (FSL_SAI_CSR_FRDE) for Tx and Rx are
> now totally exclusive: It would fail to run simultaneous Tx-Rx cases.
> 2) The TERE disabling operation depends on an incorrect condition -- active
> reference count that only gets increased in snd_pcm_open() and decreased
> in snd_pcm_close(): The TERE would never get cleared.
Applied, thanks.
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* [PATCH 2/2] ARM: dts: Add ipg clock for sai2 on VF610 platform
From: Nicolin Chen @ 2014-04-01 11:52 UTC (permalink / raw)
To: broonie, shawn.guo
Cc: mark.rutland, devicetree, alsa-devel, pawel.moll, linux-doc,
ijc+devicetree, linux-kernel, robh+dt, timur, Li.Xiubo, rob,
galak, linuxppc-dev
In-Reply-To: <cover.1396352401.git.Guangyu.Chen@freescale.com>
Since we added ipg clock to the DT binding, we should update the current
SAI dts/dtsi so as not to break their functions.
Signed-off-by: Nicolin Chen <Guangyu.Chen@freescale.com>
---
arch/arm/boot/dts/vf610.dtsi | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi
index d31ce1b..493c498 100644
--- a/arch/arm/boot/dts/vf610.dtsi
+++ b/arch/arm/boot/dts/vf610.dtsi
@@ -140,6 +140,6 @@
reg = <0x40031000 0x1000>;
interrupts = <0 86 0x04>;
- clocks = <&clks VF610_CLK_SAI2>;
- clock-names = "sai";
+ clocks = <&clks VF610_CLK_SAI2>, <&clks VF610_CLK_SAI2>;
+ clock-names = "ipg", "sai";
status = "disabled";
};
--
1.8.4
^ permalink raw reply related
* [PATCH 0/2] Add ipg clock control to sai driver
From: Nicolin Chen @ 2014-04-01 11:52 UTC (permalink / raw)
To: broonie, shawn.guo
Cc: mark.rutland, devicetree, alsa-devel, pawel.moll, linux-doc,
ijc+devicetree, linux-kernel, robh+dt, timur, Li.Xiubo, rob,
galak, linuxppc-dev
This series of patches add ipg clock control to fsl_sai driver and updates
the vf610.dtsi accordingly.
@Shawn
I'm not sure if VF610 currently does full works with SAI audio function.
The PATCH-2 is based on broonie/for-next.
Nicolin Chen (2):
ASoC: fsl_sai: Add clock control for SAI
ARM: dts: Add ipg clock for sai2 on VF610 platform
.../devicetree/bindings/sound/fsl-sai.txt | 7 ++--
arch/arm/boot/dts/vf610.dtsi | 4 +--
sound/soc/fsl/fsl_sai.c | 37 ++++++++++++++++++++--
sound/soc/fsl/fsl_sai.h | 2 ++
4 files changed, 43 insertions(+), 7 deletions(-)
--
1.8.4
^ permalink raw reply
* [PATCH 1/2] ASoC: fsl_sai: Add clock control for SAI
From: Nicolin Chen @ 2014-04-01 11:52 UTC (permalink / raw)
To: broonie, shawn.guo
Cc: mark.rutland, devicetree, alsa-devel, pawel.moll, linux-doc,
ijc+devicetree, linux-kernel, robh+dt, timur, Li.Xiubo, rob,
galak, linuxppc-dev
In-Reply-To: <cover.1396352401.git.Guangyu.Chen@freescale.com>
The SAI mainly has two clocks:
ipg_clock -- registers access for SoC or DMA to read and write.
sai_clock -- providing DAI format bit clock and frame clock.
Thus this patch adds these two clocks to the driver with their clock
controls and replaces the regmap clock 'sai_clock' with 'ipg_clock'.
Signed-off-by: Nicolin Chen <Guangyu.Chen@freescale.com>
---
.../devicetree/bindings/sound/fsl-sai.txt | 7 ++--
sound/soc/fsl/fsl_sai.c | 37 ++++++++++++++++++++--
sound/soc/fsl/fsl_sai.h | 2 ++
3 files changed, 41 insertions(+), 5 deletions(-)
diff --git a/Documentation/devicetree/bindings/sound/fsl-sai.txt b/Documentation/devicetree/bindings/sound/fsl-sai.txt
index 35c09fe..bad4453 100644
--- a/Documentation/devicetree/bindings/sound/fsl-sai.txt
+++ b/Documentation/devicetree/bindings/sound/fsl-sai.txt
@@ -11,5 +11,6 @@ Required properties:
- reg: Offset and length of the register set for the device.
- clocks: Must contain an entry for each entry in clock-names.
-- clock-names : Must include the "sai" entry.
+- clock-names : Must include the "ipg" for register access and "sai" for bit
+ clock and frame clock providing.
- dmas : Generic dma devicetree binding as described in
Documentation/devicetree/bindings/dma/dma.txt.
@@ -31,6 +32,6 @@ sai2: sai@40031000 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sai2_1>;
- clocks = <&clks VF610_CLK_SAI2>;
- clock-names = "sai";
+ clocks = <&clks VF610_CLK_SAI2>, <&clks VF610_CLK_SAI2>;
+ clock-names = "ipg", "sai";
dma-names = "tx", "rx";
dmas = <&edma0 0 VF610_EDMA_MUXID0_SAI2_TX>,
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index 3847d2a..2d749df 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -428,5 +428,18 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream,
{
struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
- u32 reg;
+ struct device *dev = &sai->pdev->dev;
+ u32 reg, ret;
+
+ ret = clk_prepare_enable(sai->ipg_clk);
+ if (ret) {
+ dev_err(dev, "failed to prepare and enable ipg clock\n");
+ return ret;
+ }
+
+ ret = clk_prepare_enable(sai->sai_clk);
+ if (ret) {
+ dev_err(dev, "failed to prepare and enable sai clock\n");
+ goto err;
+ }
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -439,4 +452,9 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream,
return 0;
+
+err:
+ clk_disable_unprepare(sai->ipg_clk);
+
+ return ret;
}
@@ -454,4 +472,7 @@ static void fsl_sai_shutdown(struct snd_pcm_substream *substream,
regmap_update_bits(sai->regmap, reg, FSL_SAI_CR3_TRCE,
~FSL_SAI_CR3_TRCE);
+
+ clk_disable_unprepare(sai->sai_clk);
+ clk_disable_unprepare(sai->ipg_clk);
}
@@ -609,5 +630,5 @@ static int fsl_sai_probe(struct platform_device *pdev)
sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
- "sai", base, &fsl_sai_regmap_config);
+ "ipg", base, &fsl_sai_regmap_config);
if (IS_ERR(sai->regmap)) {
dev_err(&pdev->dev, "regmap init failed\n");
@@ -615,4 +636,16 @@ static int fsl_sai_probe(struct platform_device *pdev)
}
+ sai->ipg_clk = devm_clk_get(&pdev->dev, "ipg");
+ if (IS_ERR(sai->ipg_clk)) {
+ dev_err(&pdev->dev, "failed to get ipg clock\n");
+ return PTR_ERR(sai->ipg_clk);
+ }
+
+ sai->sai_clk = devm_clk_get(&pdev->dev, "sai");
+ if (IS_ERR(sai->sai_clk)) {
+ dev_err(&pdev->dev, "failed to get sai clock\n");
+ return PTR_ERR(sai->sai_clk);
+ }
+
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h
index 677670d..cbaf114 100644
--- a/sound/soc/fsl/fsl_sai.h
+++ b/sound/soc/fsl/fsl_sai.h
@@ -127,4 +127,6 @@ struct fsl_sai {
struct platform_device *pdev;
struct regmap *regmap;
+ struct clk *ipg_clk;
+ struct clk *sai_clk;
bool big_endian_regs;
--
1.8.4
^ permalink raw reply related
* [PATCH] ASoC: fsl_sai: Add imx6sx platform support
From: Nicolin Chen @ 2014-04-01 11:34 UTC (permalink / raw)
To: broonie
Cc: mark.rutland, devicetree, alsa-devel, pawel.moll, linux-doc,
ijc+devicetree, linux-kernel, robh+dt, timur, Li.Xiubo, rob,
galak, linuxppc-dev
The next coming i.MX6 Solo X SoC also contains SAI module while we use
imp_pcm_init() for i.MX platform.
So this patch adds one compatible route for imx6sx and updates the DT
doc accordingly.
Signed-off-by: Nicolin Chen <Guangyu.Chen@freescale.com>
---
Documentation/devicetree/bindings/sound/fsl-sai.txt | 2 +-
sound/soc/fsl/fsl_sai.c | 12 ++++++++++--
sound/soc/fsl/fsl_sai.h | 1 +
3 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/sound/fsl-sai.txt b/Documentation/devicetree/bindings/sound/fsl-sai.txt
index 98611a6..35c09fe 100644
--- a/Documentation/devicetree/bindings/sound/fsl-sai.txt
+++ b/Documentation/devicetree/bindings/sound/fsl-sai.txt
@@ -7,7 +7,7 @@ codec/DSP interfaces.
Required properties:
-- compatible: Compatible list, contains "fsl,vf610-sai".
+- compatible: Compatible list, contains "fsl,vf610-sai" or "fsl,imx6sx-sai".
- reg: Offset and length of the register set for the device.
- clocks: Must contain an entry for each entry in clock-names.
- clock-names : Must include the "sai" entry.
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index d64c33f..9ed6795 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -22,6 +22,7 @@
#include <sound/pcm_params.h>
#include "fsl_sai.h"
+#include "imx-pcm.h"
#define FSL_SAI_FLAGS (FSL_SAI_CSR_SEIE |\
FSL_SAI_CSR_FEIE)
@@ -592,6 +593,9 @@ static int fsl_sai_probe(struct platform_device *pdev)
sai->pdev = pdev;
+ if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx6sx-sai"))
+ sai->sai_on_imx = true;
+
sai->big_endian_regs = of_property_read_bool(np, "big-endian-regs");
if (sai->big_endian_regs)
fsl_sai_regmap_config.val_format_endian = REGMAP_ENDIAN_BIG;
@@ -634,12 +638,16 @@ static int fsl_sai_probe(struct platform_device *pdev)
if (ret)
return ret;
- return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL,
- SND_DMAENGINE_PCM_FLAG_NO_RESIDUE);
+ if (sai->sai_on_imx)
+ return imx_pcm_dma_init(pdev);
+ else
+ return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL,
+ SND_DMAENGINE_PCM_FLAG_NO_RESIDUE);
}
static const struct of_device_id fsl_sai_ids[] = {
{ .compatible = "fsl,vf610-sai", },
+ { .compatible = "fsl,imx6sx-sai", },
{ /* sentinel */ }
};
diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h
index be26d46..677670d 100644
--- a/sound/soc/fsl/fsl_sai.h
+++ b/sound/soc/fsl/fsl_sai.h
@@ -130,6 +130,7 @@ struct fsl_sai {
bool big_endian_regs;
bool big_endian_data;
bool is_dsp_mode;
+ bool sai_on_imx;
struct snd_dmaengine_dai_dma_data dma_params_rx;
struct snd_dmaengine_dai_dma_data dma_params_tx;
--
1.8.4
^ permalink raw reply related
* [RFC] powerpc, ptrace: Add few more ptrace request macros
From: Anshuman Khandual @ 2014-04-01 11:14 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel; +Cc: mikey, Anshuman Khandual
This patch adds few more ptrace request macros expanding
the existing capability. These ptrace requests macros can
be classified into two categories.
(1) Transactional memory
/* TM special purpose registers */
PTRACE_GETTM_SPRREGS
PTRACE_SETTM_SPRREGS
/* Checkpointed GPR registers */
PTRACE_GETTM_CGPRREGS
PTRACE_SETTM_CGPRREGS
/* Checkpointed FPR registers */
PTRACE_GETTM_CFPRREGS
PTRACE_SETTM_CFPRREGS
/* Checkpointed VMX registers */
PTRACE_GETTM_CVMXREGS
PTRACE_SETTM_CVMXREGS
(2) Miscellaneous
/* TAR, PPR, DSCR registers */
PTRACE_GETMSCREGS
PTRACE_SETMSCREGS
This patch also adds mutliple new generic ELF core note sections in
this regard which can be listed as follows.
NT_PPC_TM_SPR /* Transactional memory specific registers */
NT_PPC_TM_CGPR /* Transactional memory checkpointed GPR */
NT_PPC_TM_CFPR /* Transactional memory checkpointed FPR */
NT_PPC_TM_CVMX /* Transactional memory checkpointed VMX */
NT_PPC_MISC /* Miscellaneous registers */
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/switch_to.h | 8 +
arch/powerpc/include/uapi/asm/ptrace.h | 61 +++
arch/powerpc/kernel/process.c | 24 ++
arch/powerpc/kernel/ptrace.c | 658 +++++++++++++++++++++++++++++++--
include/uapi/linux/elf.h | 5 +
5 files changed, 729 insertions(+), 27 deletions(-)
diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h
index 0e83e7d..73e2601 100644
--- a/arch/powerpc/include/asm/switch_to.h
+++ b/arch/powerpc/include/asm/switch_to.h
@@ -80,6 +80,14 @@ static inline void flush_spe_to_thread(struct task_struct *t)
}
#endif
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+extern void flush_tmreg_to_thread(struct task_struct *);
+#else
+static inline void flush_tmreg_to_thread(struct task_struct *t)
+{
+}
+#endif
+
static inline void clear_task_ebb(struct task_struct *t)
{
#ifdef CONFIG_PPC_BOOK3S_64
diff --git a/arch/powerpc/include/uapi/asm/ptrace.h b/arch/powerpc/include/uapi/asm/ptrace.h
index 77d2ed3..fd962d6 100644
--- a/arch/powerpc/include/uapi/asm/ptrace.h
+++ b/arch/powerpc/include/uapi/asm/ptrace.h
@@ -190,6 +190,67 @@ struct pt_regs {
#define PPC_PTRACE_SETHWDEBUG 0x88
#define PPC_PTRACE_DELHWDEBUG 0x87
+/* Transactional memory registers */
+
+/*
+ * SPR
+ *
+ * struct data {
+ * u64 tm_tfhar;
+ * u64 tm_texasr;
+ * u64 tm_tfiar;
+ * unsigned long tm_orig_msr;
+ * u64 tm_tar;
+ * u64 tm_ppr;
+ * u64 tm_dscr;
+ * };
+ */
+#define PTRACE_GETTM_SPRREGS 0x70
+#define PTRACE_SETTM_SPRREGS 0x71
+
+/*
+ * Checkpointed GPR
+ *
+ * struct data {
+ * struct pt_regs ckpt_regs;
+ * };
+ */
+#define PTRACE_GETTM_CGPRREGS 0x72
+#define PTRACE_SETTM_CGPRREGS 0x73
+
+/*
+ * Checkpointed FPR
+ *
+ * struct data {
+ * u64 fpr[32];
+ * u64 fpscr;
+ * };
+ */
+#define PTRACE_GETTM_CFPRREGS 0x74
+#define PTRACE_SETTM_CFPRREGS 0x75
+
+/*
+ * Checkpointed VMX
+ *
+ * struct data {
+ * vector128 vr[32];
+ * vector128 vscr;
+ * unsigned long vrsave;
+ *};
+ */
+#define PTRACE_GETTM_CVMXREGS 0x76
+#define PTRACE_SETTM_CVMXREGS 0x77
+
+/* Miscellaneous registers */
+#define PTRACE_GETMSCREGS 0x78
+#define PTRACE_SETMSCREGS 0x79
+
+/*
+ * XXX: A note to application developers. The existing data layout
+ * of the above four ptrace requests can change when new registers
+ * are available for each category in forthcoming processors.
+ */
+
#ifndef __ASSEMBLY__
struct ppc_debug_info {
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index af064d2..e5dfd8e 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -673,6 +673,30 @@ static inline void __switch_to_tm(struct task_struct *prev)
}
}
+void flush_tmreg_to_thread(struct task_struct *tsk)
+{
+ /*
+ * If task is not current, it should have been flushed
+ * already to it's thread_struct during __switch_to().
+ */
+ if (tsk != current)
+ return;
+
+ preempt_disable();
+ if (tsk->thread.regs) {
+ /*
+ * If we are still current, the TM state need to
+ * be flushed to thread_struct as it will be still
+ * present in the current cpu
+ */
+ if (MSR_TM_ACTIVE(tsk->thread.regs->msr)) {
+ __switch_to_tm(tsk);
+ tm_recheckpoint_new_task(tsk);
+ }
+ }
+ preempt_enable();
+}
+
/*
* This is called if we are on the way out to userspace and the
* TIF_RESTORE_TM flag is set. It checks if we need to reload
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 2e3d2bf..cb4d5bf 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -357,6 +357,17 @@ static int gpr_set(struct task_struct *target, const struct user_regset *regset,
return ret;
}
+/*
+ * When any transaction is active, thread_struct->transact_fp holds
+ * the current running value of all FPR registers and thread_struct->
+ * fp_state hold the last checkpointed FPR state for the given
+ * transaction.
+ *
+ * struct data {
+ * u64 fpr[32];
+ * u64 fpscr;
+ * };
+ */
static int fpr_get(struct task_struct *target, const struct user_regset *regset,
unsigned int pos, unsigned int count,
void *kbuf, void __user *ubuf)
@@ -365,21 +376,41 @@ static int fpr_get(struct task_struct *target, const struct user_regset *regset,
u64 buf[33];
int i;
#endif
- flush_fp_to_thread(target);
+ if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
+ flush_fp_to_thread(target);
+ flush_altivec_to_thread(target);
+ flush_tmreg_to_thread(target);
+ } else {
+ flush_fp_to_thread(target);
+ }
#ifdef CONFIG_VSX
/* copy to local buffer then write that out */
- for (i = 0; i < 32 ; i++)
- buf[i] = target->thread.TS_FPR(i);
- buf[32] = target->thread.fp_state.fpscr;
+ if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
+ for (i = 0; i < 32 ; i++)
+ buf[i] = target->thread.TS_TRANS_FPR(i);
+ buf[32] = target->thread.transact_fp.fpscr;
+ } else {
+ for (i = 0; i < 32 ; i++)
+ buf[i] = target->thread.TS_FPR(i);
+ buf[32] = target->thread.fp_state.fpscr;
+ }
return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
#else
- BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
- offsetof(struct thread_fp_state, fpr[32][0]));
+ if (MSR_TM_ACTIVE(tsk->thread.regs->msr)) {
+ BUILD_BUG_ON(offsetof(struct transact_fp, fpscr) !=
+ offsetof(struct transact_fp, fpr[32][0]));
- return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.transact_fp, 0, -1);
+ } esle {
+ BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
+ offsetof(struct thread_fp_state, fpr[32][0]));
+
+ return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
&target->thread.fp_state, 0, -1);
+ }
#endif
}
@@ -391,23 +422,44 @@ static int fpr_set(struct task_struct *target, const struct user_regset *regset,
u64 buf[33];
int i;
#endif
- flush_fp_to_thread(target);
+ if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
+ flush_fp_to_thread(target);
+ flush_altivec_to_thread(target);
+ flush_tmreg_to_thread(target);
+ } else {
+ flush_fp_to_thread(target);
+ }
#ifdef CONFIG_VSX
/* copy to local buffer then write that out */
i = user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
if (i)
return i;
- for (i = 0; i < 32 ; i++)
- target->thread.TS_FPR(i) = buf[i];
- target->thread.fp_state.fpscr = buf[32];
+ for (i = 0; i < 32 ; i++) {
+ if (MSR_TM_ACTIVE(target->thread.regs->msr))
+ target->thread.TS_TRANS_FPR(i) = buf[i];
+ else
+ target->thread.TS_FPR(i) = buf[i];
+ }
+ if (MSR_TM_ACTIVE(target->thread.regs->msr))
+ target->thread.transact_fp.fpscr = buf[32];
+ else
+ target->thread.fp_state.fpscr = buf[32];
return 0;
#else
- BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
- offsetof(struct thread_fp_state, fpr[32][0]));
+ if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
+ BUILD_BUG_ON(offsetof(struct transact_fp, fpscr) !=
+ offsetof(struct transact_fp, fpr[32][0]));
- return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
- &target->thread.fp_state, 0, -1);
+ return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.transact_fp, 0, -1);
+ } else {
+ BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
+ offsetof(struct thread_fp_state, fpr[32][0]));
+
+ return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.fp_state, 0, -1);
+ }
#endif
}
@@ -432,20 +484,44 @@ static int vr_active(struct task_struct *target,
return target->thread.used_vr ? regset->n : 0;
}
+/*
+ * When any transaction is active, thread_struct->transact_vr holds
+ * the current running value of all VMX registers and thread_struct->
+ * vr_state hold the last checkpointed VMX state for the given
+ * transaction.
+ *
+ * struct data {
+ * vector128 vr[32];
+ * vector128 vscr;
+ * vector128 vrsave;
+ * };
+ */
static int vr_get(struct task_struct *target, const struct user_regset *regset,
unsigned int pos, unsigned int count,
void *kbuf, void __user *ubuf)
{
int ret;
+ struct thread_vr_state *addr;
- flush_altivec_to_thread(target);
+ if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
+ flush_fp_to_thread(target);
+ flush_altivec_to_thread(target);
+ flush_tmreg_to_thread(target);
+ } else {
+ flush_altivec_to_thread(target);
+ }
BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
offsetof(struct thread_vr_state, vr[32]));
+ if (MSR_TM_ACTIVE(target->thread.regs->msr))
+ addr = &target->thread.transact_vr;
+ else
+ addr = &target->thread.vr_state;
+
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- &target->thread.vr_state, 0,
- 33 * sizeof(vector128));
+ addr, 0, 33 * sizeof(vector128));
+
if (!ret) {
/*
* Copy out only the low-order word of vrsave.
@@ -455,11 +531,14 @@ static int vr_get(struct task_struct *target, const struct user_regset *regset,
u32 word;
} vrsave;
memset(&vrsave, 0, sizeof(vrsave));
- vrsave.word = target->thread.vrsave;
+ if (MSR_TM_ACTIVE(target->thread.regs->msr))
+ vrsave.word = target->thread.transact_vrsave;
+ else
+ vrsave.word = target->thread.vrsave;
+
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &vrsave,
33 * sizeof(vector128), -1);
}
-
return ret;
}
@@ -467,16 +546,27 @@ static int vr_set(struct task_struct *target, const struct user_regset *regset,
unsigned int pos, unsigned int count,
const void *kbuf, const void __user *ubuf)
{
+ struct thread_vr_state *addr;
int ret;
- flush_altivec_to_thread(target);
+ if (MSR_TM_ACTIVE(target->thread.regs->msr)) {
+ flush_fp_to_thread(target);
+ flush_altivec_to_thread(target);
+ flush_tmreg_to_thread(target);
+ } else {
+ flush_altivec_to_thread(target);
+ }
BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
offsetof(struct thread_vr_state, vr[32]));
+ if (MSR_TM_ACTIVE(target->thread.regs->msr))
+ addr = &target->thread.transact_vr;
+ else
+ addr = &target->thread.vr_state;
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
- &target->thread.vr_state, 0,
- 33 * sizeof(vector128));
+ addr, 0, 33 * sizeof(vector128));
+
if (!ret && count > 0) {
/*
* We use only the first word of vrsave.
@@ -486,13 +576,21 @@ static int vr_set(struct task_struct *target, const struct user_regset *regset,
u32 word;
} vrsave;
memset(&vrsave, 0, sizeof(vrsave));
- vrsave.word = target->thread.vrsave;
+
+ if (MSR_TM_ACTIVE(target->thread.regs->msr))
+ vrsave.word = target->thread.transact_vrsave;
+ else
+ vrsave.word = target->thread.vrsave;
+
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave,
33 * sizeof(vector128), -1);
- if (!ret)
- target->thread.vrsave = vrsave.word;
+ if (!ret) {
+ if (MSR_TM_ACTIVE(target->thread.regs->msr))
+ target->thread.transact_vrsave = vrsave.word;
+ else
+ target->thread.vrsave = vrsave.word;
+ }
}
-
return ret;
}
#endif /* CONFIG_ALTIVEC */
@@ -613,6 +711,417 @@ static int evr_set(struct task_struct *target, const struct user_regset *regset,
}
#endif /* CONFIG_SPE */
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+
+/*
+ * Transactional SPR
+ *
+ * struct {
+ * u64 tm_tfhar;
+ * u64 tm_texasr;
+ * u64 tm_tfiar;
+ * unsigned long tm_orig_msr;
+ * unsigned long tm_tar;
+ * unsigned long tm_ppr;
+ * unsigned long tm_dscr;
+ * };
+ */
+static int tm_spr_get(struct task_struct *target, const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
+{
+ int ret;
+
+ flush_fp_to_thread(target);
+ flush_altivec_to_thread(target);
+ flush_tmreg_to_thread(target);
+
+ /* TFHAR register */
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tm_tfhar, 0, sizeof(u64));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, tm_tfhar) +
+ sizeof(u64) != offsetof(struct thread_struct, tm_texasr));
+
+ /* TEXASR register */
+ if (!ret)
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tm_texasr, sizeof(u64), 2 * sizeof(u64));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, tm_texasr) +
+ sizeof(u64) != offsetof(struct thread_struct, tm_tfiar));
+
+ /* TFIAR register */
+ if (!ret)
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tm_tfiar, 2 * sizeof(u64), 3 * sizeof(u64));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, tm_tfiar) +
+ sizeof(u64) != offsetof(struct thread_struct, tm_orig_msr));
+
+ /* TM checkpointed original MSR */
+ if (!ret)
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tm_orig_msr, 3 * sizeof(u64),
+ 3 * sizeof(u64) + sizeof(unsigned long));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, tm_orig_msr) +
+ sizeof(unsigned long) + sizeof(struct pt_regs)
+ != offsetof(struct thread_struct, tm_tar));
+
+ /* TM checkpointed TAR register */
+ if (!ret)
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tm_tar, 3 * sizeof(u64) +
+ sizeof(unsigned long) , 3 * sizeof(u64) +
+ 2 * sizeof(unsigned long));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, tm_tar)
+ + sizeof(unsigned long) !=
+ offsetof(struct thread_struct, tm_ppr));
+
+ /* TM checkpointed PPR register */
+ if (!ret)
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tm_ppr, 3 * sizeof(u64) +
+ 2 * sizeof(unsigned long), 3 * sizeof(u64) +
+ 3 * sizeof(unsigned long));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, tm_ppr) +
+ sizeof(unsigned long) !=
+ offsetof(struct thread_struct, tm_dscr));
+
+ /* TM checkpointed DSCR register */
+ if (!ret)
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tm_dscr, 3 * sizeof(u64)
+ + 3 * sizeof(unsigned long), 3 * sizeof(u64)
+ + 4 * sizeof(unsigned long));
+ return ret;
+}
+
+static int tm_spr_set(struct task_struct *target, const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+ int ret;
+
+ flush_fp_to_thread(target);
+ flush_altivec_to_thread(target);
+ flush_tmreg_to_thread(target);
+
+ /* TFHAR register */
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tm_tfhar, 0, sizeof(u64));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, tm_tfhar)
+ + sizeof(u64) != offsetof(struct thread_struct, tm_texasr));
+
+ /* TEXASR register */
+ if (!ret)
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tm_texasr, sizeof(u64), 2 * sizeof(u64));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, tm_texasr)
+ + sizeof(u64) != offsetof(struct thread_struct, tm_tfiar));
+
+ /* TFIAR register */
+ if (!ret)
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tm_tfiar, 2 * sizeof(u64), 3 * sizeof(u64));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, tm_tfiar)
+ + sizeof(u64) != offsetof(struct thread_struct, tm_orig_msr));
+
+ /* TM checkpointed orig MSR */
+ if (!ret)
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tm_orig_msr, 3 * sizeof(u64),
+ 3 * sizeof(u64) + sizeof(unsigned long));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, tm_orig_msr)
+ + sizeof(unsigned long) + sizeof(struct pt_regs) !=
+ offsetof(struct thread_struct, tm_tar));
+
+ /* TM checkpointed TAR register */
+ if (!ret)
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tm_tar, 3 * sizeof(u64) +
+ sizeof(unsigned long), 3 * sizeof(u64) +
+ 2 * sizeof(unsigned long));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, tm_tar)
+ + sizeof(unsigned long) != offsetof(struct thread_struct, tm_ppr));
+
+ /* TM checkpointed PPR register */
+ if (!ret)
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tm_ppr, 3 * sizeof(u64)
+ + 2 * sizeof(unsigned long), 3 * sizeof(u64)
+ + 3 * sizeof(unsigned long));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, tm_ppr) +
+ sizeof(unsigned long) !=
+ offsetof(struct thread_struct, tm_dscr));
+
+ /* TM checkpointed DSCR register */
+ if (!ret)
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tm_dscr,
+ 3 * sizeof(u64) + 3 * sizeof(unsigned long),
+ 3 * sizeof(u64) + 4 * sizeof(unsigned long));
+
+ return ret;
+}
+
+/*
+ * Checkpointed GPR
+ *
+ * struct data {
+ * struct pt_regs ckpt_regs;
+ * };
+ */
+static int tm_cgpr_get(struct task_struct *target, const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
+{
+ int ret;
+
+ flush_fp_to_thread(target);
+ flush_altivec_to_thread(target);
+ flush_tmreg_to_thread(target);
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.ckpt_regs, 0,
+ sizeof(struct pt_regs));
+ return ret;
+}
+
+static int tm_cgpr_set(struct task_struct *target, const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+ int ret;
+
+ flush_fp_to_thread(target);
+ flush_altivec_to_thread(target);
+ flush_tmreg_to_thread(target);
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.ckpt_regs, 0,
+ sizeof(struct pt_regs));
+ return ret;
+}
+
+/*
+ * Checkpointed FPR
+ *
+ * struct data {
+ * u64 fpr[32];
+ * u64 fpscr;
+ * };
+ */
+static int tm_cfpr_get(struct task_struct *target, const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
+{
+#ifdef CONFIG_VSX
+ u64 buf[33];
+ int i;
+#endif
+ flush_fp_to_thread(target);
+ flush_altivec_to_thread(target);
+ flush_tmreg_to_thread(target);
+
+#ifdef CONFIG_VSX
+ /* copy to local buffer then write that out */
+ for (i = 0; i < 32 ; i++)
+ buf[i] = target->thread.TS_FPR(i);
+ buf[32] = target->thread.fp_state.fpscr;
+ return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
+
+#else
+ BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
+ offsetof(struct thread_fp_state, fpr[32][0]));
+
+ return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.thread_fp_state, 0, -1);
+#endif
+}
+
+static int tm_cfpr_set(struct task_struct *target, const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+#ifdef CONFIG_VSX
+ u64 buf[33];
+ int i;
+#endif
+ flush_fp_to_thread(target);
+ flush_altivec_to_thread(target);
+ flush_tmreg_to_thread(target);
+
+#ifdef CONFIG_VSX
+ /* copy to local buffer then write that out */
+ i = user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
+ if (i)
+ return i;
+ for (i = 0; i < 32 ; i++)
+ target->thread.TS_FPR(i) = buf[i];
+ target->thread.fp_state.fpscr = buf[32];
+ return 0;
+#else
+ BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
+ offsetof(struct thread_fp_state, fpr[32][0]));
+
+ return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.fp_state, 0, -1);
+#endif
+}
+
+/*
+ * Checkpointed VMX
+ *
+ * struct data {
+ * vector128 vr[32];
+ * vector128 vscr;
+ * vector128 vrsave;
+ *};
+ */
+static int tm_cvmx_get(struct task_struct *target, const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
+{
+ int ret;
+
+ flush_fp_to_thread(target);
+ flush_altivec_to_thread(target);
+ flush_tmreg_to_thread(target);
+
+ BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
+ offsetof(struct thread_vr_state, vr[32]));
+
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.vr_state, 0,
+ 33 * sizeof(vector128));
+ if (!ret) {
+ /*
+ * Copy out only the low-order word of vrsave.
+ */
+ union {
+ elf_vrreg_t reg;
+ u32 word;
+ } vrsave;
+ memset(&vrsave, 0, sizeof(vrsave));
+ vrsave.word = target->thread.vrsave;
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &vrsave,
+ 33 * sizeof(vector128), -1);
+ }
+ return ret;
+}
+
+static int tm_cvmx_set(struct task_struct *target, const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+ int ret;
+
+ flush_fp_to_thread(target);
+ flush_altivec_to_thread(target);
+ flush_tmreg_to_thread(target);
+
+ BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
+ offsetof(struct thread_vr_state, vr[32]));
+
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.vr_state, 0,
+ 33 * sizeof(vector128));
+ if (!ret && count > 0) {
+ /*
+ * We use only the first word of vrsave.
+ */
+ union {
+ elf_vrreg_t reg;
+ u32 word;
+ } vrsave;
+ memset(&vrsave, 0, sizeof(vrsave));
+ vrsave.word = target->thread.vrsave;
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave,
+ 33 * sizeof(vector128), -1);
+ if (!ret)
+ target->thread.vrsave = vrsave.word;
+ }
+ return ret;
+}
+#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
+
+/*
+ * Miscellaneous Registers
+ *
+ * struct {
+ * unsigned long dscr;
+ * unsigned long ppr;
+ * unsigned long tar;
+ * };
+ */
+static int misc_get(struct task_struct *target, const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
+{
+ int ret;
+
+ /* DSCR register */
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.dscr, 0,
+ sizeof(unsigned long));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, dscr) + sizeof(unsigned long) +
+ sizeof(unsigned long) != offsetof(struct thread_struct, ppr));
+
+ /* PPR register */
+ if (!ret)
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.ppr, sizeof(unsigned long),
+ 2 * sizeof(unsigned long));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, ppr) + sizeof(unsigned long)
+ != offsetof(struct thread_struct, tar));
+ /* TAR register */
+ if (!ret)
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tar, 2 * sizeof(unsigned long),
+ 3 * sizeof(unsigned long));
+ return ret;
+}
+
+static int misc_set(struct task_struct *target, const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+ int ret;
+
+ /* DSCR register */
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.dscr, 0,
+ sizeof(unsigned long));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, dscr) + sizeof(unsigned long) +
+ sizeof(unsigned long) != offsetof(struct thread_struct, ppr));
+
+ /* PPR register */
+ if (!ret)
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.ppr, sizeof(unsigned long),
+ 2 * sizeof(unsigned long));
+
+ BUILD_BUG_ON(offsetof(struct thread_struct, ppr) + sizeof(unsigned long)
+ != offsetof(struct thread_struct, tar));
+
+ /* TAR register */
+ if (!ret)
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.tar, 2 * sizeof(unsigned long),
+ 3 * sizeof(unsigned long));
+ return ret;
+}
/*
* These are our native regset flavors.
@@ -629,6 +1138,13 @@ enum powerpc_regset {
#ifdef CONFIG_SPE
REGSET_SPE,
#endif
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+ REGSET_TM_SPR, /* TM generic SPR */
+ REGSET_TM_CGPR, /* TM checkpointed GPR */
+ REGSET_TM_CFPR, /* TM checkpointed FPR */
+ REGSET_TM_CVMX, /* TM checkpointed VMX */
+#endif
+ REGSET_MISC /* Miscellaneous */
};
static const struct user_regset native_regsets[] = {
@@ -663,6 +1179,33 @@ static const struct user_regset native_regsets[] = {
.active = evr_active, .get = evr_get, .set = evr_set
},
#endif
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+ [REGSET_TM_SPR] = {
+ .core_note_type = NT_PPC_TM_SPR, .n = 7,
+ .size = sizeof(u64), .align = sizeof(u64),
+ .get = tm_spr_get, .set = tm_spr_set
+ },
+ [REGSET_TM_CGPR] = {
+ .core_note_type = NT_PPC_TM_CGPR, .n = 14,
+ .size = sizeof(u64), .align = sizeof(u64),
+ .get = tm_cgpr_get, .set = tm_cgpr_set
+ },
+ [REGSET_TM_CFPR] = {
+ .core_note_type = NT_PPC_TM_CFPR, .n = ELF_NFPREG,
+ .size = sizeof(double), .align = sizeof(double),
+ .get = tm_cfpr_get, .set = tm_cfpr_set
+ },
+ [REGSET_TM_CVMX] = {
+ .core_note_type = NT_PPC_TM_CVMX, .n = 34,
+ .size = sizeof(vector128), .align = sizeof(vector128),
+ .get = tm_cvmx_get, .set = tm_cvmx_set
+ },
+#endif
+ [REGSET_MISC] = {
+ .core_note_type = NT_PPC_MISC, .n = 3,
+ .size = sizeof(u64), .align = sizeof(u64),
+ .get = misc_get, .set = misc_set
+ },
};
static const struct user_regset_view user_ppc_native_view = {
@@ -831,6 +1374,33 @@ static const struct user_regset compat_regsets[] = {
.active = evr_active, .get = evr_get, .set = evr_set
},
#endif
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+ [REGSET_TM_SPR] = {
+ .core_note_type = NT_PPC_TM_SPR, .n = 7,
+ .size = sizeof(u64), .align = sizeof(u64),
+ .get = tm_spr_get, .set = tm_spr_set
+ },
+ [REGSET_TM_CGPR] = {
+ .core_note_type = NT_PPC_TM_CGPR, .n = 14,
+ .size = sizeof(u64), .align = sizeof(u64),
+ .get = tm_cgpr_get, .set = tm_cgpr_set
+ },
+ [REGSET_TM_CFPR] = {
+ .core_note_type = NT_PPC_TM_CFPR, .n = ELF_NFPREG,
+ .size = sizeof(double), .align = sizeof(double),
+ .get = tm_cfpr_get, .set = tm_cfpr_set
+ },
+ [REGSET_TM_CVMX] = {
+ .core_note_type = NT_PPC_TM_CVMX, .n = 34,
+ .size = sizeof(vector128), .align = sizeof(vector128),
+ .get = tm_cvmx_get, .set = tm_cvmx_set
+ },
+#endif
+ [REGSET_MISC] = {
+ .core_note_type = NT_PPC_MISC, .n = 3,
+ .size = sizeof(u64), .align = sizeof(u64),
+ .get = misc_get, .set = misc_set
+ },
};
static const struct user_regset_view user_ppc_compat_view = {
@@ -1754,7 +2324,41 @@ long arch_ptrace(struct task_struct *child, long request,
REGSET_SPE, 0, 35 * sizeof(u32),
datavp);
#endif
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+ case PTRACE_GETTM_SPRREGS:
+ return copy_regset_to_user(child, &user_ppc_native_view,
+ REGSET_TM_SPR, 0, 6 * sizeof(u64) + sizeof(unsigned long), datavp);
+ case PTRACE_SETTM_SPRREGS:
+ return copy_regset_from_user(child, &user_ppc_native_view,
+ REGSET_TM_SPR, 0, 6 * sizeof(u64) + sizeof(unsigned long), datavp);
+ case PTRACE_GETTM_CGPRREGS:
+ return copy_regset_to_user(child, &user_ppc_native_view,
+ REGSET_TM_CGPR, 0, sizeof(struct pt_regs), datavp);
+ case PTRACE_SETTM_CGPRREGS:
+ return copy_regset_from_user(child, &user_ppc_native_view,
+ REGSET_TM_CGPR, 0, sizeof(struct pt_regs), datavp);
+ case PTRACE_GETTM_CFPRREGS:
+ return copy_regset_to_user(child, &user_ppc_native_view,
+ REGSET_TM_CFPR, 0, sizeof(elf_fpregset_t), datavp);
+ case PTRACE_SETTM_CFPRREGS:
+ return copy_regset_from_user(child, &user_ppc_native_view,
+ REGSET_TM_CFPR, 0, sizeof(elf_fpregset_t), datavp);
+ case PTRACE_GETTM_CVMXREGS:
+ return copy_regset_to_user(child, &user_ppc_native_view,
+ REGSET_TM_CVMX, 0, (33 * sizeof(vector128) + sizeof(u32)), datavp);
+ case PTRACE_SETTM_CVMXREGS:
+ return copy_regset_from_user(child, &user_ppc_native_view,
+ REGSET_TM_CVMX, 0, (33 * sizeof(vector128) + sizeof(u32)), datavp);
+#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
+ case PTRACE_GETMSCREGS:
+ return copy_regset_to_user(child, &user_ppc_native_view,
+ REGSET_MISC, 0, 3 * sizeof(u64),
+ datavp);
+ case PTRACE_SETMSCREGS:
+ return copy_regset_from_user(child, &user_ppc_native_view,
+ REGSET_MISC, 0, 3 * sizeof(u64),
+ datavp);
default:
ret = ptrace_request(child, request, addr, data);
break;
diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h
index ef6103b..13090e3 100644
--- a/include/uapi/linux/elf.h
+++ b/include/uapi/linux/elf.h
@@ -379,6 +379,11 @@ typedef struct elf64_shdr {
#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */
#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */
#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */
+#define NT_PPC_TM_SPR 0x103 /* PowerPC transactional memory specific registers */
+#define NT_PPC_TM_CGPR 0x104 /* PowerpC transactional memory checkpointed GPR */
+#define NT_PPC_TM_CFPR 0x105 /* PowerPC transactional memory checkpointed FPR */
+#define NT_PPC_TM_CVMX 0x106 /* PowerPC transactional memory checkpointed VMX */
+#define NT_PPC_MISC 0x107 /* PowerPC miscellaneous registers */
#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */
#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */
#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */
--
1.7.11.7
^ permalink raw reply related
* Re: [PATCH bisect 0/2] ASoC: fsl_sai: Overwrite trigger()
From: Nicolin Chen @ 2014-04-01 10:54 UTC (permalink / raw)
To: Mark Brown; +Cc: alsa-devel, Li.Xiubo, linuxppc-dev, linux-kernel, timur
In-Reply-To: <20140401110412.GJ2269@sirena.org.uk>
On Tue, Apr 01, 2014 at 12:04:12PM +0100, Mark Brown wrote:
> On Tue, Apr 01, 2014 at 11:17:05AM +0800, Nicolin Chen wrote:
>
> > * The patches are generated by using '-U2' because the default '-U3'
> > would conflict the baseline without fsl_sai_isr patches.
>
> What are these "fsi_sai_isr patches"?
Ah..I should have mentioned the full patch name:
e2681a1 ASoC: fsl_sai: Add isr to deal with error flag
The patch conflicts against that asoc-3.15-4 tag at the fsl_sai.h because
this isr patch added some new macros to it.
Thank you,
Nicolin Chen
^ permalink raw reply
* Re: [PATCH bisect 0/2] ASoC: fsl_sai: Overwrite trigger()
From: Mark Brown @ 2014-04-01 11:04 UTC (permalink / raw)
To: Nicolin Chen; +Cc: alsa-devel, Li.Xiubo, linuxppc-dev, linux-kernel, timur
In-Reply-To: <1396322227-482-1-git-send-email-Guangyu.Chen@freescale.com>
[-- Attachment #1: Type: text/plain, Size: 234 bytes --]
On Tue, Apr 01, 2014 at 11:17:05AM +0800, Nicolin Chen wrote:
> * The patches are generated by using '-U2' because the default '-U3'
> would conflict the baseline without fsl_sai_isr patches.
What are these "fsi_sai_isr patches"?
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [RFC PATCH] powerpc/le: enable RTAS events support
From: Geert Uytterhoeven @ 2014-04-01 10:26 UTC (permalink / raw)
To: Nathan Fontenot
Cc: linux-kernel@vger.kernel.org, Paul Mackerras, Anton Blanchard,
linuxppc-dev@lists.ozlabs.org, Greg Kurz
In-Reply-To: <53398379.8000203@linux.vnet.ibm.com>
On Mon, Mar 31, 2014 at 5:02 PM, Nathan Fontenot
<nfont@linux.vnet.ibm.com> wrote:
> struct rtas_error_log {
> - unsigned long version:8; /* Architectural version */
> - unsigned long severity:3; /* Severity level of error */
> - unsigned long disposition:2; /* Degree of recovery */
> - unsigned long extended:1; /* extended log present? */
> - unsigned long /* reserved */ :2; /* Reserved for future use */
> - unsigned long initiator:4; /* Initiator of event */
> - unsigned long target:4; /* Target of failed operation */
> - unsigned long type:8; /* General event or error*/
> - unsigned long extended_log_length:32; /* length in bytes */
> - unsigned char buffer[1]; /* Start of extended log */
> + /* Byte 0 */
> + uint8_t version; /* Architectural version */
> +
> + /* Byte 1 */
> + uint8_t severity;
> + /* XXXXXXXX
> + * XXX 3: Severity level of error
> + * XX 2: Degree of recovery
> + * X 1: Extended log present?
> + * XX 2: Reserved
> + */
> +
> + /* Byte 2 */
> + uint8_t :8;
> + /* XXXXXXXX
> + * XXXX 4: Initiator of event
> + * XXXX 4: Target of failed operation
> + */
> + uint8_t type; /* General event or error*/
> + uint32_t extended_log_length; /* length in bytes */
Now the bitfields are gone, things like the above can become __be32,
so we get extra type checking from sparse ("make C=1").
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH REPOST v5 1/3] powernv, cpufreq: Select CPUFreq related Kconfig options for powernv
From: Benjamin Herrenschmidt @ 2014-04-01 9:46 UTC (permalink / raw)
To: Gautham R. Shenoy
Cc: Linux PM list, Viresh Kumar, rjw, linux-kernel, cpufreq,
linuxppc-dev, Anton Blanchard, srivatsa.bhat
In-Reply-To: <1396336408-20954-3-git-send-email-ego@linux.vnet.ibm.com>
On Tue, 2014-04-01 at 12:43 +0530, Gautham R. Shenoy wrote:
> From: "Gautham R. Shenoy" <ego@linux.vnet.ibm.com>
>
> Enable CPUFreq for PowerNV. Select "performance", "powersave",
> "userspace" and "ondemand" governors. Choose "ondemand" to be the
> default governor.
Rafael, are you going to take these or should I send them to Linus ?
(I'd rather you take them :-)
Cheers,
Ben.
>
> Signed-off-by: Gautham R. Shenoy <ego@linux.vnet.ibm.com>
> Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
> ---
> arch/powerpc/configs/pseries_defconfig | 1 +
> arch/powerpc/configs/pseries_le_defconfig | 1 +
> arch/powerpc/platforms/powernv/Kconfig | 6 ++++++
> 3 files changed, 8 insertions(+)
>
> diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig
> index 9ea8342b..a905063 100644
> --- a/arch/powerpc/configs/pseries_defconfig
> +++ b/arch/powerpc/configs/pseries_defconfig
> @@ -306,3 +306,4 @@ CONFIG_KVM_BOOK3S_64=m
> CONFIG_KVM_BOOK3S_64_HV=y
> CONFIG_TRANSPARENT_HUGEPAGE=y
> CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
> +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
> diff --git a/arch/powerpc/configs/pseries_le_defconfig b/arch/powerpc/configs/pseries_le_defconfig
> index 3c84f9d..58e3dbf 100644
> --- a/arch/powerpc/configs/pseries_le_defconfig
> +++ b/arch/powerpc/configs/pseries_le_defconfig
> @@ -301,3 +301,4 @@ CONFIG_CRYPTO_LZO=m
> # CONFIG_CRYPTO_ANSI_CPRNG is not set
> CONFIG_CRYPTO_DEV_NX=y
> CONFIG_CRYPTO_DEV_NX_ENCRYPT=m
> +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
> diff --git a/arch/powerpc/platforms/powernv/Kconfig b/arch/powerpc/platforms/powernv/Kconfig
> index 895e8a2..c252ee9 100644
> --- a/arch/powerpc/platforms/powernv/Kconfig
> +++ b/arch/powerpc/platforms/powernv/Kconfig
> @@ -11,6 +11,12 @@ config PPC_POWERNV
> select PPC_UDBG_16550
> select PPC_SCOM
> select ARCH_RANDOM
> + select CPU_FREQ
> + select CPU_FREQ_GOV_PERFORMANCE
> + select CPU_FREQ_GOV_POWERSAVE
> + select CPU_FREQ_GOV_USERSPACE
> + select CPU_FREQ_GOV_ONDEMAND
> + select CPU_FREQ_GOV_CONSERVATIVE
> default y
>
> config PPC_POWERNV_RTAS
^ permalink raw reply
* [PATCH v2] spi: add "spi-lsb-first" to devicetree
From: Zhao Qiang @ 2014-04-01 9:10 UTC (permalink / raw)
To: linuxppc-dev, broonie, devicetree, linux-spi, B07421
Cc: Zhao Qiang, baruch, R63061, wangyuhang2014
add optional property devicetree for SPI slave nodes
into devicetree so that LSB mode can be enabled by devicetree.
Signed-off-by: Zhao Qiang <B45475@freescale.com>
---
changs for v2:
- remove duplicate "spi-rx-bus-width"
Documentation/devicetree/bindings/spi/spi-bus.txt | 2 ++
drivers/spi/spi.c | 2 ++
2 files changed, 4 insertions(+)
diff --git a/Documentation/devicetree/bindings/spi/spi-bus.txt b/Documentation/devicetree/bindings/spi/spi-bus.txt
index e5a4d1b..22d5740 100644
--- a/Documentation/devicetree/bindings/spi/spi-bus.txt
+++ b/Documentation/devicetree/bindings/spi/spi-bus.txt
@@ -55,6 +55,8 @@ contain the following properties.
chip select active high
- spi-3wire - (optional) Empty property indicating device requires
3-wire mode.
+- spi-lsb-first - (optional) Empty property indicating device requires
+ LSB first mode.
- spi-tx-bus-width - (optional) The bus width(number of data wires) that
used for MOSI. Defaults to 1 if not present.
- spi-rx-bus-width - (optional) The bus width(number of data wires) that
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 23756b0..0a20a90 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1050,6 +1050,8 @@ static void of_register_spi_devices(struct spi_master *master)
spi->mode |= SPI_CS_HIGH;
if (of_find_property(nc, "spi-3wire", NULL))
spi->mode |= SPI_3WIRE;
+ if (of_find_property(nc, "spi-lsb-first", NULL))
+ spi->mode |= SPI_LSB_FIRST;
/* Device DUAL/QUAD mode */
if (!of_property_read_u32(nc, "spi-tx-bus-width", &value)) {
--
1.8.5
^ permalink raw reply related
* Re: [PATCH] spi: add "spi-lsb-first" to devicetree
From: Baruch Siach @ 2014-04-01 8:42 UTC (permalink / raw)
To: Zhao Qiang
Cc: B07421, devicetree, linux-spi, broonie, R63061, linuxppc-dev,
wangyuhang2014
In-Reply-To: <1396338931-10887-1-git-send-email-B45475@freescale.com>
Hi Zhao Qiang,
On Tue, Apr 01, 2014 at 03:55:31PM +0800, Zhao Qiang wrote:
> add optional property devicetree for SPI slave nodes
> into devicetree so that LSB mode can be enabled by devicetree.
>
> Signed-off-by: Zhao Qiang <B45475@freescale.com>
> ---
> Documentation/devicetree/bindings/spi/spi-bus.txt | 4 ++++
> drivers/spi/spi.c | 2 ++
> 2 files changed, 6 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/spi/spi-bus.txt b/Documentation/devicetree/bindings/spi/spi-bus.txt
> index e5a4d1b..fdd9f15 100644
> --- a/Documentation/devicetree/bindings/spi/spi-bus.txt
> +++ b/Documentation/devicetree/bindings/spi/spi-bus.txt
> @@ -55,11 +55,15 @@ contain the following properties.
> chip select active high
> - spi-3wire - (optional) Empty property indicating device requires
> 3-wire mode.
> +- spi-lsb-first - (optional) Empty property indicating device requires
> + LSB first mode.
> - spi-tx-bus-width - (optional) The bus width(number of data wires) that
> used for MOSI. Defaults to 1 if not present.
> - spi-rx-bus-width - (optional) The bus width(number of data wires) that
> used for MISO. Defaults to 1 if not present.
>
> +- spi-rx-bus-width - (optional) The bus width(number of data wires) that
> + used for MISO. Defaults to 1 if not present.
Is this part intentionally here? It is not mentioned in the commit log, and
seems to merit a separate patch.
baruch
> Some SPI controllers and devices support Dual and Quad SPI transfer mode.
> It allows data in SPI system transfered in 2 wires(DUAL) or 4 wires(QUAD).
> Now the value that spi-tx-bus-width and spi-rx-bus-width can receive is
> diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
> index 23756b0..0a20a90 100644
> --- a/drivers/spi/spi.c
> +++ b/drivers/spi/spi.c
> @@ -1050,6 +1050,8 @@ static void of_register_spi_devices(struct spi_master *master)
> spi->mode |= SPI_CS_HIGH;
> if (of_find_property(nc, "spi-3wire", NULL))
> spi->mode |= SPI_3WIRE;
> + if (of_find_property(nc, "spi-lsb-first", NULL))
> + spi->mode |= SPI_LSB_FIRST;
>
> /* Device DUAL/QUAD mode */
> if (!of_property_read_u32(nc, "spi-tx-bus-width", &value)) {
--
http://baruch.siach.name/blog/ ~. .~ Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
- baruch@tkos.co.il - tel: +972.2.679.5364, http://www.tkos.co.il -
^ permalink raw reply
* [PATCH] cpuidle: add freescale e500 family porcessors idle support
From: Dongsheng Wang @ 2014-04-01 8:33 UTC (permalink / raw)
To: daniel.lezcano, scottwood
Cc: chenhui.zhao, linux-pm, Wang Dongsheng, rjw, jason.jin,
linuxppc-dev
From: Wang Dongsheng <dongsheng.wang@freescale.com>
Add cpuidle support for e500 family, using cpuidle framework to
manage various low power modes. The new implementation will remain
compatible with original idle method.
I have done test about power consumption and latency. Cpuidle framework
will make CPU response time faster than original method, but power
consumption is higher than original method.
Power consumption:
The original method, power consumption is 10.51202 (W).
The cpuidle framework, power consumption is 10.5311 (W).
Latency:
The original method, avg latency is 6782 (us).
The cpuidle framework, avg latency is 6482 (us).
Initially, this supports PW10, PW20 and subsequent patches will support
DOZE/NAP and PH10, PH20.
Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index 5b6c03f..9301420 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -294,6 +294,15 @@ extern void power7_idle(void);
extern void ppc6xx_idle(void);
extern void book3e_idle(void);
+static inline void cpuidle_wait(void)
+{
+#ifdef CONFIG_PPC64
+ book3e_idle();
+#else
+ e500_idle();
+#endif
+}
+
/*
* ppc_md contains a copy of the machine description structure for the
* current platform. machine_id contains the initial address where the
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index 97e1dc9..edd193f 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -190,6 +190,9 @@ static ssize_t show_pw20_wait_time(struct device *dev,
return sprintf(buf, "%llu\n", time > 0 ? time : 0);
}
+#ifdef CONFIG_CPU_IDLE_E500
+u32 cpuidle_entry_bit;
+#endif
static void set_pw20_wait_entry_bit(void *val)
{
u32 *value = val;
@@ -204,7 +207,11 @@ static void set_pw20_wait_entry_bit(void *val)
/* set count */
pw20_idle |= ((MAX_BIT - *value) << PWRMGTCR0_PW20_ENT_SHIFT);
+#ifdef CONFIG_CPU_IDLE_E500
+ cpuidle_entry_bit = *value;
+#else
mtspr(SPRN_PWRMGTCR0, pw20_idle);
+#endif
}
static ssize_t store_pw20_wait_time(struct device *dev,
diff --git a/drivers/cpuidle/Kconfig.powerpc b/drivers/cpuidle/Kconfig.powerpc
index 66c3a09..0949dbf 100644
--- a/drivers/cpuidle/Kconfig.powerpc
+++ b/drivers/cpuidle/Kconfig.powerpc
@@ -18,3 +18,10 @@ config POWERNV_CPUIDLE
help
Select this option to enable processor idle state management
through cpuidle subsystem.
+
+config CPU_IDLE_E500
+ bool "CPU Idle Driver for E500 family processors"
+ depends on CPU_IDLE
+ depends on FSL_SOC_BOOKE
+ help
+ Select this to enable cpuidle on e500 family processors.
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
index f71ae1b..7e6adea 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
@@ -18,3 +18,4 @@ obj-$(CONFIG_ARM_AT91_CPUIDLE) += cpuidle-at91.o
# POWERPC drivers
obj-$(CONFIG_PSERIES_CPUIDLE) += cpuidle-pseries.o
obj-$(CONFIG_POWERNV_CPUIDLE) += cpuidle-powernv.o
+obj-$(CONFIG_CPU_IDLE_E500) += cpuidle-e500.o
diff --git a/drivers/cpuidle/cpuidle-e500.c b/drivers/cpuidle/cpuidle-e500.c
new file mode 100644
index 0000000..ddc0def
--- /dev/null
+++ b/drivers/cpuidle/cpuidle-e500.c
@@ -0,0 +1,194 @@
+/*
+ * CPU Idle driver for Freescale PowerPC e500 family processors.
+ *
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ *
+ * Author: Dongsheng Wang <dongsheng.wang@freescale.com>
+ *
+ * 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.
+ */
+
+#include <linux/cpu.h>
+#include <linux/cpuidle.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/notifier.h>
+
+#include <asm/cputable.h>
+#include <asm/machdep.h>
+#include <asm/mpc85xx.h>
+
+static unsigned int max_idle_state;
+static struct cpuidle_state *cpuidle_state_table;
+
+struct cpuidle_driver e500_idle_driver = {
+ .name = "e500_idle",
+ .owner = THIS_MODULE,
+};
+
+static void e500_cpuidle(void)
+{
+ if (cpuidle_idle_call())
+ cpuidle_wait();
+}
+
+static int pw10_enter(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index)
+{
+ cpuidle_wait();
+ return index;
+}
+
+#define MAX_BIT 63
+#define MIN_BIT 1
+extern u32 cpuidle_entry_bit;
+static int pw20_enter(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index)
+{
+ u32 pw20_idle;
+ u32 entry_bit;
+ pw20_idle = mfspr(SPRN_PWRMGTCR0);
+ if ((pw20_idle & PWRMGTCR0_PW20_ENT) != PWRMGTCR0_PW20_ENT) {
+ pw20_idle &= ~PWRMGTCR0_PW20_ENT;
+ entry_bit = MAX_BIT - cpuidle_entry_bit;
+ pw20_idle |= (entry_bit << PWRMGTCR0_PW20_ENT_SHIFT);
+ mtspr(SPRN_PWRMGTCR0, pw20_idle);
+ }
+
+ cpuidle_wait();
+
+ pw20_idle &= ~PWRMGTCR0_PW20_ENT;
+ pw20_idle |= (MIN_BIT << PWRMGTCR0_PW20_ENT_SHIFT);
+ mtspr(SPRN_PWRMGTCR0, pw20_idle);
+
+ return index;
+}
+
+static struct cpuidle_state pw_idle_states[] = {
+ {
+ .name = "pw10",
+ .desc = "pw10",
+ .flags = CPUIDLE_FLAG_TIME_VALID,
+ .exit_latency = 0,
+ .target_residency = 0,
+ .enter = &pw10_enter
+ },
+
+ {
+ .name = "pw20",
+ .desc = "pw20-core-idle",
+ .flags = CPUIDLE_FLAG_TIME_VALID,
+ .exit_latency = 1,
+ .target_residency = 50,
+ .enter = &pw20_enter
+ },
+};
+
+static int cpu_hotplug_notify(struct notifier_block *n,
+ unsigned long action, void *hcpu)
+{
+ unsigned long hotcpu = (unsigned long)hcpu;
+ struct cpuidle_device *dev =
+ per_cpu_ptr(cpuidle_devices, hotcpu);
+
+ if (dev && cpuidle_get_driver()) {
+ switch (action) {
+ case CPU_ONLINE:
+ case CPU_ONLINE_FROZEN:
+ cpuidle_pause_and_lock();
+ cpuidle_enable_device(dev);
+ cpuidle_resume_and_unlock();
+ break;
+
+ case CPU_DEAD:
+ case CPU_DEAD_FROZEN:
+ cpuidle_pause_and_lock();
+ cpuidle_disable_device(dev);
+ cpuidle_resume_and_unlock();
+ break;
+
+ default:
+ return NOTIFY_DONE;
+ }
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block cpu_hotplug_notifier = {
+ .notifier_call = cpu_hotplug_notify,
+};
+
+static void e500_cpuidle_driver_init(void)
+{
+ int idle_state;
+ struct cpuidle_driver *drv = &e500_idle_driver;
+
+ drv->state_count = 0;
+
+ for (idle_state = 0; idle_state < max_idle_state; ++idle_state) {
+ if (!cpuidle_state_table[idle_state].enter)
+ break;
+
+ drv->states[drv->state_count] = cpuidle_state_table[idle_state];
+ drv->state_count++;
+ }
+}
+
+static int e500_idle_state_probe(void)
+{
+ if (cpuidle_disable != IDLE_NO_OVERRIDE)
+ return -ENODEV;
+
+ cpuidle_state_table = pw_idle_states;
+ max_idle_state = ARRAY_SIZE(pw_idle_states);
+
+ /* Disable PW20 feature for e500mc, e5500 */
+ if (PVR_VER(cur_cpu_spec->pvr_value) != PVR_VER_E6500)
+ cpuidle_state_table[1].enter = NULL;
+
+ if (!cpuidle_state_table || !max_idle_state)
+ return -ENODEV;
+
+ return 0;
+}
+
+static void replace_orig_idle(void *dummy)
+{
+ return;
+}
+
+static int __init e500_idle_init(void)
+{
+ struct cpuidle_driver *drv = &e500_idle_driver;
+ int err;
+
+ if (e500_idle_state_probe())
+ return -ENODEV;
+
+ e500_cpuidle_driver_init();
+ if (!drv->state_count)
+ return -ENODEV;
+
+ err = cpuidle_register(drv, NULL);
+ if (err) {
+ pr_err("Register e500 family cpuidle driver failed.\n");
+
+ return err;
+ }
+
+ err = register_cpu_notifier(&cpu_hotplug_notifier);
+ if (err)
+ pr_warn("Cpuidle driver: register cpu notifier failed.\n");
+
+ /* Replace the original way of idle after cpuidle registered. */
+ ppc_md.power_save = e500_cpuidle;
+ on_each_cpu(replace_orig_idle, NULL, 1);
+
+ pr_info("e500_idle_driver registered.\n");
+
+ return 0;
+}
+late_initcall(e500_idle_init);
--
1.8.5
^ permalink raw reply related
* Re: Build regressions/improvements in v3.14
From: Geert Uytterhoeven @ 2014-04-01 8:01 UTC (permalink / raw)
To: linux-kernel@vger.kernel.org
Cc: the arch/x86 maintainers, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <1396339078-22125-1-git-send-email-geert@linux-m68k.org>
On Tue, Apr 1, 2014 at 9:57 AM, Geert Uytterhoeven <geert@linux-m68k.org> wrote:
> JFYI, when comparing v3.14[1] to v3.14-rc8[3], the summaries are:
> - build errors: +2/-10
+ error: No rule to make target include/config/auto.conf: => N/A
powerpc-randconfig
+ error: initramfs.c: undefined reference to `__stack_chk_guard':
=> .init.text+0x1067)
x86_64-randconfig
> [1] http://kisskb.ellerman.id.au/kisskb/head/7320/ (all 119 configs)
> [3] http://kisskb.ellerman.id.au/kisskb/head/7303/ (all 119 configs)
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torval
^ permalink raw reply
* [PATCH] spi: add "spi-lsb-first" to devicetree
From: Zhao Qiang @ 2014-04-01 7:55 UTC (permalink / raw)
To: linuxppc-dev, broonie, devicetree, linux-spi, B07421
Cc: Zhao Qiang, baruch, R63061, wangyuhang2014
add optional property devicetree for SPI slave nodes
into devicetree so that LSB mode can be enabled by devicetree.
Signed-off-by: Zhao Qiang <B45475@freescale.com>
---
Documentation/devicetree/bindings/spi/spi-bus.txt | 4 ++++
drivers/spi/spi.c | 2 ++
2 files changed, 6 insertions(+)
diff --git a/Documentation/devicetree/bindings/spi/spi-bus.txt b/Documentation/devicetree/bindings/spi/spi-bus.txt
index e5a4d1b..fdd9f15 100644
--- a/Documentation/devicetree/bindings/spi/spi-bus.txt
+++ b/Documentation/devicetree/bindings/spi/spi-bus.txt
@@ -55,11 +55,15 @@ contain the following properties.
chip select active high
- spi-3wire - (optional) Empty property indicating device requires
3-wire mode.
+- spi-lsb-first - (optional) Empty property indicating device requires
+ LSB first mode.
- spi-tx-bus-width - (optional) The bus width(number of data wires) that
used for MOSI. Defaults to 1 if not present.
- spi-rx-bus-width - (optional) The bus width(number of data wires) that
used for MISO. Defaults to 1 if not present.
+- spi-rx-bus-width - (optional) The bus width(number of data wires) that
+ used for MISO. Defaults to 1 if not present.
Some SPI controllers and devices support Dual and Quad SPI transfer mode.
It allows data in SPI system transfered in 2 wires(DUAL) or 4 wires(QUAD).
Now the value that spi-tx-bus-width and spi-rx-bus-width can receive is
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 23756b0..0a20a90 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1050,6 +1050,8 @@ static void of_register_spi_devices(struct spi_master *master)
spi->mode |= SPI_CS_HIGH;
if (of_find_property(nc, "spi-3wire", NULL))
spi->mode |= SPI_3WIRE;
+ if (of_find_property(nc, "spi-lsb-first", NULL))
+ spi->mode |= SPI_LSB_FIRST;
/* Device DUAL/QUAD mode */
if (!of_property_read_u32(nc, "spi-tx-bus-width", &value)) {
--
1.8.5
^ permalink raw reply related
* [PATCH 1/2] bootmem/powerpc: Unify bootmem initialization
From: Emil Medve @ 2014-04-01 7:21 UTC (permalink / raw)
To: benh, paulus, linuxppc-dev; +Cc: Emil Medve
Unify the low/highmem code path from do_init_bootmem() by using (the)
lowmem related variables/parameters even when the low/highmem split
is not needed (64-bit) or configured. In such cases the "lowmem"
variables/parameters continue to observe the definition by referring
to memory directly mapped by the kernel
Signed-off-by: Emil Medve <Emilian.Medve@Freescale.com>
---
arch/powerpc/mm/mem.c | 36 ++++++++++++++++--------------------
1 file changed, 16 insertions(+), 20 deletions(-)
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 32202c9..eaf5d1d8 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -188,27 +188,31 @@ EXPORT_SYMBOL_GPL(walk_system_ram_range);
void __init do_init_bootmem(void)
{
unsigned long start, bootmap_pages;
- unsigned long total_pages;
struct memblock_region *reg;
int boot_mapsize;
+ phys_addr_t _total_lowmem;
+ phys_addr_t _lowmem_end_addr;
- max_low_pfn = max_pfn = memblock_end_of_DRAM() >> PAGE_SHIFT;
- total_pages = (memblock_end_of_DRAM() - memstart_addr) >> PAGE_SHIFT;
-#ifdef CONFIG_HIGHMEM
- total_pages = total_lowmem >> PAGE_SHIFT;
- max_low_pfn = lowmem_end_addr >> PAGE_SHIFT;
+#ifndef CONFIG_HIGHMEM
+ _lowmem_end_addr = memblock_end_of_DRAM();
+#else
+ _lowmem_end_addr = lowmem_end_addr;
#endif
+ max_pfn = memblock_end_of_DRAM() >> PAGE_SHIFT;
+ max_low_pfn = _lowmem_end_addr >> PAGE_SHIFT;
+ min_low_pfn = MEMORY_START >> PAGE_SHIFT;
+
/*
* Find an area to use for the bootmem bitmap. Calculate the size of
* bitmap required as (Total Memory) / PAGE_SIZE / BITS_PER_BYTE.
* Add 1 additional page in case the address isn't page-aligned.
*/
- bootmap_pages = bootmem_bootmap_pages(total_pages);
+ _total_lowmem = _lowmem_end_addr - memstart_addr;
+ bootmap_pages = bootmem_bootmap_pages(_total_lowmem >> PAGE_SHIFT);
start = memblock_alloc(bootmap_pages << PAGE_SHIFT, PAGE_SIZE);
- min_low_pfn = MEMORY_START >> PAGE_SHIFT;
boot_mapsize = init_bootmem_node(NODE_DATA(0), start >> PAGE_SHIFT, min_low_pfn, max_low_pfn);
/* Place all memblock_regions in the same node and merge contiguous
@@ -219,26 +223,18 @@ void __init do_init_bootmem(void)
/* Add all physical memory to the bootmem map, mark each area
* present.
*/
-#ifdef CONFIG_HIGHMEM
- free_bootmem_with_active_regions(0, lowmem_end_addr >> PAGE_SHIFT);
+ free_bootmem_with_active_regions(0, max_low_pfn);
/* reserve the sections we're already using */
for_each_memblock(reserved, reg) {
- unsigned long top = reg->base + reg->size - 1;
- if (top < lowmem_end_addr)
+ if (reg->base + reg->size - 1 < _lowmem_end_addr)
reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT);
- else if (reg->base < lowmem_end_addr) {
- unsigned long trunc_size = lowmem_end_addr - reg->base;
+ else if (reg->base < _lowmem_end_addr) {
+ unsigned long trunc_size = _lowmem_end_addr - reg->base;
reserve_bootmem(reg->base, trunc_size, BOOTMEM_DEFAULT);
}
}
-#else
- free_bootmem_with_active_regions(0, max_pfn);
- /* reserve the sections we're already using */
- for_each_memblock(reserved, reg)
- reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT);
-#endif
/* XXX need to clip this if using highmem? */
sparse_memory_present_with_active_regions(0);
--
1.9.1
^ permalink raw reply related
* [PATCH 2/2] powerpc: Enable NO_BOOTMEM
From: Emil Medve @ 2014-04-01 7:21 UTC (permalink / raw)
To: benh, paulus, linuxppc-dev; +Cc: Emil Medve
In-Reply-To: <1396336891-13480-1-git-send-email-Emilian.Medve@Freescale.com>
Currently bootmem is just a wrapper around memblock. This gets rid of
the wrapper code just as other ARHC(es) did: x86, arm, etc.
Signed-off-by: Emil Medve <Emilian.Medve@Freescale.com>
---
arch/powerpc/Kconfig | 3 +++
arch/powerpc/mm/mem.c | 8 ++++++++
2 files changed, 11 insertions(+)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 957d3e5..2a2d4b3 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -471,6 +471,9 @@ config SYS_SUPPORTS_HUGETLBFS
source "mm/Kconfig"
+config NO_BOOTMEM
+ def_bool y
+
config ARCH_MEMORY_PROBE
def_bool y
depends on MEMORY_HOTPLUG
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index eaf5d1d8..d3e1d5f 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -187,10 +187,12 @@ EXPORT_SYMBOL_GPL(walk_system_ram_range);
#ifndef CONFIG_NEED_MULTIPLE_NODES
void __init do_init_bootmem(void)
{
+#ifndef CONFIG_NO_BOOTMEM
unsigned long start, bootmap_pages;
struct memblock_region *reg;
int boot_mapsize;
phys_addr_t _total_lowmem;
+#endif
phys_addr_t _lowmem_end_addr;
#ifndef CONFIG_HIGHMEM
@@ -203,6 +205,7 @@ void __init do_init_bootmem(void)
max_low_pfn = _lowmem_end_addr >> PAGE_SHIFT;
min_low_pfn = MEMORY_START >> PAGE_SHIFT;
+#ifndef CONFIG_NO_BOOTMEM
/*
* Find an area to use for the bootmem bitmap. Calculate the size of
* bitmap required as (Total Memory) / PAGE_SIZE / BITS_PER_BYTE.
@@ -214,12 +217,14 @@ void __init do_init_bootmem(void)
start = memblock_alloc(bootmap_pages << PAGE_SHIFT, PAGE_SIZE);
boot_mapsize = init_bootmem_node(NODE_DATA(0), start >> PAGE_SHIFT, min_low_pfn, max_low_pfn);
+#endif
/* Place all memblock_regions in the same node and merge contiguous
* memblock_regions
*/
memblock_set_node(0, (phys_addr_t)ULLONG_MAX, &memblock.memory, 0);
+#ifndef CONFIG_NO_BOOTMEM
/* Add all physical memory to the bootmem map, mark each area
* present.
*/
@@ -234,11 +239,14 @@ void __init do_init_bootmem(void)
reserve_bootmem(reg->base, trunc_size, BOOTMEM_DEFAULT);
}
}
+#endif
/* XXX need to clip this if using highmem? */
sparse_memory_present_with_active_regions(0);
+#ifndef CONFIG_NO_BOOTMEM
init_bootmem_done = 1;
+#endif
}
/* mark pages that don't exist as nosave */
--
1.9.1
^ permalink raw reply related
* RE: [PATCH 2/2] Make the diu driver work without board level initilization
From: Jason.Jin @ 2014-04-01 7:28 UTC (permalink / raw)
To: Li.Xiubo@freescale.com, Scott Wood, timur@tabi.org
Cc: linux-fbdev@vger.kernel.org, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <1305603ae9b846d9bc4c78f21a8c0494@BY2PR03MB505.namprd03.prod.outlook.com>
> > + if (!diu_ops.set_pixel_clock) {
> > + data->pixelclk_reg =3D of_iomap(np, 1);
> > + if (!data->pixelclk_reg) {
> > + dev_err(&pdev->dev, "Cannot map pixelclk registers,
> please \
> > + provide the diu_ops for pixclk setting
> instead.\n");
>=20
> The error message should be in one line if possible, or it will hard to
> grep.
> If cannot, should split it into two or more lines, like:
> + dev_err(&pdev->dev, "Cannot map pixelclk registers,\n"
> + "please provide the diu_ops for pixclk setting
> instead.\n");
Thanks, This has been fixed in the update version, please help to review it=
at:
http://patchwork.ozlabs.org/patch/335225/
I forgot to add the V2 information in the subject in the update patch so th=
is may confuse the reviewer, sorry for that.
Best Regards,
Jason=20
^ permalink raw reply
* [PATCH REPOST v5 1/3] powernv, cpufreq: Select CPUFreq related Kconfig options for powernv
From: Gautham R. Shenoy @ 2014-04-01 7:13 UTC (permalink / raw)
To: Viresh Kumar, rjw, Benjamin Herrenschmidt
Cc: Gautham R. Shenoy, Linux PM list, linux-kernel, cpufreq,
linuxppc-dev, Anton Blanchard, srivatsa.bhat
In-Reply-To: <1396336408-20954-1-git-send-email-ego@linux.vnet.ibm.com>
From: "Gautham R. Shenoy" <ego@linux.vnet.ibm.com>
Enable CPUFreq for PowerNV. Select "performance", "powersave",
"userspace" and "ondemand" governors. Choose "ondemand" to be the
default governor.
Signed-off-by: Gautham R. Shenoy <ego@linux.vnet.ibm.com>
Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
---
arch/powerpc/configs/pseries_defconfig | 1 +
arch/powerpc/configs/pseries_le_defconfig | 1 +
arch/powerpc/platforms/powernv/Kconfig | 6 ++++++
3 files changed, 8 insertions(+)
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig
index 9ea8342b..a905063 100644
--- a/arch/powerpc/configs/pseries_defconfig
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -306,3 +306,4 @@ CONFIG_KVM_BOOK3S_64=m
CONFIG_KVM_BOOK3S_64_HV=y
CONFIG_TRANSPARENT_HUGEPAGE=y
CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
diff --git a/arch/powerpc/configs/pseries_le_defconfig b/arch/powerpc/configs/pseries_le_defconfig
index 3c84f9d..58e3dbf 100644
--- a/arch/powerpc/configs/pseries_le_defconfig
+++ b/arch/powerpc/configs/pseries_le_defconfig
@@ -301,3 +301,4 @@ CONFIG_CRYPTO_LZO=m
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_DEV_NX=y
CONFIG_CRYPTO_DEV_NX_ENCRYPT=m
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
diff --git a/arch/powerpc/platforms/powernv/Kconfig b/arch/powerpc/platforms/powernv/Kconfig
index 895e8a2..c252ee9 100644
--- a/arch/powerpc/platforms/powernv/Kconfig
+++ b/arch/powerpc/platforms/powernv/Kconfig
@@ -11,6 +11,12 @@ config PPC_POWERNV
select PPC_UDBG_16550
select PPC_SCOM
select ARCH_RANDOM
+ select CPU_FREQ
+ select CPU_FREQ_GOV_PERFORMANCE
+ select CPU_FREQ_GOV_POWERSAVE
+ select CPU_FREQ_GOV_USERSPACE
+ select CPU_FREQ_GOV_ONDEMAND
+ select CPU_FREQ_GOV_CONSERVATIVE
default y
config PPC_POWERNV_RTAS
--
1.8.3.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