Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 3/4] ARM: dts: imx7d-cl-som: Fix OTG power pinctrl
From: Fabio Estevam @ 2017-01-19 12:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170119090924.19636-4-s.hauer@pengutronix.de>

On Thu, Jan 19, 2017 at 7:09 AM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> GPIO01_IO05 is controlled by the LPSR iomux controller, so attach
> the corresponding pin to this controller.
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>

^ permalink raw reply

* [PATCH 2/4] ARM: dts: imx7d-sdp: Fix watchdog and pwm pinmux
From: Fabio Estevam @ 2017-01-19 12:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170119090924.19636-3-s.hauer@pengutronix.de>

On Thu, Jan 19, 2017 at 7:09 AM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> The watchdog pin and the pwm output pin are controlled by the
> iomuxc_lpsr, not the regular iomux, so move the pins there.
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>

Just two minor nits that probably Shawn can take care while applying it"

in Subject there is a typo "sdb".

> ---
>  arch/arm/boot/dts/imx7d-sdb.dts | 26 ++++++++++++++------------
>  1 file changed, 14 insertions(+), 12 deletions(-)
>
> diff --git a/arch/arm/boot/dts/imx7d-sdb.dts b/arch/arm/boot/dts/imx7d-sdb.dts
> index 2f33c463cbce..84f35a6cbb30 100644
> --- a/arch/arm/boot/dts/imx7d-sdb.dts
> +++ b/arch/arm/boot/dts/imx7d-sdb.dts
> @@ -502,12 +502,6 @@
>                         >;
>                 };
>
> -               pinctrl_pwm1: pwm1grp {
> -                       fsl,pins = <
> -                               MX7D_PAD_GPIO1_IO01__PWM1_OUT           0x110b0
> -                       >;
> -               };
> -
>                 pinctrl_tsc2046_pendown: tsc2046_pendown {
>                         fsl,pins = <
>                                 MX7D_PAD_EPDC_BDR1__GPIO2_IO29          0x59
> @@ -635,11 +629,19 @@
>                                 MX7D_PAD_SD3_STROBE__SD3_STROBE         0x1b
>                         >;
>                 };
> -
> -               pinctrl_wdog: wdoggrp {
> -                       fsl,pins = <
> -                               MX7D_PAD_GPIO1_IO00__WDOD1_WDOG_B       0x74
> -                       >;
> -               };
>         };
>  };
> +
> +&iomuxc_lpsr {
> +       pinctrl_wdog: wdoggrp {
> +               fsl,pins = <
> +                       MX7D_PAD_GPIO1_IO00__WDOD1_WDOG_B       0x74
> +               >;
> +       };
> +
> +       pinctrl_pwm1: pwm1grp {
> +               fsl,pins = <
> +                       MX7D_PAD_GPIO1_IO01__PWM1_OUT           0x110b0
> +               >;
> +       };
> +};
> \ No newline at end of file

This could be fixed as well.

^ permalink raw reply

* [PATCH v8 2/4] arm64: arch_timer: Introduce a generic erratum handing mechanism for fsl-a008585
From: Marc Zyngier @ 2017-01-19 11:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484824474-12172-3-git-send-email-dingtianhong@huawei.com>

On 19/01/17 11:14, Ding Tianhong wrote:
> The workaround for hisilicon,161010101 will check the return value of the system counter
> by different way, in order to distinguish with the fsl-a008585 workaround, introduce
> a new generic erratum handing mechanism for fsl-a008585 and rename some functions.
> 
> After discussion with Marc and Will, a consensus decision was made to remove the commandline
> parameter for enabling fsl,erratum-a008585 erratum.
> 
> Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
> ---
>  Documentation/admin-guide/kernel-parameters.txt |   9 --
>  arch/arm64/include/asm/arch_timer.h             |  38 +++------
>  drivers/clocksource/Kconfig                     |   8 ++
>  drivers/clocksource/arm_arch_timer.c            | 105 ++++++++++++++----------
>  4 files changed, 84 insertions(+), 76 deletions(-)
> 
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index 21e2d88..76437ad 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -539,15 +539,6 @@
>  			loops can be debugged more effectively on production
>  			systems.
>  
> -	clocksource.arm_arch_timer.fsl-a008585=
> -			[ARM64]
> -			Format: <bool>
> -			Enable/disable the workaround of Freescale/NXP
> -			erratum A-008585.  This can be useful for KVM
> -			guests, if the guest device tree doesn't show the
> -			erratum.  If unspecified, the workaround is
> -			enabled based on the device tree.
> -
>  	clearcpuid=BITNUM [X86]
>  			Disable CPUID feature X for the kernel. See
>  			arch/x86/include/asm/cpufeatures.h for the valid bit
> diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
> index eaa5bbe..b4b3400 100644
> --- a/arch/arm64/include/asm/arch_timer.h
> +++ b/arch/arm64/include/asm/arch_timer.h
> @@ -29,41 +29,29 @@
>  
>  #include <clocksource/arm_arch_timer.h>
>  
> -#if IS_ENABLED(CONFIG_FSL_ERRATUM_A008585)
> +#if IS_ENABLED(CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND)
>  extern struct static_key_false arch_timer_read_ool_enabled;
> -#define needs_fsl_a008585_workaround() \
> +#define needs_unstable_timer_counter_workaround() \
>  	static_branch_unlikely(&arch_timer_read_ool_enabled)
>  #else
> -#define needs_fsl_a008585_workaround()  false
> +#define needs_unstable_timer_counter_workaround()  false
>  #endif
>  
> -u32 __fsl_a008585_read_cntp_tval_el0(void);
> -u32 __fsl_a008585_read_cntv_tval_el0(void);
> -u64 __fsl_a008585_read_cntvct_el0(void);
>  
> -/*
> - * The number of retries is an arbitrary value well beyond the highest number
> - * of iterations the loop has been observed to take.
> - */
> -#define __fsl_a008585_read_reg(reg) ({			\
> -	u64 _old, _new;					\
> -	int _retries = 200;				\
> -							\
> -	do {						\
> -		_old = read_sysreg(reg);		\
> -		_new = read_sysreg(reg);		\
> -		_retries--;				\
> -	} while (unlikely(_old != _new) && _retries);	\
> -							\
> -	WARN_ON_ONCE(!_retries);			\
> -	_new;						\
> -})
> +struct arch_timer_erratum_workaround {
> +	const char *id;		/* Indicate the Erratum ID */
> +	u32 (*read_cntp_tval_el0)(void);
> +	u32 (*read_cntv_tval_el0)(void);
> +	u64 (*read_cntvct_el0)(void);
> +};
> +
> +extern const struct arch_timer_erratum_workaround *timer_unstable_counter_workaround;
>  
>  #define arch_timer_reg_read_stable(reg) 		\
>  ({							\
>  	u64 _val;					\
> -	if (needs_fsl_a008585_workaround())		\
> -		_val = __fsl_a008585_read_##reg();	\
> +	if (needs_unstable_timer_counter_workaround())		\
> +		_val = timer_unstable_counter_workaround->read_##reg();\
>  	else						\
>  		_val = read_sysreg(reg);		\
>  	_val;						\
> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> index 4866f7a..04c2b93 100644
> --- a/drivers/clocksource/Kconfig
> +++ b/drivers/clocksource/Kconfig
> @@ -325,10 +325,18 @@ config ARM_ARCH_TIMER_EVTSTREAM
>  	  This must be disabled for hardware validation purposes to detect any
>  	  hardware anomalies of missing events.
>  
> +config ARM_ARCH_TIMER_OOL_WORKAROUND
> +	bool "Workaround for arm arch timer unstable counter"

Please drop the message. We don't want that option to be selectable by a
user, but only selected if an erratum that depends on it is enabled.

> +	depends on FSL_ERRATUM_A008585
> +	help
> +	  This option would only be enabled by Freescale/NXP Erratum A-008585
> +	  or something else chip has similar erratum.
> +
>  config FSL_ERRATUM_A008585
>  	bool "Workaround for Freescale/NXP Erratum A-008585"
>  	default y
>  	depends on ARM_ARCH_TIMER && ARM64
> +	select ARM_ARCH_TIMER_OOL_WORKAROUND
>  	help
>  	  This option enables a workaround for Freescale/NXP Erratum
>  	  A-008585 ("ARM generic timer may contain an erroneous

Thanks,

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

^ permalink raw reply

* [PATCH 1/4] ARM: dts: imx7s-warp: Fix watchdog pinmux
From: Fabio Estevam @ 2017-01-19 11:56 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170119090924.19636-2-s.hauer@pengutronix.de>

On Thu, Jan 19, 2017 at 7:09 AM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> The watchdog pin is controlled by the iomuxc_lpsr, not the regular
> iomux, so move it there.
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>

^ permalink raw reply

* [PATCH V7 1/4] Documentation/devicetree/bindings: b850v3_lvds_dp
From: Laurent Pinchart @ 2017-01-19 11:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170119092532.GB29457@collabora.com>

Hi Peter,

On Thursday 19 Jan 2017 10:25:32 Peter Senna Tschudin wrote:
> On Thu, Jan 19, 2017 at 10:17:45AM +0200, Laurent Pinchart wrote:
> > On Thursday 19 Jan 2017 09:12:14 Peter Senna Tschudin wrote:
> >> On Wed, Jan 18, 2017 at 11:10:58PM +0200, Laurent Pinchart wrote:
> >>> On Monday 16 Jan 2017 09:37:11 Peter Senna Tschudin wrote:
> >>>> On Tue, Jan 10, 2017 at 11:04:58PM +0200, Laurent Pinchart wrote:
> >>>>> On Saturday 07 Jan 2017 01:29:52 Peter Senna Tschudin wrote:
> >>>>>> On 04 January, 2017 21:39 CET, Rob Herring wrote:
> >>>>>>> On Tue, Jan 3, 2017 at 5:34 PM, Peter Senna Tschudin wrote:
> >>>>>>>> On 03 January, 2017 23:51 CET, Rob Herring <robh@kernel.org> wrote:
> >>>>>>>>> On Sun, Jan 01, 2017 at 09:24:29PM +0100, Peter Senna Tschudin 
> > wrote:
> >>>>>>>>>> Devicetree bindings documentation for the GE B850v3 LVDS/DP++
> >>>>>>>>>> display bridge.
> >>>>>>>>>> 
> >>>>>>>>>> Cc: Martyn Welch <martyn.welch@collabora.co.uk>
> >>>>>>>>>> Cc: Martin Donnelly <martin.donnelly@ge.com>
> >>>>>>>>>> Cc: Javier Martinez Canillas <javier@dowhile0.org>
> >>>>>>>>>> Cc: Enric Balletbo i Serra <enric.balletbo@collabora.com>
> >>>>>>>>>> Cc: Philipp Zabel <p.zabel@pengutronix.de>
> >>>>>>>>>> Cc: Rob Herring <robh@kernel.org>
> >>>>>>>>>> Cc: Fabio Estevam <fabio.estevam@nxp.com>
> >>>>>>>>>> Signed-off-by: Peter Senna Tschudin <peter.senna@collabora.com>
> >>>>>>>>> ---
> >>>>>>>>>> There was an Acked-by from Rob Herring <robh@kernel.org> for
> >>>>>>>>>> V6, but I changed the bindings to use i2c_new_secondary_device()
> >>>>>>>>>> so I removed it from the commit message.
> >> 
> >> [...]
> >> 
> >>>>>>>>>> .../devicetree/bindings/ge/b850v3-lvds-dp.txt      | 39 +++++++++
> >>>>>>>>> 
> >>>>>>>>> Isn't '-lvds-dp' redundant? The part# should be enough.
> >>>>>>>> 
> >>>>>>>> b850v3 is the name of the product, this is why the proposed name.
> >>>>>>>> What about, b850v3-dp2 dp2 indicating the second DP output?
> >>>>>>> 
> >>>>>> Humm, b850v3 is the board name? This node should be the name of
> >>>>>>> the bridge chip.
> >>>>>> 
> >>>>>> From the cover letter:
> >>>>>> 
> >>>>>> -- // --
> >>>>>> There are two physical bridges on the video signal pipeline: a
> >>>>>> STDP4028(LVDS to DP) and a STDP2690(DP to DP++).  The hardware and
> >>>>>> firmware made it complicated for this binding to comprise two
> >>>>>> device tree nodes, as the design goal is to configure both bridges
> >>>>>> based on the LVDS signal, which leave the driver powerless to control
> >>>>>> the video processing pipeline. The two bridges behaves as a single
> >>>>>> bridge, and the driver is only needed for telling the host about EDID
> >>>>>> / HPD, and for giving the host powers to ack interrupts. The video
> >>>>>> signal pipeline
> >>>>>> 
> >>>>>> is as follows:
> >>>>>>   Host -> LVDS|--(STDP4028)--|DP -> DP|--(STDP2690)--|DP++ -> Video
> >>>>>>   output
> >>>>>> 
> >>>>>> -- // --
> >>>>> 
> >>>>> You forgot to prefix your patch series with [HACK] ;-)
> >>>>> 
> >>>>> How about fixing the issues that make the two DT nodes solution
> >>>>> difficult ? What are they ?
> >>>> 
> >>>> The Firmware and the hardware design. Both bridges, with stock
> >>>> firmware, are fully capable of providig EDID information and handling
> >>>> interrupts. But on this specific design, with this specific firmware, I
> >>>> need to read EDID from one bridge, and handle interrupts on the other.
> >>> 
> >>> Which firmware are you talking about ? Firmware running on the
> >>> bridges, or somewhere else ?
> >> 
> >> Each bridge has it's own external flash containing a binary firmware.
> >> The goal of the firmware is to configure the output end based on the
> >> input end. This is part of what makes handling EDID and HPD challenging.
> >> 
> >>>> Back when I was starting the development I could not come up with a
> >>>> proper way to split EDID and interrupts between two bridges in a way
> >>>> that would result in a fully functional connector. Did I miss
> >>>> something?
> >>> 
> >>> You didn't, we did :-) I've been telling for quite some time now that
> >>> we must decouple bridges from connectors, and this is another example of
> >>> why we have such a need. Bridges should expose additional functions
> >>> needed to implement connector operations, and the connector should be
> >>> instantiated by the display driver with the help of bridge operations.
> >>> You could then create a connector that relies on one bridge to read the
> >>> EDID and on the other bridge to handle HPD.
> >> 
> >> Ah thanks. So for now the single DT node approach is acceptable, right?
> >> The problem is that even if the driver is getting better on each
> >> iteration, the single DT node for two chips issue comes back often and I
> >> believe is _the_ issue preventing the driver from getting upstream. V1
> >> was sent ~ 8 months ago...
> >> 
> >> Can I have some blessing on the single DT node approach for now?
> > 
> > With the "DT as an ABI" approach, I'm afraid not. Temporary hacks are
> > acceptable on the driver side, but you need two nodes in DT.
> 
> So can I make two node DT "in the right way" and work around current
> connectors vs. bridge limitations on the driver side? This seems to be
> doable.
> 
> Then I could fix bridge API, with my own driver and update API clients
> affected by the change...

I'm willing to discuss that as long as the DT bindings are correct, yes.

> >> I'm one of the 3 proposed maintainers for the driver, and I'm willing to
> >> maintain the driver on the long run, as is the same with the other two
> >> proposed maintainers. So when the time to split the node in two comes,
> >> we will be around, and willing to do it ourselves.
> > 
> > How about putting that team of 3 maintainers to work on fixing the problem
> > in the bridge API ? :-)
> 
> Guess you would be a good lawyer! My point was not exactly that we could
> work in parallel. Point was that there is redundancy in case one or two
> of us loose interest. But nice try! :-)
> 
> Chances of having resources to fix bridge API and clients were better 6
> months ago, but let me see what I can get.  Last blocking issue was the
> migration to atomic, now this. I'm going to need to answer what the next
> blocking issue is going to be.
> 
> Actually in these ~8 months one bit of the required changes was
> accepted: dc80d7038883, but this was generic and not related to our
> specific use case.

-- 
Regards,

Laurent Pinchart

^ permalink raw reply

* [PATCH RFC] mmc: mxs-mmc: Implement CMD23 support
From: Ulf Hansson @ 2017-01-19 11:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484414958-2665-1-git-send-email-stefan.wahren@i2se.com>

On 14 January 2017 at 18:29, Stefan Wahren <stefan.wahren@i2se.com> wrote:
> This patch implements support for multiblock transfers bounded
> by SET_BLOCK_COUNT (CMD23) on the MXS MMC host driver.
>
> Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>

Thanks, applied for next!

Kind regards
Uffe

> ---
>  drivers/mmc/host/mxs-mmc.c |   16 ++++++++++++----
>  1 file changed, 12 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
> index c8b8ac6..add1e70 100644
> --- a/drivers/mmc/host/mxs-mmc.c
> +++ b/drivers/mmc/host/mxs-mmc.c
> @@ -153,7 +153,11 @@ static void mxs_mmc_request_done(struct mxs_mmc_host *host)
>                 }
>         }
>
> -       if (data) {
> +       if (cmd == mrq->sbc) {
> +               /* Finished CMD23, now send actual command. */
> +               mxs_mmc_start_cmd(host, mrq->cmd);
> +               return;
> +       } else if (data) {
>                 dma_unmap_sg(mmc_dev(host->mmc), data->sg,
>                              data->sg_len, ssp->dma_dir);
>                 /*
> @@ -166,7 +170,7 @@ static void mxs_mmc_request_done(struct mxs_mmc_host *host)
>                         data->bytes_xfered = 0;
>
>                 host->data = NULL;
> -               if (mrq->stop) {
> +               if (data->stop && (data->error || !mrq->sbc)) {
>                         mxs_mmc_start_cmd(host, mrq->stop);
>                         return;
>                 }
> @@ -495,7 +499,11 @@ static void mxs_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
>
>         WARN_ON(host->mrq != NULL);
>         host->mrq = mrq;
> -       mxs_mmc_start_cmd(host, mrq->cmd);
> +
> +       if (mrq->sbc)
> +               mxs_mmc_start_cmd(host, mrq->sbc);
> +       else
> +               mxs_mmc_start_cmd(host, mrq->cmd);
>  }
>
>  static void mxs_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
> @@ -642,7 +650,7 @@ static int mxs_mmc_probe(struct platform_device *pdev)
>         /* set mmc core parameters */
>         mmc->ops = &mxs_mmc_ops;
>         mmc->caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED |
> -                   MMC_CAP_SDIO_IRQ | MMC_CAP_NEEDS_POLL;
> +                   MMC_CAP_SDIO_IRQ | MMC_CAP_NEEDS_POLL | MMC_CAP_CMD23;
>
>         host->broken_cd = of_property_read_bool(np, "broken-cd");
>
> --
> 1.7.9.5
>

^ permalink raw reply

* [PATCH RESEND v8 4/4] arm64: arch timer: Add timer erratum property for Hip05-d02 and Hip06-d03
From: Ding Tianhong @ 2017-01-19 11:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484826406-16348-1-git-send-email-dingtianhong@huawei.com>

Enable workaround for hisilicon erratum 161010101 on Hip05-d02 and Hip06-d03 board.

Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
---
 arch/arm64/boot/dts/hisilicon/hip05.dtsi | 1 +
 arch/arm64/boot/dts/hisilicon/hip06.dtsi | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/hisilicon/hip05.dtsi b/arch/arm64/boot/dts/hisilicon/hip05.dtsi
index 4b472a3..6b76f3a 100644
--- a/arch/arm64/boot/dts/hisilicon/hip05.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hip05.dtsi
@@ -281,6 +281,7 @@
 			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
 			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
 			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+		hisilicon,erratum-161010101;
 	};
 
 	pmu {
diff --git a/arch/arm64/boot/dts/hisilicon/hip06.dtsi b/arch/arm64/boot/dts/hisilicon/hip06.dtsi
index a049b64..cf8b9db 100644
--- a/arch/arm64/boot/dts/hisilicon/hip06.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hip06.dtsi
@@ -260,6 +260,7 @@
 			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
 			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
 			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+		hisilicon,erratum-161010101;
 	};
 
 	pmu {
-- 
1.9.0

^ permalink raw reply related

* [PATCH RESEND v8 3/4] arm64: arch_timer: Work around Erratum Hisilicon-161010101
From: Ding Tianhong @ 2017-01-19 11:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484826406-16348-1-git-send-email-dingtianhong@huawei.com>

Erratum Hisilicon-161010101 says that the ARM generic timer counter "has the
potential to contain an erroneous value when the timer value changes".
Accesses to TVAL (both read and write) are also affected due to the implicit counter
read.  Accesses to CVAL are not affected.

The workaround is to reread the system count registers until the value of the second
read is larger than the first one by less than 32, the system counter can be guaranteed
not to return wrong value twice by back-to-back read and the error value is always larger
than the correct one by 32. Writes to TVAL are replaced with an equivalent write to CVAL.

The hisilicon erratum CONFIG name is too long, breaking the line format in silicon-errata.txt,
so extended the character spacing to fit all the erratum config.

Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
---
 Documentation/arm64/silicon-errata.txt | 43 ++++++++++++++---------------
 drivers/clocksource/Kconfig            | 12 ++++++++-
 drivers/clocksource/arm_arch_timer.c   | 49 ++++++++++++++++++++++++++++++++++
 3 files changed, 82 insertions(+), 22 deletions(-)

diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt
index 405da11..0aaae35 100644
--- a/Documentation/arm64/silicon-errata.txt
+++ b/Documentation/arm64/silicon-errata.txt
@@ -42,24 +42,25 @@ file acts as a registry of software workarounds in the Linux Kernel and
 will be updated when new workarounds are committed and backported to
 stable kernels.
 
-| Implementor    | Component       | Erratum ID      | Kconfig                 |
-+----------------+-----------------+-----------------+-------------------------+
-| ARM            | Cortex-A53      | #826319         | ARM64_ERRATUM_826319    |
-| ARM            | Cortex-A53      | #827319         | ARM64_ERRATUM_827319    |
-| ARM            | Cortex-A53      | #824069         | ARM64_ERRATUM_824069    |
-| ARM            | Cortex-A53      | #819472         | ARM64_ERRATUM_819472    |
-| ARM            | Cortex-A53      | #845719         | ARM64_ERRATUM_845719    |
-| ARM            | Cortex-A53      | #843419         | ARM64_ERRATUM_843419    |
-| ARM            | Cortex-A57      | #832075         | ARM64_ERRATUM_832075    |
-| ARM            | Cortex-A57      | #852523         | N/A                     |
-| ARM            | Cortex-A57      | #834220         | ARM64_ERRATUM_834220    |
-| ARM            | Cortex-A72      | #853709         | N/A                     |
-| ARM            | MMU-500         | #841119,#826419 | N/A                     |
-|                |                 |                 |                         |
-| Cavium         | ThunderX ITS    | #22375, #24313  | CAVIUM_ERRATUM_22375    |
-| Cavium         | ThunderX ITS    | #23144          | CAVIUM_ERRATUM_23144    |
-| Cavium         | ThunderX GICv3  | #23154          | CAVIUM_ERRATUM_23154    |
-| Cavium         | ThunderX Core   | #27456          | CAVIUM_ERRATUM_27456    |
-| Cavium         | ThunderX SMMUv2 | #27704          | N/A		       |
-|                |                 |                 |                         |
-| Freescale/NXP  | LS2080A/LS1043A | A-008585        | FSL_ERRATUM_A008585     |
+| Implementor    | Component       | Erratum ID      | Kconfig                         |
++----------------+-----------------+-----------------+---------------------------------+
+| ARM            | Cortex-A53      | #826319         | ARM64_ERRATUM_826319            |
+| ARM            | Cortex-A53      | #827319         | ARM64_ERRATUM_827319            |
+| ARM            | Cortex-A53      | #824069         | ARM64_ERRATUM_824069            |
+| ARM            | Cortex-A53      | #819472         | ARM64_ERRATUM_819472            |
+| ARM            | Cortex-A53      | #845719         | ARM64_ERRATUM_845719            |
+| ARM            | Cortex-A53      | #843419         | ARM64_ERRATUM_843419            |
+| ARM            | Cortex-A57      | #832075         | ARM64_ERRATUM_832075            |
+| ARM            | Cortex-A57      | #852523         | N/A                             |
+| ARM            | Cortex-A57      | #834220         | ARM64_ERRATUM_834220            |
+| ARM            | Cortex-A72      | #853709         | N/A                             |
+| ARM            | MMU-500         | #841119,#826419 | N/A                             |
+|                |                 |                 |                                 |
+| Cavium         | ThunderX ITS    | #22375, #24313  | CAVIUM_ERRATUM_22375            |
+| Cavium         | ThunderX ITS    | #23144          | CAVIUM_ERRATUM_23144            |
+| Cavium         | ThunderX GICv3  | #23154          | CAVIUM_ERRATUM_23154            |
+| Cavium         | ThunderX Core   | #27456          | CAVIUM_ERRATUM_27456            |
+| Cavium         | ThunderX SMMUv2 | #27704          | N/A                             |
+|                |                 |                 |                                 |
+| Freescale/NXP  | LS2080A/LS1043A | A-008585        | FSL_ERRATUM_A008585             |
+| Hisilicon      | Hip0{5,6,7}     | #161010101      | HISILICON_ERRATUM_161010101     |
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 04c2b93..628cb44 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -327,7 +327,7 @@ config ARM_ARCH_TIMER_EVTSTREAM
 
 config ARM_ARCH_TIMER_OOL_WORKAROUND
 	bool "Workaround for arm arch timer unstable counter"
-	depends on FSL_ERRATUM_A008585
+	depends on FSL_ERRATUM_A008585 || HISILICON_ERRATUM_161010101
 	help
 	  This option would only be enabled by Freescale/NXP Erratum A-008585
 	  or something else chip has similar erratum.
@@ -343,6 +343,16 @@ config FSL_ERRATUM_A008585
 	  value").  The workaround will only be active if the
 	  fsl,erratum-a008585 property is found in the timer node.
 
+config HISILICON_ERRATUM_161010101
+	bool "Workaround for Hisilicon Erratum 161010101"
+	default y
+	select ARM_ARCH_TIMER_OOL_WORKAROUND
+	depends on ARM_ARCH_TIMER && ARM64
+	help
+	  This option enables a workaround for Hisilicon Erratum
+	  161010101. The workaround will be active if the hisilicon,erratum-161010101
+	  property is found in the timer node.
+
 config ARM_GLOBAL_TIMER
 	bool "Support for the ARM global timer" if COMPILE_TEST
 	select CLKSRC_OF if OF
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 2487c66..7451b62 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -131,6 +131,47 @@ static u64 notrace fsl_a008585_read_cntvct_el0(void)
 }
 #endif
 
+#ifdef CONFIG_HISILICON_ERRATUM_161010101
+/*
+ * Verify whether the value of the second read is larger than the first by
+ * less than 32 is the only way to confirm the value is correct, so clear the
+ * lower 5 bits to check whether the difference is greater than 32 or not.
+ * Theoretically the erratum should not occur more than twice in succession
+ * when reading the system counter, but it is possible that some interrupts
+ * may lead to more than twice read errors, triggering the warning, so setting
+ * the number of retries far beyond the number of iterations the loop has been
+ * observed to take.
+ */
+#define __hisi_161010101_read_reg(reg) ({				\
+	u64 _old, _new;						\
+	int _retries = 50;					\
+								\
+	do {							\
+		_old = read_sysreg(reg);			\
+		_new = read_sysreg(reg);			\
+		_retries--;					\
+	} while (unlikely((_new - _old) >> 5) && _retries);	\
+								\
+	WARN_ON_ONCE(!_retries);				\
+	_new;							\
+})
+
+static u32 notrace hisi_161010101_read_cntp_tval_el0(void)
+{
+	return __hisi_161010101_read_reg(cntp_tval_el0);
+}
+
+static u32 notrace hisi_161010101_read_cntv_tval_el0(void)
+{
+	return __hisi_161010101_read_reg(cntv_tval_el0);
+}
+
+static u64 notrace hisi_161010101_read_cntvct_el0(void)
+{
+	return __hisi_161010101_read_reg(cntvct_el0);
+}
+#endif
+
 #ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
 const struct arch_timer_erratum_workaround *timer_unstable_counter_workaround = NULL;
 EXPORT_SYMBOL_GPL(timer_unstable_counter_workaround);
@@ -147,6 +188,14 @@ static u64 notrace fsl_a008585_read_cntvct_el0(void)
 		.read_cntvct_el0 = fsl_a008585_read_cntvct_el0,
 	},
 #endif
+#ifdef CONFIG_HISILICON_ERRATUM_161010101
+	{
+		.id = "hisilicon,erratum-161010101",
+		.read_cntp_tval_el0 = hisi_161010101_read_cntp_tval_el0,
+		.read_cntv_tval_el0 = hisi_161010101_read_cntv_tval_el0,
+		.read_cntvct_el0 = hisi_161010101_read_cntvct_el0,
+	},
+#endif
 };
 #endif /* CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND */
 
-- 
1.9.0

^ permalink raw reply related

* [PATCH RESEND v8 2/4] arm64: arch_timer: Introduce a generic erratum handing mechanism for fsl-a008585
From: Ding Tianhong @ 2017-01-19 11:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484826406-16348-1-git-send-email-dingtianhong@huawei.com>

The workaround for hisilicon,161010101 will check the return value of the system counter
by different way, in order to distinguish with the fsl-a008585 workaround, introduce
a new generic erratum handing mechanism for fsl-a008585 and rename some functions.

After discussion with Marc and Will, a consensus decision was made to remove the commandline
parameter for enabling fsl,erratum-a008585 erratum.

Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
---
 Documentation/admin-guide/kernel-parameters.txt |   9 --
 arch/arm64/include/asm/arch_timer.h             |  38 +++------
 drivers/clocksource/Kconfig                     |   8 ++
 drivers/clocksource/arm_arch_timer.c            | 105 ++++++++++++++----------
 4 files changed, 84 insertions(+), 76 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 21e2d88..76437ad 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -539,15 +539,6 @@
 			loops can be debugged more effectively on production
 			systems.
 
-	clocksource.arm_arch_timer.fsl-a008585=
-			[ARM64]
-			Format: <bool>
-			Enable/disable the workaround of Freescale/NXP
-			erratum A-008585.  This can be useful for KVM
-			guests, if the guest device tree doesn't show the
-			erratum.  If unspecified, the workaround is
-			enabled based on the device tree.
-
 	clearcpuid=BITNUM [X86]
 			Disable CPUID feature X for the kernel. See
 			arch/x86/include/asm/cpufeatures.h for the valid bit
diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index eaa5bbe..b4b3400 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -29,41 +29,29 @@
 
 #include <clocksource/arm_arch_timer.h>
 
-#if IS_ENABLED(CONFIG_FSL_ERRATUM_A008585)
+#if IS_ENABLED(CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND)
 extern struct static_key_false arch_timer_read_ool_enabled;
-#define needs_fsl_a008585_workaround() \
+#define needs_unstable_timer_counter_workaround() \
 	static_branch_unlikely(&arch_timer_read_ool_enabled)
 #else
-#define needs_fsl_a008585_workaround()  false
+#define needs_unstable_timer_counter_workaround()  false
 #endif
 
-u32 __fsl_a008585_read_cntp_tval_el0(void);
-u32 __fsl_a008585_read_cntv_tval_el0(void);
-u64 __fsl_a008585_read_cntvct_el0(void);
 
-/*
- * The number of retries is an arbitrary value well beyond the highest number
- * of iterations the loop has been observed to take.
- */
-#define __fsl_a008585_read_reg(reg) ({			\
-	u64 _old, _new;					\
-	int _retries = 200;				\
-							\
-	do {						\
-		_old = read_sysreg(reg);		\
-		_new = read_sysreg(reg);		\
-		_retries--;				\
-	} while (unlikely(_old != _new) && _retries);	\
-							\
-	WARN_ON_ONCE(!_retries);			\
-	_new;						\
-})
+struct arch_timer_erratum_workaround {
+	const char *id;		/* Indicate the Erratum ID */
+	u32 (*read_cntp_tval_el0)(void);
+	u32 (*read_cntv_tval_el0)(void);
+	u64 (*read_cntvct_el0)(void);
+};
+
+extern const struct arch_timer_erratum_workaround *timer_unstable_counter_workaround;
 
 #define arch_timer_reg_read_stable(reg) 		\
 ({							\
 	u64 _val;					\
-	if (needs_fsl_a008585_workaround())		\
-		_val = __fsl_a008585_read_##reg();	\
+	if (needs_unstable_timer_counter_workaround())		\
+		_val = timer_unstable_counter_workaround->read_##reg();\
 	else						\
 		_val = read_sysreg(reg);		\
 	_val;						\
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 4866f7a..04c2b93 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -325,10 +325,18 @@ config ARM_ARCH_TIMER_EVTSTREAM
 	  This must be disabled for hardware validation purposes to detect any
 	  hardware anomalies of missing events.
 
+config ARM_ARCH_TIMER_OOL_WORKAROUND
+	bool "Workaround for arm arch timer unstable counter"
+	depends on FSL_ERRATUM_A008585
+	help
+	  This option would only be enabled by Freescale/NXP Erratum A-008585
+	  or something else chip has similar erratum.
+
 config FSL_ERRATUM_A008585
 	bool "Workaround for Freescale/NXP Erratum A-008585"
 	default y
 	depends on ARM_ARCH_TIMER && ARM64
+	select ARM_ARCH_TIMER_OOL_WORKAROUND
 	help
 	  This option enables a workaround for Freescale/NXP Erratum
 	  A-008585 ("ARM generic timer may contain an erroneous
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 02fef68..2487c66 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -96,41 +96,59 @@ static int __init early_evtstrm_cfg(char *buf)
  */
 
 #ifdef CONFIG_FSL_ERRATUM_A008585
-DEFINE_STATIC_KEY_FALSE(arch_timer_read_ool_enabled);
-EXPORT_SYMBOL_GPL(arch_timer_read_ool_enabled);
-
-static int fsl_a008585_enable = -1;
-
-static int __init early_fsl_a008585_cfg(char *buf)
-{
-	int ret;
-	bool val;
 
-	ret = strtobool(buf, &val);
-	if (ret)
-		return ret;
-
-	fsl_a008585_enable = val;
-	return 0;
-}
-early_param("clocksource.arm_arch_timer.fsl-a008585", early_fsl_a008585_cfg);
-
-u32 __fsl_a008585_read_cntp_tval_el0(void)
+/*
+ * The number of retries is an arbitrary value well beyond the highest number
+ * of iterations the loop has been observed to take.
+ */
+#define __fsl_a008585_read_reg(reg) ({			\
+	u64 _old, _new;					\
+	int _retries = 200;				\
+							\
+	do {						\
+		_old = read_sysreg(reg);		\
+		_new = read_sysreg(reg);		\
+		_retries--;				\
+	} while (unlikely(_old != _new) && _retries);	\
+							\
+	WARN_ON_ONCE(!_retries);			\
+	_new;						\
+})
+
+static u32 notrace fsl_a008585_read_cntp_tval_el0(void)
 {
 	return __fsl_a008585_read_reg(cntp_tval_el0);
 }
 
-u32 __fsl_a008585_read_cntv_tval_el0(void)
+static u32 notrace fsl_a008585_read_cntv_tval_el0(void)
 {
 	return __fsl_a008585_read_reg(cntv_tval_el0);
 }
 
-u64 __fsl_a008585_read_cntvct_el0(void)
+static u64 notrace fsl_a008585_read_cntvct_el0(void)
 {
 	return __fsl_a008585_read_reg(cntvct_el0);
 }
-EXPORT_SYMBOL(__fsl_a008585_read_cntvct_el0);
-#endif /* CONFIG_FSL_ERRATUM_A008585 */
+#endif
+
+#ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
+const struct arch_timer_erratum_workaround *timer_unstable_counter_workaround = NULL;
+EXPORT_SYMBOL_GPL(timer_unstable_counter_workaround);
+
+DEFINE_STATIC_KEY_FALSE(arch_timer_read_ool_enabled);
+EXPORT_SYMBOL_GPL(arch_timer_read_ool_enabled);
+
+static const struct arch_timer_erratum_workaround ool_workarounds[] = {
+#ifdef CONFIG_FSL_ERRATUM_A008585
+	{
+		.id = "fsl,erratum-a008585",
+		.read_cntp_tval_el0 = fsl_a008585_read_cntp_tval_el0,
+		.read_cntv_tval_el0 = fsl_a008585_read_cntv_tval_el0,
+		.read_cntvct_el0 = fsl_a008585_read_cntvct_el0,
+	},
+#endif
+};
+#endif /* CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND */
 
 static __always_inline
 void arch_timer_reg_write(int access, enum arch_timer_reg reg, u32 val,
@@ -281,8 +299,8 @@ static __always_inline void set_next_event(const int access, unsigned long evt,
 	arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
 }
 
-#ifdef CONFIG_FSL_ERRATUM_A008585
-static __always_inline void fsl_a008585_set_next_event(const int access,
+#ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
+static __always_inline void erratum_set_next_event_generic(const int access,
 		unsigned long evt, struct clock_event_device *clk)
 {
 	unsigned long ctrl;
@@ -300,20 +318,20 @@ static __always_inline void fsl_a008585_set_next_event(const int access,
 	arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
 }
 
-static int fsl_a008585_set_next_event_virt(unsigned long evt,
+static int erratum_set_next_event_virt(unsigned long evt,
 					   struct clock_event_device *clk)
 {
-	fsl_a008585_set_next_event(ARCH_TIMER_VIRT_ACCESS, evt, clk);
+	erratum_set_next_event_generic(ARCH_TIMER_VIRT_ACCESS, evt, clk);
 	return 0;
 }
 
-static int fsl_a008585_set_next_event_phys(unsigned long evt,
+static int erratum_set_next_event_phys(unsigned long evt,
 					   struct clock_event_device *clk)
 {
-	fsl_a008585_set_next_event(ARCH_TIMER_PHYS_ACCESS, evt, clk);
+	erratum_set_next_event_generic(ARCH_TIMER_PHYS_ACCESS, evt, clk);
 	return 0;
 }
-#endif /* CONFIG_FSL_ERRATUM_A008585 */
+#endif /* CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND */
 
 static int arch_timer_set_next_event_virt(unsigned long evt,
 					  struct clock_event_device *clk)
@@ -343,16 +361,16 @@ static int arch_timer_set_next_event_phys_mem(unsigned long evt,
 	return 0;
 }
 
-static void fsl_a008585_set_sne(struct clock_event_device *clk)
+static void erratum_workaround_set_sne(struct clock_event_device *clk)
 {
-#ifdef CONFIG_FSL_ERRATUM_A008585
+#ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
 	if (!static_branch_unlikely(&arch_timer_read_ool_enabled))
 		return;
 
 	if (arch_timer_uses_ppi == VIRT_PPI)
-		clk->set_next_event = fsl_a008585_set_next_event_virt;
+		clk->set_next_event = erratum_set_next_event_virt;
 	else
-		clk->set_next_event = fsl_a008585_set_next_event_phys;
+		clk->set_next_event = erratum_set_next_event_phys;
 #endif
 }
 
@@ -385,7 +403,7 @@ static void __arch_timer_setup(unsigned type,
 			BUG();
 		}
 
-		fsl_a008585_set_sne(clk);
+		erratum_workaround_set_sne(clk);
 	} else {
 		clk->features |= CLOCK_EVT_FEAT_DYNIRQ;
 		clk->name = "arch_mem_timer";
@@ -605,7 +623,7 @@ static void __init arch_counter_register(unsigned type)
 
 		clocksource_counter.archdata.vdso_direct = true;
 
-#ifdef CONFIG_FSL_ERRATUM_A008585
+#ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
 		/*
 		 * Don't use the vdso fastpath if errata require using
 		 * the out-of-line counter accessor.
@@ -893,12 +911,15 @@ static int __init arch_timer_of_init(struct device_node *np)
 
 	arch_timer_c3stop = !of_property_read_bool(np, "always-on");
 
-#ifdef CONFIG_FSL_ERRATUM_A008585
-	if (fsl_a008585_enable < 0)
-		fsl_a008585_enable = of_property_read_bool(np, "fsl,erratum-a008585");
-	if (fsl_a008585_enable) {
-		static_branch_enable(&arch_timer_read_ool_enabled);
-		pr_info("Enabling workaround for FSL erratum A-008585\n");
+#ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
+	for (i = 0; i < ARRAY_SIZE(ool_workarounds); i++) {
+		if (of_property_read_bool(np, ool_workarounds[i].id)) {
+			timer_unstable_counter_workaround = &ool_workarounds[i];
+			static_branch_enable(&arch_timer_read_ool_enabled);
+			pr_info("arch_timer: Enabling workaround for %s\n",
+				timer_unstable_counter_workaround->id);
+			break;
+		}
 	}
 #endif
 
-- 
1.9.0

^ permalink raw reply related

* [PATCH RESEND v8 1/4] arm64: arch_timer: Add device tree binding for hisilicon-161010101 erratum
From: Ding Tianhong @ 2017-01-19 11:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484826406-16348-1-git-send-email-dingtianhong@huawei.com>

This erratum describes a bug in logic outside the core, so MIDR can't be
used to identify its presence, and reading an SoC-specific revision
register from common arch timer code would be awkward.  So, describe it
in the device tree.

Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
Acked-by: Rob Herring <robh@kernel.org>
---
 Documentation/devicetree/bindings/arm/arch_timer.txt | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/arch_timer.txt b/Documentation/devicetree/bindings/arm/arch_timer.txt
index ad440a2..9116934 100644
--- a/Documentation/devicetree/bindings/arm/arch_timer.txt
+++ b/Documentation/devicetree/bindings/arm/arch_timer.txt
@@ -31,6 +31,14 @@ to deliver its interrupts via SPIs.
   This also affects writes to the tval register, due to the implicit
   counter read.
 
+- hisilicon,erratum-161010101 : A boolean property. Indicates the presence of
+  erratum 161010101, which says that reading the counter is unreliable unless
+  reading twice on the register and the value of the second read is larger
+  than the first by less than 32. If the verification is unsuccessful, then
+  discard the value of this read and repeat this procedure until the verification
+  is successful.  This also affects writes to the tval register, due to the
+  implicit counter read.
+
 ** Optional properties:
 
 - arm,cpu-registers-not-fw-configured : Firmware does not initialize
-- 
1.9.0

^ permalink raw reply related

* [PATCH RESEND v8 0/4] arm64: arch_timer: Add workaround for hisilicon-161010101 erratum
From: Ding Tianhong @ 2017-01-19 11:46 UTC (permalink / raw)
  To: linux-arm-kernel

Erratum Hisilicon-161010101 says that the ARM generic timer counter "has the
potential to contain an erroneous value when the timer value changes".
Accesses to TVAL (both read and write) are also affected due to the implicit counter
read.  Accesses to CVAL are not affected.

The workaround is to reread the system count registers until the value of the second
read is larger than the first one by less than 32, the system counter can be guaranteed
not to return wrong value twice by back-to-back read and the error value is always larger
than the correct one by 32. Writes to TVAL are replaced with an equivalent write to CVAL.

v2: Introducing a new generic erratum handling mechanism for fsl,a008585 and hisilicon,161601.
    Significant rework based on feedback, including seperate the fsl erratum a008585
    to another patch, update the erratum name and remove unwanted code.

v3: Introducing the erratum_workaround_set_sne generic function for fsl erratum a008585
    and make the #define __fsl_a008585_read_reg to be private to the .c file instead of
    being globally visible. After discussion with Marc and Will, a consensus decision was
    made to remove the commandline parameter for enabling fsl,erratum-a008585 erratum,
    and make some generic name more specific, export timer_unstable_counter_workaround
    for module access.
    
    Significant rework based on feedback, including fix some alignment problem, make the
    #define __hisi_161601_read_reg to be private to the .c file instead of being globally
    visible, add more accurate annotation and modify a bit of logical format to enable
    arch_timer_read_ool_enabled, remove the kernel commandline parameter
    clocksource.arm_arch_timer.hisilicon-161601.

    Introduce a generic aquick framework for erratum in ACPI mode.

v4: rename the quirk handler parameter to make it more generic, and
    avoid break loop when handling the quirk becasue it need to
    support multi quirks handler.

    update some data structures for acpi mode. 

v5: Adapt the new kernel-parameters.txt for latest kernel version.
    Set the retries of reread system counter to 50, because it is possible 
    that some interrupts may lead to more than twice read errors and break the loop,
    it will trigger the warning, so we set the number of retries far beyond the number of
    iterations the loop has been observed to take.

v6: The last 2 patches in the previous version about the ACPI mode will conflict witch Fuwei's
    GTDT patches, so remove the ACPI part and only support the DT base code for this patch set.

    We have trigger a bug when select the CONFIG_FUNCTION_GRAPH_TRACER and enable function_graph
    to /sys/kernel/debug/tracing/current_tracer, the system will stall into an endless loop, it looks
    like that the ftrace_graph_caller will be related to xxx.read_cntvct_el0 and read the system counter
    again, so mark the xxx.read_cntvct_el0 with notrace to fix the problem.

v7: Introduce a new general config symbol named CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND to enable the workaround
    for any chips which has similar arch timer erratum just like "fsl,erratum_a008585" and "hisilicon,erratum_161601",
    modify the struct arch_timer_erratum_workaround to be compatible different chip erratum more easily, and
    reconstruction some code base on the new config symbol and struct, thanks to Marc's suggestion. 

v8: The original erratum ID could not cover all modules, which only specified <Errata-Prefix><SerialNum>, so after
    discussion with the soc team, we decide to use the new ID "161010101" for this timer erratum which consist of
    <Errata-Prefix><SeriesFlag><ModuleID><SerialNum> and also update the hisilicon erratum official documents.

Ding Tianhong (4):
  arm64: arch_timer: Add device tree binding for hisilicon-161010101
    erratum
  arm64: arch_timer: Introduce a generic erratum handing mechanism for
    fsl-a008585
  arm64: arch_timer: Work around Erratum Hisilicon-161010101
  arm64: arch timer: Add timer erratum property for Hip05-d02 and
    Hip06-d03

 Documentation/admin-guide/kernel-parameters.txt    |   9 --
 Documentation/arm64/silicon-errata.txt             |  43 +++---
 .../devicetree/bindings/arm/arch_timer.txt         |   8 ++
 arch/arm64/boot/dts/hisilicon/hip05.dtsi           |   1 +
 arch/arm64/boot/dts/hisilicon/hip06.dtsi           |   1 +
 arch/arm64/include/asm/arch_timer.h                |  38 ++----
 drivers/clocksource/Kconfig                        |  18 +++
 drivers/clocksource/arm_arch_timer.c               | 150 +++++++++++++++------
 8 files changed, 173 insertions(+), 95 deletions(-)

-- 
1.9.0

^ permalink raw reply

* [PATCH 2/2] security: Change name of CONFIG_DEBUG_SET_MODULE_RONX
From: Robin Murphy @ 2017-01-19 11:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484789346-21012-3-git-send-email-labbott@redhat.com>

Hi Laura,

On 19/01/17 01:29, Laura Abbott wrote:
> 
> Despite the word 'debug' in CONFIG_DEBUG_SET_MODULE_RONX, this kernel
> option provides key security features that are to be expected on a
> modern system. Change the name to CONFIG_HARDENED_MODULE_MAPPINGS which
> more accurately describes what this option is intended to do.
> 
> Signed-off-by: Laura Abbott <labbott@redhat.com>
> ---

[...]

> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 09aff28..ef852e4 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -8,6 +8,7 @@ config ARM
>  	select ARCH_HAVE_CUSTOM_GPIO_H
>  	select ARCH_HAS_GCOV_PROFILE_ALL
>  	select ARCH_HAS_HARDENED_MAPPINGS if MMU && !XIP_KERNEL
> +	select ARCH_HAS_HARDENED_MODULE_MAPPINGS if MMU
>  	select ARCH_MIGHT_HAVE_PC_PARPORT
>  	select ARCH_SUPPORTS_ATOMIC_RMW
>  	select ARCH_USE_BUILTIN_BSWAP
> diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
> index d83f7c3..426d271 100644
> --- a/arch/arm/Kconfig.debug
> +++ b/arch/arm/Kconfig.debug
> @@ -1738,17 +1738,6 @@ config PID_IN_CONTEXTIDR
>  	  additional instructions during context switch. Say Y here only if you
>  	  are planning to use hardware trace tools with this kernel.
>  
> -config DEBUG_SET_MODULE_RONX
> -	bool "Set loadable kernel module data as NX and text as RO"
> -	depends on MODULES && MMU
> -	---help---
> -	  This option helps catch unintended modifications to loadable
> -	  kernel module's text and read-only data. It also prevents execution
> -	  of module data. Such protection may interfere with run-time code
> -	  patching and dynamic kernel tracing - and they might also protect
> -	  against certain classes of kernel exploits.
> -	  If in doubt, say "N".
> -
>  source "drivers/hwtracing/coresight/Kconfig"
>  
>  endmenu

[...]

> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -12,6 +12,7 @@ config ARM64
>  	select ARCH_HAS_GCOV_PROFILE_ALL
>  	select ARCH_HAS_GIGANTIC_PAGE
>  	select ARCH_HAS_HARDENED_MAPPINGS
> +	select ARCH_HAS_HARDENED_MODULE_MAPPINGS
>  	select ARCH_HAS_KCOV
>  	select ARCH_HAS_SG_CHAIN
>  	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
> diff --git a/arch/arm64/Kconfig.debug b/arch/arm64/Kconfig.debug
> index a26d27f..1eebe1f 100644
> --- a/arch/arm64/Kconfig.debug
> +++ b/arch/arm64/Kconfig.debug
> @@ -71,17 +71,6 @@ config DEBUG_WX
>  
>  	  If in doubt, say "Y".
>  
> -config DEBUG_SET_MODULE_RONX
> -	bool "Set loadable kernel module data as NX and text as RO"
> -	depends on MODULES
> -	default y
> -	help
> -	  Is this is set, kernel module text and rodata will be made read-only.
> -	  This is to help catch accidental or malicious attempts to change the
> -	  kernel's executable code.
> -
> -	  If in doubt, say Y.
> -
>  config DEBUG_ALIGN_RODATA
>  	depends on ARCH_HAS_HARDENED_MAPPINGS
>  	bool "Align linker sections up to SECTION_SIZE"

[...]

> --- a/arch/s390/Kconfig
> +++ b/arch/s390/Kconfig
> @@ -69,6 +69,7 @@ config S390
>  	select ARCH_HAS_GCOV_PROFILE_ALL
>  	select ARCH_HAS_GIGANTIC_PAGE
>  	select ARCH_HAS_HARDENED_MAPPINGS
> +	select ARCH_HAS_HARDENED_MODULE_MAPPINGS
>  	select ARCH_HAS_KCOV
>  	select ARCH_HAS_SG_CHAIN
>  	select ARCH_HAS_UBSAN_SANITIZE_ALL
> diff --git a/arch/s390/Kconfig.debug b/arch/s390/Kconfig.debug
> index 26c5d5be..57f8ea9 100644
> --- a/arch/s390/Kconfig.debug
> +++ b/arch/s390/Kconfig.debug
> @@ -17,7 +17,4 @@ config S390_PTDUMP
>  	  kernel.
>  	  If in doubt, say "N"
>  
> -config DEBUG_SET_MODULE_RONX
> -	def_bool y
> -	depends on MODULES
>  endmenu
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index 9d80cd8..38ce850 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -51,6 +51,7 @@ config X86
>  	select ARCH_HAS_FAST_MULTIPLIER
>  	select ARCH_HAS_GCOV_PROFILE_ALL
>  	select ARCH_HAS_HARDENED_MAPPINGS
> +	select ARCH_HAS_HARDENED_MODULE_MAPPINGS
>  	select ARCH_HAS_KCOV			if X86_64
>  	select ARCH_HAS_MMIO_FLUSH
>  	select ARCH_HAS_PMEM_API		if X86_64
> diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
> index 67eec55..69cdd0b 100644
> --- a/arch/x86/Kconfig.debug
> +++ b/arch/x86/Kconfig.debug
> @@ -109,17 +109,6 @@ config DEBUG_WX
>  
>  	  If in doubt, say "Y".
>  
> -config DEBUG_SET_MODULE_RONX
> -	bool "Set loadable kernel module data as NX and text as RO"
> -	depends on MODULES
> -	---help---
> -	  This option helps catch unintended modifications to loadable
> -	  kernel module's text and read-only data. It also prevents execution
> -	  of module data. Such protection may interfere with run-time code
> -	  patching and dynamic kernel tracing - and they might also protect
> -	  against certain classes of kernel exploits.
> -	  If in doubt, say "N".
> -
>  config DEBUG_NX_TEST
>  	tristate "Testcase for the NX non-executable stack feature"
>  	depends on DEBUG_KERNEL && m

[...]

> --- a/security/Kconfig
> +++ b/security/Kconfig
> @@ -174,6 +174,22 @@ config HARDENED_PAGE_MAPPINGS
>  	  Unless your system has known restrictions or performance issues, it
>  	  is recommended to say Y here.
>  
> +config ARCH_HAS_HARDENED_MODULE_MAPPINGS
> +	def_bool n
> +
> +config HARDENED_MODULE_MAPPINGS
> +	bool "Mark module mappings with stricter permissions (RO/W^X)"
> +	default y
> +	depends on ARCH_HAS_HARDENED_MODULE_MAPPINGS

It would seem that this ends up losing the previous dependency on
MODULES - is that intentional?

Robin.

> +	help
> +	  If this is set, module text and rodata memory will be made read-only,
> +	  and non-text memory will be made non-executable. This provides
> +	  protection against certain security vulnerabilities (e.g. modifying
> +	  code)
> +
> +	  Unless your system has known restrictions or performance issues, it
> +	  is recommended to say Y here.
> +
>  source security/selinux/Kconfig
>  source security/smack/Kconfig
>  source security/tomoyo/Kconfig
> 

^ permalink raw reply

* [PATCH] coresight: STM: Balance enable/disable
From: Greg KH @ 2017-01-19 11:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484589600-21397-1-git-send-email-suzuki.poulose@arm.com>

On Mon, Jan 16, 2017 at 06:00:00PM +0000, Suzuki K Poulose wrote:
> The stm is automatically enabled when an application sets the policy
> via ->link() call back by using coresight_enable(), which keeps the
> refcount of the current users of the STM. However, the unlink() callback
> issues stm_disable() directly, which leaves the STM turned off, without
> the coresight layer knowing about it. This prevents any further uses
> of the STM hardware as the coresight layer still thinks the STM is
> turned on and doesn't enable the hardware when required. Even manually
> enabling the STM via sysfs can't really enable the hw.
> 
> e.g,
> 
>  $ echo 1 > $CS_DEVS/$ETR/enable_sink
>  $ mkdir -p $CONFIG_FS/stp-policy/$source.0/stm_test/
>  $ echo 32768 65535 > $CONFIG_FS/stp-policy/$source.0/stm_test/channels
>  $ echo 64 > $CS_DEVS/$source/traceid
>  $ ./stm_app
>  Sending 64000 byte blocks of pattern 0 at 0us intervals
>  Success to map channel(32768~32783) to 0xffffa95fa000
>  Sending on channel 32768
>  $ dd if=/dev/$ETR of=~/trace.bin.1
>  597+1 records in
>  597+1 records out
>  305920 bytes (306 kB) copied, 0.399952 s, 765 kB/s
>  $ ./stm_app
>  Sending 64000 byte blocks of pattern 0 at 0us intervals
>  Success to map channel(32768~32783) to 0xffff7e9e2000
>  Sending on channel 32768
>  $ dd if=/dev/$ETR of=~/trace.bin.2
>  0+0 records in
>  0+0 records out
>  0 bytes (0 B) copied, 0.0232083 s, 0.0 kB/s
> 
>  Note that we don't get any data from the ETR for the second session.
> 
>  Also dmesg shows :
> 
>  [   77.520458] coresight-tmc 20800000.etr: TMC-ETR enabled
>  [   77.537097] coresight-replicator etr_replicator at 20890000: REPLICATOR enabled
>  [   77.558828] coresight-replicator main_replicator at 208a0000: REPLICATOR enabled
>  [   77.581068] coresight-funnel 208c0000.main_funnel: FUNNEL inport 0 enabled
>  [   77.602217] coresight-tmc 20840000.etf: TMC-ETF enabled
>  [   77.618422] coresight-stm 20860000.stm: STM tracing enabled
>  [  139.554252] coresight-stm 20860000.stm: STM tracing disabled
>   # End of first tracing session
>  [  146.351135] coresight-tmc 20800000.etr: TMC read start
>  [  146.514486] coresight-tmc 20800000.etr: TMC read end
>   # Note that the STM is not turned on via stm_generic_link()->coresight_enable()
>   # and hence none of the components are turned on.
>  [  152.479080] coresight-tmc 20800000.etr: TMC read start
>  [  152.542632] coresight-tmc 20800000.etr: TMC read end
> 
> This patch fixes the problem by balancing the unlink operation by using
> the coresight_disable(), keeping the coresight layer in sync with the
> hardware state and thus allowing normal usage of the STM component.
> 
> Fixes: commit 237483aa5cf43 ("coresight: stm: adding driver for CoreSight STM component")
> Cc: Pratik Patel <pratikp@codeaurora.org>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: stable at vger.kernel.org # 4.7+
> Acked-by: Mathieu Poirier <mathieu.poirier@linaro.org>
> Reviewed-by: Chunyan Zhang <zhang.chunyan@linaro.org>
> Reported-by: Robert Walker <robert.walker@arm.com>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> ---
> 
> Greg,
> 
> Without this patch, the coresight STM IP can only be used for one tracing
> session per boot, seriously limiting its usability.

When you resend a patch, please tell me what is different from the
previous version you sent.  I figured it out here, but please do this
next time.

thanks,

greg k-h

^ permalink raw reply

* [PATCH 2/2] security: Change name of CONFIG_DEBUG_SET_MODULE_RONX
From: Heiko Carstens @ 2017-01-19 11:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170119111117.GB11176@leverpostej>

On Thu, Jan 19, 2017 at 11:11:18AM +0000, Mark Rutland wrote:
> > +config HARDENED_MODULE_MAPPINGS
> > +	bool "Mark module mappings with stricter permissions (RO/W^X)"
> > +	default y
> > +	depends on ARCH_HAS_HARDENED_MODULE_MAPPINGS
> > +	help
> > +	  If this is set, module text and rodata memory will be made read-only,
> > +	  and non-text memory will be made non-executable. This provides
> > +	  protection against certain security vulnerabilities (e.g. modifying
> > +	  code)
> > +
> > +	  Unless your system has known restrictions or performance issues, it
> > +	  is recommended to say Y here.
> > +
> 
> I was hoping that we'd make this mandatory, as we'd already done for
> DEBUG_RODATA.

Same for s390: would be good to make this mandatory.

^ permalink raw reply

* [PATCH 1/2] security: Change name of CONFIG_DEBUG_RODATA
From: Heiko Carstens @ 2017-01-19 11:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170119105646.GA11176@leverpostej>

On Thu, Jan 19, 2017 at 10:56:46AM +0000, Mark Rutland wrote:
> > +config HARDENED_PAGE_MAPPINGS
> > +	bool "Mark kernel mappings with stricter permissions (RO/W^X)"
> > +	default y
> > +	depends on ARCH_HAS_HARDENED_MAPPINGS
> > +	help
> > +          If this is set, kernel text and rodata memory will be made read-only,
> > +	  and non-text memory will be made non-executable. This provides
> > +	  protection against certain security attacks (e.g. executing the heap
> > +	  or modifying text).
> > +
> > +	  Unless your system has known restrictions or performance issues, it
> > +	  is recommended to say Y here.
> 
> It's somewhat unfortunate that this means the feature is no longer
> mandatory on arm64 (and s390+x86). We have a boot-time switch to turn
> the protections off, so I was hoping we could make this mandatory on all
> architectures with support.
> 
> It would be good to see if we could make this mandatory for arm and
> parisc, or if it really needs to be optional for either of those.

Looks like the config option is a no-op on parisc just like it is on
s390. Irrelavant of the config option at least on s390 the page tables for
kernel text and rodata will be read-only anyway.

This works since ages and I don't see a reason why this should be
changed. Also trying to disable this with the "rodata=" command line option
does not work at least on s390, and I guess this is true for parisc as
well.

The only thing implemented with CONFIG_DEBUG_RODATA on both architectures
is to emit a message that states memory has been protected
(mark_rodata_ro).
This just avoids a wrong "Kernel memory protection disabled." message.

So yes, I'd really like to keep this option mandatory.

^ permalink raw reply

* [PATCH v29 3/9] arm64: kdump: reserve memory for crash dump kernel
From: Mark Rutland @ 2017-01-19 11:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170119094941.GP20972@linaro.org>

On Thu, Jan 19, 2017 at 06:49:42PM +0900, AKASHI Takahiro wrote:
> On Tue, Jan 17, 2017 at 11:54:42AM +0000, Mark Rutland wrote:
> > On Tue, Jan 17, 2017 at 05:20:44PM +0900, AKASHI Takahiro wrote:
> > > On Fri, Jan 13, 2017 at 11:39:15AM +0000, Mark Rutland wrote:
> > > > Great! I think it would be better to follow the approach of
> > > > mark_rodata_ro(), rather than opening up set_memory_*(), but otherwise,
> > > > it looks like it should work.
> > > 
> > > I'm not quite sure what the approach of mark_rodata_ro() means, but
> > > I found that using create_mapping_late() may cause two problems:
> > > 
> > > 1) it fails when PTE_CONT bits mismatch between an old and new mmu entry.
> > >    This can happen, say, if the memory range for crash dump kernel
> > >    starts in the mid of _continuous_ pages.
> > 
> > That should only happen if we try to remap a segment different to what
> > we originally mapped.
> > 
> > I was intending that we'd explicitly map the reserved region separately
> > in the boot path, like we do for kernel segments in map_kernel(). We
> > would allow sections and/or CONT entires. 
> > 
> > Then, in __map_memblock() we'd then skip that range as we do for the
> > linear map alias of the kernel image.
> > 
> > That way, we can later use create_mapping_late for that same region, and
> > it should handle sections and/or CONT entries in the exact same way as
> > it does for the kernel image segments in mark_rodata_ro().
> 
> I see.
> Which one do you prefer, yours above or my (second) solution?
> Either way, they do almost the same thing in terms of mapping.

While both should work, I'd prefer to match the existing map_kernel()
logic, (i.e. my suggestion above), for consistency.

> > I don't think we have much code useful for unmapping. We could re-use 
> > create_mapping_late for this, passing a set of prot bits that means the
> > entries are invalid (e.g. have a PAGE_KERNEL_INVALID).
> 
> Do you really think that we should totally invalidate mmu entries?
> I guess that, given proper cache & TLB flush operations, RO attribute is
> good enough for memory consistency, no?
> (None accesses the region, as I said, except in the case of re-loading
> crash dump kernel though.)

My worry is that the first kernel and kdump kernel may map (portions of)
the region with potentially confliciting memory attributes. So it would
be necessary to completely unmap the region.

You raise a good point that this would also mean we need to perform some
cache maintenance, which makes that a little more painful. We'd need a
sequence like:

* Unmap the region
* TLB invalidation
* Remap the region with non-cacheable attributes
* Cache maintenance
* Unmap the region
* TLB invalidation

> > We'd have to perform the TLB invalidation ourselves, but that shouldn't
> > be too painful.
> 
> Do we need to invalidate TLBs not only before but also after changing
> permission attributes as make_rodata_ro() does?

I believe we'd only have to perform the TLB invalidation after the
change of attributes.

Thanks,
Mark.

^ permalink raw reply

* [PATCH v3 06/13] ARM: davinci: da850: model the SATA refclk
From: Bartosz Golaszewski @ 2017-01-19 11:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <ff4deee6-9700-fff3-be96-0ad2f008914b@lechnology.com>

2017-01-18 18:26 GMT+01:00 David Lechner <david@lechnology.com>:
> On 01/18/2017 07:19 AM, Bartosz Golaszewski wrote:
>>
>>  int __init da850_register_sata(unsigned long refclkpn)
>>  {
>> +       int ret;
>> +
>>         /* please see comment in drivers/ata/ahci_da850.c */
>>         BUG_ON(refclkpn != 100 * 1000 * 1000);
>
>
> This BUG_ON() should be removed since the sata driver can now handle other
> clock frequencies.
>

Right, will fix in v4.

Thanks,
Bartosz Golaszewski

^ permalink raw reply

* [PATCH v20 13/17] acpi/arm64: Add GTDT table parse driver
From: Mark Rutland @ 2017-01-19 11:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CADyBb7tdfw+wbTZbcnsaHRa=aG6i9acLp7rzMpfMs-vOHXL6pQ@mail.gmail.com>

On Thu, Jan 19, 2017 at 06:32:55PM +0800, Fu Wei wrote:
> On 19 January 2017 at 17:11, Hanjun Guo <hanjun.guo@linaro.org> wrote:
> > On 2017/1/18 21:25, fu.wei at linaro.org wrote:
> >> From: Fu Wei <fu.wei@linaro.org>

> >> +       else if (!gtdt->platform_timer_count)
> >> +               pr_debug("No Platform Timer.\n");
> >> +       else
> >> +               timer_count = gtdt->platform_timer_count;
> >> +
> >> +       if (timer_count) {
> >> +               platform_timer = (void *)gtdt +
> >> gtdt->platform_timer_offset;
> >> +               if (platform_timer < (void *)table +
> >> +                                    sizeof(struct acpi_table_gtdt)) {
> >> +                       pr_err(FW_BUG "invalid timer data.\n");
> >
> >
> > It's ok but I didn't see other ACPI tables parsing did this check,
> > maybe we can just remove it :)
> 
> here, I want to make sure the FW is valid.
> Once there is a FW bug, we could just return with error.  :-)

Yes, please keep the check!

If anything, it would be nicer for the other ACPI code to verify things
a little more stringently.

Thanks,
Mark.

^ permalink raw reply

* [PATCH v8 4/4] arm64: arch timer: Add timer erratum property for Hip05-d02 and Hip06-d03
From: Ding Tianhong @ 2017-01-19 11:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484824474-12172-1-git-send-email-dingtianhong@huawei.com>

Enable workaround for hisilicon erratum 161010101 on Hip05-d02 and Hip06-d03 board.

Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
---
 arch/arm64/boot/dts/hisilicon/hip05.dtsi | 1 +
 arch/arm64/boot/dts/hisilicon/hip06.dtsi | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/hisilicon/hip05.dtsi b/arch/arm64/boot/dts/hisilicon/hip05.dtsi
index 4b472a3..6b76f3a 100644
--- a/arch/arm64/boot/dts/hisilicon/hip05.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hip05.dtsi
@@ -281,6 +281,7 @@
 			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
 			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
 			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+		hisilicon,erratum-161010101;
 	};
 
 	pmu {
diff --git a/arch/arm64/boot/dts/hisilicon/hip06.dtsi b/arch/arm64/boot/dts/hisilicon/hip06.dtsi
index a049b64..cf8b9db 100644
--- a/arch/arm64/boot/dts/hisilicon/hip06.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hip06.dtsi
@@ -260,6 +260,7 @@
 			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
 			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
 			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+		hisilicon,erratum-161010101;
 	};
 
 	pmu {
-- 
1.9.0

^ permalink raw reply related

* [PATCH v8 3/4] arm64: arch_timer: Work around Erratum Hisilicon-161010101
From: Ding Tianhong @ 2017-01-19 11:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484824474-12172-1-git-send-email-dingtianhong@huawei.com>

Erratum Hisilicon-161010101 says that the ARM generic timer counter "has the
potential to contain an erroneous value when the timer value changes".
Accesses to TVAL (both read and write) are also affected due to the implicit counter
read.  Accesses to CVAL are not affected.

The workaround is to reread the system count registers until the value of the second
read is larger than the first one by less than 32, the system counter can be guaranteed
not to return wrong value twice by back-to-back read and the error value is always larger
than the correct one by 32. Writes to TVAL are replaced with an equivalent write to CVAL.

The hisilicon erratum CONFIG name is too long, breaking the line format in silicon-errata.txt,
so extended the character spacing to fit all the erratum config.

Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
---
 Documentation/arm64/silicon-errata.txt | 43 ++++++++++++++---------------
 drivers/clocksource/Kconfig            | 12 ++++++++-
 drivers/clocksource/arm_arch_timer.c   | 49 ++++++++++++++++++++++++++++++++++
 3 files changed, 82 insertions(+), 22 deletions(-)

diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt
index 405da11..0aaae35 100644
--- a/Documentation/arm64/silicon-errata.txt
+++ b/Documentation/arm64/silicon-errata.txt
@@ -42,24 +42,25 @@ file acts as a registry of software workarounds in the Linux Kernel and
 will be updated when new workarounds are committed and backported to
 stable kernels.
 
-| Implementor    | Component       | Erratum ID      | Kconfig                 |
-+----------------+-----------------+-----------------+-------------------------+
-| ARM            | Cortex-A53      | #826319         | ARM64_ERRATUM_826319    |
-| ARM            | Cortex-A53      | #827319         | ARM64_ERRATUM_827319    |
-| ARM            | Cortex-A53      | #824069         | ARM64_ERRATUM_824069    |
-| ARM            | Cortex-A53      | #819472         | ARM64_ERRATUM_819472    |
-| ARM            | Cortex-A53      | #845719         | ARM64_ERRATUM_845719    |
-| ARM            | Cortex-A53      | #843419         | ARM64_ERRATUM_843419    |
-| ARM            | Cortex-A57      | #832075         | ARM64_ERRATUM_832075    |
-| ARM            | Cortex-A57      | #852523         | N/A                     |
-| ARM            | Cortex-A57      | #834220         | ARM64_ERRATUM_834220    |
-| ARM            | Cortex-A72      | #853709         | N/A                     |
-| ARM            | MMU-500         | #841119,#826419 | N/A                     |
-|                |                 |                 |                         |
-| Cavium         | ThunderX ITS    | #22375, #24313  | CAVIUM_ERRATUM_22375    |
-| Cavium         | ThunderX ITS    | #23144          | CAVIUM_ERRATUM_23144    |
-| Cavium         | ThunderX GICv3  | #23154          | CAVIUM_ERRATUM_23154    |
-| Cavium         | ThunderX Core   | #27456          | CAVIUM_ERRATUM_27456    |
-| Cavium         | ThunderX SMMUv2 | #27704          | N/A		       |
-|                |                 |                 |                         |
-| Freescale/NXP  | LS2080A/LS1043A | A-008585        | FSL_ERRATUM_A008585     |
+| Implementor    | Component       | Erratum ID      | Kconfig                         |
++----------------+-----------------+-----------------+---------------------------------+
+| ARM            | Cortex-A53      | #826319         | ARM64_ERRATUM_826319            |
+| ARM            | Cortex-A53      | #827319         | ARM64_ERRATUM_827319            |
+| ARM            | Cortex-A53      | #824069         | ARM64_ERRATUM_824069            |
+| ARM            | Cortex-A53      | #819472         | ARM64_ERRATUM_819472            |
+| ARM            | Cortex-A53      | #845719         | ARM64_ERRATUM_845719            |
+| ARM            | Cortex-A53      | #843419         | ARM64_ERRATUM_843419            |
+| ARM            | Cortex-A57      | #832075         | ARM64_ERRATUM_832075            |
+| ARM            | Cortex-A57      | #852523         | N/A                             |
+| ARM            | Cortex-A57      | #834220         | ARM64_ERRATUM_834220            |
+| ARM            | Cortex-A72      | #853709         | N/A                             |
+| ARM            | MMU-500         | #841119,#826419 | N/A                             |
+|                |                 |                 |                                 |
+| Cavium         | ThunderX ITS    | #22375, #24313  | CAVIUM_ERRATUM_22375            |
+| Cavium         | ThunderX ITS    | #23144          | CAVIUM_ERRATUM_23144            |
+| Cavium         | ThunderX GICv3  | #23154          | CAVIUM_ERRATUM_23154            |
+| Cavium         | ThunderX Core   | #27456          | CAVIUM_ERRATUM_27456            |
+| Cavium         | ThunderX SMMUv2 | #27704          | N/A                             |
+|                |                 |                 |                                 |
+| Freescale/NXP  | LS2080A/LS1043A | A-008585        | FSL_ERRATUM_A008585             |
+| Hisilicon      | Hip0{5,6,7}     | #161010101      | HISILICON_ERRATUM_161010101     |
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 04c2b93..628cb44 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -327,7 +327,7 @@ config ARM_ARCH_TIMER_EVTSTREAM
 
 config ARM_ARCH_TIMER_OOL_WORKAROUND
 	bool "Workaround for arm arch timer unstable counter"
-	depends on FSL_ERRATUM_A008585
+	depends on FSL_ERRATUM_A008585 || HISILICON_ERRATUM_161010101
 	help
 	  This option would only be enabled by Freescale/NXP Erratum A-008585
 	  or something else chip has similar erratum.
@@ -343,6 +343,16 @@ config FSL_ERRATUM_A008585
 	  value").  The workaround will only be active if the
 	  fsl,erratum-a008585 property is found in the timer node.
 
+config HISILICON_ERRATUM_161010101
+	bool "Workaround for Hisilicon Erratum 161010101"
+	default y
+	select ARM_ARCH_TIMER_OOL_WORKAROUND
+	depends on ARM_ARCH_TIMER && ARM64
+	help
+	  This option enables a workaround for Hisilicon Erratum
+	  161010101. The workaround will be active if the hisilicon,erratum-161010101
+	  property is found in the timer node.
+
 config ARM_GLOBAL_TIMER
 	bool "Support for the ARM global timer" if COMPILE_TEST
 	select CLKSRC_OF if OF
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 2487c66..7451b62 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -131,6 +131,47 @@ static u64 notrace fsl_a008585_read_cntvct_el0(void)
 }
 #endif
 
+#ifdef CONFIG_HISILICON_ERRATUM_161010101
+/*
+ * Verify whether the value of the second read is larger than the first by
+ * less than 32 is the only way to confirm the value is correct, so clear the
+ * lower 5 bits to check whether the difference is greater than 32 or not.
+ * Theoretically the erratum should not occur more than twice in succession
+ * when reading the system counter, but it is possible that some interrupts
+ * may lead to more than twice read errors, triggering the warning, so setting
+ * the number of retries far beyond the number of iterations the loop has been
+ * observed to take.
+ */
+#define __hisi_161010101_read_reg(reg) ({				\
+	u64 _old, _new;						\
+	int _retries = 50;					\
+								\
+	do {							\
+		_old = read_sysreg(reg);			\
+		_new = read_sysreg(reg);			\
+		_retries--;					\
+	} while (unlikely((_new - _old) >> 5) && _retries);	\
+								\
+	WARN_ON_ONCE(!_retries);				\
+	_new;							\
+})
+
+static u32 notrace hisi_161010101_read_cntp_tval_el0(void)
+{
+	return __hisi_161010101_read_reg(cntp_tval_el0);
+}
+
+static u32 notrace hisi_161010101_read_cntv_tval_el0(void)
+{
+	return __hisi_161010101_read_reg(cntv_tval_el0);
+}
+
+static u64 notrace hisi_161010101_read_cntvct_el0(void)
+{
+	return __hisi_161010101_read_reg(cntvct_el0);
+}
+#endif
+
 #ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
 const struct arch_timer_erratum_workaround *timer_unstable_counter_workaround = NULL;
 EXPORT_SYMBOL_GPL(timer_unstable_counter_workaround);
@@ -147,6 +188,14 @@ static u64 notrace fsl_a008585_read_cntvct_el0(void)
 		.read_cntvct_el0 = fsl_a008585_read_cntvct_el0,
 	},
 #endif
+#ifdef CONFIG_HISILICON_ERRATUM_161010101
+	{
+		.id = "hisilicon,erratum-161010101",
+		.read_cntp_tval_el0 = hisi_161010101_read_cntp_tval_el0,
+		.read_cntv_tval_el0 = hisi_161010101_read_cntv_tval_el0,
+		.read_cntvct_el0 = hisi_161010101_read_cntvct_el0,
+	},
+#endif
 };
 #endif /* CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND */
 
-- 
1.9.0

^ permalink raw reply related

* [PATCH v8 2/4] arm64: arch_timer: Introduce a generic erratum handing mechanism for fsl-a008585
From: Ding Tianhong @ 2017-01-19 11:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484824474-12172-1-git-send-email-dingtianhong@huawei.com>

The workaround for hisilicon,161010101 will check the return value of the system counter
by different way, in order to distinguish with the fsl-a008585 workaround, introduce
a new generic erratum handing mechanism for fsl-a008585 and rename some functions.

After discussion with Marc and Will, a consensus decision was made to remove the commandline
parameter for enabling fsl,erratum-a008585 erratum.

Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
---
 Documentation/admin-guide/kernel-parameters.txt |   9 --
 arch/arm64/include/asm/arch_timer.h             |  38 +++------
 drivers/clocksource/Kconfig                     |   8 ++
 drivers/clocksource/arm_arch_timer.c            | 105 ++++++++++++++----------
 4 files changed, 84 insertions(+), 76 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 21e2d88..76437ad 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -539,15 +539,6 @@
 			loops can be debugged more effectively on production
 			systems.
 
-	clocksource.arm_arch_timer.fsl-a008585=
-			[ARM64]
-			Format: <bool>
-			Enable/disable the workaround of Freescale/NXP
-			erratum A-008585.  This can be useful for KVM
-			guests, if the guest device tree doesn't show the
-			erratum.  If unspecified, the workaround is
-			enabled based on the device tree.
-
 	clearcpuid=BITNUM [X86]
 			Disable CPUID feature X for the kernel. See
 			arch/x86/include/asm/cpufeatures.h for the valid bit
diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index eaa5bbe..b4b3400 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -29,41 +29,29 @@
 
 #include <clocksource/arm_arch_timer.h>
 
-#if IS_ENABLED(CONFIG_FSL_ERRATUM_A008585)
+#if IS_ENABLED(CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND)
 extern struct static_key_false arch_timer_read_ool_enabled;
-#define needs_fsl_a008585_workaround() \
+#define needs_unstable_timer_counter_workaround() \
 	static_branch_unlikely(&arch_timer_read_ool_enabled)
 #else
-#define needs_fsl_a008585_workaround()  false
+#define needs_unstable_timer_counter_workaround()  false
 #endif
 
-u32 __fsl_a008585_read_cntp_tval_el0(void);
-u32 __fsl_a008585_read_cntv_tval_el0(void);
-u64 __fsl_a008585_read_cntvct_el0(void);
 
-/*
- * The number of retries is an arbitrary value well beyond the highest number
- * of iterations the loop has been observed to take.
- */
-#define __fsl_a008585_read_reg(reg) ({			\
-	u64 _old, _new;					\
-	int _retries = 200;				\
-							\
-	do {						\
-		_old = read_sysreg(reg);		\
-		_new = read_sysreg(reg);		\
-		_retries--;				\
-	} while (unlikely(_old != _new) && _retries);	\
-							\
-	WARN_ON_ONCE(!_retries);			\
-	_new;						\
-})
+struct arch_timer_erratum_workaround {
+	const char *id;		/* Indicate the Erratum ID */
+	u32 (*read_cntp_tval_el0)(void);
+	u32 (*read_cntv_tval_el0)(void);
+	u64 (*read_cntvct_el0)(void);
+};
+
+extern const struct arch_timer_erratum_workaround *timer_unstable_counter_workaround;
 
 #define arch_timer_reg_read_stable(reg) 		\
 ({							\
 	u64 _val;					\
-	if (needs_fsl_a008585_workaround())		\
-		_val = __fsl_a008585_read_##reg();	\
+	if (needs_unstable_timer_counter_workaround())		\
+		_val = timer_unstable_counter_workaround->read_##reg();\
 	else						\
 		_val = read_sysreg(reg);		\
 	_val;						\
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 4866f7a..04c2b93 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -325,10 +325,18 @@ config ARM_ARCH_TIMER_EVTSTREAM
 	  This must be disabled for hardware validation purposes to detect any
 	  hardware anomalies of missing events.
 
+config ARM_ARCH_TIMER_OOL_WORKAROUND
+	bool "Workaround for arm arch timer unstable counter"
+	depends on FSL_ERRATUM_A008585
+	help
+	  This option would only be enabled by Freescale/NXP Erratum A-008585
+	  or something else chip has similar erratum.
+
 config FSL_ERRATUM_A008585
 	bool "Workaround for Freescale/NXP Erratum A-008585"
 	default y
 	depends on ARM_ARCH_TIMER && ARM64
+	select ARM_ARCH_TIMER_OOL_WORKAROUND
 	help
 	  This option enables a workaround for Freescale/NXP Erratum
 	  A-008585 ("ARM generic timer may contain an erroneous
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 02fef68..2487c66 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -96,41 +96,59 @@ static int __init early_evtstrm_cfg(char *buf)
  */
 
 #ifdef CONFIG_FSL_ERRATUM_A008585
-DEFINE_STATIC_KEY_FALSE(arch_timer_read_ool_enabled);
-EXPORT_SYMBOL_GPL(arch_timer_read_ool_enabled);
-
-static int fsl_a008585_enable = -1;
-
-static int __init early_fsl_a008585_cfg(char *buf)
-{
-	int ret;
-	bool val;
 
-	ret = strtobool(buf, &val);
-	if (ret)
-		return ret;
-
-	fsl_a008585_enable = val;
-	return 0;
-}
-early_param("clocksource.arm_arch_timer.fsl-a008585", early_fsl_a008585_cfg);
-
-u32 __fsl_a008585_read_cntp_tval_el0(void)
+/*
+ * The number of retries is an arbitrary value well beyond the highest number
+ * of iterations the loop has been observed to take.
+ */
+#define __fsl_a008585_read_reg(reg) ({			\
+	u64 _old, _new;					\
+	int _retries = 200;				\
+							\
+	do {						\
+		_old = read_sysreg(reg);		\
+		_new = read_sysreg(reg);		\
+		_retries--;				\
+	} while (unlikely(_old != _new) && _retries);	\
+							\
+	WARN_ON_ONCE(!_retries);			\
+	_new;						\
+})
+
+static u32 notrace fsl_a008585_read_cntp_tval_el0(void)
 {
 	return __fsl_a008585_read_reg(cntp_tval_el0);
 }
 
-u32 __fsl_a008585_read_cntv_tval_el0(void)
+static u32 notrace fsl_a008585_read_cntv_tval_el0(void)
 {
 	return __fsl_a008585_read_reg(cntv_tval_el0);
 }
 
-u64 __fsl_a008585_read_cntvct_el0(void)
+static u64 notrace fsl_a008585_read_cntvct_el0(void)
 {
 	return __fsl_a008585_read_reg(cntvct_el0);
 }
-EXPORT_SYMBOL(__fsl_a008585_read_cntvct_el0);
-#endif /* CONFIG_FSL_ERRATUM_A008585 */
+#endif
+
+#ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
+const struct arch_timer_erratum_workaround *timer_unstable_counter_workaround = NULL;
+EXPORT_SYMBOL_GPL(timer_unstable_counter_workaround);
+
+DEFINE_STATIC_KEY_FALSE(arch_timer_read_ool_enabled);
+EXPORT_SYMBOL_GPL(arch_timer_read_ool_enabled);
+
+static const struct arch_timer_erratum_workaround ool_workarounds[] = {
+#ifdef CONFIG_FSL_ERRATUM_A008585
+	{
+		.id = "fsl,erratum-a008585",
+		.read_cntp_tval_el0 = fsl_a008585_read_cntp_tval_el0,
+		.read_cntv_tval_el0 = fsl_a008585_read_cntv_tval_el0,
+		.read_cntvct_el0 = fsl_a008585_read_cntvct_el0,
+	},
+#endif
+};
+#endif /* CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND */
 
 static __always_inline
 void arch_timer_reg_write(int access, enum arch_timer_reg reg, u32 val,
@@ -281,8 +299,8 @@ static __always_inline void set_next_event(const int access, unsigned long evt,
 	arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
 }
 
-#ifdef CONFIG_FSL_ERRATUM_A008585
-static __always_inline void fsl_a008585_set_next_event(const int access,
+#ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
+static __always_inline void erratum_set_next_event_generic(const int access,
 		unsigned long evt, struct clock_event_device *clk)
 {
 	unsigned long ctrl;
@@ -300,20 +318,20 @@ static __always_inline void fsl_a008585_set_next_event(const int access,
 	arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk);
 }
 
-static int fsl_a008585_set_next_event_virt(unsigned long evt,
+static int erratum_set_next_event_virt(unsigned long evt,
 					   struct clock_event_device *clk)
 {
-	fsl_a008585_set_next_event(ARCH_TIMER_VIRT_ACCESS, evt, clk);
+	erratum_set_next_event_generic(ARCH_TIMER_VIRT_ACCESS, evt, clk);
 	return 0;
 }
 
-static int fsl_a008585_set_next_event_phys(unsigned long evt,
+static int erratum_set_next_event_phys(unsigned long evt,
 					   struct clock_event_device *clk)
 {
-	fsl_a008585_set_next_event(ARCH_TIMER_PHYS_ACCESS, evt, clk);
+	erratum_set_next_event_generic(ARCH_TIMER_PHYS_ACCESS, evt, clk);
 	return 0;
 }
-#endif /* CONFIG_FSL_ERRATUM_A008585 */
+#endif /* CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND */
 
 static int arch_timer_set_next_event_virt(unsigned long evt,
 					  struct clock_event_device *clk)
@@ -343,16 +361,16 @@ static int arch_timer_set_next_event_phys_mem(unsigned long evt,
 	return 0;
 }
 
-static void fsl_a008585_set_sne(struct clock_event_device *clk)
+static void erratum_workaround_set_sne(struct clock_event_device *clk)
 {
-#ifdef CONFIG_FSL_ERRATUM_A008585
+#ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
 	if (!static_branch_unlikely(&arch_timer_read_ool_enabled))
 		return;
 
 	if (arch_timer_uses_ppi == VIRT_PPI)
-		clk->set_next_event = fsl_a008585_set_next_event_virt;
+		clk->set_next_event = erratum_set_next_event_virt;
 	else
-		clk->set_next_event = fsl_a008585_set_next_event_phys;
+		clk->set_next_event = erratum_set_next_event_phys;
 #endif
 }
 
@@ -385,7 +403,7 @@ static void __arch_timer_setup(unsigned type,
 			BUG();
 		}
 
-		fsl_a008585_set_sne(clk);
+		erratum_workaround_set_sne(clk);
 	} else {
 		clk->features |= CLOCK_EVT_FEAT_DYNIRQ;
 		clk->name = "arch_mem_timer";
@@ -605,7 +623,7 @@ static void __init arch_counter_register(unsigned type)
 
 		clocksource_counter.archdata.vdso_direct = true;
 
-#ifdef CONFIG_FSL_ERRATUM_A008585
+#ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
 		/*
 		 * Don't use the vdso fastpath if errata require using
 		 * the out-of-line counter accessor.
@@ -893,12 +911,15 @@ static int __init arch_timer_of_init(struct device_node *np)
 
 	arch_timer_c3stop = !of_property_read_bool(np, "always-on");
 
-#ifdef CONFIG_FSL_ERRATUM_A008585
-	if (fsl_a008585_enable < 0)
-		fsl_a008585_enable = of_property_read_bool(np, "fsl,erratum-a008585");
-	if (fsl_a008585_enable) {
-		static_branch_enable(&arch_timer_read_ool_enabled);
-		pr_info("Enabling workaround for FSL erratum A-008585\n");
+#ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
+	for (i = 0; i < ARRAY_SIZE(ool_workarounds); i++) {
+		if (of_property_read_bool(np, ool_workarounds[i].id)) {
+			timer_unstable_counter_workaround = &ool_workarounds[i];
+			static_branch_enable(&arch_timer_read_ool_enabled);
+			pr_info("arch_timer: Enabling workaround for %s\n",
+				timer_unstable_counter_workaround->id);
+			break;
+		}
 	}
 #endif
 
-- 
1.9.0

^ permalink raw reply related

* [PATCH v8 1/4] arm64: arch_timer: Add device tree binding for hisilicon-161010101 erratum
From: Ding Tianhong @ 2017-01-19 11:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484824474-12172-1-git-send-email-dingtianhong@huawei.com>

This erratum describes a bug in logic outside the core, so MIDR can't be
used to identify its presence, and reading an SoC-specific revision
register from common arch timer code would be awkward.  So, describe it
in the device tree.

Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
Acked-by: Rob Herring <robh@kernel.org>
---
 Documentation/devicetree/bindings/arm/arch_timer.txt | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/arch_timer.txt b/Documentation/devicetree/bindings/arm/arch_timer.txt
index ad440a2..9116934 100644
--- a/Documentation/devicetree/bindings/arm/arch_timer.txt
+++ b/Documentation/devicetree/bindings/arm/arch_timer.txt
@@ -31,6 +31,14 @@ to deliver its interrupts via SPIs.
   This also affects writes to the tval register, due to the implicit
   counter read.
 
+- hisilicon,erratum-161010101 : A boolean property. Indicates the presence of
+  erratum 161010101, which says that reading the counter is unreliable unless
+  reading twice on the register and the value of the second read is larger
+  than the first by less than 32. If the verification is unsuccessful, then
+  discard the value of this read and repeat this procedure until the verification
+  is successful.  This also affects writes to the tval register, due to the
+  implicit counter read.
+
 ** Optional properties:
 
 - arm,cpu-registers-not-fw-configured : Firmware does not initialize
-- 
1.9.0

^ permalink raw reply related

* [PATCH v8 0/4] arm64: arch_timer: Add workaround for hisilicon-161601 erratum
From: Ding Tianhong @ 2017-01-19 11:14 UTC (permalink / raw)
  To: linux-arm-kernel

Erratum Hisilicon-161601 says that the ARM generic timer counter "has the
potential to contain an erroneous value when the timer value changes".
Accesses to TVAL (both read and write) are also affected due to the implicit counter
read.  Accesses to CVAL are not affected.

The workaround is to reread the system count registers until the value of the second
read is larger than the first one by less than 32, the system counter can be guaranteed
not to return wrong value twice by back-to-back read and the error value is always larger
than the correct one by 32. Writes to TVAL are replaced with an equivalent write to CVAL.

v2: Introducing a new generic erratum handling mechanism for fsl,a008585 and hisilicon,161601.
    Significant rework based on feedback, including seperate the fsl erratum a008585
    to another patch, update the erratum name and remove unwanted code.

v3: Introducing the erratum_workaround_set_sne generic function for fsl erratum a008585
    and make the #define __fsl_a008585_read_reg to be private to the .c file instead of
    being globally visible. After discussion with Marc and Will, a consensus decision was
    made to remove the commandline parameter for enabling fsl,erratum-a008585 erratum,
    and make some generic name more specific, export timer_unstable_counter_workaround
    for module access.
    
    Significant rework based on feedback, including fix some alignment problem, make the
    #define __hisi_161601_read_reg to be private to the .c file instead of being globally
    visible, add more accurate annotation and modify a bit of logical format to enable
    arch_timer_read_ool_enabled, remove the kernel commandline parameter
    clocksource.arm_arch_timer.hisilicon-161601.

    Introduce a generic aquick framework for erratum in ACPI mode.

v4: rename the quirk handler parameter to make it more generic, and
    avoid break loop when handling the quirk becasue it need to
    support multi quirks handler.

    update some data structures for acpi mode. 

v5: Adapt the new kernel-parameters.txt for latest kernel version.
    Set the retries of reread system counter to 50, because it is possible 
    that some interrupts may lead to more than twice read errors and break the loop,
    it will trigger the warning, so we set the number of retries far beyond the number of
    iterations the loop has been observed to take.

v6: The last 2 patches in the previous version about the ACPI mode will conflict witch Fuwei's
    GTDT patches, so remove the ACPI part and only support the DT base code for this patch set.

    We have trigger a bug when select the CONFIG_FUNCTION_GRAPH_TRACER and enable function_graph
    to /sys/kernel/debug/tracing/current_tracer, the system will stall into an endless loop, it looks
    like that the ftrace_graph_caller will be related to xxx.read_cntvct_el0 and read the system counter
    again, so mark the xxx.read_cntvct_el0 with notrace to fix the problem.

v7: Introduce a new general config symbol named CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND to enable the workaround
    for any chips which has similar arch timer erratum just like "fsl,erratum_a008585" and "hisilicon,erratum_161601",
    modify the struct arch_timer_erratum_workaround to be compatible different chip erratum more easily, and
    reconstruction some code base on the new config symbol and struct, thanks to Marc's suggestion. 

v8: The original erratum ID could not cover all modules, which only specified <Errata-Prefix><SerialNum>, so after
    discussion with the soc team, we decide to use the new ID "161010101" for this timer erratum which consist of
    <Errata-Prefix><SeriesFlag><ModuleID><SerialNum> and also update the hisilicon erratum official documents.

Ding Tianhong (4):
  arm64: arch_timer: Add device tree binding for hisilicon-161010101
    erratum
  arm64: arch_timer: Introduce a generic erratum handing mechanism for
    fsl-a008585
  arm64: arch_timer: Work around Erratum Hisilicon-161010101
  arm64: arch timer: Add timer erratum property for Hip05-d02 and
    Hip06-d03

 Documentation/admin-guide/kernel-parameters.txt    |   9 --
 Documentation/arm64/silicon-errata.txt             |  43 +++---
 .../devicetree/bindings/arm/arch_timer.txt         |   8 ++
 arch/arm64/boot/dts/hisilicon/hip05.dtsi           |   1 +
 arch/arm64/boot/dts/hisilicon/hip06.dtsi           |   1 +
 arch/arm64/include/asm/arch_timer.h                |  38 ++----
 drivers/clocksource/Kconfig                        |  18 +++
 drivers/clocksource/arm_arch_timer.c               | 150 +++++++++++++++------
 8 files changed, 173 insertions(+), 95 deletions(-)

-- 
1.9.0

^ permalink raw reply

* [PATCH 2/2] security: Change name of CONFIG_DEBUG_SET_MODULE_RONX
From: Mark Rutland @ 2017-01-19 11:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484789346-21012-3-git-send-email-labbott@redhat.com>

Hi,

On Wed, Jan 18, 2017 at 05:29:06PM -0800, Laura Abbott wrote:
> 
> Despite the word 'debug' in CONFIG_DEBUG_SET_MODULE_RONX, this kernel
> option provides key security features that are to be expected on a
> modern system. Change the name to CONFIG_HARDENED_MODULE_MAPPINGS which
> more accurately describes what this option is intended to do.

This looks good; my naming comments from the DEBUG_RODATA also apply
here -- the proposed name is fine.

> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 06fed56..2fe0e98 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -12,6 +12,7 @@ config ARM64
>  	select ARCH_HAS_GCOV_PROFILE_ALL
>  	select ARCH_HAS_GIGANTIC_PAGE
>  	select ARCH_HAS_HARDENED_MAPPINGS
> +	select ARCH_HAS_HARDENED_MODULE_MAPPINGS
>  	select ARCH_HAS_KCOV
>  	select ARCH_HAS_SG_CHAIN
>  	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
> diff --git a/arch/arm64/Kconfig.debug b/arch/arm64/Kconfig.debug
> index a26d27f..1eebe1f 100644
> --- a/arch/arm64/Kconfig.debug
> +++ b/arch/arm64/Kconfig.debug
> @@ -71,17 +71,6 @@ config DEBUG_WX
>  
>  	  If in doubt, say "Y".
>  
> -config DEBUG_SET_MODULE_RONX
> -	bool "Set loadable kernel module data as NX and text as RO"
> -	depends on MODULES
> -	default y
> -	help
> -	  Is this is set, kernel module text and rodata will be made read-only.
> -	  This is to help catch accidental or malicious attempts to change the
> -	  kernel's executable code.
> -
> -	  If in doubt, say Y.
> -

> +config ARCH_HAS_HARDENED_MODULE_MAPPINGS
> +	def_bool n
> +
> +config HARDENED_MODULE_MAPPINGS
> +	bool "Mark module mappings with stricter permissions (RO/W^X)"
> +	default y
> +	depends on ARCH_HAS_HARDENED_MODULE_MAPPINGS
> +	help
> +	  If this is set, module text and rodata memory will be made read-only,
> +	  and non-text memory will be made non-executable. This provides
> +	  protection against certain security vulnerabilities (e.g. modifying
> +	  code)
> +
> +	  Unless your system has known restrictions or performance issues, it
> +	  is recommended to say Y here.
> +

I was hoping that we'd make this mandatory, as we'd already done for
DEBUG_RODATA.

Takahiro-san did a bit of work towards that in commit 39290b389ea2654f
("module: extend 'rodata=off' boot cmdline parameter to module
mappings").

It would be good to know if there's any reason we can't do that.

Otherwise, this looks fine.

Thanks,
Mark.

^ permalink raw reply

* [PATCH v3 2/2] mmc: host: s3cmci: allow probing from device tree
From: Ulf Hansson @ 2017-01-19 11:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1484319953-6479-3-git-send-email-sergio.prado@e-labworks.com>

On 13 January 2017 at 16:05, Sergio Prado <sergio.prado@e-labworks.com> wrote:
> Allows configuring Samsung S3C24XX MMC/SD/SDIO controller using a device
> tree.
>
> Signed-off-by: Sergio Prado <sergio.prado@e-labworks.com>

Looks good to me. Waiting for Rob's ack for the DT changes in patch1
(needed a re-spin) before I queue it.

Kind regards
Uffe

> ---
>  drivers/mmc/host/s3cmci.c | 298 ++++++++++++++++++++++++----------------------
>  drivers/mmc/host/s3cmci.h |   3 +-
>  2 files changed, 158 insertions(+), 143 deletions(-)
>
> diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
> index 932a4b1fed33..55535b65e0b3 100644
> --- a/drivers/mmc/host/s3cmci.c
> +++ b/drivers/mmc/host/s3cmci.c
> @@ -23,6 +23,10 @@
>  #include <linux/gpio.h>
>  #include <linux/irq.h>
>  #include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/of_gpio.h>
> +#include <linux/mmc/slot-gpio.h>
>
>  #include <plat/gpio-cfg.h>
>  #include <mach/dma.h>
> @@ -127,6 +131,22 @@ enum dbg_channels {
>         dbg_conf  = (1 << 8),
>  };
>
> +struct s3cmci_variant_data {
> +       int s3c2440_compatible;
> +};
> +
> +static const struct s3cmci_variant_data s3c2410_s3cmci_variant_data = {
> +       .s3c2440_compatible = 0,
> +};
> +
> +static const struct s3cmci_variant_data s3c2412_s3cmci_variant_data = {
> +       .s3c2440_compatible = 1,
> +};
> +
> +static const struct s3cmci_variant_data s3c2440_s3cmci_variant_data = {
> +       .s3c2440_compatible = 1,
> +};
> +
>  static const int dbgmap_err   = dbg_fail;
>  static const int dbgmap_info  = dbg_info | dbg_conf;
>  static const int dbgmap_debug = dbg_err | dbg_debug;
> @@ -730,7 +750,7 @@ static irqreturn_t s3cmci_irq(int irq, void *dev_id)
>                 goto clear_status_bits;
>
>         /* Check for FIFO failure */
> -       if (host->is2440) {
> +       if (host->variant->s3c2440_compatible) {
>                 if (mci_fsta & S3C2440_SDIFSTA_FIFOFAIL) {
>                         dbg(host, dbg_err, "FIFO failure\n");
>                         host->mrq->data->error = -EILSEQ;
> @@ -806,21 +826,6 @@ static irqreturn_t s3cmci_irq(int irq, void *dev_id)
>
>  }
>
> -/*
> - * ISR for the CardDetect Pin
> -*/
> -
> -static irqreturn_t s3cmci_irq_cd(int irq, void *dev_id)
> -{
> -       struct s3cmci_host *host = (struct s3cmci_host *)dev_id;
> -
> -       dbg(host, dbg_irq, "card detect\n");
> -
> -       mmc_detect_change(host->mmc, msecs_to_jiffies(500));
> -
> -       return IRQ_HANDLED;
> -}
> -
>  static void s3cmci_dma_done_callback(void *arg)
>  {
>         struct s3cmci_host *host = arg;
> @@ -912,7 +917,7 @@ static void finalize_request(struct s3cmci_host *host)
>                 if (s3cmci_host_usedma(host))
>                         dmaengine_terminate_all(host->dma);
>
> -               if (host->is2440) {
> +               if (host->variant->s3c2440_compatible) {
>                         /* Clear failure register and reset fifo. */
>                         writel(S3C2440_SDIFSTA_FIFORESET |
>                                S3C2440_SDIFSTA_FIFOFAIL,
> @@ -1025,7 +1030,7 @@ static int s3cmci_setup_data(struct s3cmci_host *host, struct mmc_data *data)
>                 dcon |= S3C2410_SDIDCON_XFER_RXSTART;
>         }
>
> -       if (host->is2440) {
> +       if (host->variant->s3c2440_compatible) {
>                 dcon |= S3C2440_SDIDCON_DS_WORD;
>                 dcon |= S3C2440_SDIDCON_DATSTART;
>         }
> @@ -1044,7 +1049,7 @@ static int s3cmci_setup_data(struct s3cmci_host *host, struct mmc_data *data)
>
>         /* write TIMER register */
>
> -       if (host->is2440) {
> +       if (host->variant->s3c2440_compatible) {
>                 writel(0x007FFFFF, host->base + S3C2410_SDITIMER);
>         } else {
>                 writel(0x0000FFFF, host->base + S3C2410_SDITIMER);
> @@ -1176,19 +1181,6 @@ static void s3cmci_send_request(struct mmc_host *mmc)
>         s3cmci_enable_irq(host, true);
>  }
>
> -static int s3cmci_card_present(struct mmc_host *mmc)
> -{
> -       struct s3cmci_host *host = mmc_priv(mmc);
> -       struct s3c24xx_mci_pdata *pdata = host->pdata;
> -       int ret;
> -
> -       if (pdata->no_detect)
> -               return -ENOSYS;
> -
> -       ret = gpio_get_value(pdata->gpio_detect) ? 0 : 1;
> -       return ret ^ pdata->detect_invert;
> -}
> -
>  static void s3cmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
>  {
>         struct s3cmci_host *host = mmc_priv(mmc);
> @@ -1197,7 +1189,7 @@ static void s3cmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
>         host->cmd_is_stop = 0;
>         host->mrq = mrq;
>
> -       if (s3cmci_card_present(mmc) == 0) {
> +       if (mmc_gpio_get_cd(mmc) == 0) {
>                 dbg(host, dbg_err, "%s: no medium present\n", __func__);
>                 host->mrq->cmd->error = -ENOMEDIUM;
>                 mmc_request_done(mmc, mrq);
> @@ -1241,22 +1233,24 @@ static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>         case MMC_POWER_ON:
>         case MMC_POWER_UP:
>                 /* Configure GPE5...GPE10 pins in SD mode */
> -               s3c_gpio_cfgall_range(S3C2410_GPE(5), 6, S3C_GPIO_SFN(2),
> -                                     S3C_GPIO_PULL_NONE);
> +               if (!host->pdev->dev.of_node)
> +                       s3c_gpio_cfgall_range(S3C2410_GPE(5), 6, S3C_GPIO_SFN(2),
> +                                             S3C_GPIO_PULL_NONE);
>
>                 if (host->pdata->set_power)
>                         host->pdata->set_power(ios->power_mode, ios->vdd);
>
> -               if (!host->is2440)
> +               if (!host->variant->s3c2440_compatible)
>                         mci_con |= S3C2410_SDICON_FIFORESET;
>
>                 break;
>
>         case MMC_POWER_OFF:
>         default:
> -               gpio_direction_output(S3C2410_GPE(5), 0);
> +               if (!host->pdev->dev.of_node)
> +                       gpio_direction_output(S3C2410_GPE(5), 0);
>
> -               if (host->is2440)
> +               if (host->variant->s3c2440_compatible)
>                         mci_con |= S3C2440_SDICON_SDRESET;
>
>                 if (host->pdata->set_power)
> @@ -1294,21 +1288,6 @@ static void s3cmci_reset(struct s3cmci_host *host)
>         writel(con, host->base + S3C2410_SDICON);
>  }
>
> -static int s3cmci_get_ro(struct mmc_host *mmc)
> -{
> -       struct s3cmci_host *host = mmc_priv(mmc);
> -       struct s3c24xx_mci_pdata *pdata = host->pdata;
> -       int ret;
> -
> -       if (pdata->no_wprotect)
> -               return 0;
> -
> -       ret = gpio_get_value(pdata->gpio_wprotect) ? 1 : 0;
> -       ret ^= pdata->wprotect_invert;
> -
> -       return ret;
> -}
> -
>  static void s3cmci_enable_sdio_irq(struct mmc_host *mmc, int enable)
>  {
>         struct s3cmci_host *host = mmc_priv(mmc);
> @@ -1352,8 +1331,8 @@ static void s3cmci_enable_sdio_irq(struct mmc_host *mmc, int enable)
>  static struct mmc_host_ops s3cmci_ops = {
>         .request        = s3cmci_request,
>         .set_ios        = s3cmci_set_ios,
> -       .get_ro         = s3cmci_get_ro,
> -       .get_cd         = s3cmci_card_present,
> +       .get_ro         = mmc_gpio_get_ro,
> +       .get_cd         = mmc_gpio_get_cd,
>         .enable_sdio_irq = s3cmci_enable_sdio_irq,
>  };
>
> @@ -1429,7 +1408,7 @@ static int s3cmci_state_show(struct seq_file *seq, void *v)
>         seq_printf(seq, "Register base = 0x%08x\n", (u32)host->base);
>         seq_printf(seq, "Clock rate = %ld\n", host->clk_rate);
>         seq_printf(seq, "Prescale = %d\n", host->prescaler);
> -       seq_printf(seq, "is2440 = %d\n", host->is2440);
> +       seq_printf(seq, "S3C2440 compatible = %d\n", host->variant->s3c2440_compatible);
>         seq_printf(seq, "IRQ = %d\n", host->irq);
>         seq_printf(seq, "IRQ enabled = %d\n", host->irq_enabled);
>         seq_printf(seq, "IRQ disabled = %d\n", host->irq_disabled);
> @@ -1544,21 +1523,15 @@ static inline void s3cmci_debugfs_remove(struct s3cmci_host *host) { }
>
>  #endif /* CONFIG_DEBUG_FS */
>
> -static int s3cmci_probe(struct platform_device *pdev)
> +static int s3cmci_probe_pdata(struct s3cmci_host *host)
>  {
> -       struct s3cmci_host *host;
> -       struct mmc_host *mmc;
> -       int ret;
> -       int is2440;
> -       int i;
> +       struct platform_device *pdev = host->pdev;
> +       struct mmc_host *mmc = host->mmc;
> +       struct s3c24xx_mci_pdata *pdata;
> +       int i, ret;
>
> -       is2440 = platform_get_device_id(pdev)->driver_data;
> -
> -       mmc = mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev);
> -       if (!mmc) {
> -               ret = -ENOMEM;
> -               goto probe_out;
> -       }
> +       host->variant = (const struct s3cmci_variant_data *)
> +               platform_get_device_id(pdev)->driver_data;
>
>         for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++) {
>                 ret = gpio_request(i, dev_name(&pdev->dev));
> @@ -1568,25 +1541,103 @@ static int s3cmci_probe(struct platform_device *pdev)
>                         for (i--; i >= S3C2410_GPE(5); i--)
>                                 gpio_free(i);
>
> -                       goto probe_free_host;
> +                       return ret;
>                 }
>         }
>
> +       if (!pdev->dev.platform_data)
> +               pdev->dev.platform_data = &s3cmci_def_pdata;
> +
> +       pdata = pdev->dev.platform_data;
> +
> +       if (pdata->no_wprotect)
> +               mmc->caps2 |= MMC_CAP2_NO_WRITE_PROTECT;
> +
> +       if (pdata->no_detect)
> +               mmc->caps |= MMC_CAP_NEEDS_POLL;
> +
> +       if (pdata->wprotect_invert);
> +               mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
> +
> +       if (pdata->detect_invert)
> +                mmc->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH;
> +
> +       if (gpio_is_valid(pdata->gpio_detect)) {
> +               ret = mmc_gpio_request_cd(mmc, pdata->gpio_detect, 0);
> +               if (ret) {
> +                       dev_err(&pdev->dev, "error requesting GPIO for CD %d\n",
> +                               ret);
> +                       return ret;
> +               }
> +       }
> +
> +       if (gpio_is_valid(pdata->gpio_wprotect)) {
> +               ret = mmc_gpio_request_ro(mmc, pdata->gpio_wprotect);
> +               if (ret) {
> +                       dev_err(&pdev->dev, "error requesting GPIO for WP %d\n",
> +                               ret);
> +                       return ret;
> +               }
> +       }
> +
> +       return 0;
> +}
> +
> +static int s3cmci_probe_dt(struct s3cmci_host *host)
> +{
> +       struct platform_device *pdev = host->pdev;
> +       struct s3c24xx_mci_pdata *pdata;
> +       struct mmc_host *mmc = host->mmc;
> +       int ret;
> +
> +       host->variant = of_device_get_match_data(&pdev->dev);
> +       if (!host->variant)
> +               return -ENODEV;
> +
> +       ret = mmc_of_parse(mmc);
> +       if (ret)
> +               return ret;
> +
> +       pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
> +       if (!pdata)
> +               return -ENOMEM;
> +
> +       pdev->dev.platform_data = pdata;
> +
> +       return 0;
> +}
> +
> +static int s3cmci_probe(struct platform_device *pdev)
> +{
> +       struct s3cmci_host *host;
> +       struct mmc_host *mmc;
> +       int ret;
> +       int i;
> +
> +       mmc = mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev);
> +       if (!mmc) {
> +               ret = -ENOMEM;
> +               goto probe_out;
> +       }
> +
>         host = mmc_priv(mmc);
>         host->mmc       = mmc;
>         host->pdev      = pdev;
> -       host->is2440    = is2440;
> +
> +       if (pdev->dev.of_node)
> +               ret = s3cmci_probe_dt(host);
> +       else
> +               ret = s3cmci_probe_pdata(host);
> +
> +       if (ret)
> +               goto probe_free_host;
>
>         host->pdata = pdev->dev.platform_data;
> -       if (!host->pdata) {
> -               pdev->dev.platform_data = &s3cmci_def_pdata;
> -               host->pdata = &s3cmci_def_pdata;
> -       }
>
>         spin_lock_init(&host->complete_lock);
>         tasklet_init(&host->pio_tasklet, pio_tasklet, (unsigned long) host);
>
> -       if (is2440) {
> +       if (host->variant->s3c2440_compatible) {
>                 host->sdiimsk   = S3C2440_SDIIMSK;
>                 host->sdidata   = S3C2440_SDIDATA;
>                 host->clk_div   = 1;
> @@ -1644,43 +1695,6 @@ static int s3cmci_probe(struct platform_device *pdev)
>         disable_irq(host->irq);
>         host->irq_state = false;
>
> -       if (!host->pdata->no_detect) {
> -               ret = gpio_request(host->pdata->gpio_detect, "s3cmci detect");
> -               if (ret) {
> -                       dev_err(&pdev->dev, "failed to get detect gpio\n");
> -                       goto probe_free_irq;
> -               }
> -
> -               host->irq_cd = gpio_to_irq(host->pdata->gpio_detect);
> -
> -               if (host->irq_cd >= 0) {
> -                       if (request_irq(host->irq_cd, s3cmci_irq_cd,
> -                                       IRQF_TRIGGER_RISING |
> -                                       IRQF_TRIGGER_FALLING,
> -                                       DRIVER_NAME, host)) {
> -                               dev_err(&pdev->dev,
> -                                       "can't get card detect irq.\n");
> -                               ret = -ENOENT;
> -                               goto probe_free_gpio_cd;
> -                       }
> -               } else {
> -                       dev_warn(&pdev->dev,
> -                                "host detect has no irq available\n");
> -                       gpio_direction_input(host->pdata->gpio_detect);
> -               }
> -       } else
> -               host->irq_cd = -1;
> -
> -       if (!host->pdata->no_wprotect) {
> -               ret = gpio_request(host->pdata->gpio_wprotect, "s3cmci wp");
> -               if (ret) {
> -                       dev_err(&pdev->dev, "failed to get writeprotect\n");
> -                       goto probe_free_irq_cd;
> -               }
> -
> -               gpio_direction_input(host->pdata->gpio_wprotect);
> -       }
> -
>         /* Depending on the dma state, get a DMA channel to use. */
>
>         if (s3cmci_host_usedma(host)) {
> @@ -1688,7 +1702,7 @@ static int s3cmci_probe(struct platform_device *pdev)
>                 ret = PTR_ERR_OR_ZERO(host->dma);
>                 if (ret) {
>                         dev_err(&pdev->dev, "cannot get DMA channel.\n");
> -                       goto probe_free_gpio_wp;
> +                       goto probe_free_irq;
>                 }
>         }
>
> @@ -1730,7 +1744,7 @@ static int s3cmci_probe(struct platform_device *pdev)
>
>         dbg(host, dbg_debug,
>             "probe: mode:%s mapped mci_base:%p irq:%u irq_cd:%u dma:%p.\n",
> -           (host->is2440?"2440":""),
> +           (host->variant->s3c2440_compatible?"2440":""),
>             host->base, host->irq, host->irq_cd, host->dma);
>
>         ret = s3cmci_cpufreq_register(host);
> @@ -1767,18 +1781,6 @@ static int s3cmci_probe(struct platform_device *pdev)
>         if (s3cmci_host_usedma(host))
>                 dma_release_channel(host->dma);
>
> - probe_free_gpio_wp:
> -       if (!host->pdata->no_wprotect)
> -               gpio_free(host->pdata->gpio_wprotect);
> -
> - probe_free_gpio_cd:
> -       if (!host->pdata->no_detect)
> -               gpio_free(host->pdata->gpio_detect);
> -
> - probe_free_irq_cd:
> -       if (host->irq_cd >= 0)
> -               free_irq(host->irq_cd, host);
> -
>   probe_free_irq:
>         free_irq(host->irq, host);
>
> @@ -1789,8 +1791,9 @@ static int s3cmci_probe(struct platform_device *pdev)
>         release_mem_region(host->mem->start, resource_size(host->mem));
>
>   probe_free_gpio:
> -       for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
> -               gpio_free(i);
> +       if (!pdev->dev.of_node)
> +               for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
> +                       gpio_free(i);
>
>   probe_free_host:
>         mmc_free_host(mmc);
> @@ -1817,7 +1820,6 @@ static int s3cmci_remove(struct platform_device *pdev)
>  {
>         struct mmc_host         *mmc  = platform_get_drvdata(pdev);
>         struct s3cmci_host      *host = mmc_priv(mmc);
> -       struct s3c24xx_mci_pdata *pd = host->pdata;
>         int i;
>
>         s3cmci_shutdown(pdev);
> @@ -1831,15 +1833,9 @@ static int s3cmci_remove(struct platform_device *pdev)
>
>         free_irq(host->irq, host);
>
> -       if (!pd->no_wprotect)
> -               gpio_free(pd->gpio_wprotect);
> -
> -       if (!pd->no_detect)
> -               gpio_free(pd->gpio_detect);
> -
> -       for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
> -               gpio_free(i);
> -
> +       if (!pdev->dev.of_node)
> +               for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
> +                       gpio_free(i);
>
>         iounmap(host->base);
>         release_mem_region(host->mem->start, resource_size(host->mem));
> @@ -1848,16 +1844,33 @@ static int s3cmci_remove(struct platform_device *pdev)
>         return 0;
>  }
>
> +static const struct of_device_id s3cmci_dt_match[] = {
> +       {
> +               .compatible = "samsung,s3c2410-sdi",
> +               .data = &s3c2410_s3cmci_variant_data,
> +       },
> +       {
> +               .compatible = "samsung,s3c2412-sdi",
> +               .data = &s3c2412_s3cmci_variant_data,
> +       },
> +       {
> +               .compatible = "samsung,s3c2440-sdi",
> +               .data = &s3c2440_s3cmci_variant_data,
> +       },
> +       { /* sentinel */ },
> +};
> +MODULE_DEVICE_TABLE(of, sdhci_s3c_dt_match);
> +
>  static const struct platform_device_id s3cmci_driver_ids[] = {
>         {
>                 .name   = "s3c2410-sdi",
> -               .driver_data    = 0,
> +               .driver_data    = (kernel_ulong_t) &s3c2410_s3cmci_variant_data,
>         }, {
>                 .name   = "s3c2412-sdi",
> -               .driver_data    = 1,
> +               .driver_data    = (kernel_ulong_t) &s3c2412_s3cmci_variant_data,
>         }, {
>                 .name   = "s3c2440-sdi",
> -               .driver_data    = 1,
> +               .driver_data    = (kernel_ulong_t) &s3c2440_s3cmci_variant_data,
>         },
>         { }
>  };
> @@ -1867,6 +1880,7 @@ static int s3cmci_remove(struct platform_device *pdev)
>  static struct platform_driver s3cmci_driver = {
>         .driver = {
>                 .name   = "s3c-sdi",
> +               .of_match_table = s3cmci_dt_match,
>         },
>         .id_table       = s3cmci_driver_ids,
>         .probe          = s3cmci_probe,
> diff --git a/drivers/mmc/host/s3cmci.h b/drivers/mmc/host/s3cmci.h
> index 30c2c0dd1bc8..e9fe48915a2e 100644
> --- a/drivers/mmc/host/s3cmci.h
> +++ b/drivers/mmc/host/s3cmci.h
> @@ -33,7 +33,8 @@ struct s3cmci_host {
>         unsigned long           real_rate;
>         u8                      prescaler;
>
> -       int                     is2440;
> +       const struct s3cmci_variant_data *variant;
> +
>         unsigned                sdiimsk;
>         unsigned                sdidata;
>
> --
> 1.9.1
>

^ permalink raw reply


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