* [PATCH v2 2/2] Documentation: devicetree: Add boost-frequency binding to list boost mode frequency
From: Thomas Abraham @ 2014-02-08 6:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52F51FCD.5000009@arm.com>
On Fri, Feb 7, 2014 at 11:32 PM, Sudeep Holla <Sudeep.Holla@arm.com> wrote:
> On 07/02/14 17:37, Nishanth Menon wrote:
>> On Fri, Feb 7, 2014 at 11:31 AM, Sudeep Holla <Sudeep.Holla@arm.com> wrote:
>
> [...]
>
>>> Yes I think its counter-intuitive as it's visible to the userspace(list of
>>> frequencies and the boost parameters are exposed through sysfs)
>>
>> That will be a different problem -> as currently every single
>> frequency in the cpufreq list has ability to be marked as boost
>> frequency - if userspace does not maintain that, then, IMHO, fix the
>> userspace :D
>>
>
> /sys/devices/system/cpu/cpu*/cpufreq/scaling_available_frequencies gives
> the list of frequencies based on the state of the boost feature at anytime.
The list of frequencies in
/sys/devices/system/cpu/cpu*/cpufreq/scaling_available_frequencies
does not change based in the state of the boost feature (enabled or
disabled). But the scaling_max_frequency and scaling_min_frequency are
updated based on the set of available + boost frequencies available.
>
> Intuitively the list without boost shouldn't have any frequency above the range
> when it's enabled :), that's what I was referring to. So I am not talking about
> any issue with user-space maintenance.
>
> Regards,
> Sudeep
>
^ permalink raw reply
* [PATCH] ARM: smp_twd: Set the CLOCK_EVT_FEAT_PERCPU flag
From: Soren Brinkmann @ 2014-02-08 6:02 UTC (permalink / raw)
To: linux-arm-kernel
The twd timers are per CPU devices. Set the corresponding flag to mark
them as such.
Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com>
---
arch/arm/kernel/smp_twd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index 6591e26fc13f..85407473c97d 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -294,7 +294,7 @@ static void twd_timer_setup(void)
clk->name = "local_timer";
clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
- CLOCK_EVT_FEAT_C3STOP;
+ CLOCK_EVT_FEAT_C3STOP | CLOCK_EVT_FEAT_PERCPU;
clk->rating = 350;
clk->set_mode = twd_set_mode;
clk->set_next_event = twd_set_next_event;
--
1.8.5.4
^ permalink raw reply related
* [PATCH] ASoC: fsl: fix pm support of machine drivers
From: Nicolin Chen @ 2014-02-08 5:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391836835-14892-1-git-send-email-shawn.guo@linaro.org>
On Sat, Feb 08, 2014 at 01:20:35PM +0800, Shawn Guo wrote:
> The commit 1abe729 (ASoC: fsl: Add missing pm to current machine
> drivers) enables pm support for a few IMX machine drivers. But it does
> not update dev drvdata to be the pointer to 'card'. This causes the
Right...I forgot to merge this part.
> kernel dump below in system suspend, because snd_soc_suspend() expects
> that the dev drvdata points to 'card', while it still points to the
> private data of machine driver.
>
> This patch fixes imx-sgtl5000 and imx-wm8962 by attaching 'card' to dev
> drvdata and private data to card drvdata. For imx-mc13783, I simply
> revert the pm change because it must be broken for the same reason and
> I don't have hardware to test pm enabling code.
Thank you Shawn, and sorry for screwing up.
Nicolin Chen
---
>
> $ echo mem > /sys/power/state
> PM: Syncing filesystems ... done.
> PM: Preparing system for mem sleep
> mmc1: card e624 removed
> Freezing user space processes ... (elapsed 0.002 seconds) done.
> Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done.
> PM: Entering mem sleep
> INFO: trying to register non-static key.
> the code is fine but needs lockdep annotation.
> turning off the locking correctness validator.
> CPU: 0 PID: 1861 Comm: bash Not tainted 3.14.0-rc1+ #1648
> Backtrace:
> [<80012144>] (dump_backtrace) from [<800122e4>] (show_stack+0x18/0x1c)
> r6:8079c77c r5:00000c5a r4:00000000 r3:00000000
> [<800122cc>] (show_stack) from [<80637ac0>] (dump_stack+0x78/0x94)
> [<80637a48>] (dump_stack) from [<80028918>] (warn_slowpath_common+0x6c/0x8c)
> r4:bdb21c38 r3:be62df00
> [<800288ac>] (warn_slowpath_common) from [<800289dc>] (warn_slowpath_fmt+0x38/0x40)
> r8:be62e3a8 r7:bf122960 r6:00000005 r5:00000000 r4:00000000
> [<800289a8>] (warn_slowpath_fmt) from [<8006518c>] (__lock_acquire+0x1ae0/0x1ce0)
> r3:8079d598 r2:80799e70
> [<800636ac>] (__lock_acquire) from [<80065894>] (lock_acquire+0x68/0x7c)
> r10:bdb20000 r9:be62df00 r8:00000000 r7:00000000 r6:60000013 r5:bdb20000
> r4:00000000
> [<8006582c>] (lock_acquire) from [<8063c938>] (mutex_lock_nested+0x5c/0x3b8)
> r7:00000000 r6:80dfc78c r5:804be444 r4:bf122928
> [<8063c8dc>] (mutex_lock_nested) from [<804be444>] (snd_soc_suspend+0x34/0x42c)
> r10:00000000 r9:00000000 r8:00000000 r7:bf1c4444 r6:bf1c4410 r5:be978150
> r4:be978010
> [<804be410>] (snd_soc_suspend) from [<8034392c>] (platform_pm_suspend+0x34/0x64)
> r10:00000000 r8:00000000 r7:bf1c4444 r6:bf1c4410 r5:803438f8 r4:bf1c4410
> [<803438f8>] (platform_pm_suspend) from [<80348e18>] (dpm_run_callback.isra.7+0x34/0x6c)
> [<80348de4>] (dpm_run_callback.isra.7) from [<80349354>] (__device_suspend+0x10c/0x220)
> r9:808dd974 r8:808c4a5c r6:00000002 r5:80e5001c r4:bf1c4410
> [<80349248>] (__device_suspend) from [<8034a338>] (dpm_suspend+0x60/0x220)
> r7:bf1c4410 r6:808dd90c r5:80e5001c r4:bf1c44c0
> [<8034a2d8>] (dpm_suspend) from [<8034a790>] (dpm_suspend_start+0x60/0x68)
> r10:8079a818 r9:00000000 r8:00000004 r7:80dfbe90 r6:80641eec r5:00000000
> r4:00000002
> [<8034a730>] (dpm_suspend_start) from [<8006a788>] (suspend_devices_and_enter+0x74/0x318)
> r4:00000003 r3:80dfbe98
> [<8006a714>] (suspend_devices_and_enter) from [<8006abd8>] (pm_suspend+0x1ac/0x244)
> r10:8079a818 r8:00000004 r7:00000003 r6:80641eec r5:00000000 r4:00000003
> [<8006aa2c>] (pm_suspend) from [<80069a4c>] (state_store+0x70/0xc0)
> r5:00000003 r4:bd85ea40
> [<800699dc>] (state_store) from [<80294034>] (kobj_attr_store+0x1c/0x28)
> r10:beb9fe08 r8:00000000 r7:bdb21f78 r6:bd85ea40 r5:00000004 r4:beb9fe00
> [<80294018>] (kobj_attr_store) from [<80140f90>] (sysfs_kf_write+0x54/0x58)
> [<80140f3c>] (sysfs_kf_write) from [<8014474c>] (kernfs_fop_write+0xc4/0x160)
> r6:bd85ea40 r5:beb9fe00 r4:00000004 r3:80140f3c
> [<80144688>] (kernfs_fop_write) from [<800dfa14>] (vfs_write+0xbc/0x184)
> r10:00000000 r9:00000000 r8:00000000 r7:bdb21f78 r6:00500c08 r5:00000004
> r4:be782600
> [<800df958>] (vfs_write) from [<800dfe00>] (SyS_write+0x48/0x70)
> r10:00000000 r8:00000000 r7:00000004 r6:00500c08 r5:00000000 r4:be782600
> [<800dfdb8>] (SyS_write) from [<8000e800>] (ret_fast_syscall+0x0/0x48)
> r9:bdb20000 r8:8000e9c4 r7:00000004 r6:00500c08 r5:00000004 r4:76eb65e0
>
> Fixes: 1abe729 (ASoC: fsl: Add missing pm to current machine drivers)
> Cc: stable at vger.kernel.org
> Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> ---
> sound/soc/fsl/imx-mc13783.c | 1 -
> sound/soc/fsl/imx-sgtl5000.c | 10 ++++++----
> sound/soc/fsl/imx-wm8962.c | 11 +++++++----
> 3 files changed, 13 insertions(+), 9 deletions(-)
>
> diff --git a/sound/soc/fsl/imx-mc13783.c b/sound/soc/fsl/imx-mc13783.c
> index 79cee78..a2fd732 100644
> --- a/sound/soc/fsl/imx-mc13783.c
> +++ b/sound/soc/fsl/imx-mc13783.c
> @@ -160,7 +160,6 @@ static struct platform_driver imx_mc13783_audio_driver = {
> .driver = {
> .name = "imx_mc13783",
> .owner = THIS_MODULE,
> - .pm = &snd_soc_pm_ops,
> },
> .probe = imx_mc13783_probe,
> .remove = imx_mc13783_remove
> diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c
> index f2beae7..1cb22dd 100644
> --- a/sound/soc/fsl/imx-sgtl5000.c
> +++ b/sound/soc/fsl/imx-sgtl5000.c
> @@ -33,8 +33,7 @@ struct imx_sgtl5000_data {
>
> static int imx_sgtl5000_dai_init(struct snd_soc_pcm_runtime *rtd)
> {
> - struct imx_sgtl5000_data *data = container_of(rtd->card,
> - struct imx_sgtl5000_data, card);
> + struct imx_sgtl5000_data *data = snd_soc_card_get_drvdata(rtd->card);
> struct device *dev = rtd->card->dev;
> int ret;
>
> @@ -159,13 +158,15 @@ static int imx_sgtl5000_probe(struct platform_device *pdev)
> data->card.dapm_widgets = imx_sgtl5000_dapm_widgets;
> data->card.num_dapm_widgets = ARRAY_SIZE(imx_sgtl5000_dapm_widgets);
>
> + platform_set_drvdata(pdev, &data->card);
> + snd_soc_card_set_drvdata(&data->card, data);
> +
> ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
> if (ret) {
> dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
> goto fail;
> }
>
> - platform_set_drvdata(pdev, data);
> of_node_put(ssi_np);
> of_node_put(codec_np);
>
> @@ -184,7 +185,8 @@ fail:
>
> static int imx_sgtl5000_remove(struct platform_device *pdev)
> {
> - struct imx_sgtl5000_data *data = platform_get_drvdata(pdev);
> + struct snd_soc_card *card = platform_get_drvdata(pdev);
> + struct imx_sgtl5000_data *data = snd_soc_card_get_drvdata(card);
>
> clk_put(data->codec_clk);
>
> diff --git a/sound/soc/fsl/imx-wm8962.c b/sound/soc/fsl/imx-wm8962.c
> index 3fd76bc..3a3d17c 100644
> --- a/sound/soc/fsl/imx-wm8962.c
> +++ b/sound/soc/fsl/imx-wm8962.c
> @@ -71,7 +71,7 @@ static int imx_wm8962_set_bias_level(struct snd_soc_card *card,
> {
> struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
> struct imx_priv *priv = &card_priv;
> - struct imx_wm8962_data *data = platform_get_drvdata(priv->pdev);
> + struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
> struct device *dev = &priv->pdev->dev;
> unsigned int pll_out;
> int ret;
> @@ -137,7 +137,7 @@ static int imx_wm8962_late_probe(struct snd_soc_card *card)
> {
> struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
> struct imx_priv *priv = &card_priv;
> - struct imx_wm8962_data *data = platform_get_drvdata(priv->pdev);
> + struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
> struct device *dev = &priv->pdev->dev;
> int ret;
>
> @@ -264,13 +264,15 @@ static int imx_wm8962_probe(struct platform_device *pdev)
> data->card.late_probe = imx_wm8962_late_probe;
> data->card.set_bias_level = imx_wm8962_set_bias_level;
>
> + platform_set_drvdata(pdev, &data->card);
> + snd_soc_card_set_drvdata(&data->card, data);
> +
> ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
> if (ret) {
> dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
> goto clk_fail;
> }
>
> - platform_set_drvdata(pdev, data);
> of_node_put(ssi_np);
> of_node_put(codec_np);
>
> @@ -289,7 +291,8 @@ fail:
>
> static int imx_wm8962_remove(struct platform_device *pdev)
> {
> - struct imx_wm8962_data *data = platform_get_drvdata(pdev);
> + struct snd_soc_card *card = platform_get_drvdata(pdev);
> + struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
>
> if (!IS_ERR(data->codec_clk))
> clk_disable_unprepare(data->codec_clk);
> --
> 1.7.9.5
>
>
^ permalink raw reply
* [PATCH v3 5/7] ARM: dts: Exynos: add cpu nodes, opp and cpu clock configuration data
From: Thomas Abraham @ 2014-02-08 5:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52F507CB.6090300@arm.com>
On Fri, Feb 7, 2014 at 9:50 PM, Sudeep Holla <Sudeep.Holla@arm.com> wrote:
> On 07/02/14 15:55, Thomas Abraham wrote:
>> From: Thomas Abraham <thomas.ab@samsung.com>
>>
>> For all Exynos based platforms, add CPU nodes, operating points and cpu
>> clock data for migrating from Exynos specific cpufreq driver to using
>> generic cpufreq-cpu0 driver.
>>
>> Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>
>
> [...]
>
>> diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
>> index 5c412aa..c613fc2 100644
>> --- a/arch/arm/boot/dts/exynos4x12.dtsi
>> +++ b/arch/arm/boot/dts/exynos4x12.dtsi
>> @@ -31,6 +31,42 @@
>> mshc0 = &mshc_0;
>> };
>>
>> + cpus {
>> + #address-cells = <1>;
>> + #size-cells = <0>;
>> + cpu at 0 {
>> + device_type = "cpu";
>> + compatible = "arm,cortex-a9";
>> + reg = <0>;
>> + clocks = <&clock 12>;
>> + clock-names = "cpu";
>> +
>> + operating-points = <
>> + 1500000 1350000
>> + 1400000 1287500
>> + 1300000 1250000
>> + 1200000 1187500
>> + 1100000 1137500
>> + 1000000 1087500
>> + 900000 1037500
>> + 800000 1000000
>> + 700000 987500
>> + 600000 975000
>> + 500000 950000
>> + 400000 925000
>> + 300000 900000
>> + 200000 900000
>> + >;
>> + clock-latency = <200000>;
>> + boost-frequency = <1500000 1350000>;
>
> This is confusing, 1350000 is not in the OPP frequency list or this is still
> following old binding with voltage. Either case this needs to be fixed.
Yes, I missed that. Will fix it. Thanks for your review.
Regards,
Thomas.
>
> Regards,
> Sudeep
>
^ permalink raw reply
* [PATCH] ASoC: fsl: fix pm support of machine drivers
From: Shawn Guo @ 2014-02-08 5:20 UTC (permalink / raw)
To: linux-arm-kernel
The commit 1abe729 (ASoC: fsl: Add missing pm to current machine
drivers) enables pm support for a few IMX machine drivers. But it does
not update dev drvdata to be the pointer to 'card'. This causes the
kernel dump below in system suspend, because snd_soc_suspend() expects
that the dev drvdata points to 'card', while it still points to the
private data of machine driver.
This patch fixes imx-sgtl5000 and imx-wm8962 by attaching 'card' to dev
drvdata and private data to card drvdata. For imx-mc13783, I simply
revert the pm change because it must be broken for the same reason and
I don't have hardware to test pm enabling code.
$ echo mem > /sys/power/state
PM: Syncing filesystems ... done.
PM: Preparing system for mem sleep
mmc1: card e624 removed
Freezing user space processes ... (elapsed 0.002 seconds) done.
Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done.
PM: Entering mem sleep
INFO: trying to register non-static key.
the code is fine but needs lockdep annotation.
turning off the locking correctness validator.
CPU: 0 PID: 1861 Comm: bash Not tainted 3.14.0-rc1+ #1648
Backtrace:
[<80012144>] (dump_backtrace) from [<800122e4>] (show_stack+0x18/0x1c)
r6:8079c77c r5:00000c5a r4:00000000 r3:00000000
[<800122cc>] (show_stack) from [<80637ac0>] (dump_stack+0x78/0x94)
[<80637a48>] (dump_stack) from [<80028918>] (warn_slowpath_common+0x6c/0x8c)
r4:bdb21c38 r3:be62df00
[<800288ac>] (warn_slowpath_common) from [<800289dc>] (warn_slowpath_fmt+0x38/0x40)
r8:be62e3a8 r7:bf122960 r6:00000005 r5:00000000 r4:00000000
[<800289a8>] (warn_slowpath_fmt) from [<8006518c>] (__lock_acquire+0x1ae0/0x1ce0)
r3:8079d598 r2:80799e70
[<800636ac>] (__lock_acquire) from [<80065894>] (lock_acquire+0x68/0x7c)
r10:bdb20000 r9:be62df00 r8:00000000 r7:00000000 r6:60000013 r5:bdb20000
r4:00000000
[<8006582c>] (lock_acquire) from [<8063c938>] (mutex_lock_nested+0x5c/0x3b8)
r7:00000000 r6:80dfc78c r5:804be444 r4:bf122928
[<8063c8dc>] (mutex_lock_nested) from [<804be444>] (snd_soc_suspend+0x34/0x42c)
r10:00000000 r9:00000000 r8:00000000 r7:bf1c4444 r6:bf1c4410 r5:be978150
r4:be978010
[<804be410>] (snd_soc_suspend) from [<8034392c>] (platform_pm_suspend+0x34/0x64)
r10:00000000 r8:00000000 r7:bf1c4444 r6:bf1c4410 r5:803438f8 r4:bf1c4410
[<803438f8>] (platform_pm_suspend) from [<80348e18>] (dpm_run_callback.isra.7+0x34/0x6c)
[<80348de4>] (dpm_run_callback.isra.7) from [<80349354>] (__device_suspend+0x10c/0x220)
r9:808dd974 r8:808c4a5c r6:00000002 r5:80e5001c r4:bf1c4410
[<80349248>] (__device_suspend) from [<8034a338>] (dpm_suspend+0x60/0x220)
r7:bf1c4410 r6:808dd90c r5:80e5001c r4:bf1c44c0
[<8034a2d8>] (dpm_suspend) from [<8034a790>] (dpm_suspend_start+0x60/0x68)
r10:8079a818 r9:00000000 r8:00000004 r7:80dfbe90 r6:80641eec r5:00000000
r4:00000002
[<8034a730>] (dpm_suspend_start) from [<8006a788>] (suspend_devices_and_enter+0x74/0x318)
r4:00000003 r3:80dfbe98
[<8006a714>] (suspend_devices_and_enter) from [<8006abd8>] (pm_suspend+0x1ac/0x244)
r10:8079a818 r8:00000004 r7:00000003 r6:80641eec r5:00000000 r4:00000003
[<8006aa2c>] (pm_suspend) from [<80069a4c>] (state_store+0x70/0xc0)
r5:00000003 r4:bd85ea40
[<800699dc>] (state_store) from [<80294034>] (kobj_attr_store+0x1c/0x28)
r10:beb9fe08 r8:00000000 r7:bdb21f78 r6:bd85ea40 r5:00000004 r4:beb9fe00
[<80294018>] (kobj_attr_store) from [<80140f90>] (sysfs_kf_write+0x54/0x58)
[<80140f3c>] (sysfs_kf_write) from [<8014474c>] (kernfs_fop_write+0xc4/0x160)
r6:bd85ea40 r5:beb9fe00 r4:00000004 r3:80140f3c
[<80144688>] (kernfs_fop_write) from [<800dfa14>] (vfs_write+0xbc/0x184)
r10:00000000 r9:00000000 r8:00000000 r7:bdb21f78 r6:00500c08 r5:00000004
r4:be782600
[<800df958>] (vfs_write) from [<800dfe00>] (SyS_write+0x48/0x70)
r10:00000000 r8:00000000 r7:00000004 r6:00500c08 r5:00000000 r4:be782600
[<800dfdb8>] (SyS_write) from [<8000e800>] (ret_fast_syscall+0x0/0x48)
r9:bdb20000 r8:8000e9c4 r7:00000004 r6:00500c08 r5:00000004 r4:76eb65e0
Fixes: 1abe729 (ASoC: fsl: Add missing pm to current machine drivers)
Cc: stable at vger.kernel.org
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
---
sound/soc/fsl/imx-mc13783.c | 1 -
sound/soc/fsl/imx-sgtl5000.c | 10 ++++++----
sound/soc/fsl/imx-wm8962.c | 11 +++++++----
3 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/sound/soc/fsl/imx-mc13783.c b/sound/soc/fsl/imx-mc13783.c
index 79cee78..a2fd732 100644
--- a/sound/soc/fsl/imx-mc13783.c
+++ b/sound/soc/fsl/imx-mc13783.c
@@ -160,7 +160,6 @@ static struct platform_driver imx_mc13783_audio_driver = {
.driver = {
.name = "imx_mc13783",
.owner = THIS_MODULE,
- .pm = &snd_soc_pm_ops,
},
.probe = imx_mc13783_probe,
.remove = imx_mc13783_remove
diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c
index f2beae7..1cb22dd 100644
--- a/sound/soc/fsl/imx-sgtl5000.c
+++ b/sound/soc/fsl/imx-sgtl5000.c
@@ -33,8 +33,7 @@ struct imx_sgtl5000_data {
static int imx_sgtl5000_dai_init(struct snd_soc_pcm_runtime *rtd)
{
- struct imx_sgtl5000_data *data = container_of(rtd->card,
- struct imx_sgtl5000_data, card);
+ struct imx_sgtl5000_data *data = snd_soc_card_get_drvdata(rtd->card);
struct device *dev = rtd->card->dev;
int ret;
@@ -159,13 +158,15 @@ static int imx_sgtl5000_probe(struct platform_device *pdev)
data->card.dapm_widgets = imx_sgtl5000_dapm_widgets;
data->card.num_dapm_widgets = ARRAY_SIZE(imx_sgtl5000_dapm_widgets);
+ platform_set_drvdata(pdev, &data->card);
+ snd_soc_card_set_drvdata(&data->card, data);
+
ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
if (ret) {
dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
goto fail;
}
- platform_set_drvdata(pdev, data);
of_node_put(ssi_np);
of_node_put(codec_np);
@@ -184,7 +185,8 @@ fail:
static int imx_sgtl5000_remove(struct platform_device *pdev)
{
- struct imx_sgtl5000_data *data = platform_get_drvdata(pdev);
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+ struct imx_sgtl5000_data *data = snd_soc_card_get_drvdata(card);
clk_put(data->codec_clk);
diff --git a/sound/soc/fsl/imx-wm8962.c b/sound/soc/fsl/imx-wm8962.c
index 3fd76bc..3a3d17c 100644
--- a/sound/soc/fsl/imx-wm8962.c
+++ b/sound/soc/fsl/imx-wm8962.c
@@ -71,7 +71,7 @@ static int imx_wm8962_set_bias_level(struct snd_soc_card *card,
{
struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
struct imx_priv *priv = &card_priv;
- struct imx_wm8962_data *data = platform_get_drvdata(priv->pdev);
+ struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
struct device *dev = &priv->pdev->dev;
unsigned int pll_out;
int ret;
@@ -137,7 +137,7 @@ static int imx_wm8962_late_probe(struct snd_soc_card *card)
{
struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
struct imx_priv *priv = &card_priv;
- struct imx_wm8962_data *data = platform_get_drvdata(priv->pdev);
+ struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
struct device *dev = &priv->pdev->dev;
int ret;
@@ -264,13 +264,15 @@ static int imx_wm8962_probe(struct platform_device *pdev)
data->card.late_probe = imx_wm8962_late_probe;
data->card.set_bias_level = imx_wm8962_set_bias_level;
+ platform_set_drvdata(pdev, &data->card);
+ snd_soc_card_set_drvdata(&data->card, data);
+
ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
if (ret) {
dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
goto clk_fail;
}
- platform_set_drvdata(pdev, data);
of_node_put(ssi_np);
of_node_put(codec_np);
@@ -289,7 +291,8 @@ fail:
static int imx_wm8962_remove(struct platform_device *pdev)
{
- struct imx_wm8962_data *data = platform_get_drvdata(pdev);
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+ struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
if (!IS_ERR(data->codec_clk))
clk_disable_unprepare(data->codec_clk);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v3 1/7] cpufreq: cpufreq-cpu0: allow use of optional boost mode frequencies
From: Thomas Abraham @ 2014-02-08 5:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52F506EC.2070907@ti.com>
On Fri, Feb 7, 2014 at 9:46 PM, Nishanth Menon <nm@ti.com> wrote:
> On 02/07/2014 09:55 AM, Thomas Abraham wrote:
>> From: Thomas Abraham <thomas.ab@samsung.com>
>>
>> Lookup for the optional boost-frequency property in cpu0 node and if
>> available, enable support for boost mode frequencies. The frequencies
>> usable in boost mode are determined while preparing the cpufreq table
>> from the list of operating points available.
>>
>> In addition to this, enable the CPU_FREQ_BOOST_SW config option for
>> this driver by default. On platforms that do not support boost mode,
>> the boost mode frequencies will not be specified in cpu0 node and
>> hence the boost mode support will not be enabled. Since this driver
>> anyways depends on THERMAL config option, it is safe to enable
>> CPU_FREQ_BOOST_SW config option as default.
>>
>> Cc: Shawn Guo <shawn.guo@linaro.org>
>> Cc: Lukasz Majewski <l.majewski@samsung.com>
>> Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>
>> ---
>> Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt | 2 ++
>> drivers/cpufreq/Kconfig | 1 +
>> drivers/cpufreq/cpufreq-cpu0.c | 3 +++
>> 3 files changed, 6 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt b/Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt
>> index f055515..60f321a 100644
>> --- a/Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt
>> +++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-cpu0.txt
>> @@ -19,6 +19,8 @@ Optional properties:
>> - cooling-min-level:
>> - cooling-max-level:
>> Please refer to Documentation/devicetree/bindings/thermal/thermal.txt.
>> +- boost-frequency:
>> + Please refer to Documentation/devicetree/bindings/cpufreq/cpufreq-boost.txt
>>
>> Examples:
>>
>> diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
>> index 4b029c0..52cc704 100644
>> --- a/drivers/cpufreq/Kconfig
>> +++ b/drivers/cpufreq/Kconfig
>> @@ -187,6 +187,7 @@ config GENERIC_CPUFREQ_CPU0
>> tristate "Generic CPU0 cpufreq driver"
>> depends on HAVE_CLK && REGULATOR && OF && THERMAL && CPU_THERMAL
>> select PM_OPP
>> + select CPU_FREQ_BOOST_SW
>> help
>> This adds a generic cpufreq driver for CPU0 frequency management.
>> It supports both uniprocessor (UP) and symmetric multiprocessor (SMP)
>> diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c
>> index 0c12ffc..06539eb 100644
>> --- a/drivers/cpufreq/cpufreq-cpu0.c
>> +++ b/drivers/cpufreq/cpufreq-cpu0.c
>> @@ -195,6 +195,9 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev)
>> transition_latency += ret * 1000;
>> }
>>
>> + if (of_find_property(cpu_dev->of_node, "boost-frequency", NULL))
>> + cpu0_cpufreq_driver.boost_supported = true;
>> +
>> ret = cpufreq_register_driver(&cpu0_cpufreq_driver);
>> if (ret) {
>> pr_err("failed register driver: %d\n", ret);
>>
>
> might as well hide that under the opp api which returns a bool that
> says if boost is supported or not. that allows the parse to be
> isolated to a single location.
This is specific to the cpufreq-cpu0 driver. Other cpufreq drivers
might want to use other methods and additional constraints to
determine if boost has to be enabled.
Thanks,
Thomas.
>
> --
> Regards,
> Nishanth Menon
^ permalink raw reply
* [PATCH v2 1/2] PM / OPP: Allow boost frequency to be looked up from device tree
From: Thomas Abraham @ 2014-02-08 5:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52F50346.7040707@arm.com>
On Fri, Feb 7, 2014 at 9:31 PM, Sudeep Holla <Sudeep.Holla@arm.com> wrote:
> On 07/02/14 15:19, Thomas Abraham wrote:
>> From: Thomas Abraham <thomas.ab@samsung.com>
>>
>> Commit 6f19efc0 ("cpufreq: Add boost frequency support in core") adds
>> support for CPU boost mode. This patch adds support for finding available
>> boost frequencies from device tree and marking them as usable in boost mode.
>>
>> Cc: Nishanth Menon <nm@ti.com>
>> Cc: Lukasz Majewski <l.majewski@samsung.com>
>> Signed-off-by: Thomas Abraham <thomas.ab@samsung.com>
>> ---
>> drivers/base/power/opp.c | 34 +++++++++++++++++++++++++++++++++-
>> 1 file changed, 33 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c
>> index fa41874..b636826 100644
>> --- a/drivers/base/power/opp.c
>> +++ b/drivers/base/power/opp.c
>> @@ -628,7 +628,8 @@ int dev_pm_opp_init_cpufreq_table(struct device *dev,
>> struct device_opp *dev_opp;
>> struct dev_pm_opp *opp;
>> struct cpufreq_frequency_table *freq_table;
>> - int i = 0;
>> + int i = 0, j, len, ret;
>> + u32 *boost_freqs = NULL;
>>
>> /* Pretend as if I am an updater */
>> mutex_lock(&dev_opp_list_lock);
>> @@ -650,10 +651,35 @@ int dev_pm_opp_init_cpufreq_table(struct device *dev,
>> return -ENOMEM;
>> }
>>
>> + if (of_find_property(dev->of_node, "boost-frequency", &len)) {
>> + if (len == 0 || (len & (sizeof(u32) - 1)) != 0) {
>> + dev_err(dev, "%s: invalid boost frequency\n", __func__);
>> + ret = -EINVAL;
>> + goto err_boost;
>> + }
>> +
>> + boost_freqs = kzalloc(len, GFP_KERNEL);
>> + if (!boost_freqs) {
>> + dev_warn(dev, "%s: no memory for boost freq table\n",
>> + __func__);
>> + ret = -ENOMEM;
>> + goto err_boost;
>> + }
>> + of_property_read_u32_array(dev->of_node, "boost-frequency",
>> + boost_freqs, len / sizeof(u32));
>> + }
>> +
>> list_for_each_entry(opp, &dev_opp->opp_list, node) {
>> if (opp->available) {
>> freq_table[i].driver_data = i;
>> freq_table[i].frequency = opp->rate / 1000;
>> + for (j = 0; j < len / sizeof(u32) && boost_freqs; j++) {
>> + if (boost_freqs[j] == freq_table[i].frequency) {
>> + freq_table[i].driver_data =
>> + CPUFREQ_BOOST_FREQ;
>> + break;
>> + }
>> + }
>> i++;
>> }
>> }
> IIRC you had mentioned that the boost-opp was not limited to be a cpufreq, but
> this change seems to be cpufreq only.
Yes, but as you have initiated the discussion on extending the OPP
binding, this has been limited to cpufreq only. If the new OPP library
has support for listing boost frequency, this can be migrated to the
new OPP libaray.
Thanks,
Thomas.
>
> Regards,
> Sudeep
>
^ permalink raw reply
* [alsa-devel] v3.14-rc1 locking bug in system suspend
From: Shawn Guo @ 2014-02-08 4:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140206145509.GB6610@S2101-09.ap.freescale.net>
On Thu, Feb 06, 2014 at 10:55:13PM +0800, Shawn Guo wrote:
> On Wed, Feb 05, 2014 at 10:54:10PM +0800, Shawn Guo wrote:
> > I start seeing the following locking bug on IMX6 with suspend operation
> > after moving to v3.14-rc1. Before I start looking into the issue, I
> > would like to confirm if it's an IMX specific problem or one seen on
> > other platforms. Please ask if you need more info.
>
> Sorry. This is not a new bug of v3.14-rc1. It's been there with
> v3.13-rc for a while. It looks like there is something wrong in the
> use of power_lock in struct snd_card. Will dig into it.
Okay. This is an IMX specific problem caused by audio driver. I will
send a fix to alsa-devel list shortly.
Shawn
^ permalink raw reply
* [linux-sunxi] [PATCH v2] ARM: sunxi: Add driver for sunxi usb phy
From: Chen-Yu Tsai @ 2014-02-08 4:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391790801-27864-1-git-send-email-hdegoede@redhat.com>
On Sat, Feb 8, 2014 at 12:33 AM, Hans de Goede <hdegoede@redhat.com> wrote:
> The Allwinner A1x / A2x SoCs have 2 or 3 usb phys which are all accessed
> through a single set of registers. Besides this there are also some other
> phy related bits which need poking, which are per phy, but shared between the
> ohci and ehci controllers, so these are also controlled from this new phy
> driver.
>
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
> .../devicetree/bindings/phy/sun4i-usb-phy.txt | 28 ++
> drivers/phy/Kconfig | 11 +
> drivers/phy/Makefile | 1 +
> drivers/phy/phy-sun4i-usb.c | 326 +++++++++++++++++++++
> 4 files changed, 366 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt
> create mode 100644 drivers/phy/phy-sun4i-usb.c
>
[...]
> diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
> new file mode 100644
> index 0000000..bd9cb7fa
> --- /dev/null
> +++ b/drivers/phy/phy-sun4i-usb.c
> @@ -0,0 +1,326 @@
> +/*
> + * Allwinner sun4i USB phy driver
> + *
> + * Copyright (C) 2014 Hans de Goede <hdegoede@redhat.com>
> + *
> + * Based on code from
> + * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
> + *
> + * Modelled after: Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY driver
> + * Copyright (C) 2013 Samsung Electronics Co., Ltd.
> + * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/reset.h>
> +
> +#define REG_ISCR 0x00
> +#define REG_PHYCTL 0x04
> +#define REG_PHYBIST 0x08
> +#define REG_PHYTUNE 0x0c
> +
> +#define SUNXI_AHB_ICHR8_EN BIT(10)
> +#define SUNXI_AHB_INCR4_BURST_EN BIT(9)
> +#define SUNXI_AHB_INCRX_ALIGN_EN BIT(8)
> +#define SUNXI_ULPI_BYPASS_EN BIT(0)
> +
> +/* Common Control Bits for Both PHYs */
> +#define PHY_PLL_BW 0x03
> +#define PHY_RES45_CAL_EN 0x0c
> +
> +/* Private Control Bits for Each PHY */
> +#define PHY_TX_AMPLITUDE_TUNE 0x20
> +#define PHY_TX_SLEWRATE_TUNE 0x22
> +#define PHY_VBUSVALID_TH_SEL 0x25
> +#define PHY_PULLUP_RES_SEL 0x27
> +#define PHY_OTG_FUNC_EN 0x28
> +#define PHY_VBUS_DET_EN 0x29
> +#define PHY_DISCON_TH_SEL 0x2a
> +
> +#define MAX_PHYS 3
> +
> +struct sun4i_usb_phy_data {
> + struct clk *clk;
> + void __iomem *base;
> + struct mutex mutex;
> + int num_phys;
> + u32 disc_thresh;
> + struct sun4i_usb_phy {
> + struct phy *phy;
> + void __iomem *pmu;
> + struct regulator *vbus;
> + struct reset_control *reset;
> + int index;
> + } phys[MAX_PHYS];
> +};
> +
> +#define to_sun4i_usb_phy_data(phy) \
> + container_of((phy), struct sun4i_usb_phy_data, phys[(phy)->index])
> +
> +static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data,
> + int len)
> +{
> + struct sun4i_usb_phy_data *phy_data = to_sun4i_usb_phy_data(phy);
> + u32 temp, usbc_bit = BIT(phy->index * 2);
> + int i;
> +
> + mutex_lock(&phy_data->mutex);
> +
> + for (i = 0; i < len; i++) {
> + temp = readl(phy_data->base + REG_PHYCTL);
> +
> + /* clear the address portion */
> + temp &= ~(0xff << 8);
> +
> + /* set the address */
> + temp |= ((addr + i) << 8);
> + writel(temp, phy_data->base + REG_PHYCTL);
> +
> + /* set the data bit and clear usbc bit*/
> + temp = readb(phy_data->base + REG_PHYCTL);
> + if (data & 0x1)
> + temp |= BIT(7);
> + else
> + temp &= ~BIT(7);
> + temp &= ~usbc_bit;
> + writeb(temp, phy_data->base + REG_PHYCTL);
> +
> + /* pulse usbc_bit */
> + temp = readb(phy_data->base + REG_PHYCTL);
> + temp |= usbc_bit;
> + writeb(temp, phy_data->base + REG_PHYCTL);
> +
> + temp = readb(phy_data->base + REG_PHYCTL);
> + temp &= ~usbc_bit;
> + writeb(temp, phy_data->base + REG_PHYCTL);
> +
> + data >>= 1;
> + }
> + mutex_unlock(&phy_data->mutex);
> +}
> +
> +static void sun4i_usb_phy_passby(struct sun4i_usb_phy *phy, int enable)
> +{
> + u32 bits, reg_value;
> +
> + if (!phy->pmu)
> + return;
> +
> + bits = SUNXI_AHB_ICHR8_EN | SUNXI_AHB_INCR4_BURST_EN |
> + SUNXI_AHB_INCRX_ALIGN_EN | SUNXI_ULPI_BYPASS_EN;
> +
> + reg_value = readl(phy->pmu);
> +
> + if (enable)
> + reg_value |= bits;
> + else
> + reg_value &= ~bits;
> +
> + writel(reg_value, phy->pmu);
> +}
> +
> +static int sun4i_usb_phy_init(struct phy *_phy)
> +{
> + struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
> + struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
> + int ret;
> +
> + ret = clk_prepare_enable(data->clk);
> + if (ret)
> + return ret;
> +
> + ret = reset_control_deassert(phy->reset);
> + if (ret) {
> + clk_disable_unprepare(data->clk);
> + return ret;
> + }
> +
> + /* Adjust PHY's magnitude and rate */
> + sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5);
> +
> + /* Disconnect threshold adjustment */
> + sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL, data->disc_thresh, 2);
> +
> + sun4i_usb_phy_passby(phy, 1);
> +
> + return 0;
> +}
> +
> +static int sun4i_usb_phy_exit(struct phy *_phy)
> +{
> + struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
> + struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
> +
> + sun4i_usb_phy_passby(phy, 0);
> + reset_control_assert(phy->reset);
> + clk_disable_unprepare(data->clk);
> +
> + return 0;
> +}
> +
> +static int sun4i_usb_phy_power_on(struct phy *_phy)
> +{
> + struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
> + int ret = 0;
> +
> + if (phy->vbus)
> + ret = regulator_enable(phy->vbus);
> +
> + return ret;
> +}
> +
> +static int sun4i_usb_phy_power_off(struct phy *_phy)
> +{
> + struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
> +
> + if (phy->vbus)
> + regulator_disable(phy->vbus);
> +
> + return 0;
> +}
> +
> +static struct phy_ops sun4i_usb_phy_ops = {
> + .init = sun4i_usb_phy_init,
> + .exit = sun4i_usb_phy_exit,
> + .power_on = sun4i_usb_phy_power_on,
> + .power_off = sun4i_usb_phy_power_off,
> + .owner = THIS_MODULE,
> +};
> +
> +static struct phy *sun4i_usb_phy_xlate(struct device *dev,
> + struct of_phandle_args *args)
> +{
> + struct sun4i_usb_phy_data *data = dev_get_drvdata(dev);
> +
> + if (WARN_ON(args->args[0] == 0 || args->args[0] >= data->num_phys))
> + return ERR_PTR(-ENODEV);
> +
> + return data->phys[args->args[0]].phy;
> +}
> +
> +static int sun4i_usb_phy_probe(struct platform_device *pdev)
> +{
> + struct sun4i_usb_phy_data *data;
> + struct device *dev = &pdev->dev;
> + struct device_node *np = dev->of_node;
> + void __iomem *pmu = NULL;
> + struct phy_provider *phy_provider;
> + struct reset_control *reset;
> + struct regulator *vbus;
> + struct phy *phy;
> + char name[16];
> + int i;
> +
> + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
> + if (!data)
> + return -ENOMEM;
> +
> + mutex_init(&data->mutex);
> +
> + if (of_device_is_compatible(np, "allwinner,sun5i-a13-usb-phy"))
> + data->num_phys = 2;
> + else
> + data->num_phys = 3;
> +
> + if (of_device_is_compatible(np, "allwinner,sun4i-a10-usb-phy"))
> + data->disc_thresh = 3;
> + else
> + data->disc_thresh = 2;
> +
> + data->clk = devm_clk_get(dev, "usb_phy");
> + if (IS_ERR(data->clk)) {
> + dev_err(dev, "could not get usb_phy clock\n");
> + return PTR_ERR(data->clk);
> + }
> +
> + /* Skip 0, 0 is the phy for otg which is not yet supported. */
> + for (i = 1; i < data->num_phys; i++) {
> + snprintf(name, sizeof(name), "usb%d_vbus", i);
> + vbus = devm_regulator_get_optional(dev, name);
> + if (IS_ERR(vbus)) {
> + if (PTR_ERR(vbus) == -EPROBE_DEFER)
> + return -EPROBE_DEFER;
> + vbus = NULL;
> + }
> +
> + snprintf(name, sizeof(name), "usb%d_reset", i);
> + reset = devm_reset_control_get(dev, name);
> + if (IS_ERR(phy)) {
> + dev_err(dev, "failed to get reset %s\n", name);
> + return PTR_ERR(phy);
> + }
Wrong variable checked for error here that I pointed out before is still wrong.
Cheers
ChenYu
> +
> + if (i) { /* No pmu for usbc0 */
> + pmu = devm_ioremap_resource(dev,
> + platform_get_resource(pdev, IORESOURCE_MEM, i));
> + if (IS_ERR(pmu))
> + return PTR_ERR(pmu);
> + }
> +
> + phy = devm_phy_create(dev, &sun4i_usb_phy_ops, NULL);
> + if (IS_ERR(phy)) {
> + dev_err(dev, "failed to create PHY %d\n", i);
> + return PTR_ERR(phy);
> + }
> +
> + data->phys[i].phy = phy;
> + data->phys[i].pmu = pmu;
> + data->phys[i].vbus = vbus;
> + data->phys[i].reset = reset;
> + data->phys[i].index = i;
> + phy_set_drvdata(phy, &data->phys[i]);
> + }
> +
> + data->base = devm_ioremap_resource(dev,
> + platform_get_resource(pdev, IORESOURCE_MEM, 0));
> + if (IS_ERR(data->base))
> + return PTR_ERR(data->base);
> +
> + dev_set_drvdata(dev, data);
> + phy_provider = devm_of_phy_provider_register(dev, sun4i_usb_phy_xlate);
> + if (IS_ERR(phy_provider))
> + return PTR_ERR(phy_provider);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id sun4i_usb_phy_of_match[] = {
> + { .compatible = "allwinner,sun4i-a10-usb-phy" },
> + { .compatible = "allwinner,sun5i-a13-usb-phy" },
> + { .compatible = "allwinner,sun7i-a20-usb-phy" },
> + { },
> +};
> +MODULE_DEVICE_TABLE(of, sun4i_usb_phy_of_match);
> +
> +static struct platform_driver sun4i_usb_phy_driver = {
> + .probe = sun4i_usb_phy_probe,
> + .driver = {
> + .of_match_table = sun4i_usb_phy_of_match,
> + .name = "sun4i-usb-phy",
> + .owner = THIS_MODULE,
> + }
> +};
> +module_platform_driver(sun4i_usb_phy_driver);
> +
> +MODULE_DESCRIPTION("Allwinner sun4i USB phy driver");
> +MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
> +MODULE_LICENSE("GPL v2");
> --
> 1.8.4.2
>
> --
> You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe at googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
^ permalink raw reply
* [PATCH] ARM: dts: qcom: Add RNG device tree node
From: Stephen Boyd @ 2014-02-08 3:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391764987-17138-1-git-send-email-svarbanov@mm-sol.com>
On 02/07, Stanimir Varbanov wrote:
> Add the necessary DT node to probe the rng driver on
> msm8974 platforms.
>
Looks good. We should add it to msm8960-cdp and enable the driver
in the defconfig as well.
> Signed-off-by: Stanimir Varbanov <svarbanov@mm-sol.com>
Acked-by: Stephen Boyd <sboyd@codeaurora.org>
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
^ permalink raw reply
* [PATCH v3 3/5] ARM: qcom: Split Qualcomm support into legacy and multiplatform
From: Stephen Boyd @ 2014-02-08 3:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391725484-6673-4-git-send-email-galak@codeaurora.org>
On 02/06, Kumar Gala wrote:
> diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-qcom/platsmp.c
> similarity index 98%
> rename from arch/arm/mach-msm/platsmp.c
> rename to arch/arm/mach-qcom/platsmp.c
> index 251a91e..67823a7 100644
> --- a/arch/arm/mach-msm/platsmp.c
> +++ b/arch/arm/mach-qcom/platsmp.c
> @@ -2,6 +2,7 @@
> * Copyright (C) 2002 ARM Ltd.
> * All Rights Reserved
> * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
> + * Copyright (c) 2014 The Linux Foundation. All rights reserved.
We should replace the Code Aurora Forum copyright with Linux
Foundation here.
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
^ permalink raw reply
* [Patch v5 1/2] dmaengine: add Qualcomm BAM dma driver
From: Stephen Boyd @ 2014-02-08 2:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391546556-27702-2-git-send-email-agross@codeaurora.org>
On 02/04, Andy Gross wrote:
> diff --git a/drivers/dma/qcom_bam_dma.c b/drivers/dma/qcom_bam_dma.c
> new file mode 100644
> index 0000000..214250c
> --- /dev/null
> +++ b/drivers/dma/qcom_bam_dma.c
> @@ -0,0 +1,1066 @@
> +/*
> + * QCOM BAM DMA engine driver
Can you please move this down into the comment below?
> + *
> + * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only 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.
> + *
And split this out into its own comment block? I think this will
make the lawyers happier.
> + *
> + * QCOM BAM DMA blocks are distributed amongst a number of the on-chip
> + * peripherals on the MSM 8x74. The configuration of the channels are dependent
> + * on the way they are hard wired to that specific peripheral. The peripheral
> + * device tree entries specify the configuration of each channel.
> + *
> + * The DMA controller requires the use of external memory for storage of the
> + * hardware descriptors for each channel. The descriptor FIFO is accessed as a
> + * circular buffer and operations are managed according to the offset within the
> + * FIFO. After pipe/channel reset, all of the pipe registers and internal state
> + * are back to defaults.
> + *
> + * During DMA operations, we write descriptors to the FIFO, being careful to
> + * handle wrapping and then write the last FIFO offset to that channel's
> + * P_EVNT_REG register to kick off the transaction. The P_SW_OFSTS register
> + * indicates the current FIFO offset that is being processed, so there is some
> + * indication of where the hardware is currently working.
> + */
[...]
> +
> +/* PIPE CTRL */
> +#define P_EN BIT(1)
^^^^
Nitpick: Weird tab here?
> +
> +/**
> + * bam_start_dma - start next transaction
> + * @bchan - bam dma channel
> + *
> + * Note: must hold bam dma channel vc.lock
You can use lockdep_assert_held() here to document this
requirement and test for it at runtime.
> + */
> +static void bam_start_dma(struct bam_chan *bchan)
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
^ permalink raw reply
* [PATCH v2 00/12] Samsung PM consolidation part 2 (multiplatform)
From: Tomasz Figa @ 2014-02-08 2:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAD=FV=UPH4vf2-5GuOypkkbMsDPmM7dPZJtFpHs+wBsN0wy8=Q@mail.gmail.com>
Hi Doug,
On 08.02.2014 01:51, Doug Anderson wrote:
> Tomasz,
>
> On Fri, Feb 7, 2014 at 3:59 PM, Tomasz Figa <tomasz.figa@gmail.com> wrote:
>>
>>
>> On 07.02.2014 23:15, Olof Johansson wrote:
>>>
>>> On Thu, Feb 06, 2014 at 08:12:45PM +0100, Tomasz Figa wrote:
>>>
>>>> On Exynos4210-based Trats, Exynos4412-based Trats2 and Exynos5250-based
>>>> Arndale boards (except suspend/resume, which is broken because of
>>>> unrelated reasons):
>>>
>>>
>>> Has this been reported, and is it being worked on by anyone?
>>
>>
>> Yes, reported quite a long time ago by Vikas Sajjan of Samsung/Linaro, but
>> I'm not sure if anybody is working to fix it.
>>
>> I've been looking into this for a while, but couldn't really find anything
>> except that it hangs when PMU starts power state transtion after CPU
>> executing WFI instruction.
>
> It's likely it's something else, but just in case I'll point you to a
> bug that we fixed that had the same symptom. There's some details
> (and a lot of noise) in <http://crbug.com/218132>. ...or maybe just
> look at the root cause at <http://crosreview.com/42067>.
OK. Thanks for pointing me to this. Will do some more tests back at the
office after the weekend.
Best regards,
Tomasz
^ permalink raw reply
* [PATCH v2 00/12] Samsung PM consolidation part 2 (multiplatform)
From: Doug Anderson @ 2014-02-08 0:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52F57372.7010507@gmail.com>
Tomasz,
On Fri, Feb 7, 2014 at 3:59 PM, Tomasz Figa <tomasz.figa@gmail.com> wrote:
>
>
> On 07.02.2014 23:15, Olof Johansson wrote:
>>
>> On Thu, Feb 06, 2014 at 08:12:45PM +0100, Tomasz Figa wrote:
>>
>>> On Exynos4210-based Trats, Exynos4412-based Trats2 and Exynos5250-based
>>> Arndale boards (except suspend/resume, which is broken because of
>>> unrelated reasons):
>>
>>
>> Has this been reported, and is it being worked on by anyone?
>
>
> Yes, reported quite a long time ago by Vikas Sajjan of Samsung/Linaro, but
> I'm not sure if anybody is working to fix it.
>
> I've been looking into this for a while, but couldn't really find anything
> except that it hangs when PMU starts power state transtion after CPU
> executing WFI instruction.
It's likely it's something else, but just in case I'll point you to a
bug that we fixed that had the same symptom. There's some details
(and a lot of noise) in <http://crbug.com/218132>. ...or maybe just
look at the root cause at <http://crosreview.com/42067>.
-Doug
^ permalink raw reply
* [PATCH RFC 0/2] drivers/base: simplify simple DT-based components
From: Russell King - ARM Linux @ 2014-02-08 0:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140207185911.GG26684@n2100.arm.linux.org.uk>
On Fri, Feb 07, 2014 at 06:59:11PM +0000, Russell King - ARM Linux wrote:
> Sorry. Deferred probe does work, it's been tested with imx-drm, not
> only from the master component but also the sub-components. There's
> no problem here.
Here's the proof that it also works with the Cubox, and armada DRM:
[drm] Initialized drm 1.1.0 20060810
...
armada-drm armada-510-drm: master bind failed: -517
i2c 0-0070: Driver tda998x requests probe deferral
...
tda998x 0-0070: found TDA19988
armada-drm armada-510-drm: bound 0-0070 (ops tda998x_ops)
So, in the above sequence, the armada DRM driver was bound to its driver
initially, but the TDA998x driver wasn't.
Then, the TDA998x driver is bound, which completes the requirements for
the DRM master. So the system attempts to bind.
In doing so, the master probe function discovers a missing clock (because
the SIL5531 driver hasn't probed) and it returns -EPROBE_DEFER. This
causes the probe of the TDA998x to be deferred.
Later, deferred probes are run - at this time the SIL5531 driver has
probed its device, and the clocks are now available. So when the TDA998x
driver is re-probed, it retriggers the binding attempt, and as the clock
can now be found, the system is bound and the DRM system for the device
is initialised.
I've just committed a patch locally which makes Armada DRM fully use
the component helper, which removes in totality the four armada_output.*
and armada_slave.* files since they're no longer required:
[cubox-3.13 e2713ff5ac2f] DRM: armada: remove non-component support
7 files changed, 8 insertions(+), 437 deletions(-)
delete mode 100644 drivers/gpu/drm/armada/armada_output.c
delete mode 100644 drivers/gpu/drm/armada/armada_output.h
delete mode 100644 drivers/gpu/drm/armada/armada_slave.c
delete mode 100644 drivers/gpu/drm/armada/armada_slave.h
--
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
* [PATCH] pci: Add support for creating a generic host_bridge from device tree
From: Tanmay Inamdar @ 2014-02-08 0:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140206101814.GA4993@e106497-lin.cambridge.arm.com>
On Thu, Feb 6, 2014 at 2:18 AM, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> On Wed, Feb 05, 2014 at 10:26:27PM +0000, Tanmay Inamdar wrote:
>> Hello Liviu,
>>
>> I did not get the first email of this particular patch on any of
>> subscribed mailing lists (don't know why), hence replying here.
>
> Strange, it shows in the MARC and GMANE archive for linux-pci, probably
> a hickup on your receiving side?
>
>>
>> +struct pci_host_bridge *
>> +pci_host_bridge_of_init(struct device *parent, int busno, struct pci_ops *ops,
>> + void *host_data, struct list_head *resources)
>> +{
>> + struct pci_bus *root_bus;
>> + struct pci_host_bridge *bridge;
>> +
>> + /* first parse the host bridge bus ranges */
>> + if (pci_host_bridge_of_get_ranges(parent->of_node, resources))
>> + return NULL;
>> +
>> + /* then create the root bus */
>> + root_bus = pci_create_root_bus(parent, busno, ops, host_data, resources);
>> + if (!root_bus)
>> + return NULL;
>> +
>> + bridge = to_pci_host_bridge(root_bus->bridge);
>> +
>> + return bridge;
>> +}
>>
>> You are keeping the domain_nr inside pci_host_bridge structure. In
>> above API, domain_nr is required in 'pci_find_bus' function called
>> from 'pci_create_root_bus'. Since the bridge is allocated after
>> creating root bus, 'pci_find_bus' always gets domain_nr as 0. This
>> will cause problem for scanning multiple domains.
>
> Good catch. I was switching between creating a pci_controller in arch/arm64 and
> adding the needed bits in pci_host_bridge. After internal review I've decided to
> add the domain_nr to pci_host_bridge, but forgot to update the code everywhere.
>
> Thanks for reviewing this, will fix in v2.
>
> Do you find porting to the new API straight forward?
It is quite straight forward for MEM regions but for IO regions it is
not. You always assume IO resource starting at 0x0. IMO, this will
cause problem for systems with multiple ports / IO windows. You can
take a look at 'drivers/pci/host/pcie-designware.c'.
Also the manipulations of addresses for IO_RESOURCES can be dangerous.
It can make some value negative. For example if my PCI IO range starts
in 32 bit address range say 0x8000_0000 with CPU address
0xb0_8000_0000, window->offset after manipulation will become
negative.
Personally I would like to do get all the PCI and CPU addresses from
my device tree as is and do the 'pci_add_resource_offset'. This will
help me setup my regions correctly without any further arithmetic.
Please let me know what you think.
>
> Best regards,
> Liviu
>
>>
>>
>> On Mon, Feb 3, 2014 at 10:46 AM, Arnd Bergmann <arnd@arndb.de> wrote:
>> > On Monday 03 February 2014 18:33:48 Liviu Dudau wrote:
>> >> +/**
>> >> + * pci_host_bridge_of_get_ranges - Parse PCI host bridge resources from DT
>> >> + * @dev: device node of the host bridge having the range property
>> >> + * @resources: list where the range of resources will be added after DT parsing
>> >> + *
>> >> + * This function will parse the "ranges" property of a PCI host bridge device
>> >> + * node and setup the resource mapping based on its content. It is expected
>> >> + * that the property conforms with the Power ePAPR document.
>> >> + *
>> >> + * Each architecture will then apply their filtering based on the limitations
>> >> + * of each platform. One general restriction seems to be the number of IO space
>> >> + * ranges, the PCI framework makes intensive use of struct resource management,
>> >> + * and for IORESOURCE_IO types they can only be requested if they are contained
>> >> + * within the global ioport_resource, so that should be limited to one IO space
>> >> + * range.
>> >
>> > Actually we have quite a different set of restrictions around I/O space on ARM32
>> > at the moment: Each host bridge can have its own 64KB range in an arbitrary
>> > location on MMIO space, and the total must not exceed 2MB of I/O space.
>> >
>> >> + */
>> >> +static int pci_host_bridge_of_get_ranges(struct device_node *dev,
>> >> + struct list_head *resources)
>> >> +{
>> >> + struct resource *res;
>> >> + struct of_pci_range range;
>> >> + struct of_pci_range_parser parser;
>> >> + int err;
>> >> +
>> >> + pr_info("PCI host bridge %s ranges:\n", dev->full_name);
>> >> +
>> >> + /* Check for ranges property */
>> >> + err = of_pci_range_parser_init(&parser, dev);
>> >> + if (err)
>> >> + return err;
>> >> +
>> >> + pr_debug("Parsing ranges property...\n");
>> >> + for_each_of_pci_range(&parser, &range) {
>> >> + /* Read next ranges element */
>> >> + pr_debug("pci_space: 0x%08x pci_addr:0x%016llx ",
>> >> + range.pci_space, range.pci_addr);
>> >> + pr_debug("cpu_addr:0x%016llx size:0x%016llx\n",
>> >> + range.cpu_addr, range.size);
>> >> +
>> >> + /* If we failed translation or got a zero-sized region
>> >> + * (some FW try to feed us with non sensical zero sized regions
>> >> + * such as power3 which look like some kind of attempt
>> >> + * at exposing the VGA memory hole) then skip this range
>> >> + */
>> >> + if (range.cpu_addr == OF_BAD_ADDR || range.size == 0)
>> >> + continue;
>> >> +
>> >> + res = kzalloc(sizeof(struct resource), GFP_KERNEL);
>> >> + if (!res) {
>> >> + err = -ENOMEM;
>> >> + goto bridge_ranges_nomem;
>> >> + }
>> >> +
>> >> + of_pci_range_to_resource(&range, dev, res);
>> >> +
>> >> + pci_add_resource_offset(resources, res,
>> >> + range.cpu_addr - range.pci_addr);
>> >> + }
>> >
>> > I believe of_pci_range_to_resource() will return the MMIO aperture for the
>> > I/O space window here, which is not what you are supposed to pass into
>> > pci_add_resource_offset.
>> >
>> >> +EXPORT_SYMBOL(pci_host_bridge_of_init);
>> >
>> > EXPORT_SYMBOL_GPL
>> >
>> >> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
>> >> index 6e34498..16febae 100644
>> >> --- a/drivers/pci/probe.c
>> >> +++ b/drivers/pci/probe.c
>> >> @@ -1787,6 +1787,17 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>> >> list_for_each_entry_safe(window, n, resources, list) {
>> >> list_move_tail(&window->list, &bridge->windows);
>> >> res = window->res;
>> >> + /*
>> >> + * IO resources are stored in the kernel with a CPU start
>> >> + * address of zero. Adjust the data accordingly and remember
>> >> + * the offset
>> >> + */
>> >> + if (resource_type(res) == IORESOURCE_IO) {
>> >> + bridge->io_offset = res->start;
>> >> + res->end -= res->start;
>> >> + window->offset -= res->start;
>> >> + res->start = 0;
>> >> + }
>> >> offset = window->offset;
>> >> if (res->flags & IORESOURCE_BUS)
>> >
>> > Won't this break all existing host bridges?
>> >
>> > Arnd
>> >
>> > _______________________________________________
>> > linux-arm-kernel mailing list
>> > linux-arm-kernel at lists.infradead.org
>> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>
>
> --
> ====================
> | I would like to |
> | fix the world, |
> | but they're not |
> | giving me the |
> \ source code! /
> ---------------
> ?\_(?)_/?
>
> -- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
>
> ARM Limited, Registered office 110 Fulbourn Road, Cambridge CB1 9NJ, Registered in England & Wales, Company No: 2557590
> ARM Holdings plc, Registered office 110 Fulbourn Road, Cambridge CB1 9NJ, Registered in England & Wales, Company No: 2548782
>
^ permalink raw reply
* [PATCH v2 00/12] Samsung PM consolidation part 2 (multiplatform)
From: Tomasz Figa @ 2014-02-07 23:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140207221537.GA12714@quad.lixom.net>
On 07.02.2014 23:15, Olof Johansson wrote:
> On Thu, Feb 06, 2014 at 08:12:45PM +0100, Tomasz Figa wrote:
>
>> On Exynos4210-based Trats, Exynos4412-based Trats2 and Exynos5250-based
>> Arndale boards (except suspend/resume, which is broken because of
>> unrelated reasons):
>
> Has this been reported, and is it being worked on by anyone?
Yes, reported quite a long time ago by Vikas Sajjan of Samsung/Linaro,
but I'm not sure if anybody is working to fix it.
I've been looking into this for a while, but couldn't really find
anything except that it hangs when PMU starts power state transtion
after CPU executing WFI instruction.
Best regards,
Tomasz
^ permalink raw reply
* [PATCH 2/2] ARM: tegra: enable PCA9546 on Cardhu
From: Bryan Wu @ 2014-02-07 23:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391817298-10600-1-git-send-email-pengw@nvidia.com>
Cardhu has a PCA9546 for I2C bus extension, which connects to 3
cameras. It's required for Tegra V4L2 soc camera driver and camera
sensor drivers.
Signed-off-by: Bryan Wu <pengw@nvidia.com>
---
arch/arm/boot/dts/tegra30-cardhu.dtsi | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/arm/boot/dts/tegra30-cardhu.dtsi b/arch/arm/boot/dts/tegra30-cardhu.dtsi
index 9104224..004002c 100644
--- a/arch/arm/boot/dts/tegra30-cardhu.dtsi
+++ b/arch/arm/boot/dts/tegra30-cardhu.dtsi
@@ -187,6 +187,13 @@
interrupt-parent = <&gpio>;
interrupts = <TEGRA_GPIO(L, 0) IRQ_TYPE_LEVEL_HIGH>;
};
+
+ i2cmux at 70 {
+ compatible = "nxp,pca9546";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x70>;
+ };
};
i2c at 7000c700 {
--
1.8.3.2
^ permalink raw reply related
* [PATCH 1/2] ARM: tegra: enable I2C Mux driver for PCA9546 in defconfig
From: Bryan Wu @ 2014-02-07 23:54 UTC (permalink / raw)
To: linux-arm-kernel
PCA9546 is used in Cardhu Tegra30 board to connect to 3 cameras.
Enabling this driver for Tegra V4L2 soc camera driver and camera
sensor drivers.
Signed-off-by: Bryan Wu <pengw@nvidia.com>
---
arch/arm/configs/tegra_defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig
index 995d434..efcf15f 100644
--- a/arch/arm/configs/tegra_defconfig
+++ b/arch/arm/configs/tegra_defconfig
@@ -125,6 +125,7 @@ CONFIG_SERIAL_TEGRA=y
CONFIG_SERIAL_OF_PLATFORM=y
# CONFIG_HW_RANDOM is not set
# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_MUX_PCA954x=y
CONFIG_I2C_MUX_PINCTRL=y
CONFIG_I2C_TEGRA=y
CONFIG_SPI=y
--
1.8.3.2
^ permalink raw reply related
* [PATCH] ARM: tegra: enable I2C MUX PCA954x
From: Bryan Wu @ 2014-02-07 23:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52F56D95.50707@wwwdotorg.org>
On Fri, Feb 7, 2014 at 3:34 PM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 02/07/2014 01:53 PM, Bryan Wu wrote:
>> Cardhu has a PCA9546 for I2C bus extension, which connects to 3
>> cameras. It's required for Tegra V4L2 soc camera driver and camera
>> sensor drivers.
>
>> arch/arm/boot/dts/tegra30-cardhu.dtsi | 8 ++++++++
>> arch/arm/configs/tegra_defconfig | 1 +
>
> DT and defconfig changes go into separate branches. Could I get this
> split into two patches please?
>
>> diff --git a/arch/arm/boot/dts/tegra30-cardhu.dtsi b/arch/arm/boot/dts/tegra30-cardhu.dtsi
>
>> + /* NXP PCA9546 I2C Mux */
>
> That comment isn't useful, since the compatible value below spells out
> what the device is.
>
>> + pca9546 at 70 {
>
> DT nodes should be named after the class/type of device, not the
> identify. As such, use "i2cmux at 70".
>
OK, cool. I will take all the comments and post my V2 patches.
^ permalink raw reply
* [PATCH v4 02/10] ARM/ARM64: KVM: Add base for PSCI v0.2 emulation
From: Jungseok Lee @ 2014-02-07 23:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAAhSdy2p5rfBR59sGbs_mZvh3WmnPAJA2=OwEmdN2xrxp7R2Ug@mail.gmail.com>
On Friday, February 07, 2014 6:26 PM, Anup Patel wrote:
>On Fri, Feb 7, 2014 at 2:37 PM, Jungseok Lee <jays.lee@samsung.com> wrote:
>> On Friday, February 07, 2014 5:36 PM, Anup Patel wrote:
>>> On Fri, Feb 7, 2014 at 1:58 PM, Jungseok Lee <jays.lee@samsung.com> wrote:
>>> > On Thursday, February 06, 2014 8:32 PM, 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/asm/kvm_psci.h | 4 ++
>>> >> arch/arm/include/uapi/asm/kvm.h | 35 ++++++++++++++-
>>> >> arch/arm/kvm/arm.c | 1 +
>>> >> arch/arm/kvm/psci.c | 85 +++++++++++++++++++++++++++++++------
>>> >> arch/arm64/include/asm/kvm_host.h | 2 +-
>>> >> arch/arm64/include/asm/kvm_psci.h | 4 ++
>>> >> arch/arm64/include/uapi/asm/kvm.h | 35 ++++++++++++++-
>>> >> 8 files changed, 152 insertions(+), 16 deletions(-)
>>> >>
>>> >> diff --git a/arch/arm/include/asm/kvm_host.h
>>> >> b/arch/arm/include/asm/kvm_host.h index 09af149..193ceaf
>>> >> 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/asm/kvm_psci.h
>>> >> b/arch/arm/include/asm/kvm_psci.h index 9a83d98..4c0e3e1
>>> >> 100644
>>> >> --- a/arch/arm/include/asm/kvm_psci.h
>>> >> +++ b/arch/arm/include/asm/kvm_psci.h
>>> >> @@ -18,6 +18,10 @@
>>> >> #ifndef __ARM_KVM_PSCI_H__
>>> >> #define __ARM_KVM_PSCI_H__
>>> >>
>>> >> +#define KVM_ARM_PSCI_0_1 1
>>> >> +#define KVM_ARM_PSCI_0_2 2
>>> >> +
>>> >> +int kvm_psci_version(struct kvm_vcpu *vcpu);
>>> >> bool kvm_psci_call(struct kvm_vcpu *vcpu);
>>> >>
>>> >> #endif /* __ARM_KVM_PSCI_H__ */
>>> >> diff --git a/arch/arm/include/uapi/asm/kvm.h
>>> >> b/arch/arm/include/uapi/asm/kvm.h index ef0c878..9c922d9
>>> >> 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;
>>> >> @@ -192,7 +193,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))
>>> >>
>>> >> @@ -201,9 +202,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)
>>> >> +
>>> >
>>> > Hi
>>> >
>>> > This patch describes PSCI v0.2 specification well. Instead, I have
>>> > a question on interface types, not implementation.
>>> >
>>> > According to PSCI v0.2 document, it does not cover DVFS.
>>> > Could I get an idea why DVFS is not supported?
>>>
>>> PSCI v0.2 only describes few mandatory functions required for being
>>> PSCI v0.2 compliant. For rest of the stuff such as DVFS you will need to define your own platform
>specific PSCI function.
>>> (Marc/Mark correct me if I am wrong here?)
>>
>> It seems that I should change architecture codes if I need other interfaces.
>> Under this implementation, I should add my own interface to generic
>> codes, such as, arch/arm/include/asm/kvm_psci.h. However, I think that
>> it is not acceptable to upstream. If so, is there any place to define
>> a platform specific PSCI functions?
>
>Are you trying to emulate your platform specific DVFS PSCI function for a VM using KVM ARM/ARM64??
[Sorry for noise to mailing-list as violating mailing rule]
No, I am not.
My original intention is to clarify the interface between KVM and VM if
DVFS scheme is applied to VM. Currently, PSCI v0.2 does not define it.
Thus, I wonder why this interface is not covered.
>If so then arch/arm/kvm/psci.c is not the place for it. All platform specific PSCI function are to be
>emulated from user space. KVM
>ARM/ARM64 will only emulate HVC-based mandatory PSCI v0.2 functions.
Okay, clear.
Regards
Jungseok Lee
>User space emulation of platform specific PSCI functions are still a TODO item for KVM ARM/ARM64. It
>will require a mechanism in KVM ARM/ARM64 to route SMC-based PSCI function calls to user space (i.e.
>QEMU or KVMTOOL).
>
>Regards,
>Anup
>
>>
>> Best Regards
>> Jungseok Lee
>>
>>> Mab be in future some PSCI vX.Y will define standardized PSCI function for DVFS too.
>>>
>>> Regards,
>>> Anup
>>>
>>> >
>>> > Best Regards
>>> > Jungseok Lee
>>> >
>>> >> +/* 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_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
>>> >> 1d8248e..c8a71df 100644
>>> >> --- a/arch/arm/kvm/arm.c
>>> >> +++ b/arch/arm/kvm/arm.c
>>> >> @@ -197,6 +197,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:
>>> >> diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c index
>>> >> 448f60e..e4ec4af 100644
>>> >> --- a/arch/arm/kvm/psci.c
>>> >> +++ b/arch/arm/kvm/psci.c
>>> >> @@ -85,17 +85,57 @@ 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)
>>> >> +int kvm_psci_version(struct kvm_vcpu *vcpu) {
>>> >> + if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features))
>>> >> + return KVM_ARM_PSCI_0_2;
>>> >> +
>>> >> + return KVM_ARM_PSCI_0_1;
>>> >> +}
>>> >> +
>>> >> +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_NI;
>>> >> + 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;
>>> >> @@ -112,7 +152,6 @@ bool kvm_psci_call(struct kvm_vcpu *vcpu)
>>> >> case KVM_PSCI_FN_MIGRATE:
>>> >> val = KVM_PSCI_RET_NI;
>>> >> break;
>>> >> -
>>> >> default:
>>> >> return false;
>>> >> }
>>> >> @@ -120,3 +159,25 @@ 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) {
>>> >> + switch (kvm_psci_version(vcpu)) {
>>> >> + case KVM_ARM_PSCI_0_2:
>>> >> + return kvm_psci_0_2_call(vcpu);
>>> >> + case KVM_ARM_PSCI_0_1:
>>> >> + return kvm_psci_0_1_call(vcpu);
>>> >> + default:
>>> >> + return false;
>>> >> + };
>>> >> +}
>>> >> 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/asm/kvm_psci.h
>>> >> b/arch/arm64/include/asm/kvm_psci.h
>>> >> index e301a48..e25c658 100644
>>> >> --- a/arch/arm64/include/asm/kvm_psci.h
>>> >> +++ b/arch/arm64/include/asm/kvm_psci.h
>>> >> @@ -18,6 +18,10 @@
>>> >> #ifndef __ARM64_KVM_PSCI_H__
>>> >> #define __ARM64_KVM_PSCI_H__
>>> >>
>>> >> +#define KVM_ARM_PSCI_0_1 1
>>> >> +#define KVM_ARM_PSCI_0_2 2
>>> >> +
>>> >> +int kvm_psci_version(struct kvm_vcpu *vcpu);
>>> >> bool kvm_psci_call(struct kvm_vcpu *vcpu);
>>> >>
>>> >> #endif /* __ARM64_KVM_PSCI_H__ */ diff --git
>>> >> a/arch/arm64/include/uapi/asm/kvm.h
>>> >> b/arch/arm64/include/uapi/asm/kvm.h
>>> >> index eaf54a3..cadc318 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;
>>> >> @@ -177,7 +178,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))
>>> >>
>>> >> @@ -186,10 +187,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_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
>>> >>
>>> >> _______________________________________________
>>> >> kvmarm mailing list
>>> >> kvmarm at lists.cs.columbia.edu
>>> >> https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm
>>> >
>>> > _______________________________________________
>>> > kvmarm mailing list
>>> > kvmarm at lists.cs.columbia.edu
>>> > https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm
>>
^ permalink raw reply
* [PATCH v4 02/10] ARM/ARM64: KVM: Add base for PSCI v0.2 emulation
From: Jungseok Lee @ 2014-02-07 23:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAAhSdy2p5rfBR59sGbs_mZvh3WmnPAJA2=OwEmdN2xrxp7R2Ug@mail.gmail.com>
>-----Original Message-----
>From: Anup Patel [mailto:anup at brainfault.org]
>Sent: Friday, February 07, 2014 6:26 PM
>To: Jungseok Lee
>Cc: Anup Patel; kvmarm at lists.cs.columbia.edu; Mark Rutland; linaro-kernel at lists.linaro.org;
>patches at linaro.org; Marc Zyngier; patches; linux-arm-kernel
>Subject: Re: [PATCH v4 02/10] ARM/ARM64: KVM: Add base for PSCI v0.2 emulation
>
>On Fri, Feb 7, 2014 at 2:37 PM, Jungseok Lee <jays.lee@samsung.com> wrote:
>> On Friday, February 07, 2014 5:36 PM, Anup Patel wrote:
>>> On Fri, Feb 7, 2014 at 1:58 PM, Jungseok Lee <jays.lee@samsung.com> wrote:
>>> > On Thursday, February 06, 2014 8:32 PM, 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/asm/kvm_psci.h | 4 ++
>>> >> arch/arm/include/uapi/asm/kvm.h | 35 ++++++++++++++-
>>> >> arch/arm/kvm/arm.c | 1 +
>>> >> arch/arm/kvm/psci.c | 85 +++++++++++++++++++++++++++++++------
>>> >> arch/arm64/include/asm/kvm_host.h | 2 +-
>>> >> arch/arm64/include/asm/kvm_psci.h | 4 ++
>>> >> arch/arm64/include/uapi/asm/kvm.h | 35 ++++++++++++++-
>>> >> 8 files changed, 152 insertions(+), 16 deletions(-)
>>> >>
>>> >> diff --git a/arch/arm/include/asm/kvm_host.h
>>> >> b/arch/arm/include/asm/kvm_host.h index 09af149..193ceaf
>>> >> 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/asm/kvm_psci.h
>>> >> b/arch/arm/include/asm/kvm_psci.h index 9a83d98..4c0e3e1
>>> >> 100644
>>> >> --- a/arch/arm/include/asm/kvm_psci.h
>>> >> +++ b/arch/arm/include/asm/kvm_psci.h
>>> >> @@ -18,6 +18,10 @@
>>> >> #ifndef __ARM_KVM_PSCI_H__
>>> >> #define __ARM_KVM_PSCI_H__
>>> >>
>>> >> +#define KVM_ARM_PSCI_0_1 1
>>> >> +#define KVM_ARM_PSCI_0_2 2
>>> >> +
>>> >> +int kvm_psci_version(struct kvm_vcpu *vcpu);
>>> >> bool kvm_psci_call(struct kvm_vcpu *vcpu);
>>> >>
>>> >> #endif /* __ARM_KVM_PSCI_H__ */
>>> >> diff --git a/arch/arm/include/uapi/asm/kvm.h
>>> >> b/arch/arm/include/uapi/asm/kvm.h index ef0c878..9c922d9
>>> >> 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;
>>> >> @@ -192,7 +193,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))
>>> >>
>>> >> @@ -201,9 +202,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)
>>> >> +
>>> >
>>> > Hi
>>> >
>>> > This patch describes PSCI v0.2 specification well. Instead, I have
>>> > a question on interface types, not implementation.
>>> >
>>> > According to PSCI v0.2 document, it does not cover DVFS.
>>> > Could I get an idea why DVFS is not supported?
>>>
>>> PSCI v0.2 only describes few mandatory functions required for being
>>> PSCI v0.2 compliant. For rest of the stuff such as DVFS you will need to define your own platform
>specific PSCI function.
>>> (Marc/Mark correct me if I am wrong here?)
>>
>> It seems that I should change architecture codes if I need other interfaces.
>> Under this implementation, I should add my own interface to generic
>> codes, such as, arch/arm/include/asm/kvm_psci.h. However, I think that
>> it is not acceptable to upstream. If so, is there any place to define
>> a platform specific PSCI functions?
>
>Are you trying to emulate your platform specific DVFS PSCI function for a VM using KVM ARM/ARM64??
No, I am not.
My original intention is to clarify the interface between KVM and VM if
DVFS scheme is applied to VM. Currently, PSIC v0.2 does not define it.
Thus, I wonder why this interface is not covered.
>If so then arch/arm/kvm/psci.c is not the place for it. All platform specific PSCI function are to be
>emulated from user space. KVM
>ARM/ARM64 will only emulate HVC-based mandatory PSCI v0.2 functions.
Okay, clear.
Regards
Jungseok Lee
>User space emulation of platform specific PSCI functions are still a TODO item for KVM ARM/ARM64. It
>will require a mechanism in KVM ARM/ARM64 to route SMC-based PSCI function calls to user space (i.e.
>QEMU or KVMTOOL).
>
>Regards,
>Anup
>
>>
>> Best Regards
>> Jungseok Lee
>>
>>> Mab be in future some PSCI vX.Y will define standardized PSCI function for DVFS too.
>>>
>>> Regards,
>>> Anup
>>>
>>> >
>>> > Best Regards
>>> > Jungseok Lee
>>> >
>>> >> +/* 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_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
>>> >> 1d8248e..c8a71df 100644
>>> >> --- a/arch/arm/kvm/arm.c
>>> >> +++ b/arch/arm/kvm/arm.c
>>> >> @@ -197,6 +197,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:
>>> >> diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c index
>>> >> 448f60e..e4ec4af 100644
>>> >> --- a/arch/arm/kvm/psci.c
>>> >> +++ b/arch/arm/kvm/psci.c
>>> >> @@ -85,17 +85,57 @@ 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)
>>> >> +int kvm_psci_version(struct kvm_vcpu *vcpu) {
>>> >> + if (test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features))
>>> >> + return KVM_ARM_PSCI_0_2;
>>> >> +
>>> >> + return KVM_ARM_PSCI_0_1;
>>> >> +}
>>> >> +
>>> >> +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_NI;
>>> >> + 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;
>>> >> @@ -112,7 +152,6 @@ bool kvm_psci_call(struct kvm_vcpu *vcpu)
>>> >> case KVM_PSCI_FN_MIGRATE:
>>> >> val = KVM_PSCI_RET_NI;
>>> >> break;
>>> >> -
>>> >> default:
>>> >> return false;
>>> >> }
>>> >> @@ -120,3 +159,25 @@ 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) {
>>> >> + switch (kvm_psci_version(vcpu)) {
>>> >> + case KVM_ARM_PSCI_0_2:
>>> >> + return kvm_psci_0_2_call(vcpu);
>>> >> + case KVM_ARM_PSCI_0_1:
>>> >> + return kvm_psci_0_1_call(vcpu);
>>> >> + default:
>>> >> + return false;
>>> >> + };
>>> >> +}
>>> >> 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/asm/kvm_psci.h
>>> >> b/arch/arm64/include/asm/kvm_psci.h
>>> >> index e301a48..e25c658 100644
>>> >> --- a/arch/arm64/include/asm/kvm_psci.h
>>> >> +++ b/arch/arm64/include/asm/kvm_psci.h
>>> >> @@ -18,6 +18,10 @@
>>> >> #ifndef __ARM64_KVM_PSCI_H__
>>> >> #define __ARM64_KVM_PSCI_H__
>>> >>
>>> >> +#define KVM_ARM_PSCI_0_1 1
>>> >> +#define KVM_ARM_PSCI_0_2 2
>>> >> +
>>> >> +int kvm_psci_version(struct kvm_vcpu *vcpu);
>>> >> bool kvm_psci_call(struct kvm_vcpu *vcpu);
>>> >>
>>> >> #endif /* __ARM64_KVM_PSCI_H__ */ diff --git
>>> >> a/arch/arm64/include/uapi/asm/kvm.h
>>> >> b/arch/arm64/include/uapi/asm/kvm.h
>>> >> index eaf54a3..cadc318 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;
>>> >> @@ -177,7 +178,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))
>>> >>
>>> >> @@ -186,10 +187,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_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
>>> >>
>>> >> _______________________________________________
>>> >> kvmarm mailing list
>>> >> kvmarm at lists.cs.columbia.edu
>>> >> https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm
>>> >
>>> > _______________________________________________
>>> > kvmarm mailing list
>>> > kvmarm at lists.cs.columbia.edu
>>> > https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm
>>
^ permalink raw reply
* [PATCH v5 00/14] Add support for MSM's mmio clock/reset controller
From: Frank Rowand @ 2014-02-07 23:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391806318.28199.6.camel@joe-AO722>
On 2/7/2014 12:51 PM, Joe Perches wrote:
> On Fri, 2014-02-07 at 11:38 -0800, Frank Rowand wrote:
>> On 2/6/2014 9:11 PM, Joe Perches wrote:
>>> For patch 1, what checkpatch bug might that be?
> []
>> Sorry, it is patch 2, not patch 1 ("[PATCH v5 02/14] clk: Add set_rate_and_parent() op"):
>>
>> WARNING: Multiple spaces after return type
>> #188: FILE: include/linux/clk-provider.h:154:
>> + int (*set_rate_and_parent)(struct clk_hw *hw,
>>
>> total: 0 errors, 1 warnings, 152 lines checked
>
> Yup, that one might be a bit aggressive.
>
> It's a complaint about function pointer declaration style.
>
> from checkpatch:
> ------------------------------------------------------
> # unnecessary space "type (*funcptr)(args...)"
> elsif ($declare =~ /\s{2,}$/) {
> WARN("SPACING",
> "Multiple spaces after return type\n" . $herecurr);
> }
> ------------------------------------------------------
>
> This is warning about style equivalent to declarations like:
>
> int foo(int bar);
>
> checkpatch doesn't warn about declarations of that style,
> so likely checkpatch shouldn't warn about multiple spaces
> after a function pointer return type either.
>
> I don't have a strong opinion one way or another about it.
>
> If you think it should be silenced, it could be either
> downgraded to a CHK or removed altogether.
OK, now the warning makes sense. I was reading "spaces" to mean
the space character instead of white space.
I don't have a strong opinion either, but downgrading to a CHK
would be nice.
It would be less confusing to me (though awkward sounding) to
change the message to "Multiple whitespaces after return type".
-Frank
^ permalink raw reply
* [PATCH] ARM: tegra: enable I2C MUX PCA954x
From: Stephen Warren @ 2014-02-07 23:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391806412-8561-1-git-send-email-pengw@nvidia.com>
On 02/07/2014 01:53 PM, Bryan Wu wrote:
> Cardhu has a PCA9546 for I2C bus extension, which connects to 3
> cameras. It's required for Tegra V4L2 soc camera driver and camera
> sensor drivers.
> arch/arm/boot/dts/tegra30-cardhu.dtsi | 8 ++++++++
> arch/arm/configs/tegra_defconfig | 1 +
DT and defconfig changes go into separate branches. Could I get this
split into two patches please?
> diff --git a/arch/arm/boot/dts/tegra30-cardhu.dtsi b/arch/arm/boot/dts/tegra30-cardhu.dtsi
> + /* NXP PCA9546 I2C Mux */
That comment isn't useful, since the compatible value below spells out
what the device is.
> + pca9546 at 70 {
DT nodes should be named after the class/type of device, not the
identify. As such, use "i2cmux at 70".
^ permalink raw reply
* [PATCH v2] ARM: sunxi: Add driver for sunxi usb phy
From: Hans de Goede @ 2014-02-07 23:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140207223646.GU3192@lukather>
Hi,
On 02/07/2014 11:36 PM, Maxime Ripard wrote:
> Hi Hans,
>
> It looks very nice, I just have a few comments below though.
>
> On Fri, Feb 07, 2014 at 05:33:21PM +0100, Hans de Goede wrote:
>> The Allwinner A1x / A2x SoCs have 2 or 3 usb phys which are all accessed
>> through a single set of registers. Besides this there are also some other
>> phy related bits which need poking, which are per phy, but shared between the
>> ohci and ehci controllers, so these are also controlled from this new phy
>> driver.
>>
>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>> ---
>> .../devicetree/bindings/phy/sun4i-usb-phy.txt | 28 ++
>> drivers/phy/Kconfig | 11 +
>> drivers/phy/Makefile | 1 +
>> drivers/phy/phy-sun4i-usb.c | 326 +++++++++++++++++++++
>> 4 files changed, 366 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt
>> create mode 100644 drivers/phy/phy-sun4i-usb.c
>>
>> diff --git a/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt
>> new file mode 100644
>> index 0000000..f7eccb2
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt
>> @@ -0,0 +1,28 @@
>> +Allwinner sun4i USB PHY
>> +-----------------------
>> +
>> +Required properties:
>> +- compatible : should be one of "allwinner,sun4i-a10-usb-phy",
>> + "allwinner,sun5i-a13-usb-phy" or "allwinner,sun7i-a20-usb-phy"
>> +- reg : a list of offset + length pairs, the 1st list entry should point to
>> + the phy base regs, the 2nd entry to the pmu reg for phy1, and the 3th
>> + entry to the pmu reg of phy2 (for devices which have a phy2).
>
> I'm concerned about devices that would only have a phy2 for some
> reason.
phy1 and phy2 are identical, so in that case we would just call the phy
phy1 I guess, and specify its register where ever it lives and be done with
it.
> Using reg-names would be much more robust, and is quite painless to
> use. Just use platform_get_resource_by_name instead of
> platform_get_resource, and that's pretty much it.
The above argument does not really help to convince me to use
register-names, I don't really see them as useful / necessary,
adding support for them will just grow the driver-code, as well
as the devicetree bindings docs, as well as the dts files.
But if you really really want me to use register-names, just say so
and I'll modify the patch.
>
>> +- #phy-cells : from the generic phy bindings, must be 1
>> +
>> +Optional properties:
>> +- clocks : phandle + clock specifier for the phy clock
>> +- clock-names : "usb_phy"
>> +- resets : a list of phandle + reset specifier pairs
>> +- reset-names : "usb0_reset", "usb1_reset", and / or "usb2_reset"
>> +
>> +Example:
>> + usbphy: phy at 0x01c13400 {
>> + #phy-cells = <1>;
>> + compatible = "allwinner,sun4i-a10-usb-phy";
>> + /* phy base regs, phy1 pmu reg, phy2 pmu reg */
>> + reg = <0x01c13400 0x10 0x01c14800 0x4 0x01c1c800 0x4>;
>> + clocks = <&usb_clk 8>;
>> + clock-names = "usb_phy";
>> + resets = <&usb_clk 1>, <&usb_clk 2>;
>> + reset-names = "usb1_reset", "usb2_reset";
>> + };
>> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
>> index afa2354..6070c99 100644
>> --- a/drivers/phy/Kconfig
>> +++ b/drivers/phy/Kconfig
>> @@ -64,4 +64,15 @@ config BCM_KONA_USB2_PHY
>> help
>> Enable this to support the Broadcom Kona USB 2.0 PHY.
>>
>> +config PHY_SUN4I_USB
>> + tristate "Allwinner sunxi SoC USB PHY driver"
>> + depends on ARCH_SUNXI
>> + select GENERIC_PHY
>> + help
>> + Enable this to support the transceiver that is part of Allwinner
>> + sunxi SoCs.
>> +
>> + This driver controls the entire USB PHY block, both the USB OTG
>> + parts, as well as the 2 regular USB 2 host PHYs.
>> +
>> endmenu
>> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
>> index b57c253..9d4f8bb 100644
>> --- a/drivers/phy/Makefile
>> +++ b/drivers/phy/Makefile
>> @@ -9,3 +9,4 @@ obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO) += phy-exynos-mipi-video.o
>> obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o
>> obj-$(CONFIG_OMAP_USB2) += phy-omap-usb2.o
>> obj-$(CONFIG_TWL4030_USB) += phy-twl4030-usb.o
>> +obj-$(CONFIG_PHY_SUN4I_USB) += phy-sun4i-usb.o
>> diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
>> new file mode 100644
>> index 0000000..bd9cb7fa
>> --- /dev/null
>> +++ b/drivers/phy/phy-sun4i-usb.c
>> @@ -0,0 +1,326 @@
>> +/*
>> + * Allwinner sun4i USB phy driver
>> + *
>> + * Copyright (C) 2014 Hans de Goede <hdegoede@redhat.com>
>> + *
>> + * Based on code from
>> + * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
>> + *
>> + * Modelled after: Samsung S5P/EXYNOS SoC series MIPI CSIS/DSIM DPHY driver
>> + * Copyright (C) 2013 Samsung Electronics Co., Ltd.
>> + * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> + * GNU General Public License for more details.
>> + */
>> +
>> +#include <linux/clk.h>
>> +#include <linux/io.h>
>> +#include <linux/kernel.h>
>> +#include <linux/module.h>
>> +#include <linux/mutex.h>
>> +#include <linux/of.h>
>> +#include <linux/of_address.h>
>> +#include <linux/phy/phy.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/regulator/consumer.h>
>> +#include <linux/reset.h>
>> +
>> +#define REG_ISCR 0x00
>> +#define REG_PHYCTL 0x04
>> +#define REG_PHYBIST 0x08
>> +#define REG_PHYTUNE 0x0c
>> +
>> +#define SUNXI_AHB_ICHR8_EN BIT(10)
>> +#define SUNXI_AHB_INCR4_BURST_EN BIT(9)
>> +#define SUNXI_AHB_INCRX_ALIGN_EN BIT(8)
>> +#define SUNXI_ULPI_BYPASS_EN BIT(0)
>> +
>> +/* Common Control Bits for Both PHYs */
>> +#define PHY_PLL_BW 0x03
>> +#define PHY_RES45_CAL_EN 0x0c
>> +
>> +/* Private Control Bits for Each PHY */
>> +#define PHY_TX_AMPLITUDE_TUNE 0x20
>> +#define PHY_TX_SLEWRATE_TUNE 0x22
>> +#define PHY_VBUSVALID_TH_SEL 0x25
>> +#define PHY_PULLUP_RES_SEL 0x27
>> +#define PHY_OTG_FUNC_EN 0x28
>> +#define PHY_VBUS_DET_EN 0x29
>> +#define PHY_DISCON_TH_SEL 0x2a
>> +
>> +#define MAX_PHYS 3
>> +
>> +struct sun4i_usb_phy_data {
>> + struct clk *clk;
>> + void __iomem *base;
>> + struct mutex mutex;
>> + int num_phys;
>> + u32 disc_thresh;
>> + struct sun4i_usb_phy {
>> + struct phy *phy;
>> + void __iomem *pmu;
>> + struct regulator *vbus;
>> + struct reset_control *reset;
>> + int index;
>> + } phys[MAX_PHYS];
>> +};
>> +
>> +#define to_sun4i_usb_phy_data(phy) \
>> + container_of((phy), struct sun4i_usb_phy_data, phys[(phy)->index])
>> +
>> +static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data,
>> + int len)
>> +{
>> + struct sun4i_usb_phy_data *phy_data = to_sun4i_usb_phy_data(phy);
>> + u32 temp, usbc_bit = BIT(phy->index * 2);
>> + int i;
>> +
>> + mutex_lock(&phy_data->mutex);
>> +
>> + for (i = 0; i < len; i++) {
>> + temp = readl(phy_data->base + REG_PHYCTL);
>> +
>> + /* clear the address portion */
>> + temp &= ~(0xff << 8);
>> +
>> + /* set the address */
>> + temp |= ((addr + i) << 8);
>> + writel(temp, phy_data->base + REG_PHYCTL);
>> +
>> + /* set the data bit and clear usbc bit*/
>> + temp = readb(phy_data->base + REG_PHYCTL);
>> + if (data & 0x1)
>> + temp |= BIT(7);
>> + else
>> + temp &= ~BIT(7);
>> + temp &= ~usbc_bit;
>> + writeb(temp, phy_data->base + REG_PHYCTL);
>> +
>> + /* pulse usbc_bit */
>> + temp = readb(phy_data->base + REG_PHYCTL);
>> + temp |= usbc_bit;
>> + writeb(temp, phy_data->base + REG_PHYCTL);
>> +
>> + temp = readb(phy_data->base + REG_PHYCTL);
>> + temp &= ~usbc_bit;
>> + writeb(temp, phy_data->base + REG_PHYCTL);
>> +
>> + data >>= 1;
>> + }
>> + mutex_unlock(&phy_data->mutex);
>> +}
>> +
>> +static void sun4i_usb_phy_passby(struct sun4i_usb_phy *phy, int enable)
>> +{
>> + u32 bits, reg_value;
>> +
>> + if (!phy->pmu)
>> + return;
>> +
>> + bits = SUNXI_AHB_ICHR8_EN | SUNXI_AHB_INCR4_BURST_EN |
>> + SUNXI_AHB_INCRX_ALIGN_EN | SUNXI_ULPI_BYPASS_EN;
>> +
>> + reg_value = readl(phy->pmu);
>> +
>> + if (enable)
>> + reg_value |= bits;
>> + else
>> + reg_value &= ~bits;
>> +
>> + writel(reg_value, phy->pmu);
>> +}
>> +
>> +static int sun4i_usb_phy_init(struct phy *_phy)
>> +{
>> + struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
>> + struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
>> + int ret;
>> +
>> + ret = clk_prepare_enable(data->clk);
>> + if (ret)
>> + return ret;
>> +
>> + ret = reset_control_deassert(phy->reset);
>> + if (ret) {
>> + clk_disable_unprepare(data->clk);
>> + return ret;
>> + }
>> +
>> + /* Adjust PHY's magnitude and rate */
>> + sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5);
>> +
>> + /* Disconnect threshold adjustment */
>> + sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL, data->disc_thresh, 2);
>> +
>> + sun4i_usb_phy_passby(phy, 1);
>> +
>> + return 0;
>> +}
>> +
>> +static int sun4i_usb_phy_exit(struct phy *_phy)
>> +{
>> + struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
>> + struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy);
>> +
>> + sun4i_usb_phy_passby(phy, 0);
>> + reset_control_assert(phy->reset);
>> + clk_disable_unprepare(data->clk);
>> +
>> + return 0;
>> +}
>> +
>> +static int sun4i_usb_phy_power_on(struct phy *_phy)
>> +{
>> + struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
>> + int ret = 0;
>> +
>> + if (phy->vbus)
>> + ret = regulator_enable(phy->vbus);
>> +
>> + return ret;
>> +}
>> +
>> +static int sun4i_usb_phy_power_off(struct phy *_phy)
>> +{
>> + struct sun4i_usb_phy *phy = phy_get_drvdata(_phy);
>> +
>> + if (phy->vbus)
>> + regulator_disable(phy->vbus);
>> +
>> + return 0;
>> +}
>> +
>> +static struct phy_ops sun4i_usb_phy_ops = {
>> + .init = sun4i_usb_phy_init,
>> + .exit = sun4i_usb_phy_exit,
>> + .power_on = sun4i_usb_phy_power_on,
>> + .power_off = sun4i_usb_phy_power_off,
>> + .owner = THIS_MODULE,
>> +};
>> +
>> +static struct phy *sun4i_usb_phy_xlate(struct device *dev,
>> + struct of_phandle_args *args)
>> +{
>> + struct sun4i_usb_phy_data *data = dev_get_drvdata(dev);
>> +
>> + if (WARN_ON(args->args[0] == 0 || args->args[0] >= data->num_phys))
>> + return ERR_PTR(-ENODEV);
>> +
>> + return data->phys[args->args[0]].phy;
>> +}
>> +
>> +static int sun4i_usb_phy_probe(struct platform_device *pdev)
>> +{
>> + struct sun4i_usb_phy_data *data;
>> + struct device *dev = &pdev->dev;
>> + struct device_node *np = dev->of_node;
>> + void __iomem *pmu = NULL;
>> + struct phy_provider *phy_provider;
>> + struct reset_control *reset;
>> + struct regulator *vbus;
>> + struct phy *phy;
>> + char name[16];
>> + int i;
>> +
>> + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
>> + if (!data)
>> + return -ENOMEM;
>> +
>> + mutex_init(&data->mutex);
>> +
>> + if (of_device_is_compatible(np, "allwinner,sun5i-a13-usb-phy"))
>> + data->num_phys = 2;
>> + else
>> + data->num_phys = 3;
>> +
>> + if (of_device_is_compatible(np, "allwinner,sun4i-a10-usb-phy"))
>> + data->disc_thresh = 3;
>> + else
>> + data->disc_thresh = 2;
>
> I'd still prefer to pass this through the .data field of of_device_id,
> but it looks much cleaner already :)
The problem with using the .data field is that I can only store a single
integer there. To store 2 I need to: define a struct, create an array
of these structs with initialization. Create an enum for indexing the
array which must be kept in sync with the initializers manually, store
either the index, or a direct pointer to the correct array entry into
the .data field, add code to get the of_device_id from the compatible
string, and then finally extract the settings from the struct again.
See IE how this is done in drivers/ata/ahci_platform.c, I've tried
to come up with a simpler way and failed, for ahci_platform.c the
struct with per compatible-string data is quite big so it makes some
sense to use this construction. Here however not so much, this adds a
whole lot of unnecessary extra code + indirection. I esp. object against
the indirection as that unnecessarily makes it harder to follow whats
going on.
>
>> + data->clk = devm_clk_get(dev, "usb_phy");
>> + if (IS_ERR(data->clk)) {
>> + dev_err(dev, "could not get usb_phy clock\n");
>> + return PTR_ERR(data->clk);
>> + }
>> +
>> + /* Skip 0, 0 is the phy for otg which is not yet supported. */
>> + for (i = 1; i < data->num_phys; i++) {
>> + snprintf(name, sizeof(name), "usb%d_vbus", i);
>> + vbus = devm_regulator_get_optional(dev, name);
>> + if (IS_ERR(vbus)) {
>> + if (PTR_ERR(vbus) == -EPROBE_DEFER)
>> + return -EPROBE_DEFER;
>> + vbus = NULL;
>> + }
>> +
>> + snprintf(name, sizeof(name), "usb%d_reset", i);
>> + reset = devm_reset_control_get(dev, name);
>> + if (IS_ERR(phy)) {
>> + dev_err(dev, "failed to get reset %s\n", name);
>> + return PTR_ERR(phy);
>> + }
>> +
>> + if (i) { /* No pmu for usbc0 */
>> + pmu = devm_ioremap_resource(dev,
>> + platform_get_resource(pdev, IORESOURCE_MEM, i));
>> + if (IS_ERR(pmu))
>> + return PTR_ERR(pmu);
>> + }
>> +
>> + phy = devm_phy_create(dev, &sun4i_usb_phy_ops, NULL);
>> + if (IS_ERR(phy)) {
>> + dev_err(dev, "failed to create PHY %d\n", i);
>> + return PTR_ERR(phy);
>> + }
>> +
>> + data->phys[i].phy = phy;
>> + data->phys[i].pmu = pmu;
>> + data->phys[i].vbus = vbus;
>> + data->phys[i].reset = reset;
>> + data->phys[i].index = i;
>> + phy_set_drvdata(phy, &data->phys[i]);
>> + }
>> +
>> + data->base = devm_ioremap_resource(dev,
>> + platform_get_resource(pdev, IORESOURCE_MEM, 0));
>> + if (IS_ERR(data->base))
>> + return PTR_ERR(data->base);
>> +
>> + dev_set_drvdata(dev, data);
>> + phy_provider = devm_of_phy_provider_register(dev, sun4i_usb_phy_xlate);
>> + if (IS_ERR(phy_provider))
>> + return PTR_ERR(phy_provider);
>> +
>> + return 0;
>> +}
>> +
>> +static const struct of_device_id sun4i_usb_phy_of_match[] = {
>> + { .compatible = "allwinner,sun4i-a10-usb-phy" },
>> + { .compatible = "allwinner,sun5i-a13-usb-phy" },
>> + { .compatible = "allwinner,sun7i-a20-usb-phy" },
>> + { },
>> +};
>> +MODULE_DEVICE_TABLE(of, sun4i_usb_phy_of_match);
>> +
>> +static struct platform_driver sun4i_usb_phy_driver = {
>> + .probe = sun4i_usb_phy_probe,
>> + .driver = {
>> + .of_match_table = sun4i_usb_phy_of_match,
>> + .name = "sun4i-usb-phy",
>> + .owner = THIS_MODULE,
>> + }
>> +};
>> +module_platform_driver(sun4i_usb_phy_driver);
>> +
>> +MODULE_DESCRIPTION("Allwinner sun4i USB phy driver");
>> +MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
>> +MODULE_LICENSE("GPL v2");
>> --
>> 1.8.4.2
>>
>
Regards,
Hans
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox