Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] ARM: imx: disable cpu in .cpu_kill hook
From: Shawn Guo @ 2013-01-14 14:23 UTC (permalink / raw)
  To: linux-arm-kernel

It's buggy to disable the cpu that is being hot-unplugged in .cpu_die
hook which runs on the cpu itself.  Instead, it should be done in
.cpu_kill which runs on the thread (another cpu) that asks for shutting
down the cpu.  Move imx_enable_cpu(cpu, false) call into .cpu_kill
hook, and leave the cpu to be hot-unplugged in WFI within .cpu_die,
so that we can get a more stable cpu hot-plug operation.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 arch/arm/mach-imx/common.h  |    1 +
 arch/arm/mach-imx/hotplug.c |   10 ++++++----
 arch/arm/mach-imx/platsmp.c |    1 +
 3 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index 7191ab4..fa36fb8 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -142,6 +142,7 @@ extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode);
 extern void imx6q_clock_map_io(void);
 
 extern void imx_cpu_die(unsigned int cpu);
+extern int imx_cpu_kill(unsigned int cpu);
 
 #ifdef CONFIG_PM
 extern void imx6q_pm_init(void);
diff --git a/arch/arm/mach-imx/hotplug.c b/arch/arm/mach-imx/hotplug.c
index 3dec962..7bc5fe1 100644
--- a/arch/arm/mach-imx/hotplug.c
+++ b/arch/arm/mach-imx/hotplug.c
@@ -46,9 +46,11 @@ static inline void cpu_enter_lowpower(void)
 void imx_cpu_die(unsigned int cpu)
 {
 	cpu_enter_lowpower();
-	imx_enable_cpu(cpu, false);
+	cpu_do_idle();
+}
 
-	/* spin here until hardware takes it down */
-	while (1)
-		;
+int imx_cpu_kill(unsigned int cpu)
+{
+	imx_enable_cpu(cpu, false);
+	return 1;
 }
diff --git a/arch/arm/mach-imx/platsmp.c b/arch/arm/mach-imx/platsmp.c
index 3777b80..66fae88 100644
--- a/arch/arm/mach-imx/platsmp.c
+++ b/arch/arm/mach-imx/platsmp.c
@@ -92,5 +92,6 @@ struct smp_operations  imx_smp_ops __initdata = {
 	.smp_boot_secondary	= imx_boot_secondary,
 #ifdef CONFIG_HOTPLUG_CPU
 	.cpu_die		= imx_cpu_die,
+	.cpu_kill		= imx_cpu_kill,
 #endif
 };
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 0/9] ARM: PRIMA2: bringup new CSR SiRFmarco SMP SoC
From: Barry Song @ 2013-01-14 14:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <201301141107.53449.arnd@arndb.de>

Hi Arnd,
Thanks a lot!

2013/1/14 Arnd Bergmann <arnd@arndb.de>:
> On Sunday 06 January 2013, Barry Song wrote:
>> except those from Mark, would you kindly give more feedbacks about
>> this series? after this, i'd like to send out a series about SiRF
>> firmware based on trustzone.
>
> Hi Barry,
>
> Sorry for the late reply. I have looked at the patches and have no
> further comments besides what Mark already mentioned.
>
> Patch 4/9 will unfortunately conflict with the removal of struct sys_timer,
> but we can probably handle that, or you base your patches on top of
> the timer/cleanup branch in arm-soc.

yes. i have read that sys_timer removing patchset recently. i'll
handle the move directly in v2.

>
>         Arnd

-barry

^ permalink raw reply

* Question: ARM: local timers: add num_possible_cpus() in local_timer_register()
From: steve.zhan @ 2013-01-14 14:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <50F413EA.5010403@arm.com>

Hi,
    Russel, Marc,
2013/1/14 Marc Zyngier <marc.zyngier@arm.com>:
> On 14/01/13 13:33, Steve zhan wrote:
>
> Hi Steve,
>
>>       Do you think we should add num_possible_cpus() in
>> local_timer_register() function, When core number is
>>> 1, then reutrn TRUE? Enable the local timer only if
>> we have more than one CPU, if the current config is
>> SMP and setup_max_cpus >= 1, but if smp_init_cpus in
>> platform code have set cpu possible value to One(that
>> maybe read number from scu or other hardware), then
>> percpu_timer_setup in smp_prepare_cpus have no chance
>> to be called.
>>
>>       For local timer, because local_timer_register have
>> return 1, that will miss global timer register.
>>
>>       Could you pls check it?
>
> I'm not sure I understand your question.
>
> We only enable the use of the SMP local timers infrastructure if we're
> SMP and we have more that one CPU. If you only have one CPU up and
> running, then you can still use your CPU local timer as a global timer.
>
> What would we gain by using the local timer infrastructure when we're
> not running on SMP hardware?
>
>         M.
> --
> Jazz is not dead. It just smells funny...
>

For these code:
        err = local_timer_register(&arch_timer_ops);
        if (err) {
                /*
                 * We couldn't register as a local timer (could be
                 * because we're on a UP platform, or because some
                 * other local timer is already present...). Try as a
                 * global timer instead.
                 */
                arch_timer_global_evt.cpumask = cpumask_of(0);
                err = arch_timer_setup(&arch_timer_global_evt);
        }

if err == 0, we have no register global arch timer,  but platform code
platsmp.c will set
cpu possible number to one, that let percpu_timer_setup in
smp_prepare_cpus have no
chance to call becaue ncores = num_possible_cpus() is one.
Is this right?


-- 
Steve Zhan

^ permalink raw reply

* [PATCH v3] arm: mvebu: add DTS file for Marvell RD-A370-A1 board
From: Florian Fainelli @ 2013-01-14 14:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <3816648.2TVsTiMOWx@bender>

This patch adds the DTS file to support the Marvell RD-A370-A1
(Reference Design board) also known as RD-88F6710 board. It is almost
entirely similar to the DB-A370 except on the following points:

- second Ethernet MAC is connected to a switch using RGMII
- it only has 512MB of physical RAM
- SDIO interface is enabled and working by default (no need for jumpers)

Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
Jason,

This is rebased against your mvebu/for-next branch, can you please drop v2 of
the previous patch and take this one instead? Thanks!

Changes since v2:
- rebased against Jason's mvebu/for-next
- added SDIO bindings
- changed commit message a bit

Changes since v1:
- added missing entry in arch/arm/boot/dts/Makefile to actually build the DTB

 arch/arm/boot/dts/Makefile          |    1 +
 arch/arm/boot/dts/armada-370-rd.dts |   68 +++++++++++++++++++++++++++++++++++
 2 files changed, 69 insertions(+)
 create mode 100644 arch/arm/boot/dts/armada-370-rd.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index b7246d6..7a75171 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -78,6 +78,7 @@ dtb-$(CONFIG_ARCH_MSM) += msm8660-surf.dtb \
 	msm8960-cdp.dtb
 dtb-$(CONFIG_ARCH_MVEBU) += armada-370-db.dtb \
 	armada-370-mirabox.dtb \
+	armada-370-rd.dtb \
 	armada-xp-db.dtb \
 	armada-xp-openblocks-ax3-4.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx51-babbage.dtb \
diff --git a/arch/arm/boot/dts/armada-370-rd.dts b/arch/arm/boot/dts/armada-370-rd.dts
new file mode 100644
index 0000000..f8e4855
--- /dev/null
+++ b/arch/arm/boot/dts/armada-370-rd.dts
@@ -0,0 +1,68 @@
+/*
+ * Device Tree file for Marvell Armada 370 Reference Design board
+ * (RD-88F6710-A1)
+ *
+ *  Copied from arch/arm/boot/dts/armada-370-db.dts
+ *
+ *  Copyright (C) 2013 Florian Fainelli <florian@openwrt.org>
+ *
+ * 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.
+ */
+
+/dts-v1/;
+/include/ "armada-370.dtsi"
+
+/ {
+	model = "Marvell Armada 370 Reference Design";
+	compatible = "marvell,a370-rd", "marvell,armada370", "marvell,armada-370-xp";
+
+	chosen {
+		bootargs = "console=ttyS0,115200 earlyprintk";
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x20000000>; /* 512 MB */
+	};
+
+	soc {
+		serial at d0012000 {
+			clock-frequency = <200000000>;
+			status = "okay";
+		};
+		sata at d00a0000 {
+			nr-ports = <2>;
+			status = "okay";
+		};
+
+		mdio {
+			phy0: ethernet-phy at 0 {
+				reg = <0>;
+			};
+
+			phy1: ethernet-phy at 1 {
+				reg = <1>;
+			};
+		};
+
+		ethernet at d0070000 {
+			status = "okay";
+			phy = <&phy0>;
+			phy-mode = "sgmii";
+		};
+		ethernet at d0074000 {
+			status = "okay";
+			phy = <&phy1>;
+			phy-mode = "rgmii-id";
+		};
+
+		mvsdio at d00d4000 {
+			pinctrl-0 = <&sdio_pins1>;
+			pinctrl-names = "default";
+			status = "okay";
+			/* No CD or WP GPIOs */
+		};
+	};
+};
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH 5/6] ARM: dts: Add basic dts include files for Samsung S3C64xx SoCs
From: Mark Rutland @ 2013-01-14 14:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358039458-31960-6-git-send-email-tomasz.figa@gmail.com>

Hello,

This all looks good. I just have a couple of comments about the cpus node.

On Sun, Jan 13, 2013 at 01:10:57AM +0000, Tomasz Figa wrote:
> This patch adds basic device tree definitions for Samsung S3C64xx SoCs.
> 
> Since all the SoCs in the series are very similar, the files are created
> hierarchically - one file for the whole series and then separate files
> for particular SoCs including the common one.
> 
> Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>

[...]

> diff --git a/arch/arm/boot/dts/s3c64xx.dtsi b/arch/arm/boot/dts/s3c64xx.dtsi
> new file mode 100644
> index 0000000..55d6e08
> --- /dev/null
> +++ b/arch/arm/boot/dts/s3c64xx.dtsi
> @@ -0,0 +1,97 @@
> +/*
> + * Samsung's S3C64xx SoC series common device tree source
> + *
> + * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
> + *
> + * Samsung's S3C64xx SoC series device nodes are listed in this file.
> + * Particular SoCs from S3C64xx series can include this file and provide
> + * values for SoCs specfic bindings.
> + *
> + * Note: This file does not include device nodes for all the controllers in
> + * S3C64xx SoCs. As device tree coverage for S3C64xx increases, additional
> + * nodes can be added to this file.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +/include/ "skeleton.dtsi"
> +
> +/ {
> +	cpus {
> +		cpu at 0 {
> +			compatible = "arm,arm1176jzf-s";
> +		};
> +	};

You can drop the unit address from the cpu node - it's meant to be there to
differentiate multiple nodes (and is supposed to match the reg property, which
the 1176jzf-s can't have, as it doesn't have an MPIDR).

Also, "arm,arm1176jzf-s" isn't listed in the binding doc. There was a question
about how to maintain this list [1], but I can't seem to find a conclusion, if
any were reached.  It might be worth appending "arm,arm1176" to the compatible
list for the cpu node in case we want to enable something via dt for all 1176
variations.

Dave, Lorenzo, any thoughts?

[...]

Thanks,
Mark.

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2012-November/131362.html

^ permalink raw reply

* [PATCH 1/1] ARM: ux500: Disable Power Supply and Battery Management by default
From: Lee Jones @ 2013-01-14 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

The AB8500 Battery Management collection of drivers are more than a
little bit broken. There is lots of work still on-going in that area
and it's improving day by day; however, it's not ready to be enabled
by default just yet.

Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 arch/arm/configs/u8500_defconfig |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig
index 231dca6..426270f 100644
--- a/arch/arm/configs/u8500_defconfig
+++ b/arch/arm/configs/u8500_defconfig
@@ -66,9 +66,9 @@ CONFIG_SPI=y
 CONFIG_SPI_PL022=y
 CONFIG_GPIO_STMPE=y
 CONFIG_GPIO_TC3589X=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_AB8500_BM=y
-CONFIG_AB8500_BATTERY_THERM_ON_BATCTRL=y
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_AB8500_BM is not set
+# CONFIG_AB8500_BATTERY_THERM_ON_BATCTRL is not set
 CONFIG_THERMAL=y
 CONFIG_CPU_THERMAL=y
 CONFIG_MFD_STMPE=y
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v3 0/2] Add imx6q-cpufreq driver support
From: Shawn Guo @ 2013-01-14 15:02 UTC (permalink / raw)
  To: linux-arm-kernel

Changes since v2:
 - Fix typo in commit log
 - Put all OPPs in dts and disable 1.2 GHz one for Si revs that do not
   support it in kernel.

Shawn Guo (2):
  cpufreq: add imx6q-cpufreq driver
  ARM: imx: enable imx6q-cpufreq support

 arch/arm/boot/dts/imx6q.dtsi    |   20 ++-
 arch/arm/mach-imx/mach-imx6q.c  |   65 +++++++++
 drivers/cpufreq/Kconfig.arm     |    9 ++
 drivers/cpufreq/Makefile        |    1 +
 drivers/cpufreq/imx6q-cpufreq.c |  296 +++++++++++++++++++++++++++++++++++++++
 5 files changed, 385 insertions(+), 6 deletions(-)
 create mode 100644 drivers/cpufreq/imx6q-cpufreq.c

-- 
1.7.9.5

^ permalink raw reply

* [PATCH v3 1/2] cpufreq: add imx6q-cpufreq driver
From: Shawn Guo @ 2013-01-14 15:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358175733-13475-1-git-send-email-shawn.guo@linaro.org>

Add an imx6q-cpufreq driver for Freescale i.MX6Q SoC to handle the
hardware specific frequency and voltage scaling requirements.

The driver supports module build and is instantiated by the platform
device/driver mechanism, so that it will not be instantiated on other
platforms, as IMX is built with multiplatform support.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Acked-by: Rafael J. Wysocki <rjw@sisk.pl>
---
 drivers/cpufreq/Kconfig.arm     |    9 ++
 drivers/cpufreq/Makefile        |    1 +
 drivers/cpufreq/imx6q-cpufreq.c |  296 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 306 insertions(+)
 create mode 100644 drivers/cpufreq/imx6q-cpufreq.c

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index a0b3661..9e628ba 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -77,6 +77,15 @@ config ARM_EXYNOS5250_CPUFREQ
 	  This adds the CPUFreq driver for Samsung EXYNOS5250
 	  SoC.
 
+config ARM_IMX6Q_CPUFREQ
+	tristate "Freescale i.MX6Q cpufreq support"
+	depends on SOC_IMX6Q
+	depends on REGULATOR_ANATOP
+	help
+	  This adds cpufreq driver support for Freescale i.MX6Q SOC.
+
+	  If in doubt, say N.
+
 config ARM_SPEAR_CPUFREQ
 	bool "SPEAr CPUFreq support"
 	depends on PLAT_SPEAR
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 1f254ec0..31699a0 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_ARM_EXYNOS_CPUFREQ)	+= exynos-cpufreq.o
 obj-$(CONFIG_ARM_EXYNOS4210_CPUFREQ)	+= exynos4210-cpufreq.o
 obj-$(CONFIG_ARM_EXYNOS4X12_CPUFREQ)	+= exynos4x12-cpufreq.o
 obj-$(CONFIG_ARM_EXYNOS5250_CPUFREQ)	+= exynos5250-cpufreq.o
+obj-$(CONFIG_ARM_IMX6Q_CPUFREQ)		+= imx6q-cpufreq.o
 obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)     += omap-cpufreq.o
 obj-$(CONFIG_ARM_SPEAR_CPUFREQ)		+= spear-cpufreq.o
 
diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c
new file mode 100644
index 0000000..218d8f1
--- /dev/null
+++ b/drivers/cpufreq/imx6q-cpufreq.c
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/cpu.h>
+#include <linux/cpufreq.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/opp.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+
+#define PU_SOC_VOLTAGE_NORMAL	1250000
+#define PU_SOC_VOLTAGE_HIGH	1275000
+#define FREQ_1P2_GHZ		1200000000
+
+static struct regulator *arm_reg;
+static struct regulator *pu_reg;
+static struct regulator *soc_reg;
+
+static struct clk *arm_clk;
+static struct clk *pll1_sys_clk;
+static struct clk *pll1_sw_clk;
+static struct clk *step_clk;
+static struct clk *pll2_pfd2_396m_clk;
+
+static struct device *cpu_dev;
+static struct cpufreq_frequency_table *freq_table;
+static unsigned int transition_latency;
+
+static int imx6q_verify_speed(struct cpufreq_policy *policy)
+{
+	return cpufreq_frequency_table_verify(policy, freq_table);
+}
+
+static unsigned int imx6q_get_speed(unsigned int cpu)
+{
+	return clk_get_rate(arm_clk) / 1000;
+}
+
+static int imx6q_set_target(struct cpufreq_policy *policy,
+			    unsigned int target_freq, unsigned int relation)
+{
+	struct cpufreq_freqs freqs;
+	struct opp *opp;
+	unsigned long freq_hz, volt, volt_old;
+	unsigned int index, cpu;
+	int ret;
+
+	ret = cpufreq_frequency_table_target(policy, freq_table, target_freq,
+					     relation, &index);
+	if (ret) {
+		dev_err(cpu_dev, "failed to match target frequency %d: %d\n",
+			target_freq, ret);
+		return ret;
+	}
+
+	freqs.new = freq_table[index].frequency;
+	freq_hz = freqs.new * 1000;
+	freqs.old = clk_get_rate(arm_clk) / 1000;
+
+	if (freqs.old == freqs.new)
+		return 0;
+
+	for_each_online_cpu(cpu) {
+		freqs.cpu = cpu;
+		cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+	}
+
+	opp = opp_find_freq_ceil(cpu_dev, &freq_hz);
+	if (IS_ERR(opp)) {
+		dev_err(cpu_dev, "failed to find OPP for %ld\n", freq_hz);
+		return PTR_ERR(opp);
+	}
+
+	volt = opp_get_voltage(opp);
+	volt_old = regulator_get_voltage(arm_reg);
+
+	dev_dbg(cpu_dev, "%u MHz, %ld mV --> %u MHz, %ld mV\n",
+		freqs.old / 1000, volt_old / 1000,
+		freqs.new / 1000, volt / 1000);
+
+	/* scaling up?  scale voltage before frequency */
+	if (freqs.new > freqs.old) {
+		ret = regulator_set_voltage_tol(arm_reg, volt, 0);
+		if (ret) {
+			dev_err(cpu_dev, "failed to scale voltage up: %d\n", ret);
+			return ret;
+		}
+
+		/*
+		 * Need to increase vddpu and vddsoc for safety
+		 * if we are about to run at 1.2 GHz.
+		 */
+		if (freqs.new == FREQ_1P2_GHZ / 1000) {
+			regulator_set_voltage_tol(pu_reg,
+					PU_SOC_VOLTAGE_HIGH, 0);
+			regulator_set_voltage_tol(soc_reg,
+					PU_SOC_VOLTAGE_HIGH, 0);
+		}
+	}
+
+	/*
+	 * The setpoints are selected per PLL/PDF frequencies, so we need to
+	 * reprogram PLL for frequency scaling.  The procedure of reprogramming
+	 * PLL1 is as below.
+	 *
+	 *  - Enable pll2_pfd2_396m_clk and reparent pll1_sw_clk to it
+	 *  - Disable pll1_sys_clk and reprogram it
+	 *  - Enable pll1_sys_clk and reparent pll1_sw_clk back to it
+	 *  - Disable pll2_pfd2_396m_clk
+	 */
+	clk_prepare_enable(pll2_pfd2_396m_clk);
+	clk_set_parent(step_clk, pll2_pfd2_396m_clk);
+	clk_set_parent(pll1_sw_clk, step_clk);
+	clk_prepare_enable(pll1_sys_clk);
+	if (freq_hz > clk_get_rate(pll2_pfd2_396m_clk)) {
+		clk_disable_unprepare(pll1_sys_clk);
+		clk_set_rate(pll1_sys_clk, freqs.new * 1000);
+		clk_prepare_enable(pll1_sys_clk);
+		clk_set_parent(pll1_sw_clk, pll1_sys_clk);
+		clk_disable_unprepare(pll2_pfd2_396m_clk);
+	} else {
+		/*
+		 * Disable pll1_sys_clk if pll2_pfd2_396m_clk is sufficient
+		 * to provide the frequency.
+		 */
+		clk_disable_unprepare(pll1_sys_clk);
+	}
+
+	/* Ensure the arm clock divider is what we expect */
+	ret = clk_set_rate(arm_clk, freqs.new * 1000);
+	if (ret) {
+		dev_err(cpu_dev, "failed to set clock rate: %d\n", ret);
+		regulator_set_voltage_tol(arm_reg, volt_old, 0);
+		return ret;
+	}
+
+	/* scaling down?  scale voltage after frequency */
+	if (freqs.new < freqs.old) {
+		ret = regulator_set_voltage_tol(arm_reg, volt, 0);
+		if (ret)
+			dev_warn(cpu_dev, "failed to scale voltage down: %d\n", ret);
+
+		if (freqs.old == FREQ_1P2_GHZ / 1000) {
+			regulator_set_voltage_tol(pu_reg,
+					PU_SOC_VOLTAGE_NORMAL, 0);
+			regulator_set_voltage_tol(soc_reg,
+					PU_SOC_VOLTAGE_NORMAL, 0);
+		}
+	}
+
+	for_each_online_cpu(cpu) {
+		freqs.cpu = cpu;
+		cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+	}
+
+	return 0;
+}
+
+static int imx6q_cpufreq_init(struct cpufreq_policy *policy)
+{
+	int ret;
+
+	ret = cpufreq_frequency_table_cpuinfo(policy, freq_table);
+	if (ret) {
+		dev_err(cpu_dev, "invalid frequency table: %d\n", ret);
+		return ret;
+	}
+
+	policy->cpuinfo.transition_latency = transition_latency;
+	policy->cur = clk_get_rate(arm_clk) / 1000;
+	policy->shared_type = CPUFREQ_SHARED_TYPE_ANY;
+	cpumask_setall(policy->cpus);
+	cpufreq_frequency_table_get_attr(freq_table, policy->cpu);
+
+	return 0;
+}
+
+static int imx6q_cpufreq_exit(struct cpufreq_policy *policy)
+{
+	cpufreq_frequency_table_put_attr(policy->cpu);
+	return 0;
+}
+
+static struct freq_attr *imx6q_cpufreq_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,
+};
+
+static struct cpufreq_driver imx6q_cpufreq_driver = {
+	.verify = imx6q_verify_speed,
+	.target = imx6q_set_target,
+	.get = imx6q_get_speed,
+	.init = imx6q_cpufreq_init,
+	.exit = imx6q_cpufreq_exit,
+	.name = "imx6q-cpufreq",
+	.attr = imx6q_cpufreq_attr,
+};
+
+static int imx6q_cpufreq_probe(struct platform_device *pdev)
+{
+	struct device_node *np;
+	int ret;
+
+	cpu_dev = &pdev->dev;
+
+	np = of_find_node_by_path("/cpus/cpu at 0");
+	if (!np) {
+		dev_err(cpu_dev, "failed to find cpu0 node\n");
+		return -ENOENT;
+	}
+
+	cpu_dev->of_node = np;
+
+	arm_clk = devm_clk_get(cpu_dev, "arm");
+	pll1_sys_clk = devm_clk_get(cpu_dev, "pll1_sys");
+	pll1_sw_clk = devm_clk_get(cpu_dev, "pll1_sw");
+	step_clk = devm_clk_get(cpu_dev, "step");
+	pll2_pfd2_396m_clk = devm_clk_get(cpu_dev, "pll2_pfd2_396m");
+	if (IS_ERR(arm_clk) || IS_ERR(pll1_sys_clk) || IS_ERR(pll1_sw_clk) ||
+	    IS_ERR(step_clk) || IS_ERR(pll2_pfd2_396m_clk)) {
+		dev_err(cpu_dev, "failed to get clocks\n");
+		ret = -ENOENT;
+		goto put_node;
+	}
+
+	arm_reg = devm_regulator_get(cpu_dev, "arm");
+	pu_reg = devm_regulator_get(cpu_dev, "pu");
+	soc_reg = devm_regulator_get(cpu_dev, "soc");
+	if (!arm_reg || !pu_reg || !soc_reg) {
+		dev_err(cpu_dev, "failed to get regulators\n");
+		ret = -ENOENT;
+		goto put_node;
+	}
+
+	/* We expect an OPP table supplied by platform */
+	ret = opp_get_opp_count(cpu_dev);
+	if (ret < 0) {
+		dev_err(cpu_dev, "no OPP table is found: %d\n", ret);
+		goto put_node;
+	}
+
+	ret = opp_init_cpufreq_table(cpu_dev, &freq_table);
+	if (ret) {
+		dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret);
+		goto put_node;
+	}
+
+	if (of_property_read_u32(np, "clock-latency", &transition_latency))
+		transition_latency = CPUFREQ_ETERNAL;
+
+	ret = cpufreq_register_driver(&imx6q_cpufreq_driver);
+	if (ret) {
+		dev_err(cpu_dev, "failed register driver: %d\n", ret);
+		goto free_freq_table;
+	}
+
+	of_node_put(np);
+	return 0;
+
+free_freq_table:
+	opp_free_cpufreq_table(cpu_dev, &freq_table);
+put_node:
+	of_node_put(np);
+	return ret;
+}
+
+static int imx6q_cpufreq_remove(struct platform_device *pdev)
+{
+	cpufreq_unregister_driver(&imx6q_cpufreq_driver);
+	opp_free_cpufreq_table(cpu_dev, &freq_table);
+
+	return 0;
+}
+
+static struct platform_driver imx6q_cpufreq_platdrv = {
+	.driver = {
+		.name	= "imx6q-cpufreq",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= imx6q_cpufreq_probe,
+	.remove		= imx6q_cpufreq_remove,
+};
+module_platform_driver(imx6q_cpufreq_platdrv);
+
+MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
+MODULE_DESCRIPTION("Freescale i.MX6Q cpufreq driver");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v3 2/2] ARM: imx: enable imx6q-cpufreq support
From: Shawn Guo @ 2013-01-14 15:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358175733-13475-1-git-send-email-shawn.guo@linaro.org>

Update operating-points per hardware document and add support for
1 GHz and 1.2 GHz frequencies.

400 MHz, 800 MHz and 1 GHz should be supported by all i.MX6Q chips,
while 1.2 GHz support needs to know from OTP fuse bit.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
 arch/arm/boot/dts/imx6q.dtsi   |   20 +++++++++----
 arch/arm/mach-imx/mach-imx6q.c |   65 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+), 6 deletions(-)

diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
index d6265ca..231a32c 100644
--- a/arch/arm/boot/dts/imx6q.dtsi
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -38,12 +38,19 @@
 			next-level-cache = <&L2>;
 			operating-points = <
 				/* kHz    uV */
-				792000  1100000
+				1200000 1275000
+				996000  1250000
+				792000  1150000
 				396000  950000
-				198000  850000
 			>;
 			clock-latency = <61036>; /* two CLK32 periods */
-			cpu0-supply = <&reg_cpu>;
+			clocks = <&clks 104>, <&clks 6>, <&clks 16>,
+				 <&clks 17>, <&clks 170>;
+			clock-names = "arm", "pll2_pfd2_396m", "step",
+				      "pll1_sw", "pll1_sys";
+			arm-supply = <&reg_arm>;
+			pu-supply = <&reg_pu>;
+			soc-supply = <&reg_soc>;
 		};
 
 		cpu at 1 {
@@ -471,7 +478,7 @@
 					anatop-max-voltage = <2750000>;
 				};
 
-				reg_cpu: regulator-vddcore at 140 {
+				reg_arm: regulator-vddcore at 140 {
 					compatible = "fsl,anatop-regulator";
 					regulator-name = "cpu";
 					regulator-min-microvolt = <725000>;
@@ -485,7 +492,7 @@
 					anatop-max-voltage = <1450000>;
 				};
 
-				regulator-vddpu at 140 {
+				reg_pu: regulator-vddpu at 140 {
 					compatible = "fsl,anatop-regulator";
 					regulator-name = "vddpu";
 					regulator-min-microvolt = <725000>;
@@ -499,7 +506,7 @@
 					anatop-max-voltage = <1450000>;
 				};
 
-				regulator-vddsoc at 140 {
+				reg_soc: regulator-vddsoc at 140 {
 					compatible = "fsl,anatop-regulator";
 					regulator-name = "vddsoc";
 					regulator-min-microvolt = <725000>;
@@ -965,6 +972,7 @@
 			};
 
 			ocotp at 021bc000 {
+				compatible = "fsl,imx6q-ocotp";
 				reg = <0x021bc000 0x4000>;
 			};
 
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index 4eb1b3a..2f974f5 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -12,6 +12,7 @@
 
 #include <linux/clk.h>
 #include <linux/clkdev.h>
+#include <linux/cpu.h>
 #include <linux/cpuidle.h>
 #include <linux/delay.h>
 #include <linux/export.h>
@@ -22,6 +23,7 @@
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
+#include <linux/opp.h>
 #include <linux/phy.h>
 #include <linux/regmap.h>
 #include <linux/micrel_phy.h>
@@ -209,9 +211,72 @@ static struct cpuidle_driver imx6q_cpuidle_driver = {
 	.state_count		= 1,
 };
 
+#define OCOTP_CFG3			0x440
+#define OCOTP_CFG3_SPEED_SHIFT		16
+#define OCOTP_CFG3_SPEED_1P2GHZ		0x3
+
+static void __init imx6q_opp_check_1p2ghz(struct device *cpu_dev)
+{
+	struct device_node *np;
+	void __iomem *base;
+	u32 val;
+
+	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ocotp");
+	if (!np) {
+		pr_warn("failed to find ocotp node\n");
+		return;
+	}
+
+	base = of_iomap(np, 0);
+	if (!base) {
+		pr_warn("failed to map ocotp\n");
+		goto put_node;
+	}
+
+	val = readl_relaxed(base + OCOTP_CFG3);
+	val >>= OCOTP_CFG3_SPEED_SHIFT;
+	if ((val & 0x3) != OCOTP_CFG3_SPEED_1P2GHZ)
+		if (opp_disable(cpu_dev, 1200000000))
+			pr_warn("failed to disable 1.2 GHz OPP\n");
+
+put_node:
+	of_node_put(np);
+}
+
+static void __init imx6q_opp_init(struct device *cpu_dev)
+{
+	struct device_node *np;
+
+	np = of_find_node_by_path("/cpus/cpu at 0");
+	if (!np) {
+		pr_warn("failed to find cpu0 node\n");
+		return;
+	}
+
+	cpu_dev->of_node = np;
+	if (of_init_opp_table(cpu_dev)) {
+		pr_warn("failed to init OPP table\n");
+		goto put_node;
+	}
+
+	imx6q_opp_check_1p2ghz(cpu_dev);
+
+put_node:
+	of_node_put(np);
+}
+
+struct platform_device imx6q_cpufreq_pdev = {
+	.name = "imx6q-cpufreq",
+};
+
 static void __init imx6q_init_late(void)
 {
 	imx_cpuidle_init(&imx6q_cpuidle_driver);
+
+	if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ)) {
+		imx6q_opp_init(&imx6q_cpufreq_pdev.dev);
+		platform_device_register(&imx6q_cpufreq_pdev);
+	}
 }
 
 static void __init imx6q_map_io(void)
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 5/6] ARM: dts: Add basic dts include files for Samsung S3C64xx SoCs
From: Lorenzo Pieralisi @ 2013-01-14 15:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130114144841.GE7990@e106331-lin.cambridge.arm.com>

On Mon, Jan 14, 2013 at 02:48:41PM +0000, Mark Rutland wrote:
> Hello,
> 
> This all looks good. I just have a couple of comments about the cpus node.
> 
> On Sun, Jan 13, 2013 at 01:10:57AM +0000, Tomasz Figa wrote:
> > This patch adds basic device tree definitions for Samsung S3C64xx SoCs.
> > 
> > Since all the SoCs in the series are very similar, the files are created
> > hierarchically - one file for the whole series and then separate files
> > for particular SoCs including the common one.
> > 
> > Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
> 
> [...]
> 
> > diff --git a/arch/arm/boot/dts/s3c64xx.dtsi b/arch/arm/boot/dts/s3c64xx.dtsi
> > new file mode 100644
> > index 0000000..55d6e08
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/s3c64xx.dtsi
> > @@ -0,0 +1,97 @@
> > +/*
> > + * Samsung's S3C64xx SoC series common device tree source
> > + *
> > + * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
> > + *
> > + * Samsung's S3C64xx SoC series device nodes are listed in this file.
> > + * Particular SoCs from S3C64xx series can include this file and provide
> > + * values for SoCs specfic bindings.
> > + *
> > + * Note: This file does not include device nodes for all the controllers in
> > + * S3C64xx SoCs. As device tree coverage for S3C64xx increases, additional
> > + * nodes can be added to this file.
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + */
> > +
> > +/include/ "skeleton.dtsi"
> > +
> > +/ {
> > +	cpus {
> > +		cpu at 0 {
> > +			compatible = "arm,arm1176jzf-s";
> > +		};
> > +	};
> 
> You can drop the unit address from the cpu node - it's meant to be there to
> differentiate multiple nodes (and is supposed to match the reg property, which
> the 1176jzf-s can't have, as it doesn't have an MPIDR).

Well, this is a point that I should consider since the kernel docs I wrote are
misleading, they require the reg property that can not be there on UP.
True, MPIDR does not exist in this case, but I have to document this in the
bindings since it is unclear.

> 
> Also, "arm,arm1176jzf-s" isn't listed in the binding doc. There was a question
> about how to maintain this list [1], but I can't seem to find a conclusion, if
> any were reached.  It might be worth appending "arm,arm1176" to the compatible
> list for the cpu node in case we want to enable something via dt for all 1176
> variations.
> 
> Dave, Lorenzo, any thoughts?

Eh, frankly I do not know how to handle this. Either we add a compatible
string to the bindings anytime a DT gets merged in the kernel but how
to maintain it, it has to be defined. Happy to hear some feedback on
this.

Lorenzo

^ permalink raw reply

* [PATCH v5 03/14] KVM: ARM: Initial skeleton to compile KVM support
From: Will Deacon @ 2013-01-14 15:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130108183855.46302.40539.stgit@ubuntu>

On Tue, Jan 08, 2013 at 06:38:55PM +0000, Christoffer Dall wrote:
> Targets KVM support for Cortex A-15 processors.
> 
> Contains all the framework components, make files, header files, some
> tracing functionality, and basic user space API.
> 
> Only supported core is Cortex-A15 for now.
> 
> Most functionality is in arch/arm/kvm/* or arch/arm/include/asm/kvm_*.h.
> 
> Reviewed-by: Marcelo Tosatti <mtosatti@redhat.com>
> Signed-off-by: Rusty Russell <rusty.russell@linaro.org>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
> ---
>  Documentation/virtual/kvm/api.txt  |   57 +++++-
>  arch/arm/Kconfig                   |    2
>  arch/arm/Makefile                  |    1
>  arch/arm/include/asm/kvm_arm.h     |   24 ++
>  arch/arm/include/asm/kvm_asm.h     |   58 ++++++
>  arch/arm/include/asm/kvm_coproc.h  |   24 ++
>  arch/arm/include/asm/kvm_emulate.h |   50 +++++
>  arch/arm/include/asm/kvm_host.h    |  114 ++++++++++++
>  arch/arm/include/uapi/asm/kvm.h    |  106 +++++++++++

[...]

> diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
> new file mode 100644
> index 0000000..c6298b1
> --- /dev/null
> +++ b/arch/arm/include/uapi/asm/kvm.h
> @@ -0,0 +1,106 @@
> +/*
> + * Copyright (C) 2012 - Virtual Open Systems and Columbia University
> + * Author: Christoffer Dall <c.dall@virtualopensystems.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, write to the Free Software
> + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
> + */
> +
> +#ifndef __ARM_KVM_H__
> +#define __ARM_KVM_H__
> +
> +#include <asm/types.h>
> +#include <asm/ptrace.h>

I think you want linux/types.h, as asm/types.h isn't exported from what I
can tell. make headers_check screams about it too:

/home/will/sources/linux/linux/usr/include/asm/kvm.h:22: include of <linux/types.h> is preferred over <asm/types.h>
/home/will/sources/linux/linux/usr/include/asm/kvm.h:57: found __[us]{8,16,32,64} type without #include <linux/types.h>

Will

^ permalink raw reply

* [PATCH v5 04/14] KVM: ARM: Hypervisor initialization
From: Will Deacon @ 2013-01-14 15:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130108183903.46302.97512.stgit@ubuntu>

On Tue, Jan 08, 2013 at 06:39:03PM +0000, Christoffer Dall wrote:
> Sets up KVM code to handle all exceptions taken to Hyp mode.
> 
> When the kernel is booted in Hyp mode, calling an hvc instruction with r0
> pointing to the new vectors, the HVBAR is changed to the the vector pointers.
> This allows subsystems (like KVM here) to execute code in Hyp-mode with the
> MMU disabled.
> 
> We initialize other Hyp-mode registers and enables the MMU for Hyp-mode from
> the id-mapped hyp initialization code. Afterwards, the HVBAR is changed to
> point to KVM Hyp vectors used to catch guest faults and to switch to Hyp mode
> to perform a world-switch into a KVM guest.
> 
> Also provides memory mapping code to map required code pages, data structures,
> and I/O regions  accessed in Hyp mode at the same virtual address as the host
> kernel virtual addresses, but which conforms to the architectural requirements
> for translations in Hyp mode. This interface is added in arch/arm/kvm/arm_mmu.c
> and comprises:
>  - create_hyp_mappings(from, to);
>  - create_hyp_io_mappings(from, to, phys_addr);
>  - free_hyp_pmds();

[...]

> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> index 82cb338..2dddc58 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -34,11 +34,21 @@
>  #include <asm/ptrace.h>
>  #include <asm/mman.h>
>  #include <asm/cputype.h>
> +#include <asm/tlbflush.h>
> +#include <asm/virt.h>
> +#include <asm/kvm_arm.h>
> +#include <asm/kvm_asm.h>
> +#include <asm/kvm_mmu.h>
> 
>  #ifdef REQUIRES_VIRT
>  __asm__(".arch_extension       virt");
>  #endif
> 
> +static DEFINE_PER_CPU(unsigned long, kvm_arm_hyp_stack_page);
> +static struct vfp_hard_struct __percpu *kvm_host_vfp_state;
> +static unsigned long hyp_default_vectors;
> +
> +
>  int kvm_arch_hardware_enable(void *garbage)
>  {
>         return 0;
> @@ -336,9 +346,176 @@ long kvm_arch_vm_ioctl(struct file *filp,
>         return -EINVAL;
>  }
> 
> +static void cpu_init_hyp_mode(void *vector)
> +{
> +       unsigned long long pgd_ptr;
> +       unsigned long hyp_stack_ptr;
> +       unsigned long stack_page;
> +       unsigned long vector_ptr;
> +
> +       /* Switch from the HYP stub to our own HYP init vector */
> +       __hyp_set_vectors((unsigned long)vector);
> +
> +       pgd_ptr = (unsigned long long)kvm_mmu_get_httbr();
> +       stack_page = __get_cpu_var(kvm_arm_hyp_stack_page);
> +       hyp_stack_ptr = stack_page + PAGE_SIZE;
> +       vector_ptr = (unsigned long)__kvm_hyp_vector;
> +
> +       /*
> +        * Call initialization code, and switch to the full blown
> +        * HYP code. The init code corrupts r12, so set the clobber
> +        * list accordingly.
> +        */
> +       asm volatile (
> +               "mov    r0, %[pgd_ptr_low]\n\t"
> +               "mov    r1, %[pgd_ptr_high]\n\t"
> +               "mov    r2, %[hyp_stack_ptr]\n\t"
> +               "mov    r3, %[vector_ptr]\n\t"
> +               "hvc    #0\n\t" : :
> +               [pgd_ptr_low] "r" ((unsigned long)(pgd_ptr & 0xffffffff)),
> +               [pgd_ptr_high] "r" ((unsigned long)(pgd_ptr >> 32ULL)),
> +               [hyp_stack_ptr] "r" (hyp_stack_ptr),
> +               [vector_ptr] "r" (vector_ptr) :
> +               "r0", "r1", "r2", "r3", "r12");
> +}

Use kvm_call_hyp here instead.

Will

^ permalink raw reply

* [PATCH v5 2/4] ARM: KVM: arch_timers: Add guest timer core support
From: Will Deacon @ 2013-01-14 15:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130108184320.46758.56628.stgit@ubuntu>

On Tue, Jan 08, 2013 at 06:43:20PM +0000, Christoffer Dall wrote:
> From: Marc Zyngier <marc.zyngier@arm.com>
> 
> Add some the architected timer related infrastructure, and support timer
> interrupt injection, which can happen as a resultof three possible
> events:
> 
> - The virtual timer interrupt has fired while we were still
>   executing the guest
> - The timer interrupt hasn't fired, but it expired while we
>   were doing the world switch
> - A hrtimer we programmed earlier has fired

[...]

> +void kvm_timer_sync_to_cpu(struct kvm_vcpu *vcpu)
> +{
> +       struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
> +
> +       /*
> +        * We're about to run this vcpu again, so there is no need to
> +        * keep the background timer running, as we're about to
> +        * populate the CPU timer again.
> +        */
> +       timer_disarm(timer);
> +}
> +
> +void kvm_timer_sync_from_cpu(struct kvm_vcpu *vcpu)
> +{
> +       struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
> +       cycle_t cval, now;
> +       u64 ns;
> +
> +       /* Check if the timer is enabled and unmasked first */
> +       if ((timer->cntv_ctl & 3) != 1)
> +               return;
> +
> +       cval = timer->cntv_cval;
> +       now = kvm_phys_timer_read() - vcpu->kvm->arch.timer.cntvoff;
> +
> +       BUG_ON(timer_is_armed(timer));
> +
> +       if (cval <= now) {
> +               /*
> +                * Timer has already expired while we were not
> +                * looking. Inject the interrupt and carry on.
> +                */
> +               kvm_timer_inject_irq(vcpu);
> +               return;
> +       }
> +
> +       ns = cyclecounter_cyc2ns(timecounter->cc, cval - now);
> +       timer_arm(timer, ns);
> +}

Please use flush/sync terminology to match the rest of arch/arm/.

Will

^ permalink raw reply

* [PATCH v5 3/4] ARM: KVM: arch_timers: Add timer world switch
From: Will Deacon @ 2013-01-14 15:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130108184327.46758.70599.stgit@ubuntu>

On Tue, Jan 08, 2013 at 06:43:27PM +0000, Christoffer Dall wrote:
> From: Marc Zyngier <marc.zyngier@arm.com>
> 
> Do the necessary save/restore dance for the timers in the world
> switch code. In the process, allow the guest to read the physical
> counter, which is useful for its own clock_event_device.

[...]

> @@ -476,6 +513,7 @@ vcpu	.req	r0		@ vcpu pointer always in r0
>   * for the host.
>   *
>   * Assumes vcpu pointer in vcpu reg
> + * Clobbers r2-r4
>   */
>  .macro restore_timer_state
>  	@ Disallow physical timer access for the guest
> @@ -484,6 +522,30 @@ vcpu	.req	r0		@ vcpu pointer always in r0
>  	orr	r2, r2, #CNTHCTL_PL1PCTEN
>  	bic	r2, r2, #CNTHCTL_PL1PCEN
>  	mcr	p15, 4, r2, c14, c1, 0	@ CNTHCTL
> +
> +#ifdef CONFIG_KVM_ARM_TIMER
> +	ldr	r4, [vcpu, #VCPU_KVM]
> +	ldr	r2, [r4, #KVM_TIMER_ENABLED]
> +	cmp	r2, #0
> +	beq	1f
> +
> +	ldr	r2, [r4, #KVM_TIMER_CNTVOFF]
> +	ldr	r3, [r4, #(KVM_TIMER_CNTVOFF + 4)]
> +	mcrr	p15, 4, r2, r3, c14	@ CNTVOFF
> +	isb
> +
> +	ldr	r4, =VCPU_TIMER_CNTV_CVAL
> +	add	vcpu, vcpu, r4
> +	ldrd	r2, r3, [vcpu]
> +	sub	vcpu, vcpu, r4
> +	mcrr	p15, 3, r2, r3, c14	@ CNTV_CVAL
> +
> +	ldr	r2, [vcpu, #VCPU_TIMER_CNTV_CTL]
> +	and	r2, r2, #3
> +	mcr	p15, 0, r2, c14, c3, 1	@ CNTV_CTL
> +	isb

How many of these isbs are actually needed, given that we're going to make
an exception return to the guest? The last one certainly looks redundant and
I can't see the need for ordering CNTVOFF vs CNTV_CVAL. I can see an
argument to putting one *before* CNTV_CTL, but you don't have one there!

Will

^ permalink raw reply

* Question: ARM: local timers: add num_possible_cpus() in local_timer_register()
From: Marc Zyngier @ 2013-01-14 15:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAKvkGKfxT6cQF6rXmYZEL5tJbtsm0Yv4i1D_9NXQRsdbNFi2PQ@mail.gmail.com>

On 14/01/13 14:31, steve.zhan wrote:
> Hi,
>     Russel, Marc,
> 2013/1/14 Marc Zyngier <marc.zyngier@arm.com>:
>> On 14/01/13 13:33, Steve zhan wrote:
>>
>> Hi Steve,
>>
>>>       Do you think we should add num_possible_cpus() in
>>> local_timer_register() function, When core number is
>>>> 1, then reutrn TRUE? Enable the local timer only if
>>> we have more than one CPU, if the current config is
>>> SMP and setup_max_cpus >= 1, but if smp_init_cpus in
>>> platform code have set cpu possible value to One(that
>>> maybe read number from scu or other hardware), then
>>> percpu_timer_setup in smp_prepare_cpus have no chance
>>> to be called.
>>>
>>>       For local timer, because local_timer_register have
>>> return 1, that will miss global timer register.
>>>
>>>       Could you pls check it?
>>
>> I'm not sure I understand your question.
>>
>> We only enable the use of the SMP local timers infrastructure if we're
>> SMP and we have more that one CPU. If you only have one CPU up and
>> running, then you can still use your CPU local timer as a global timer.
>>
>> What would we gain by using the local timer infrastructure when we're
>> not running on SMP hardware?
>>
>>         M.
>> --
>> Jazz is not dead. It just smells funny...
>>
> 
> For these code:
>         err = local_timer_register(&arch_timer_ops);
>         if (err) {
>                 /*
>                  * We couldn't register as a local timer (could be
>                  * because we're on a UP platform, or because some
>                  * other local timer is already present...). Try as a
>                  * global timer instead.
>                  */
>                 arch_timer_global_evt.cpumask = cpumask_of(0);
>                 err = arch_timer_setup(&arch_timer_global_evt);
>         }
> 
> if err == 0, we have no register global arch timer,  but platform code
> platsmp.c will set
> cpu possible number to one, that let percpu_timer_setup in
> smp_prepare_cpus have no
> chance to call becaue ncores = num_possible_cpus() is one.
> Is this right?

Ah, I get it now. Yes, this is a problem. Mark Rutland's patch series
actually fixes this issue entirely though. You may want to check it out.

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply

* [PATCH v5 04/12] ARM: KVM: Initial VGIC infrastructure code
From: Will Deacon @ 2013-01-14 15:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130108184150.46558.35674.stgit@ubuntu>

On Tue, Jan 08, 2013 at 06:41:51PM +0000, Christoffer Dall wrote:
> From: Marc Zyngier <marc.zyngier@arm.com>
> 
> Wire the basic framework code for VGIC support and the initial in-kernel
> MMIO support code for the VGIC, used for the distributor emulation.

[...]

> +/**
> + * vgic_reg_access - access vgic register
> + * @mmio:   pointer to the data describing the mmio access
> + * @reg:    pointer to the virtual backing of vgic distributor data
> + * @offset: least significant 2 bits used for word offset
> + * @mode:   ACCESS_ mode (see defines above)
> + *
> + * Helper to make vgic register access easier using one of the access
> + * modes defined for vgic register access
> + * (read,raz,write-ignored,setbit,clearbit,write)
> + */
> +static void vgic_reg_access(struct kvm_exit_mmio *mmio, u32 *reg,
> +                           phys_addr_t offset, int mode)
> +{
> +       int shift = (offset & 3) * 8;
> +       u32 mask;
> +       u32 regval;
> +
> +       /*
> +        * Any alignment fault should have been delivered to the guest
> +        * directly (ARM ARM B3.12.7 "Prioritization of aborts").
> +        */
> +
> +       mask = (~0U) >> shift;
> +       if (reg) {
> +               regval = *reg;
> +       } else {
> +               BUG_ON(mode != (ACCESS_READ_RAZ | ACCESS_WRITE_IGNORED));
> +               regval = 0;
> +       }
> +
> +       if (mmio->is_write) {
> +               u32 data = (*((u32 *)mmio->data) & mask) << shift;
> +               switch (ACCESS_WRITE_MASK(mode)) {
> +               case ACCESS_WRITE_IGNORED:
> +                       return;
> +
> +               case ACCESS_WRITE_SETBIT:
> +                       regval |= data;
> +                       break;
> +
> +               case ACCESS_WRITE_CLEARBIT:
> +                       regval &= ~data;
> +                       break;
> +
> +               case ACCESS_WRITE_VALUE:
> +                       regval = (regval & ~(mask << shift)) | data;
> +                       break;
> +               }
> +               *reg = regval;
> +       } else {
> +               switch (ACCESS_READ_MASK(mode)) {
> +               case ACCESS_READ_RAZ:
> +                       regval = 0;
> +                       /* fall through */
> +
> +               case ACCESS_READ_VALUE:
> +                       *((u32 *)mmio->data) = (regval >> shift) & mask;
> +               }
> +       }
> +}

As I mentioned previously, I suspect that this doesn't work with big-endian
systems. Whilst that's reasonable for the moment, a comment would be useful
for the unlucky soul that decides to do that work in future (or add
accessors for mmio->data as I suggested before).

Will

^ permalink raw reply

* [PATCHv2 1/4] clockevents: Add generic timer broadcast receiver
From: Mark Rutland @ 2013-01-14 15:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.02.1301141318460.7475@ionos>

On Mon, Jan 14, 2013 at 02:17:26PM +0000, Thomas Gleixner wrote:
> On Mon, 14 Jan 2013, Mark Rutland wrote:
> > On Mon, Jan 14, 2013 at 11:50:55AM +0000, Thomas Gleixner wrote:
> > > On Mon, 14 Jan 2013, Mark Rutland wrote:
> > > 
> > > > On Mon, Jan 14, 2013 at 11:06:31AM +0000, Thomas Gleixner wrote:
> > > > > On Wed, 9 Jan 2013, Mark Rutland wrote:
> > > > > > +#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
> > > > > > +extern int tick_receive_broadcast(void);
> > > > > > +#else
> > > > > > +static inline int tick_receive_broadcast(void)
> > > > > > +{
> > > > > > +	return 0;
> > > > > > +}
> > > > > 
> > > > > What's the inline function for? If an arch does not have broadcasting
> > > > > support it should not have a receive broadcast function call either.
> > > > 
> > > > That was how this was originally structured [1], but Santosh suggested this
> > > > would break the build for !GENERIC_CLOCKEVENTS_BROADCAST [1]. It means that the
> > > > arch-specific receive path (i.e. IPI handler) doesn't have to be #ifdef'd,
> > > > which makes it less ugly.
> > > 
> > > Hmm. If you want to keep the IPI around unconditionally the inline
> > > makes some sense, though the question is whether keeping an unused IPI
> > > around makes sense in the first place. I'd rather see a warning that
> > > an unexpected IPI happened than a silent inline function being called.
> > 
> > How about I add a warning (e.g. "Impossible timer broadcast received.") and
> > return -EOPNOTSUPP when !GENERIC_CLOCKEVENTS_BROADCAST?
> 
> You still need to do something with the return value in the arch IPI
> code, right?

Good point. Having the stub when !CONFIG_GENERIC_CLOCKEVENTS_BROADCAST is
clearly problematic.

I'll go with your original suggestion, removing the tick_receive_broadcast stub
for !CONFIG_GENERIC_CLOCKEVENTS_BROADCAST and I'll #idef the IPI_TIMER handler.
That way it'll fall down to the standard warning for an unexpected/unknown IPI
for arch/arm at least.

> > > > > Is anything going to use the return value?
> > > > 
> > > > I'd added this after looking at the x86 lapic timers, where interrupts might
> > > > remain pending over a kexec, and lapic interrupts come up before timers are
> > > > registered. The return value is useful for shutting down the timer in that case
> > > > (see x86's local_apic_timer_interrupt).
> > > 
> > > Right, though then you need to check for evt->event_handler as well.
> > 
> > I thought this previously also [1], but I couldn't find any path such that a
> > tick_cpu_device would have an evtdev without an event_handler. We always set the
> > handler before setting evtdev, and alway wipe evtdev before wiping the handler.
> > 
> > Have I missed something?
> 
> That's an x86 specific issue. Though we could try and make that
> functionality completely generic.

Just to check: is the evt->event_handler check necessary?

> Thanks,
> 
> 	tglx
> 

Thanks,
Mark.

^ permalink raw reply

* [PATCH v5 06/12] ARM: KVM: VGIC distributor handling
From: Will Deacon @ 2013-01-14 15:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130108184204.46558.51956.stgit@ubuntu>

On Tue, Jan 08, 2013 at 06:42:04PM +0000, Christoffer Dall wrote:
> From: Marc Zyngier <marc.zyngier@arm.com>
> 
> Add the GIC distributor emulation code. A number of the GIC features
> are simply ignored as they are not required to boot a Linux guest.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
> ---
>  arch/arm/include/asm/kvm_vgic.h |   82 +++++
>  arch/arm/kvm/vgic.c             |  593 +++++++++++++++++++++++++++++++++++++++
>  2 files changed, 674 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/include/asm/kvm_vgic.h b/arch/arm/include/asm/kvm_vgic.h
> index 270dcd2..9ff0d9c 100644
> --- a/arch/arm/include/asm/kvm_vgic.h
> +++ b/arch/arm/include/asm/kvm_vgic.h
> @@ -19,12 +19,94 @@
>  #ifndef __ASM_ARM_KVM_VGIC_H
>  #define __ASM_ARM_KVM_VGIC_H
> 
> +#include <linux/kernel.h>
> +#include <linux/kvm.h>
> +#include <linux/kvm_host.h>
> +#include <linux/irqreturn.h>
> +#include <linux/spinlock.h>
> +#include <linux/types.h>
>  #include <asm/hardware/gic.h>
> 
> +#define VGIC_NR_IRQS           128
> +#define VGIC_NR_SGIS           16

Now that you have this, you can use it in a few places (see also the BUG_ONs
in vgic_queue_irq).

> +#define VGIC_NR_PPIS           16
> +#define VGIC_NR_PRIVATE_IRQS   (VGIC_NR_SGIS + VGIC_NR_PPIS)
> +#define VGIC_NR_SHARED_IRQS    (VGIC_NR_IRQS - VGIC_NR_PRIVATE_IRQS)
> +#define VGIC_MAX_CPUS          KVM_MAX_VCPUS
> +
> +/* Sanity checks... */
> +#if (VGIC_MAX_CPUS > 8)
> +#error Invalid number of CPU interfaces
> +#endif
> +
> +#if (VGIC_NR_IRQS & 31)
> +#error "VGIC_NR_IRQS must be a multiple of 32"
> +#endif
> +
> +#if (VGIC_NR_IRQS > 1024)
> +#error "VGIC_NR_IRQS must be <= 1024"
> +#endif
> +
> +/*
> + * The GIC distributor registers describing interrupts have two parts:
> + * - 32 per-CPU interrupts (SGI + PPI)
> + * - a bunch of shared interrupts (SPI)
> + */
> +struct vgic_bitmap {
> +       union {
> +               u32 reg[VGIC_NR_PRIVATE_IRQS / 32];
> +               DECLARE_BITMAP(reg_ul, VGIC_NR_PRIVATE_IRQS);
> +       } percpu[VGIC_MAX_CPUS];
> +       union {
> +               u32 reg[VGIC_NR_SHARED_IRQS / 32];
> +               DECLARE_BITMAP(reg_ul, VGIC_NR_SHARED_IRQS);
> +       } shared;
> +};
> +
> +struct vgic_bytemap {
> +       u32 percpu[VGIC_MAX_CPUS][VGIC_NR_PRIVATE_IRQS / 4];
> +       u32 shared[VGIC_NR_SHARED_IRQS  / 4];
> +};
> +
>  struct vgic_dist {
> +#ifdef CONFIG_KVM_ARM_VGIC
> +       spinlock_t              lock;
> +
> +       /* Virtual control interface mapping */
> +       void __iomem            *vctrl_base;
> +
>         /* Distributor and vcpu interface mapping in the guest */
>         phys_addr_t             vgic_dist_base;
>         phys_addr_t             vgic_cpu_base;
> +
> +       /* Distributor enabled */
> +       u32                     enabled;
> +
> +       /* Interrupt enabled (one bit per IRQ) */
> +       struct vgic_bitmap      irq_enabled;
> +
> +       /* Interrupt 'pin' level */
> +       struct vgic_bitmap      irq_state;
> +
> +       /* Level-triggered interrupt in progress */
> +       struct vgic_bitmap      irq_active;
> +
> +       /* Interrupt priority. Not used yet. */
> +       struct vgic_bytemap     irq_priority;
> +
> +       /* Level/edge triggered */
> +       struct vgic_bitmap      irq_cfg;
> +
> +       /* Source CPU per SGI and target CPU */
> +       u8                      irq_sgi_sources[VGIC_MAX_CPUS][16];

VGIC_NR_SGIS


> +static u32 vgic_get_target_reg(struct kvm *kvm, int irq)
> +{
> +       struct vgic_dist *dist = &kvm->arch.vgic;
> +       struct kvm_vcpu *vcpu;
> +       int i, c;
> +       unsigned long *bmap;
> +       u32 val = 0;
> +
> +       irq -= VGIC_NR_PRIVATE_IRQS;
> +
> +       kvm_for_each_vcpu(c, vcpu, kvm) {
> +               bmap = vgic_bitmap_get_shared_map(&dist->irq_spi_target[c]);
> +               for (i = 0; i < GICD_IRQS_PER_ITARGETSR; i++)
> +                       if (test_bit(irq + i, bmap))
> +                               val |= 1 << (c + i * 8);
> +       }
> +
> +       return val;
> +}
> +
> +static void vgic_set_target_reg(struct kvm *kvm, u32 val, int irq)
> +{
> +       struct vgic_dist *dist = &kvm->arch.vgic;
> +       struct kvm_vcpu *vcpu;
> +       int i, c;
> +       unsigned long *bmap;
> +       u32 target;
> +
> +       BUG_ON(irq & 3);
> +       BUG_ON(irq < VGIC_NR_PRIVATE_IRQS);

This is now different to vgic_Get_target_reg, which doesn't have the
BUG_ONs. Can we remove these ones too?

> +       irq -= VGIC_NR_PRIVATE_IRQS;
> +
> +       /*
> +        * Pick the LSB in each byte. This ensures we target exactly
> +        * one vcpu per IRQ. If the byte is null, assume we target
> +        * CPU0.
> +        */
> +       for (i = 0; i < GICD_IRQS_PER_ITARGETSR; i++) {
> +               int shift = i * GICD_CPUTARGETS_BITS;
> +               target = ffs((val >> shift) & 0xffU);
> +               target = target ? (target - 1) : 0;
> +               dist->irq_spi_cpu[irq + i] = target;
> +               kvm_for_each_vcpu(c, vcpu, kvm) {
> +                       bmap = vgic_bitmap_get_shared_map(&dist->irq_spi_target[c]);
> +                       if (c == target)
> +                               set_bit(irq + i, bmap);
> +                       else
> +                               clear_bit(irq + i, bmap);
> +               }
> +       }
> +}

[...]

>  static const struct mmio_range vgic_ranges[] = {
> +       {                       /* CTRL, TYPER, IIDR */
> +               .base           = 0,
> +               .len            = 12,
> +               .handle_mmio    = handle_mmio_misc,
> +       },
> +       {                       /* IGROUPRn */
> +               .base           = 0x80,
> +               .len            = VGIC_NR_IRQS / 8,
> +               .handle_mmio    = handle_mmio_raz_wi,
> +       },
> +       {                       /* ISENABLERn */
> +               .base           = 0x100,
> +               .len            = VGIC_NR_IRQS / 8,
> +               .handle_mmio    = handle_mmio_set_enable_reg,
> +       },
> +       {                       /* ICENABLERn */
> +               .base           = 0x180,
> +               .len            = VGIC_NR_IRQS / 8,
> +               .handle_mmio    = handle_mmio_clear_enable_reg,
> +       },
> +       {                       /* ISPENDRn */
> +               .base           = 0x200,
> +               .len            = VGIC_NR_IRQS / 8,
> +               .handle_mmio    = handle_mmio_set_pending_reg,
> +       },
> +       {                       /* ICPENDRn */
> +               .base           = 0x280,
> +               .len            = VGIC_NR_IRQS / 8,
> +               .handle_mmio    = handle_mmio_clear_pending_reg,
> +       },
> +       {                       /* ISACTIVERn */
> +               .base           = 0x300,
> +               .len            = VGIC_NR_IRQS / 8,
> +               .handle_mmio    = handle_mmio_raz_wi,
> +       },
> +       {                       /* ICACTIVERn */
> +               .base           = 0x380,
> +               .len            = VGIC_NR_IRQS / 8,
> +               .handle_mmio    = handle_mmio_raz_wi,
> +       },
> +       {                       /* IPRIORITYRn */
> +               .base           = 0x400,
> +               .len            = VGIC_NR_IRQS,
> +               .handle_mmio    = handle_mmio_priority_reg,
> +       },
> +       {                       /* ITARGETSRn */
> +               .base           = 0x800,
> +               .len            = VGIC_NR_IRQS,
> +               .handle_mmio    = handle_mmio_target_reg,
> +       },
> +       {                       /* ICFGRn */
> +               .base           = 0xC00,
> +               .len            = VGIC_NR_IRQS / 4,
> +               .handle_mmio    = handle_mmio_cfg_reg,
> +       },
> +       {                       /* SGIRn */
> +               .base           = 0xF00,
> +               .len            = 4,
> +               .handle_mmio    = handle_mmio_sgi_reg,
> +       },
>         {}
>  };

You've added named definitions for these constants to the GIC header file,
so please replace these immediates with those and delete the comments.

Will

^ permalink raw reply

* [PATCH v5 03/14] KVM: ARM: Initial skeleton to compile KVM support
From: Christoffer Dall @ 2013-01-14 15:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130114150917.GA18935@mudshark.cambridge.arm.com>

On Mon, Jan 14, 2013 at 10:09 AM, Will Deacon <will.deacon@arm.com> wrote:
> On Tue, Jan 08, 2013 at 06:38:55PM +0000, Christoffer Dall wrote:
>> Targets KVM support for Cortex A-15 processors.
>>
>> Contains all the framework components, make files, header files, some
>> tracing functionality, and basic user space API.
>>
>> Only supported core is Cortex-A15 for now.
>>
>> Most functionality is in arch/arm/kvm/* or arch/arm/include/asm/kvm_*.h.
>>
>> Reviewed-by: Marcelo Tosatti <mtosatti@redhat.com>
>> Signed-off-by: Rusty Russell <rusty.russell@linaro.org>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
>> ---
>>  Documentation/virtual/kvm/api.txt  |   57 +++++-
>>  arch/arm/Kconfig                   |    2
>>  arch/arm/Makefile                  |    1
>>  arch/arm/include/asm/kvm_arm.h     |   24 ++
>>  arch/arm/include/asm/kvm_asm.h     |   58 ++++++
>>  arch/arm/include/asm/kvm_coproc.h  |   24 ++
>>  arch/arm/include/asm/kvm_emulate.h |   50 +++++
>>  arch/arm/include/asm/kvm_host.h    |  114 ++++++++++++
>>  arch/arm/include/uapi/asm/kvm.h    |  106 +++++++++++
>
> [...]
>
>> diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
>> new file mode 100644
>> index 0000000..c6298b1
>> --- /dev/null
>> +++ b/arch/arm/include/uapi/asm/kvm.h
>> @@ -0,0 +1,106 @@
>> +/*
>> + * Copyright (C) 2012 - Virtual Open Systems and Columbia University
>> + * Author: Christoffer Dall <c.dall@virtualopensystems.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, write to the Free Software
>> + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
>> + */
>> +
>> +#ifndef __ARM_KVM_H__
>> +#define __ARM_KVM_H__
>> +
>> +#include <asm/types.h>
>> +#include <asm/ptrace.h>
>
> I think you want linux/types.h, as asm/types.h isn't exported from what I
> can tell. make headers_check screams about it too:
>
> /home/will/sources/linux/linux/usr/include/asm/kvm.h:22: include of <linux/types.h> is preferred over <asm/types.h>
> /home/will/sources/linux/linux/usr/include/asm/kvm.h:57: found __[us]{8,16,32,64} type without #include <linux/types.h>
>
right, fixed:

commit 4f880a3224b26a854736f19b21de9d457829940e
Author: Christoffer Dall <c.dall@virtualopensystems.com>
Date:   Mon Jan 14 10:39:03 2013 -0500

    KVM: ARM: Include linux/types.h instead of asm/types.h

    Include the right header file.

    Cc: Will Deacon <will.deacon@arm.com>
    Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>

diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
index 972b90d..236f528 100644
--- a/arch/arm/include/uapi/asm/kvm.h
+++ b/arch/arm/include/uapi/asm/kvm.h
@@ -19,7 +19,7 @@
 #ifndef __ARM_KVM_H__
 #define __ARM_KVM_H__

-#include <asm/types.h>
+#include <linux/types.h>
 #include <asm/ptrace.h>

 #define __KVM_HAVE_GUEST_DEBUG

--

Thanks,
-Christoffer

^ permalink raw reply related

* [PATCH v5 07/12] ARM: KVM: VGIC virtual CPU interface management
From: Will Deacon @ 2013-01-14 15:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130108184211.46558.74646.stgit@ubuntu>

On Tue, Jan 08, 2013 at 06:42:11PM +0000, Christoffer Dall wrote:
> From: Marc Zyngier <marc.zyngier@arm.com>
> 
> Add VGIC virtual CPU interface code, picking pending interrupts
> from the distributor and stashing them in the VGIC control interface
> list registers.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
> ---
>  arch/arm/include/asm/kvm_vgic.h |   30 ++++
>  arch/arm/kvm/vgic.c             |  327 +++++++++++++++++++++++++++++++++++++++
>  2 files changed, 356 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/include/asm/kvm_vgic.h b/arch/arm/include/asm/kvm_vgic.h
> index 9ff0d9c..b3133c4 100644
> --- a/arch/arm/include/asm/kvm_vgic.h
> +++ b/arch/arm/include/asm/kvm_vgic.h
> @@ -110,8 +110,33 @@ struct vgic_dist {
>  };
> 
>  struct vgic_cpu {
> +#ifdef CONFIG_KVM_ARM_VGIC
> +       /* per IRQ to LR mapping */
> +       u8              vgic_irq_lr_map[VGIC_NR_IRQS];
> +
> +       /* Pending interrupts on this VCPU */
> +       DECLARE_BITMAP( pending_percpu, VGIC_NR_PRIVATE_IRQS);
> +       DECLARE_BITMAP( pending_shared, VGIC_NR_SHARED_IRQS);
> +
> +       /* Bitmap of used/free list registers */
> +       DECLARE_BITMAP( lr_used, 64);
> +
> +       /* Number of list registers on this CPU */
> +       int             nr_lr;
> +
> +       /* CPU vif control registers for world switch */
> +       u32             vgic_hcr;
> +       u32             vgic_vmcr;
> +       u32             vgic_misr;      /* Saved only */
> +       u32             vgic_eisr[2];   /* Saved only */
> +       u32             vgic_elrsr[2];  /* Saved only */
> +       u32             vgic_apr;
> +       u32             vgic_lr[64];    /* A15 has only 4... */

Have a #define for the maximum number of list registers.

> +#endif
>  };
> 
> +#define LR_EMPTY       0xff
> +
>  struct kvm;
>  struct kvm_vcpu;
>  struct kvm_run;
> @@ -119,9 +144,14 @@ struct kvm_exit_mmio;
> 
>  #ifdef CONFIG_KVM_ARM_VGIC
>  int kvm_vgic_set_addr(struct kvm *kvm, unsigned long type, u64 addr);
> +void kvm_vgic_sync_to_cpu(struct kvm_vcpu *vcpu);
> +void kvm_vgic_sync_from_cpu(struct kvm_vcpu *vcpu);

Same comment as for the arch timer (flush/sync).

> +int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
>  bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run,
>                       struct kvm_exit_mmio *mmio);
> 
> +#define irqchip_in_kernel(k)   (!!((k)->arch.vgic.vctrl_base))
> +
>  #else
>  static inline int kvm_vgic_hyp_init(void)
>  {
> diff --git a/arch/arm/kvm/vgic.c b/arch/arm/kvm/vgic.c
> index bd2bd7f..58237d5 100644
> --- a/arch/arm/kvm/vgic.c
> +++ b/arch/arm/kvm/vgic.c
> @@ -152,6 +152,34 @@ static int vgic_irq_is_enabled(struct kvm_vcpu *vcpu, int irq)
>         return vgic_bitmap_get_irq_val(&dist->irq_enabled, vcpu->vcpu_id, irq);
>  }
> 
> +static int vgic_irq_is_active(struct kvm_vcpu *vcpu, int irq)
> +{
> +       struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
> +
> +       return vgic_bitmap_get_irq_val(&dist->irq_active, vcpu->vcpu_id, irq);
> +}
> +
> +static void vgic_irq_set_active(struct kvm_vcpu *vcpu, int irq)
> +{
> +       struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
> +
> +       vgic_bitmap_set_irq_val(&dist->irq_active, vcpu->vcpu_id, irq, 1);
> +}
> +
> +static void vgic_irq_clear_active(struct kvm_vcpu *vcpu, int irq)
> +{
> +       struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
> +
> +       vgic_bitmap_set_irq_val(&dist->irq_active, vcpu->vcpu_id, irq, 0);
> +}
> +
> +static int vgic_dist_irq_is_pending(struct kvm_vcpu *vcpu, int irq)
> +{
> +       struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
> +
> +       return vgic_bitmap_get_irq_val(&dist->irq_state, vcpu->vcpu_id, irq);
> +}
> +
>  static void vgic_dist_irq_set(struct kvm_vcpu *vcpu, int irq)
>  {
>         struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
> @@ -711,7 +739,30 @@ static void vgic_dispatch_sgi(struct kvm_vcpu *vcpu, u32 reg)
> 
>  static int compute_pending_for_cpu(struct kvm_vcpu *vcpu)
>  {
> -       return 0;
> +       struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
> +       unsigned long *pending, *enabled, *pend_percpu, *pend_shared;
> +       unsigned long pending_private, pending_shared;
> +       int vcpu_id;
> +
> +       vcpu_id = vcpu->vcpu_id;
> +       pend_percpu = vcpu->arch.vgic_cpu.pending_percpu;
> +       pend_shared = vcpu->arch.vgic_cpu.pending_shared;
> +
> +       pending = vgic_bitmap_get_cpu_map(&dist->irq_state, vcpu_id);
> +       enabled = vgic_bitmap_get_cpu_map(&dist->irq_enabled, vcpu_id);
> +       bitmap_and(pend_percpu, pending, enabled, VGIC_NR_PRIVATE_IRQS);
> +
> +       pending = vgic_bitmap_get_shared_map(&dist->irq_state);
> +       enabled = vgic_bitmap_get_shared_map(&dist->irq_enabled);
> +       bitmap_and(pend_shared, pending, enabled, VGIC_NR_SHARED_IRQS);
> +       bitmap_and(pend_shared, pend_shared,
> +                  vgic_bitmap_get_shared_map(&dist->irq_spi_target[vcpu_id]),
> +                  VGIC_NR_SHARED_IRQS);
> +
> +       pending_private = find_first_bit(pend_percpu, VGIC_NR_PRIVATE_IRQS);
> +       pending_shared = find_first_bit(pend_shared, VGIC_NR_SHARED_IRQS);
> +       return (pending_private < VGIC_NR_PRIVATE_IRQS ||
> +               pending_shared < VGIC_NR_SHARED_IRQS);
>  }
> 
>  /*
> @@ -737,6 +788,280 @@ static void vgic_update_state(struct kvm *kvm)
>         }
>  }
> 
> +#define LR_CPUID(lr)   \
> +       (((lr) & GICH_LR_PHYSID_CPUID) >> GICH_LR_PHYSID_CPUID_SHIFT)
> +#define MK_LR_PEND(src, irq)   \
> +       (GICH_LR_PENDING_BIT | ((src) << GICH_LR_PHYSID_CPUID_SHIFT) | (irq))
> +/*
> + * Queue an interrupt to a CPU virtual interface. Return true on success,
> + * or false if it wasn't possible to queue it.
> + */
> +static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
> +{
> +       struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
> +       int lr;
> +
> +       /* Sanitize the input... */
> +       BUG_ON(sgi_source_id & ~7);
> +       BUG_ON(sgi_source_id && irq > 15);

You can use your new NR_SGIS definition here.

Will

^ permalink raw reply

* [PATCH v3 1/2] cpufreq: add imx6q-cpufreq driver
From: Eric Nelson @ 2013-01-14 15:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358175733-13475-2-git-send-email-shawn.guo@linaro.org>

Hi Shawn,

On 01/14/2013 08:02 AM, Shawn Guo wrote:
> Add an imx6q-cpufreq driver for Freescale i.MX6Q SoC to handle the
> hardware specific frequency and voltage scaling requirements.
>
>
 > <snip>
 >
> --- /dev/null
> +++ b/drivers/cpufreq/imx6q-cpufreq.c
> @@ -0,0 +1,296 @@
>
> <snip>
>
> +
> +static int imx6q_set_target(struct cpufreq_policy *policy,
> +			    unsigned int target_freq, unsigned int relation)
> +{
>
> <snip>
>
> +
> +	/* scaling up?  scale voltage before frequency */
> +	if (freqs.new > freqs.old) {
> +		ret = regulator_set_voltage_tol(arm_reg, volt, 0);
> +		if (ret) {
> +			dev_err(cpu_dev, "failed to scale voltage up: %d\n", ret);
> +			return ret;
> +		}
> +
> +		/*
> +		 * Need to increase vddpu and vddsoc for safety
> +		 * if we are about to run at 1.2 GHz.
> +		 */
> +		if (freqs.new == FREQ_1P2_GHZ / 1000) {
> +			regulator_set_voltage_tol(pu_reg,
> +					PU_SOC_VOLTAGE_HIGH, 0);
> +			regulator_set_voltage_tol(soc_reg,
> +					PU_SOC_VOLTAGE_HIGH, 0);
> +		}

I believe you need a delay here to let the LDOs ramp before changing
the CPU frequency.

According to the i.MX6Q reference manual, with the factory default
step times in PMU_MISC2 and the maximum voltage swing is
	1.25V (1.2GHz) - 0.95V (400MHz) == 0.325V

or 13 steps at 25mV.

The default step time is 0.000021333s (512 clocks at 24MHz), so
the worst case delay needed is ~280uS.

This could also be done in the regulator driver, but that may
require multiple delays if multiple rails are changed.

Regards,


Eric

^ permalink raw reply

* [PATCH v2 1/3] mmc: slot-gpio: use devm_* managed functions to ease users
From: Guennadi Liakhovetski @ 2013-01-14 15:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1355236340-21304-2-git-send-email-shawn.guo@linaro.org>

Hi Shawn

Sorry for a late reply.

On Tue, 11 Dec 2012, Shawn Guo wrote:

> Use devm_* managed functions, so that slot-gpio users do not have to
> call mmc_gpio_free_ro/cd to free up resources requested in
> mmc_gpio_request_ro/cd.
> 
> Signed-off-by: Shawn Guo <shawn.guo@linaro.org>

Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>

Thanks
Guennadi

> ---
>  drivers/mmc/core/slot-gpio.c |   57 +++++++++++++++++++++++++++++++++++++-----
>  1 file changed, 51 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
> index 16a1c0b..3242351 100644
> --- a/drivers/mmc/core/slot-gpio.c
> +++ b/drivers/mmc/core/slot-gpio.c
> @@ -92,6 +92,20 @@ int mmc_gpio_get_cd(struct mmc_host *host)
>  }
>  EXPORT_SYMBOL(mmc_gpio_get_cd);
>  
> +/**
> + * mmc_gpio_request_ro - request a gpio for write-protection
> + * @host: mmc host
> + * @gpio: gpio number requested
> + *
> + * As devm_* managed functions are used in mmc_gpio_request_ro(), client
> + * drivers do not need to explicitly call mmc_gpio_free_ro() for freeing up,
> + * if the requesting and freeing are only needed at probing and unbinding time
> + * for once.  However, if client drivers do something special like runtime
> + * switching for write-protection, they are responsible for calling
> + * mmc_gpio_request_ro() and mmc_gpio_free_ro() as a pair on their own.
> + *
> + * Returns zero on success, else an error.
> + */
>  int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio)
>  {
>  	struct mmc_gpio *ctx;
> @@ -106,7 +120,8 @@ int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio)
>  
>  	ctx = host->slot.handler_priv;
>  
> -	ret = gpio_request_one(gpio, GPIOF_DIR_IN, ctx->ro_label);
> +	ret = devm_gpio_request_one(&host->class_dev, gpio, GPIOF_DIR_IN,
> +				    ctx->ro_label);
>  	if (ret < 0)
>  		return ret;
>  
> @@ -116,6 +131,20 @@ int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio)
>  }
>  EXPORT_SYMBOL(mmc_gpio_request_ro);
>  
> +/**
> + * mmc_gpio_request_cd - request a gpio for card-detection
> + * @host: mmc host
> + * @gpio: gpio number requested
> + *
> + * As devm_* managed functions are used in mmc_gpio_request_cd(), client
> + * drivers do not need to explicitly call mmc_gpio_free_cd() for freeing up,
> + * if the requesting and freeing are only needed at probing and unbinding time
> + * for once.  However, if client drivers do something special like runtime
> + * switching for card-detection, they are responsible for calling
> + * mmc_gpio_request_cd() and mmc_gpio_free_cd() as a pair on their own.
> + *
> + * Returns zero on success, else an error.
> + */
>  int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
>  {
>  	struct mmc_gpio *ctx;
> @@ -128,7 +157,8 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
>  
>  	ctx = host->slot.handler_priv;
>  
> -	ret = gpio_request_one(gpio, GPIOF_DIR_IN, ctx->cd_label);
> +	ret = devm_gpio_request_one(&host->class_dev, gpio, GPIOF_DIR_IN,
> +				    ctx->cd_label);
>  	if (ret < 0)
>  		/*
>  		 * don't bother freeing memory. It might still get used by other
> @@ -146,7 +176,8 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
>  		irq = -EINVAL;
>  
>  	if (irq >= 0) {
> -		ret = request_threaded_irq(irq, NULL, mmc_gpio_cd_irqt,
> +		ret = devm_request_threaded_irq(&host->class_dev, irq,
> +			NULL, mmc_gpio_cd_irqt,
>  			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
>  			ctx->cd_label, host);
>  		if (ret < 0)
> @@ -164,6 +195,13 @@ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
>  }
>  EXPORT_SYMBOL(mmc_gpio_request_cd);
>  
> +/**
> + * mmc_gpio_free_ro - free the write-protection gpio
> + * @host: mmc host
> + *
> + * It's provided only for cases that client drivers need to manually free
> + * up the write-protection gpio requested by mmc_gpio_request_ro().
> + */
>  void mmc_gpio_free_ro(struct mmc_host *host)
>  {
>  	struct mmc_gpio *ctx = host->slot.handler_priv;
> @@ -175,10 +213,17 @@ void mmc_gpio_free_ro(struct mmc_host *host)
>  	gpio = ctx->ro_gpio;
>  	ctx->ro_gpio = -EINVAL;
>  
> -	gpio_free(gpio);
> +	devm_gpio_free(&host->class_dev, gpio);
>  }
>  EXPORT_SYMBOL(mmc_gpio_free_ro);
>  
> +/**
> + * mmc_gpio_free_cd - free the card-detection gpio
> + * @host: mmc host
> + *
> + * It's provided only for cases that client drivers need to manually free
> + * up the card-detection gpio requested by mmc_gpio_request_cd().
> + */
>  void mmc_gpio_free_cd(struct mmc_host *host)
>  {
>  	struct mmc_gpio *ctx = host->slot.handler_priv;
> @@ -188,13 +233,13 @@ void mmc_gpio_free_cd(struct mmc_host *host)
>  		return;
>  
>  	if (host->slot.cd_irq >= 0) {
> -		free_irq(host->slot.cd_irq, host);
> +		devm_free_irq(&host->class_dev, host->slot.cd_irq, host);
>  		host->slot.cd_irq = -EINVAL;
>  	}
>  
>  	gpio = ctx->cd_gpio;
>  	ctx->cd_gpio = -EINVAL;
>  
> -	gpio_free(gpio);
> +	devm_gpio_free(&host->class_dev, gpio);
>  }
>  EXPORT_SYMBOL(mmc_gpio_free_cd);
> -- 
> 1.7.9.5
> 
> 

---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply

* [PATCH v2 2/3] mmc: remove unncessary mmc_gpio_free_cd() call from slot-gpio users
From: Guennadi Liakhovetski @ 2013-01-14 15:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1355236340-21304-3-git-send-email-shawn.guo@linaro.org>

On Tue, 11 Dec 2012, Shawn Guo wrote:

> Since slot-gpio uses devm_* managed functions in mmc_gpio_request_cd()
> now, we can remove those mmc_gpio_free_cd() call from host drivers'
> .probe() error path and .remove().
> 
> Signed-off-by: Shawn Guo <shawn.guo@linaro.org>

(for mmcif and tmio)

Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>

Thanks
Guennadi

> ---
>  drivers/mmc/host/sdhci-pxav3.c  |    5 -----
>  drivers/mmc/host/sh_mmcif.c     |    6 ------
>  drivers/mmc/host/tmio_mmc_pio.c |    8 --------
>  3 files changed, 19 deletions(-)
> 
> diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
> index fad0966..b7ee776 100644
> --- a/drivers/mmc/host/sdhci-pxav3.c
> +++ b/drivers/mmc/host/sdhci-pxav3.c
> @@ -316,7 +316,6 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
>  err_add_host:
>  	clk_disable_unprepare(clk);
>  	clk_put(clk);
> -	mmc_gpio_free_cd(host->mmc);
>  err_cd_req:
>  err_clk_get:
>  	sdhci_pltfm_free(pdev);
> @@ -329,16 +328,12 @@ static int sdhci_pxav3_remove(struct platform_device *pdev)
>  	struct sdhci_host *host = platform_get_drvdata(pdev);
>  	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>  	struct sdhci_pxa *pxa = pltfm_host->priv;
> -	struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
>  
>  	sdhci_remove_host(host, 1);
>  
>  	clk_disable_unprepare(pltfm_host->clk);
>  	clk_put(pltfm_host->clk);
>  
> -	if (gpio_is_valid(pdata->ext_cd_gpio))
> -		mmc_gpio_free_cd(host->mmc);
> -
>  	sdhci_pltfm_free(pdev);
>  	kfree(pxa);
>  
> diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
> index 9b8efac..2f229e0 100644
> --- a/drivers/mmc/host/sh_mmcif.c
> +++ b/drivers/mmc/host/sh_mmcif.c
> @@ -1410,8 +1410,6 @@ static int sh_mmcif_probe(struct platform_device *pdev)
>  	return ret;
>  
>  emmcaddh:
> -	if (pd && pd->use_cd_gpio)
> -		mmc_gpio_free_cd(mmc);
>  erqcd:
>  	free_irq(irq[1], host);
>  ereqirq1:
> @@ -1433,7 +1431,6 @@ ealloch:
>  static int sh_mmcif_remove(struct platform_device *pdev)
>  {
>  	struct sh_mmcif_host *host = platform_get_drvdata(pdev);
> -	struct sh_mmcif_plat_data *pd = pdev->dev.platform_data;
>  	int irq[2];
>  
>  	host->dying = true;
> @@ -1442,9 +1439,6 @@ static int sh_mmcif_remove(struct platform_device *pdev)
>  
>  	dev_pm_qos_hide_latency_limit(&pdev->dev);
>  
> -	if (pd && pd->use_cd_gpio)
> -		mmc_gpio_free_cd(host->mmc);
> -
>  	mmc_remove_host(host->mmc);
>  	sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
>  
> diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
> index 50bf495..0f992e9 100644
> --- a/drivers/mmc/host/tmio_mmc_pio.c
> +++ b/drivers/mmc/host/tmio_mmc_pio.c
> @@ -1060,16 +1060,8 @@ EXPORT_SYMBOL(tmio_mmc_host_probe);
>  void tmio_mmc_host_remove(struct tmio_mmc_host *host)
>  {
>  	struct platform_device *pdev = host->pdev;
> -	struct tmio_mmc_data *pdata = host->pdata;
>  	struct mmc_host *mmc = host->mmc;
>  
> -	if (pdata->flags & TMIO_MMC_USE_GPIO_CD)
> -		/*
> -		 * This means we can miss a card-eject, but this is anyway
> -		 * possible, because of delayed processing of hotplug events.
> -		 */
> -		mmc_gpio_free_cd(mmc);
> -
>  	if (!host->native_hotplug)
>  		pm_runtime_get_sync(&pdev->dev);
>  
> -- 
> 1.7.9.5
> 
> 

---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply

* [PATCH v5 00/14] KVM/ARM Implementation
From: Will Deacon @ 2013-01-14 16:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130108183811.46302.58543.stgit@ubuntu>

Hi Christoffer,

On Tue, Jan 08, 2013 at 06:38:34PM +0000, Christoffer Dall wrote:
> The following series implements KVM support for ARM processors,
> specifically on the Cortex-A15 platform.

[...]

This is looking pretty good to me now and I feel that the longer it stays
out-of-tree, the more issues will creep in (without continual effort from
yourself and others). I've sent some minor comments (mainly vgic-related)
so, if you fix those, then you can add:

  Reviewed-by: Will Deacon <will.deacon@arm.com>

for the series.

Now, there's a lot of code here and merging isn't completely
straightforward. I propose:

  * The first series should go via Russell's tree. It depends on my
    perf branch for the CPU type stuff, but that should go in for 3.9
    anyway (also via Russell).

  * The vGIC patches need rebasing on top of Rob Herring's work, which
    he sent a pull for over the weekend:

      http://lists.infradead.org/pipermail/linux-arm-kernel/2013-January/141488.html

    In light of that, this stuff will need to go via arm-soc.

  * The hyp arch-timers are in a similar situation to the vGIC: Mark Rutland
    is moving those into drivers:

      http://lists.infradead.org/pipermail/linux-arm-kernel/2013-January/140560.html

    so the kvm bits will need rebasing appropriately and also sent to
    arm-soc (Mark -- I assume you intend to send a PULL for 3.9 for those
    patches?)

Obviously this is all open for discussion, but that seems like the easiest
option to me.

Cheers,

Will

^ permalink raw reply

* [PATCH v5 02/14] ARM: Section based HYP idmap
From: Russell King - ARM Linux @ 2013-01-14 16:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20130108183848.46302.77369.stgit@ubuntu>

On Tue, Jan 08, 2013 at 01:38:48PM -0500, Christoffer Dall wrote:
> +	pr_info("Setting up static %sidentity map for 0x%llx - 0x%llx\n",
> +		prot ? "HYP " : "",
> +		(long long)addr, (long long)end);

There's no point using 0x%llx and casting to 64-bit longs if the arguments
are always going to be 32-bit.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox