* [PATCH 1/2] ARM: dts: imx6sl-evk: Add PFUZE100 support
From: Shawn Guo @ 2014-01-28 12:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390443213-14061-1-git-send-email-festevam@gmail.com>
On Thu, Jan 23, 2014 at 12:13:32AM -0200, Fabio Estevam wrote:
> From: Fabio Estevam <fabio.estevam@freescale.com>
>
> imx6sl-evk board has Freescale PFUZE100 regulator, so add support for it.
>
> Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
> ---
> arch/arm/boot/dts/imx6sl-evk.dts | 110 ++++++++++++++++++++++++++++++++++++++
> arch/arm/boot/dts/imx6sl-pingrp.h | 4 ++
> 2 files changed, 114 insertions(+)
>
> diff --git a/arch/arm/boot/dts/imx6sl-evk.dts b/arch/arm/boot/dts/imx6sl-evk.dts
> index f23b5d1..5ba15ab 100644
> --- a/arch/arm/boot/dts/imx6sl-evk.dts
> +++ b/arch/arm/boot/dts/imx6sl-evk.dts
> @@ -46,6 +46,112 @@
> };
> };
>
> +&i2c1 {
> + clock-frequency = <100000>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_i2c1>;
> + status = "okay";
> +
> + pmic: pfuze100 at 08 {
> + compatible = "fsl,pfuze100";
> + reg = <0x08>;
> +
> + regulators {
> + sw1a_reg: sw1ab {
> + regulator-min-microvolt = <300000>;
> + regulator-max-microvolt = <1875000>;
> + regulator-boot-on;
> + regulator-always-on;
> + regulator-ramp-delay = <6250>;
> + };
> +
> + sw1c_reg: sw1c {
> + regulator-min-microvolt = <300000>;
> + regulator-max-microvolt = <1875000>;
> + regulator-boot-on;
> + regulator-always-on;
> + regulator-ramp-delay = <6250>;
> + };
> +
> + sw2_reg: sw2 {
> + regulator-min-microvolt = <800000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-boot-on;
> + regulator-always-on;
> + };
> +
> + sw3a_reg: sw3a {
> + regulator-min-microvolt = <400000>;
> + regulator-max-microvolt = <1975000>;
> + regulator-boot-on;
> + regulator-always-on;
> + };
> +
> + sw3b_reg: sw3b {
> + regulator-min-microvolt = <400000>;
> + regulator-max-microvolt = <1975000>;
> + regulator-boot-on;
> + regulator-always-on;
> + };
> +
> + sw4_reg: sw4 {
> + regulator-min-microvolt = <800000>;
> + regulator-max-microvolt = <3300000>;
> + };
> +
> + swbst_reg: swbst {
> + regulator-min-microvolt = <5000000>;
> + regulator-max-microvolt = <5150000>;
> + };
> +
> + snvs_reg: vsnvs {
> + regulator-min-microvolt = <1000000>;
> + regulator-max-microvolt = <3000000>;
> + regulator-boot-on;
> + regulator-always-on;
> + };
> +
> + vref_reg: vrefddr {
> + regulator-boot-on;
> + regulator-always-on;
> + };
> +
> + vgen1_reg: vgen1 {
> + regulator-min-microvolt = <800000>;
> + regulator-max-microvolt = <1550000>;
> + };
> +
> + vgen2_reg: vgen2 {
> + regulator-min-microvolt = <800000>;
> + regulator-max-microvolt = <1550000>;
> + };
> +
> + vgen3_reg: vgen3 {
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <3300000>;
> + };
> +
> + vgen4_reg: vgen4 {
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-always-on;
> + };
> +
> + vgen5_reg: vgen5 {
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-always-on;
> + };
> +
> + vgen6_reg: vgen6 {
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-always-on;
> + };
> + };
> + };
> +};
> +
> &ecspi1 {
> fsl,spi-num-chipselects = <1>;
> cs-gpios = <&gpio4 11 0>;
> @@ -86,6 +192,10 @@
> >;
> };
>
> + pinctrl_i2c1: i2c1grp {
> + fsl,pins = <MX6SL_I2C1_PINGRP1>;
> + };
> +
> pinctrl_ecspi1: ecspi1grp {
> fsl,pins = <MX6SL_ECSPI1_PINGRP1>;
> };
> diff --git a/arch/arm/boot/dts/imx6sl-pingrp.h b/arch/arm/boot/dts/imx6sl-pingrp.h
> index ead26d4..cada37a 100644
> --- a/arch/arm/boot/dts/imx6sl-pingrp.h
> +++ b/arch/arm/boot/dts/imx6sl-pingrp.h
> @@ -15,6 +15,10 @@
> MX6SL_PAD_ECSPI1_MOSI__ECSPI1_MOSI 0x100b1 \
> MX6SL_PAD_ECSPI1_SCLK__ECSPI1_SCLK 0x100b1
>
> +#define MX6SL_I2C1_PINGRP1 \
> + MX6SL_PAD_I2C1_SCL__I2C1_SCL 0x4001b8b1 \
> + MX6SL_PAD_I2C1_SDA__I2C1_SDA 0x4001b8b1
> +
The PINGRP is gone.
Shawn
> #define MX6SL_FEC_PINGRP1 \
> MX6SL_PAD_FEC_MDC__FEC_MDC 0x1b0b0 \
> MX6SL_PAD_FEC_MDIO__FEC_MDIO 0x1b0b0 \
> --
> 1.8.1.2
>
^ permalink raw reply
* [PATCH 1/2] ARM: dts: imx6: edmqmx6: fix wrong usbotg pingroup
From: Shawn Guo @ 2014-01-28 12:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390419567-2643-2-git-send-email-silvio.fricke@gmail.com>
On Wed, Jan 22, 2014 at 08:39:26PM +0100, Silvio F wrote:
> Signed-off-by: Silvio F <silvio.fricke@gmail.com>
> ---
> arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts
> index b8a1ff4..6706d1b 100644
> --- a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts
> +++ b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts
> @@ -266,7 +266,7 @@
> };
>
> pinctrl_usbotg: usbotggrp {
> - fsl,pins = <MX6QDL_USBOTG_PINGRP1>;
> + fsl,pins = <MX6QDL_USBOTG_PINGRP2>;
The PINGRP header is gone now. Please rebase it on branch below.
git://git.linaro.org/people/shawn.guo/linux-2.6.git imx/dt
Shawn
> };
>
> pinctrl_usdhc3: usdhc3grp {
> --
> 1.8.5.2
>
^ permalink raw reply
* [Patch v3 2/2] dmaengine: qcom_bam_dma: Add device tree binding
From: Arnd Bergmann @ 2014-01-28 12:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140128113242.GJ10628@intel.com>
On Tuesday 28 January 2014 17:02:42 Vinod Koul wrote:
> On Tue, Jan 28, 2014 at 11:17:57AM +0000, Russell King - ARM Linux wrote:
> > On Tue, Jan 28, 2014 at 10:16:53AM +0100, Arnd Bergmann wrote:
> > > On Tuesday 28 January 2014 10:05:35 Lars-Peter Clausen wrote:
> > > > Why does the direction needs to be specified in specifier? I see two
> > > > options, either the direction per is fixed in hardware. In that case the DMA
> > > > controller node should describe which channel is which direction. Or the
> > > > direction is not fixed in hardware and can be changed at runtime in which
> > > > case it should be set on a per descriptor basis.
> > >
> > > Normally the direction is implied by dmaengine_slave_config().
> >
> > No. The direction argument in there is deprecated - we've been talking
> > about removing it for some time.
> >
> > DMA engine drivers should store all parameters of the configuration, and
> > then select the appropriate ones when preparing a transfer (which itself
> > involves a direction.)
>
> Right all the prep_ calls for slave cases have explcit direction argument so
> sending it using slave config makes no sense. So will remove it after the merge
> window closes and fix
Ok, thanks for clearing up my mistake. However, the argument remains:
the direction doesn't need to be in the DT DMA descriptor since it
gets set by software anyway.
Arnd
^ permalink raw reply
* [PATCH] ARM: imx: enable delaytimer on the imx timer
From: Shawn Guo @ 2014-01-28 12:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390390544-10319-1-git-send-email-bigeasy@linutronix.de>
On Wed, Jan 22, 2014 at 12:35:44PM +0100, Sebastian Andrzej Siewior wrote:
> The imx can support timer-based delays, so implement this.
> Skips past jiffy calibration.
>
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Applied, thanks.
^ permalink raw reply
* Building with gcc 4.6.4
From: Russell King - ARM Linux @ 2014-01-28 12:01 UTC (permalink / raw)
To: linux-arm-kernel
So, yesterday I built gcc 4.6.4 (mainline) for the autobuilder, and the
result is that every build failed with the same error:
scripts/mod/empty.c:1:0: error: FPA is unsupported in the AAPCS
This seems to be because linux-elf targets default to fpe3 in mainline
gcc, but specifying -mabi=aapcs-linux switches us into EABI mode where
the compiler errors out with the default FPU.
Hence, I believe we need this to ensure that a compatible VFP is
selected. One can argue that building EABI ARMv4 with VFP is silly,
but it seems that's what the gcc folk have decided (rightly or
wrongly.)
Maybe this is a bug in mainline GCC - which begs the question why
(presumably, since no one has picked this up) Linaro's toolchain
has fixes but mainline GCC doesn't.
Comments?
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 23d5e3946589..08a9ef58d9c3 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -96,7 +96,7 @@ tune-$(CONFIG_CPU_V6K) =$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm)
tune-y := $(tune-y)
ifeq ($(CONFIG_AEABI),y)
-CFLAGS_ABI :=-mabi=aapcs-linux -mno-thumb-interwork
+CFLAGS_ABI :=-mabi=aapcs-linux -mno-thumb-interwork -mfpu=vfp
else
CFLAGS_ABI :=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) $(call cc-option,-mno-thumb-interwork,)
endif
--
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up. Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".
^ permalink raw reply related
* [PATCH V3] ARM: imx: add always-on clock array for i.mx6sl to maintain correct usecount
From: Shawn Guo @ 2014-01-28 11:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390374887-22833-1-git-send-email-b20788@freescale.com>
On Wed, Jan 22, 2014 at 03:14:47PM +0800, Anson Huang wrote:
> IPG, ARM and MMDC's clock should be enabled during kernel boot up,
> so we need to maintain their usecount, otherwise, they may be
> disabled unexpectedly if their children's clock are turned off, and
> caused their parent PLLs also get disabled, which is incorrect.
>
> Signed-off-by: Anson Huang <b20788@freescale.com>
Applied, thanks.
^ permalink raw reply
* [PATCH] ARM: dts: imx6qdl-sabreauto: Add PFUZE100 support
From: Shawn Guo @ 2014-01-28 11:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390250840-24196-1-git-send-email-festevam@gmail.com>
On Mon, Jan 20, 2014 at 06:47:20PM -0200, Fabio Estevam wrote:
> From: Fabio Estevam <fabio.estevam@freescale.com>
>
> mx6 sabreauto boards have Freescale PFUZE100 regulator, so add support for it.
>
> Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
> ---
> arch/arm/boot/dts/imx6qdl-sabreauto.dtsi | 110 +++++++++++++++++++++++++++++++
> 1 file changed, 110 insertions(+)
>
> diff --git a/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
> index 47c5a3f..e44ff49 100644
> --- a/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
> +++ b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
> @@ -63,6 +63,112 @@
> status = "okay";
> };
>
> +&i2c2 {
> + clock-frequency = <100000>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_i2c2>;
> + status = "okay";
> +
> + pmic: pfuze100 at 08 {
> + compatible = "fsl,pfuze100";
> + reg = <0x08>;
> +
> + regulators {
> + sw1a_reg: sw1ab {
> + regulator-min-microvolt = <300000>;
> + regulator-max-microvolt = <1875000>;
> + regulator-boot-on;
> + regulator-always-on;
> + regulator-ramp-delay = <6250>;
> + };
> +
> + sw1c_reg: sw1c {
> + regulator-min-microvolt = <300000>;
> + regulator-max-microvolt = <1875000>;
> + regulator-boot-on;
> + regulator-always-on;
> + regulator-ramp-delay = <6250>;
> + };
> +
> + sw2_reg: sw2 {
> + regulator-min-microvolt = <800000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-boot-on;
> + regulator-always-on;
> + };
> +
> + sw3a_reg: sw3a {
> + regulator-min-microvolt = <400000>;
> + regulator-max-microvolt = <1975000>;
> + regulator-boot-on;
> + regulator-always-on;
> + };
> +
> + sw3b_reg: sw3b {
> + regulator-min-microvolt = <400000>;
> + regulator-max-microvolt = <1975000>;
> + regulator-boot-on;
> + regulator-always-on;
> + };
> +
> + sw4_reg: sw4 {
> + regulator-min-microvolt = <800000>;
> + regulator-max-microvolt = <3300000>;
> + };
> +
> + swbst_reg: swbst {
> + regulator-min-microvolt = <5000000>;
> + regulator-max-microvolt = <5150000>;
> + };
> +
> + snvs_reg: vsnvs {
> + regulator-min-microvolt = <1000000>;
> + regulator-max-microvolt = <3000000>;
> + regulator-boot-on;
> + regulator-always-on;
> + };
> +
> + vref_reg: vrefddr {
> + regulator-boot-on;
> + regulator-always-on;
> + };
> +
> + vgen1_reg: vgen1 {
> + regulator-min-microvolt = <800000>;
> + regulator-max-microvolt = <1550000>;
> + };
> +
> + vgen2_reg: vgen2 {
> + regulator-min-microvolt = <800000>;
> + regulator-max-microvolt = <1550000>;
> + };
> +
> + vgen3_reg: vgen3 {
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <3300000>;
> + };
> +
> + vgen4_reg: vgen4 {
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-always-on;
> + };
> +
> + vgen5_reg: vgen5 {
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-always-on;
> + };
> +
> + vgen6_reg: vgen6 {
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-always-on;
> + };
> + };
> + };
> +};
> +
> &iomuxc {
> pinctrl-names = "default";
> pinctrl-0 = <&pinctrl_hog>;
> @@ -90,6 +196,10 @@
> fsl,pins = <MX6QDL_ENET_PINGRP2_GPIO6>;
> };
>
> + pinctrl_i2c2: i2c2grp {
> + fsl,pins = <MX6QDL_I2C2_PINGRP3>;
The PINGRP header is gone. Please rebase it against to my imx/dt
branch.
Shawn
> + };
> +
> pinctrl_gpmi_nand: gpminandgrp {
> fsl,pins = <MX6QDL_GPMI_NAND_PINGRP1>;
> };
> --
> 1.8.1.2
>
^ permalink raw reply
* [PATCH v2 1/7] cpufreq: cpufreq-cpu0: allow optional safe voltage during frequency transitions
From: Shawn Guo @ 2014-01-28 11:49 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAJuA9ah1vsgpD04QhM5RApkCe9xcvpPkLvdwzgadKGWvngAt+g@mail.gmail.com>
On Tue, Jan 28, 2014 at 11:00:29AM +0530, Thomas Abraham wrote:
> Hi Mike,
>
> On Tue, Jan 28, 2014 at 1:55 AM, Mike Turquette <mturquette@linaro.org> wrote:
> > Quoting Thomas Abraham (2014-01-18 04:10:51)
> >> From: Thomas Abraham <thomas.ab@samsung.com>
> >>
> >> On some platforms such as the Samsung Exynos, changing the frequency
> >> of the CPU clock requires changing the frequency of the PLL that is
> >> supplying the CPU clock. To change the frequency of the PLL, the CPU
> >> clock is temporarily reparented to another parent clock.
> >>
> >> The clock frequency of this temporary parent clock could be much higher
> >> than the clock frequency of the PLL at the time of reparenting. Due
> >> to the temporary increase in the CPU clock speed, the CPU (and any other
> >> components in the CPU clock domain such as dividers, mux, etc.) have to
> >> to be operated at a higher voltage level, called the safe voltage level.
> >> This patch adds optional support to temporarily switch to a safe voltage
> >> level during CPU frequency transitions.
> >>
> >> Cc: Shawn Guo <shawn.guo@linaro.org>
> >> Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>
> >
> > I'm not a fan of this change. This corner case should be abstracted away
> > somehow. I had talked to Chander Kayshap previously about handling
> > voltage changes in clock notifier callbacks, which then renders any
> > voltage change as a trivial part of the clock rate transition. That
> > means that this "safe voltage" thing could be handled automagically
> > without any additional code in the CPUfreq driver.
> >
> > There are two nice ways to do this with the clock framework. First is
> > explicit re-parenting with voltage scaling done in the clock rate-change
> > notifiers:
> >
> > clk_set_parent(cpu_clk, temp_parent);
> > /* implicit voltage scaling to "safe voltage" happens above */
> > clk_set_rate(pll, some_rate);
> > clk_set_parent(cpu_clk, pll);
> > /* implicit voltage scaling to nominal OPP voltage happens above */
> >
> > The above sequence would require a separate exnyos CPUfreq driver, due
> > to the added clk_set_parent logic.
> >
> > The second way to do this is to abstract the clk re-muxing logic out
> > into the clk driver, which would allow cpufreq-cpu0 to be used for the
> > exynos chips.
>
> This is the approach this patch series takes (patch 2/7). The clock
> re-muxing logic is handled by a clock driver code. The difference from
> what you suggested is that the safe voltage (that may be optionally)
> required before doing the re-muxing is handled here in cpufreq-cpu0
> driver.
>
> The safe voltage setup can be done in the notifier as you suggested.
> But, doing that in cpufreq-cpu0 driver will help other platforms reuse
> this feature if required. Also, if done here, the regulator handling
> is localized in this driver which otherwise would need to be handled
> in two places, cpufreq-cpu0 driver and the clock notifier.
>
> So I tend to prefer the approach in this patch but I am willing to
> consider any suggestions. Shawn, it would be helpful if you could let
> us know your thoughts on this. I am almost done with testing the v3 of
> this series and want to post it so if there are any objections to the
> changes in this patch, please let me know.
To me, it's the best that we reuse cpufreq-cpu0 for exynos without any
changes on cpufreq-cpu0 driver ;)
Shawn
^ permalink raw reply
* [RFC PATCH 2/3] ARM/ARM64: KVM: Add support for PSCI v0.2 emulation
From: Anup Patel @ 2014-01-28 11:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52E79408.5000903@arm.com>
On Tue, Jan 28, 2014 at 4:57 PM, Marc Zyngier <marc.zyngier@arm.com> wrote:
> Hi Anup,
>
> On 21/01/14 13:01, Anup Patel wrote:
>> Currently, the in-kernel PSCI emulation provides PSCI v0.1 interface to
>> VCPUs. This patch extends current in-kernel PSCI emulation to provide
>> PSCI v0.2 interface to VCPUs.
>>
>> By default, ARM/ARM64 KVM will always provide PSCI v0.1 interface for
>> keeping the ABI backward-compatible.
>>
>> To select PSCI v0.2 interface for VCPUs, the user space (i.e. QEMU or
>> KVMTOOL) will have to set KVM_ARM_VCPU_PSCI_0_2 feature when doing VCPU
>> init using KVM_ARM_VCPU_INIT ioctl.
>>
>> Signed-off-by: Anup Patel <anup.patel@linaro.org>
>> Signed-off-by: Pranavkumar Sawargaonkar <pranavkumar@linaro.org>
>> ---
>> arch/arm/include/asm/kvm_host.h | 2 +-
>> arch/arm/include/uapi/asm/kvm.h | 39 ++++++++++++++++--
>> arch/arm/kvm/arm.c | 6 ++-
>> arch/arm/kvm/psci.c | 79 ++++++++++++++++++++++++++++++-------
>> arch/arm64/include/asm/kvm_host.h | 2 +-
>> arch/arm64/include/uapi/asm/kvm.h | 39 ++++++++++++++++--
>> 6 files changed, 143 insertions(+), 24 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
>> index 8a6f6db..0239ac5 100644
>> --- a/arch/arm/include/asm/kvm_host.h
>> +++ b/arch/arm/include/asm/kvm_host.h
>> @@ -36,7 +36,7 @@
>> #define KVM_COALESCED_MMIO_PAGE_OFFSET 1
>> #define KVM_HAVE_ONE_REG
>>
>> -#define KVM_VCPU_MAX_FEATURES 1
>> +#define KVM_VCPU_MAX_FEATURES 2
>>
>> #include <kvm/arm_vgic.h>
>>
>> diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
>> index c498b60..d9eb74c 100644
>> --- a/arch/arm/include/uapi/asm/kvm.h
>> +++ b/arch/arm/include/uapi/asm/kvm.h
>> @@ -83,6 +83,7 @@ struct kvm_regs {
>> #define KVM_VGIC_V2_CPU_SIZE 0x2000
>>
>> #define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
>> +#define KVM_ARM_VCPU_PSCI_0_2 1 /* CPU uses PSCI v0.2 */
>>
>> struct kvm_vcpu_init {
>> __u32 target;
>> @@ -164,7 +165,7 @@ struct kvm_arch_memory_slot {
>> /* Highest supported SPI, from VGIC_NR_IRQS */
>> #define KVM_ARM_IRQ_GIC_MAX 127
>>
>> -/* PSCI interface */
>> +/* PSCI v0.1 interface */
>> #define KVM_PSCI_FN_BASE 0x95c1ba5e
>> #define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n))
>>
>> @@ -173,9 +174,41 @@ struct kvm_arch_memory_slot {
>> #define KVM_PSCI_FN_CPU_ON KVM_PSCI_FN(2)
>> #define KVM_PSCI_FN_MIGRATE KVM_PSCI_FN(3)
>>
>> +/* PSCI v0.2 interface */
>> +#define KVM_PSCI_0_2_FN_BASE 0x84000000
>> +#define KVM_PSCI_0_2_FN(n) (KVM_PSCI_0_2_FN_BASE + (n))
>> +#define KVM_PSCI_0_2_FN64_BASE 0xC4000000
>> +#define KVM_PSCI_0_2_FN64(n) (KVM_PSCI_0_2_FN64_BASE + (n))
>> +
>> +#define KVM_PSCI_0_2_FN_PSCI_VERSION KVM_PSCI_0_2_FN(0)
>> +#define KVM_PSCI_0_2_FN_CPU_SUSPEND KVM_PSCI_0_2_FN(1)
>> +#define KVM_PSCI_0_2_FN_CPU_OFF KVM_PSCI_0_2_FN(2)
>> +#define KVM_PSCI_0_2_FN_CPU_ON KVM_PSCI_0_2_FN(3)
>> +#define KVM_PSCI_0_2_FN_AFFINITY_INFO KVM_PSCI_0_2_FN(4)
>> +#define KVM_PSCI_0_2_FN_MIGRATE KVM_PSCI_0_2_FN(5)
>> +#define KVM_PSCI_0_2_FN_MIGRATE_INFO_TYPE \
>> + KVM_PSCI_0_2_FN(6)
>> +#define KVM_PSCI_0_2_FN_MIGRATE_INFO_UP_CPU \
>> + KVM_PSCI_0_2_FN(7)
>> +#define KVM_PSCI_0_2_FN_SYSTEM_OFF KVM_PSCI_0_2_FN(8)
>> +#define KVM_PSCI_0_2_FN_SYSTEM_RESET KVM_PSCI_0_2_FN(9)
>> +
>> +#define KVM_PSCI_0_2_FN64_CPU_SUSPEND KVM_PSCI_0_2_FN64(1)
>> +#define KVM_PSCI_0_2_FN64_CPU_ON KVM_PSCI_0_2_FN64(3)
>> +#define KVM_PSCI_0_2_FN64_AFFINITY_INFO KVM_PSCI_0_2_FN64(4)
>> +#define KVM_PSCI_0_2_FN64_MIGRATE KVM_PSCI_0_2_FN64(5)
>> +#define KVM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU \
>> + KVM_PSCI_0_2_FN64(7)
>> +
>> +/* PSCI return values */
>> #define KVM_PSCI_RET_SUCCESS 0
>> -#define KVM_PSCI_RET_NI ((unsigned long)-1)
>> -#define KVM_PSCI_RET_INVAL ((unsigned long)-2)
>
> This is a massive no-no. It is already part of the userspace API, and we
> cannot break it (neither arm nor arm64). These #defines have to stay
> forever.
>
>> +#define KVM_PSCI_RET_NOT_SUPPORTED ((unsigned long)-1)
>> +#define KVM_PSCI_RET_INVALID_PARAMS ((unsigned long)-2)
>
> As such, you can drop these two defines, and use the original ones in
> your new code, which will reduce the churn.
Sure, I will use the original defines. I was just trying to name all
return values
as described in spec.
>
>> #define KVM_PSCI_RET_DENIED ((unsigned long)-3)
>> +#define KVM_PSCI_RET_ALREADY_ON ((unsigned long)-4)
>> +#define KVM_PSCI_RET_ON_PENDING ((unsigned long)-5)
>> +#define KVM_PSCI_RET_INTERNAL_FAILURE ((unsigned long)-6)
>> +#define KVM_PSCI_RET_NOT_PRESENT ((unsigned long)-7)
>> +#define KVM_PSCI_RET_DISABLED ((unsigned long)-8)
>>
>> #endif /* __ARM_KVM_H__ */
>> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
>> index 2a700e0..0b7817a 100644
>> --- a/arch/arm/kvm/arm.c
>> +++ b/arch/arm/kvm/arm.c
>> @@ -193,6 +193,7 @@ int kvm_dev_ioctl_check_extension(long ext)
>> case KVM_CAP_DESTROY_MEMORY_REGION_WORKS:
>> case KVM_CAP_ONE_REG:
>> case KVM_CAP_ARM_PSCI:
>> + case KVM_CAP_ARM_PSCI_0_2:
>> r = 1;
>> break;
>> case KVM_CAP_COALESCED_MMIO:
>> @@ -483,7 +484,10 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
>> * PSCI code.
>> */
>> if (test_and_clear_bit(KVM_ARM_VCPU_POWER_OFF, vcpu->arch.features)) {
>> - *vcpu_reg(vcpu, 0) = KVM_PSCI_FN_CPU_OFF;
>> + if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features))
>
> Can you make this a function? Something like:
>
> int get_psci_version(struct kvm_vcpu *vcpu)
> {
> if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features))
> return PSCI_VERSION_0_2;
>
> return PSCI_VERSION_0_1;
> }
>
> probably located in psci.c. This way, when PSCI version 3.14159 comes
> along, we'll have some mechanism in place, and we're free to change the
> detection method without impacting the rest of the code.
Yes, I was not sure about this change.
I will implement "int psci_version(struct kvm_vcpu *vcpu)" in psci.c and use
this wherever applicable (as-per your suggestion).
>
>> + *vcpu_reg(vcpu, 0) = KVM_PSCI_0_2_FN_CPU_OFF;
>> + else
>> + *vcpu_reg(vcpu, 0) = KVM_PSCI_FN_CPU_OFF;
>> kvm_psci_call(vcpu);
>> }
>>
>> diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c
>> index 0881bf1..ee044a3 100644
>> --- a/arch/arm/kvm/psci.c
>> +++ b/arch/arm/kvm/psci.c
>> @@ -55,13 +55,13 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
>> }
>>
>> if (!vcpu)
>> - return KVM_PSCI_RET_INVAL;
>> + return KVM_PSCI_RET_INVALID_PARAMS;
>>
>> target_pc = *vcpu_reg(source_vcpu, 2);
>>
>> wq = kvm_arch_vcpu_wq(vcpu);
>> if (!waitqueue_active(wq))
>> - return KVM_PSCI_RET_INVAL;
>> + return KVM_PSCI_RET_INVALID_PARAMS;
>>
>> kvm_reset_vcpu(vcpu);
>>
>> @@ -84,17 +84,49 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
>> return KVM_PSCI_RET_SUCCESS;
>> }
>>
>> -/**
>> - * kvm_psci_call - handle PSCI call if r0 value is in range
>> - * @vcpu: Pointer to the VCPU struct
>> - *
>> - * Handle PSCI calls from guests through traps from HVC instructions.
>> - * The calling convention is similar to SMC calls to the secure world where
>> - * the function number is placed in r0 and this function returns true if the
>> - * function number specified in r0 is withing the PSCI range, and false
>> - * otherwise.
>> - */
>> -bool kvm_psci_call(struct kvm_vcpu *vcpu)
>> +static bool kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
>> +{
>> + unsigned long psci_fn = *vcpu_reg(vcpu, 0) & ~((u32) 0);
>> + unsigned long val;
>> +
>> + switch (psci_fn) {
>> + case KVM_PSCI_0_2_FN_PSCI_VERSION:
>> + /*
>> + * Bits[31:16] = Major Version = 0
>> + * Bits[15:0] = Minor Version = 2
>> + */
>> + val = 2;
>> + break;
>> + case KVM_PSCI_0_2_FN_CPU_OFF:
>> + kvm_psci_vcpu_off(vcpu);
>> + val = KVM_PSCI_RET_SUCCESS;
>> + break;
>> + case KVM_PSCI_0_2_FN_CPU_ON:
>> + case KVM_PSCI_0_2_FN64_CPU_ON:
>> + val = kvm_psci_vcpu_on(vcpu);
>> + break;
>> + case KVM_PSCI_0_2_FN_CPU_SUSPEND:
>> + case KVM_PSCI_0_2_FN_AFFINITY_INFO:
>> + case KVM_PSCI_0_2_FN_MIGRATE:
>> + case KVM_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
>> + case KVM_PSCI_0_2_FN_MIGRATE_INFO_UP_CPU:
>> + case KVM_PSCI_0_2_FN_SYSTEM_OFF:
>> + case KVM_PSCI_0_2_FN_SYSTEM_RESET:
>> + case KVM_PSCI_0_2_FN64_CPU_SUSPEND:
>> + case KVM_PSCI_0_2_FN64_AFFINITY_INFO:
>> + case KVM_PSCI_0_2_FN64_MIGRATE:
>> + case KVM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU:
>> + val = KVM_PSCI_RET_NOT_SUPPORTED;
>> + break;
>> + default:
>> + return false;
>> + }
>> +
>> + *vcpu_reg(vcpu, 0) = val;
>> + return true;
>> +}
>> +
>> +static bool kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
>> {
>> unsigned long psci_fn = *vcpu_reg(vcpu, 0) & ~((u32) 0);
>> unsigned long val;
>> @@ -109,9 +141,8 @@ bool kvm_psci_call(struct kvm_vcpu *vcpu)
>> break;
>> case KVM_PSCI_FN_CPU_SUSPEND:
>> case KVM_PSCI_FN_MIGRATE:
>> - val = KVM_PSCI_RET_NI;
>> + val = KVM_PSCI_RET_NOT_SUPPORTED;
>> break;
>> -
>> default:
>> return false;
>> }
>> @@ -119,3 +150,21 @@ bool kvm_psci_call(struct kvm_vcpu *vcpu)
>> *vcpu_reg(vcpu, 0) = val;
>> return true;
>> }
>> +
>> +/**
>> + * kvm_psci_call - handle PSCI call if r0 value is in range
>> + * @vcpu: Pointer to the VCPU struct
>> + *
>> + * Handle PSCI calls from guests through traps from HVC instructions.
>> + * The calling convention is similar to SMC calls to the secure world where
>> + * the function number is placed in r0 and this function returns true if the
>> + * function number specified in r0 is withing the PSCI range, and false
>> + * otherwise.
>> + */
>> +bool kvm_psci_call(struct kvm_vcpu *vcpu)
>> +{
>> + if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features))
>> + return kvm_psci_0_2_call(vcpu);
>> +
>> + return kvm_psci_0_1_call(vcpu);
>> +}
>> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
>> index 0a1d697..92242ce 100644
>> --- a/arch/arm64/include/asm/kvm_host.h
>> +++ b/arch/arm64/include/asm/kvm_host.h
>> @@ -39,7 +39,7 @@
>> #include <kvm/arm_vgic.h>
>> #include <kvm/arm_arch_timer.h>
>>
>> -#define KVM_VCPU_MAX_FEATURES 2
>> +#define KVM_VCPU_MAX_FEATURES 3
>>
>> struct kvm_vcpu;
>> int kvm_target_cpu(void);
>> diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
>> index d9f026b..0eb254d 100644
>> --- a/arch/arm64/include/uapi/asm/kvm.h
>> +++ b/arch/arm64/include/uapi/asm/kvm.h
>> @@ -77,6 +77,7 @@ struct kvm_regs {
>>
>> #define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
>> #define KVM_ARM_VCPU_EL1_32BIT 1 /* CPU running a 32bit VM */
>> +#define KVM_ARM_VCPU_PSCI_0_2 2 /* CPU uses PSCI v0.2 */
>>
>> struct kvm_vcpu_init {
>> __u32 target;
>> @@ -150,7 +151,7 @@ struct kvm_arch_memory_slot {
>> /* Highest supported SPI, from VGIC_NR_IRQS */
>> #define KVM_ARM_IRQ_GIC_MAX 127
>>
>> -/* PSCI interface */
>> +/* PSCI v0.1 interface */
>> #define KVM_PSCI_FN_BASE 0x95c1ba5e
>> #define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n))
>>
>> @@ -159,10 +160,42 @@ struct kvm_arch_memory_slot {
>> #define KVM_PSCI_FN_CPU_ON KVM_PSCI_FN(2)
>> #define KVM_PSCI_FN_MIGRATE KVM_PSCI_FN(3)
>>
>> +/* PSCI v0.2 interface */
>> +#define KVM_PSCI_0_2_FN_BASE 0x84000000
>> +#define KVM_PSCI_0_2_FN(n) (KVM_PSCI_0_2_FN_BASE + (n))
>> +#define KVM_PSCI_0_2_FN64_BASE 0xC4000000
>> +#define KVM_PSCI_0_2_FN64(n) (KVM_PSCI_0_2_FN64_BASE + (n))
>> +
>> +#define KVM_PSCI_0_2_FN_PSCI_VERSION KVM_PSCI_0_2_FN(0)
>> +#define KVM_PSCI_0_2_FN_CPU_SUSPEND KVM_PSCI_0_2_FN(1)
>> +#define KVM_PSCI_0_2_FN_CPU_OFF KVM_PSCI_0_2_FN(2)
>> +#define KVM_PSCI_0_2_FN_CPU_ON KVM_PSCI_0_2_FN(3)
>> +#define KVM_PSCI_0_2_FN_AFFINITY_INFO KVM_PSCI_0_2_FN(4)
>> +#define KVM_PSCI_0_2_FN_MIGRATE KVM_PSCI_0_2_FN(5)
>> +#define KVM_PSCI_0_2_FN_MIGRATE_INFO_TYPE \
>> + KVM_PSCI_0_2_FN(6)
>> +#define KVM_PSCI_0_2_FN_MIGRATE_INFO_UP_CPU \
>> + KVM_PSCI_0_2_FN(7)
>> +#define KVM_PSCI_0_2_FN_SYSTEM_OFF KVM_PSCI_0_2_FN(8)
>> +#define KVM_PSCI_0_2_FN_SYSTEM_RESET KVM_PSCI_0_2_FN(9)
>> +
>> +#define KVM_PSCI_0_2_FN64_CPU_SUSPEND KVM_PSCI_0_2_FN64(1)
>> +#define KVM_PSCI_0_2_FN64_CPU_ON KVM_PSCI_0_2_FN64(3)
>> +#define KVM_PSCI_0_2_FN64_AFFINITY_INFO KVM_PSCI_0_2_FN64(4)
>> +#define KVM_PSCI_0_2_FN64_MIGRATE KVM_PSCI_0_2_FN64(5)
>> +#define KVM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU \
>> + KVM_PSCI_0_2_FN64(7)
>> +
>> +/* PSCI return values */
>> #define KVM_PSCI_RET_SUCCESS 0
>> -#define KVM_PSCI_RET_NI ((unsigned long)-1)
>> -#define KVM_PSCI_RET_INVAL ((unsigned long)-2)
>> +#define KVM_PSCI_RET_NOT_SUPPORTED ((unsigned long)-1)
>> +#define KVM_PSCI_RET_INVALID_PARAMS ((unsigned long)-2)
>> #define KVM_PSCI_RET_DENIED ((unsigned long)-3)
>> +#define KVM_PSCI_RET_ALREADY_ON ((unsigned long)-4)
>> +#define KVM_PSCI_RET_ON_PENDING ((unsigned long)-5)
>> +#define KVM_PSCI_RET_INTERNAL_FAILURE ((unsigned long)-6)
>> +#define KVM_PSCI_RET_NOT_PRESENT ((unsigned long)-7)
>> +#define KVM_PSCI_RET_DISABLED ((unsigned long)-8)
>>
>> #endif
>>
>> --
>> 1.7.9.5
>
> With the above remarks fixed, I think we'll have a good base for future
> developments. Looking forward to the next version.
I will revise and send-out next version soon.
>
> Thanks,
>
> M.
> --
> Jazz is not dead. It just smells funny...
> _______________________________________________
> kvmarm mailing list
> kvmarm at lists.cs.columbia.edu
> https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm
Thanks,
Anup
^ permalink raw reply
* [PATCH v2 1/7] cpufreq: cpufreq-cpu0: allow optional safe voltage during frequency transitions
From: Thomas Abraham @ 2014-01-28 11:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140128091721.1d8128cd@amdc2363>
Hi Lukasz,
On Tue, Jan 28, 2014 at 1:47 PM, Lukasz Majewski <l.majewski@samsung.com> wrote:
> Hi Thomas, Mike
>
>> Hi Mike,
>>
>> On Tue, Jan 28, 2014 at 1:55 AM, Mike Turquette
>> <mturquette@linaro.org> wrote:
>> > Quoting Thomas Abraham (2014-01-18 04:10:51)
>> >> From: Thomas Abraham <thomas.ab@samsung.com>
>> >>
>> >> On some platforms such as the Samsung Exynos, changing the
>> >> frequency of the CPU clock requires changing the frequency of the
>> >> PLL that is supplying the CPU clock. To change the frequency of
>> >> the PLL, the CPU clock is temporarily reparented to another parent
>> >> clock.
>> >>
>> >> The clock frequency of this temporary parent clock could be much
>> >> higher than the clock frequency of the PLL at the time of
>> >> reparenting. Due to the temporary increase in the CPU clock speed,
>> >> the CPU (and any other components in the CPU clock domain such as
>> >> dividers, mux, etc.) have to to be operated at a higher voltage
>> >> level, called the safe voltage level. This patch adds optional
>> >> support to temporarily switch to a safe voltage level during CPU
>> >> frequency transitions.
>> >>
>> >> Cc: Shawn Guo <shawn.guo@linaro.org>
>> >> Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>
>> >
>> > I'm not a fan of this change. This corner case should be abstracted
>> > away somehow. I had talked to Chander Kayshap previously about
>> > handling voltage changes in clock notifier callbacks, which then
>> > renders any voltage change as a trivial part of the clock rate
>> > transition. That means that this "safe voltage" thing could be
>> > handled automagically without any additional code in the CPUfreq
>> > driver.
>> >
>> > There are two nice ways to do this with the clock framework. First
>> > is explicit re-parenting with voltage scaling done in the clock
>> > rate-change notifiers:
>> >
>> > clk_set_parent(cpu_clk, temp_parent);
>> > /* implicit voltage scaling to "safe voltage" happens above */
>> > clk_set_rate(pll, some_rate);
>> > clk_set_parent(cpu_clk, pll);
>> > /* implicit voltage scaling to nominal OPP voltage happens above */
>> >
>
> I must agree with Mike here. In my opinion the above approach is more
> compliant with CCF (as I've pointed it out in my other comment - the
> cpu_clk has more than one parent and we could switch between them when
> needed).
The mux which is used to re-parent is part of the larger opaque cpu
clock type (more like the composite clock). So I am not sure how this
isn't compliant with ccf.
>
>> > The above sequence would require a separate exnyos CPUfreq driver,
>> > due to the added clk_set_parent logic.
>> >
>> > The second way to do this is to abstract the clk re-muxing logic out
>> > into the clk driver, which would allow cpufreq-cpu0 to be used for
>> > the exynos chips.
>>
>> This is the approach this patch series takes (patch 2/7). The clock
>> re-muxing logic is handled by a clock driver code. The difference from
>> what you suggested is that the safe voltage (that may be optionally)
>> required before doing the re-muxing is handled here in cpufreq-cpu0
>> driver.
>>
>> The safe voltage setup can be done in the notifier as you suggested.
>
> If the clk_set_parent() approach is not suitable, then cannot we
> consider using the one from highbank-cpufreq.c?
>
> Here we have cpufreq-cpu0.c which sets voltage of the cpu_clk.
> In the highbank-cpufreq.c there are clock notifiers to change the
> voltage.
>
> Cannot Exynos reuse such approach? Why shall we pollute cpufreq-cpu0.c
> with another solution?
The highbank-cpufreq.c file was introduced because platforms using
this driver did not have the usual regulator to control the voltage.
The first commit of this driver explains this (copied below).
"Highbank processors depend on the external ECME to perform voltage
management based on a requested frequency. Communication between the
A9 cores and the ECME happens over the pl320 IPC channel."
So those platforms had no choice but to use an alternative approach to
control the voltage (and reuse cpufreq-cpu0 as much as possible). The
case with exynos is a different one. cpufreq-cpu0 is fully re-usable
for exynos with the additional support for "safe voltage". If we agree
that there might be existing or future platforms with single
clock/voltage rail that require the "safe voltage" feature, then
adding "safe voltage" support in cpufreq-cpu0 driver seems to be the
right approach.
>
>> But, doing that in cpufreq-cpu0 driver will help other platforms reuse
>> this feature if required. Also, if done here, the regulator handling
>> is localized in this driver which otherwise would need to be handled
>> in two places, cpufreq-cpu0 driver and the clock notifier.
>
> I think that there is a logical distinction between setting voltage for
> cpufreq-cpu0 related clock and increasing voltage of reparented clock.
>
> The former fits naturally to cpufreq-cpu0, when the latter seems like
> some corner case (as Mike pointed out) for Exynos.
Agreed, it is a corner case. But for this corner case, we are
performing some additional actions on the same regulator which is used
in the normal functioning of the driver.
>
>>
>> So I tend to prefer the approach in this patch but I am willing to
>> consider any suggestions.
>
> Thomas, what do you think about highbank-cpufreq.c approach (with
> using clock notifiers)?
I have made a related comment on this above.
>
> Do you think, that it is feasible to reuse it with Exynos?
highbank cpufreq driver is intended for a different purpose so I don't
think it can be reused for exynos. Yes, we can make exynos specific
hacks into highbank driver but how would that be better over the
approach in this patch?
>
>> Shawn, it would be helpful if you could let
>> us know your thoughts on this. I am almost done with testing the v3 of
>> this series and want to post it so if there are any objections to the
>> changes in this patch, please let me know.
>>
>> Thanks,
>> Thomas.
>>
>> >
>> > I'm more a fan of explicitly listing the Exact Steps for the cpu opp
>> > transition in a separate exynos-specific CPUfreq driver, but that's
>> > probably an unpopular view.
>> >
>> > Regards,
>> > Mike
>> >
>> >> ---
>> >> .../devicetree/bindings/cpufreq/cpufreq-cpu0.txt | 7 ++++
>> >> drivers/cpufreq/cpufreq-cpu0.c | 37
>> >> +++++++++++++++++-- 2 files changed, 40 insertions(+), 4
>> >> deletions(-)
>> >>
>> >> diff --git
>> >> a/Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt
>> >> b/Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt index
>> >> f055515..37453ab 100644 ---
>> >> a/Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt +++
>> >> b/Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt @@
>> >> -19,6 +19,12 @@ Optional properties:
>> >> - cooling-min-level:
>> >> - cooling-max-level:
>> >> Please refer to
>> >> Documentation/devicetree/bindings/thermal/thermal.txt. +-
>> >> safe-opp: Certain platforms require that during a opp transition,
>> >> + a system should not go below a particular opp level. For such
>> >> systems,
>> >> + this property specifies the minimum opp to be maintained during
>> >> the
>> >> + opp transitions. The safe-opp value is a tuple with first
>> >> element
>> >> + representing the safe frequency and the second element
>> >> representing the
>> >> + safe voltage.
>> >>
>> >> Examples:
>> >>
>> >> @@ -36,6 +42,7 @@ cpus {
>> >> 396000 950000
>> >> 198000 850000
>> >> >;
>> >> + safe-opp = <396000 950000>
>> >> clock-latency = <61036>; /* two CLK32 periods */
>> >> #cooling-cells = <2>;
>> >> cooling-min-level = <0>;
>> >> diff --git a/drivers/cpufreq/cpufreq-cpu0.c
>> >> b/drivers/cpufreq/cpufreq-cpu0.c index 0c12ffc..075d3d1 100644
>> >> --- a/drivers/cpufreq/cpufreq-cpu0.c
>> >> +++ b/drivers/cpufreq/cpufreq-cpu0.c
>> >> @@ -27,6 +27,8 @@
>> >>
>> >> static unsigned int transition_latency;
>> >> static unsigned int voltage_tolerance; /* in percentage */
>> >> +static unsigned long safe_frequency;
>> >> +static unsigned long safe_voltage;
>> >>
>> >> static struct device *cpu_dev;
>> >> static struct clk *cpu_clk;
>> >> @@ -64,17 +66,30 @@ static int cpu0_set_target(struct
>> >> cpufreq_policy *policy, unsigned int index) volt_old =
>> >> regulator_get_voltage(cpu_reg); }
>> >>
>> >> - pr_debug("%u MHz, %ld mV --> %u MHz, %ld mV\n",
>> >> + pr_debug("\n\n%u MHz, %ld mV --> %u MHz, %ld mV\n",
>> >> old_freq / 1000, volt_old ? volt_old / 1000 : -1,
>> >> new_freq / 1000, volt ? volt / 1000 : -1);
>> >>
>> >> /* scaling up? scale voltage before frequency */
>> >> - if (!IS_ERR(cpu_reg) && new_freq > old_freq) {
>> >> + if (!IS_ERR(cpu_reg) && new_freq > old_freq &&
>> >> + new_freq >= safe_frequency) {
>> >> ret = regulator_set_voltage_tol(cpu_reg, volt,
>> >> tol); if (ret) {
>> >> pr_err("failed to scale voltage up: %d\n",
>> >> ret); return ret;
>> >> }
>> >> + } else if (!IS_ERR(cpu_reg) && old_freq < safe_frequency) {
>> >> + /*
>> >> + * the scaled up voltage level for the new_freq is
>> >> lower
>> >> + * than the safe voltage level. so set safe_voltage
>> >> + * as the intermediate voltage level and revert it
>> >> + * back after the frequency has been changed.
>> >> + */
>> >> + ret = regulator_set_voltage_tol(cpu_reg,
>> >> safe_voltage, tol);
>> >> + if (ret) {
>> >> + pr_err("failed to set safe voltage: %d\n",
>> >> ret);
>> >> + return ret;
>> >> + }
>> >> }
>> >>
>> >> ret = clk_set_rate(cpu_clk, freq_exact);
>> >> @@ -86,7 +101,8 @@ static int cpu0_set_target(struct
>> >> cpufreq_policy *policy, unsigned int index) }
>> >>
>> >> /* scaling down? scale voltage after frequency */
>> >> - if (!IS_ERR(cpu_reg) && new_freq < old_freq) {
>> >> + if (!IS_ERR(cpu_reg) &&
>> >> + (new_freq < old_freq || new_freq <
>> >> safe_frequency)) { ret = regulator_set_voltage_tol(cpu_reg, volt,
>> >> tol); if (ret) {
>> >> pr_err("failed to scale voltage down:
>> >> %d\n", ret); @@ -116,6 +132,8 @@ static struct cpufreq_driver
>> >> cpu0_cpufreq_driver = {
>> >>
>> >> static int cpu0_cpufreq_probe(struct platform_device *pdev)
>> >> {
>> >> + const struct property *prop;
>> >> + struct dev_pm_opp *opp;
>> >> struct device_node *np;
>> >> int ret;
>> >>
>> >> @@ -165,13 +183,24 @@ static int cpu0_cpufreq_probe(struct
>> >> platform_device *pdev) goto out_put_node;
>> >> }
>> >>
>> >> + prop = of_find_property(np, "safe-opp", NULL);
>> >> + if (prop) {
>> >> + if (prop->value && (prop->length / sizeof(u32)) ==
>> >> 2) {
>> >> + const __be32 *val;
>> >> + val = prop->value;
>> >> + safe_frequency = be32_to_cpup(val++);
>> >> + safe_voltage = be32_to_cpup(val);
>> >> + } else {
>> >> + pr_err("invalid safe-opp level
>> >> specified\n");
>> >> + }
>> >> + }
>> >> +
>> >> of_property_read_u32(np, "voltage-tolerance",
>> >> &voltage_tolerance);
>> >>
>> >> if (of_property_read_u32(np, "clock-latency",
>> >> &transition_latency)) transition_latency = CPUFREQ_ETERNAL;
>> >>
>> >> if (!IS_ERR(cpu_reg)) {
>> >> - struct dev_pm_opp *opp;
>> >> unsigned long min_uV, max_uV;
>> >> int i;
>> >>
>> >> --
>> >> 1.6.6.rc2
>> >>
>
>
>
> --
> Best regards,
>
> Lukasz Majewski
>
> Samsung R&D Institute Poland (SRPOL) | Linux Platform Group
Thanks for your comments Lukasz.
Regards,
Thomas.
^ permalink raw reply
* [PATCH 1/6] arm64: Add macros to manage processor debug state
From: Vijay Kilari @ 2014-01-28 11:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140124163920.GI31040@mudshark.cambridge.arm.com>
Hi Wiil,
On Fri, Jan 24, 2014 at 10:09 PM, Will Deacon <will.deacon@arm.com> wrote:
> Hello,
>
> On Thu, Jan 23, 2014 at 03:29:07PM +0000, vijay.kilari at gmail.com wrote:
>> From: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
>>
>> Add macros to enable and disable to manage PSTATE.D
>> for debugging. The macros local_dbg_save and local_dbg_restore
>> are moved to irqflags.h file
>>
>> KGDB boot tests fail because of PSTATE.D is masked.
>> unmask it for debugging support
>>
>> Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
>> ---
>> arch/arm64/include/asm/debug-monitors.h | 17 -----------
>> arch/arm64/include/asm/irqflags.h | 48 +++++++++++++++++++++++++++++++
>> arch/arm64/kernel/debug-monitors.c | 1 +
>> 3 files changed, 49 insertions(+), 17 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/debug-monitors.h b/arch/arm64/include/asm/debug-monitors.h
>> index 6231479..ee9f28e 100644
>> --- a/arch/arm64/include/asm/debug-monitors.h
>> +++ b/arch/arm64/include/asm/debug-monitors.h
>> @@ -43,23 +43,6 @@ enum debug_el {
>> #ifndef __ASSEMBLY__
>> struct task_struct;
>>
>> -#define local_dbg_save(flags) \
>> - do { \
>> - typecheck(unsigned long, flags); \
>> - asm volatile( \
>> - "mrs %0, daif // local_dbg_save\n" \
>> - "msr daifset, #8" \
>> - : "=r" (flags) : : "memory"); \
>> - } while (0)
>> -
>> -#define local_dbg_restore(flags) \
>> - do { \
>> - typecheck(unsigned long, flags); \
>> - asm volatile( \
>> - "msr daif, %0 // local_dbg_restore\n" \
>> - : : "r" (flags) : "memory"); \
>> - } while (0)
>> -
>> #define DBG_ARCH_ID_RESERVED 0 /* In case of ptrace ABI updates. */
>>
>> #define DBG_HOOK_HANDLED 0
>> diff --git a/arch/arm64/include/asm/irqflags.h b/arch/arm64/include/asm/irqflags.h
>> index b2fcfbc..f9b013e 100644
>> --- a/arch/arm64/include/asm/irqflags.h
>> +++ b/arch/arm64/include/asm/irqflags.h
>> @@ -90,5 +90,53 @@ static inline int arch_irqs_disabled_flags(unsigned long flags)
>> return flags & PSR_I_BIT;
>> }
>>
>> +/*
>> + * save and restore debug state
>> + */
>> +static inline unsigned long arch_local_dbg_save(void)
>> +{
>> + unsigned long flags;
>> + asm volatile(
>> + "mrs %0, daif // arch_local_dbg_save"
>> + "msr daifset, #8"
>> + : "=r" (flags) : : "memory");
>> + return flags;
>> +}
>> +
>> +static inline void arch_local_dbg_restore(unsigned long flags)
>> +{
>> + asm volatile(
>> + "msr daif, %0 // arch_local_dbg_restore"
>> + :
>> + : "r" (flags)
>> + : "memory");
>> +}
>> +
>> +#define raw_local_dbg_save(flags) \
>> + do { \
>> + typecheck(unsigned long, flags); \
>> + flags = arch_local_dbg_save(); \
>> + } while (0)
>> +
>> +#define raw_local_dbg_restore(flags) \
>> + do { \
>> + typecheck(unsigned long, flags); \
>> + arch_local_dbg_restore(flags); \
>> + } while (0)
>> +
>> +#define local_dbg_save(flags) \
>> + do { \
>> + raw_local_dbg_save(flags); \
>> + } while (0)
>> +
>> +#define local_dbg_restore(flags) \
>> + do { \
>> + typecheck(unsigned long, flags); \
>> + raw_local_dbg_restore(flags); \
>> + } while (0)
>
> Hehe, I think you took me a bit too literally when I said to follow what we
> do for irqs. This code is arm64-specific, so you don't need to construct it
> in the same way. All you need to do is *move* the existing code from
> debug-monitors.h to irqflags.h. That's it!
>
I have reposted the patch (v9) please review.
>> +#define local_dbg_enable() asm("msr daifclr, #8" : : : "memory")
>> +#define local_dbg_disable() asm("msr daifset, #8" : : : "memory")
>
> I'm also fine with adding these two.
>
> Will
^ permalink raw reply
* [Patch v3 2/2] dmaengine: qcom_bam_dma: Add device tree binding
From: Vinod Koul @ 2014-01-28 11:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140128111756.GE15937@n2100.arm.linux.org.uk>
On Tue, Jan 28, 2014 at 11:17:57AM +0000, Russell King - ARM Linux wrote:
> On Tue, Jan 28, 2014 at 10:16:53AM +0100, Arnd Bergmann wrote:
> > On Tuesday 28 January 2014 10:05:35 Lars-Peter Clausen wrote:
> > > Why does the direction needs to be specified in specifier? I see two
> > > options, either the direction per is fixed in hardware. In that case the DMA
> > > controller node should describe which channel is which direction. Or the
> > > direction is not fixed in hardware and can be changed at runtime in which
> > > case it should be set on a per descriptor basis.
> >
> > Normally the direction is implied by dmaengine_slave_config().
>
> No. The direction argument in there is deprecated - we've been talking
> about removing it for some time.
>
> DMA engine drivers should store all parameters of the configuration, and
> then select the appropriate ones when preparing a transfer (which itself
> involves a direction.)
Right all the prep_ calls for slave cases have explcit direction argument so
sending it using slave config makes no sense. So will remove it after the merge
window closes and fix :)
--
~Vinod
>
> Not doing this implies that if you have a half-duplex device, you have to
> repeatedly issue a dmaengine_slave_config() call, a prepare call, and a
> submit call to the DMA engine code for every segment you want to transfer.
> We don't need that kind of DMA engine specific behaviour in DMA engine
> users.
>
> --
> FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up. Estimation
> in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
> Estimate before purchase was "up to 13.2Mbit".
> --
> To unsubscribe from this list: send the line "unsubscribe dmaengine" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
^ permalink raw reply
* [PATCH] ARM: dts: imx28-m28cu3: Remove 'reset-active-high'
From: Shawn Guo @ 2014-01-28 11:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390596324-20904-1-git-send-email-festevam@gmail.com>
On Fri, Jan 24, 2014 at 06:45:24PM -0200, Fabio Estevam wrote:
> From: Fabio Estevam <fabio.estevam@freescale.com>
>
> The 'reset-active-high' property is not defined anywhere, so just remove it.
>
> Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Applied, thanks.
^ permalink raw reply
* [RFC PATCH 2/3] ARM/ARM64: KVM: Add support for PSCI v0.2 emulation
From: Marc Zyngier @ 2014-01-28 11:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390309301-28424-3-git-send-email-anup.patel@linaro.org>
Hi Anup,
On 21/01/14 13:01, Anup Patel wrote:
> Currently, the in-kernel PSCI emulation provides PSCI v0.1 interface to
> VCPUs. This patch extends current in-kernel PSCI emulation to provide
> PSCI v0.2 interface to VCPUs.
>
> By default, ARM/ARM64 KVM will always provide PSCI v0.1 interface for
> keeping the ABI backward-compatible.
>
> To select PSCI v0.2 interface for VCPUs, the user space (i.e. QEMU or
> KVMTOOL) will have to set KVM_ARM_VCPU_PSCI_0_2 feature when doing VCPU
> init using KVM_ARM_VCPU_INIT ioctl.
>
> Signed-off-by: Anup Patel <anup.patel@linaro.org>
> Signed-off-by: Pranavkumar Sawargaonkar <pranavkumar@linaro.org>
> ---
> arch/arm/include/asm/kvm_host.h | 2 +-
> arch/arm/include/uapi/asm/kvm.h | 39 ++++++++++++++++--
> arch/arm/kvm/arm.c | 6 ++-
> arch/arm/kvm/psci.c | 79 ++++++++++++++++++++++++++++++-------
> arch/arm64/include/asm/kvm_host.h | 2 +-
> arch/arm64/include/uapi/asm/kvm.h | 39 ++++++++++++++++--
> 6 files changed, 143 insertions(+), 24 deletions(-)
>
> diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
> index 8a6f6db..0239ac5 100644
> --- a/arch/arm/include/asm/kvm_host.h
> +++ b/arch/arm/include/asm/kvm_host.h
> @@ -36,7 +36,7 @@
> #define KVM_COALESCED_MMIO_PAGE_OFFSET 1
> #define KVM_HAVE_ONE_REG
>
> -#define KVM_VCPU_MAX_FEATURES 1
> +#define KVM_VCPU_MAX_FEATURES 2
>
> #include <kvm/arm_vgic.h>
>
> diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
> index c498b60..d9eb74c 100644
> --- a/arch/arm/include/uapi/asm/kvm.h
> +++ b/arch/arm/include/uapi/asm/kvm.h
> @@ -83,6 +83,7 @@ struct kvm_regs {
> #define KVM_VGIC_V2_CPU_SIZE 0x2000
>
> #define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
> +#define KVM_ARM_VCPU_PSCI_0_2 1 /* CPU uses PSCI v0.2 */
>
> struct kvm_vcpu_init {
> __u32 target;
> @@ -164,7 +165,7 @@ struct kvm_arch_memory_slot {
> /* Highest supported SPI, from VGIC_NR_IRQS */
> #define KVM_ARM_IRQ_GIC_MAX 127
>
> -/* PSCI interface */
> +/* PSCI v0.1 interface */
> #define KVM_PSCI_FN_BASE 0x95c1ba5e
> #define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n))
>
> @@ -173,9 +174,41 @@ struct kvm_arch_memory_slot {
> #define KVM_PSCI_FN_CPU_ON KVM_PSCI_FN(2)
> #define KVM_PSCI_FN_MIGRATE KVM_PSCI_FN(3)
>
> +/* PSCI v0.2 interface */
> +#define KVM_PSCI_0_2_FN_BASE 0x84000000
> +#define KVM_PSCI_0_2_FN(n) (KVM_PSCI_0_2_FN_BASE + (n))
> +#define KVM_PSCI_0_2_FN64_BASE 0xC4000000
> +#define KVM_PSCI_0_2_FN64(n) (KVM_PSCI_0_2_FN64_BASE + (n))
> +
> +#define KVM_PSCI_0_2_FN_PSCI_VERSION KVM_PSCI_0_2_FN(0)
> +#define KVM_PSCI_0_2_FN_CPU_SUSPEND KVM_PSCI_0_2_FN(1)
> +#define KVM_PSCI_0_2_FN_CPU_OFF KVM_PSCI_0_2_FN(2)
> +#define KVM_PSCI_0_2_FN_CPU_ON KVM_PSCI_0_2_FN(3)
> +#define KVM_PSCI_0_2_FN_AFFINITY_INFO KVM_PSCI_0_2_FN(4)
> +#define KVM_PSCI_0_2_FN_MIGRATE KVM_PSCI_0_2_FN(5)
> +#define KVM_PSCI_0_2_FN_MIGRATE_INFO_TYPE \
> + KVM_PSCI_0_2_FN(6)
> +#define KVM_PSCI_0_2_FN_MIGRATE_INFO_UP_CPU \
> + KVM_PSCI_0_2_FN(7)
> +#define KVM_PSCI_0_2_FN_SYSTEM_OFF KVM_PSCI_0_2_FN(8)
> +#define KVM_PSCI_0_2_FN_SYSTEM_RESET KVM_PSCI_0_2_FN(9)
> +
> +#define KVM_PSCI_0_2_FN64_CPU_SUSPEND KVM_PSCI_0_2_FN64(1)
> +#define KVM_PSCI_0_2_FN64_CPU_ON KVM_PSCI_0_2_FN64(3)
> +#define KVM_PSCI_0_2_FN64_AFFINITY_INFO KVM_PSCI_0_2_FN64(4)
> +#define KVM_PSCI_0_2_FN64_MIGRATE KVM_PSCI_0_2_FN64(5)
> +#define KVM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU \
> + KVM_PSCI_0_2_FN64(7)
> +
> +/* PSCI return values */
> #define KVM_PSCI_RET_SUCCESS 0
> -#define KVM_PSCI_RET_NI ((unsigned long)-1)
> -#define KVM_PSCI_RET_INVAL ((unsigned long)-2)
This is a massive no-no. It is already part of the userspace API, and we
cannot break it (neither arm nor arm64). These #defines have to stay
forever.
> +#define KVM_PSCI_RET_NOT_SUPPORTED ((unsigned long)-1)
> +#define KVM_PSCI_RET_INVALID_PARAMS ((unsigned long)-2)
As such, you can drop these two defines, and use the original ones in
your new code, which will reduce the churn.
> #define KVM_PSCI_RET_DENIED ((unsigned long)-3)
> +#define KVM_PSCI_RET_ALREADY_ON ((unsigned long)-4)
> +#define KVM_PSCI_RET_ON_PENDING ((unsigned long)-5)
> +#define KVM_PSCI_RET_INTERNAL_FAILURE ((unsigned long)-6)
> +#define KVM_PSCI_RET_NOT_PRESENT ((unsigned long)-7)
> +#define KVM_PSCI_RET_DISABLED ((unsigned long)-8)
>
> #endif /* __ARM_KVM_H__ */
> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> index 2a700e0..0b7817a 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -193,6 +193,7 @@ int kvm_dev_ioctl_check_extension(long ext)
> case KVM_CAP_DESTROY_MEMORY_REGION_WORKS:
> case KVM_CAP_ONE_REG:
> case KVM_CAP_ARM_PSCI:
> + case KVM_CAP_ARM_PSCI_0_2:
> r = 1;
> break;
> case KVM_CAP_COALESCED_MMIO:
> @@ -483,7 +484,10 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
> * PSCI code.
> */
> if (test_and_clear_bit(KVM_ARM_VCPU_POWER_OFF, vcpu->arch.features)) {
> - *vcpu_reg(vcpu, 0) = KVM_PSCI_FN_CPU_OFF;
> + if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features))
Can you make this a function? Something like:
int get_psci_version(struct kvm_vcpu *vcpu)
{
if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features))
return PSCI_VERSION_0_2;
return PSCI_VERSION_0_1;
}
probably located in psci.c. This way, when PSCI version 3.14159 comes
along, we'll have some mechanism in place, and we're free to change the
detection method without impacting the rest of the code.
> + *vcpu_reg(vcpu, 0) = KVM_PSCI_0_2_FN_CPU_OFF;
> + else
> + *vcpu_reg(vcpu, 0) = KVM_PSCI_FN_CPU_OFF;
> kvm_psci_call(vcpu);
> }
>
> diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c
> index 0881bf1..ee044a3 100644
> --- a/arch/arm/kvm/psci.c
> +++ b/arch/arm/kvm/psci.c
> @@ -55,13 +55,13 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
> }
>
> if (!vcpu)
> - return KVM_PSCI_RET_INVAL;
> + return KVM_PSCI_RET_INVALID_PARAMS;
>
> target_pc = *vcpu_reg(source_vcpu, 2);
>
> wq = kvm_arch_vcpu_wq(vcpu);
> if (!waitqueue_active(wq))
> - return KVM_PSCI_RET_INVAL;
> + return KVM_PSCI_RET_INVALID_PARAMS;
>
> kvm_reset_vcpu(vcpu);
>
> @@ -84,17 +84,49 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
> return KVM_PSCI_RET_SUCCESS;
> }
>
> -/**
> - * kvm_psci_call - handle PSCI call if r0 value is in range
> - * @vcpu: Pointer to the VCPU struct
> - *
> - * Handle PSCI calls from guests through traps from HVC instructions.
> - * The calling convention is similar to SMC calls to the secure world where
> - * the function number is placed in r0 and this function returns true if the
> - * function number specified in r0 is withing the PSCI range, and false
> - * otherwise.
> - */
> -bool kvm_psci_call(struct kvm_vcpu *vcpu)
> +static bool kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
> +{
> + unsigned long psci_fn = *vcpu_reg(vcpu, 0) & ~((u32) 0);
> + unsigned long val;
> +
> + switch (psci_fn) {
> + case KVM_PSCI_0_2_FN_PSCI_VERSION:
> + /*
> + * Bits[31:16] = Major Version = 0
> + * Bits[15:0] = Minor Version = 2
> + */
> + val = 2;
> + break;
> + case KVM_PSCI_0_2_FN_CPU_OFF:
> + kvm_psci_vcpu_off(vcpu);
> + val = KVM_PSCI_RET_SUCCESS;
> + break;
> + case KVM_PSCI_0_2_FN_CPU_ON:
> + case KVM_PSCI_0_2_FN64_CPU_ON:
> + val = kvm_psci_vcpu_on(vcpu);
> + break;
> + case KVM_PSCI_0_2_FN_CPU_SUSPEND:
> + case KVM_PSCI_0_2_FN_AFFINITY_INFO:
> + case KVM_PSCI_0_2_FN_MIGRATE:
> + case KVM_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
> + case KVM_PSCI_0_2_FN_MIGRATE_INFO_UP_CPU:
> + case KVM_PSCI_0_2_FN_SYSTEM_OFF:
> + case KVM_PSCI_0_2_FN_SYSTEM_RESET:
> + case KVM_PSCI_0_2_FN64_CPU_SUSPEND:
> + case KVM_PSCI_0_2_FN64_AFFINITY_INFO:
> + case KVM_PSCI_0_2_FN64_MIGRATE:
> + case KVM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU:
> + val = KVM_PSCI_RET_NOT_SUPPORTED;
> + break;
> + default:
> + return false;
> + }
> +
> + *vcpu_reg(vcpu, 0) = val;
> + return true;
> +}
> +
> +static bool kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
> {
> unsigned long psci_fn = *vcpu_reg(vcpu, 0) & ~((u32) 0);
> unsigned long val;
> @@ -109,9 +141,8 @@ bool kvm_psci_call(struct kvm_vcpu *vcpu)
> break;
> case KVM_PSCI_FN_CPU_SUSPEND:
> case KVM_PSCI_FN_MIGRATE:
> - val = KVM_PSCI_RET_NI;
> + val = KVM_PSCI_RET_NOT_SUPPORTED;
> break;
> -
> default:
> return false;
> }
> @@ -119,3 +150,21 @@ bool kvm_psci_call(struct kvm_vcpu *vcpu)
> *vcpu_reg(vcpu, 0) = val;
> return true;
> }
> +
> +/**
> + * kvm_psci_call - handle PSCI call if r0 value is in range
> + * @vcpu: Pointer to the VCPU struct
> + *
> + * Handle PSCI calls from guests through traps from HVC instructions.
> + * The calling convention is similar to SMC calls to the secure world where
> + * the function number is placed in r0 and this function returns true if the
> + * function number specified in r0 is withing the PSCI range, and false
> + * otherwise.
> + */
> +bool kvm_psci_call(struct kvm_vcpu *vcpu)
> +{
> + if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features))
> + return kvm_psci_0_2_call(vcpu);
> +
> + return kvm_psci_0_1_call(vcpu);
> +}
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 0a1d697..92242ce 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -39,7 +39,7 @@
> #include <kvm/arm_vgic.h>
> #include <kvm/arm_arch_timer.h>
>
> -#define KVM_VCPU_MAX_FEATURES 2
> +#define KVM_VCPU_MAX_FEATURES 3
>
> struct kvm_vcpu;
> int kvm_target_cpu(void);
> diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
> index d9f026b..0eb254d 100644
> --- a/arch/arm64/include/uapi/asm/kvm.h
> +++ b/arch/arm64/include/uapi/asm/kvm.h
> @@ -77,6 +77,7 @@ struct kvm_regs {
>
> #define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
> #define KVM_ARM_VCPU_EL1_32BIT 1 /* CPU running a 32bit VM */
> +#define KVM_ARM_VCPU_PSCI_0_2 2 /* CPU uses PSCI v0.2 */
>
> struct kvm_vcpu_init {
> __u32 target;
> @@ -150,7 +151,7 @@ struct kvm_arch_memory_slot {
> /* Highest supported SPI, from VGIC_NR_IRQS */
> #define KVM_ARM_IRQ_GIC_MAX 127
>
> -/* PSCI interface */
> +/* PSCI v0.1 interface */
> #define KVM_PSCI_FN_BASE 0x95c1ba5e
> #define KVM_PSCI_FN(n) (KVM_PSCI_FN_BASE + (n))
>
> @@ -159,10 +160,42 @@ struct kvm_arch_memory_slot {
> #define KVM_PSCI_FN_CPU_ON KVM_PSCI_FN(2)
> #define KVM_PSCI_FN_MIGRATE KVM_PSCI_FN(3)
>
> +/* PSCI v0.2 interface */
> +#define KVM_PSCI_0_2_FN_BASE 0x84000000
> +#define KVM_PSCI_0_2_FN(n) (KVM_PSCI_0_2_FN_BASE + (n))
> +#define KVM_PSCI_0_2_FN64_BASE 0xC4000000
> +#define KVM_PSCI_0_2_FN64(n) (KVM_PSCI_0_2_FN64_BASE + (n))
> +
> +#define KVM_PSCI_0_2_FN_PSCI_VERSION KVM_PSCI_0_2_FN(0)
> +#define KVM_PSCI_0_2_FN_CPU_SUSPEND KVM_PSCI_0_2_FN(1)
> +#define KVM_PSCI_0_2_FN_CPU_OFF KVM_PSCI_0_2_FN(2)
> +#define KVM_PSCI_0_2_FN_CPU_ON KVM_PSCI_0_2_FN(3)
> +#define KVM_PSCI_0_2_FN_AFFINITY_INFO KVM_PSCI_0_2_FN(4)
> +#define KVM_PSCI_0_2_FN_MIGRATE KVM_PSCI_0_2_FN(5)
> +#define KVM_PSCI_0_2_FN_MIGRATE_INFO_TYPE \
> + KVM_PSCI_0_2_FN(6)
> +#define KVM_PSCI_0_2_FN_MIGRATE_INFO_UP_CPU \
> + KVM_PSCI_0_2_FN(7)
> +#define KVM_PSCI_0_2_FN_SYSTEM_OFF KVM_PSCI_0_2_FN(8)
> +#define KVM_PSCI_0_2_FN_SYSTEM_RESET KVM_PSCI_0_2_FN(9)
> +
> +#define KVM_PSCI_0_2_FN64_CPU_SUSPEND KVM_PSCI_0_2_FN64(1)
> +#define KVM_PSCI_0_2_FN64_CPU_ON KVM_PSCI_0_2_FN64(3)
> +#define KVM_PSCI_0_2_FN64_AFFINITY_INFO KVM_PSCI_0_2_FN64(4)
> +#define KVM_PSCI_0_2_FN64_MIGRATE KVM_PSCI_0_2_FN64(5)
> +#define KVM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU \
> + KVM_PSCI_0_2_FN64(7)
> +
> +/* PSCI return values */
> #define KVM_PSCI_RET_SUCCESS 0
> -#define KVM_PSCI_RET_NI ((unsigned long)-1)
> -#define KVM_PSCI_RET_INVAL ((unsigned long)-2)
> +#define KVM_PSCI_RET_NOT_SUPPORTED ((unsigned long)-1)
> +#define KVM_PSCI_RET_INVALID_PARAMS ((unsigned long)-2)
> #define KVM_PSCI_RET_DENIED ((unsigned long)-3)
> +#define KVM_PSCI_RET_ALREADY_ON ((unsigned long)-4)
> +#define KVM_PSCI_RET_ON_PENDING ((unsigned long)-5)
> +#define KVM_PSCI_RET_INTERNAL_FAILURE ((unsigned long)-6)
> +#define KVM_PSCI_RET_NOT_PRESENT ((unsigned long)-7)
> +#define KVM_PSCI_RET_DISABLED ((unsigned long)-8)
>
> #endif
>
> --
> 1.7.9.5
With the above remarks fixed, I think we'll have a good base for future
developments. Looking forward to the next version.
Thanks,
M.
--
Jazz is not dead. It just smells funny...
^ permalink raw reply
* [PATCH 2/9] ARM: dts: imx6sl: remove the use of pingrp macros
From: Shawn Guo @ 2014-01-28 11:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <5923680.sl3G3EgCsY@phil>
On Tue, Jan 28, 2014 at 11:17:22AM +0100, Heiko St?bner wrote:
> [... and so on for the other groups ... ]
>
> I'm confused now :-) . Current linux-next [0] shows the pin-settings as part
> of imx6sl.dtsi - a way a lot of other architectures organize their pingroups
> too, with the board file only referencing the relevant pingroups from the
> predefined ones of the soc.
>
> So I guess your move to the pingrp-header moved them out of the imx6sl.dtsi to
> the .h and is not part of linux-next;
Yes, my for-next branch was excluded from linux-next temporarily for
some reason. I will ask Stephen to add it back once v3.14-rc1 is out.
That said, you can see nothing we developed in this cycle on linux-next
for now.
> but this patch (and the others in this
> series) now moves the definitions into the individual board files. Can't you
> just move them back to the soc-dtsi files to prevent each board duplicating
> them?
No. That will bring back the problem we try to solve from the
beginning [1].
Shawn
[1] http://thread.gmane.org/gmane.linux.ports.arm.kernel/275912/
^ permalink raw reply
* [PATCH v9 6/6] arm64: KGDB: Add KGDB config
From: vijay.kilari at gmail.com @ 2014-01-28 11:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390908022-10287-1-git-send-email-vijay.kilari@gmail.com>
From: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
Add HAVE_ARCH_KGDB for arm64 Kconfig
Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
---
arch/arm64/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 6d4dd22..c7a08e0 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -28,6 +28,7 @@ config ARM64
select HAVE_HW_BREAKPOINT if PERF_EVENTS
select HAVE_MEMBLOCK
select HAVE_PERF_EVENTS
+ select HAVE_ARCH_KGDB
select IRQ_DOMAIN
select MODULES_USE_ELF_RELA
select NO_BOOTMEM
--
1.7.9.5
^ permalink raw reply related
* [PATCH v9 5/6] misc: debug: remove compilation warnings
From: vijay.kilari at gmail.com @ 2014-01-28 11:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390908022-10287-1-git-send-email-vijay.kilari@gmail.com>
From: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
typecast instruction_pointer macro to unsigned long to
resolve following compiler warnings like
warning: format '%lx' expects argument of type 'long unsigned int',
but argument 2 has type 'u64' [-Wformat]
Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
---
arch/arm64/include/asm/ptrace.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index 0e7fa49..5233966 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -164,7 +164,7 @@ static inline int valid_user_regs(struct user_pt_regs *regs)
return 0;
}
-#define instruction_pointer(regs) (regs)->pc
+#define instruction_pointer(regs) ((unsigned long)(regs)->pc)
#ifdef CONFIG_SMP
extern unsigned long profile_pc(struct pt_regs *regs);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v9 4/6] KGDB: make kgdb_breakpoint() as noinline
From: vijay.kilari at gmail.com @ 2014-01-28 11:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390908022-10287-1-git-send-email-vijay.kilari@gmail.com>
From: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
The function kgdb_breakpoint() sets up break point at
compile time by calling arch_kgdb_breakpoint();
Though this call is surrounded by wmb() barrier,
the compile can still re-order the break point,
because this scheduling barrier is not a code motion
barrier in gcc.
Making kgdb_breakpoint() as noinline solves this problem
of code reording around break point instruction and also
avoids problem of being called as inline function from
other places
More details about discussion on this can be found here
http://comments.gmane.org/gmane.linux.ports.arm.kernel/269732
Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
Acked-by: Will Deacon <will.deacon@arm.com>
Acked-by: Jason Wessel <jason.wessel@windriver.com>
---
kernel/debug/debug_core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c
index 7d2f35e..cf04798 100644
--- a/kernel/debug/debug_core.c
+++ b/kernel/debug/debug_core.c
@@ -1034,7 +1034,7 @@ int dbg_io_get_char(void)
* otherwise as a quick means to stop program execution and "break" into
* the debugger.
*/
-void kgdb_breakpoint(void)
+noinline void kgdb_breakpoint(void)
{
atomic_inc(&kgdb_setting_breakpoint);
wmb(); /* Sync point before breakpoint */
--
1.7.9.5
^ permalink raw reply related
* [PATCH v9 3/6] arm64: KGDB: Add step debugging support
From: vijay.kilari at gmail.com @ 2014-01-28 11:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390908022-10287-1-git-send-email-vijay.kilari@gmail.com>
From: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
Add KGDB software step debugging support for EL1 debug
in AArch64 mode.
KGDB registers step debug handler with debug monitor.
On receiving 'step' command from GDB tool, target enables
software step debugging and step address is updated in ELR.
Software Step debugging is disabled when 'continue' command
is received
Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
Reviewed-by: Will Deacon <will.deacon@arm.com>
---
arch/arm64/kernel/kgdb.c | 64 ++++++++++++++++++++++++++++++++++++++++------
1 file changed, 56 insertions(+), 8 deletions(-)
diff --git a/arch/arm64/kernel/kgdb.c b/arch/arm64/kernel/kgdb.c
index 4b7a569..75c9cf1 100644
--- a/arch/arm64/kernel/kgdb.c
+++ b/arch/arm64/kernel/kgdb.c
@@ -137,13 +137,26 @@ void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
static int compiled_break;
+static void kgdb_arch_update_addr(struct pt_regs *regs,
+ char *remcom_in_buffer)
+{
+ unsigned long addr;
+ char *ptr;
+
+ ptr = &remcom_in_buffer[1];
+ if (kgdb_hex2long(&ptr, &addr))
+ kgdb_arch_set_pc(regs, addr);
+ else if (compiled_break == 1)
+ kgdb_arch_set_pc(regs, regs->pc + 4);
+
+ compiled_break = 0;
+}
+
int kgdb_arch_handle_exception(int exception_vector, int signo,
int err_code, char *remcom_in_buffer,
char *remcom_out_buffer,
struct pt_regs *linux_regs)
{
- unsigned long addr;
- char *ptr;
int err;
switch (remcom_in_buffer[0]) {
@@ -162,13 +175,36 @@ int kgdb_arch_handle_exception(int exception_vector, int signo,
* to the next instruction else we will just breakpoint
* over and over again.
*/
- ptr = &remcom_in_buffer[1];
- if (kgdb_hex2long(&ptr, &addr))
- kgdb_arch_set_pc(linux_regs, addr);
- else if (compiled_break == 1)
- kgdb_arch_set_pc(linux_regs, linux_regs->pc + 4);
+ kgdb_arch_update_addr(linux_regs, remcom_in_buffer);
+ atomic_set(&kgdb_cpu_doing_single_step, -1);
+ kgdb_single_step = 0;
+
+ /*
+ * Received continue command, disable single step
+ */
+ if (kernel_active_single_step())
+ kernel_disable_single_step();
+
+ err = 0;
+ break;
+ case 's':
+ /*
+ * Update step address value with address passed
+ * with step packet.
+ * On debug exception return PC is copied to ELR
+ * So just update PC.
+ * If no step address is passed, resume from the address
+ * pointed by PC. Do not update PC
+ */
+ kgdb_arch_update_addr(linux_regs, remcom_in_buffer);
+ atomic_set(&kgdb_cpu_doing_single_step, raw_smp_processor_id());
+ kgdb_single_step = 1;
- compiled_break = 0;
+ /*
+ * Enable single step handling
+ */
+ if (!kernel_active_single_step())
+ kernel_enable_single_step(linux_regs);
err = 0;
break;
default:
@@ -191,6 +227,12 @@ static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int esr)
return 0;
}
+static int kgdb_step_brk_fn(struct pt_regs *regs, unsigned int esr)
+{
+ kgdb_handle_exception(1, SIGTRAP, 0, regs);
+ return 0;
+}
+
static struct break_hook kgdb_brkpt_hook = {
.esr_mask = 0xffffffff,
.esr_val = DBG_ESR_VAL_BRK(KGDB_DYN_DGB_BRK_IMM),
@@ -203,6 +245,10 @@ static struct break_hook kgdb_compiled_brkpt_hook = {
.fn = kgdb_compiled_brk_fn
};
+static struct step_hook kgdb_step_hook = {
+ .fn = kgdb_step_brk_fn
+};
+
static void kgdb_call_nmi_hook(void *ignored)
{
kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs());
@@ -259,6 +305,7 @@ int kgdb_arch_init(void)
register_break_hook(&kgdb_brkpt_hook);
register_break_hook(&kgdb_compiled_brkpt_hook);
+ register_step_hook(&kgdb_step_hook);
return 0;
}
@@ -271,6 +318,7 @@ void kgdb_arch_exit(void)
{
unregister_break_hook(&kgdb_brkpt_hook);
unregister_break_hook(&kgdb_compiled_brkpt_hook);
+ unregister_step_hook(&kgdb_step_hook);
unregister_die_notifier(&kgdb_notifier);
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH v9 2/6] arm64: KGDB: Add Basic KGDB support
From: vijay.kilari at gmail.com @ 2014-01-28 11:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390908022-10287-1-git-send-email-vijay.kilari@gmail.com>
From: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
Add KGDB debug support for kernel debugging.
With this patch, basic KGDB debugging is possible.GDB register
layout is updated and GDB tool can establish connection with
target and can set/clear breakpoints.
Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
Reviewed-by: Will Deacon <will.deacon@arm.com>
---
arch/arm64/include/asm/debug-monitors.h | 47 +++++
arch/arm64/include/asm/kgdb.h | 84 +++++++++
arch/arm64/kernel/Makefile | 1 +
arch/arm64/kernel/kgdb.c | 288 +++++++++++++++++++++++++++++++
4 files changed, 420 insertions(+)
diff --git a/arch/arm64/include/asm/debug-monitors.h b/arch/arm64/include/asm/debug-monitors.h
index ee9f28e..6e9b5b3 100644
--- a/arch/arm64/include/asm/debug-monitors.h
+++ b/arch/arm64/include/asm/debug-monitors.h
@@ -26,6 +26,53 @@
#define DBG_ESR_EVT_HWWP 0x2
#define DBG_ESR_EVT_BRK 0x6
+/*
+ * Break point instruction encoding
+ */
+#define BREAK_INSTR_SIZE 4
+
+/*
+ * ESR values expected for dynamic and compile time BRK instruction
+ */
+#define DBG_ESR_VAL_BRK(x) (0xf2000000 | ((x) & 0xfffff))
+
+/*
+ * #imm16 values used for BRK instruction generation
+ * Allowed values for kgbd are 0x400 - 0x7ff
+ * 0x400: for dynamic BRK instruction
+ * 0x401: for compile time BRK instruction
+ */
+#define KGDB_DYN_DGB_BRK_IMM 0x400
+#define KDBG_COMPILED_DBG_BRK_IMM 0x401
+
+/*
+ * BRK instruction encoding
+ * The #imm16 value should be placed at bits[20:5] within BRK ins
+ */
+#define AARCH64_BREAK_MON 0xd4200000
+
+/*
+ * Extract byte from BRK instruction
+ */
+#define KGDB_DYN_DGB_BRK_INS_BYTE(x) \
+ ((((AARCH64_BREAK_MON) & 0xffe0001f) >> (x * 8)) & 0xff)
+
+/*
+ * Extract byte from BRK #imm16
+ */
+#define KGBD_DYN_DGB_BRK_IMM_BYTE(x) \
+ (((((KGDB_DYN_DGB_BRK_IMM) & 0xffff) << 5) >> (x * 8)) & 0xff)
+
+#define KGDB_DYN_DGB_BRK_BYTE(x) \
+ (KGDB_DYN_DGB_BRK_INS_BYTE(x) | KGBD_DYN_DGB_BRK_IMM_BYTE(x))
+
+#define KGDB_DYN_BRK_INS_BYTE0 KGDB_DYN_DGB_BRK_BYTE(0)
+#define KGDB_DYN_BRK_INS_BYTE1 KGDB_DYN_DGB_BRK_BYTE(1)
+#define KGDB_DYN_BRK_INS_BYTE2 KGDB_DYN_DGB_BRK_BYTE(2)
+#define KGDB_DYN_BRK_INS_BYTE3 KGDB_DYN_DGB_BRK_BYTE(3)
+
+#define CACHE_FLUSH_IS_SAFE 1
+
enum debug_el {
DBG_ACTIVE_EL0 = 0,
DBG_ACTIVE_EL1,
diff --git a/arch/arm64/include/asm/kgdb.h b/arch/arm64/include/asm/kgdb.h
new file mode 100644
index 0000000..3c8aafc
--- /dev/null
+++ b/arch/arm64/include/asm/kgdb.h
@@ -0,0 +1,84 @@
+/*
+ * AArch64 KGDB support
+ *
+ * Based on arch/arm/include/kgdb.h
+ *
+ * Copyright (C) 2013 Cavium Inc.
+ * Author: Vijaya Kumar K <vijaya.kumar@caviumnetworks.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.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ARM_KGDB_H
+#define __ARM_KGDB_H
+
+#include <linux/ptrace.h>
+#include <asm/debug-monitors.h>
+
+#ifndef __ASSEMBLY__
+
+static inline void arch_kgdb_breakpoint(void)
+{
+ asm ("brk %0" : : "I" (KDBG_COMPILED_DBG_BRK_IMM));
+}
+
+extern void kgdb_handle_bus_error(void);
+extern int kgdb_fault_expected;
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * gdb is expecting the following registers layout.
+ *
+ * General purpose regs:
+ * r0-r30: 64 bit
+ * sp,pc : 64 bit
+ * pstate : 64 bit
+ * Total: 34
+ * FPU regs:
+ * f0-f31: 128 bit
+ * Total: 32
+ * Extra regs
+ * fpsr & fpcr: 32 bit
+ * Total: 2
+ *
+ */
+
+#define _GP_REGS 34
+#define _FP_REGS 32
+#define _EXTRA_REGS 2
+/*
+ * general purpose registers size in bytes.
+ * pstate is only 4 bytes. subtract 4 bytes
+ */
+#define GP_REG_BYTES (_GP_REGS * 8)
+#define DBG_MAX_REG_NUM (_GP_REGS + _FP_REGS + _EXTRA_REGS)
+
+/*
+ * Size of I/O buffer for gdb packet.
+ * considering to hold all register contents, size is set
+ */
+
+#define BUFMAX 2048
+
+/*
+ * Number of bytes required for gdb_regs buffer.
+ * _GP_REGS: 8 bytes, _FP_REGS: 16 bytes and _EXTRA_REGS: 4 bytes each
+ * GDB fails to connect for size beyond this with error
+ * "'g' packet reply is too long"
+ */
+
+#define NUMREGBYTES ((_GP_REGS * 8) + (_FP_REGS * 16) + \
+ (_EXTRA_REGS * 4))
+
+#endif /* __ASM_KGDB_H */
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 5ba2fd4..b9b87fa 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -18,6 +18,7 @@ arm64-obj-$(CONFIG_SMP) += smp.o smp_spin_table.o
arm64-obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)+= hw_breakpoint.o
arm64-obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+arm64-obj-$(CONFIG_KGDB) += kgdb.o
obj-y += $(arm64-obj-y) vdso/
obj-m += $(arm64-obj-m)
diff --git a/arch/arm64/kernel/kgdb.c b/arch/arm64/kernel/kgdb.c
new file mode 100644
index 0000000..4b7a569
--- /dev/null
+++ b/arch/arm64/kernel/kgdb.c
@@ -0,0 +1,288 @@
+/*
+ * AArch64 KGDB support
+ *
+ * Based on arch/arm/kernel/kgdb.c
+ *
+ * Copyright (C) 2013 Cavium Inc.
+ * Author: Vijaya Kumar K <vijaya.kumar@caviumnetworks.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.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/irq.h>
+#include <linux/kdebug.h>
+#include <linux/kgdb.h>
+#include <asm/traps.h>
+
+struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = {
+ { "x0", 8, offsetof(struct pt_regs, regs[0])},
+ { "x1", 8, offsetof(struct pt_regs, regs[1])},
+ { "x2", 8, offsetof(struct pt_regs, regs[2])},
+ { "x3", 8, offsetof(struct pt_regs, regs[3])},
+ { "x4", 8, offsetof(struct pt_regs, regs[4])},
+ { "x5", 8, offsetof(struct pt_regs, regs[5])},
+ { "x6", 8, offsetof(struct pt_regs, regs[6])},
+ { "x7", 8, offsetof(struct pt_regs, regs[7])},
+ { "x8", 8, offsetof(struct pt_regs, regs[8])},
+ { "x9", 8, offsetof(struct pt_regs, regs[9])},
+ { "x10", 8, offsetof(struct pt_regs, regs[10])},
+ { "x11", 8, offsetof(struct pt_regs, regs[11])},
+ { "x12", 8, offsetof(struct pt_regs, regs[12])},
+ { "x13", 8, offsetof(struct pt_regs, regs[13])},
+ { "x14", 8, offsetof(struct pt_regs, regs[14])},
+ { "x15", 8, offsetof(struct pt_regs, regs[15])},
+ { "x16", 8, offsetof(struct pt_regs, regs[16])},
+ { "x17", 8, offsetof(struct pt_regs, regs[17])},
+ { "x18", 8, offsetof(struct pt_regs, regs[18])},
+ { "x19", 8, offsetof(struct pt_regs, regs[19])},
+ { "x20", 8, offsetof(struct pt_regs, regs[20])},
+ { "x21", 8, offsetof(struct pt_regs, regs[21])},
+ { "x22", 8, offsetof(struct pt_regs, regs[22])},
+ { "x23", 8, offsetof(struct pt_regs, regs[23])},
+ { "x24", 8, offsetof(struct pt_regs, regs[24])},
+ { "x25", 8, offsetof(struct pt_regs, regs[25])},
+ { "x26", 8, offsetof(struct pt_regs, regs[26])},
+ { "x27", 8, offsetof(struct pt_regs, regs[27])},
+ { "x28", 8, offsetof(struct pt_regs, regs[28])},
+ { "x29", 8, offsetof(struct pt_regs, regs[29])},
+ { "x30", 8, offsetof(struct pt_regs, regs[30])},
+ { "sp", 8, offsetof(struct pt_regs, sp)},
+ { "pc", 8, offsetof(struct pt_regs, pc)},
+ { "pstate", 8, offsetof(struct pt_regs, pstate)},
+ { "v0", 16, -1 },
+ { "v1", 16, -1 },
+ { "v2", 16, -1 },
+ { "v3", 16, -1 },
+ { "v4", 16, -1 },
+ { "v5", 16, -1 },
+ { "v6", 16, -1 },
+ { "v7", 16, -1 },
+ { "v8", 16, -1 },
+ { "v9", 16, -1 },
+ { "v10", 16, -1 },
+ { "v11", 16, -1 },
+ { "v12", 16, -1 },
+ { "v13", 16, -1 },
+ { "v14", 16, -1 },
+ { "v15", 16, -1 },
+ { "v16", 16, -1 },
+ { "v17", 16, -1 },
+ { "v18", 16, -1 },
+ { "v19", 16, -1 },
+ { "v20", 16, -1 },
+ { "v21", 16, -1 },
+ { "v22", 16, -1 },
+ { "v23", 16, -1 },
+ { "v24", 16, -1 },
+ { "v25", 16, -1 },
+ { "v26", 16, -1 },
+ { "v27", 16, -1 },
+ { "v28", 16, -1 },
+ { "v29", 16, -1 },
+ { "v30", 16, -1 },
+ { "v31", 16, -1 },
+ { "fpsr", 4, -1 },
+ { "fpcr", 4, -1 },
+};
+
+char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
+{
+ if (regno >= DBG_MAX_REG_NUM || regno < 0)
+ return NULL;
+
+ if (dbg_reg_def[regno].offset != -1)
+ memcpy(mem, (void *)regs + dbg_reg_def[regno].offset,
+ dbg_reg_def[regno].size);
+ else
+ memset(mem, 0, dbg_reg_def[regno].size);
+ return dbg_reg_def[regno].name;
+}
+
+int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
+{
+ if (regno >= DBG_MAX_REG_NUM || regno < 0)
+ return -EINVAL;
+
+ if (dbg_reg_def[regno].offset != -1)
+ memcpy((void *)regs + dbg_reg_def[regno].offset, mem,
+ dbg_reg_def[regno].size);
+ return 0;
+}
+
+void
+sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
+{
+ struct pt_regs *thread_regs;
+
+ /* Initialize to zero */
+ memset((char *)gdb_regs, 0, NUMREGBYTES);
+ thread_regs = task_pt_regs(task);
+ memcpy((void *)gdb_regs, (void *)thread_regs->regs, GP_REG_BYTES);
+}
+
+void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
+{
+ regs->pc = pc;
+}
+
+static int compiled_break;
+
+int kgdb_arch_handle_exception(int exception_vector, int signo,
+ int err_code, char *remcom_in_buffer,
+ char *remcom_out_buffer,
+ struct pt_regs *linux_regs)
+{
+ unsigned long addr;
+ char *ptr;
+ int err;
+
+ switch (remcom_in_buffer[0]) {
+ case 'D':
+ case 'k':
+ /*
+ * Packet D (Detach), k (kill). No special handling
+ * is required here. Handle same as c packet.
+ */
+ case 'c':
+ /*
+ * Packet c (Continue) to continue executing.
+ * Set pc to required address.
+ * Try to read optional parameter and set pc.
+ * If this was a compiled breakpoint, we need to move
+ * to the next instruction else we will just breakpoint
+ * over and over again.
+ */
+ ptr = &remcom_in_buffer[1];
+ if (kgdb_hex2long(&ptr, &addr))
+ kgdb_arch_set_pc(linux_regs, addr);
+ else if (compiled_break == 1)
+ kgdb_arch_set_pc(linux_regs, linux_regs->pc + 4);
+
+ compiled_break = 0;
+ err = 0;
+ break;
+ default:
+ err = -1;
+ }
+ return err;
+}
+
+static int kgdb_brk_fn(struct pt_regs *regs, unsigned int esr)
+{
+ kgdb_handle_exception(1, SIGTRAP, 0, regs);
+ return 0;
+}
+
+static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int esr)
+{
+ compiled_break = 1;
+ kgdb_handle_exception(1, SIGTRAP, 0, regs);
+
+ return 0;
+}
+
+static struct break_hook kgdb_brkpt_hook = {
+ .esr_mask = 0xffffffff,
+ .esr_val = DBG_ESR_VAL_BRK(KGDB_DYN_DGB_BRK_IMM),
+ .fn = kgdb_brk_fn
+};
+
+static struct break_hook kgdb_compiled_brkpt_hook = {
+ .esr_mask = 0xffffffff,
+ .esr_val = DBG_ESR_VAL_BRK(KDBG_COMPILED_DBG_BRK_IMM),
+ .fn = kgdb_compiled_brk_fn
+};
+
+static void kgdb_call_nmi_hook(void *ignored)
+{
+ kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs());
+}
+
+void kgdb_roundup_cpus(unsigned long flags)
+{
+ local_irq_enable();
+ smp_call_function(kgdb_call_nmi_hook, NULL, 0);
+ local_irq_disable();
+}
+
+static int __kgdb_notify(struct die_args *args, unsigned long cmd)
+{
+ struct pt_regs *regs = args->regs;
+
+ if (kgdb_handle_exception(1, args->signr, cmd, regs))
+ return NOTIFY_DONE;
+ return NOTIFY_STOP;
+}
+
+static int
+kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr)
+{
+ unsigned long flags;
+ int ret;
+
+ local_irq_save(flags);
+ ret = __kgdb_notify(ptr, cmd);
+ local_irq_restore(flags);
+
+ return ret;
+}
+
+static struct notifier_block kgdb_notifier = {
+ .notifier_call = kgdb_notify,
+ /*
+ * Want to be lowest priority
+ */
+ .priority = -INT_MAX,
+};
+
+/*
+ * kgdb_arch_init - Perform any architecture specific initalization.
+ * This function will handle the initalization of any architecture
+ * specific callbacks.
+ */
+int kgdb_arch_init(void)
+{
+ int ret = register_die_notifier(&kgdb_notifier);
+
+ if (ret != 0)
+ return ret;
+
+ register_break_hook(&kgdb_brkpt_hook);
+ register_break_hook(&kgdb_compiled_brkpt_hook);
+ return 0;
+}
+
+/*
+ * kgdb_arch_exit - Perform any architecture specific uninitalization.
+ * This function will handle the uninitalization of any architecture
+ * specific callbacks, for dynamic registration and unregistration.
+ */
+void kgdb_arch_exit(void)
+{
+ unregister_break_hook(&kgdb_brkpt_hook);
+ unregister_break_hook(&kgdb_compiled_brkpt_hook);
+ unregister_die_notifier(&kgdb_notifier);
+}
+
+/*
+ * ARM instructions are always in LE.
+ * Break instruction is encoded in LE format
+ */
+struct kgdb_arch arch_kgdb_ops = {
+ .gdb_bpt_instr = {
+ KGDB_DYN_BRK_INS_BYTE0,
+ KGDB_DYN_BRK_INS_BYTE1,
+ KGDB_DYN_BRK_INS_BYTE2,
+ KGDB_DYN_BRK_INS_BYTE3,
+ }
+};
--
1.7.9.5
^ permalink raw reply related
* [PATCH v9 1/6] arm64: Add macros to manage processor debug state
From: vijay.kilari at gmail.com @ 2014-01-28 11:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390908022-10287-1-git-send-email-vijay.kilari@gmail.com>
From: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
Add macros to enable and disable to manage PSTATE.D
for debugging. The macros local_dbg_save and local_dbg_restore
are moved to irqflags.h file
KGDB boot tests fail because of PSTATE.D is masked.
unmask it for debugging support
Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
---
arch/arm64/include/asm/debug-monitors.h | 17 -----------------
arch/arm64/include/asm/irqflags.h | 23 +++++++++++++++++++++++
arch/arm64/kernel/debug-monitors.c | 1 +
3 files changed, 24 insertions(+), 17 deletions(-)
diff --git a/arch/arm64/include/asm/debug-monitors.h b/arch/arm64/include/asm/debug-monitors.h
index 6231479..ee9f28e 100644
--- a/arch/arm64/include/asm/debug-monitors.h
+++ b/arch/arm64/include/asm/debug-monitors.h
@@ -43,23 +43,6 @@ enum debug_el {
#ifndef __ASSEMBLY__
struct task_struct;
-#define local_dbg_save(flags) \
- do { \
- typecheck(unsigned long, flags); \
- asm volatile( \
- "mrs %0, daif // local_dbg_save\n" \
- "msr daifset, #8" \
- : "=r" (flags) : : "memory"); \
- } while (0)
-
-#define local_dbg_restore(flags) \
- do { \
- typecheck(unsigned long, flags); \
- asm volatile( \
- "msr daif, %0 // local_dbg_restore\n" \
- : : "r" (flags) : "memory"); \
- } while (0)
-
#define DBG_ARCH_ID_RESERVED 0 /* In case of ptrace ABI updates. */
#define DBG_HOOK_HANDLED 0
diff --git a/arch/arm64/include/asm/irqflags.h b/arch/arm64/include/asm/irqflags.h
index b2fcfbc..11cc941 100644
--- a/arch/arm64/include/asm/irqflags.h
+++ b/arch/arm64/include/asm/irqflags.h
@@ -90,5 +90,28 @@ static inline int arch_irqs_disabled_flags(unsigned long flags)
return flags & PSR_I_BIT;
}
+/*
+ * save and restore debug state
+ */
+#define local_dbg_save(flags) \
+ do { \
+ typecheck(unsigned long, flags); \
+ asm volatile( \
+ "mrs %0, daif // local_dbg_save\n" \
+ "msr daifset, #8" \
+ : "=r" (flags) : : "memory"); \
+ } while (0)
+
+#define local_dbg_restore(flags) \
+ do { \
+ typecheck(unsigned long, flags); \
+ asm volatile( \
+ "msr daif, %0 // local_dbg_restore\n" \
+ : : "r" (flags) : "memory"); \
+ } while (0)
+
+#define local_dbg_enable() asm("msr daifclr, #8" : : : "memory")
+#define local_dbg_disable() asm("msr daifset, #8" : : : "memory")
+
#endif
#endif
diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c
index 23586bd..a86e5b1 100644
--- a/arch/arm64/kernel/debug-monitors.c
+++ b/arch/arm64/kernel/debug-monitors.c
@@ -138,6 +138,7 @@ static void clear_os_lock(void *unused)
{
asm volatile("msr oslar_el1, %0" : : "r" (0));
isb();
+ local_dbg_enable();
}
static int os_lock_notify(struct notifier_block *self,
--
1.7.9.5
^ permalink raw reply related
* [PATCH v9 0/6] arm64: KGDB Support
From: vijay.kilari at gmail.com @ 2014-01-28 11:20 UTC (permalink / raw)
To: linux-arm-kernel
From: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
Based on the step-handler and break-handler hooks patch from
Sandeepa, KGDB debugging support is added for EL1
debug in AArch64 mode.
In first patch, PSTATE.D is set correctly
In second patch,register layout is updated to be inline with GDB tool.
Basic GDB connection, break point set/clear and info commands
are supported except step/next debugging
With second patch, step/next debugging support is added, where in
pc is updated to point to the instruction to be stepped and
stopped.
With third patch, the compile time breakpoint instruction
reordering is fixed by making kgbd_breakpoint() as noinline
Tested with ARM64 simulator
v9:
- minor code movement comments fix
v8:
- fixed comments on local_dbg_{save,restore} macros
- instruction_pointer() macro to return unsigned long to fix
compilation warnings
v7:
- Changes made to set PSTATE.D properly
- Performed KGDB boot tests
- Fixed compilation warnings in driver/misc/kgbdts.c
Results:
kgdb boot test:
[32927.237895] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
[32927.266066] kgdb: Registered I/O driver kgdbts.
[32927.266419] kgdb: Waiting for connection from remote gdb...
[32927.268598] kgdbts:RUN plant and detach test
[32927.270683] kgdbts:RUN sw breakpoint test
[32927.287659] kgdbts:RUN bad memory access test
[32927.290322] kgdbts:RUN singlestep test 1000 iterations
[32927.330342] kgdbts:RUN singlestep [0/1000]
[32931.286356] kgdbts:RUN singlestep [100/1000]
[32935.242536] kgdbts:RUN singlestep [200/1000]
[32939.205392] kgdbts:RUN singlestep [300/1000]
[32943.169522] kgdbts:RUN singlestep [400/1000]
[32947.231868] kgdbts:RUN singlestep [500/1000]
[32951.188008] kgdbts:RUN singlestep [600/1000]
[32955.332243] kgdbts:RUN singlestep [700/1000]
[32959.467109] kgdbts:RUN singlestep [800/1000]
[32963.430888] kgdbts:RUN singlestep [900/1000]
[32967.346992] kgdbts:RUN do_fork for 100 breakpoints
kgdb test from sysfs:
~ # echo V1F1000 > /sys/module/kgdbts/parameters/kgdbts
[33231.554237] kgdb: Registered I/O driver kgdbts.
[33231.554677] kgdbts:RUN plant and detach test
[33231.557072] kgdbts:RUN sw breakpoint test
[33231.576980] kgdbts:RUN bad memory access test
[33231.580022] kgdbts:RUN singlestep test 1000 iterations
[33231.627056] kgdbts:RUN singlestep [0/1000]
[33235.954027] kgdbts:RUN singlestep [100/1000]
[33240.429086] kgdbts:RUN singlestep [200/1000]
[33244.687118] kgdbts:RUN singlestep [300/1000]
[33248.945191] kgdbts:RUN singlestep [400/1000]
[33253.203751] kgdbts:RUN singlestep [500/1000]
[33257.462019] kgdbts:RUN singlestep [600/1000]
[33261.817809] kgdbts:RUN singlestep [700/1000]
[33266.081268] kgdbts:RUN singlestep [800/1000]
[33270.339813] kgdbts:RUN singlestep [900/1000]
[33274.712404] kgdbts:RUN do_fork for 1000 breakpoints
~ #
v6:
- Change pstate register to 8 bytes to make endian nuetral.
Use GDB below GDB patch to display pstate in Big endian mode.
https://sourceware.org/ml/gdb-patches/2013-12/msg00720.html
Thanks to Andrew.
v5:
- Updated BRK #imm16 value to 0x400 & 0x401 as per recommendation
as per Marcus recommendataion
http://patchwork.ozlabs.org/patch/290801/
- Rebased to 3.13 AArch64 kernel
v4:
- Updated kgdb_single_step and kgdb_cpu_doing_single_step
variables properly based on gdb state
v3:
- Rebased to v4 version of Sandeepa Prabhu's patch (patch 1)
- Made dynamic break point instruction encoding generic
- Made ESR value encoding generic for dynamic and compile break point
- Used memcpy and memset to copy register contents to gdb buffer
- Fixed reordering of break point instruction by compiler with
patch 3
- Rebased against AAach64 upstream kernel
v2:
- Moved break instruction encoding to debug-monitors.h file
- Fixed endianess of compile break instruction encoding
- Updated I/O buffer sizes
- Updated register buffer size
- Remove changes to debug_exception handler in entry.S for
- ELR update and step debugging with update pc instead of ELR
- Rebased against AArch64 upstream kernel
v1:
- Initial patch-set
Vijaya Kumar K (6):
arm64: Add macros to manage processor debug state
arm64: KGDB: Add Basic KGDB support
arm64: KGDB: Add step debugging support
KGDB: make kgdb_breakpoint() as noinline
misc: debug: remove compilation warnings
arm64: KGDB: Add KGDB config
arch/arm64/Kconfig | 1 +
arch/arm64/include/asm/debug-monitors.h | 64 ++++--
arch/arm64/include/asm/irqflags.h | 23 +++
arch/arm64/include/asm/kgdb.h | 84 ++++++++
arch/arm64/include/asm/ptrace.h | 2 +-
arch/arm64/kernel/Makefile | 1 +
arch/arm64/kernel/debug-monitors.c | 1 +
arch/arm64/kernel/kgdb.c | 336 +++++++++++++++++++++++++++++++
kernel/debug/debug_core.c | 2 +-
9 files changed, 495 insertions(+), 19 deletions(-)
create mode 100644 arch/arm64/include/asm/kgdb.h
create mode 100644 arch/arm64/kernel/kgdb.c
--
1.7.9.5
^ permalink raw reply
* [Patch v3 2/2] dmaengine: qcom_bam_dma: Add device tree binding
From: Russell King - ARM Linux @ 2014-01-28 11:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4697306.PPWWh8UGTE@wuerfel>
On Tue, Jan 28, 2014 at 10:16:53AM +0100, Arnd Bergmann wrote:
> On Tuesday 28 January 2014 10:05:35 Lars-Peter Clausen wrote:
> > Why does the direction needs to be specified in specifier? I see two
> > options, either the direction per is fixed in hardware. In that case the DMA
> > controller node should describe which channel is which direction. Or the
> > direction is not fixed in hardware and can be changed at runtime in which
> > case it should be set on a per descriptor basis.
>
> Normally the direction is implied by dmaengine_slave_config().
No. The direction argument in there is deprecated - we've been talking
about removing it for some time.
DMA engine drivers should store all parameters of the configuration, and
then select the appropriate ones when preparing a transfer (which itself
involves a direction.)
Not doing this implies that if you have a half-duplex device, you have to
repeatedly issue a dmaengine_slave_config() call, a prepare call, and a
submit call to the DMA engine code for every segment you want to transfer.
We don't need that kind of DMA engine specific behaviour in DMA engine
users.
--
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up. Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".
^ permalink raw reply
* [alsa-devel] [PATCH 4/4] ASoC: tda998x: adjust the audio hw parameters from EDID
From: Takashi Iwai @ 2014-01-28 11:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140128110051.GI11841@sirena.org.uk>
At Tue, 28 Jan 2014 11:00:51 +0000,
Mark Brown wrote:
>
> On Tue, Jan 28, 2014 at 10:23:57AM +0100, Takashi Iwai wrote:
> > Mark Brown wrote:
> > > On Mon, Jan 27, 2014 at 08:49:15PM +0000, Russell King - ARM Linux wrote:
>
> > > > Yes, preferably as a generic ALSA helper rather than an ASoC helper -
> > > > I don't see any need for this to be ASoC specific (I have a pure ALSA
> > > > driver which has very similar code in it.)
>
> > > Indeed, definitely ALSA generic - ideally we could factor a lot of the
> > > integration with the video side out.
>
> > Yes, indeed.
>
> > OTOH, as discussed recently, we're heading to move from ELD parsing to
> > more direct communication between video and audio drivers for
> > HD-audio. ELD will be still provided to user-space, but not evaluated
> > any longer in the new scenario.
>
> That sort of refactoring being one of the best reasons to keep things
> out of individual drivers! Having said all this I don't know if it's
> worth blocking Jean-Francois' work on that, it's an improvement in
> itself. Splitting the code out a bit would be good to help prepare but
> having the full refactoring done might be too much of a blocker.
I just rather wanted to point out the general direction for the
further development, didn't mean NAK. Jean-Francois' patch itself
looks simple enough, so I see no problem to take it for now as is.
Takashi
^ permalink raw reply
* [PATCH v11] clk: add MOXA ART SoCs clock driver
From: Jonas Jensen @ 2014-01-28 11:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1390308261-4026-1-git-send-email-jonas.jensen@gmail.com>
MOXA ART SoCs allow to determine PLL output and APB frequencies
by reading registers holding multiplier and divisor information.
Add a clock driver for this SoC.
Signed-off-by: Jonas Jensen <jonas.jensen@gmail.com>
---
Notes:
Thanks for the replies,
Changes since v10:
1. add clock-specifier to DT binding description
2. remove local variable "rate"
3. add local variable "parent_name"
4. use clk_register_fixed_factor() instead of clk_register_fixed_rate()
5. remove flag CLK_IS_ROOT
Applies to next-20140128
.../bindings/clock/moxa,moxart-clock.txt | 48 +++++++++++
drivers/clk/Makefile | 1 +
drivers/clk/clk-moxart.c | 97 ++++++++++++++++++++++
3 files changed, 146 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/moxa,moxart-clock.txt
create mode 100644 drivers/clk/clk-moxart.c
diff --git a/Documentation/devicetree/bindings/clock/moxa,moxart-clock.txt b/Documentation/devicetree/bindings/clock/moxa,moxart-clock.txt
new file mode 100644
index 0000000..fedea84
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/moxa,moxart-clock.txt
@@ -0,0 +1,48 @@
+Device Tree Clock bindings for arch-moxart
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+MOXA ART SoCs allow to determine PLL output and APB frequencies
+by reading registers holding multiplier and divisor information.
+
+
+PLL:
+
+Required properties:
+- compatible : Must be "moxa,moxart-pll-clock"
+- #clock-cells : Should be 0
+- reg : Should contain registers location and length
+- clocks : Should contain phandle + clock-specifier for the parent clock
+
+Optional properties:
+- clock-output-names : Should contain clock name
+
+
+APB:
+
+Required properties:
+- compatible : Must be "moxa,moxart-apb-clock"
+- #clock-cells : Should be 0
+- reg : Should contain registers location and length
+- clocks : Should contain phandle + clock-specifier for the parent clock
+
+Optional properties:
+- clock-output-names : Should contain clock name
+
+
+For example:
+
+ clk_pll: clk_pll at 98100000 {
+ compatible = "moxa,moxart-pll-clock";
+ #clock-cells = <0>;
+ reg = <0x98100000 0x34>;
+ };
+
+ clk_apb: clk_apb at 98100000 {
+ compatible = "moxa,moxart-apb-clock";
+ #clock-cells = <0>;
+ reg = <0x98100000 0x34>;
+ clocks = <&clk_pll>;
+ };
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 0faf730..7940d0c 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_COMMON_CLK) += clk-composite.o
# SoCs specific
obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o
obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o
+obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o
obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o
obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o
obj-$(CONFIG_ARCH_HI3xxx) += hisilicon/
diff --git a/drivers/clk/clk-moxart.c b/drivers/clk/clk-moxart.c
new file mode 100644
index 0000000..30a3b69
--- /dev/null
+++ b/drivers/clk/clk-moxart.c
@@ -0,0 +1,97 @@
+/*
+ * MOXA ART SoCs clock driver.
+ *
+ * Copyright (C) 2013 Jonas Jensen
+ *
+ * Jonas Jensen <jonas.jensen@gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/clkdev.h>
+
+void __init moxart_of_pll_clk_init(struct device_node *node)
+{
+ static void __iomem *base;
+ struct clk *clk, *ref_clk;
+ unsigned int mul;
+ const char *name = node->name;
+ const char *parent_name;
+
+ of_property_read_string(node, "clock-output-names", &name);
+ parent_name = of_clk_get_parent_name(node, 0);
+
+ base = of_iomap(node, 0);
+ if (!base) {
+ pr_err("%s: of_iomap failed\n", node->full_name);
+ return;
+ }
+
+ mul = readl(base + 0x30) >> 3 & 0x3f;
+ iounmap(base);
+
+ ref_clk = of_clk_get(node, 0);
+ if (IS_ERR(ref_clk)) {
+ pr_err("%s: of_clk_get failed\n", node->full_name);
+ return;
+ }
+
+ clk = clk_register_fixed_factor(NULL, name, parent_name, 0, mul, 1);
+ if (IS_ERR(clk)) {
+ pr_err("%s: failed to register clock\n", node->full_name);
+ return;
+ }
+
+ clk_register_clkdev(clk, NULL, name);
+ of_clk_add_provider(node, of_clk_src_simple_get, clk);
+}
+CLK_OF_DECLARE(moxart_pll_clock, "moxa,moxart-pll-clock",
+ moxart_of_pll_clk_init);
+
+void __init moxart_of_apb_clk_init(struct device_node *node)
+{
+ static void __iomem *base;
+ struct clk *clk, *pll_clk;
+ unsigned int div, val;
+ unsigned int div_idx[] = { 2, 3, 4, 6, 8};
+ const char *name = node->name;
+ const char *parent_name;
+
+ of_property_read_string(node, "clock-output-names", &name);
+ parent_name = of_clk_get_parent_name(node, 0);
+
+ base = of_iomap(node, 0);
+ if (!base) {
+ pr_err("%s: of_iomap failed\n", node->full_name);
+ return;
+ }
+
+ val = readl(base + 0xc) >> 4 & 0x7;
+ iounmap(base);
+
+ if (val > 4)
+ val = 0;
+ div = div_idx[val] * 2;
+
+ pll_clk = of_clk_get(node, 0);
+ if (IS_ERR(pll_clk)) {
+ pr_err("%s: of_clk_get failed\n", node->full_name);
+ return;
+ }
+
+ clk = clk_register_fixed_factor(NULL, name, parent_name, 0, 1, div);
+ if (IS_ERR(clk)) {
+ pr_err("%s: failed to register clock\n", node->full_name);
+ return;
+ }
+
+ clk_register_clkdev(clk, NULL, name);
+ of_clk_add_provider(node, of_clk_src_simple_get, clk);
+}
+CLK_OF_DECLARE(moxart_apb_clock, "moxa,moxart-apb-clock",
+ moxart_of_apb_clk_init);
--
1.8.2.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