From f40a1e3705be23e845fbeec66acf3a6582524145 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Wed, 24 Jan 2018 00:42:13 +0800 Subject: soc: imx: gpc: ARM power domain should be always-on ARM power domain does NOT support runtime off, always-on flag should be set to avoid incorrect power state in pm_genpd_summary: Before: root@imx6qpdlsolox:~# cat /sys/kernel/debug/pm_genpd/pm_genpd_summary domain status slaves /device runtime status ---------------------------------------------------------------------- ARM off-0 After: root@imx6qpdlsolox:~# cat /sys/kernel/debug/pm_genpd/pm_genpd_summary domain status slaves /device runtime status ---------------------------------------------------------------------- ARM on Signed-off-by: Anson Huang Reviewed-by: Lucas Stach Acked-by: Dong Aisheng Signed-off-by: Shawn Guo --- drivers/soc/imx/gpc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/soc/imx/gpc.c b/drivers/soc/imx/gpc.c index 53f7275d6cbd..6cafa9b60bc6 100644 --- a/drivers/soc/imx/gpc.c +++ b/drivers/soc/imx/gpc.c @@ -254,6 +254,7 @@ static struct imx_pm_domain imx_gpc_domains[] = { { .base = { .name = "ARM", + .flags = GENPD_FLAG_ALWAYS_ON, }, }, { .base = { -- cgit v1.2.3 From e17ee5f08b9849b9f80fadab96364121c6bdd207 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Wed, 7 Feb 2018 14:20:03 +0800 Subject: soc: rockchip: disable jtag switching for RK3228/RK3229 SoCs Disable IO function switching between sdmmc and jtag for RK3228 and RK3229 SoCs. Signed-off-by: Shawn Lin Signed-off-by: Heiko Stuebner --- drivers/soc/rockchip/grf.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/soc/rockchip/grf.c b/drivers/soc/rockchip/grf.c index 15e71fd6c513..dd81b87d79f0 100644 --- a/drivers/soc/rockchip/grf.c +++ b/drivers/soc/rockchip/grf.c @@ -43,6 +43,17 @@ static const struct rockchip_grf_info rk3036_grf __initconst = { .num_values = ARRAY_SIZE(rk3036_defaults), }; +#define RK3228_GRF_SOC_CON6 0x418 + +static const struct rockchip_grf_value rk3228_defaults[] __initconst = { + { "jtag switching", RK3228_GRF_SOC_CON6, HIWORD_UPDATE(0, 1, 8) }, +}; + +static const struct rockchip_grf_info rk3228_grf __initconst = { + .values = rk3228_defaults, + .num_values = ARRAY_SIZE(rk3228_defaults), +}; + #define RK3288_GRF_SOC_CON0 0x244 static const struct rockchip_grf_value rk3288_defaults[] __initconst = { @@ -91,6 +102,9 @@ static const struct of_device_id rockchip_grf_dt_match[] __initconst = { { .compatible = "rockchip,rk3036-grf", .data = (void *)&rk3036_grf, + }, { + .compatible = "rockchip,rk3228-grf", + .data = (void *)&rk3228_grf, }, { .compatible = "rockchip,rk3288-grf", .data = (void *)&rk3288_grf, -- cgit v1.2.3 From f12bb91624f9511c1ee87e7c358e4dc11fb44ab3 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 9 Jan 2018 19:29:55 +0100 Subject: memory: samsung: Add SPDX license identifiers Replace GPL license statements with SPDX GPL-2.0 license identifiers. Signed-off-by: Krzysztof Kozlowski --- drivers/memory/samsung/Kconfig | 1 + drivers/memory/samsung/Makefile | 1 + drivers/memory/samsung/exynos-srom.c | 18 +++++++----------- drivers/memory/samsung/exynos-srom.h | 7 ++----- 4 files changed, 11 insertions(+), 16 deletions(-) diff --git a/drivers/memory/samsung/Kconfig b/drivers/memory/samsung/Kconfig index 9de12222061c..79ce7ea58903 100644 --- a/drivers/memory/samsung/Kconfig +++ b/drivers/memory/samsung/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 config SAMSUNG_MC bool "Samsung Exynos Memory Controller support" if COMPILE_TEST help diff --git a/drivers/memory/samsung/Makefile b/drivers/memory/samsung/Makefile index 9c554d5522ad..00587be66211 100644 --- a/drivers/memory/samsung/Makefile +++ b/drivers/memory/samsung/Makefile @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_EXYNOS_SROM) += exynos-srom.o diff --git a/drivers/memory/samsung/exynos-srom.c b/drivers/memory/samsung/exynos-srom.c index bf827a666694..7edd7fb540f2 100644 --- a/drivers/memory/samsung/exynos-srom.c +++ b/drivers/memory/samsung/exynos-srom.c @@ -1,14 +1,10 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * EXYNOS - SROM Controller support - * Author: Pankaj Dubey - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (c) 2015 Samsung Electronics Co., Ltd. +// http://www.samsung.com/ +// +// EXYNOS - SROM Controller support +// Author: Pankaj Dubey #include #include diff --git a/drivers/memory/samsung/exynos-srom.h b/drivers/memory/samsung/exynos-srom.h index 34660c6a57a9..da612797f522 100644 --- a/drivers/memory/samsung/exynos-srom.h +++ b/drivers/memory/samsung/exynos-srom.h @@ -1,13 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2015 Samsung Electronics Co., Ltd. * http://www.samsung.com * * Exynos SROMC register definitions - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ + */ #ifndef __EXYNOS_SROM_H #define __EXYNOS_SROM_H __FILE__ -- cgit v1.2.3 From bcb41a53b0b075600cb821302e7177ca5ab62efd Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 9 Jan 2018 19:29:56 +0100 Subject: soc: samsung: Add SPDX license identifiers to headers Replace GPL license statements with SPDX GPL-2.0 license identifiers. Signed-off-by: Krzysztof Kozlowski --- include/linux/soc/samsung/exynos-pmu.h | 5 +---- include/linux/soc/samsung/exynos-regs-pmu.h | 6 +----- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/include/linux/soc/samsung/exynos-pmu.h b/include/linux/soc/samsung/exynos-pmu.h index e57eb4b6cc5a..fc0b445bb36b 100644 --- a/include/linux/soc/samsung/exynos-pmu.h +++ b/include/linux/soc/samsung/exynos-pmu.h @@ -1,12 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2014 Samsung Electronics Co., Ltd. * http://www.samsung.com * * Header for EXYNOS PMU Driver support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #ifndef __LINUX_SOC_EXYNOS_PMU_H diff --git a/include/linux/soc/samsung/exynos-regs-pmu.h b/include/linux/soc/samsung/exynos-regs-pmu.h index bebdde5dccd6..66dcb9ec273a 100644 --- a/include/linux/soc/samsung/exynos-regs-pmu.h +++ b/include/linux/soc/samsung/exynos-regs-pmu.h @@ -1,14 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2010-2015 Samsung Electronics Co., Ltd. * http://www.samsung.com * * EXYNOS - Power management unit definition * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * * Notice: * This is not a list of all Exynos Power Management Unit SFRs. * There are too many of them, not mentioning subtle differences -- cgit v1.2.3 From 3a2ad7bd3151cc282f06d18948dfb7a0e1138fb2 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Thu, 21 Dec 2017 20:40:52 +0100 Subject: soc: amlogic: meson-gx-pwrc-vpu: don't print error message on probe deferral The error message may be misleading in case of probe deferral (happens on my Odroid-C2). Therefore don't print it in this case. Fixes: 75fcb5ca4b46 "soc: amlogic: add Meson GX VPU Domains driver" Signed-off-by: Heiner Kallweit Acked-by: Neil Armstrong Signed-off-by: Kevin Hilman --- drivers/soc/amlogic/meson-gx-pwrc-vpu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/soc/amlogic/meson-gx-pwrc-vpu.c b/drivers/soc/amlogic/meson-gx-pwrc-vpu.c index 2bdeebc48901..3adb2f2ecefd 100644 --- a/drivers/soc/amlogic/meson-gx-pwrc-vpu.c +++ b/drivers/soc/amlogic/meson-gx-pwrc-vpu.c @@ -184,7 +184,8 @@ static int meson_gx_pwrc_vpu_probe(struct platform_device *pdev) rstc = devm_reset_control_array_get(&pdev->dev, false, false); if (IS_ERR(rstc)) { - dev_err(&pdev->dev, "failed to get reset lines\n"); + if (PTR_ERR(rstc) != -EPROBE_DEFER) + dev_err(&pdev->dev, "failed to get reset lines\n"); return PTR_ERR(rstc); } -- cgit v1.2.3 From 87f88732d25e6175cb4faa8070658f604660d720 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Thu, 21 Dec 2017 20:41:02 +0100 Subject: soc: amlogic: meson-gx-pwrc-vpu: fix error on shutdown when domain is powered off When operating the system headless headless, the domain is never powered on, leaving the clocks disabled. The shutdown function then tries to disable the already disabled clocks, resulting in errors. Therefore call meson_gx_pwrc_vpu_power_off() only if domain is powered on. This patch fixes the described issue on my system (Odorid-C2). Fixes: 339cd0ea0822 "soc: amlogic: meson-gx-pwrc-vpu: fix power-off when powered by bootloader" Signed-off-by: Heiner Kallweit Reviewed-by: Neil Armstrong Signed-off-by: Kevin Hilman --- drivers/soc/amlogic/meson-gx-pwrc-vpu.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/soc/amlogic/meson-gx-pwrc-vpu.c b/drivers/soc/amlogic/meson-gx-pwrc-vpu.c index 3adb2f2ecefd..6289965c42e9 100644 --- a/drivers/soc/amlogic/meson-gx-pwrc-vpu.c +++ b/drivers/soc/amlogic/meson-gx-pwrc-vpu.c @@ -225,7 +225,11 @@ static int meson_gx_pwrc_vpu_probe(struct platform_device *pdev) static void meson_gx_pwrc_vpu_shutdown(struct platform_device *pdev) { - meson_gx_pwrc_vpu_power_off(&vpu_hdmi_pd.genpd); + bool powered_off; + + powered_off = meson_gx_pwrc_vpu_get_power(&vpu_hdmi_pd); + if (!powered_off) + meson_gx_pwrc_vpu_power_off(&vpu_hdmi_pd.genpd); } static const struct of_device_id meson_gx_pwrc_vpu_match_table[] = { -- cgit v1.2.3 From 82a759c91801d1f9851196d73516a504064e472c Mon Sep 17 00:00:00 2001 From: "weiyongjun (A)" Date: Wed, 10 Jan 2018 14:19:40 +0000 Subject: meson-mx-socinfo: Make local function meson_mx_socinfo_init() static Fixes the following sparse warnings: drivers/soc/amlogic/meson-mx-socinfo.c:107:12: warning: symbol 'meson_mx_socinfo_init' was not declared. Should it be static? Signed-off-by: Wei Yongjun Signed-off-by: Kevin Hilman --- drivers/soc/amlogic/meson-mx-socinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/soc/amlogic/meson-mx-socinfo.c b/drivers/soc/amlogic/meson-mx-socinfo.c index 7bfff5ff22a2..78f0f1aeca57 100644 --- a/drivers/soc/amlogic/meson-mx-socinfo.c +++ b/drivers/soc/amlogic/meson-mx-socinfo.c @@ -104,7 +104,7 @@ static const struct of_device_id meson_mx_socinfo_analog_top_ids[] = { { /* sentinel */ } }; -int __init meson_mx_socinfo_init(void) +static int __init meson_mx_socinfo_init(void) { struct soc_device_attribute *soc_dev_attr; struct soc_device *soc_dev; -- cgit v1.2.3 From 01517dfc819f003855c1893d9382581cafe2877b Mon Sep 17 00:00:00 2001 From: "weiyongjun (A)" Date: Wed, 10 Jan 2018 14:19:48 +0000 Subject: meson-gx-socinfo: make local function meson_gx_socinfo_init static Fixes the following sparse warnings: drivers/soc/amlogic/meson-gx-socinfo.c:100:12: warning: symbol 'meson_gx_socinfo_init' was not declared. Should it be static? Signed-off-by: Wei Yongjun Acked-by: Neil Armstrong Signed-off-by: Kevin Hilman --- drivers/soc/amlogic/meson-gx-socinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/soc/amlogic/meson-gx-socinfo.c b/drivers/soc/amlogic/meson-gx-socinfo.c index f2d8c3c53ea4..ea091f1f7dae 100644 --- a/drivers/soc/amlogic/meson-gx-socinfo.c +++ b/drivers/soc/amlogic/meson-gx-socinfo.c @@ -97,7 +97,7 @@ static const char *socinfo_to_soc_id(u32 socinfo) return "Unknown"; } -int __init meson_gx_socinfo_init(void) +static int __init meson_gx_socinfo_init(void) { struct soc_device_attribute *soc_dev_attr; struct soc_device *soc_dev; -- cgit v1.2.3 From 7353c54620732797dcc3b4b1fc6f3cc0c0d9b6ef Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 30 Jan 2018 22:18:16 +0100 Subject: soc: samsung: pmu: Populate children syscon nodes The syscon poweroff and restart nodes logically belong to the Power Management Unit so populate possible children. This also requires providing compatibles for Exynos5410 and Exynos7 so the PMU device and its children will be instantiated for them as well. Just like Exynos5433, these chipsets are not yet supported by the PMU driver. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Rob Herring Tested-by: Marek Szyprowski --- Documentation/devicetree/bindings/arm/samsung/pmu.txt | 6 ++++++ drivers/soc/samsung/exynos-pmu.c | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/samsung/pmu.txt b/Documentation/devicetree/bindings/arm/samsung/pmu.txt index 779f5614bcee..16685787d2bd 100644 --- a/Documentation/devicetree/bindings/arm/samsung/pmu.txt +++ b/Documentation/devicetree/bindings/arm/samsung/pmu.txt @@ -43,6 +43,12 @@ following properties: - interrupt-parent: a phandle indicating which interrupt controller this PMU signals interrupts to. + +Optional nodes: + +- nodes defining the restart and poweroff syscon children + + Example : pmu_system_controller: system-controller@10040000 { compatible = "samsung,exynos5250-pmu", "syscon"; diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c index f56adbd9fb8b..d34ca201b8b7 100644 --- a/drivers/soc/samsung/exynos-pmu.c +++ b/drivers/soc/samsung/exynos-pmu.c @@ -84,11 +84,15 @@ static const struct of_device_id exynos_pmu_of_device_ids[] = { }, { .compatible = "samsung,exynos5250-pmu", .data = exynos_pmu_data_arm_ptr(exynos5250_pmu_data), + }, { + .compatible = "samsung,exynos5410-pmu", }, { .compatible = "samsung,exynos5420-pmu", .data = exynos_pmu_data_arm_ptr(exynos5420_pmu_data), }, { .compatible = "samsung,exynos5433-pmu", + }, { + .compatible = "samsung,exynos7-pmu", }, { /*sentinel*/ }, }; @@ -126,6 +130,9 @@ static int exynos_pmu_probe(struct platform_device *pdev) platform_set_drvdata(pdev, pmu_context); + if (devm_of_platform_populate(dev)) + dev_err(dev, "Error populating children, reboot and poweroff might not work properly\n"); + dev_dbg(dev, "Exynos PMU Driver probe done\n"); return 0; } -- cgit v1.2.3 From 320da785db9b724cc099c79852de477f390b6cab Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Tue, 26 Dec 2017 12:50:41 +0100 Subject: reset: meson: enable level reset support on Meson8b Commit a5a10afe04ef ("reset: meson: add level reset support for GX SoC family") only enabled the level resets for the newer GX SoC family. However, the older 32-Meson SoCs (Meson8, Meson8b and Meson8m2) also support level resets using the same offset as the newer GX SoCs. This removes the separation between Meson8b and the GX SoCs from the reset-meson driver to enable the level resets also on Meson8b. Signed-off-by: Martin Blumenstingl Reviewed-by: Neil Armstrong Signed-off-by: Philipp Zabel --- drivers/reset/reset-meson.c | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/drivers/reset/reset-meson.c b/drivers/reset/reset-meson.c index 93cbee1ae8ef..5242e0679df7 100644 --- a/drivers/reset/reset-meson.c +++ b/drivers/reset/reset-meson.c @@ -124,29 +124,21 @@ static int meson_reset_deassert(struct reset_controller_dev *rcdev, return meson_reset_level(rcdev, id, false); } -static const struct reset_control_ops meson_reset_meson8_ops = { - .reset = meson_reset_reset, -}; - -static const struct reset_control_ops meson_reset_gx_ops = { +static const struct reset_control_ops meson_reset_ops = { .reset = meson_reset_reset, .assert = meson_reset_assert, .deassert = meson_reset_deassert, }; static const struct of_device_id meson_reset_dt_ids[] = { - { .compatible = "amlogic,meson8b-reset", - .data = &meson_reset_meson8_ops, }, - { .compatible = "amlogic,meson-gxbb-reset", - .data = &meson_reset_gx_ops, }, - { .compatible = "amlogic,meson-axg-reset", - .data = &meson_reset_gx_ops, }, + { .compatible = "amlogic,meson8b-reset" }, + { .compatible = "amlogic,meson-gxbb-reset" }, + { .compatible = "amlogic,meson-axg-reset" }, { /* sentinel */ }, }; static int meson_reset_probe(struct platform_device *pdev) { - const struct reset_control_ops *ops; struct meson_reset *data; struct resource *res; @@ -154,10 +146,6 @@ static int meson_reset_probe(struct platform_device *pdev) if (!data) return -ENOMEM; - ops = of_device_get_match_data(&pdev->dev); - if (!ops) - return -EINVAL; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); data->reg_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(data->reg_base)) @@ -169,7 +157,7 @@ static int meson_reset_probe(struct platform_device *pdev) data->rcdev.owner = THIS_MODULE; data->rcdev.nr_resets = REG_COUNT * BITS_PER_REG; - data->rcdev.ops = ops; + data->rcdev.ops = &meson_reset_ops; data->rcdev.of_node = pdev->dev.of_node; return devm_reset_controller_register(&pdev->dev, &data->rcdev); -- cgit v1.2.3 From 14b5057a2f84b9da246e5bda29c9fd914a8f691c Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Tue, 20 Feb 2018 12:13:28 +1030 Subject: dt-bindings: aspeed-lpc: Add reset controller This describes the reset controller present in the LPC address space. Reviewed-by: Rob Herring Signed-off-by: Joel Stanley [p.zabel@pengutronix.de: removed a space before tab in indent] Signed-off-by: Philipp Zabel --- .../devicetree/bindings/mfd/aspeed-lpc.txt | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt b/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt index 514d82ced95b..7136432f9905 100644 --- a/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt +++ b/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt @@ -135,3 +135,24 @@ lhc: lhc@20 { compatible = "aspeed,ast2500-lhc"; reg = <0x20 0x24 0x48 0x8>; }; + +LPC reset control +----------------- + +The UARTs present in the ASPEED SoC can have their resets tied to the reset +state of the LPC bus. Some systems may chose to modify this configuration. + +Required properties: + + - compatible: "aspeed,ast2500-lpc-reset" or + "aspeed,ast2400-lpc-reset" + - reg: offset and length of the IP in the LHC memory region + - #reset-controller indicates the number of reset cells expected + +Example: + +lpc_reset: reset-controller@18 { + compatible = "aspeed,ast2500-lpc-reset"; + reg = <0x18 0x4>; + #reset-cells = <1>; +}; -- cgit v1.2.3 From 1d7592f84f92c6344978186fdbe547af044274b5 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Tue, 20 Feb 2018 12:13:29 +1030 Subject: reset: simple: Enable for ASPEED systems ASPEED BMC SoCs have a reset controller in the LPC IP that can be controlled using this driver to release the UARTs from reset. No special configuration is required, so only the compatible string is added. Signed-off-by: Joel Stanley Signed-off-by: Philipp Zabel --- drivers/reset/Kconfig | 10 +++++++--- drivers/reset/reset-simple.c | 2 ++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 7fc77696bb1e..18f152d251d7 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -83,14 +83,18 @@ config RESET_PISTACHIO config RESET_SIMPLE bool "Simple Reset Controller Driver" if COMPILE_TEST - default ARCH_SOCFPGA || ARCH_STM32 || ARCH_STRATIX10 || ARCH_SUNXI || ARCH_ZX + default ARCH_SOCFPGA || ARCH_STM32 || ARCH_STRATIX10 || ARCH_SUNXI || ARCH_ZX || ARCH_ASPEED help This enables a simple reset controller driver for reset lines that that can be asserted and deasserted by toggling bits in a contiguous, exclusive register space. - Currently this driver supports Altera SoCFPGAs, the RCC reset - controller in STM32 MCUs, Allwinner SoCs, and ZTE's zx2967 family. + Currently this driver supports: + - Altera SoCFPGAs + - ASPEED BMC SoCs + - RCC reset controller in STM32 MCUs + - Allwinner SoCs + - ZTE's zx2967 family config RESET_SUNXI bool "Allwinner SoCs Reset Driver" if COMPILE_TEST && !ARCH_SUNXI diff --git a/drivers/reset/reset-simple.c b/drivers/reset/reset-simple.c index 2d4f362ef025..f7ce8910a392 100644 --- a/drivers/reset/reset-simple.c +++ b/drivers/reset/reset-simple.c @@ -125,6 +125,8 @@ static const struct of_device_id reset_simple_dt_ids[] = { .data = &reset_simple_active_low }, { .compatible = "zte,zx296718-reset", .data = &reset_simple_active_low }, + { .compatible = "aspeed,ast2400-lpc-reset" }, + { .compatible = "aspeed,ast2500-lpc-reset" }, { /* sentinel */ }, }; -- cgit v1.2.3 From cd6f0602d2950efb488290571c2ae2ca92befe53 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Tue, 5 Dec 2017 23:16:35 +0100 Subject: firmware: arm_scpi: remove two unneeded devm_kfree's in scpi_remove Both memory areas are free'd anyway when the device is destroyed, so we don't have to do it manually. Tested-by: Kevin Hilman Signed-off-by: Heiner Kallweit Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scpi.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c index 7da9f1b83ebe..2a30d255e750 100644 --- a/drivers/firmware/arm_scpi.c +++ b/drivers/firmware/arm_scpi.c @@ -918,8 +918,6 @@ static int scpi_remove(struct platform_device *pdev) kfree(info->dvfs[i]->opps); kfree(info->dvfs[i]); } - devm_kfree(dev, info->channels); - devm_kfree(dev, info); return 0; } -- cgit v1.2.3 From c14f1db41d0af210986468637f555dfdc72b0d57 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Tue, 5 Dec 2017 23:16:42 +0100 Subject: firmware: arm_scpi: make freeing mbox channels device-managed Make freeing the mbox channels device-managed, thus further simplifying scpi_remove and and one further step to get rid of scpi_remove. Tested-by: Kevin Hilman Signed-off-by: Heiner Kallweit Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scpi.c | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c index 2a30d255e750..4447738d4b62 100644 --- a/drivers/firmware/arm_scpi.c +++ b/drivers/firmware/arm_scpi.c @@ -889,16 +889,13 @@ static struct attribute *versions_attrs[] = { }; ATTRIBUTE_GROUPS(versions); -static void -scpi_free_channels(struct device *dev, struct scpi_chan *pchan, int count) +static void scpi_free_channels(void *data) { + struct scpi_drvinfo *info = data; int i; - for (i = 0; i < count && pchan->chan; i++, pchan++) { - mbox_free_channel(pchan->chan); - devm_kfree(dev, pchan->xfers); - devm_iounmap(dev, pchan->rx_payload); - } + for (i = 0; i < info->num_chans; i++) + mbox_free_channel(info->channels[i].chan); } static int scpi_remove(struct platform_device *pdev) @@ -911,7 +908,6 @@ static int scpi_remove(struct platform_device *pdev) of_platform_depopulate(dev); sysfs_remove_groups(&dev->kobj, versions_groups); - scpi_free_channels(dev, info->channels, info->num_chans); platform_set_drvdata(pdev, NULL); for (i = 0; i < MAX_DVFS_DOMAINS && info->dvfs[i]; i++) { @@ -950,7 +946,6 @@ static int scpi_probe(struct platform_device *pdev) { int count, idx, ret; struct resource res; - struct scpi_chan *scpi_chan; struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; @@ -967,13 +962,19 @@ static int scpi_probe(struct platform_device *pdev) return -ENODEV; } - scpi_chan = devm_kcalloc(dev, count, sizeof(*scpi_chan), GFP_KERNEL); - if (!scpi_chan) + scpi_info->channels = devm_kcalloc(dev, count, sizeof(struct scpi_chan), + GFP_KERNEL); + if (!scpi_info->channels) return -ENOMEM; - for (idx = 0; idx < count; idx++) { + ret = devm_add_action(dev, scpi_free_channels, scpi_info); + if (ret) + return ret; + + for (; scpi_info->num_chans < count; scpi_info->num_chans++) { resource_size_t size; - struct scpi_chan *pchan = scpi_chan + idx; + int idx = scpi_info->num_chans; + struct scpi_chan *pchan = scpi_info->channels + idx; struct mbox_client *cl = &pchan->cl; struct device_node *shmem = of_parse_phandle(np, "shmem", idx); @@ -981,15 +982,14 @@ static int scpi_probe(struct platform_device *pdev) of_node_put(shmem); if (ret) { dev_err(dev, "failed to get SCPI payload mem resource\n"); - goto err; + return ret; } size = resource_size(&res); pchan->rx_payload = devm_ioremap(dev, res.start, size); if (!pchan->rx_payload) { dev_err(dev, "failed to ioremap SCPI payload\n"); - ret = -EADDRNOTAVAIL; - goto err; + return -EADDRNOTAVAIL; } pchan->tx_payload = pchan->rx_payload + (size >> 1); @@ -1015,14 +1015,9 @@ static int scpi_probe(struct platform_device *pdev) dev_err(dev, "failed to get channel%d err %d\n", idx, ret); } -err: - scpi_free_channels(dev, scpi_chan, idx); - scpi_info = NULL; return ret; } - scpi_info->channels = scpi_chan; - scpi_info->num_chans = count; scpi_info->commands = scpi_std_commands; platform_set_drvdata(pdev, scpi_info); -- cgit v1.2.3 From 5abc7935ed5bf70aa69a6001eee8495df43a17c7 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Tue, 5 Dec 2017 23:16:48 +0100 Subject: firmware: arm_scpi: make scpi_probe completely device-managed Replace two remaining functions in probe with their devm versions. Tested-by: Kevin Hilman Signed-off-by: Heiner Kallweit Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scpi.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c index 4447738d4b62..a6f6039ee3f9 100644 --- a/drivers/firmware/arm_scpi.c +++ b/drivers/firmware/arm_scpi.c @@ -901,15 +901,10 @@ static void scpi_free_channels(void *data) static int scpi_remove(struct platform_device *pdev) { int i; - struct device *dev = &pdev->dev; struct scpi_drvinfo *info = platform_get_drvdata(pdev); scpi_info = NULL; /* stop exporting SCPI ops through get_scpi_ops */ - of_platform_depopulate(dev); - sysfs_remove_groups(&dev->kobj, versions_groups); - platform_set_drvdata(pdev, NULL); - for (i = 0; i < MAX_DVFS_DOMAINS && info->dvfs[i]; i++) { kfree(info->dvfs[i]->opps); kfree(info->dvfs[i]); @@ -1036,7 +1031,6 @@ static int scpi_probe(struct platform_device *pdev) ret = scpi_init_versions(scpi_info); if (ret) { dev_err(dev, "incorrect or no SCP firmware found\n"); - scpi_remove(pdev); return ret; } @@ -1048,11 +1042,11 @@ static int scpi_probe(struct platform_device *pdev) FW_REV_PATCH(scpi_info->firmware_version)); scpi_info->scpi_ops = &scpi_ops; - ret = sysfs_create_groups(&dev->kobj, versions_groups); + ret = devm_device_add_groups(dev, versions_groups); if (ret) dev_err(dev, "unable to create sysfs version group\n"); - return of_platform_populate(dev->of_node, NULL, NULL, dev); + return devm_of_platform_populate(dev); } static const struct of_device_id scpi_of_match[] = { -- cgit v1.2.3 From a963d7c5264eaa544837ac8182a9eea55007a669 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Tue, 5 Dec 2017 23:16:52 +0100 Subject: firmware: arm_scpi: improve struct dvfs_info to make code better readable Making the header subfields members of struct dvfs_info allows to make the code better readable and avoids some macro magic. In addition remove a useless statement using info->latency. Tested-by: Kevin Hilman Signed-off-by: Heiner Kallweit Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scpi.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c index a6f6039ee3f9..9eeb53b766e0 100644 --- a/drivers/firmware/arm_scpi.c +++ b/drivers/firmware/arm_scpi.c @@ -72,8 +72,6 @@ #define MAX_DVFS_DOMAINS 8 #define MAX_DVFS_OPPS 16 -#define DVFS_LATENCY(hdr) (le32_to_cpu(hdr) >> 16) -#define DVFS_OPP_COUNT(hdr) ((le32_to_cpu(hdr) >> 8) & 0xff) #define PROTOCOL_REV_MINOR_BITS 16 #define PROTOCOL_REV_MINOR_MASK ((1U << PROTOCOL_REV_MINOR_BITS) - 1) @@ -328,7 +326,9 @@ struct legacy_clk_set_value { } __packed; struct dvfs_info { - __le32 header; + u8 domain; + u8 opp_count; + __le16 latency; struct { __le32 freq; __le32 m_volt; @@ -665,8 +665,8 @@ static struct scpi_dvfs_info *scpi_dvfs_get_info(u8 domain) if (!info) return ERR_PTR(-ENOMEM); - info->count = DVFS_OPP_COUNT(buf.header); - info->latency = DVFS_LATENCY(buf.header) * 1000; /* uS to nS */ + info->count = buf.opp_count; + info->latency = le16_to_cpu(buf.latency) * 1000; /* uS to nS */ info->opps = kcalloc(info->count, sizeof(*opp), GFP_KERNEL); if (!info->opps) { @@ -713,9 +713,6 @@ static int scpi_dvfs_get_transition_latency(struct device *dev) if (IS_ERR(info)) return PTR_ERR(info); - if (!info->latency) - return 0; - return info->latency; } -- cgit v1.2.3 From 7cd49a264594251d87e504fe07dcb1fe2c99bbef Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Tue, 5 Dec 2017 23:16:55 +0100 Subject: firmware: arm_scpi: improve handling of protocol and firmware version subfields By using FIELD_GET and proper masks we can avoid quite some shifting and masking macro magic and make the code better readable. Tested-by: Kevin Hilman Signed-off-by: Heiner Kallweit Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scpi.c | 43 +++++++++++++++++++------------------------ 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c index 9eeb53b766e0..63441e403f60 100644 --- a/drivers/firmware/arm_scpi.c +++ b/drivers/firmware/arm_scpi.c @@ -28,6 +28,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include +#include #include #include #include @@ -73,18 +74,12 @@ #define MAX_DVFS_DOMAINS 8 #define MAX_DVFS_OPPS 16 -#define PROTOCOL_REV_MINOR_BITS 16 -#define PROTOCOL_REV_MINOR_MASK ((1U << PROTOCOL_REV_MINOR_BITS) - 1) -#define PROTOCOL_REV_MAJOR(x) ((x) >> PROTOCOL_REV_MINOR_BITS) -#define PROTOCOL_REV_MINOR(x) ((x) & PROTOCOL_REV_MINOR_MASK) +#define PROTO_REV_MAJOR_MASK GENMASK(31, 16) +#define PROTO_REV_MINOR_MASK GENMASK(15, 0) -#define FW_REV_MAJOR_BITS 24 -#define FW_REV_MINOR_BITS 16 -#define FW_REV_PATCH_MASK ((1U << FW_REV_MINOR_BITS) - 1) -#define FW_REV_MINOR_MASK ((1U << FW_REV_MAJOR_BITS) - 1) -#define FW_REV_MAJOR(x) ((x) >> FW_REV_MAJOR_BITS) -#define FW_REV_MINOR(x) (((x) & FW_REV_MINOR_MASK) >> FW_REV_MINOR_BITS) -#define FW_REV_PATCH(x) ((x) & FW_REV_PATCH_MASK) +#define FW_REV_MAJOR_MASK GENMASK(31, 24) +#define FW_REV_MINOR_MASK GENMASK(23, 16) +#define FW_REV_PATCH_MASK GENMASK(15, 0) #define MAX_RX_TIMEOUT (msecs_to_jiffies(30)) @@ -861,9 +856,9 @@ static ssize_t protocol_version_show(struct device *dev, { struct scpi_drvinfo *scpi_info = dev_get_drvdata(dev); - return sprintf(buf, "%d.%d\n", - PROTOCOL_REV_MAJOR(scpi_info->protocol_version), - PROTOCOL_REV_MINOR(scpi_info->protocol_version)); + return sprintf(buf, "%lu.%lu\n", + FIELD_GET(PROTO_REV_MAJOR_MASK, scpi_info->protocol_version), + FIELD_GET(PROTO_REV_MINOR_MASK, scpi_info->protocol_version)); } static DEVICE_ATTR_RO(protocol_version); @@ -872,10 +867,10 @@ static ssize_t firmware_version_show(struct device *dev, { struct scpi_drvinfo *scpi_info = dev_get_drvdata(dev); - return sprintf(buf, "%d.%d.%d\n", - FW_REV_MAJOR(scpi_info->firmware_version), - FW_REV_MINOR(scpi_info->firmware_version), - FW_REV_PATCH(scpi_info->firmware_version)); + return sprintf(buf, "%lu.%lu.%lu\n", + FIELD_GET(FW_REV_MAJOR_MASK, scpi_info->firmware_version), + FIELD_GET(FW_REV_MINOR_MASK, scpi_info->firmware_version), + FIELD_GET(FW_REV_PATCH_MASK, scpi_info->firmware_version)); } static DEVICE_ATTR_RO(firmware_version); @@ -1031,12 +1026,12 @@ static int scpi_probe(struct platform_device *pdev) return ret; } - _dev_info(dev, "SCP Protocol %d.%d Firmware %d.%d.%d version\n", - PROTOCOL_REV_MAJOR(scpi_info->protocol_version), - PROTOCOL_REV_MINOR(scpi_info->protocol_version), - FW_REV_MAJOR(scpi_info->firmware_version), - FW_REV_MINOR(scpi_info->firmware_version), - FW_REV_PATCH(scpi_info->firmware_version)); + dev_info(dev, "SCP Protocol %lu.%lu Firmware %lu.%lu.%lu version\n", + FIELD_GET(PROTO_REV_MAJOR_MASK, scpi_info->protocol_version), + FIELD_GET(PROTO_REV_MINOR_MASK, scpi_info->protocol_version), + FIELD_GET(FW_REV_MAJOR_MASK, scpi_info->firmware_version), + FIELD_GET(FW_REV_MINOR_MASK, scpi_info->firmware_version), + FIELD_GET(FW_REV_PATCH_MASK, scpi_info->firmware_version)); scpi_info->scpi_ops = &scpi_ops; ret = devm_device_add_groups(dev, versions_groups); -- cgit v1.2.3 From 83a6060c0cd07cafdf8baa08e26c602a06977a2c Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Tue, 5 Dec 2017 23:16:58 +0100 Subject: firmware: arm_scpi: improve struct sensor_value lo_val and hi_val together in this order are a little endian 64 bit value. Therefore we can simplify struct sensor_value and the code by defining it as a __le64 value and by using le64_to_cpu. Tested-by: Kevin Hilman Signed-off-by: Heiner Kallweit Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scpi.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c index 63441e403f60..4447af482fe9 100644 --- a/drivers/firmware/arm_scpi.c +++ b/drivers/firmware/arm_scpi.c @@ -347,9 +347,8 @@ struct _scpi_sensor_info { }; struct sensor_value { - __le32 lo_val; - __le32 hi_val; -} __packed; + __le64 val; +}; struct dev_pstate_set { __le16 dev_id; @@ -777,11 +776,10 @@ static int scpi_sensor_get_value(u16 sensor, u64 *val) return ret; if (scpi_info->is_legacy) - /* only 32-bits supported, hi_val can be junk */ - *val = le32_to_cpu(buf.lo_val); + /* only 32-bits supported, upper 32 bits can be junk */ + *val = le32_to_cpup((__le32 *)&buf.val); else - *val = (u64)le32_to_cpu(buf.hi_val) << 32 | - le32_to_cpu(buf.lo_val); + *val = le64_to_cpu(buf.val); return 0; } -- cgit v1.2.3 From 27901cccf8dd7b9e8d77c2637a2b306d731e567d Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Tue, 5 Dec 2017 23:17:03 +0100 Subject: firmware: arm_scpi: drop unnecessary type cast to scpi_shared_mem This patch drops the only present type cast of the SCPI payload pointer to scpi_shared_mem inorder to align with other occurrences, IOW for consistency. Tested-by: Kevin Hilman Reviewed-by: Heiner Kallweit Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c index 4447af482fe9..e02d58208a94 100644 --- a/drivers/firmware/arm_scpi.c +++ b/drivers/firmware/arm_scpi.c @@ -453,7 +453,7 @@ static void scpi_tx_prepare(struct mbox_client *c, void *msg) unsigned long flags; struct scpi_xfer *t = msg; struct scpi_chan *ch = container_of(c, struct scpi_chan, cl); - struct scpi_shared_mem *mem = (struct scpi_shared_mem *)ch->tx_payload; + struct scpi_shared_mem *mem = ch->tx_payload; if (t->tx_buf) { if (scpi_info->is_legacy) -- cgit v1.2.3 From c10bd41ab0b2508a98651ab3e4e9fbc85425eaad Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Tue, 5 Dec 2017 23:17:09 +0100 Subject: firmware: arm_scpi: remove all single element structures Both clk_get_value and sensor_value structures contains a single element and hence needs no packing making the whole structure defination unnecessary. This patch gets rid of both those unnecessary structures. Tested-by: Kevin Hilman Reviewed-by: Heiner Kallweit Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scpi.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c index e02d58208a94..3a722e5a6666 100644 --- a/drivers/firmware/arm_scpi.c +++ b/drivers/firmware/arm_scpi.c @@ -304,10 +304,6 @@ struct clk_get_info { u8 name[20]; } __packed; -struct clk_get_value { - __le32 rate; -} __packed; - struct clk_set_value { __le16 id; __le16 reserved; @@ -346,10 +342,6 @@ struct _scpi_sensor_info { char name[20]; }; -struct sensor_value { - __le64 val; -}; - struct dev_pstate_set { __le16 dev_id; u8 pstate; @@ -577,13 +569,13 @@ scpi_clk_get_range(u16 clk_id, unsigned long *min, unsigned long *max) static unsigned long scpi_clk_get_val(u16 clk_id) { int ret; - struct clk_get_value clk; + __le32 rate; __le16 le_clk_id = cpu_to_le16(clk_id); ret = scpi_send_message(CMD_GET_CLOCK_VALUE, &le_clk_id, - sizeof(le_clk_id), &clk, sizeof(clk)); + sizeof(le_clk_id), &rate, sizeof(rate)); - return ret ? ret : le32_to_cpu(clk.rate); + return ret ? ret : le32_to_cpu(rate); } static int scpi_clk_set_val(u16 clk_id, unsigned long rate) @@ -767,19 +759,19 @@ static int scpi_sensor_get_info(u16 sensor_id, struct scpi_sensor_info *info) static int scpi_sensor_get_value(u16 sensor, u64 *val) { __le16 id = cpu_to_le16(sensor); - struct sensor_value buf; + __le64 value; int ret; ret = scpi_send_message(CMD_SENSOR_VALUE, &id, sizeof(id), - &buf, sizeof(buf)); + &value, sizeof(value)); if (ret) return ret; if (scpi_info->is_legacy) /* only 32-bits supported, upper 32 bits can be junk */ - *val = le32_to_cpup((__le32 *)&buf.val); + *val = le32_to_cpup((__le32 *)&value); else - *val = le64_to_cpu(buf.val); + *val = le64_to_cpu(value); return 0; } -- cgit v1.2.3 From 5204abd35243760116efcf565b55880915452bab Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Tue, 5 Dec 2017 23:17:11 +0100 Subject: firmware: arm_scpi: fix incorrect __iomem accesses using correct accessors At several positions in the code sparse complains about incorrect access to __iomem annotated memory. Fix this and make sparse happy. Tested-by: Kevin Hilman Signed-off-by: Heiner Kallweit [Sudeep Holla: changed the patch title to describe the change] Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scpi.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c index 3a722e5a6666..b653ada42e1d 100644 --- a/drivers/firmware/arm_scpi.c +++ b/drivers/firmware/arm_scpi.c @@ -405,19 +405,20 @@ static void scpi_process_cmd(struct scpi_chan *ch, u32 cmd) unsigned int len; if (scpi_info->is_legacy) { - struct legacy_scpi_shared_mem *mem = ch->rx_payload; + struct legacy_scpi_shared_mem __iomem *mem = + ch->rx_payload; /* RX Length is not replied by the legacy Firmware */ len = match->rx_len; - match->status = le32_to_cpu(mem->status); + match->status = ioread32(&mem->status); memcpy_fromio(match->rx_buf, mem->payload, len); } else { - struct scpi_shared_mem *mem = ch->rx_payload; + struct scpi_shared_mem __iomem *mem = ch->rx_payload; len = min(match->rx_len, CMD_SIZE(cmd)); - match->status = le32_to_cpu(mem->status); + match->status = ioread32(&mem->status); memcpy_fromio(match->rx_buf, mem->payload, len); } @@ -431,11 +432,11 @@ static void scpi_process_cmd(struct scpi_chan *ch, u32 cmd) static void scpi_handle_remote_msg(struct mbox_client *c, void *msg) { struct scpi_chan *ch = container_of(c, struct scpi_chan, cl); - struct scpi_shared_mem *mem = ch->rx_payload; + struct scpi_shared_mem __iomem *mem = ch->rx_payload; u32 cmd = 0; if (!scpi_info->is_legacy) - cmd = le32_to_cpu(mem->command); + cmd = ioread32(&mem->command); scpi_process_cmd(ch, cmd); } @@ -445,7 +446,7 @@ static void scpi_tx_prepare(struct mbox_client *c, void *msg) unsigned long flags; struct scpi_xfer *t = msg; struct scpi_chan *ch = container_of(c, struct scpi_chan, cl); - struct scpi_shared_mem *mem = ch->tx_payload; + struct scpi_shared_mem __iomem *mem = ch->tx_payload; if (t->tx_buf) { if (scpi_info->is_legacy) @@ -464,7 +465,7 @@ static void scpi_tx_prepare(struct mbox_client *c, void *msg) } if (!scpi_info->is_legacy) - mem->command = cpu_to_le32(t->cmd); + iowrite32(t->cmd, &mem->command); } static struct scpi_xfer *get_scpi_xfer(struct scpi_chan *ch) -- cgit v1.2.3 From 17431b787460d5c365d81224f95bf88b4685588b Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Tue, 5 Dec 2017 23:17:13 +0100 Subject: firmware: arm_scpi: remove struct sensor_capabilities One more single-element struct was left, remove it. Tested-by: Kevin Hilman Signed-off-by: Heiner Kallweit Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scpi.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c index b653ada42e1d..5695b1f4d6f9 100644 --- a/drivers/firmware/arm_scpi.c +++ b/drivers/firmware/arm_scpi.c @@ -331,10 +331,6 @@ struct dvfs_set { u8 index; } __packed; -struct sensor_capabilities { - __le16 sensors; -} __packed; - struct _scpi_sensor_info { __le16 sensor_id; u8 class; @@ -730,13 +726,13 @@ static int scpi_dvfs_add_opps_to_device(struct device *dev) static int scpi_sensor_get_capability(u16 *sensors) { - struct sensor_capabilities cap_buf; + __le16 cap; int ret; - ret = scpi_send_message(CMD_SENSOR_CAPABILITIES, NULL, 0, &cap_buf, - sizeof(cap_buf)); + ret = scpi_send_message(CMD_SENSOR_CAPABILITIES, NULL, 0, &cap, + sizeof(cap)); if (!ret) - *sensors = le16_to_cpu(cap_buf.sensors); + *sensors = le16_to_cpu(cap); return ret; } -- cgit v1.2.3 From 96fe77b6d4762604ba034d57319ad6c4ef071205 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Tue, 5 Dec 2017 23:17:15 +0100 Subject: firmware: arm_scpi: use FIELD_GET/_PREP to simplify macro definitions Macro definitions can be simplified by making use of the FIELD_GET/_PREP bitfield macros. Tested-by: Kevin Hilman Signed-off-by: Heiner Kallweit Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scpi.c | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c index 5695b1f4d6f9..bc7055a6a617 100644 --- a/drivers/firmware/arm_scpi.c +++ b/drivers/firmware/arm_scpi.c @@ -46,27 +46,19 @@ #include #include -#define CMD_ID_SHIFT 0 -#define CMD_ID_MASK 0x7f -#define CMD_TOKEN_ID_SHIFT 8 -#define CMD_TOKEN_ID_MASK 0xff -#define CMD_DATA_SIZE_SHIFT 16 -#define CMD_DATA_SIZE_MASK 0x1ff -#define CMD_LEGACY_DATA_SIZE_SHIFT 20 -#define CMD_LEGACY_DATA_SIZE_MASK 0x1ff -#define PACK_SCPI_CMD(cmd_id, tx_sz) \ - ((((cmd_id) & CMD_ID_MASK) << CMD_ID_SHIFT) | \ - (((tx_sz) & CMD_DATA_SIZE_MASK) << CMD_DATA_SIZE_SHIFT)) -#define ADD_SCPI_TOKEN(cmd, token) \ - ((cmd) |= (((token) & CMD_TOKEN_ID_MASK) << CMD_TOKEN_ID_SHIFT)) -#define PACK_LEGACY_SCPI_CMD(cmd_id, tx_sz) \ - ((((cmd_id) & CMD_ID_MASK) << CMD_ID_SHIFT) | \ - (((tx_sz) & CMD_LEGACY_DATA_SIZE_MASK) << CMD_LEGACY_DATA_SIZE_SHIFT)) - -#define CMD_SIZE(cmd) (((cmd) >> CMD_DATA_SIZE_SHIFT) & CMD_DATA_SIZE_MASK) -#define CMD_LEGACY_SIZE(cmd) (((cmd) >> CMD_LEGACY_DATA_SIZE_SHIFT) & \ - CMD_LEGACY_DATA_SIZE_MASK) -#define CMD_UNIQ_MASK (CMD_TOKEN_ID_MASK << CMD_TOKEN_ID_SHIFT | CMD_ID_MASK) +#define CMD_ID_MASK GENMASK(6, 0) +#define CMD_TOKEN_ID_MASK GENMASK(15, 8) +#define CMD_DATA_SIZE_MASK GENMASK(24, 16) +#define CMD_LEGACY_DATA_SIZE_MASK GENMASK(28, 20) +#define PACK_SCPI_CMD(cmd_id, tx_sz) \ + (FIELD_PREP(CMD_ID_MASK, cmd_id) | \ + FIELD_PREP(CMD_DATA_SIZE_MASK, tx_sz)) +#define PACK_LEGACY_SCPI_CMD(cmd_id, tx_sz) \ + (FIELD_PREP(CMD_ID_MASK, cmd_id) | \ + FIELD_PREP(CMD_LEGACY_DATA_SIZE_MASK, tx_sz)) + +#define CMD_SIZE(cmd) FIELD_GET(CMD_DATA_SIZE_MASK, cmd) +#define CMD_UNIQ_MASK (CMD_TOKEN_ID_MASK | CMD_ID_MASK) #define CMD_XTRACT_UNIQ(cmd) ((cmd) & CMD_UNIQ_MASK) #define SCPI_SLOT 0 @@ -412,7 +404,7 @@ static void scpi_process_cmd(struct scpi_chan *ch, u32 cmd) } else { struct scpi_shared_mem __iomem *mem = ch->rx_payload; - len = min(match->rx_len, CMD_SIZE(cmd)); + len = min_t(unsigned int, match->rx_len, CMD_SIZE(cmd)); match->status = ioread32(&mem->status); memcpy_fromio(match->rx_buf, mem->payload, len); @@ -454,7 +446,7 @@ static void scpi_tx_prepare(struct mbox_client *c, void *msg) if (t->rx_buf) { if (!(++ch->token)) ++ch->token; - ADD_SCPI_TOKEN(t->cmd, ch->token); + t->cmd |= FIELD_PREP(CMD_TOKEN_ID_MASK, ch->token); spin_lock_irqsave(&ch->rx_lock, flags); list_add_tail(&t->node, &ch->rx_pending); spin_unlock_irqrestore(&ch->rx_lock, flags); -- cgit v1.2.3 From 62c60efb63c868c1b1e54a1138c3295deae76eda Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Tue, 5 Dec 2017 23:17:19 +0100 Subject: firmware: arm_scpi: improve info message for pre-1.0 firmware On legacy pre-1.0 firmware versions so far the following message is printed which may cause some confusion: SCP Protocol 0.0 Firmware 0.0.0 version Therefore replace the message with the following if firmware doesn't provide usable version information: SCP Protocol legacy pre-1.0 firmware Tested-by: Kevin Hilman Signed-off-by: Heiner Kallweit Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scpi.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c index bc7055a6a617..6d7a6c0a5e07 100644 --- a/drivers/firmware/arm_scpi.c +++ b/drivers/firmware/arm_scpi.c @@ -1005,12 +1005,21 @@ static int scpi_probe(struct platform_device *pdev) return ret; } - dev_info(dev, "SCP Protocol %lu.%lu Firmware %lu.%lu.%lu version\n", - FIELD_GET(PROTO_REV_MAJOR_MASK, scpi_info->protocol_version), - FIELD_GET(PROTO_REV_MINOR_MASK, scpi_info->protocol_version), - FIELD_GET(FW_REV_MAJOR_MASK, scpi_info->firmware_version), - FIELD_GET(FW_REV_MINOR_MASK, scpi_info->firmware_version), - FIELD_GET(FW_REV_PATCH_MASK, scpi_info->firmware_version)); + if (scpi_info->is_legacy && !scpi_info->protocol_version && + !scpi_info->firmware_version) + dev_info(dev, "SCP Protocol legacy pre-1.0 firmware\n"); + else + dev_info(dev, "SCP Protocol %lu.%lu Firmware %lu.%lu.%lu version\n", + FIELD_GET(PROTO_REV_MAJOR_MASK, + scpi_info->protocol_version), + FIELD_GET(PROTO_REV_MINOR_MASK, + scpi_info->protocol_version), + FIELD_GET(FW_REV_MAJOR_MASK, + scpi_info->firmware_version), + FIELD_GET(FW_REV_MINOR_MASK, + scpi_info->firmware_version), + FIELD_GET(FW_REV_PATCH_MASK, + scpi_info->firmware_version)); scpi_info->scpi_ops = &scpi_ops; ret = devm_device_add_groups(dev, versions_groups); -- cgit v1.2.3 From 07455e4e4321129af0053c61191707ccf8289fc7 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Mon, 26 Jun 2017 16:02:39 +0100 Subject: dt-bindings: mailbox: add support for mailbox client shared memory Many users of the mailbox controllers depend on the shared memory between the two end points to exchange the main data while using simple doorbell mechanism to alert the end points of the presence of a message. This patch defines device tree bindings to represent such shared memory in a generic way. Cc: Mark Rutland Acked-by: Rob Herring Signed-off-by: Sudeep Holla --- .../devicetree/bindings/mailbox/mailbox.txt | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/Documentation/devicetree/bindings/mailbox/mailbox.txt b/Documentation/devicetree/bindings/mailbox/mailbox.txt index be05b9746c69..af8ecee2ac68 100644 --- a/Documentation/devicetree/bindings/mailbox/mailbox.txt +++ b/Documentation/devicetree/bindings/mailbox/mailbox.txt @@ -23,6 +23,11 @@ Required property: Optional property: - mbox-names: List of identifier strings for each mailbox channel. +- shmem : List of phandle pointing to the shared memory(SHM) area between the + users of these mailboxes for IPC, one for each mailbox. This shared + memory can be part of any memory reserved for the purpose of this + communication between the mailbox client and the remote. + Example: pwr_cntrl: power { @@ -30,3 +35,26 @@ Example: mbox-names = "pwr-ctrl", "rpc"; mboxes = <&mailbox 0 &mailbox 1>; }; + +Example with shared memory(shmem): + + sram: sram@50000000 { + compatible = "mmio-sram"; + reg = <0x50000000 0x10000>; + + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x50000000 0x10000>; + + cl_shmem: shmem@0 { + compatible = "client-shmem"; + reg = <0x0 0x200>; + }; + }; + + client@2e000000 { + ... + mboxes = <&mailbox 0>; + shmem = <&cl_shmem>; + .. + }; -- cgit v1.2.3 From fe7be8b297b279189260f8ce084ea16fab0c2be0 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Mon, 5 Jun 2017 17:27:11 +0100 Subject: dt-bindings: arm: add support for ARM System Control and Management Interface(SCMI) protocol This patch adds devicetree binding for System Control and Management Interface (SCMI) Message Protocol used between the Application Cores(AP) and the System Control Processor(SCP). The MHU peripheral provides a mechanism for inter-processor communication between SCP's M3 processor and AP. SCP offers control and management of the core/cluster power states, various power domain DVFS including the core/cluster, certain system clocks configuration, thermal sensors and many others. SCMI protocol is developed as better replacement to the existing SCPI which is not flexible and easily extensible. Cc: Mark Rutland Acked-by: Rob Herring Signed-off-by: Sudeep Holla --- Documentation/devicetree/bindings/arm/arm,scmi.txt | 179 +++++++++++++++++++++ MAINTAINERS | 4 +- 2 files changed, 181 insertions(+), 2 deletions(-) create mode 100644 Documentation/devicetree/bindings/arm/arm,scmi.txt diff --git a/Documentation/devicetree/bindings/arm/arm,scmi.txt b/Documentation/devicetree/bindings/arm/arm,scmi.txt new file mode 100644 index 000000000000..5f3719ab7075 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/arm,scmi.txt @@ -0,0 +1,179 @@ +System Control and Management Interface (SCMI) Message Protocol +---------------------------------------------------------- + +The SCMI is intended to allow agents such as OSPM to manage various functions +that are provided by the hardware platform it is running on, including power +and performance functions. + +This binding is intended to define the interface the firmware implementing +the SCMI as described in ARM document number ARM DUI 0922B ("ARM System Control +and Management Interface Platform Design Document")[0] provide for OSPM in +the device tree. + +Required properties: + +The scmi node with the following properties shall be under the /firmware/ node. + +- compatible : shall be "arm,scmi" +- mboxes: List of phandle and mailbox channel specifiers. It should contain + exactly one or two mailboxes, one for transmitting messages("tx") + and another optional for receiving the notifications("rx") if + supported. +- shmem : List of phandle pointing to the shared memory(SHM) area as per + generic mailbox client binding. +- #address-cells : should be '1' if the device has sub-nodes, maps to + protocol identifier for a given sub-node. +- #size-cells : should be '0' as 'reg' property doesn't have any size + associated with it. + +Optional properties: + +- mbox-names: shall be "tx" or "rx" depending on mboxes entries. + +See Documentation/devicetree/bindings/mailbox/mailbox.txt for more details +about the generic mailbox controller and client driver bindings. + +The mailbox is the only permitted method of calling the SCMI firmware. +Mailbox doorbell is used as a mechanism to alert the presence of a +messages and/or notification. + +Each protocol supported shall have a sub-node with corresponding compatible +as described in the following sections. If the platform supports dedicated +communication channel for a particular protocol, the 3 properties namely: +mboxes, mbox-names and shmem shall be present in the sub-node corresponding +to that protocol. + +Clock/Performance bindings for the clocks/OPPs based on SCMI Message Protocol +------------------------------------------------------------ + +This binding uses the common clock binding[1]. + +Required properties: +- #clock-cells : Should be 1. Contains the Clock ID value used by SCMI commands. + +Power domain bindings for the power domains based on SCMI Message Protocol +------------------------------------------------------------ + +This binding for the SCMI power domain providers uses the generic power +domain binding[2]. + +Required properties: + - #power-domain-cells : Should be 1. Contains the device or the power + domain ID value used by SCMI commands. + +Sensor bindings for the sensors based on SCMI Message Protocol +-------------------------------------------------------------- +SCMI provides an API to access the various sensors on the SoC. + +Required properties: +- #thermal-sensor-cells: should be set to 1. This property follows the + thermal device tree bindings[3]. + + Valid cell values are raw identifiers (Sensor ID) + as used by the firmware. Refer to platform details + for your implementation for the IDs to use. + +SRAM and Shared Memory for SCMI +------------------------------- + +A small area of SRAM is reserved for SCMI communication between application +processors and SCP. + +The properties should follow the generic mmio-sram description found in [4] + +Each sub-node represents the reserved area for SCMI. + +Required sub-node properties: +- reg : The base offset and size of the reserved area with the SRAM +- compatible : should be "arm,scmi-shmem" for Non-secure SRAM based + shared memory + +[0] http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/index.html +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt +[2] Documentation/devicetree/bindings/power/power_domain.txt +[3] Documentation/devicetree/bindings/thermal/thermal.txt +[4] Documentation/devicetree/bindings/sram/sram.txt + +Example: + +sram@50000000 { + compatible = "mmio-sram"; + reg = <0x0 0x50000000 0x0 0x10000>; + + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x0 0x50000000 0x10000>; + + cpu_scp_lpri: scp-shmem@0 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0x200>; + }; + + cpu_scp_hpri: scp-shmem@200 { + compatible = "arm,scmi-shmem"; + reg = <0x200 0x200>; + }; +}; + +mailbox@40000000 { + .... + #mbox-cells = <1>; + reg = <0x0 0x40000000 0x0 0x10000>; +}; + +firmware { + + ... + + scmi { + compatible = "arm,scmi"; + mboxes = <&mailbox 0 &mailbox 1>; + mbox-names = "tx", "rx"; + shmem = <&cpu_scp_lpri &cpu_scp_hpri>; + #address-cells = <1>; + #size-cells = <0>; + + scmi_devpd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi_dvfs: protocol@13 { + reg = <0x13>; + #clock-cells = <1>; + }; + + scmi_clk: protocol@14 { + reg = <0x14>; + #clock-cells = <1>; + }; + + scmi_sensors0: protocol@15 { + reg = <0x15>; + #thermal-sensor-cells = <1>; + }; + }; +}; + +cpu@0 { + ... + reg = <0 0>; + clocks = <&scmi_dvfs 0>; +}; + +hdlcd@7ff60000 { + ... + reg = <0 0x7ff60000 0 0x1000>; + clocks = <&scmi_clk 4>; + power-domains = <&scmi_devpd 1>; +}; + +thermal-zones { + soc_thermal { + polling-delay-passive = <100>; + polling-delay = <1000>; + /* sensor ID */ + thermal-sensors = <&scmi_sensors0 3>; + ... + }; +}; diff --git a/MAINTAINERS b/MAINTAINERS index 3bdc260e36b7..5c8c55ba22a3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13379,11 +13379,11 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git S: Supported F: drivers/mfd/syscon.c -SYSTEM CONTROL & POWER INTERFACE (SCPI) Message Protocol drivers +SYSTEM CONTROL & POWER/MANAGEMENT INTERFACE (SCPI/SCMI) Message Protocol drivers M: Sudeep Holla L: linux-arm-kernel@lists.infradead.org S: Maintained -F: Documentation/devicetree/bindings/arm/arm,scpi.txt +F: Documentation/devicetree/bindings/arm/arm,sc[mp]i.txt F: drivers/clk/clk-scpi.c F: drivers/cpufreq/scpi-cpufreq.c F: drivers/firmware/arm_scpi.c -- cgit v1.2.3 From aa4f886f3893f88146e8e02fd1e9c5c9e43cbcc1 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Tue, 28 Mar 2017 11:36:07 +0100 Subject: firmware: arm_scmi: add basic driver infrastructure for SCMI The SCMI is intended to allow OSPM to manage various functions that are provided by the hardware platform it is running on, including power and performance functions. SCMI provides two levels of abstraction, protocols and transports. Protocols define individual groups of system control and management messages. A protocol specification describes the messages that it supports. Transports describe the method by which protocol messages are communicated between agents and the platform. This patch adds basic infrastructure to manage the message allocation, initialisation, packing/unpacking and shared memory management. Cc: Arnd Bergmann Cc: Greg Kroah-Hartman Signed-off-by: Sudeep Holla --- MAINTAINERS | 3 +- drivers/firmware/Kconfig | 21 ++ drivers/firmware/Makefile | 1 + drivers/firmware/arm_scmi/Makefile | 2 + drivers/firmware/arm_scmi/common.h | 66 ++++ drivers/firmware/arm_scmi/driver.c | 678 +++++++++++++++++++++++++++++++++++++ include/linux/scmi_protocol.h | 16 + 7 files changed, 786 insertions(+), 1 deletion(-) create mode 100644 drivers/firmware/arm_scmi/Makefile create mode 100644 drivers/firmware/arm_scmi/common.h create mode 100644 drivers/firmware/arm_scmi/driver.c create mode 100644 include/linux/scmi_protocol.h diff --git a/MAINTAINERS b/MAINTAINERS index 5c8c55ba22a3..7cede6e7dfed 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13387,7 +13387,8 @@ F: Documentation/devicetree/bindings/arm/arm,sc[mp]i.txt F: drivers/clk/clk-scpi.c F: drivers/cpufreq/scpi-cpufreq.c F: drivers/firmware/arm_scpi.c -F: include/linux/scpi_protocol.h +F: drivers/firmware/arm_scmi/ +F: include/linux/sc[mp]i_protocol.h SYSTEM RESET/SHUTDOWN DRIVERS M: Sebastian Reichel diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index b7c748248e53..704961e0473a 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -19,6 +19,27 @@ config ARM_PSCI_CHECKER on and off through hotplug, so for now torture tests and PSCI checker are mutually exclusive. +config ARM_SCMI_PROTOCOL + bool "ARM System Control and Management Interface (SCMI) Message Protocol" + depends on ARM || ARM64 || COMPILE_TEST + depends on MAILBOX + help + ARM System Control and Management Interface (SCMI) protocol is a + set of operating system-independent software interfaces that are + used in system management. SCMI is extensible and currently provides + interfaces for: Discovery and self-description of the interfaces + it supports, Power domain management which is the ability to place + a given device or domain into the various power-saving states that + it supports, Performance management which is the ability to control + the performance of a domain that is composed of compute engines + such as application processors and other accelerators, Clock + management which is the ability to set and inquire rates on platform + managed clocks and Sensor management which is the ability to read + sensor data, and be notified of sensor value. + + This protocol library provides interface for all the client drivers + making use of the features offered by the SCMI. + config ARM_SCPI_PROTOCOL tristate "ARM System Control and Power Interface (SCPI) Message Protocol" depends on ARM || ARM64 || COMPILE_TEST diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile index b248238ddc6a..e18a041cfc53 100644 --- a/drivers/firmware/Makefile +++ b/drivers/firmware/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_QCOM_SCM_32) += qcom_scm-32.o CFLAGS_qcom_scm-32.o :=$(call as-instr,.arch armv7-a\n.arch_extension sec,-DREQUIRES_SEC=1) -march=armv7-a obj-$(CONFIG_TI_SCI_PROTOCOL) += ti_sci.o +obj-$(CONFIG_ARM_SCMI_PROTOCOL) += arm_scmi/ obj-y += broadcom/ obj-y += meson/ obj-$(CONFIG_GOOGLE_FIRMWARE) += google/ diff --git a/drivers/firmware/arm_scmi/Makefile b/drivers/firmware/arm_scmi/Makefile new file mode 100644 index 000000000000..b2a24ba2b636 --- /dev/null +++ b/drivers/firmware/arm_scmi/Makefile @@ -0,0 +1,2 @@ +obj-y = scmi-driver.o +scmi-driver-y = driver.o diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h new file mode 100644 index 000000000000..d57eb1862f68 --- /dev/null +++ b/drivers/firmware/arm_scmi/common.h @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * System Control and Management Interface (SCMI) Message Protocol + * driver common header file containing some definitions, structures + * and function prototypes used in all the different SCMI protocols. + * + * Copyright (C) 2018 ARM Ltd. + */ + +#include +#include +#include + +/** + * struct scmi_msg_hdr - Message(Tx/Rx) header + * + * @id: The identifier of the command being sent + * @protocol_id: The identifier of the protocol used to send @id command + * @seq: The token to identify the message. when a message/command returns, + * the platform returns the whole message header unmodified including + * the token. + */ +struct scmi_msg_hdr { + u8 id; + u8 protocol_id; + u16 seq; + u32 status; + bool poll_completion; +}; + +/** + * struct scmi_msg - Message(Tx/Rx) structure + * + * @buf: Buffer pointer + * @len: Length of data in the Buffer + */ +struct scmi_msg { + void *buf; + size_t len; +}; + +/** + * struct scmi_xfer - Structure representing a message flow + * + * @hdr: Transmit message header + * @tx: Transmit message + * @rx: Receive message, the buffer should be pre-allocated to store + * message. If request-ACK protocol is used, we can reuse the same + * buffer for the rx path as we use for the tx pa