* [PATCH 1/6] hwspinlock/core: Switch to SPDX license identifier
From: Suman Anna @ 2018-05-11 17:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180511170321.2452-1-s-anna@ti.com>
Use the appropriate SPDX license identifier in the Hwspinlock core
driver source files and drop the previous boilerplate license text.
Signed-off-by: Suman Anna <s-anna@ti.com>
---
drivers/hwspinlock/Kconfig | 1 +
drivers/hwspinlock/hwspinlock_core.c | 10 +---------
drivers/hwspinlock/hwspinlock_internal.h | 10 +---------
include/linux/hwspinlock.h | 10 +---------
4 files changed, 4 insertions(+), 27 deletions(-)
diff --git a/drivers/hwspinlock/Kconfig b/drivers/hwspinlock/Kconfig
index f0f467983960..e895d29500ee 100644
--- a/drivers/hwspinlock/Kconfig
+++ b/drivers/hwspinlock/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Generic HWSPINLOCK framework
#
diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c
index 4074441444fe..a41bc79aaa15 100644
--- a/drivers/hwspinlock/hwspinlock_core.c
+++ b/drivers/hwspinlock/hwspinlock_core.c
@@ -1,18 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Hardware spinlock framework
*
* Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com
*
* Contact: Ohad Ben-Cohen <ohad@wizery.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
*/
#define pr_fmt(fmt) "%s: " fmt, __func__
diff --git a/drivers/hwspinlock/hwspinlock_internal.h b/drivers/hwspinlock/hwspinlock_internal.h
index d26f78b8f214..9eb6bd020dc7 100644
--- a/drivers/hwspinlock/hwspinlock_internal.h
+++ b/drivers/hwspinlock/hwspinlock_internal.h
@@ -1,18 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Hardware spinlocks internal header
*
* Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com
*
* Contact: Ohad Ben-Cohen <ohad@wizery.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
*/
#ifndef __HWSPINLOCK_HWSPINLOCK_H
diff --git a/include/linux/hwspinlock.h b/include/linux/hwspinlock.h
index 859d673d98c8..cd6cd7fbd3c9 100644
--- a/include/linux/hwspinlock.h
+++ b/include/linux/hwspinlock.h
@@ -1,18 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Hardware spinlock public header
*
* Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com
*
* Contact: Ohad Ben-Cohen <ohad@wizery.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
*/
#ifndef __LINUX_HWSPINLOCK_H
--
2.17.0
^ permalink raw reply related
* [PATCH 0/6] hwspinlock: Convert to use SPDX license identifiers
From: Suman Anna @ 2018-05-11 17:03 UTC (permalink / raw)
To: linux-arm-kernel
Hi Bjorn,
The following series switches over the current licensing text in
various HwSpinlock drivers to the SPDX licensing format. Please
let me know if you need any changes. If you are ok with the changes,
I will make similar changes to the remoteproc and rpmsg drivers and
post them at the earliest so that they can be picked up for 4.18.
regards
Suman
Suman Anna (6):
hwspinlock/core: Switch to SPDX license identifier
hwspinlock/omap: Switch to SPDX license identifier
hwspinlock: qcom: Switch to SPDX license identifier
hwspinlock/sirf: Switch to SPDX license identifier
hwspinlock/u8500: Switch to SPDX license identifier
hwspinlock: sprd: Switch to SPDX license identifier
drivers/hwspinlock/Kconfig | 1 +
drivers/hwspinlock/hwspinlock_core.c | 10 +---------
drivers/hwspinlock/hwspinlock_internal.h | 10 +---------
drivers/hwspinlock/omap_hwspinlock.c | 10 +---------
drivers/hwspinlock/qcom_hwspinlock.c | 10 +---------
drivers/hwspinlock/sirf_hwspinlock.c | 3 +--
drivers/hwspinlock/sprd_hwspinlock.c | 10 +---------
drivers/hwspinlock/u8500_hsem.c | 10 +---------
include/linux/hwspinlock.h | 10 +---------
9 files changed, 9 insertions(+), 65 deletions(-)
--
2.17.0
^ permalink raw reply
* [PATCH 3/9] soc: fsl: set rcpm bit for FTM
From: Leo Li @ 2018-05-11 17:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180511033530.7931-3-yinbo.zhu@nxp.com>
> -----Original Message-----
> From: Yinbo Zhu [mailto:yinbo.zhu at nxp.com]
> Sent: Thursday, May 10, 2018 10:35 PM
> To: Yinbo Zhu <yinbo.zhu@nxp.com>; Rob Herring <robh+dt@kernel.org>;
> Mark Rutland <mark.rutland@arm.com>; Catalin Marinas )
> <catalin.marinas@arm.com>; Will Deacon ) <will.deacon@arm.com>;
> Lorenzo Pieralisi ) <lorenzo.pieralisi@arm.com>; Leo Li <leoyang.li@nxp.com>
> Cc: Xiaobo Xie <xiaobo.xie@nxp.com>; Ran Wang <ran.wang_1@nxp.com>;
> Daniel Lezcano <daniel.lezcano@linaro.org>; Thomas Gleixner
> <tglx@linutronix.de>; Shawn Guo <shawnguo@kernel.org>; Madalin-cristian
> Bucur <madalin.bucur@nxp.com>; Z.q. Hou <zhiqiang.hou@nxp.com>; Jerry
> Huang <jerry.huang@nxp.com>; M.h. Lian <minghuan.lian@nxp.com>;
> Qiang Zhao <qiang.zhao@nxp.com>; Fabio Estevam
> <fabio.estevam@nxp.com>; Jiaheng Fan <jiaheng.fan@nxp.com>; Po Liu
> <po.liu@nxp.com>; Nipun Gupta <nipun.gupta@nxp.com>; Horia Geant?
> <horia.geanta@nxp.com>; Priyanka Jain <priyanka.jain@nxp.com>; Sumit
> Garg <sumit.garg@nxp.com>; costi <constantin.tudor@freescale.com>;
> Bogdan Purcareata <bogdan.purcareata@nxp.com>; Meng Yi
> <meng.yi@nxp.com>; Wang Dongsheng <dongsheng.wang@nxp.com>; open
> list:CLOCKSOURCE, CLOCKEVENT DRIVERS <linux-kernel@vger.kernel.org>;
> open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
> <devicetree@vger.kernel.org>; linux-arm-kernel at lists.infradead.org; open
> list:FREESCALE SOC DRIVERS <linuxppc-dev@lists.ozlabs.org>; Andy Tang
> <andy.tang@nxp.com>; Ying Zhang <ying.zhang22455@nxp.com>
> Subject: [PATCH 3/9] soc: fsl: set rcpm bit for FTM
>
> From: Zhang Ying-22455 <ying.zhang22455@nxp.com>
>
> Set RCPM for FTM when using FTM as wakeup source. Because the RCPM
> module of each platform has different big-end and little-end mode, there
> need to set RCPM depending on the platform.
>
> Signed-off-by: Zhang Ying-22455 <ying.zhang22455@nxp.com>
> Signed-off-by: Yinbo Zhu <yinbo.zhu@nxp.com>
> ---
> .../devicetree/bindings/timer/fsl,ftm-timer.txt | 7 ++
> drivers/soc/fsl/layerscape/ftm_alarm.c | 92 ++++++++++++++++++-
> 2 files changed, 94 insertions(+), 5 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/timer/fsl,ftm-timer.txt
> b/Documentation/devicetree/bindings/timer/fsl,ftm-timer.txt
> index aa8c402..15ead58 100644
> --- a/Documentation/devicetree/bindings/timer/fsl,ftm-timer.txt
> +++ b/Documentation/devicetree/bindings/timer/fsl,ftm-timer.txt
> @@ -3,6 +3,13 @@ Freescale FlexTimer Module (FTM) Timer Required
> properties:
>
> - compatible : should be "fsl,ftm-timer"
Hi Yingbo,
This is a change that breaks backward compatibility and not acceptable.
> + Possible compatibles for ARM:
> + "fsl,ls1012a-ftm"
> + "fsl,ls1021a-ftm"
> + "fsl,ls1043a-ftm"
> + "fsl,ls1046a-ftm"
> + "fsl,ls1088a-ftm"
> + "fsl,ls208xa-ftm"
> - reg : Specifies base physical address and size of the register sets for the
> clock event device and clock source device.
> - interrupts : Should be the clock event device interrupt.
> diff --git a/drivers/soc/fsl/layerscape/ftm_alarm.c
> b/drivers/soc/fsl/layerscape/ftm_alarm.c
> index 6f9882f..811dcfa 100644
> --- a/drivers/soc/fsl/layerscape/ftm_alarm.c
> +++ b/drivers/soc/fsl/layerscape/ftm_alarm.c
There is no such file in the mainline kernel. So it looks like the patch set is based on some internal git repo instead of the upstream Linux kernel. This kind of patches shouldn't be sent to the upstream mailing list for review.
Regards,
Leo
^ permalink raw reply
* [PATCH 2/2] arm64: dts: mt7622: add audio related device nodes
From: Matthias Brugger @ 2018-05-11 16:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1525233238.14792.14.camel@mtkswgap22>
On 05/02/2018 05:53 AM, Sean Wang wrote:
> Hi, Matthias
>
> On Wed, 2018-05-02 at 11:41 +0800, sean.wang at mediatek.com wrote:
>> From: Ryder Lee <ryder.lee@mediatek.com>
>>
>> Add audio device nodes and its proper setup for all used pins
>>
>> Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
>> Signed-off-by: Sean Wang <sean.wang@mediatek.com>
>> ---
>> arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts | 11 +++-
>> arch/arm64/boot/dts/mediatek/mt7622.dtsi | 89 ++++++++++++++++++++++++++++
>> 2 files changed, 98 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
>> index 45d8655..b783764 100644
>> --- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
>> +++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
>> @@ -18,7 +18,7 @@
>> compatible = "mediatek,mt7622-rfb1", "mediatek,mt7622";
>>
>> chosen {
>> - bootargs = "console=ttyS0,115200n1";
>> + bootargs = "console=ttyS0,115200n1 swiotlb=512";
>> };
>>
>> cpus {
>> @@ -163,10 +163,17 @@
>> i2s1_pins: i2s1-pins {
>> mux {
>> function = "i2s";
>> - groups = "i2s_out_bclk_ws_mclk",
>> + groups = "i2s_out_mclk_bclk_ws",
>
> The old one ("i2s_out_bclk_ws_mclk") should be the indecisive value when
> I initially worked on the pinctrl device.
>
> It has to be corrected with "i2s_out_mclk_bclk_ws" to comply with the
> final dt-bindings.
>
>> "i2s1_in_data",
>> "i2s1_out_data";
>> };
>> +
>> + conf {
>> + pins = "I2S1_IN", "I2S1_OUT", "I2S_BCLK",
>> + "I2S_WS", "I2S_MCLK";
>> + drive-strength = <12>;
>> + bias-pull-down;
>> + };
>> };
>>
>> irrx_pins: irrx-pins {
>> diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
>> index 6bbabb6..9213c96 100644
>> --- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
>> +++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
>> @@ -527,6 +527,95 @@
>> status = "disabled";
>> };
>>
>> + audsys: clock-controller at 11220000 {
>> + compatible = "mediatek,mt7622-audsys", "syscon";
>> + reg = <0 0x11220000 0 0x2000>;
>> + #clock-cells = <1>;
>
> The binding have been through broonie/sound.git around a week ago
>
Thanks for the clarifications!
Pushed to v4.17-next/dts64
Regards,
Matthias
>> +
>> + afe: audio-controller {
>> + compatible = "mediatek,mt7622-audio";
>> + interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_LOW>,
>> + <GIC_SPI 145 IRQ_TYPE_LEVEL_LOW>;
>> + interrupt-names = "afe", "asys";
>> +
>> + clocks = <&infracfg CLK_INFRA_AUDIO_PD>,
>> + <&topckgen CLK_TOP_AUD1_SEL>,
>> + <&topckgen CLK_TOP_AUD2_SEL>,
>> + <&topckgen CLK_TOP_A1SYS_HP_DIV_PD>,
>> + <&topckgen CLK_TOP_A2SYS_HP_DIV_PD>,
>> + <&topckgen CLK_TOP_I2S0_MCK_SEL>,
>> + <&topckgen CLK_TOP_I2S1_MCK_SEL>,
>> + <&topckgen CLK_TOP_I2S2_MCK_SEL>,
>> + <&topckgen CLK_TOP_I2S3_MCK_SEL>,
>> + <&topckgen CLK_TOP_I2S0_MCK_DIV>,
>> + <&topckgen CLK_TOP_I2S1_MCK_DIV>,
>> + <&topckgen CLK_TOP_I2S2_MCK_DIV>,
>> + <&topckgen CLK_TOP_I2S3_MCK_DIV>,
>> + <&topckgen CLK_TOP_I2S0_MCK_DIV_PD>,
>> + <&topckgen CLK_TOP_I2S1_MCK_DIV_PD>,
>> + <&topckgen CLK_TOP_I2S2_MCK_DIV_PD>,
>> + <&topckgen CLK_TOP_I2S3_MCK_DIV_PD>,
>> + <&audsys CLK_AUDIO_I2SO1>,
>> + <&audsys CLK_AUDIO_I2SO2>,
>> + <&audsys CLK_AUDIO_I2SO3>,
>> + <&audsys CLK_AUDIO_I2SO4>,
>> + <&audsys CLK_AUDIO_I2SIN1>,
>> + <&audsys CLK_AUDIO_I2SIN2>,
>> + <&audsys CLK_AUDIO_I2SIN3>,
>> + <&audsys CLK_AUDIO_I2SIN4>,
>> + <&audsys CLK_AUDIO_ASRCO1>,
>> + <&audsys CLK_AUDIO_ASRCO2>,
>> + <&audsys CLK_AUDIO_ASRCO3>,
>> + <&audsys CLK_AUDIO_ASRCO4>,
>> + <&audsys CLK_AUDIO_AFE>,
>> + <&audsys CLK_AUDIO_AFE_CONN>,
>> + <&audsys CLK_AUDIO_A1SYS>,
>> + <&audsys CLK_AUDIO_A2SYS>;
>> +
>> + clock-names = "infra_sys_audio_clk",
>> + "top_audio_mux1_sel",
>> + "top_audio_mux2_sel",
>> + "top_audio_a1sys_hp",
>> + "top_audio_a2sys_hp",
>> + "i2s0_src_sel",
>> + "i2s1_src_sel",
>> + "i2s2_src_sel",
>> + "i2s3_src_sel",
>> + "i2s0_src_div",
>> + "i2s1_src_div",
>> + "i2s2_src_div",
>> + "i2s3_src_div",
>> + "i2s0_mclk_en",
>> + "i2s1_mclk_en",
>> + "i2s2_mclk_en",
>> + "i2s3_mclk_en",
>> + "i2so0_hop_ck",
>> + "i2so1_hop_ck",
>> + "i2so2_hop_ck",
>> + "i2so3_hop_ck",
>> + "i2si0_hop_ck",
>> + "i2si1_hop_ck",
>> + "i2si2_hop_ck",
>> + "i2si3_hop_ck",
>> + "asrc0_out_ck",
>> + "asrc1_out_ck",
>> + "asrc2_out_ck",
>> + "asrc3_out_ck",
>> + "audio_afe_pd",
>> + "audio_afe_conn_pd",
>> + "audio_a1sys_pd",
>> + "audio_a2sys_pd";
>> +
>> + assigned-clocks = <&topckgen CLK_TOP_A1SYS_HP_SEL>,
>> + <&topckgen CLK_TOP_A2SYS_HP_SEL>,
>> + <&topckgen CLK_TOP_A1SYS_HP_DIV>,
>> + <&topckgen CLK_TOP_A2SYS_HP_DIV>;
>> + assigned-clock-parents = <&topckgen CLK_TOP_AUD1PLL>,
>> + <&topckgen CLK_TOP_AUD2PLL>;
>> + assigned-clock-rates = <0>, <0>, <49152000>, <45158400>;
>> + };
>> + };
>> +
>> mmc0: mmc at 11230000 {
>> compatible = "mediatek,mt7622-mmc";
>> reg = <0 0x11230000 0 0x1000>;
>
>
^ permalink raw reply
* [PATCH] ARM: dts: BCM5301X: Switch D-Link DIR-885L to the new partitions syntax
From: Florian Fainelli @ 2018-05-11 16:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180510212000.11110-1-zajec5@gmail.com>
On Thu, 10 May 2018 23:20:00 +0200, Rafa? Mi?ecki <zajec5@gmail.com> wrote:
> From: Rafa? Mi?ecki <rafal@milecki.pl>
>
> This new syntax is slightly better designed & uses "compatible" string.
> For details see Documentation/devicetree/bindings/mtd/partition.txt .
>
> Signed-off-by: Rafa? Mi?ecki <rafal@milecki.pl>
> ---
Applied to devicetree/next, thanks!
--
Florian
^ permalink raw reply
* [PATCH v2 1/4] drm/rockchip: add transfer function for cdn-dp
From: Enric Balletbo Serra @ 2018-05-11 16:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1525861364-26323-1-git-send-email-hl@rock-chips.com>
Hi Lin,
2018-05-09 12:22 GMT+02:00 Lin Huang <hl@rock-chips.com>:
> From: Chris Zhong <zyw@rock-chips.com>
>
> We may support training outside firmware, so we need support
> dpcd read/write to get the message or do some setting with
> display.
>
> Signed-off-by: Chris Zhong <zyw@rock-chips.com>
> Signed-off-by: Lin Huang <hl@rock-chips.com>
> ---
>
> Changes in v2:
> - update patch following Enric suggest
>
> drivers/gpu/drm/rockchip/cdn-dp-core.c | 55 ++++++++++++++++++++++++----
> drivers/gpu/drm/rockchip/cdn-dp-core.h | 1 +
> drivers/gpu/drm/rockchip/cdn-dp-reg.c | 67 ++++++++++++++++++++++++++++++----
> drivers/gpu/drm/rockchip/cdn-dp-reg.h | 14 ++++++-
> 4 files changed, 120 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
> index c6fbdcd..cce64c1 100644
> --- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
> +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
> @@ -176,8 +176,8 @@ static int cdn_dp_get_sink_count(struct cdn_dp_device *dp, u8 *sink_count)
> u8 value;
>
> *sink_count = 0;
> - ret = cdn_dp_dpcd_read(dp, DP_SINK_COUNT, &value, 1);
> - if (ret)
> + ret = drm_dp_dpcd_read(&dp->aux, DP_SINK_COUNT, &value, 1);
> + if (ret < 0)
> return ret;
>
> *sink_count = DP_GET_SINK_COUNT(value);
> @@ -374,9 +374,9 @@ static int cdn_dp_get_sink_capability(struct cdn_dp_device *dp)
> if (!cdn_dp_check_sink_connection(dp))
> return -ENODEV;
>
> - ret = cdn_dp_dpcd_read(dp, DP_DPCD_REV, dp->dpcd,
> - DP_RECEIVER_CAP_SIZE);
> - if (ret) {
> + ret = drm_dp_dpcd_read(&dp->aux, DP_DPCD_REV, dp->dpcd,
> + sizeof(dp->dpcd));
> + if (ret < 0) {
> DRM_DEV_ERROR(dp->dev, "Failed to get caps %d\n", ret);
> return ret;
> }
> @@ -582,8 +582,8 @@ static bool cdn_dp_check_link_status(struct cdn_dp_device *dp)
> if (!port || !dp->link.rate || !dp->link.num_lanes)
> return false;
>
> - if (cdn_dp_dpcd_read(dp, DP_LANE0_1_STATUS, link_status,
> - DP_LINK_STATUS_SIZE)) {
> + if (drm_dp_dpcd_read_link_status(&dp->aux, link_status) !=
> + DP_LINK_STATUS_SIZE) {
> DRM_ERROR("Failed to get link status\n");
> return false;
> }
> @@ -1012,6 +1012,40 @@ static int cdn_dp_pd_event(struct notifier_block *nb,
> return NOTIFY_DONE;
> }
>
> +static ssize_t cdn_dp_aux_transfer(struct drm_dp_aux *aux,
> + struct drm_dp_aux_msg *msg)
> +{
> + struct cdn_dp_device *dp = container_of(aux, struct cdn_dp_device, aux);
> + int ret;
> + u8 status;
> +
> + switch (msg->request & ~DP_AUX_I2C_MOT) {
> + case DP_AUX_NATIVE_WRITE:
> + case DP_AUX_I2C_WRITE:
> + case DP_AUX_I2C_WRITE_STATUS_UPDATE:
> + ret = cdn_dp_dpcd_write(dp, msg->address, msg->buffer,
> + msg->size);
> + break;
> + case DP_AUX_NATIVE_READ:
> + case DP_AUX_I2C_READ:
> + ret = cdn_dp_dpcd_read(dp, msg->address, msg->buffer,
> + msg->size);
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + status = cdn_dp_get_aux_status(dp);
> + if (status == AUX_STATUS_ACK)
> + msg->reply = DP_AUX_NATIVE_REPLY_ACK;
> + else if (status == AUX_STATUS_NACK)
> + msg->reply = DP_AUX_NATIVE_REPLY_NACK;
> + else if (status == AUX_STATUS_DEFER)
> + msg->reply = DP_AUX_NATIVE_REPLY_DEFER;
> +
> + return ret;
> +}
> +
> static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
> {
> struct cdn_dp_device *dp = dev_get_drvdata(dev);
> @@ -1030,6 +1064,13 @@ static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
> dp->active = false;
> dp->active_port = -1;
> dp->fw_loaded = false;
> + dp->aux.name = "DP-AUX";
> + dp->aux.transfer = cdn_dp_aux_transfer;
> + dp->aux.dev = dev;
> +
> + ret = drm_dp_aux_register(&dp->aux);
> + if (ret)
> + return ret;
>
> INIT_WORK(&dp->event_work, cdn_dp_pd_event_work);
>
> diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.h b/drivers/gpu/drm/rockchip/cdn-dp-core.h
> index f57e296..46159b2 100644
> --- a/drivers/gpu/drm/rockchip/cdn-dp-core.h
> +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h
> @@ -78,6 +78,7 @@ struct cdn_dp_device {
> struct platform_device *audio_pdev;
> struct work_struct event_work;
> struct edid *edid;
> + struct drm_dp_aux aux;
>
> struct mutex lock;
> bool connected;
> diff --git a/drivers/gpu/drm/rockchip/cdn-dp-reg.c b/drivers/gpu/drm/rockchip/cdn-dp-reg.c
> index eb3042c..afdfda0 100644
> --- a/drivers/gpu/drm/rockchip/cdn-dp-reg.c
> +++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.c
> @@ -221,7 +221,11 @@ static int cdn_dp_reg_write_bit(struct cdn_dp_device *dp, u16 addr,
> sizeof(field), field);
> }
>
> -int cdn_dp_dpcd_read(struct cdn_dp_device *dp, u32 addr, u8 *data, u16 len)
> +/*
> + * Returns the number of bytes transferred on success, or a negative error
> + * code on failure. -ETIMEDOUT is returned if mailbox message not send success;
nit: -ETIMEDOUT is returned if mailbox message was not sent successfully.
> + */
> +ssize_t cdn_dp_dpcd_read(struct cdn_dp_device *dp, u32 addr, u8 *data, u16 len)
> {
> u8 msg[5], reg[5];
> int ret;
> @@ -247,24 +251,40 @@ int cdn_dp_dpcd_read(struct cdn_dp_device *dp, u32 addr, u8 *data, u16 len)
> goto err_dpcd_read;
>
> ret = cdn_dp_mailbox_read_receive(dp, data, len);
> + if (!ret)
> + return len;
>
> err_dpcd_read:
> + DRM_DEV_ERROR(dp->dev, "dpcd read failed: %d\n", ret);
> return ret;
> }
>
> -int cdn_dp_dpcd_write(struct cdn_dp_device *dp, u32 addr, u8 value)
> +#define CDN_AUX_HEADER_SIZE 5
> +#define CDN_AUX_MSG_SIZE 20
> +/*
> + * Returns the number of bytes transferred on success, or a negative error
> + * code on failure. -ETIMEDOUT is returned if mailbox message not send success;
> + * -EINVAL is return if get the wrong data size after message send.
nit:
-ETIMEDOUT is returned if mailbox message was not sent successfully;
-EINVAL is returned if you get the wrong data size after the message
is sent.
> + */
> +ssize_t cdn_dp_dpcd_write(struct cdn_dp_device *dp, u32 addr, u8 *data, u16 len)
> {
> - u8 msg[6], reg[5];
> + u8 msg[CDN_AUX_MSG_SIZE + CDN_AUX_HEADER_SIZE];
> + u8 reg[CDN_AUX_HEADER_SIZE];
> int ret;
>
> - msg[0] = 0;
> - msg[1] = 1;
> + if (WARN_ON(len > CDN_AUX_MSG_SIZE) || WARN_ON(len <= 0))
> + return -EINVAL;
> +
> + msg[0] = (len >> 8) & 0xff;
> + msg[1] = len & 0xff;
> msg[2] = (addr >> 16) & 0xff;
> msg[3] = (addr >> 8) & 0xff;
> msg[4] = addr & 0xff;
> - msg[5] = value;
> +
> + memcpy(msg + CDN_AUX_HEADER_SIZE, data, len);
> +
> ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_WRITE_DPCD,
> - sizeof(msg), msg);
> + CDN_AUX_HEADER_SIZE + len, msg);
> if (ret)
> goto err_dpcd_write;
>
> @@ -277,8 +297,12 @@ int cdn_dp_dpcd_write(struct cdn_dp_device *dp, u32 addr, u8 value)
> if (ret)
> goto err_dpcd_write;
>
> - if (addr != (reg[2] << 16 | reg[3] << 8 | reg[4]))
> + if ((len != (reg[0] << 8 | reg[1])) ||
> + (addr != (reg[2] << 16 | reg[3] << 8 | reg[4]))) {
> ret = -EINVAL;
> + } else {
> + return len;
> + }
>
> err_dpcd_write:
> if (ret)
> @@ -286,6 +310,33 @@ int cdn_dp_dpcd_write(struct cdn_dp_device *dp, u32 addr, u8 value)
> return ret;
> }
>
> +int cdn_dp_get_aux_status(struct cdn_dp_device *dp)
> +{
> + u8 status;
> + int ret;
> +
> + ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX,
> + DPTX_GET_LAST_AUX_STAUS, 0, NULL);
> + if (ret)
> + goto err_get_hpd;
> +
> + ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX,
> + DPTX_GET_LAST_AUX_STAUS,
> + sizeof(status));
> + if (ret)
> + goto err_get_hpd;
> +
> + ret = cdn_dp_mailbox_read_receive(dp, &status, sizeof(status));
> + if (ret)
> + goto err_get_hpd;
> +
> + return status;
> +
> +err_get_hpd:
> + DRM_DEV_ERROR(dp->dev, "get aux status failed: %d\n", ret);
> + return ret;
> +}
> +
> int cdn_dp_load_firmware(struct cdn_dp_device *dp, const u32 *i_mem,
> u32 i_size, const u32 *d_mem, u32 d_size)
> {
> diff --git a/drivers/gpu/drm/rockchip/cdn-dp-reg.h b/drivers/gpu/drm/rockchip/cdn-dp-reg.h
> index c4bbb4a83..6580b11 100644
> --- a/drivers/gpu/drm/rockchip/cdn-dp-reg.h
> +++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.h
> @@ -328,6 +328,13 @@
> #define GENERAL_BUS_SETTINGS 0x03
> #define GENERAL_TEST_ACCESS 0x04
>
> +/* AUX status*/
> +#define AUX_STATUS_ACK 0
> +#define AUX_STATUS_NACK 1
> +#define AUX_STATUS_DEFER 2
> +#define AUX_STATUS_SINK_ERROR 3
> +#define AUX_STATUS_BUS_ERROR 4
> +
> #define DPTX_SET_POWER_MNG 0x00
> #define DPTX_SET_HOST_CAPABILITIES 0x01
> #define DPTX_GET_EDID 0x02
> @@ -469,8 +476,11 @@ int cdn_dp_set_host_cap(struct cdn_dp_device *dp, u8 lanes, bool flip);
> int cdn_dp_event_config(struct cdn_dp_device *dp);
> u32 cdn_dp_get_event(struct cdn_dp_device *dp);
> int cdn_dp_get_hpd_status(struct cdn_dp_device *dp);
> -int cdn_dp_dpcd_write(struct cdn_dp_device *dp, u32 addr, u8 value);
> -int cdn_dp_dpcd_read(struct cdn_dp_device *dp, u32 addr, u8 *data, u16 len);
> +ssize_t cdn_dp_dpcd_write(struct cdn_dp_device *dp, u32 addr,
> + u8 *data, u16 len);
> +ssize_t cdn_dp_dpcd_read(struct cdn_dp_device *dp, u32 addr,
> + u8 *data, u16 len);
> +int cdn_dp_get_aux_status(struct cdn_dp_device *dp);
> int cdn_dp_get_edid_block(void *dp, u8 *edid,
> unsigned int block, size_t length);
> int cdn_dp_train_link(struct cdn_dp_device *dp);
> --
> 2.7.4
>
Apart from the two nits, the patch looks good to me and works.
Reviewed-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Thanks,
Enric
^ permalink raw reply
* [PATCH v2 00/12] refactor dts and add support for more boards
From: Matthias Brugger @ 2018-05-11 16:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1523434757.git.sean.wang@mediatek.com>
On 04/11/2018 10:53 AM, sean.wang at mediatek.com wrote:
> From: Sean Wang <sean.wang@mediatek.com>
>
> Changes since v1:
> - Dropped several patches which have been merged.
> - Rebased to linux-next-20180410 where those dependent patches including
> [1] and [2] all have been got merged.
> - Revised according to suggestions and comments on v1, where the major work is
> to put board-specific nodes into DTS files and to leave the common nodes
> among boards in DTSI files as done in patch 7,9,10,11 and 12.
> - Merged Ryder Lee's patch for update audio nodes reflecting the latest
> bindings.
> - Revised commit message.
>
> The series is to refactor current .dts for allowing more boards can properly
> join and reuse almost the same device node definitions.
>
> Before we're doing that, some works about enhancements and fixups are being
> made on the dt-binding document and .dts files. In addition, the series has to
> depend on the patch [1][2]. Otherwise, certain build failure would have an
> occurrence.
>
> [1] arm: dts: mt7623: add PCIe related nodes
> http://lists.infradead.org/pipermail/linux-mediatek/2018-February/012053.html
>
> [2] dt-bindings: soc: add header files required for MT7623A SCPSYS dt-binding
> http://lists.infradead.org/pipermail/linux-mediatek/2018-February/011930.html
>
> Ryder Lee (1):
> arm: dts: mediatek: modify audio related nodes for both MT2701 and
> MT7623
>
> Sean Wang (11):
> dt-bindings: cpufreq: mediatek: use - instead of _ in examples
> arm: dts: mediatek: converted to using SPDX identifiers
> arm: dts: mt7623: fix invalid memory node being generated
> arm: dts: mt7623: fix available memory size on bananapi-r2
> arm: dts: mt7623: fix all Warnings (unit_address_vs_reg)
> arm: dts: mt7623: add BTIF, HSDMA and SPI-NOR device nodes
> arm: dts: mt6323: move node mt6323 leds to mt6323.dtsi
> arm: dts: mt7623: extend common file reused by all boards with MT7623
> SoCs
> arm: dts: mt7623: add MT7623A SoC level DTS
> arm: dts: mt7623: add MT7623A reference boards
> arm: dts: mt7623: add MT7623N reference board with eMMC
>
I merged all but 1/12 which needs to go through rafaels tree and 8/12 which was
already applied from a different series.
You can find them in v4.17-next/soc on git.kernel.org
Regards,
Matthias
> .../bindings/cpufreq/cpufreq-mediatek.txt | 6 +-
> arch/arm/boot/dts/Makefile | 3 +
> arch/arm/boot/dts/mt2701-evb.dts | 9 +-
> arch/arm/boot/dts/mt2701.dtsi | 197 ++++----
> arch/arm/boot/dts/mt6323.dtsi | 17 +-
> arch/arm/boot/dts/mt6580-evbp1.dts | 9 +-
> arch/arm/boot/dts/mt6580.dtsi | 9 +-
> arch/arm/boot/dts/mt6589-aquaris5.dts | 10 +-
> arch/arm/boot/dts/mt6589.dtsi | 12 +-
> arch/arm/boot/dts/mt6592-evb.dts | 9 +-
> arch/arm/boot/dts/mt6592.dtsi | 9 +-
> arch/arm/boot/dts/mt7623.dtsi | 537 ++++++++++++++++-----
> arch/arm/boot/dts/mt7623a-rfb-emmc.dts | 291 +++++++++++
> arch/arm/boot/dts/mt7623a-rfb-nand.dts | 337 +++++++++++++
> arch/arm/boot/dts/mt7623a.dtsi | 44 ++
> arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts | 279 ++---------
> arch/arm/boot/dts/mt7623n-rfb-emmc.dts | 326 +++++++++++++
> arch/arm/boot/dts/mt7623n-rfb-nand.dts | 40 +-
> arch/arm/boot/dts/mt7623n-rfb.dtsi | 12 +-
> arch/arm/boot/dts/mt8127-moose.dts | 9 +-
> arch/arm/boot/dts/mt8127.dtsi | 9 +-
> arch/arm/boot/dts/mt8135-evbp1.dts | 9 +-
> arch/arm/boot/dts/mt8135.dtsi | 9 +-
> 23 files changed, 1576 insertions(+), 616 deletions(-)
> create mode 100644 arch/arm/boot/dts/mt7623a-rfb-emmc.dts
> create mode 100644 arch/arm/boot/dts/mt7623a-rfb-nand.dts
> create mode 100644 arch/arm/boot/dts/mt7623a.dtsi
> create mode 100644 arch/arm/boot/dts/mt7623n-rfb-emmc.dts
>
^ permalink raw reply
* [PATCH v2 26/27] coresight: perf: Remove reset_buffer call back for sinks
From: Suzuki K Poulose @ 2018-05-11 16:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180508194241.GC3389@xps15>
On 08/05/18 20:42, Mathieu Poirier wrote:
> On Tue, May 01, 2018 at 10:10:56AM +0100, Suzuki K Poulose wrote:
>> Right now we issue an update_buffer() and reset_buffer() call backs
>> in succession when we stop tracing an event. The update_buffer is
>> supposed to check the status of the buffer and make sure the ring buffer
>> is updated with the trace data. And we store information about the
>> size of the data collected only to be consumed by the reset_buffer
>> callback which always follows the update_buffer. This was originally
>> designed for handling future IPs which could trigger a buffer overflow
>> interrupt. This patch gets rid of the reset_buffer callback altogether
>> and performs the actions in update_buffer, making it return the size
>> collected. We can always add the support for handling the overflow
>> interrupt case later.
>>
>> This removes some not-so pretty hack (storing the new head in the
>> size field for snapshot mode) and cleans it up a little bit.
>
> IPs with an overflow interrupts will be arriving shortly, so it is not like the
> future is uncertain - they are coming. Right now the logic is there - I don't
> see a real need to consolidate things only to split it again in the near future.
>
> I agree the part about overloading buf->data_size with the head of the ring
> buffer when operating in snapshot mode isn't pretty (though well documented).
> If anything that can be improve, i.e add a buf->head and things will be clear.
> Once again this could be part of another patchset.
>
Mathieu,
I am not sure how was this supposed to be used in conjunction with the overflow
handling. Please could you help me here ? I might be able to retain
the callback and possibly improve it with the changes for etr_buf infrastructure.
Cheers
Suzuki
>>
>> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
>> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
>> ---
>> drivers/hwtracing/coresight/coresight-etb10.c | 56 +++++------------------
>> drivers/hwtracing/coresight/coresight-etm-perf.c | 9 +---
>> drivers/hwtracing/coresight/coresight-tmc-etf.c | 58 +++++-------------------
>> include/linux/coresight.h | 5 +-
>> 4 files changed, 26 insertions(+), 102 deletions(-)
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
>> index d9c2f87..b13712a 100644
>> --- a/drivers/hwtracing/coresight/coresight-etb10.c
>> +++ b/drivers/hwtracing/coresight/coresight-etb10.c
>> @@ -322,37 +322,7 @@ static int etb_set_buffer(struct coresight_device *csdev,
>> return ret;
>> }
>>
>> -static unsigned long etb_reset_buffer(struct coresight_device *csdev,
>> - struct perf_output_handle *handle,
>> - void *sink_config)
>> -{
>> - unsigned long size = 0;
>> - struct cs_buffers *buf = sink_config;
>> -
>> - if (buf) {
>> - /*
>> - * In snapshot mode ->data_size holds the new address of the
>> - * ring buffer's head. The size itself is the whole address
>> - * range since we want the latest information.
>> - */
>> - if (buf->snapshot)
>> - handle->head = local_xchg(&buf->data_size,
>> - buf->nr_pages << PAGE_SHIFT);
>> -
>> - /*
>> - * Tell the tracer PMU how much we got in this run and if
>> - * something went wrong along the way. Nobody else can use
>> - * this cs_buffers instance until we are done. As such
>> - * resetting parameters here and squaring off with the ring
>> - * buffer API in the tracer PMU is fine.
>> - */
>> - size = local_xchg(&buf->data_size, 0);
>> - }
>> -
>> - return size;
>> -}
>> -
>> -static void etb_update_buffer(struct coresight_device *csdev,
>> +static unsigned long etb_update_buffer(struct coresight_device *csdev,
>> struct perf_output_handle *handle,
>> void *sink_config)
>> {
>> @@ -361,13 +331,13 @@ static void etb_update_buffer(struct coresight_device *csdev,
>> u8 *buf_ptr;
>> const u32 *barrier;
>> u32 read_ptr, write_ptr, capacity;
>> - u32 status, read_data, to_read;
>> - unsigned long offset;
>> + u32 status, read_data;
>> + unsigned long offset, to_read;
>> struct cs_buffers *buf = sink_config;
>> struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>>
>> if (!buf)
>> - return;
>> + return 0;
>>
>> capacity = drvdata->buffer_depth * ETB_FRAME_SIZE_WORDS;
>>
>> @@ -472,18 +442,17 @@ static void etb_update_buffer(struct coresight_device *csdev,
>> writel_relaxed(0x0, drvdata->base + ETB_RAM_WRITE_POINTER);
>>
>> /*
>> - * In snapshot mode all we have to do is communicate to
>> - * perf_aux_output_end() the address of the current head. In full
>> - * trace mode the same function expects a size to move rb->aux_head
>> - * forward.
>> + * In snapshot mode we have to update the handle->head to point
>> + * to the new location.
>> */
>> - if (buf->snapshot)
>> - local_set(&buf->data_size, (cur * PAGE_SIZE) + offset);
>> - else
>> - local_add(to_read, &buf->data_size);
>> -
>> + if (buf->snapshot) {
>> + handle->head = (cur * PAGE_SIZE) + offset;
>> + to_read = buf->nr_pages << PAGE_SHIFT;
>> + }
>> etb_enable_hw(drvdata);
>> CS_LOCK(drvdata->base);
>> +
>> + return to_read;
>> }
>>
>> static const struct coresight_ops_sink etb_sink_ops = {
>> @@ -492,7 +461,6 @@ static const struct coresight_ops_sink etb_sink_ops = {
>> .alloc_buffer = etb_alloc_buffer,
>> .free_buffer = etb_free_buffer,
>> .set_buffer = etb_set_buffer,
>> - .reset_buffer = etb_reset_buffer,
>> .update_buffer = etb_update_buffer,
>> };
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
>> index 4e5ed65..5096def 100644
>> --- a/drivers/hwtracing/coresight/coresight-etm-perf.c
>> +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
>> @@ -342,15 +342,8 @@ static void etm_event_stop(struct perf_event *event, int mode)
>> if (!sink_ops(sink)->update_buffer)
>> return;
>>
>> - sink_ops(sink)->update_buffer(sink, handle,
>> + size = sink_ops(sink)->update_buffer(sink, handle,
>> event_data->snk_config);
>> -
>> - if (!sink_ops(sink)->reset_buffer)
>> - return;
>> -
>> - size = sink_ops(sink)->reset_buffer(sink, handle,
>> - event_data->snk_config);
>> -
>> perf_aux_output_end(handle, size);
>> }
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c
>> index 0a32734..75ef5c4 100644
>> --- a/drivers/hwtracing/coresight/coresight-tmc-etf.c
>> +++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c
>> @@ -360,36 +360,7 @@ static int tmc_set_etf_buffer(struct coresight_device *csdev,
>> return ret;
>> }
>>
>> -static unsigned long tmc_reset_etf_buffer(struct coresight_device *csdev,
>> - struct perf_output_handle *handle,
>> - void *sink_config)
>> -{
>> - long size = 0;
>> - struct cs_buffers *buf = sink_config;
>> -
>> - if (buf) {
>> - /*
>> - * In snapshot mode ->data_size holds the new address of the
>> - * ring buffer's head. The size itself is the whole address
>> - * range since we want the latest information.
>> - */
>> - if (buf->snapshot)
>> - handle->head = local_xchg(&buf->data_size,
>> - buf->nr_pages << PAGE_SHIFT);
>> - /*
>> - * Tell the tracer PMU how much we got in this run and if
>> - * something went wrong along the way. Nobody else can use
>> - * this cs_buffers instance until we are done. As such
>> - * resetting parameters here and squaring off with the ring
>> - * buffer API in the tracer PMU is fine.
>> - */
>> - size = local_xchg(&buf->data_size, 0);
>> - }
>> -
>> - return size;
>> -}
>> -
>> -static void tmc_update_etf_buffer(struct coresight_device *csdev,
>> +static unsigned long tmc_update_etf_buffer(struct coresight_device *csdev,
>> struct perf_output_handle *handle,
>> void *sink_config)
>> {
>> @@ -398,17 +369,17 @@ static void tmc_update_etf_buffer(struct coresight_device *csdev,
>> const u32 *barrier;
>> u32 *buf_ptr;
>> u64 read_ptr, write_ptr;
>> - u32 status, to_read;
>> - unsigned long offset;
>> + u32 status;
>> + unsigned long offset, to_read;
>> struct cs_buffers *buf = sink_config;
>> struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>>
>> if (!buf)
>> - return;
>> + return 0;
>>
>> /* This shouldn't happen */
>> if (WARN_ON_ONCE(drvdata->mode != CS_MODE_PERF))
>> - return;
>> + return 0;
>>
>> CS_UNLOCK(drvdata->base);
>>
>> @@ -497,18 +468,14 @@ static void tmc_update_etf_buffer(struct coresight_device *csdev,
>> }
>> }
>>
>> - /*
>> - * In snapshot mode all we have to do is communicate to
>> - * perf_aux_output_end() the address of the current head. In full
>> - * trace mode the same function expects a size to move rb->aux_head
>> - * forward.
>> - */
>> - if (buf->snapshot)
>> - local_set(&buf->data_size, (cur * PAGE_SIZE) + offset);
>> - else
>> - local_add(to_read, &buf->data_size);
>> -
>> + /* In snapshot mode we have to update the head */
>> + if (buf->snapshot) {
>> + handle->head = (cur * PAGE_SIZE) + offset;
>> + to_read = buf->nr_pages << PAGE_SHIFT;
>> + }
>> CS_LOCK(drvdata->base);
>> +
>> + return to_read;
>> }
>>
>> static const struct coresight_ops_sink tmc_etf_sink_ops = {
>> @@ -517,7 +484,6 @@ static const struct coresight_ops_sink tmc_etf_sink_ops = {
>> .alloc_buffer = tmc_alloc_etf_buffer,
>> .free_buffer = tmc_free_etf_buffer,
>> .set_buffer = tmc_set_etf_buffer,
>> - .reset_buffer = tmc_reset_etf_buffer,
>> .update_buffer = tmc_update_etf_buffer,
>> };
>>
>> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
>> index c0e1568..41b3729 100644
>> --- a/include/linux/coresight.h
>> +++ b/include/linux/coresight.h
>> @@ -212,10 +212,7 @@ struct coresight_ops_sink {
>> int (*set_buffer)(struct coresight_device *csdev,
>> struct perf_output_handle *handle,
>> void *sink_config);
>> - unsigned long (*reset_buffer)(struct coresight_device *csdev,
>> - struct perf_output_handle *handle,
>> - void *sink_config);
>> - void (*update_buffer)(struct coresight_device *csdev,
>> + unsigned long (*update_buffer)(struct coresight_device *csdev,
>> struct perf_output_handle *handle,
>> void *sink_config);
>> };
>> --
>> 2.7.4
>>
^ permalink raw reply
* [PATCH 12/12] of/platform: make the OF code aware of early platform drivers
From: Bartosz Golaszewski @ 2018-05-11 16:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180511162028.20616-1-brgl@bgdev.pl>
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Check the relevant flag in the device node and skip the allocation
part for devices that were populated early.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
drivers/of/platform.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 0e554fe1f325..91760e2d3dc7 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -21,6 +21,7 @@
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
+#include <linux/early_platform.h>
const struct of_device_id of_default_bus_match_table[] = {
{ .compatible = "simple-bus", },
@@ -196,9 +197,17 @@ static struct platform_device *of_platform_device_create_pdata(
of_node_test_and_set_flag(np, OF_POPULATED))
return NULL;
- dev = of_device_alloc(np, bus_id, parent);
- if (!dev)
- goto err_clear_flag;
+ if (of_node_check_flag(np, OF_POPULATED_EARLY)) {
+ dev = of_early_to_platform_device(np);
+ if (IS_ERR(dev))
+ goto err_clear_flag;
+
+ of_device_init(dev, np, bus_id, parent);
+ } else {
+ dev = of_device_alloc(np, bus_id, parent);
+ if (!dev)
+ goto err_clear_flag;
+ }
dev->dev.bus = &platform_bus_type;
dev->dev.platform_data = platform_data;
--
2.17.0
^ permalink raw reply related
* [PATCH 11/12] misc: implement a dummy early platform driver
From: Bartosz Golaszewski @ 2018-05-11 16:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180511162028.20616-1-brgl@bgdev.pl>
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Implement a very simple early platform driver. Its purpose is to show
how such drivers can be registered and to emit a message when probed.
It can be then added to the device tree or machine code to verify that
the early platform devices work as expected.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
drivers/misc/Kconfig | 8 ++++
drivers/misc/Makefile | 1 +
drivers/misc/dummy-early.c | 82 ++++++++++++++++++++++++++++++++++++++
3 files changed, 91 insertions(+)
create mode 100644 drivers/misc/dummy-early.c
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 5d713008749b..60fef04eb236 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -91,6 +91,14 @@ config DUMMY_IRQ
The sole purpose of this module is to help with debugging of systems on
which spurious IRQs would happen on disabled IRQ vector.
+config DUMMY_EARLY
+ bool "Dummy early platform driver"
+ select EARLY_PLATFORM
+ default n
+ help
+ This module's only function is to register itself with the early
+ platform device framework and be probed early in the boot process.
+
config IBM_ASM
tristate "Device driver for IBM RSA service processor"
depends on X86 && PCI && INPUT
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index d0a8788d5151..6170855853a1 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_INTEL_MID_PTI) += pti.o
obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o
obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o
obj-$(CONFIG_DUMMY_IRQ) += dummy-irq.o
+obj-$(CONFIG_DUMMY_EARLY) += dummy-early.o
obj-$(CONFIG_ICS932S401) += ics932s401.o
obj-$(CONFIG_LKDTM) += lkdtm/
obj-$(CONFIG_TIFM_CORE) += tifm_core.o
diff --git a/drivers/misc/dummy-early.c b/drivers/misc/dummy-early.c
new file mode 100644
index 000000000000..eb8f826aea64
--- /dev/null
+++ b/drivers/misc/dummy-early.c
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 Texas Instruments
+ *
+ * Author:
+ * Bartosz Golaszewski <bgolaszewski@baylibre.com>
+ *
+ * Dummy testing driver whose only purpose is to be registered and probed
+ * using the early platform device mechanism.
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/early_platform.h>
+
+struct dummy_early_data {
+ int a;
+ int b;
+};
+
+static int dummy_early_probe_early(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct dummy_early_data *data;
+ struct resource *res;
+
+ dev_notice(dev, "dummy-early driver probed early!\n");
+
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->a = 123;
+ data->b = 321;
+
+ dev_dbg(dev, "setting driver data early: a = %d, b = %d\n",
+ data->a, data->b);
+ dev_set_drvdata(dev, data);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res)
+ dev_dbg(dev, "got early resource: start = 0x%08x, end = 0x%08x\n",
+ res->start, res->end);
+
+ return 0;
+}
+
+static int dummy_early_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct dummy_early_data *data;
+
+ dev_notice(dev, "dummy-early driver probed late!\n");
+ data = dev_get_drvdata(dev);
+ dev_dbg(dev, "retrieving driver data late: a = %d, b = %d\n",
+ data->a, data->b);
+
+ return 0;
+}
+
+static const struct of_device_id dummy_early_of_match[] = {
+ { .compatible = "dummy-early", },
+ { },
+};
+
+static struct early_platform_driver dummy_early_driver = {
+ .early_probe = dummy_early_probe_early,
+ .pdrv = {
+ .probe = dummy_early_probe,
+ .driver = {
+ .name = "dummy-early",
+ .of_match_table = dummy_early_of_match,
+ },
+ }
+};
+module_early_platform_driver(dummy_early_driver);
+
+MODULE_AUTHOR("Bartosz Golaszewski <bgolaszewski@baylibre.com>");
+MODULE_DESCRIPTION("Dummy early platform device driver");
+MODULE_LICENSE("GPL v2");
--
2.17.0
^ permalink raw reply related
* [PATCH 10/12] platform/early: implement support for early platform drivers
From: Bartosz Golaszewski @ 2018-05-11 16:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180511162028.20616-1-brgl@bgdev.pl>
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
This introduces the core part of support for early platform drivers
and devices.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
drivers/base/Kconfig | 3 +
drivers/base/Makefile | 1 +
drivers/base/early.c | 332 +++++++++++++++++++++++++++++++++
drivers/misc/Makefile | 1 +
include/linux/early_platform.h | 75 ++++++++
5 files changed, 412 insertions(+)
create mode 100644 drivers/base/early.c
create mode 100644 include/linux/early_platform.h
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 29b0eb452b3a..ea648daecec1 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -205,6 +205,9 @@ config DEBUG_TEST_DRIVER_REMOVE
unusable. You should say N here unless you are explicitly looking to
test this functionality.
+config EARLY_PLATFORM
+ def_bool n
+
source "drivers/base/test/Kconfig"
config SYS_HYPERVISOR
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index 7845c95ee1b2..3998ad6719f1 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -7,6 +7,7 @@ obj-y := component.o core.o bus.o dd.o syscore.o \
attribute_container.o transport_class.o \
topology.o container.o property.o cacheinfo.o \
devcon.o
+obj-$(CONFIG_EARLY_PLATFORM) += early.o
obj-$(CONFIG_DEVTMPFS) += devtmpfs.o
obj-$(CONFIG_DMA_CMA) += dma-contiguous.o
obj-y += power/
diff --git a/drivers/base/early.c b/drivers/base/early.c
new file mode 100644
index 000000000000..7d0b7fb85f58
--- /dev/null
+++ b/drivers/base/early.c
@@ -0,0 +1,332 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 Texas Instruments, Inc.
+ *
+ * Author:
+ * Bartosz Golaszewski <bgolaszewski@baylibre.com>
+ */
+
+#include <linux/early_platform.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+
+#include "base.h"
+
+extern struct early_platform_driver *__early_platform_drivers_table[];
+extern struct early_platform_driver *__early_platform_drivers_table_end[];
+
+static bool early_platform_done;
+
+static LIST_HEAD(early_platform_drivers);
+static LIST_HEAD(early_platform_devices);
+
+static int early_platform_device_set_name(struct early_platform_device *edev)
+{
+ switch (edev->pdev.id) {
+ case PLATFORM_DEVID_AUTO:
+ pr_warn("auto device ID not supported in early platform devices\n");
+ /* fallthrough */
+ case PLATFORM_DEVID_NONE:
+ edev->pdev.dev.init_name = kasprintf(GFP_KERNEL,
+ "%s", edev->pdev.name);
+ break;
+ default:
+ edev->pdev.dev.init_name = kasprintf(GFP_KERNEL, "%s.%d",
+ edev->pdev.name,
+ edev->pdev.id);
+ break;
+ }
+
+ if (!edev->pdev.dev.init_name)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static void early_platform_device_add(struct early_platform_device *edev)
+{
+ edev->pdev.dev.early = true;
+ INIT_LIST_HEAD(&edev->list);
+ list_add_tail(&edev->list, &early_platform_devices);
+}
+
+static void early_platform_probe_deferred(void)
+{
+ struct early_platform_device *edev;
+ int rv;
+
+ list_for_each_entry(edev, &early_platform_devices, list) {
+ if (!edev->deferred || !edev->deferred_drv->early_probe)
+ continue;
+
+ rv = edev->deferred_drv->early_probe(&edev->pdev);
+ if (rv && rv != -EPROBE_DEFER) {
+ dev_err(&edev->pdev.dev,
+ "early platform driver probe failed: %d\n",
+ rv);
+ }
+ }
+}
+
+static void early_platform_try_probe(struct early_platform_driver *edrv,
+ struct early_platform_device *edev)
+{
+ int rv;
+
+ rv = early_platform_device_set_name(edev);
+ if (rv)
+ pr_warn("unable to set the early platform device name\n");
+
+ if (edrv->early_probe) {
+ rv = edrv->early_probe(&edev->pdev);
+ if (rv && rv != -EPROBE_DEFER &&
+ rv != -ENODEV && rv != -ENXIO) {
+ dev_err(&edev->pdev.dev,
+ "early platform driver probe failed: %d\n",
+ rv);
+ return;
+ } else if (rv == -EPROBE_DEFER) {
+ edev->deferred = true;
+ edev->deferred_drv = edrv;
+ } else {
+ early_platform_probe_deferred();
+ }
+ }
+}
+
+/**
+ * of_early_to_platform_device - return the platform device with which this
+ * device node is associated
+ * @np - device node to look up
+ *
+ * If a device node was populated early, the corresponding platform device
+ * already exists. Instead of allocating a new object, we need to retrieve
+ * the previous one. This routine enables it.
+ */
+struct platform_device *of_early_to_platform_device(struct device_node *np)
+{
+ struct early_platform_device *edev;
+
+ list_for_each_entry(edev, &early_platform_devices, list) {
+ if (np == edev->pdev.dev.of_node)
+ return &edev->pdev;
+ }
+
+ return ERR_PTR(-ENOENT);
+}
+
+static int of_early_platform_device_create(struct device_node *node,
+ struct early_platform_driver *edrv)
+{
+ struct early_platform_device *edev;
+ int rc;
+
+ edev = kzalloc(sizeof(*edev), GFP_KERNEL);
+ if (!edev)
+ return -ENOMEM;
+
+ platform_device_init(&edev->pdev, "", PLATFORM_DEVID_NONE);
+ /*
+ * We can safely use platform_device_release since the platform_device
+ * struct is the first member of early_platform_device.
+ */
+ edev->pdev.dev.release = platform_device_release;
+
+ rc = of_device_init_resources(&edev->pdev, node);
+ if (rc) {
+ kfree(edev);
+ return rc;
+ }
+
+ of_node_set_flag(node, OF_POPULATED_EARLY);
+ edev->pdev.name = edrv->pdrv.driver.name;
+ edev->pdev.dev.of_node = of_node_get(node);
+ edev->pdev.dev.fwnode = &node->fwnode;
+ early_platform_device_add(edev);
+ early_platform_try_probe(edrv, edev);
+
+ return 0;
+}
+
+static int of_early_platform_populate(struct device_node *root)
+{
+ struct early_platform_driver *edrv;
+ const struct of_device_id *match;
+ struct device_node *child;
+ int rv;
+
+ if (!root)
+ return 0;
+
+ list_for_each_entry(edrv, &early_platform_drivers, list) {
+ if (!edrv->pdrv.driver.of_match_table)
+ continue;
+
+ match = of_match_node(edrv->pdrv.driver.of_match_table, root);
+ if (!match)
+ continue;
+
+ rv = of_early_platform_device_create(root, edrv);
+ if (rv)
+ return rv;
+ }
+
+ for_each_child_of_node(root, child) {
+ rv = of_early_platform_populate(child);
+ if (rv) {
+ of_node_put(child);
+ return rv;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * early_platform_start - start handling early devices
+ *
+ * This should be called by the architecture code early in the boot sequence
+ * to register all early platform drivers, populate the early devices from DT
+ * and start matching platform devices specified in machine code.
+ */
+void early_platform_start(void)
+{
+ struct early_platform_driver **edrv;
+ struct device_node *root;
+ int rv;
+
+ WARN_ONCE(!slab_is_available(), "slab is required for early devices\n");
+
+ pr_debug("%s(): registering pending early platform drivers\n",
+ __func__);
+
+ for (edrv = __early_platform_drivers_table;
+ edrv < __early_platform_drivers_table_end; edrv++) {
+ rv = early_platform_driver_register(*edrv);
+ if (rv)
+ pr_warn("error registering early platform driver: %d\n",
+ rv);
+ }
+
+ if (of_have_populated_dt()) {
+ pr_debug("%s(): populating early_platform devices from DT\n",
+ __func__);
+
+ root = of_find_node_by_path("/");
+
+ rv = of_early_platform_populate(root);
+ if (rv)
+ pr_warn("error populating early devices from DT: %d\n",
+ rv);
+
+ of_node_put(root);
+ }
+}
+EXPORT_SYMBOL_GPL(early_platform_start);
+
+/**
+ * early_platform_driver_register - register an early platform driver
+ * @edrv: early platform driver to register
+ *
+ * If we're past postcore initcall, this works exactly as
+ * platform_device_register().
+ */
+int early_platform_driver_register(struct early_platform_driver *edrv)
+{
+ struct early_platform_device *edev;
+
+ if (early_platform_done)
+ return platform_driver_register(&edrv->pdrv);
+
+ INIT_LIST_HEAD(&edrv->list);
+ list_add_tail(&edrv->list, &early_platform_drivers);
+
+ list_for_each_entry(edev, &early_platform_devices, list) {
+ if (platform_match(&edev->pdev.dev, &edrv->pdrv.driver)) {
+ early_platform_try_probe(edrv, edev);
+ break;
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(early_platform_driver_register);
+
+/**
+ * early_platform_device_register - register an early platform device
+ * @edev: early platform device to register
+ *
+ * If we're past postcore initcall, this works exactly as
+ * platform_device_register().
+ */
+int early_platform_device_register(struct early_platform_device *edev)
+{
+ struct early_platform_driver *edrv;
+
+ if (early_platform_done)
+ return platform_device_register(&edev->pdev);
+
+ device_initialize(&edev->pdev.dev);
+ early_platform_device_add(edev);
+
+ list_for_each_entry(edrv, &early_platform_drivers, list) {
+ if (platform_match(&edev->pdev.dev, &edrv->pdrv.driver)) {
+ early_platform_try_probe(edrv, edev);
+ break;
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(early_platform_device_register);
+
+/*
+ * This is called once the entire device model infrastructure is in place to
+ * seamlessly convert all early platform devices & drivers to regular ones.
+ *
+ * From this point forward all early platform devices work exactly like normal
+ * platform devices.
+ */
+static int early_platform_finalize(void)
+{
+ struct early_platform_driver *edrv;
+ struct early_platform_device *edev;
+ int rv;
+
+ early_platform_done = true;
+
+ pr_debug("%s(): converting early platform drivers to real platform drivers\n",
+ __func__);
+
+ list_for_each_entry(edrv, &early_platform_drivers, list) {
+ rv = platform_driver_register(&edrv->pdrv);
+ if (rv)
+ pr_warn("%s: error converting early platform driver to real platform driver\n",
+ edrv->pdrv.driver.name);
+ }
+
+ pr_debug("%s(): converting early platform devices to real platform devices\n",
+ __func__);
+
+ list_for_each_entry(edev, &early_platform_devices, list) {
+ if (edev->pdev.dev.of_node)
+ /* This will be handled by of_platform_populate(). */
+ continue;
+
+ kfree(edev->pdev.dev.init_name);
+
+ /*
+ * We don't want to reinitialize the associated struct device
+ * so we must not call platform_device_register().
+ */
+ rv = platform_device_add(&edev->pdev);
+ if (rv)
+ pr_warn("%s: error converting early platform device to real platform device\n",
+ dev_name(&edev->pdev.dev));
+ }
+
+ return 0;
+}
+postcore_initcall(early_platform_finalize);
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 20be70c3f118..d0a8788d5151 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -57,3 +57,4 @@ obj-$(CONFIG_ASPEED_LPC_SNOOP) += aspeed-lpc-snoop.o
obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o
obj-$(CONFIG_OCXL) += ocxl/
obj-$(CONFIG_MISC_RTSX) += cardreader/
+CFLAGS_dummy-early.o := -DDEBUG
diff --git a/include/linux/early_platform.h b/include/linux/early_platform.h
new file mode 100644
index 000000000000..fd3fd4db8322
--- /dev/null
+++ b/include/linux/early_platform.h
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 Texas Instruments, Inc.
+ *
+ * Author:
+ * Bartosz Golaszewski <bgolaszewski@baylibre.com>
+ */
+
+#ifndef __EARLY_PLATFORM_H__
+#define __EARLY_PLATFORM_H__
+
+#include <linux/platform_device.h>
+#include <linux/types.h>
+
+/**
+ * struct early_platform_driver
+ *
+ * @pdrv: real platform driver associated with this early platform driver
+ * @list: list head for the list of early platform drivers
+ * @early_probe: early probe callback
+ */
+struct early_platform_driver {
+ struct platform_driver pdrv;
+ struct list_head list;
+ int (*early_probe)(struct platform_device *);
+};
+
+/**
+ * struct early_platform_device
+ *
+ * @pdev: real platform device associated with this early platform device
+ * @list: list head for the list of early platform devices
+ * @deferred: true if this device's early probe was deferred
+ * @deferred_drv: early platform driver with which this device was matched
+ */
+struct early_platform_device {
+ struct platform_device pdev;
+ struct list_head list;
+ bool deferred;
+ struct early_platform_driver *deferred_drv;
+};
+
+#ifdef CONFIG_EARLY_PLATFORM
+extern void early_platform_start(void);
+extern int early_platform_driver_register(struct early_platform_driver *edrv);
+extern int early_platform_device_register(struct early_platform_device *edev);
+#else /* CONFIG_EARLY_PLATFORM */
+static inline void early_platform_start(void) {}
+static int void
+early_platform_driver_register(struct early_platform_driver *edrv) {}
+static int void
+early_platform_device_register(struct early_platform_device *edev) {}
+#endif /* CONFIG_EARLY_PLATFORM */
+
+#if defined(CONFIG_EARLY_PLATFORM) && defined(CONFIG_OF)
+extern struct platform_device *
+of_early_to_platform_device(struct device_node *np);
+#else
+static inline struct platform_device *
+of_early_to_platform_device(struct device_node *np)
+{
+ return ERR_PTR(-ENOSYS);
+}
+#endif /* defined(CONFIG_EARLY_PLATFORM) && defined(CONFIG_OF) */
+
+#ifdef CONFIG_EARLY_PLATFORM
+#define module_early_platform_driver(_edrv) \
+ static const struct early_platform_driver *__##_edrv##_entry \
+ __used __section(__early_platform_drivers_table) \
+ = &(_edrv)
+#else /* CONFIG_EARLY_PLATFORM */
+#define module_early_platform_driver(_edrv)
+#endif /* CONFIG_EARLY_PLATFORM */
+
+#endif /* __EARLY_PLATFORM_H__ */
--
2.17.0
^ permalink raw reply related
* [PATCH 09/12] platform/early: add an init section for early driver data
From: Bartosz Golaszewski @ 2018-05-11 16:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180511162028.20616-1-brgl@bgdev.pl>
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Provide a separate section in which pointers to early platform driver
structs will be stored.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
include/asm-generic/vmlinux.lds.h | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index af240573e482..6b5205f30ef2 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -214,6 +214,16 @@
#define CPU_METHOD_OF_TABLES() OF_TABLE(CONFIG_SMP, cpu_method)
#define CPUIDLE_METHOD_OF_TABLES() OF_TABLE(CONFIG_CPU_IDLE, cpuidle_method)
+#ifdef CONFIG_EARLY_PLATFORM
+#define EARLY_PLATFORM_DRIVERS_TABLE() \
+ . = ALIGN(8); \
+ VMLINUX_SYMBOL(__early_platform_drivers_table) = .; \
+ KEEP(*(__early_platform_drivers_table)) \
+ VMLINUX_SYMBOL(__early_platform_drivers_table_end) = .;
+#else
+#define EARLY_PLATFORM_DRIVERS_TABLE()
+#endif
+
#ifdef CONFIG_ACPI
#define ACPI_PROBE_TABLE(name) \
. = ALIGN(8); \
@@ -593,6 +603,7 @@
RESERVEDMEM_OF_TABLES() \
TIMER_OF_TABLES() \
IOMMU_OF_TABLES() \
+ EARLY_PLATFORM_DRIVERS_TABLE() \
CPU_METHOD_OF_TABLES() \
CPUIDLE_METHOD_OF_TABLES() \
KERNEL_DTB() \
--
2.17.0
^ permalink raw reply related
* [PATCH 08/12] of/platform: provide a separate routine for device initialization
From: Bartosz Golaszewski @ 2018-05-11 16:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180511162028.20616-1-brgl@bgdev.pl>
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
The early platform device framework will need to initialize the
platform device objects without them being allocated in
of_device_alloc(). Provide a routine that allows it.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
drivers/of/platform.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 24791e558ec5..0e554fe1f325 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -132,6 +132,19 @@ int of_device_init_resources(struct platform_device *pdev,
return 0;
}
+static void of_device_init(struct platform_device *pdev, struct device_node *np,
+ const char *bus_id, struct device *parent)
+{
+ pdev->dev.of_node = of_node_get(np);
+ pdev->dev.fwnode = &np->fwnode;
+ pdev->dev.parent = parent ? : &platform_bus;
+
+ if (bus_id)
+ dev_set_name(&pdev->dev, "%s", bus_id);
+ else
+ of_device_make_bus_id(&pdev->dev);
+}
+
/**
* of_device_alloc - Allocate and initialize an of_device
* @np: device node to assign to device
@@ -155,14 +168,7 @@ struct platform_device *of_device_alloc(struct device_node *np,
return NULL;
}
- dev->dev.of_node = of_node_get(np);
- dev->dev.fwnode = &np->fwnode;
- dev->dev.parent = parent ? : &platform_bus;
-
- if (bus_id)
- dev_set_name(&dev->dev, "%s", bus_id);
- else
- of_device_make_bus_id(&dev->dev);
+ of_device_init(dev, np, bus_id, parent);
return dev;
}
--
2.17.0
^ permalink raw reply related
* [PATCH 07/12] of/platform: provide a separate routine for setting up device resources
From: Bartosz Golaszewski @ 2018-05-11 16:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180511162028.20616-1-brgl@bgdev.pl>
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
The early platform driver framework will need to setup the device
resources before the regular populating of the device tree happens.
Provide a separate function for that.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
drivers/of/platform.c | 54 +++++++++++++++++++++++--------------
include/linux/of_platform.h | 2 ++
2 files changed, 36 insertions(+), 20 deletions(-)
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index c00d81dfac0b..24791e558ec5 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -99,24 +99,12 @@ static void of_device_make_bus_id(struct device *dev)
}
}
-/**
- * of_device_alloc - Allocate and initialize an of_device
- * @np: device node to assign to device
- * @bus_id: Name to assign to the device. May be null to use default name.
- * @parent: Parent device.
- */
-struct platform_device *of_device_alloc(struct device_node *np,
- const char *bus_id,
- struct device *parent)
+int of_device_init_resources(struct platform_device *pdev,
+ struct device_node *np)
{
- struct platform_device *dev;
int rc, i, num_reg = 0, num_irq;
struct resource *res, temp_res;
- dev = platform_device_alloc("", PLATFORM_DEVID_NONE);
- if (!dev)
- return NULL;
-
/* count the io and irq resources */
while (of_address_to_resource(np, num_reg, &temp_res) == 0)
num_reg++;
@@ -125,22 +113,48 @@ struct platform_device *of_device_alloc(struct device_node *np,
/* Populate the resource table */
if (num_irq || num_reg) {
res = kzalloc(sizeof(*res) * (num_irq + num_reg), GFP_KERNEL);
- if (!res) {
- platform_device_put(dev);
- return NULL;
- }
+ if (!res)
+ return -ENOMEM;
+
+ pdev->num_resources = num_reg + num_irq;
+ pdev->resource = res;
- dev->num_resources = num_reg + num_irq;
- dev->resource = res;
for (i = 0; i < num_reg; i++, res++) {
rc = of_address_to_resource(np, i, res);
WARN_ON(rc);
}
+
if (of_irq_to_resource_table(np, res, num_irq) != num_irq)
pr_debug("not all legacy IRQ resources mapped for %s\n",
np->name);
}
+ return 0;
+}
+
+/**
+ * of_device_alloc - Allocate and initialize an of_device
+ * @np: device node to assign to device
+ * @bus_id: Name to assign to the device. May be null to use default name.
+ * @parent: Parent device.
+ */
+struct platform_device *of_device_alloc(struct device_node *np,
+ const char *bus_id,
+ struct device *parent)
+{
+ struct platform_device *dev;
+ int rc;
+
+ dev = platform_device_alloc("", PLATFORM_DEVID_NONE);
+ if (!dev)
+ return NULL;
+
+ rc = of_device_init_resources(dev, np);
+ if (rc) {
+ platform_device_put(dev);
+ return NULL;
+ }
+
dev->dev.of_node = of_node_get(np);
dev->dev.fwnode = &np->fwnode;
dev->dev.parent = parent ? : &platform_bus;
diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h
index 84a966623e78..387ab4d4a210 100644
--- a/include/linux/of_platform.h
+++ b/include/linux/of_platform.h
@@ -52,6 +52,8 @@ extern const struct of_device_id of_default_bus_match_table[];
extern struct platform_device *of_device_alloc(struct device_node *np,
const char *bus_id,
struct device *parent);
+extern int of_device_init_resources(struct platform_device *pdev,
+ struct device_node *np);
#ifdef CONFIG_OF
extern struct platform_device *of_find_device_by_node(struct device_node *np);
#else
--
2.17.0
^ permalink raw reply related
* [PATCH 06/12] of: add a new flag for OF device nodes
From: Bartosz Golaszewski @ 2018-05-11 16:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180511162028.20616-1-brgl@bgdev.pl>
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
This flag indicates that a device node has been populated early and
that it needs different handling when called from
of_platform_populate().
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
include/linux/of.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/linux/of.h b/include/linux/of.h
index 4d25e4f952d9..49ba6427c6b2 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -143,6 +143,7 @@ extern raw_spinlock_t devtree_lock;
#define OF_DETACHED 2 /* node has been detached from the device tree */
#define OF_POPULATED 3 /* device already created for the node */
#define OF_POPULATED_BUS 4 /* of_platform_populate recursed to children of this node */
+#define OF_POPULATED_EARLY 5 /* device is already allocated */
#define OF_BAD_ADDR ((u64)-1)
--
2.17.0
^ permalink raw reply related
* [PATCH 05/12] platform: export platform_device_release() locally
From: Bartosz Golaszewski @ 2018-05-11 16:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180511162028.20616-1-brgl@bgdev.pl>
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
The early platform driver mechanism will use this function as the
device release callback. Make it available in drivers/base.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
drivers/base/base.h | 1 +
drivers/base/platform.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/base/base.h b/drivers/base/base.h
index 7a72ae72a98e..514a6d198f14 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -164,3 +164,4 @@ extern void device_links_unbind_consumers(struct device *dev);
/* Platform device helpers. */
extern int platform_match(struct device *dev, struct device_driver *drv);
+extern void platform_device_release(struct device *dev);
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 0ba4effb9618..417ab6071350 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -239,7 +239,7 @@ void platform_device_put(struct platform_device *pdev)
}
EXPORT_SYMBOL_GPL(platform_device_put);
-static void platform_device_release(struct device *dev)
+void platform_device_release(struct device *dev)
{
struct platform_object *pa = container_of(dev, struct platform_object,
pdev.dev);
--
2.17.0
^ permalink raw reply related
* [PATCH 04/12] platform: provide a separate function for initializing platform devices
From: Bartosz Golaszewski @ 2018-05-11 16:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180511162028.20616-1-brgl@bgdev.pl>
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
The early platform driver framework will allocate platform devices
using its own internal mechanisms. Provide a function that allows to
initialize a platform device object without allocating it.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
drivers/base/platform.c | 24 ++++++++++++++++++++----
include/linux/platform_device.h | 2 ++
2 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 0c53e3e3e5aa..0ba4effb9618 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -252,6 +252,25 @@ static void platform_device_release(struct device *dev)
kfree(pa);
}
+/**
+ * platform_device_init - initialize a platform device
+ * @pdev: platform device to initialize
+ * @name: base name of the device we're adding, NOTE: it's not copied
+ * @id: instance id
+ *
+ * Initiate an already allocated platform device. This routine does not set
+ * the release device callback.
+ */
+void platform_device_init(struct platform_device *pdev,
+ const char *name, int id)
+{
+ pdev->name = name;
+ pdev->id = id;
+ device_initialize(&pdev->dev);
+ arch_setup_pdev_archdata(pdev);
+}
+EXPORT_SYMBOL_GPL(platform_device_init);
+
/**
* platform_device_alloc - create a platform device
* @name: base name of the device we're adding
@@ -267,11 +286,8 @@ struct platform_device *platform_device_alloc(const char *name, int id)
pa = kzalloc(sizeof(*pa) + strlen(name) + 1, GFP_KERNEL);
if (pa) {
strcpy(pa->name, name);
- pa->pdev.name = pa->name;
- pa->pdev.id = id;
- device_initialize(&pa->pdev.dev);
+ platform_device_init(&pa->pdev, pa->name, id);
pa->pdev.dev.release = platform_device_release;
- arch_setup_pdev_archdata(&pa->pdev);
}
return pa ? &pa->pdev : NULL;
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 099aaf804b50..46bfd5ff666f 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -165,6 +165,8 @@ static inline struct platform_device *platform_device_register_data(
NULL, 0, data, size);
}
+extern void platform_device_init(struct platform_device *pdev,
+ const char *name, int id);
extern struct platform_device *platform_device_alloc(const char *name, int id);
extern int platform_device_add_resources(struct platform_device *pdev,
const struct resource *res,
--
2.17.0
^ permalink raw reply related
* [PATCH 03/12] platform/early: export platform_match() locally
From: Bartosz Golaszewski @ 2018-05-11 16:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180511162028.20616-1-brgl@bgdev.pl>
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
We will use this function to match devices in the early platform core
code. Export it locally in drivers/base.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
drivers/base/base.h | 3 +++
drivers/base/platform.c | 2 +-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/base/base.h b/drivers/base/base.h
index d800de650fa5..7a72ae72a98e 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -161,3 +161,6 @@ extern void device_links_driver_cleanup(struct device *dev);
extern void device_links_no_driver(struct device *dev);
extern bool device_links_busy(struct device *dev);
extern void device_links_unbind_consumers(struct device *dev);
+
+/* Platform device helpers. */
+extern int platform_match(struct device *dev, struct device_driver *drv);
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 70b156ee267a..0c53e3e3e5aa 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -961,7 +961,7 @@ static const struct platform_device_id *platform_match_id(
* and compare it against the name of the driver. Return whether they match
* or not.
*/
-static int platform_match(struct device *dev, struct device_driver *drv)
+int platform_match(struct device *dev, struct device_driver *drv)
{
struct platform_device *pdev = to_platform_device(dev);
struct platform_driver *pdrv = to_platform_driver(drv);
--
2.17.0
^ permalink raw reply related
* [PATCH 02/12] platform/early: don't WARN() on non-empty devres list for early devices
From: Bartosz Golaszewski @ 2018-05-11 16:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180511162028.20616-1-brgl@bgdev.pl>
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Early platform devices can have devres objects allocated in
early_probe(). This is not a bug so don't dump stack in this case.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
drivers/base/dd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index c9f54089429b..0b94d9426757 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -410,7 +410,7 @@ static int really_probe(struct device *dev, struct device_driver *drv)
atomic_inc(&probe_count);
pr_debug("bus: '%s': %s: probing driver %s with device %s\n",
drv->bus->name, __func__, drv->name, dev_name(dev));
- WARN_ON(!list_empty(&dev->devres_head));
+ WARN_ON(!dev->early && !list_empty(&dev->devres_head));
re_probe:
dev->driver = drv;
--
2.17.0
^ permalink raw reply related
* [PATCH 01/12] platform/early: add a new field to struct device
From: Bartosz Golaszewski @ 2018-05-11 16:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180511162028.20616-1-brgl@bgdev.pl>
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Add a new single-bit field to struct device which will be used to
indicate that a device was probed early in the boot sequence.
This does not affect the size of struct device on any architecture
I built on (ARM, ARM64, x86_64).
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
include/linux/device.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/linux/device.h b/include/linux/device.h
index 477956990f5e..bcff8b598b20 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -992,6 +992,7 @@ struct device {
bool offline_disabled:1;
bool offline:1;
bool of_node_reused:1;
+ bool early:1;
};
static inline struct device *kobj_to_dev(struct kobject *kobj)
--
2.17.0
^ permalink raw reply related
* [PATCH 00/12] introduce support for early platform drivers
From: Bartosz Golaszewski @ 2018-05-11 16:20 UTC (permalink / raw)
To: linux-arm-kernel
This series is a follow-up to the RFC[1] posted a couple days ago.
NOTE: this series applies on top of my recent patches[2] that move the previous
implementation of early platform devices to arch/sh.
Problem:
Certain class of devices, such as timers, certain clock drivers and irq chip
drivers need to be probed early in the boot sequence. The currently preferred
approach is using one of the OF_DECLARE() macros. This however does not create
a platform device which has many drawbacks - such as not being able to use
devres routines, dev_ log functions or no way of deferring the init OF function
if some other resources are missing.
For drivers that use both platform drivers and OF_DECLARE the situation is even
more complicated as the code needs to take into account that there can possibly
be no struct device present. For a specific use case that we're having problems
with, please refer to the recent DaVinci common-clock conversion patches and
the nasty workaround that this problem implies[3].
We also used to have an early platform drivers implementation but they were not
integrated with the linux device model at all - they merely used the same data
structures. The users could not use devres, defer probe and the early devices
never became actual platform devices later on.
Proposed solution:
This series aims at solving this problem by (re-)introducing the concept of
early platform drivers and devices - this time however in a way that seamlessly
integrates with the existing platform drivers and also offers device-tree
support.
The idea is to provide a way for users to probe devices early, while already
being able to use devres, devices resources and properties and also deferred
probing.
New structures are introduced: the early platform driver contains the
early_probe callback which has the same signature as regular platform_device
probe. This callback is called early on. The user can have both the early and
regular probe speficied or only one of them and they both receive the same
platform device object as argument. Any device data allocated early will be
carried over to the normal probe.
The architecture code is responsible for calling early_platform_start() in
which the early drivers will be registered and devices populated from DT.
Once the device and kobject mechanisms are ready, all early drivers and devices
will be converted into real platform drivers and devices. Also: if any of the
early platform registration functions will be called once early initialization
is done, these functions will work like regular platform_device/driver ones.
Patches 1-9/12 introduce changes to existing code that are necessary before
adding support for early drivers. Patch 10/12 contains the new framwork in an
isolated file which can be compiled only if needed by the architecture.
Patch 11/12 contains a dummy early platform driver that serves as a code
example and can be used for simple testing.
The last patch finally makes the of/platform code aware of early platform
drivers.
If accepted, this new mechanism could potentially lead to consolidation of the
code currently used by users of OF_DECLARE, since they could be converted to
actual platform drivers.
[1] https://lkml.org/lkml/2018/4/26/657
[2] https://lkml.org/lkml/2018/4/30/547
[3] https://lkml.org/lkml/2018/4/26/1094
Bartosz Golaszewski (12):
platform/early: add a new field to struct device
platform/early: don't WARN() on non-empty devres list for early
devices
platform/early: export platform_match() locally
platform: provide a separate function for initializing platform
devices
platform: export platform_device_release() locally
of: add a new flag for OF device nodes
of/platform: provide a separate routine for setting up device
resources
of/platform: provide a separate routine for device initialization
platform/early: add an init section for early driver data
platform/early: implement support for early platform drivers
misc: implement a dummy early platform driver
of/platform: make the OF code aware of early platform drivers
drivers/base/Kconfig | 3 +
drivers/base/Makefile | 1 +
drivers/base/base.h | 4 +
drivers/base/dd.c | 2 +-
drivers/base/early.c | 332 ++++++++++++++++++++++++++++++
drivers/base/platform.c | 28 ++-
drivers/misc/Kconfig | 8 +
drivers/misc/Makefile | 2 +
drivers/misc/dummy-early.c | 82 ++++++++
drivers/of/platform.c | 85 +++++---
include/asm-generic/vmlinux.lds.h | 11 +
include/linux/device.h | 1 +
include/linux/early_platform.h | 75 +++++++
include/linux/of.h | 1 +
include/linux/of_platform.h | 2 +
include/linux/platform_device.h | 2 +
16 files changed, 604 insertions(+), 35 deletions(-)
create mode 100644 drivers/base/early.c
create mode 100644 drivers/misc/dummy-early.c
create mode 100644 include/linux/early_platform.h
--
2.17.0
^ permalink raw reply
* [PATCH resend 00/10] crypto: arm64 - play nice with CONFIG_PREEMPT
From: Herbert Xu @ 2018-05-11 16:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180430161830.14892-1-ard.biesheuvel@linaro.org>
On Mon, Apr 30, 2018 at 06:18:20PM +0200, Ard Biesheuvel wrote:
> Hello Herbert,
>
> These are the patches that depend on the arm64/assembler.h patches that
> inadvertently got pulled into the cryptodev tree and reverted shortly
> after. Those have now been merged into Linus's tree, and so the
> remaining changes can be applied as well. Please apply.
>
> Ard Biesheuvel (10):
> crypto: arm64/sha1-ce - yield NEON after every block of input
> crypto: arm64/sha2-ce - yield NEON after every block of input
> crypto: arm64/aes-ccm - yield NEON after every block of input
> crypto: arm64/aes-blk - yield NEON after every block of input
> crypto: arm64/aes-bs - yield NEON after every block of input
> crypto: arm64/aes-ghash - yield NEON after every block of input
> crypto: arm64/crc32-ce - yield NEON after every block of input
> crypto: arm64/crct10dif-ce - yield NEON after every block of input
> crypto: arm64/sha3-ce - yield NEON after every block of input
> crypto: arm64/sha512-ce - yield NEON after every block of input
>
> arch/arm64/crypto/aes-ce-ccm-core.S | 150 +++++----
> arch/arm64/crypto/aes-ce.S | 15 +-
> arch/arm64/crypto/aes-modes.S | 331 ++++++++++++--------
> arch/arm64/crypto/aes-neonbs-core.S | 305 ++++++++++--------
> arch/arm64/crypto/crc32-ce-core.S | 40 ++-
> arch/arm64/crypto/crct10dif-ce-core.S | 32 +-
> arch/arm64/crypto/ghash-ce-core.S | 113 +++++--
> arch/arm64/crypto/ghash-ce-glue.c | 28 +-
> arch/arm64/crypto/sha1-ce-core.S | 42 ++-
> arch/arm64/crypto/sha2-ce-core.S | 37 ++-
> arch/arm64/crypto/sha3-ce-core.S | 77 +++--
> arch/arm64/crypto/sha512-ce-core.S | 27 +-
> 12 files changed, 762 insertions(+), 435 deletions(-)
All applied. Thanks.
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* [PATCH] iommu/arm-smmu-v3: Set GBPA to abort all transactions
From: Goel, Sameer @ 2018-05-11 16:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <265a41d4-ec3c-6697-0340-6830807ea10f@arm.com>
On 4/12/2018 5:56 AM, Marc Zyngier wrote:
> On 12/04/18 11:17, Robin Murphy wrote:
>> On 11/04/18 17:54, Marc Zyngier wrote:
>>> Hi Sammer,
>>>
>>> On 11/04/18 16:58, Goel, Sameer wrote:
>>>>
>>>>
>>>> On 3/28/2018 9:00 AM, Marc Zyngier wrote:
>>>>> On 2018-03-28 15:39, Timur Tabi wrote:
>>>>>> From: Sameer Goel <sgoel@codeaurora.org>
>>>>>>
>>>>>> Set SMMU_GBPA to abort all incoming translations during the SMMU reset
>>>>>> when SMMUEN==0.
>>>>>>
>>>>>> This prevents a race condition where a stray DMA from the crashed primary
>>>>>> kernel can try to access an IOVA address as an invalid PA when SMMU is
>>>>>> disabled during reset in the crash kernel.
>>>>>>
>>>>>> Signed-off-by: Sameer Goel <sgoel@codeaurora.org>
>>>>>> ---
>>>>>> ?drivers/iommu/arm-smmu-v3.c | 12 ++++++++++++
>>>>>> ?1 file changed, 12 insertions(+)
>>>>>>
>>>>>> diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
>>>>>> index 3f2f1fc68b52..c04a89310c59 100644
>>>>>> --- a/drivers/iommu/arm-smmu-v3.c
>>>>>> +++ b/drivers/iommu/arm-smmu-v3.c
>>>>>> @@ -2458,6 +2458,18 @@ static int arm_smmu_device_reset(struct
>>>>>> arm_smmu_device *smmu, bool bypass)
>>>>>> ???? if (reg & CR0_SMMUEN)
>>>>>> ???????? dev_warn(smmu->dev, "SMMU currently enabled! Resetting...\n");
>>>>>>
>>>>>> +??? /*
>>>>>> +???? * Abort all incoming translations. This can happen in a kdump case
>>>>>> +???? * where SMMU is initialized when a prior DMA is pending. Just
>>>>>> +???? * disabling the SMMU in this case might result in writes to invalid
>>>>>> +???? * PAs.
>>>>>> +???? */
>>>>>> +??? ret = arm_smmu_update_gbpa(smmu, 1, GBPA_ABORT);
>>>>>> +??? if (ret) {
>>>>>> +??????? dev_err(smmu->dev, "GBPA not responding to update\n");
>>>>>> +??????? return ret;
>>>>>> +??? }
>>>>>> +
>>>>>> ???? ret = arm_smmu_device_disable(smmu);
>>>>>> ???? if (ret)
>>>>>> ???????? return ret;
>>>>>
>>>>> A tangential question: can we reliably detect that the SMMU already
>>>>> has valid mappings, which would indicate that we're in a pretty bad
>>>>> shape already by the time we set that bit? For all we know, memory
>>>>> could have been corrupted long before we hit this point, and this
>>>>> patch barely narrows the window of opportunity.
>>>>
>>>> :) Yes that is correct. This only covers the kdump scenario. Trying
>>>> to get some reliability when booting up the crash kernel. The system
>>>> is already in a bad state. I don't think that this will happen in a
>>>> normal scenario. But please point me to the GICv3 change and I'll
>>>> have a look.
>>>
>>> See this:
>>> https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git/tree/drivers/irqchip/irq-gic-v3-its.c?h=irq/irqchip-4.17&id=6eb486b66a3094cdcd68dc39c9df3a29d6a51dd5#n3407
>>
>> The nearest equivalent to that is probably the top-level SMMUEN check
>> that we already have (see the diff context above). To go beyond that
>> you'd have to chase the old stream table pointer and scan the whole
>> thing looking for valid contexts, then potentially walk page tables
>> within those contexts to check for live translations if you really
>> wanted to be sure. That would be a hell of a lot of work to do in the
>> boot path.
> Yeah, feels a bit too involved for sanity. I'd simply suggest you taint
> the kernel if you find the SMMU enabled, as you're already on shaky ground.
Ok. I think since this is a kdump kernel a taint is not necessary?
>
> Thanks,
>
> M.
>
--
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply
* [PATCH 2/2] arm64: Clear the stack
From: Mark Rutland @ 2018-05-11 16:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <71199506-b46b-5f91-e489-e6450b6d1067@linux.com>
On Fri, May 11, 2018 at 06:50:09PM +0300, Alexander Popov wrote:
> Hello everyone,
>
> On 06.05.2018 11:22, Alexander Popov wrote:
> > On 04.05.2018 14:09, Mark Rutland wrote:
> >>>>> + stack_left = sp & (THREAD_SIZE - 1);
> >>>>> + BUG_ON(stack_left < 256 || size >= stack_left - 256);
> >>>>
> >>>> Is this arbitrary, or is there something special about 256?
> >>>>
> >>>> Even if this is arbitrary, can we give it some mnemonic?
> >>>
> >>> It's just a reasonable number. We can introduce a macro for it.
> >>
> >> I'm just not sure I see the point in the offset, given things like
> >> VMAP_STACK exist. BUG_ON() handling will likely require *more* than 256
> >> bytes of stack, so it seems superfluous, as we'd be relying on stack
> >> overflow detection at that point.
> >>
> >> I can see that we should take the CONFIG_SCHED_STACK_END_CHECK offset
> >> into account, though.
> >
> > Mark, thank you for such an important remark!
> >
> > In Kconfig STACKLEAK implies but doesn't depend on VMAP_STACK. In fact x86_32
> > doesn't have VMAP_STACK at all but can have STACKLEAK.
> >
> > [Adding Andy Lutomirski]
> >
> > I've made some additional experiments: I exhaust the thread stack to have only
> > (MIN_STACK_LEFT - 1) bytes left and then force alloca. If VMAP_STACK is
> > disabled, BUG_ON() handling causes stack depth overflow, which is detected by
> > SCHED_STACK_END_CHECK. If VMAP_STACK is enabled, the kernel hangs on BUG_ON()
> > handling! Enabling CONFIG_PROVE_LOCKING gives the needed report from VMAP_STACK:
I can't see why CONFIG_VMAP_STACK would only work in conjunction with
CONFIG_PROVE_LOCKING.
On arm64 at least, if we overflow the stack while handling a BUG(), we
*should* trigger the overflow handler as usual, and that should work,
unless I'm missing something.
Maybe it gets part-way into panic(), sets up some state,
stack-overflows, and we get wedged because we're already in a panic?
Perhaps CONFIG_PROVE_LOCKING causes more stack to be used, so it dies a
little earlier in panic(), before setting up some state that causes
wedging.
... which sounds like something best fixed in those code paths, and not
here.
> [...]
>
> > I can't say why VMAP_STACK report hangs during BUG_ON() handling on defconfig.
> > Andy, can you give a clue?
> >
> > I see that MIN_STACK_LEFT = 2048 is enough for BUG_ON() handling on both x86_64
> > and x86_32. So I'm going to:
> > - set MIN_STACK_LEFT to 2048;
> > - improve the lkdtm test to cover this case.
> >
> > Mark, Kees, Laura, does it sound good?
>
>
> Could you have a look at the following changes in check_alloca() before I send
> the next version?
>
> If VMAP_STACK is enabled and alloca causes stack depth overflow, I write to
> guard page below the thread stack to cause double fault and VMAP_STACK report.
On arm64 at least, writing to the guard page will not itself trigger a
stack overflow, but will trigger a data abort. I suspect similar is true
on x86, if the stack pointer is sufficiently far above the guard page.
> If VMAP_STACK is disabled, I use MIN_STACK_LEFT = 2048, which seems to be enough
> for BUG_ON() handling both on x86_32 and x86_64. Unfortunately, I can't
> guarantee that it is always enough.
I don't think that we can choose something that's guaranteed to be
sufficient for BUG() handling and also not wasting a tonne of space
under normal operation.
Let's figure out what's going wrong on x86 in the case that you mention,
and try to solve that.
Here I don't think we should reserve space at all -- it's completely
arbitrary, and as above we can't guarantee that it's sufficient anyway.
> #ifdef CONFIG_GCC_PLUGIN_STACKLEAK
> -#define MIN_STACK_LEFT 256
> +#define MIN_STACK_LEFT 2048
>
> void __used check_alloca(unsigned long size)
> {
> unsigned long sp = (unsigned long)&sp;
> struct stack_info stack_info = {0};
> unsigned long visit_mask = 0;
> unsigned long stack_left;
>
> BUG_ON(get_stack_info(&sp, current, &stack_info, &visit_mask));
>
> stack_left = sp - (unsigned long)stack_info.begin;
> +
> +#ifdef CONFIG_VMAP_STACK
> + /*
> + * If alloca oversteps the thread stack boundary, we touch the guard
> + * page provided by VMAP_STACK to trigger handle_stack_overflow().
> + */
> + if (size >= stack_left)
> + *(stack_info.begin - 1) = 42;
> +#else
On arm64, this won't trigger our stack overflow handler, unless the SP
is already very close to the boundary.
Please just use BUG(). If there is an issue on x86, it would be good to
solve that in the x86 code.
> BUG_ON(stack_left < MIN_STACK_LEFT ||
> size >= stack_left - MIN_STACK_LEFT);
I really don't think we should bother with this arbitrary offset at all.
Thanks,
Mark.
^ permalink raw reply
* [PATCHv2] arm64: dts: stratix10: Add QSPI support for Stratix10
From: thor.thayer at linux.intel.com @ 2018-05-11 16:10 UTC (permalink / raw)
To: linux-arm-kernel
From: Thor Thayer <thor.thayer@linux.intel.com>
Add qspi_clock
The qspi_clk frequency is updated by U-Boot before starting Linux.
Add QSPI interface node.
Add QSPI flash memory child node.
Setup the QSPI memory in 2 partitions.
Signed-off-by: Thor Thayer <thor.thayer@linux.intel.com>
---
v2 s/_/-/ in qspi-clk
rename flash node.
use partition child node notation
---
arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi | 22 ++++++++++++++
.../boot/dts/altera/socfpga_stratix10_socdk.dts | 35 ++++++++++++++++++++++
2 files changed, 57 insertions(+)
diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
index e6b059378dc0..bac01b0b7907 100644
--- a/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
+++ b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
@@ -119,6 +119,12 @@
#clock-cells = <0>;
compatible = "fixed-clock";
};
+
+ qspi_clk: qspi-clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <200000000>;
+ };
};
gmac0: ethernet at ff800000 {
@@ -466,5 +472,21 @@
interrupts = <16 4>, <48 4>;
};
};
+
+ qspi: spi at ff8d2000 {
+ compatible = "cdns,qspi-nor";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0xff8d2000 0x100>,
+ <0xff900000 0x100000>;
+ interrupts = <0 3 4>;
+ cdns,fifo-depth = <128>;
+ cdns,fifo-width = <4>;
+ cdns,trigger-address = <0x00000000>;
+ clocks = <&qspi_clk>;
+ bus-num = <1>;
+
+ status = "disabled";
+ };
};
};
diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
index f9b1ef12db48..96542150654b 100644
--- a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
+++ b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
@@ -147,3 +147,38 @@
reg = <0x68>;
};
};
+
+&qspi {
+ flash at 0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "n25q00aa";
+ reg = <0>;
+ spi-max-frequency = <50000000>;
+
+ m25p,fast-read;
+ cdns,page-size = <256>;
+ cdns,block-size = <16>;
+ cdns,read-delay = <1>;
+ cdns,tshsl-ns = <50>;
+ cdns,tsd2d-ns = <50>;
+ cdns,tchsh-ns = <4>;
+ cdns,tslch-ns = <4>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ qspi_boot: partition at 0 {
+ label = "Boot and fpga data";
+ reg = <0x0 0x4000000>;
+ };
+
+ qspi_rootfs: partition at 4000000 {
+ label = "Root Filesystem - JFFS2";
+ reg = <0x4000000 0x4000000>;
+ };
+ };
+ };
+};
--
2.7.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox