Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PULL 0/5] KVM/ARM Fixes for v4.15 - Round 2
From: Paolo Bonzini @ 2017-12-18 11:56 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171218100057.7839-1-christoffer.dall@linaro.org>

On 18/12/2017 11:00, Christoffer Dall wrote:
>   git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git kvm-arm-fixes-for-v4.15-2

Pulled, thanks.

Paolo

^ permalink raw reply

* [PATCH v5 0/4] ARM: ep93xx: ts72xx: Add support for BK3 board
From: Arnd Bergmann @ 2017-12-18 11:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171217222856.2c5937a4@jawa>

On Sun, Dec 17, 2017 at 10:28 PM, Lukasz Majewski <lukma@denx.de> wrote:
> Hi Arnd,
>
>> On Sun, Dec 17, 2017 at 8:41 PM, Lukasz Majewski <lukma@denx.de>
>> wrote:
>> >> >> We also need to think about upholding support in GCC for
>> >> >> ARMv4(t) for the foreseeable future if there is a big web of
>> >> >> random deeply embedded systems out there that will need
>> >> >> updates.
>> >> >
>> >> > But we should definitely preserve at least what we have.
>> >>
>> >> Plain ARMv4 (and earlier) support in gcc is already marked
>> >> 'deprecated' and will likely be gone in gcc-8 (it's still there as
>> >> of last week). ARMv4T is going to be around for a while, and you
>> >> can even keep building for ARMv4 using "-march=armv4t -marm" when
>> >> linking with 'ld --fix-v4bx'.
>> >
>> > I think that we shall start complaining on the gcc-devel mailing
>> > list now.
>> >
>> > I would be hard to wake up in 2 years time and realise that we don't
>> > have a modern compiler.
>>
>> What distro or build system are you using?
>
> I'm using OE with the "include conf/machine/include/tune-arm920t.inc"
>
> GCC 7.2 is working

Ah wait, this is still for ep93xx, which is always at least armv4t, right?
So it won't have a problem with the armv4 deprecation anyway, even
the older ep72xx/73xx were ARM720T based and don't have a problem.
I'm not entirely sure about their clps711x predecessors, which were some
earlier arm7 variant, but Linux doesn't support them any more anyway,
and the ARM710T would already be fine without --fix-v4bx.

>> It would also be helpful
>> to test whether the -march=armv4t/--fix-v4bx workaround produces
>> working binaries for you, in that case you could report to the gcc
>> developers that the removal of armv4 can continue but that
>> the --fix-v4bx option in ld needs to stay around.
>
> I may ask this issue on OE/Yocto mailing list as well....

To clarify, the only  affected platforms are those based on either
DEC/Intel StrongARM or Faraday FA526, i.e. EBSA-110,
FootBridge, RPC, SA1100, Moxart and Gemini.

       Arnd

^ permalink raw reply

* [PATCH 1/2] ARM: dts: sun8i: h3: nanopi-m1-plus: fix missing ethernet 0 in aliases
From: Philipp Rossak @ 2017-12-18 11:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171218064508.iyi4cyjkwesoezf5@flea.lan>

Sorry!
I will fix it!

On 18.12.2017 07:45, Maxime Ripard wrote:
> Hi,
> 
> On Fri, Dec 15, 2017 at 11:39:00PM +0100, Philipp Rossak wrote:
>> Signed-off-by: Philipp Rossak <embed3d@gmail.com>
> 
> Please add a commit log here.
> 

^ permalink raw reply

* [PATCH v4 4/4] ARM: imx_v6_v7_defconfig: enable RTC_DRV_MXC_V2
From: linux-kernel-dev at beckhoff.com @ 2017-12-18 11:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171218115133.16371-1-linux-kernel-dev@beckhoff.com>

From: Patrick Bruenn <p.bruenn@beckhoff.com>

Enable SRTC driver for i.MX53 in default config

Signed-off-by: Patrick Bruenn <p.bruenn@beckhoff.com>

---
v3:
- imx_v4_v5_defconfig was the wrong default config for i.MX53

Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de> (maintainer:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE)

Cc: Alessandro Zummo <a.zummo@towertech.it>
Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com> (maintainer:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS)
Cc: linux-rtc at vger.kernel.org (open list:REAL TIME CLOCK (RTC) SUBSYSTEM)
Cc: devicetree at vger.kernel.org (open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS)
Cc: linux-kernel at vger.kernel.org (open list)
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Juergen Borleis <jbe@pengutronix.de>
Cc: Noel Vellemans <Noel.Vellemans@visionbms.com>
Cc: Russell King <linux@armlinux.org.uk> (maintainer:ARM PORT)
Cc: linux-arm-kernel at lists.infradead.org (moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE)

Cc: Philippe Ombredanne <pombredanne@nexb.com>
Cc: Lothar Wa?mann <LW@KARO-electronics.de>
---
 arch/arm/configs/imx_v6_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 0d4494922561..548c11142a4e 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -349,6 +349,7 @@ CONFIG_RTC_DRV_PCF8563=y
 CONFIG_RTC_DRV_M41T80=y
 CONFIG_RTC_DRV_MC13XXX=y
 CONFIG_RTC_DRV_MXC=y
+CONFIG_RTC_DRV_MXC_V2=y
 CONFIG_RTC_DRV_SNVS=y
 CONFIG_DMADEVICES=y
 CONFIG_FSL_EDMA=y
-- 
2.11.0

^ permalink raw reply related

* [PATCH v4 3/4] rtc: add mxc driver for i.MX53 SRTC
From: linux-kernel-dev at beckhoff.com @ 2017-12-18 11:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171218115133.16371-1-linux-kernel-dev@beckhoff.com>

From: Patrick Bruenn <p.bruenn@beckhoff.com>

Neither rtc-imxdi, rtc-mxc nor rtc-snvs are compatible with i.MX53.

This is driver enables support for the low power domain SRTC features:
- 32-bit MSB of non-rollover time counter
- 32-bit alarm register

Select the new config option RTC_DRV_MXC_V2 to build this driver

Based on:
http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git/tree/drivers/rtc/rtc-mxc_v2.c?h=imx_2.6.35_11.09.01

Signed-off-by: Patrick Bruenn <p.bruenn@beckhoff.com>

---

v3:
- introduce new config option with the same patch, which adds the driver
- call rtc_update_irq() only if necessary
- merge mxc_rtc_write_alarm_locked() with mxc_rtc_set_alarm()
- only use clk_enable/disable (without "prepare") during operation
- rebase on v4.15-rc3
- consistently use rtc_tm_to_time64() and time64_t
- refactor mxc_rtc_read_time(): don't lock for readl() only;
  don't rtc_valid_tm(); use time64_t
- check returncode of mxc_rtc_wait_for_flag()
- restructure mxc_rtc_sync_lp_locked() to replace pr_err() with
  dev_err_once(); remove explicit 'inline'
- don't touch imx_v4_v5_defconfig, instead add to imx_v6_v7_defconfig

v2:
- have seperate patches for dt-binding, CONFIG option, imx53.dtsi and driver
- add SPDX-License-Identifier and cleanup copyright notice
- replace __raw_readl/writel() with readl/writel()
- fix PM_SLEEP callbacks
- add CONFIG_RTC_DRV_MXC_V2 to build rtc-mxc_v2.c
- remove misleading or obvious comments and fix style of the remaining
- avoid endless loop while waiting for hw
- implement consistent locking; make spinlock a member of dev struct
- enable clk only for register accesses
- remove all udelay() calls since they are obsolete or redundant
  (we are already waiting for register flags to change)
- init platform_data before registering irq callback
- let set_time() fail, when 32 bit rtc counter exceeded
- make names more consistent
- cleanup and reorder includes
- cleanup and remove unused defines

Cc: Alessandro Zummo <a.zummo@towertech.it>
Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com> (maintainer:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS)
Cc: linux-rtc at vger.kernel.org (open list:REAL TIME CLOCK (RTC) SUBSYSTEM)
Cc: devicetree at vger.kernel.org (open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS)
Cc: linux-kernel at vger.kernel.org (open list)
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Juergen Borleis <jbe@pengutronix.de>
Cc: Noel Vellemans <Noel.Vellemans@visionbms.com>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de> (maintainer:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE)
Cc: Russell King <linux@armlinux.org.uk> (maintainer:ARM PORT)
Cc: linux-arm-kernel at lists.infradead.org (moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE)

Cc: Philippe Ombredanne <pombredanne@nexb.com>
Cc: Lothar Wa?mann <LW@KARO-electronics.de>
---
 drivers/rtc/Kconfig      |  10 ++
 drivers/rtc/Makefile     |   1 +
 drivers/rtc/rtc-mxc_v2.c | 422 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 433 insertions(+)
 create mode 100644 drivers/rtc/rtc-mxc_v2.c

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index b59a31b079a5..440edebf5c71 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1689,6 +1689,16 @@ config RTC_DRV_MXC
 	   This driver can also be built as a module, if so, the module
 	   will be called "rtc-mxc".
 
+config RTC_DRV_MXC_V2
+	tristate "Freescale MXC Real Time Clock for i.MX53"
+	depends on ARCH_MXC
+	help
+	   If you say yes here you get support for the Freescale MXC
+	   SRTC module in i.MX53 processor.
+
+	   This driver can also be built as a module, if so, the module
+	   will be called "rtc-mxc_v2".
+
 config RTC_DRV_SNVS
 	tristate "Freescale SNVS RTC support"
 	select REGMAP_MMIO
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index f2f50c11dc38..dcf60e61ae5c 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -106,6 +106,7 @@ obj-$(CONFIG_RTC_DRV_MT6397)	+= rtc-mt6397.o
 obj-$(CONFIG_RTC_DRV_MT7622)	+= rtc-mt7622.o
 obj-$(CONFIG_RTC_DRV_MV)	+= rtc-mv.o
 obj-$(CONFIG_RTC_DRV_MXC)	+= rtc-mxc.o
+obj-$(CONFIG_RTC_DRV_MXC_V2)	+= rtc-mxc_v2.o
 obj-$(CONFIG_RTC_DRV_NUC900)	+= rtc-nuc900.o
 obj-$(CONFIG_RTC_DRV_OMAP)	+= rtc-omap.o
 obj-$(CONFIG_RTC_DRV_OPAL)	+= rtc-opal.o
diff --git a/drivers/rtc/rtc-mxc_v2.c b/drivers/rtc/rtc-mxc_v2.c
new file mode 100644
index 000000000000..b637095b0716
--- /dev/null
+++ b/drivers/rtc/rtc-mxc_v2.c
@@ -0,0 +1,422 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Real Time Clock (RTC) Driver for i.MX53
+ * Copyright (c) 2004-2011 Freescale Semiconductor, Inc.
+ * Copyright (c) 2017 Beckhoff Automation GmbH & Co. KG
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+#define SRTC_LPPDR_INIT       0x41736166	/* init for glitch detect */
+
+#define SRTC_LPCR_EN_LP       BIT(3)	/* lp enable */
+#define SRTC_LPCR_WAE         BIT(4)	/* lp wakeup alarm enable */
+#define SRTC_LPCR_ALP         BIT(7)	/* lp alarm flag */
+#define SRTC_LPCR_NSA         BIT(11)	/* lp non secure access */
+#define SRTC_LPCR_NVE         BIT(14)	/* lp non valid state exit bit */
+#define SRTC_LPCR_IE          BIT(15)	/* lp init state exit bit */
+
+#define SRTC_LPSR_ALP         BIT(3)	/* lp alarm flag */
+#define SRTC_LPSR_NVES        BIT(14)	/* lp non-valid state exit status */
+#define SRTC_LPSR_IES         BIT(15)	/* lp init state exit status */
+
+#define SRTC_LPSCMR	0x00	/* LP Secure Counter MSB Reg */
+#define SRTC_LPSCLR	0x04	/* LP Secure Counter LSB Reg */
+#define SRTC_LPSAR	0x08	/* LP Secure Alarm Reg */
+#define SRTC_LPCR	0x10	/* LP Control Reg */
+#define SRTC_LPSR	0x14	/* LP Status Reg */
+#define SRTC_LPPDR	0x18	/* LP Power Supply Glitch Detector Reg */
+
+/* max. number of retries to read registers, 120 was max during test */
+#define REG_READ_TIMEOUT 2000
+
+struct mxc_rtc_data {
+	struct rtc_device *rtc;
+	void __iomem *ioaddr;
+	struct clk *clk;
+	spinlock_t lock; /* protects register access */
+	int irq;
+};
+
+/*
+ * This function does write synchronization for writes to the lp srtc block.
+ * To take care of the asynchronous CKIL clock, all writes from the IP domain
+ * will be synchronized to the CKIL domain.
+ * The caller should hold the pdata->lock
+ */
+static void mxc_rtc_sync_lp_locked(struct device *dev, void __iomem *ioaddr)
+{
+	unsigned int i;
+
+	/* Wait for 3 CKIL cycles */
+	for (i = 0; i < 3; i++) {
+		const u32 count = readl(ioaddr + SRTC_LPSCLR);
+		unsigned int timeout = REG_READ_TIMEOUT;
+
+		while ((readl(ioaddr + SRTC_LPSCLR)) == count) {
+			if (!--timeout) {
+				dev_err_once(dev, "SRTC_LPSCLR stuck! Check your hw.\n");
+				return;
+			}
+		}
+	}
+}
+
+/* This function is the RTC interrupt service routine. */
+static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id)
+{
+	struct device *dev = dev_id;
+	struct mxc_rtc_data *pdata = dev_get_drvdata(dev);
+	void __iomem *ioaddr = pdata->ioaddr;
+	unsigned long flags;
+	u32 lp_status;
+	u32 lp_cr;
+
+	spin_lock_irqsave(&pdata->lock, flags);
+	if (clk_enable(pdata->clk)) {
+		spin_unlock_irqrestore(&pdata->lock, flags);
+		return IRQ_NONE;
+	}
+
+	lp_status = readl(ioaddr + SRTC_LPSR);
+	lp_cr = readl(ioaddr + SRTC_LPCR);
+
+	/* update irq data & counter */
+	if (lp_status & SRTC_LPSR_ALP) {
+		if (lp_cr & SRTC_LPCR_ALP)
+			rtc_update_irq(pdata->rtc, 1, RTC_AF | RTC_IRQF);
+
+		/* disable further lp alarm interrupts */
+		lp_cr &= ~(SRTC_LPCR_ALP | SRTC_LPCR_WAE);
+	}
+
+	/* Update interrupt enables */
+	writel(lp_cr, ioaddr + SRTC_LPCR);
+
+	/* clear interrupt status */
+	writel(lp_status, ioaddr + SRTC_LPSR);
+
+	mxc_rtc_sync_lp_locked(dev, ioaddr);
+	clk_disable(pdata->clk);
+	spin_unlock_irqrestore(&pdata->lock, flags);
+	return IRQ_HANDLED;
+}
+
+/*
+ * Enable clk and aquire spinlock
+ * @return  0 if successful; non-zero otherwise.
+ */
+static int mxc_rtc_lock(struct mxc_rtc_data *const pdata)
+{
+	int ret;
+
+	spin_lock_irq(&pdata->lock);
+	ret = clk_enable(pdata->clk);
+	if (ret) {
+		spin_unlock_irq(&pdata->lock);
+		return ret;
+	}
+	return 0;
+}
+
+static int mxc_rtc_unlock(struct mxc_rtc_data *const pdata)
+{
+	clk_disable(pdata->clk);
+	spin_unlock_irq(&pdata->lock);
+	return 0;
+}
+
+/*
+ * This function reads the current RTC time into tm in Gregorian date.
+ *
+ * @param  tm           contains the RTC time value upon return
+ *
+ * @return  0 if successful; non-zero otherwise.
+ */
+static int mxc_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct mxc_rtc_data *pdata = dev_get_drvdata(dev);
+	const int clk_failed = clk_enable(pdata->clk);
+
+	if (!clk_failed) {
+		const time64_t now = readl(pdata->ioaddr + SRTC_LPSCMR);
+
+		rtc_time64_to_tm(now, tm);
+		clk_disable(pdata->clk);
+		return 0;
+	}
+	return clk_failed;
+}
+
+/*
+ * This function sets the internal RTC time based on tm in Gregorian date.
+ *
+ * @param  tm           the time value to be set in the RTC
+ *
+ * @return  0 if successful; non-zero otherwise.
+ */
+static int mxc_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct mxc_rtc_data *pdata = dev_get_drvdata(dev);
+	time64_t time = rtc_tm_to_time64(tm);
+	int ret;
+
+	if (time > U32_MAX) {
+		dev_err(dev, "RTC exceeded by %llus\n", time - U32_MAX);
+		return -EINVAL;
+	}
+
+	ret = mxc_rtc_lock(pdata);
+	if (ret)
+		return ret;
+
+	writel(time, pdata->ioaddr + SRTC_LPSCMR);
+	mxc_rtc_sync_lp_locked(dev, pdata->ioaddr);
+	return mxc_rtc_unlock(pdata);
+}
+
+/*
+ * This function reads the current alarm value into the passed in \b alrm
+ * argument. It updates the \b alrm's pending field value based on the whether
+ * an alarm interrupt occurs or not.
+ *
+ * @param  alrm         contains the RTC alarm value upon return
+ *
+ * @return  0 if successful; non-zero otherwise.
+ */
+static int mxc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct mxc_rtc_data *pdata = dev_get_drvdata(dev);
+	void __iomem *ioaddr = pdata->ioaddr;
+	int ret;
+
+	ret = mxc_rtc_lock(pdata);
+	if (ret)
+		return ret;
+
+	rtc_time_to_tm(readl(ioaddr + SRTC_LPSAR), &alrm->time);
+	alrm->pending = !!(readl(ioaddr + SRTC_LPSR) & SRTC_LPSR_ALP);
+	return mxc_rtc_unlock(pdata);
+}
+
+/*
+ * Enable/Disable alarm interrupt
+ * The caller should hold the pdata->lock
+ */
+static void mxc_rtc_alarm_irq_enable_locked(struct mxc_rtc_data *pdata,
+					    unsigned int enable)
+{
+	u32 lp_cr = readl(pdata->ioaddr + SRTC_LPCR);
+
+	if (enable)
+		lp_cr |= (SRTC_LPCR_ALP | SRTC_LPCR_WAE);
+	else
+		lp_cr &= ~(SRTC_LPCR_ALP | SRTC_LPCR_WAE);
+
+	writel(lp_cr, pdata->ioaddr + SRTC_LPCR);
+}
+
+static int mxc_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
+{
+	struct mxc_rtc_data *pdata = dev_get_drvdata(dev);
+	int ret = mxc_rtc_lock(pdata);
+
+	if (ret)
+		return ret;
+
+	mxc_rtc_alarm_irq_enable_locked(pdata, enable);
+	return mxc_rtc_unlock(pdata);
+}
+
+/*
+ * This function sets the RTC alarm based on passed in alrm.
+ *
+ * @param  alrm         the alarm value to be set in the RTC
+ *
+ * @return  0 if successful; non-zero otherwise.
+ */
+static int mxc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	const time64_t time = rtc_tm_to_time64(&alrm->time);
+	struct mxc_rtc_data *pdata = dev_get_drvdata(dev);
+	int ret = mxc_rtc_lock(pdata);
+
+	if (ret)
+		return ret;
+
+	if (time > U32_MAX) {
+		dev_err(dev, "Hopefully I am out of service by then :-(\n");
+		return -EINVAL;
+	}
+
+	writel((u32)time, pdata->ioaddr + SRTC_LPSAR);
+
+	/* clear alarm interrupt status bit */
+	writel(SRTC_LPSR_ALP, pdata->ioaddr + SRTC_LPSR);
+	mxc_rtc_sync_lp_locked(dev, pdata->ioaddr);
+
+	mxc_rtc_alarm_irq_enable_locked(pdata, alrm->enabled);
+	mxc_rtc_sync_lp_locked(dev, pdata->ioaddr);
+	mxc_rtc_unlock(pdata);
+	return ret;
+}
+
+static const struct rtc_class_ops mxc_rtc_ops = {
+	.read_time = mxc_rtc_read_time,
+	.set_time = mxc_rtc_set_time,
+	.read_alarm = mxc_rtc_read_alarm,
+	.set_alarm = mxc_rtc_set_alarm,
+	.alarm_irq_enable = mxc_rtc_alarm_irq_enable,
+};
+
+static int mxc_rtc_wait_for_flag(void *__iomem ioaddr, int flag)
+{
+	unsigned int timeout = REG_READ_TIMEOUT;
+
+	while (!(readl(ioaddr) & flag)) {
+		if (!--timeout)
+			return -EBUSY;
+	}
+	return 0;
+}
+
+static int mxc_rtc_probe(struct platform_device *pdev)
+{
+	struct mxc_rtc_data *pdata;
+	struct resource *res;
+	void __iomem *ioaddr;
+	int ret = 0;
+
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
+	pdata->ioaddr = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(pdata->ioaddr))
+		return PTR_ERR(pdata->ioaddr);
+
+	ioaddr = pdata->ioaddr;
+
+	pdata->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(pdata->clk)) {
+		dev_err(&pdev->dev, "unable to get rtc clock!\n");
+		return PTR_ERR(pdata->clk);
+	}
+
+	spin_lock_init(&pdata->lock);
+	pdata->irq = platform_get_irq(pdev, 0);
+	if (pdata->irq < 0)
+		return pdata->irq;
+
+	device_init_wakeup(&pdev->dev, 1);
+
+	ret = clk_prepare_enable(pdata->clk);
+	if (ret)
+		return ret;
+	/* initialize glitch detect */
+	writel(SRTC_LPPDR_INIT, ioaddr + SRTC_LPPDR);
+
+	/* clear lp interrupt status */
+	writel(0xFFFFFFFF, ioaddr + SRTC_LPSR);
+
+	/* move out of init state */
+	writel((SRTC_LPCR_IE | SRTC_LPCR_NSA), ioaddr + SRTC_LPCR);
+	ret = mxc_rtc_wait_for_flag(ioaddr + SRTC_LPSR, SRTC_LPSR_IES);
+	if (ret) {
+		dev_err(&pdev->dev, "Timeout waiting for SRTC_LPSR_IES\n");
+		clk_disable_unprepare(pdata->clk);
+		return ret;
+	}
+
+	/* move out of non-valid state */
+	writel((SRTC_LPCR_IE | SRTC_LPCR_NVE | SRTC_LPCR_NSA |
+		SRTC_LPCR_EN_LP), ioaddr + SRTC_LPCR);
+	ret = mxc_rtc_wait_for_flag(ioaddr + SRTC_LPSR, SRTC_LPSR_NVES);
+	if (ret) {
+		dev_err(&pdev->dev, "Timeout waiting for SRTC_LPSR_NVES\n");
+		clk_disable_unprepare(pdata->clk);
+		return ret;
+	}
+
+	clk_disable(pdata->clk);
+	platform_set_drvdata(pdev, pdata);
+	ret =
+	    devm_request_irq(&pdev->dev, pdata->irq, mxc_rtc_interrupt, 0,
+			     pdev->name, &pdev->dev);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "interrupt not available.\n");
+		clk_unprepare(pdata->clk);
+		return ret;
+	}
+
+	pdata->rtc =
+	    devm_rtc_device_register(&pdev->dev, pdev->name, &mxc_rtc_ops,
+				     THIS_MODULE);
+	if (IS_ERR(pdata->rtc)) {
+		clk_unprepare(pdata->clk);
+		return PTR_ERR(pdata->rtc);
+	}
+
+	return 0;
+}
+
+static int __exit mxc_rtc_remove(struct platform_device *pdev)
+{
+	struct mxc_rtc_data *pdata = platform_get_drvdata(pdev);
+
+	clk_disable_unprepare(pdata->clk);
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int mxc_rtc_suspend(struct device *dev)
+{
+	struct mxc_rtc_data *pdata = dev_get_drvdata(dev);
+
+	if (device_may_wakeup(dev))
+		enable_irq_wake(pdata->irq);
+
+	return 0;
+}
+
+static int mxc_rtc_resume(struct device *dev)
+{
+	struct mxc_rtc_data *pdata = dev_get_drvdata(dev);
+
+	if (device_may_wakeup(dev))
+		disable_irq_wake(pdata->irq);
+
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(mxc_rtc_pm_ops, mxc_rtc_suspend, mxc_rtc_resume);
+
+static const struct of_device_id mxc_ids[] = {
+	{ .compatible = "fsl,imx53-rtc", },
+	{}
+};
+
+static struct platform_driver mxc_rtc_driver = {
+	.driver = {
+		.name = "mxc_rtc_v2",
+		.of_match_table = mxc_ids,
+		.pm = &mxc_rtc_pm_ops,
+	},
+	.probe = mxc_rtc_probe,
+	.remove = mxc_rtc_remove,
+};
+
+module_platform_driver(mxc_rtc_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("Real Time Clock (RTC) Driver for i.MX53");
+MODULE_LICENSE("GPL");
-- 
2.11.0

^ permalink raw reply related

* [PATCH v4 2/4] ARM: dts: imx53: add srtc node
From: linux-kernel-dev at beckhoff.com @ 2017-12-18 11:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171218115133.16371-1-linux-kernel-dev@beckhoff.com>

From: Patrick Bruenn <p.bruenn@beckhoff.com>

rtc-mxc_v2 driver will add support for the i.MX53 SRTC

Note: we keep the 'srtc' label to avoid duplicate with imx53-m53.dtsi

Signed-off-by: Patrick Bruenn <p.bruenn@beckhoff.com>

---

v4:
- replace "srtc" node name with generic "rtc"

Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de> (maintainer:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE)

Cc: Alessandro Zummo <a.zummo@towertech.it>
Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com> (maintainer:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS)
Cc: linux-rtc at vger.kernel.org (open list:REAL TIME CLOCK (RTC) SUBSYSTEM)
Cc: devicetree at vger.kernel.org (open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS)
Cc: linux-kernel at vger.kernel.org (open list)
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Juergen Borleis <jbe@pengutronix.de>
Cc: Noel Vellemans <Noel.Vellemans@visionbms.com>
Cc: Russell King <linux@armlinux.org.uk> (maintainer:ARM PORT)
Cc: linux-arm-kernel at lists.infradead.org (moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE)

Cc: Philippe Ombredanne <pombredanne@nexb.com>
Cc: Lothar Wa?mann <LW@KARO-electronics.de>
---
 arch/arm/boot/dts/imx53.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi
index 84f17f7abb71..beca1c830623 100644
--- a/arch/arm/boot/dts/imx53.dtsi
+++ b/arch/arm/boot/dts/imx53.dtsi
@@ -433,6 +433,13 @@
 				clock-names = "ipg", "per";
 			};
 
+			srtc: rtc at 53fa4000 {
+				compatible = "fsl,imx53-rtc";
+				reg = <0x53fa4000 0x4000>;
+				interrupts = <24>;
+				clocks = <&clks IMX5_CLK_SRTC_GATE>;
+			};
+
 			iomuxc: iomuxc at 53fa8000 {
 				compatible = "fsl,imx53-iomuxc";
 				reg = <0x53fa8000 0x4000>;
-- 
2.11.0

^ permalink raw reply related

* [PATCH v4 1/4] dt-bindings: rtc: add bindings for i.MX53 SRTC
From: linux-kernel-dev at beckhoff.com @ 2017-12-18 11:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171218115133.16371-1-linux-kernel-dev@beckhoff.com>

From: Patrick Bruenn <p.bruenn@beckhoff.com>

Document the binding for i.MX53 SRTC implemented by rtc-mxc_v2

Signed-off-by: Patrick Bruenn <p.bruenn@beckhoff.com>

---

v4:
- replace "srtc" node name with generic "rtc"

v2:
- added "Secure" and (SRTC) to the description

Cc: Alessandro Zummo <a.zummo@towertech.it>
Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com>

Cc: Rob Herring <robh+dt@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com> (maintainer:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS)
Cc: linux-rtc at vger.kernel.org (open list:REAL TIME CLOCK (RTC) SUBSYSTEM)
Cc: devicetree at vger.kernel.org (open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS)
Cc: linux-kernel at vger.kernel.org (open list)
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Juergen Borleis <jbe@pengutronix.de>
Cc: Noel Vellemans <Noel.Vellemans@visionbms.com>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de> (maintainer:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE)
Cc: Russell King <linux@armlinux.org.uk> (maintainer:ARM PORT)
Cc: linux-arm-kernel at lists.infradead.org (moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE)

Cc: Philippe Ombredanne <pombredanne@nexb.com>
Cc: Lothar Wa?mann <LW@KARO-electronics.de>
---
 Documentation/devicetree/bindings/rtc/rtc-mxc_v2.txt | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/rtc/rtc-mxc_v2.txt

diff --git a/Documentation/devicetree/bindings/rtc/rtc-mxc_v2.txt b/Documentation/devicetree/bindings/rtc/rtc-mxc_v2.txt
new file mode 100644
index 000000000000..79d7e87b0d91
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/rtc-mxc_v2.txt
@@ -0,0 +1,17 @@
+* i.MX53 Secure Real Time Clock (SRTC)
+
+Required properties:
+- compatible: should be: "fsl,imx53-rtc"
+- reg: physical base address of the controller and length of memory mapped
+  region.
+- clocks: should contain the phandle for the rtc clock
+- interrupts: rtc alarm interrupt
+
+Example:
+
+rtc at 53fa4000 {
+	compatible = "fsl,imx53-rtc";
+	reg = <0x53fa4000 0x4000>;
+	interrupts = <24>;
+	clocks = <&clks IMX5_CLK_SRTC_GATE>;
+};
-- 
2.11.0

^ permalink raw reply related

* [PATCH v4 0/4] rtc: add mxc driver for i.MX53 SRTC
From: linux-kernel-dev at beckhoff.com @ 2017-12-18 11:51 UTC (permalink / raw)
  To: linux-arm-kernel

From: Patrick Bruenn <p.bruenn@beckhoff.com>

Neither rtc-imxdi, rtc-mxc nor rtc-snvs are compatible with i.MX53.

This is driver enables support for the low power domain SRTC features:
- 32-bit MSB of non-rollover time counter
- 32-bit alarm register

Select the new config option RTC_DRV_MXC_V2 to build this driver

Based on:
http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git/tree/drivers/rtc/rtc-mxc_v2.c?h=imx_2.6.35_11.09.01

Signed-off-by: Patrick Bruenn <p.bruenn@beckhoff.com>

---

v4:
- rename "srtc" node into generic "rtc" keep the label as "srtc" to avoid
  duplication with imx53-m53.dtsi
- fix Signed-off-by: in bindings-patch

v3:
- introduce new config option with the same patch, which adds the driver
- call rtc_update_irq() only if necessary
- merge mxc_rtc_write_alarm_locked() with mxc_rtc_set_alarm()
- only use clk_enable/disable (without "prepare") during operation
- rebase on v4.15-rc3
- consistently use rtc_tm_to_time64() and time64_t
- refactor mxc_rtc_read_time(): don't lock for readl() only;
  don't rtc_valid_tm(); use time64_t
- check returncode of mxc_rtc_wait_for_flag()
- restructure mxc_rtc_sync_lp_locked() to replace pr_err() with
  dev_err_once(); remove explicit 'inline'
- don't touch imx_v4_v5_defconfig, instead add to imx_v6_v7_defconfig

v2:
- have seperate patches for dt-binding, CONFIG option, imx53.dtsi and driver
- add SPDX-License-Identifier and cleanup copyright notice
- replace __raw_readl/writel() with readl/writel()
- fix PM_SLEEP callbacks
- add CONFIG_RTC_DRV_MXC_V2 to build rtc-mxc_v2.c
- remove misleading or obvious comments and fix style of the remaining
- avoid endless loop while waiting for hw
- implement consistent locking; make spinlock a member of dev struct
- enable clk only for register accesses
- remove all udelay() calls since they are obsolete or redundant
  (we are already waiting for register flags to change)
- init platform_data before registering irq callback
- let set_time() fail, when 32 bit rtc counter exceeded
- make names more consistent
- cleanup and reorder includes
- cleanup and remove unused defines

Cc: Alessandro Zummo <a.zummo@towertech.it>
Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com> (maintainer:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS)
Cc: linux-rtc at vger.kernel.org (open list:REAL TIME CLOCK (RTC) SUBSYSTEM)
Cc: devicetree at vger.kernel.org (open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS)
Cc: linux-kernel at vger.kernel.org (open list)
Cc: Fabio Estevam <fabio.estevam@nxp.com>
Cc: Juergen Borleis <jbe@pengutronix.de>
Cc: Noel Vellemans <Noel.Vellemans@visionbms.com>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <kernel@pengutronix.de> (maintainer:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE)
Cc: Russell King <linux@armlinux.org.uk> (maintainer:ARM PORT)
Cc: linux-arm-kernel at lists.infradead.org (moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE)

Cc: Philippe Ombredanne <pombredanne@nexb.com>
Cc: Lothar Wa?mann <LW@KARO-electronics.de>
---

Patrick Bruenn (4):
  dt-bindings: rtc: add bindings for i.MX53 SRTC
  ARM: dts: imx53: add srtc node
  rtc: add mxc driver for i.MX53 SRTC
  ARM: imx_v6_v7_defconfig: enable RTC_DRV_MXC_V2

 .../devicetree/bindings/rtc/rtc-mxc_v2.txt         |  17 +
 arch/arm/boot/dts/imx53.dtsi                       |   7 +
 arch/arm/configs/imx_v6_v7_defconfig               |   1 +
 drivers/rtc/Kconfig                                |  10 +
 drivers/rtc/Makefile                               |   1 +
 drivers/rtc/rtc-mxc_v2.c                           | 422 +++++++++++++++++++++
 6 files changed, 458 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/rtc/rtc-mxc_v2.txt
 create mode 100644 drivers/rtc/rtc-mxc_v2.c

-- 
2.11.0

^ permalink raw reply

* [RFC PATCH 5/5] ARM: NOMMU: Support PMSAv8 MPU
From: Vladimir Murzin @ 2017-12-18 11:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171214050111.GA5097@afzalpc>

Hi,

On 14/12/17 05:01, afzal mohammed wrote:
> Hi,
> 
> On Wed, Dec 13, 2017 at 05:02:07PM +0000, Vladimir Murzin wrote:
> 
>> ARMv8R/M architecture defines new memory protection scheme - PMSAv8
> 
> Is there a public ARMv8-R architecture reference manual available ?,
> seems only ARMv8-A and ARMv8-M ARM's are publically available.

Not sure why it is not there yet, but with respect to the patch set
you might get PMSA-v8 related information from Cortex-R52 TRM [1].

[1] https://developer.arm.com/docs/100026/latest/preface

Vladimir

> 
> afzal
> 

^ permalink raw reply

* [PATCH 0/2] Use SPDX-License-Identifier for rockchip devicetree files
From: Matthias Brugger @ 2017-12-18 11:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <24788EB1-9868-41E9-B97C-7D85D8C3761D@theobroma-systems.com>



On 12/15/2017 05:27 PM, klaus.goger at theobroma-systems.com wrote:
>> On 15.12.2017, at 16:20, Heiko St?bner <heiko@sntech.de> wrote:
>>
>> Am Freitag, 15. Dezember 2017, 15:42:48 CET schrieb Philippe Ombredanne:
>>> On Fri, Dec 15, 2017 at 3:28 PM, Heiko St?bner <heiko@sntech.de> wrote:
>>>> Am Freitag, 15. Dezember 2017, 14:45:34 CET schrieb Philippe Ombredanne:
>>>>> Klaus,
>>>>>
>>>>> On Fri, Dec 15, 2017 at 12:44 PM, Klaus Goger
>>>>>
>>>>> <klaus.goger@theobroma-systems.com> wrote:
>>>>>> This patch series replaces all the license text in rockchip devicetree
>>>>>> files text with a proper SPDX-License-Identifier.
>>>>>> It follows the guidelines submitted[1] by Thomas Gleixner that are not
>>>>>> yet merged.
>>>>>>
>>>>>> These series also fixes the issue with contradicting statements in most
>>>>>> licenses. The introduction text claims to be GPL or X11[2] but the
>>>>>> following verbatim copy of the license is actually a MIT[3] license.
>>>>>> The X11 license includes a advertise clause and trademark information
>>>>>> related to the X Consortium. As these X Consortium specfic points are
>>>>>> irrelevant for us we stick with the actuall license text.
>>>>>>
>>>>>> [1] https://patchwork.kernel.org/patch/10091607/
>>>>>> [2] https://spdx.org/licenses/X11.html
>>>>>> [3] https://spdx.org/licenses/MIT.html
>>>>>
>>>>> FWIW, the X11 license name was not always something clearly defined.
>>>>> SPDX calls it clearly MIT which is the most widely accepted name for
>>>>> the corresponding text. And this is also what we have in Thomas doc
>>>>> patches that should be the kernel reference.
>>>>>
>>>>> Also, as a general note, you want to make sure that such as patch set
>>>>> is not merged by mistake until you have collected an explicit review
>>>>> or ack from all the copyright holders involved.
>>>>
>>>> Just for my understanding, is it really necessary to get Acks from _all_
>>>> previous contributors?
>>>>
>>>> I see that Thomas patches moving license texts into the kernel itself do
>>>> not seem to have landed yet, but when the actual license text does _not_
>>>> change and only its location to a common place inside the kernel sources,
>>>> it feels a bit overkill trying to get Acks from _everybody_ that
>>>> contributed to Rockchip devicetrees for the last 4 years.
>>>>
>>>> If we would actually want to change the license I would definitly feel
>>>> differently, but the license text does not change.
>>>
>>> Well you are technically right. But there is a social and politeness
>>> angle to this too. So may be getting the ack of all contributors is
>>> not always needed, but getting it is best and the right to do and at
>>> least getting for the named copyright holders should be there.
>>>
>>> That's only only my take: leaving aside any technical legal issue, say
>>> I would be on the receiving end as one of the holder or contributors:
>>> I would find it really great and nice to have my ack requested. And I
>>> would be a dork not to give it. So I like to do to others the same I
>>> would appreciate done to me (within reason, as I sometimes shoot
>>> myself in the foot ;) )
>>
>> Hehe ... I didn't plan on merging this without ample time for people
>> to either ACK or NAK the change, so was planning on keeping to social
>> protocol ;-) . Just the "all" threw me for a loop.
>>
>> And having that as PATCH without RFC also communicates that people
>> should take a look, as RFC patches are often overlooked.
>>
>> As Klaus seems to have included most people that have contributed in the
>> past, I would guess we should receive any existing complaints about that
>> change :-) .
> 
> I added the full list from the get_maintainers script. Some of the original authors
> got dropped as the current contribution level dropped below the scripts limit.
> I added the missing email addresses from the copyright headers to the CC list. 
> 
> Convenience links to the original patches for the added people:
> 
> https://patchwork.kernel.org/patch/10114845/
> https://patchwork.kernel.org/patch/10114843/
> 

For both patches:
Acked-by: Matthias Brugger <mbrugger@suse.com>

^ permalink raw reply

* [PATCH] pwm: omap-dmtimer: Fix frequency when using prescaler
From: Ladislav Michl @ 2017-12-18 11:38 UTC (permalink / raw)
  To: linux-arm-kernel

Prescaler setting is currently not taken into account.
Fix that by introducing freq member variable and initialize
it at device probe time. This also avoids frequency
recomputing at each pwm configure time.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 drivers/pwm/pwm-omap-dmtimer.c | 66 +++++++++++++++++++++++++-----------------
 1 file changed, 39 insertions(+), 27 deletions(-)

diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c
index 3b27aff585b7..0a23d1c1b153 100644
--- a/drivers/pwm/pwm-omap-dmtimer.c
+++ b/drivers/pwm/pwm-omap-dmtimer.c
@@ -40,6 +40,7 @@ struct pwm_omap_dmtimer_chip {
 	pwm_omap_dmtimer *dm_timer;
 	struct omap_dm_timer_ops *pdata;
 	struct platform_device *dm_timer_pdev;
+	unsigned long freq;
 };
 
 static inline struct pwm_omap_dmtimer_chip *
@@ -99,8 +100,6 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip,
 	struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip);
 	u32 period_cycles, duty_cycles;
 	u32 load_value, match_value;
-	struct clk *fclk;
-	unsigned long clk_rate;
 	bool timer_active;
 
 	dev_dbg(chip->dev, "requested duty cycle: %d ns, period: %d ns\n",
@@ -114,19 +113,6 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip,
 		return 0;
 	}
 
-	fclk = omap->pdata->get_fclk(omap->dm_timer);
-	if (!fclk) {
-		dev_err(chip->dev, "invalid pmtimer fclk\n");
-		goto err_einval;
-	}
-
-	clk_rate = clk_get_rate(fclk);
-	if (!clk_rate) {
-		dev_err(chip->dev, "invalid pmtimer fclk rate\n");
-		goto err_einval;
-	}
-
-	dev_dbg(chip->dev, "clk rate: %luHz\n", clk_rate);
 
 	/*
 	 * Calculate the appropriate load and match values based on the
@@ -144,35 +130,35 @@ static int pwm_omap_dmtimer_config(struct pwm_chip *chip,
 	 *   OMAP4430/60/70 TRM sections 22.2.4.10 and 22.2.4.11
 	 *   AM335x Sitara TRM sections 20.1.3.5 and 20.1.3.6
 	 */
-	period_cycles = pwm_omap_dmtimer_get_clock_cycles(clk_rate, period_ns);
-	duty_cycles = pwm_omap_dmtimer_get_clock_cycles(clk_rate, duty_ns);
+	period_cycles = pwm_omap_dmtimer_get_clock_cycles(omap->freq, period_ns);
+	duty_cycles = pwm_omap_dmtimer_get_clock_cycles(omap->freq, duty_ns);
 
 	if (period_cycles < 2) {
 		dev_info(chip->dev,
 			 "period %d ns too short for clock rate %lu Hz\n",
-			 period_ns, clk_rate);
+			 period_ns, omap->freq);
 		goto err_einval;
 	}
 
 	if (duty_cycles < 1) {
 		dev_dbg(chip->dev,
 			"duty cycle %d ns is too short for clock rate %lu Hz\n",
-			duty_ns, clk_rate);
+			duty_ns, omap->freq);
 		dev_dbg(chip->dev, "using minimum of 1 clock cycle\n");
 		duty_cycles = 1;
 	} else if (duty_cycles >= period_cycles) {
 		dev_dbg(chip->dev,
 			"duty cycle %d ns is too long for period %d ns at clock rate %lu Hz\n",
-			duty_ns, period_ns, clk_rate);
+			duty_ns, period_ns, omap->freq);
 		dev_dbg(chip->dev, "using maximum of 1 clock cycle less than period\n");
 		duty_cycles = period_cycles - 1;
 	}
 
 	dev_dbg(chip->dev, "effective duty cycle: %lld ns, period: %lld ns\n",
 		DIV_ROUND_CLOSEST_ULL((u64)NSEC_PER_SEC * duty_cycles,
-				      clk_rate),
+				      omap->freq),
 		DIV_ROUND_CLOSEST_ULL((u64)NSEC_PER_SEC * period_cycles,
-				      clk_rate));
+				      omap->freq));
 
 	load_value = (DM_TIMER_MAX - period_cycles) + 1;
 	match_value = load_value + duty_cycles - 1;
@@ -248,6 +234,7 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
 	struct dmtimer_platform_data *timer_pdata;
 	struct omap_dm_timer_ops *pdata;
 	pwm_omap_dmtimer *dm_timer;
+	struct clk *fclk;
 	u32 v;
 	int status;
 
@@ -311,12 +298,37 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
 	if (pm_runtime_active(&omap->dm_timer_pdev->dev))
 		omap->pdata->stop(omap->dm_timer);
 
-	if (!of_property_read_u32(pdev->dev.of_node, "ti,prescaler", &v))
-		omap->pdata->set_prescaler(omap->dm_timer, v);
-
 	/* setup dmtimer clock source */
-	if (!of_property_read_u32(pdev->dev.of_node, "ti,clock-source", &v))
-		omap->pdata->set_source(omap->dm_timer, v);
+	if (!of_property_read_u32(pdev->dev.of_node, "ti,clock-source", &v)) {
+		status = omap->pdata->set_source(omap->dm_timer, v);
+		if (status) {
+			dev_err(&pdev->dev, "invalid clock-source\n");
+			return status;
+		}
+	}
+
+	fclk = omap->pdata->get_fclk(omap->dm_timer);
+	if (!fclk) {
+		dev_err(&pdev->dev, "invalid fclk\n");
+		return -EINVAL;
+	}
+
+	omap->freq = clk_get_rate(fclk);
+	if (!omap->freq) {
+		dev_err(&pdev->dev, "invalid fclk rate\n");
+		return -EINVAL;
+	}
+
+	if (!of_property_read_u32(pdev->dev.of_node, "ti,prescaler", &v)) {
+		status = omap->pdata->set_prescaler(omap->dm_timer, v);
+		if (status) {
+			dev_err(&pdev->dev, "invalid prescaler\n");
+			return status;
+		}
+		omap->freq >>= v + 1;
+	}
+
+	dev_dbg(&pdev->dev, "clk rate: %luHz\n", omap->freq);
 
 	omap->chip.dev = &pdev->dev;
 	omap->chip.ops = &pwm_omap_dmtimer_ops;
-- 
2.15.1

^ permalink raw reply related

* [PATCH] ARM64: meson-axg: enable hardware rng
From: Jerome Brunet @ 2017-12-18 11:35 UTC (permalink / raw)
  To: linux-arm-kernel

Enable the hardware random generator

Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
Hi Kevin,

This patch depends on the changes adding the ethernet controller [0],
for including the axg clock binding header.

Cheers
Jerome

[0]: https://lkml.kernel.org/r/20171216035527.96952-2-yixun.lan at amlogic.com


 arch/arm64/boot/dts/amlogic/meson-axg.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
index dea1bc31b4de..c741fc16486f 100644
--- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
@@ -212,6 +212,13 @@
 			#size-cells = <2>;
 			ranges = <0x0 0x0 0x0 0xff634000 0x0 0x2000>;
 
+			hwrng: rng {
+				compatible = "amlogic,meson-rng";
+				reg = <0x0 0x18 0x0 0x4>;
+				clocks = <&clkc CLKID_RNG0>;
+				clock-names = "core";
+			};
+
 			pinctrl_periphs: pinctrl at 480 {
 				compatible = "amlogic,meson-axg-periphs-pinctrl";
 				#address-cells = <2>;
-- 
2.14.3

^ permalink raw reply related

* [PATCH 2/2] clocksource: timer-dm: Check prescaler value
From: Ladislav Michl @ 2017-12-18 11:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171218111610.GA16906@lenoch>

Invalid prescaler value is silently ignored. Fix that
by returning -EINVAL in such case. As invalid value
disabled use of the prescaler, use -1 explicitely for
that purpose.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 drivers/clocksource/timer-dm.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/clocksource/timer-dm.c b/drivers/clocksource/timer-dm.c
index ec3a28c90c70..95cd98be8541 100644
--- a/drivers/clocksource/timer-dm.c
+++ b/drivers/clocksource/timer-dm.c
@@ -609,6 +609,9 @@ static int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer,
 	if (prescaler >= 0x00 && prescaler <= 0x07) {
 		l |= OMAP_TIMER_CTRL_PRE;
 		l |= prescaler << 2;
+	} else {
+		if (prescaler != -1)
+			return -EINVAL;
 	}
 	omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
 
-- 
2.15.1

^ permalink raw reply related

* [PATCH 1/2] clocksource: timer-dm: Make unexported functions static
From: Ladislav Michl @ 2017-12-18 11:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171218111610.GA16906@lenoch>

As dmtimer no longer exports functions, there is no point
to have them non-static. Also delete those not used anywhere.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 drivers/clocksource/timer-dm.c | 125 ++++++++---------------------------------
 include/clocksource/dmtimer.h  |  26 ---------
 2 files changed, 23 insertions(+), 128 deletions(-)

diff --git a/drivers/clocksource/timer-dm.c b/drivers/clocksource/timer-dm.c
index 392978ccd8a6..ec3a28c90c70 100644
--- a/drivers/clocksource/timer-dm.c
+++ b/drivers/clocksource/timer-dm.c
@@ -204,16 +204,6 @@ static inline u32 omap_dm_timer_reserved_systimer(int id)
 	return (omap_reserved_systimers & (1 << (id - 1))) ? 1 : 0;
 }
 
-int omap_dm_timer_reserve_systimer(int id)
-{
-	if (omap_dm_timer_reserved_systimer(id))
-		return -ENODEV;
-
-	omap_reserved_systimers |= (1 << (id - 1));
-
-	return 0;
-}
-
 static struct omap_dm_timer *_omap_dm_timer_request(int req_type, void *data)
 {
 	struct omap_dm_timer *timer = NULL, *t;
@@ -298,16 +288,16 @@ static struct omap_dm_timer *_omap_dm_timer_request(int req_type, void *data)
 	return timer;
 }
 
-struct omap_dm_timer *omap_dm_timer_request(void)
+static struct omap_dm_timer *omap_dm_timer_request(void)
 {
 	return _omap_dm_timer_request(REQUEST_ANY, NULL);
 }
 
-struct omap_dm_timer *omap_dm_timer_request_specific(int id)
+static struct omap_dm_timer *omap_dm_timer_request_specific(int id)
 {
 	/* Requesting timer by ID is not supported when device tree is used */
 	if (of_have_populated_dt()) {
-		pr_warn("%s: Please use omap_dm_timer_request_by_cap/node()\n",
+		pr_warn("%s: Please use omap_dm_timer_request_by_node()\n",
 			__func__);
 		return NULL;
 	}
@@ -315,20 +305,6 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id)
 	return _omap_dm_timer_request(REQUEST_BY_ID, &id);
 }
 
-/**
- * omap_dm_timer_request_by_cap - Request a timer by capability
- * @cap:	Bit mask of capabilities to match
- *
- * Find a timer based upon capabilities bit mask. Callers of this function
- * should use the definitions found in the plat/dmtimer.h file under the
- * comment "timer capabilities used in hwmod database". Returns pointer to
- * timer handle on success and a NULL pointer on failure.
- */
-struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap)
-{
-	return _omap_dm_timer_request(REQUEST_BY_CAP, &cap);
-}
-
 /**
  * omap_dm_timer_request_by_node - Request a timer by device-tree node
  * @np:		Pointer to device-tree timer node
@@ -336,7 +312,7 @@ struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap)
  * Request a timer based upon a device node pointer. Returns pointer to
  * timer handle on success and a NULL pointer on failure.
  */
-struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np)
+static struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np)
 {
 	if (!np)
 		return NULL;
@@ -344,7 +320,7 @@ struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np)
 	return _omap_dm_timer_request(REQUEST_BY_NODE, np);
 }
 
-int omap_dm_timer_free(struct omap_dm_timer *timer)
+static int omap_dm_timer_free(struct omap_dm_timer *timer)
 {
 	if (unlikely(!timer))
 		return -EINVAL;
@@ -424,7 +400,7 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
 
 #else
 
-struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
+static struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
 {
 	if (timer && !IS_ERR(timer->fclk))
 		return timer->fclk;
@@ -440,18 +416,7 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
 
 #endif
 
-int omap_dm_timer_trigger(struct omap_dm_timer *timer)
-{
-	if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
-		pr_err("%s: timer not available or enabled.\n", __func__);
-		return -EINVAL;
-	}
-
-	omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
-	return 0;
-}
-
-int omap_dm_timer_start(struct omap_dm_timer *timer)
+static int omap_dm_timer_start(struct omap_dm_timer *timer)
 {
 	u32 l;
 
@@ -471,7 +436,7 @@ int omap_dm_timer_start(struct omap_dm_timer *timer)
 	return 0;
 }
 
-int omap_dm_timer_stop(struct omap_dm_timer *timer)
+static int omap_dm_timer_stop(struct omap_dm_timer *timer)
 {
 	unsigned long rate = 0;
 
@@ -556,8 +521,8 @@ int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
 	return ret;
 }
 
-int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
-			    unsigned int load)
+static int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
+				  unsigned int load)
 {
 	u32 l;
 
@@ -581,37 +546,8 @@ int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
 	return 0;
 }
 
-/* Optimized set_load which removes costly spin wait in timer_start */
-int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
-                            unsigned int load)
-{
-	u32 l;
-
-	if (unlikely(!timer))
-		return -EINVAL;
-
-	omap_dm_timer_enable(timer);
-
-	l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
-	if (autoreload) {
-		l |= OMAP_TIMER_CTRL_AR;
-		omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load);
-	} else {
-		l &= ~OMAP_TIMER_CTRL_AR;
-	}
-	l |= OMAP_TIMER_CTRL_ST;
-
-	__omap_dm_timer_load_start(timer, l, load, timer->posted);
-
-	/* Save the context */
-	timer->context.tclr = l;
-	timer->context.tldr = load;
-	timer->context.tcrr = load;
-	return 0;
-}
-
-int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
-			     unsigned int match)
+static int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
+				   unsigned int match)
 {
 	u32 l;
 
@@ -634,8 +570,8 @@ int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
 	return 0;
 }
 
-int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
-			   int toggle, int trigger)
+static int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
+				 int toggle, int trigger)
 {
 	u32 l;
 
@@ -659,7 +595,8 @@ int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
 	return 0;
 }
 
-int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler)
+static int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer,
+					int prescaler)
 {
 	u32 l;
 
@@ -681,8 +618,8 @@ int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler)
 	return 0;
 }
 
-int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
-				  unsigned int value)
+static int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
+					unsigned int value)
 {
 	if (unlikely(!timer))
 		return -EINVAL;
@@ -704,7 +641,7 @@ int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
  *
  * Disables the specified timer interrupts for a timer.
  */
-int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask)
+static int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask)
 {
 	u32 l = mask;
 
@@ -727,7 +664,7 @@ int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask)
 	return 0;
 }
 
-unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
+static unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
 {
 	unsigned int l;
 
@@ -741,7 +678,7 @@ unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
 	return l;
 }
 
-int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
+static int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
 {
 	if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev)))
 		return -EINVAL;
@@ -751,7 +688,7 @@ int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
 	return 0;
 }
 
-unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
+static unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
 {
 	if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
 		pr_err("%s: timer not iavailable or enabled.\n", __func__);
@@ -761,7 +698,7 @@ unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
 	return __omap_dm_timer_read_counter(timer, timer->posted);
 }
 
-int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
+static int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
 {
 	if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
 		pr_err("%s: timer not available or enabled.\n", __func__);
@@ -775,22 +712,6 @@ int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
 	return 0;
 }
 
-int omap_dm_timers_active(void)
-{
-	struct omap_dm_timer *timer;
-
-	list_for_each_entry(timer, &omap_timer_list, node) {
-		if (!timer->reserved)
-			continue;
-
-		if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) &
-		    OMAP_TIMER_CTRL_ST) {
-			return 1;
-		}
-	}
-	return 0;
-}
-
 static const struct of_device_id omap_timer_match[];
 
 /**
diff --git a/include/clocksource/dmtimer.h b/include/clocksource/dmtimer.h
index 862ad62dab9d..63d6ec0747d9 100644
--- a/include/clocksource/dmtimer.h
+++ b/include/clocksource/dmtimer.h
@@ -124,40 +124,14 @@ struct omap_dm_timer {
 	struct list_head node;
 };
 
-int omap_dm_timer_reserve_systimer(int id);
-struct omap_dm_timer *omap_dm_timer_request(void);
-struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id);
-struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap);
-struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np);
-int omap_dm_timer_free(struct omap_dm_timer *timer);
 void omap_dm_timer_enable(struct omap_dm_timer *timer);
 void omap_dm_timer_disable(struct omap_dm_timer *timer);
 
 int omap_dm_timer_get_irq(struct omap_dm_timer *timer);
 
 u32 omap_dm_timer_modify_idlect_mask(u32 inputmask);
-struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer);
-
-int omap_dm_timer_trigger(struct omap_dm_timer *timer);
-int omap_dm_timer_start(struct omap_dm_timer *timer);
-int omap_dm_timer_stop(struct omap_dm_timer *timer);
 
 int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source);
-int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, unsigned int value);
-int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, unsigned int value);
-int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, unsigned int match);
-int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, int toggle, int trigger);
-int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler);
-
-int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, unsigned int value);
-int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask);
-
-unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer);
-int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value);
-unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer);
-int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value);
-
-int omap_dm_timers_active(void);
 
 /*
  * Do not use the defines below, they are not needed. They should be only
-- 
2.15.1

^ permalink raw reply related

* [PATCH] drm/rockchip: analogix_dp: Ensure that the bridge is powered before poking it
From: Marc Zyngier @ 2017-12-18 11:28 UTC (permalink / raw)
  To: linux-arm-kernel

Stopping the X display manager on a kevin platform results in the
following crash:

[  674.833536] Synchronous External Abort: synchronous external abort (0x96000010) at 0xffff00000c970640
[  674.843886] Internal error: : 96000010 [#1] PREEMPT SMP
[  674.849744] Modules linked in:
[  674.849755] CPU: 1 PID: 86 Comm: kworker/1:1 Not tainted 4.15.0-rc3-00057-gff24f8cf492d-dirty #3
[  674.849760] detected fb_set_par error, error code: -16
[  674.849761] Hardware name: Google Kevin (DT)
[  674.849773] Workqueue: events analogix_dp_psr_work
[  674.849778] pstate: 60000005 (nZCv daif -PAN -UAO)
[  674.849784] pc : analogix_dp_send_psr_spd+0x8/0x168
[  674.849788] lr : analogix_dp_enable_psr+0x54/0x60
[  674.849789] sp : ffff000009b2bd60
[  674.849790] x29: ffff000009b2bd60 x28: 0000000000000000
[  674.849794] x27: ffff000009913d20 x26: ffff00000900fbf0
[  674.849797] x25: ffff8000f1b30000 x24: ffff8000f0c21d98
[  674.849800] x23: 0000000000000000 x22: ffff8000f7d3aa00
[  674.849803] x21: ffff8000f7d36980 x20: ffff8000f0c21c18
[  674.849806] x19: ffff8000f0c21db8 x18: 0000000000000001
[  674.849809] x17: 0000ffff89f2ed58 x16: ffff000008222908
[  674.849812] x15: 0000000000000000 x14: 0000000000000400
[  674.849815] x13: 0000000000000400 x12: 0000000000000000
[  674.849817] x11: 0000000000001414 x10: 0000000000000a00
[  674.849820] x9 : ffff000009b2bbb0 x8 : ffff8000f1b30a60
[  674.849823] x7 : 0000000000080000 x6 : 0000000000000001
[  674.849826] x5 : 0000000000000010 x4 : 0000000000000007
[  674.849829] x3 : 0000000000000002 x2 : ffff00000c970640
[  674.849832] x1 : ffff000009b2bd78 x0 : ffff8000f1624018
[  674.849836] Process kworker/1:1 (pid: 86, stack limit = 0x0000000083e5f7c3)
[  674.849838] Call trace:
[  674.849842]  analogix_dp_send_psr_spd+0x8/0x168
[  674.849844]  analogix_dp_psr_work+0x9c/0xa0
[  674.849849]  process_one_work+0x1cc/0x328
[  674.849852]  worker_thread+0x50/0x450
[  674.849856]  kthread+0xf8/0x128
[  674.849860]  ret_from_fork+0x10/0x18
[  674.849864] Code: b9000001 d65f03c0 f9445802 91190042 (b9400042)

Further investigation show that this happens because the the workqueue
races with the analogix_dp_bridge_disable() call from the core DRM code,
and end up trying to write to the DP bridge that has already been powered
down. This result is a very black screen, and a hard reset.

Instead of counting on luck to keep the bridge alive, let's use the
pm_runtime framework and take a reference on the device when we're about
to poke it. That is a fairly big hammer, but one that allows the system
to stay alive across dozens of X start/stop sequences.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 08743ad96cb9..7f2c190f75e7 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -14,6 +14,7 @@
 
 #include <linux/component.h>
 #include <linux/mfd/syscon.h>
+#include <linux/pm_runtime.h>
 #include <linux/of_device.h>
 #include <linux/of_graph.h>
 #include <linux/regmap.h>
@@ -113,10 +114,12 @@ static void analogix_dp_psr_work(struct work_struct *work)
 	}
 
 	mutex_lock(&dp->psr_lock);
+	pm_runtime_get_sync(dp->dev);
 	if (dp->psr_state == EDP_VSC_PSR_STATE_ACTIVE)
 		analogix_dp_enable_psr(dp->dev);
 	else
 		analogix_dp_disable_psr(dp->dev);
+	pm_runtime_put_sync(dp->dev);
 	mutex_unlock(&dp->psr_lock);
 }
 
-- 
2.14.2

^ permalink raw reply related

* arm64 crashkernel fails to boot on acpi-only machines due to ACPI regions being no longer mapped as NOMAP
From: AKASHI Takahiro @ 2017-12-18 11:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAFTCetQ55zUKe25jSku0DHp8uVZA4hB32d5W6MSCNsTVpxu7Gw@mail.gmail.com>

Bhupesh,

On Mon, Dec 18, 2017 at 02:29:05PM +0530, Bhupesh SHARMA wrote:
> On Mon, Dec 18, 2017 at 11:24 AM, AKASHI Takahiro
> <takahiro.akashi@linaro.org> wrote:
> > On Mon, Dec 18, 2017 at 01:16:57PM +0800, Dave Young wrote:
> >> kexec at fedoraproject... is for Fedora kexec scripts discussion, changed it
> >> to kexec at lists.infradead.org
> >>
> >> Also add linux-acpi list
> >
> > Thank you.
> >
> >> On 12/18/17 at 02:31am, Bhupesh Sharma wrote:
> >> > On Fri, Dec 15, 2017 at 3:05 PM, Ard Biesheuvel
> >> > <ard.biesheuvel@linaro.org> wrote:
> >> > > On 15 December 2017 at 09:59, AKASHI Takahiro
> >> > > <takahiro.akashi@linaro.org> wrote:
> >> > >> On Wed, Dec 13, 2017 at 12:17:22PM +0000, Ard Biesheuvel wrote:
> >> > >>> On 13 December 2017 at 12:16, AKASHI Takahiro
> >> > >>> <takahiro.akashi@linaro.org> wrote:
> >> > >>> > On Wed, Dec 13, 2017 at 10:49:27AM +0000, Ard Biesheuvel wrote:
> >> > >>> >> On 13 December 2017 at 10:26, AKASHI Takahiro
> >> > >>> >> <takahiro.akashi@linaro.org> wrote:
> >> > >>> >> > Bhupesh, Ard,
> >> > >>> >> >
> >> > >>> >> > On Wed, Dec 13, 2017 at 03:21:59AM +0530, Bhupesh Sharma wrote:
> >> > >>> >> >> Hi Ard, Akashi
> >> > >>> >> >>
> >> > >>> >> > (snip)
> >> > >>> >> >
> >> > >>> >> >> Looking deeper into the issue, since the arm64 kexec-tools uses the
> >> > >>> >> >> 'linux,usable-memory-range' dt property to allow crash dump kernel to
> >> > >>> >> >> identify its own usable memory and exclude, at its boot time, any
> >> > >>> >> >> other memory areas that are part of the panicked kernel's memory.
> >> > >>> >> >> (see https://www.kernel.org/doc/Documentation/devicetree/bindings/chosen.txt
> >> > >>> >> >> , for details)
> >> > >>> >> >
> >> > >>> >> > Right.
> >> > >>> >> >
> >> > >>> >> >> 1). Now when 'kexec -p' is executed, this node is patched up only
> >> > >>> >> >> with the crashkernel memory range:
> >> > >>> >> >>
> >> > >>> >> >>                 /* add linux,usable-memory-range */
> >> > >>> >> >>                 nodeoffset = fdt_path_offset(new_buf, "/chosen");
> >> > >>> >> >>                 result = fdt_setprop_range(new_buf, nodeoffset,
> >> > >>> >> >>                                 PROP_USABLE_MEM_RANGE, &crash_reserved_mem,
> >> > >>> >> >>                                 address_cells, size_cells);
> >> > >>> >> >>
> >> > >>> >> >> (see https://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git/tree/kexec/arch/arm64/kexec-arm64.c#n465
> >> > >>> >> >> , for details)
> >> > >>> >> >>
> >> > >>> >> >> 2). This excludes the ACPI reclaim regions irrespective of whether
> >> > >>> >> >> they are marked as System RAM or as RESERVED. As,
> >> > >>> >> >> 'linux,usable-memory-range' dt node is patched up only with
> >> > >>> >> >> 'crash_reserved_mem' and not 'system_memory_ranges'
> >> > >>> >> >>
> >> > >>> >> >> 3). As a result when the crashkernel boots up it doesn't find this
> >> > >>> >> >> ACPI memory and crashes while trying to access the same:
> >> > >>> >> >>
> >> > >>> >> >> # kexec -p /boot/vmlinuz-`uname -r` --initrd=/boot/initramfs-`uname
> >> > >>> >> >> -r`.img --reuse-cmdline -d
> >> > >>> >> >>
> >> > >>> >> >> [snip..]
> >> > >>> >> >>
> >> > >>> >> >> Reserved memory range
> >> > >>> >> >> 000000000e800000-000000002e7fffff (0)
> >> > >>> >> >>
> >> > >>> >> >> Coredump memory ranges
> >> > >>> >> >> 0000000000000000-000000000e7fffff (0)
> >> > >>> >> >> 000000002e800000-000000003961ffff (0)
> >> > >>> >> >> 0000000039d40000-000000003ed2ffff (0)
> >> > >>> >> >> 000000003ed60000-000000003fbfffff (0)
> >> > >>> >> >> 0000001040000000-0000001ffbffffff (0)
> >> > >>> >> >> 0000002000000000-0000002ffbffffff (0)
> >> > >>> >> >> 0000009000000000-0000009ffbffffff (0)
> >> > >>> >> >> 000000a000000000-000000affbffffff (0)
> >> > >>> >> >>
> >> > >>> >> >> 4). So if we revert Ard's patch or just comment the fixing up of the
> >> > >>> >> >> memory cap'ing passed to the crash kernel inside
> >> > >>> >> >> 'arch/arm64/mm/init.c' (see below):
> >> > >>> >> >>
> >> > >>> >> >> static void __init fdt_enforce_memory_region(void)
> >> > >>> >> >> {
> >> > >>> >> >>         struct memblock_region reg = {
> >> > >>> >> >>                 .size = 0,
> >> > >>> >> >>         };
> >> > >>> >> >>
> >> > >>> >> >>         of_scan_flat_dt(early_init_dt_scan_usablemem, &reg);
> >> > >>> >> >>
> >> > >>> >> >>         if (reg.size)
> >> > >>> >> >>                 //memblock_cap_memory_range(reg.base, reg.size); /*
> >> > >>> >> >> comment this out */
> >> > >>> >> >> }
> >> > >>> >> >
> >> > >>> >> > Please just don't do that. It can cause a fatal damage on
> >> > >>> >> > memory contents of the *crashed* kernel.
> >> > >>> >> >
> >> > >>> >> >> 5). Both the above temporary solutions fix the problem.
> >> > >>> >> >>
> >> > >>> >> >> 6). However exposing all System RAM regions to the crashkernel is not
> >> > >>> >> >> advisable and may cause the crashkernel or some crashkernel drivers to
> >> > >>> >> >> fail.
> >> > >>> >> >>
> >> > >>> >> >> 6a). I am trying an approach now, where the ACPI reclaim regions are
> >> > >>> >> >> added to '/proc/iomem' separately as ACPI reclaim regions by the
> >> > >>> >> >> kernel code and on the other hand the user-space 'kexec-tools' will
> >> > >>> >> >> pick up the ACPI reclaim regions from '/proc/iomem' and add it to the
> >> > >>> >> >> dt node 'linux,usable-memory-range'
> >> > >>> >> >
> >> > >>> >> > I still don't understand why we need to carry over the information
> >> > >>> >> > about "ACPI Reclaim memory" to crash dump kernel. In my understandings,
> >> > >>> >> > such regions are free to be reused by the kernel after some point of
> >> > >>> >> > initialization. Why does crash dump kernel need to know about them?
> >> > >>> >> >
> >> > >>> >>
> >> > >>> >> Not really. According to the UEFI spec, they can be reclaimed after
> >> > >>> >> the OS has initialized, i.e., when it has consumed the ACPI tables and
> >> > >>> >> no longer needs them. Of course, in order to be able to boot a kexec
> >> > >>> >> kernel, those regions needs to be preserved, which is why they are
> >> > >>> >> memblock_reserve()'d now.
> >> > >>> >
> >> > >>> > For my better understandings, who is actually accessing such regions
> >> > >>> > during boot time, uefi itself or efistub?
> >> > >>> >
> >> > >>>
> >> > >>> No, only the kernel. This is where the ACPI tables are stored. For
> >> > >>> instance, on QEMU we have
> >> > >>>
> >> > >>>  ACPI: RSDP 0x0000000078980000 000024 (v02 BOCHS )
> >> > >>>  ACPI: XSDT 0x0000000078970000 000054 (v01 BOCHS  BXPCFACP 00000001
> >> > >>>   01000013)
> >> > >>>  ACPI: FACP 0x0000000078930000 00010C (v05 BOCHS  BXPCFACP 00000001
> >> > >>> BXPC 00000001)
> >> > >>>  ACPI: DSDT 0x0000000078940000 0011DA (v02 BOCHS  BXPCDSDT 00000001
> >> > >>> BXPC 00000001)
> >> > >>>  ACPI: APIC 0x0000000078920000 000140 (v03 BOCHS  BXPCAPIC 00000001
> >> > >>> BXPC 00000001)
> >> > >>>  ACPI: GTDT 0x0000000078910000 000060 (v02 BOCHS  BXPCGTDT 00000001
> >> > >>> BXPC 00000001)
> >> > >>>  ACPI: MCFG 0x0000000078900000 00003C (v01 BOCHS  BXPCMCFG 00000001
> >> > >>> BXPC 00000001)
> >> > >>>  ACPI: SPCR 0x00000000788F0000 000050 (v02 BOCHS  BXPCSPCR 00000001
> >> > >>> BXPC 00000001)
> >> > >>>  ACPI: IORT 0x00000000788E0000 00007C (v00 BOCHS  BXPCIORT 00000001
> >> > >>> BXPC 00000001)
> >> > >>>
> >> > >>> covered by
> >> > >>>
> >> > >>>  efi:   0x0000788e0000-0x00007894ffff [ACPI Reclaim Memory ...]
> >> > >>>  ...
> >> > >>>  efi:   0x000078970000-0x00007898ffff [ACPI Reclaim Memory ...]
> >> > >>
> >> > >> OK. I mistakenly understood those regions could be freed after exiting
> >> > >> UEFI boot services.
> >> > >>
> >> > >>>
> >> > >>> >> So it seems that kexec does not honour the memblock_reserve() table
> >> > >>> >> when booting the next kernel.
> >> > >>> >
> >> > >>> > not really.
> >> > >>> >
> >> > >>> >> > (In other words, can or should we skip some part of ACPI-related init code
> >> > >>> >> > on crash dump kernel?)
> >> > >>> >> >
> >> > >>> >>
> >> > >>> >> I don't think so. And the change to the handling of ACPI reclaim
> >> > >>> >> regions only revealed the bug, not created it (given that other
> >> > >>> >> memblock_reserve regions may be affected as well)
> >> > >>> >
> >> > >>> > As whether we should honor such reserved regions over kexec'ing
> >> > >>> > depends on each one's specific nature, we will have to take care one-by-one.
> >> > >>> > As a matter of fact, no information about "reserved" memblocks is
> >> > >>> > exposed to user space (via proc/iomem).
> >> > >>> >
> >> > >>>
> >> > >>> That is why I suggested (somewhere in this thread?) to not expose them
> >> > >>> as 'System RAM'. Do you think that could solve this?
> >> > >>
> >> > >> Memblock-reserv'ing them is necessary to prevent their corruption and
> >> > >> marking them under another name in /proc/iomem would also be good in order
> >> > >> not to allocate them as part of crash kernel's memory.
> >> > >>
> >> > >
> >> > > I agree. However, this may not be entirely trivial, since iterating
> >> > > over the memblock_reserved table and creating iomem entries may result
> >> > > in collisions.
> >> >
> >> > I found a method (using the patch I shared earlier in this thread) to mark these
> >> > entries as 'ACPI reclaim memory' ranges rather than System RAM or
> >> > reserved regions.
> >> >
> >> > >> But I'm not still convinced that we should export them in useable-
> >> > >> memory-range to crash dump kernel. They will be accessed through
> >> > >> acpi_os_map_memory() and so won't be required to be part of system ram
> >> > >> (or memblocks), I guess.
> >> > >
> >> > > Agreed. They will be covered by the linear mapping in the boot kernel,
> >> > > and be mapped explicitly via ioremap_cache() in the kexec kernel,
> >> > > which is exactly what we want in this case.
> >> >
> >> > Now this is what is confusing me. I don't see the above happening.
> >> >
> >> > I see that the primary kernel boots up and adds the ACPI regions via:
> >> > acpi_os_ioremap
> >> >     -> ioremap_cache
> >> >
> >> > But during the crashkernel boot, ''acpi_os_ioremap' calls
> >> > 'ioremap' for the ACPI Reclaim Memory regions and not the _cache
> >> > variant.
> >
> > It is natural if that region is out of memblocks.
> 
> Thanks for the confirmation. This was my understanding as well.
> 
> >> > And it fails while accessing the ACPI tables:
> >> >
> >> > [    0.039205] ACPI: Core revision 20170728
> >> > pud=000000002e7d0003, *pmd=000000002e7c0003, *pte=00e8000039710707
> >> > [    0.095098] Internal error: Oops: 96000021 [#1] SMP
> >
> > this (ESR = 0x96000021) means that Data Abort and Alignment fault happened.
> > As ioremap() makes the mapping as "Device memory", unaligned memory
> > access won't be allowed.
> >
> >> > [    0.100022] Modules linked in:
> >> > [    0.103102] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.14.0-rc6 #1
> >> > [    0.109432] task: ffff000008d05180 task.stack: ffff000008cc0000
> >> > [    0.115414] PC is at acpi_ns_lookup+0x25c/0x3c0
> >> > [    0.119987] LR is at acpi_ds_load1_begin_op+0xa4/0x294
> >> > [    0.125175] pc : [<ffff0000084a6764>] lr : [<ffff00000849b4f8>]
> >> > pstate: 60000045
> >> > [    0.132647] sp : ffff000008ccfb40
> >> > [    0.135989] x29: ffff000008ccfb40 x28: ffff000008a9f2a4
> >> > [    0.141354] x27: ffff0000088be820 x26: 0000000000000000
> >> > [    0.146718] x25: 000000000000001b x24: 0000000000000001
> >> > [    0.152083] x23: 0000000000000001 x22: ffff000009710027
> >> > [    0.157447] x21: ffff000008ccfc50 x20: 0000000000000001
> >> > [    0.162812] x19: 000000000000001b x18: 0000000000000005
> >> > [    0.168176] x17: 0000000000000000 x16: 0000000000000000
> >> > [    0.173541] x15: 0000000000000000 x14: 000000000000038e
> >> > [    0.178905] x13: ffffffff00000000 x12: ffffffffffffffff
> >> > [    0.184270] x11: 0000000000000006 x10: 00000000ffffff76
> >> > [    0.189634] x9 : 000000000000005f x8 : ffff8000126d0140
> >> > [    0.194998] x7 : 0000000000000000 x6 : ffff000008ccfc50
> >> > [    0.200362] x5 : ffff80000fe62c00 x4 : 0000000000000001
> >> > [    0.205727] x3 : ffff000008ccfbe0 x2 : ffff0000095e3980
> >> > [    0.211091] x1 : ffff000009710027 x0 : 0000000000000000
> >> > [    0.216456] Process swapper/0 (pid: 0, stack limit = 0xffff000008cc0000)
> >> > [    0.223224] Call trace:
> >> > [    0.225688] Exception stack(0xffff000008ccfa00 to 0xffff000008ccfb40)
> >> > [    0.232194] fa00: 0000000000000000 ffff000009710027
> >> > ffff0000095e3980 ffff000008ccfbe0
> >> > [    0.240106] fa20: 0000000000000001 ffff80000fe62c00
> >> > ffff000008ccfc50 0000000000000000
> >> > [    0.248018] fa40: ffff8000126d0140 000000000000005f
> >> > 00000000ffffff76 0000000000000006
> >> > [    0.255931] fa60: ffffffffffffffff ffffffff00000000
> >> > 000000000000038e 0000000000000000
> >> > [    0.263843] fa80: 0000000000000000 0000000000000000
> >> > 0000000000000005 000000000000001b
> >> > [    0.271754] faa0: 0000000000000001 ffff000008ccfc50
> >> > ffff000009710027 0000000000000001
> >> > [    0.279667] fac0: 0000000000000001 000000000000001b
> >> > 0000000000000000 ffff0000088be820
> >> > [    0.287579] fae0: ffff000008a9f2a4 ffff000008ccfb40
> >> > ffff00000849b4f8 ffff000008ccfb40
> >> > [    0.295491] fb00: ffff0000084a6764 0000000060000045
> >> > ffff000008ccfb40 ffff000008260a18
> >> > [    0.303403] fb20: ffffffffffffffff ffff0000087f3fb0
> >> > ffff000008ccfb40 ffff0000084a6764
> >> > [    0.311316] [<ffff0000084a6764>] acpi_ns_lookup+0x25c/0x3c0
> >> > [    0.316943] [<ffff00000849b4f8>] acpi_ds_load1_begin_op+0xa4/0x294
> >> > [    0.323186] [<ffff0000084ad4ac>] acpi_ps_build_named_op+0xc4/0x198
> >> > [    0.329428] [<ffff0000084ad6cc>] acpi_ps_create_op+0x14c/0x270
> >> > [    0.335319] [<ffff0000084acfa8>] acpi_ps_parse_loop+0x188/0x5c8
> >> > [    0.341298] [<ffff0000084ae048>] acpi_ps_parse_aml+0xb0/0x2b8
> >> > [    0.347101] [<ffff0000084a8e10>] acpi_ns_one_complete_parse+0x144/0x184
> >> > [    0.353783] [<ffff0000084a8e98>] acpi_ns_parse_table+0x48/0x68
> >> > [    0.359675] [<ffff0000084a82cc>] acpi_ns_load_table+0x4c/0xdc
> >> > [    0.365479] [<ffff0000084b32f8>] acpi_tb_load_namespace+0xe4/0x264
> >> > [    0.371723] [<ffff000008baf9b4>] acpi_load_tables+0x48/0xc0
> >> > [    0.377350] [<ffff000008badc20>] acpi_early_init+0x9c/0xd0
> >> > [    0.382891] [<ffff000008b70d50>] start_kernel+0x3b4/0x43c
> >> > [    0.388343] Code: b9008fb9 2a000318 36380054 32190318 (b94002c0)
> >> > [    0.394500] ---[ end trace c46ed37f9651c58e ]---
> >> > [    0.399160] Kernel panic - not syncing: Fatal exception
> >> > [    0.404437] Rebooting in 10 seconds.
> >> >
> >> > So, I think the linear mapping done by the primary kernel does not
> >> > make these accessible in the crash kernel directly.
> >> >
> >> > Any pointers?
> >>
> >> Can you get the code line number for acpi_ns_lookup+0x25c?
> >
> > So should we always avoid ioremap() in acpi_os_ioremap() entirely, or
> > modify acpi_ns_lookup() (or any acpi functions') to prevent unaligned
> > accesses?
> > (I didn't find out how unaligned accesses could happen there.)
> >
> 
> Right. Like I captured somewhere in this thread (perhaps the first
> email on this subject),
> this is indeed an unaligned address access.
> 
> Now, modifying acpi_os_ioremap() to not ioremap() and thus avoiding
> assigning this memory range
> as device memory doesn't seem a neat solution as it means we are not
> marking some thing with the right memory attribute and we can fall in
> similar/related issues later.
> 
> Regarding the later suggestion, what I am seeing now is that the acpi
> table access functions are perhaps reused from the earlier x86
> implementation, but on the arm64 (or even arm) arch we should not be
> allowing unaligned accesses which might cause UNDEFINED behaviour and
> resultant crash.
> 
> So I can try going this approach and see if it works for me.
> 
> However, I am still not very sure as to why the crashkernel ranges
> historically do not include the System RAM regions (which may include
> the ACPI regions as well). These regions are available for the kernel
> usage and perhaps should be exported to the crashkernel as well.
> 
> I am not fully aware of the previous discussions on capp'ing the
> crashkernel memory being passed to the kdump kernel, but did we run
> into any issues while doing so?
> 
> Also, even if I extend the kexec-tools to modify the
> linux,usable-memory-range and add the ACPI regions to it, the
> crashkernel fails to boot with the below message (I have added some
> logic to print the DTB on the crash kernel boot start):
> 
> [    0.000000]     chosen {
> [    0.000000]         linux,usable-memory-range
> [    0.000000]  = <
> [    0.000000] 0x00000000
> [    0.000000] 0x0e800000
> [    0.000000] 0x00000000
> [    0.000000] 0x20000000
> [    0.000000] 0x00000000
> [    0.000000] 0x396c0000
> [    0.000000] 0x00000000
> [    0.000000] 0x000a0000
> [    0.000000] 0x00000000
> [    0.000000] 0x39770000
> [    0.000000] 0x00000000
> [    0.000000] 0x00040000
> [    0.000000] 0x00000000
> [    0.000000] 0x398a0000
> [    0.000000] 0x00000000
> [    0.000000] 0x00020000
> [    0.000000] >
> [    0.000000] ;
> 
> [snip..]
> 
> [    0.000000] linux,usable-memory-range base e800000, size 20000000
> [    0.000000]  - e800000 ,  20000000
> [    0.000000] linux,usable-memory-range base 396c0000, size a0000
> [    0.000000]  - 396c0000 ,  a0000
> [    0.000000] linux,usable-memory-range base 39770000, size 40000
> [    0.000000]  - 39770000 ,  40000
> [    0.000000] linux,usable-memory-range base 398a0000, size 20000
> [    0.000000]  - 398a0000 ,  20000
> [    0.000000] initrd not fully accessible via the linear mapping --
> please check your bootloader ...
> [    0.000000] ------------[ cut here ]------------
> [    0.000000] WARNING: CPU: 0 PID: 0 at arch/arm64/mm/init.c:597
> arm64_memblock_init+0x210/0x484
> [    0.000000] Modules linked in:
> [    0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 4.14.0+ #7
> [    0.000000] task: ffff000008d05580 task.stack: ffff000008cc0000
> [    0.000000] PC is at arm64_memblock_init+0x210/0x484
> [    0.000000] LR is at arm64_memblock_init+0x210/0x484
> [    0.000000] pc : [<ffff000008b76984>] lr : [<ffff000008b76984>]
> pstate: 600000c5
> [    0.000000] sp : ffff000008ccfe80
> [    0.000000] x29: ffff000008ccfe80 x28: 000000000f370018
> [    0.000000] x27: 0000000011230000 x26: 00000000013b0000
> [    0.000000] x25: 000000000fe80000 x24: ffff000008cf3000
> [    0.000000] x23: ffff000008ec0000 x22: ffff000009680000
> [    0.000000] x21: ffff000008afa000 x20: ffff000008080000
> [    0.000000] x19: ffff000008afa000 x18: 000000000c283806
> [    0.000000] x17: 0000000000000000 x16: ffff000008d05580
> [    0.000000] x15: 000000002be00842 x14: 79206b6365686320
> [    0.000000] x13: 657361656c70202d x12: 2d20676e69707061
> [    0.000000] x11: 6d207261656e696c x10: 2065687420616976
> [    0.000000] x9 : 00000000000000f4 x8 : ffff000008517414
> [    0.000000] x7 : 746f6f622072756f x6 : 000000000000000d
> [    0.000000] x5 : ffff000008c96360 x4 : 0000000000000001
> [    0.000000] x3 : 0000000000000000 x2 : 0000000000000000
> [    0.000000] x1 : 0000000000000000 x0 : 0000000000000056
> [    0.000000] Call trace:
> [    0.000000] Exception stack(0xffff000008ccfd40 to 0xffff000008ccfe80)
> [    0.000000] fd40: 0000000000000056 0000000000000000
> 0000000000000000 0000000000000000
> [    0.000000] fd60: 0000000000000001 ffff000008c96360
> 000000000000000d 746f6f622072756f
> [    0.000000] fd80: ffff000008517414 00000000000000f4
> 2065687420616976 6d207261656e696c
> [    0.000000] fda0: 2d20676e69707061 657361656c70202d
> 79206b6365686320 000000002be00842
> [    0.000000] fdc0: ffff000008d05580 0000000000000000
> 000000000c283806 ffff000008afa000
> [    0.000000] fde0: ffff000008080000 ffff000008afa000
> ffff000009680000 ffff000008ec0000
> [    0.000000] fe00: ffff000008cf3000 000000000fe80000
> 00000000013b0000 0000000011230000
> [    0.000000] fe20: 000000000f370018 ffff000008ccfe80
> ffff000008b76984 ffff000008ccfe80
> [    0.000000] fe40: ffff000008b76984 00000000600000c5
> ffff00000959b7a8 ffff000008ec0000
> [    0.000000] fe60: ffffffffffffffff 0000000000000005
> ffff000008ccfe80 ffff000008b76984
> [    0.000000] [<ffff000008b76984>] arm64_memblock_init+0x210/0x484
> [    0.000000] [<ffff000008b7398c>] setup_arch+0x1b8/0x5f4
> [    0.000000] [<ffff000008b70a10>] start_kernel+0x74/0x43c
> [    0.000000] random: get_random_bytes called from
> print_oops_end_marker+0x50/0x6c with crng_init=0
> [    0.000000] ---[ end trace 0000000000000000 ]---
> [    0.000000] Reserving 4KB of memory at 0x2e7f0000 for elfcorehdr
> [    0.000000] cma: Failed to reserve 512 MiB
> [    0.000000] Kernel panic - not syncing: ERROR: Failed to allocate
> 0x0000000000010000 bytes below 0x0000000000000000.
> [    0.000000]
> [    0.000000] CPU: 0 PID: 0 Comm: swapper Tainted: G        W
> ------------   4.14.0+ #7
> [    0.000000] Call trace:
> [    0.000000] [<ffff000008088da8>] dump_backtrace+0x0/0x23c
> [    0.000000] [<ffff000008089008>] show_stack+0x24/0x2c
> [    0.000000] [<ffff0000087f647c>] dump_stack+0x84/0xa8
> [    0.000000] [<ffff0000080cfd44>] panic+0x138/0x2a0
> [    0.000000] [<ffff000008b95c88>] memblock_alloc_base+0x44/0x4c
> [    0.000000] [<ffff000008b95cbc>] memblock_alloc+0x2c/0x38
> [    0.000000] [<ffff000008b772dc>] early_pgtable_alloc+0x20/0x74
> [    0.000000] [<ffff000008b7755c>] paging_init+0x28/0x544
> [    0.000000] [<ffff000008b73990>] setup_arch+0x1bc/0x5f4
> [    0.000000] [<ffff000008b70a10>] start_kernel+0x74/0x43c
> [    0.000000] ---[ end Kernel panic - not syncing: ERROR: Failed to
> allocate 0x0000000000010000 bytes below 0x0000000000000000.
> [    0.000000]
> 
> I guess it is because of the 1G alignment requirement between the
> kernel image and the initrd and how we populate the holes between the
> kernel image, segments (including dtb) and the initrd from the
> kexec-tools.
> 
> Akashi, any pointers on this will be helpful as well.

Please show me:
 * "Virtual kernel memory layout" in dmesg
 * /proc/iomem
 * debug messages from kexec-tools (kexec -d)

-Takahiro AKASHI


> Regards,
> Bhupesh
> 
> 
> >> >
> >> > Regards,
> >> > Bhupesh
> >> >
> >> > >> Just FYI, on x86, ACPI tables seems to be exposed to crash dump kernel
> >> > >> via a kernel command line parameter, "memmap=".
> >> > >>
> >> > _______________________________________________
> >> > kexec mailing list -- kexec at lists.fedoraproject.org
> >> > To unsubscribe send an email to kexec-leave at lists.fedoraproject.org

^ permalink raw reply

* [PATCH 2/3] ARM: dts: r8a7743: Add CMT SoC specific support
From: Simon Horman @ 2017-12-18 11:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <TY1PR06MB08954C04D41BDA8EFA04E1DFC0350@TY1PR06MB0895.apcprd06.prod.outlook.com>

On Wed, Dec 13, 2017 at 10:15:39AM +0000, Fabrizio Castro wrote:
> Hello Geert,
> 
> thank you for your feedback.
> 
> > Hi Fabrizio,
> >
> > On Wed, Dec 13, 2017 at 10:42 AM, Fabrizio Castro
> > <fabrizio.castro@bp.renesas.com> wrote:
> > >> On Tue, Dec 12, 2017 at 06:49:38PM +0000, Fabrizio Castro wrote:
> > >> > Add CMT[01] support to SoC DT.
> > >> > Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com>
> > >> > Reviewed-by: Biju Das <biju.das@bp.renesas.com>
> > >> > ---
> > >> >  arch/arm/boot/dts/r8a7743.dtsi | 30 ++++++++++++++++++++++++++++++
> > >> >  1 file changed, 30 insertions(+)
> > >>
> > >> I was expecting the cmt nodes to be "disabled" in the SoC file
> > >> and then enabled selectively in board files. Am I missing something?
> > >
> > > Since this component is just a compare and match timer, I  thought there was no harm in enabling it by default in the SoC specific DT.
> > > The system will park it and leave its clock disabled until actually needed for something.
> > > The user can still disable it in the board specific DT if he/she doesn't mean to even have the option to use it. Do you prefer I left it
> > disabled by default?
> >
> > It's debatable (thus up to Simon the maintainer ;-).
> > For I/O devices, we disable them in the SoC .dtsi file.
> > For core infrastructure like interrupt, DMA, and GPIO controllers, we keep
> > them enabled.
> >
> > Timers are core functionality, but who's actually using these timers?
> 
> I don't have a use case in mind unfortunately, but it's still core
> functionality and pretty harmless as far as I can tell. Let's see what
> Simon thinks about this.

On Renesas SoCs we have a bit more flexibility with timers than might
be the case on other SoCs. Thus I'd like to keep with the scheme of
disabling them in .dtsi and enabling them when they are needed.

Please update the patches.

^ permalink raw reply

* [PATCH v5 0/8] omap: dmtimer: Move driver out of plat-omap
From: Ladislav Michl @ 2017-12-18 11:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1513059137-21593-1-git-send-email-j-keerthy@ti.com>

Keerthy,

On Tue, Dec 12, 2017 at 11:42:09AM +0530, Keerthy wrote:
> The series moves dmtimer out of plat-omap to drivers/clocksource.
> The series also does a bunch of changes to pwm-omap-dmtimer code
> to adapt to the driver migration and clean up plat specific
> pdata-quirks and use the dmtimer platform data.

thanks for nice work. I'll send two more patches as a reply to this
one. I'd be glad if you could make them part of your serie. One of
them would be nice to have for pwm driver prescaler fix which will
be send independently.
Also, if that helps you can have my
Tested-by: Ladislav Michl <ladis@linux-mips.org>
on IGEPv2 (OMAP3430 based)

> Boot tested on DRA7-EVM and AM437X-GP-EVM.

I guess PWM driver was not tested, right? See comment to PATCH 7/8.

> Compile tested omap1_defconfig.

Thank you,
	ladis

^ permalink raw reply

* [PATCH 0/5] Add Sound support for iWave RZ/G1M board
From: Simon Horman @ 2017-12-18 11:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <KL1PR06MB170226A1E9F3CA011EBF3E2DB8350@KL1PR06MB1702.apcprd06.prod.outlook.com>

On Wed, Dec 13, 2017 at 09:27:30AM +0000, Biju Das wrote:
> Hi Simon,
> 
> Thanks.
> 
> There is a typo in the documentation dependency link.
> The correct one is https://patchwork.kernel.org/patch/10108015/

Thanks, series applied.

^ permalink raw reply

* [PATCH v3 05/11] thermal: armada: Add support for Armada AP806
From: Baruch Siach @ 2017-12-18 11:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171218104127.65017555@xps13>

Hi Miqu?l,

On Mon, Dec 18, 2017 at 10:41:27AM +0100, Miquel RAYNAL wrote:
> Hello Gregory & Baruch,
> 
> On Thu, 14 Dec 2017 12:05:43 +0100
> Gregory CLEMENT <gregory.clement@free-electrons.com> wrote:
> 
> > > @@ -184,9 +214,9 @@ static int armada_get_temp(struct
> > > thermal_zone_device *thermal, div = priv->data->coef_div;
> > >  
> > >  	if (priv->data->inverted)
> > > -		*temp = ((m * reg) - b) / div;
> > > +		*temp = ((m * sample) - b) / div;
> > >  	else
> > > -		*temp = (b - (m * reg)) / div;
> > > +		*temp = (b - (m * sample)) / div;
> > >  	return 0;
> > >  }
> > >  
> > > @@ -237,6 +267,19 @@ static const struct armada_thermal_data
> > > armada380_data = { .inverted = true,
> > >  };
> > >  
> > > +static const struct armada_thermal_data armada_ap806_data = {
> > > +	.is_valid = armada_is_valid,
> > > +	.init_sensor = armada_ap806_init_sensor,
> > > +	.is_valid_bit = BIT(16),
> > > +	.temp_shift = 0,
> > > +	.temp_mask = 0x3ff,
> > > +	.coef_b = -150000,  
> > 
> > Don't you expect any side effect by storing a negative value in a
> > unsigned variable?
> 
> That is a fair question, I did not spot that.
> 
> As other values are really close to 2^32 I don't know what is the best
> option for us in this case. Should I:
> - don't care?
> - use signed values? (dangerous IMHO)
> - use a union with a signed and an unsigned value? (problem moved to
>   ->get_temp())

Another option is to use s64 type.

baruch

-- 
     http://baruch.siach.name/blog/                  ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - baruch at tkos.co.il - tel: +972.2.679.5364, http://www.tkos.co.il -

^ permalink raw reply

* [PATCH 0/4 v5] Support bridge timings
From: Laurent Pinchart @ 2017-12-18 11:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <33bc6bf1-1730-e02a-2a03-17a60f0e5c65@samsung.com>

Hi Andrzej,

On Monday, 18 December 2017 10:43:51 EET Andrzej Hajda wrote:
> On 15.12.2017 16:54, Daniel Vetter wrote:
> > On Fri, Dec 15, 2017 at 01:30:24PM +0100, Linus Walleij wrote:
> >> On Fri, Dec 15, 2017 at 1:10 PM, Linus Walleij <linus.walleij@linaro.org> 
wrote:
> >>> - The connector is apparently not the right abstraction to carry
> >>> 
> >>>   the detailed timings specification between DRI drivers and bridge
> >>>   drivers.
> >>> 
> >>> - Instead put detailed timing data into the bridge itself as an
> >>> 
> >>>   optional information pointer.
> >> 
> >> Notice that this is just my fumbling attempts to deal with the situation.
> >> 
> >> Laurent made me understand what the actual technical problem was,
> >> how come my pixels were flickering.
> >> 
> >> Both Laurent and DVetter mentioned that we may need to convey
> >> information between the bridge and the display engine in some
> >> way.
> >> 
> >> Alternatively I could go and hack on adding this to e.g. drm_display_info
> >> which was used in the previous patch sets by setting the negede flag
> >> in bus_formats.
> >> 
> >> I don't know. struct drm_display_info is getting a bit heavy as
> >> container of misc settings related to "some kind of display".
> >> The bridge isn't even a display itself, that is on the other side
> >> of it. So using the connector and treating a bridge as "some kind
> >> of display" seems wrong too.
> >> 
> >> Is there a third way?
> > 
> > If you don't plan to nest bridges too deeply, there is. Atm we have 2
> > modes in drm_crtc_state:
> > 
> > - mode, which is what userspace requested, and what it expects logically
> >   to be the actual real thing. I.e. timing, resolution and all that that
> >   userspace can observe (through plane positioning and vblank timestamps)
> >   should match this mode. For external screens this should also match
> >   what's physically going over the cable.
> > 
> > - adjusted_mode, which is something entirely undefined and to be used by
> >   drivers internally. Most drivers use it as the thing that's actually
> >   transported between the CRTC and the encoder.
> > 
> > There's a few common reasons for adjusted mode to be different:
> > - integrated panel, and your CRTC has a scaler. In that case the
> >   userspace-requested mode is what you feed into into the scaler, and the
> >   adjusted mode is what comes out of your scaler and then goes down the
> >   wire to the panel.
> > 
> > - your encoder is funky, and e.g. transcodes to the output mode itself,
> >   but expects that you program the input mode always the same. Usual
> >   reasons for this are transcoders that always want non-interlaced mode
> >   (and do the interlacing themselves), if the transcoder has some scaler
> >   itself (some TV-out transcoders had that), or if it has a strict
> >   expectation about signalling edges and stuff (and then transcodes the
> >   signal again). DACs are common doing that.
> > 
> > Anyway, sounds like your bridge is of the 2nd kind, so all you have to do
> > is
> > - in your bridge->mode_fixup function, adjust the adjusted_mode as needed
> > - in your pl111 driver, program the adjusted mode, not the originally
> > 
> >   requested mode
> > 
> > adjusted mode is set to be a copy of the requested mode by atomic helpers,
> > so this should keep working as-is on any other bridge driver.
> > 
> > No idea why I didn't tell you this right away, or maybe I'm missing
> > something this time around.
> 
> Using adjusted_mode will probably help here, fortunately the pipeline is
> short in this case and one adjusted_mode per pipeline should be enough.
> But there is more fundamental problem here - drm core does not provide a
> way to interact between adjacent components of the pipeline. So they are
> not able to negotiate/exchange parameters specific for the video link
> between them.
> adjusted_mode is one per pipeline and will note scale without hacks.
> Anyway I remember multiple attempts to somehow workaround this issue,
> for example:
> - passing DSI specific settings (currently performed via DSI control bus),
> - passing info about panel command mode parameters(by adding these
> properties to crtc node),
> - passing bus flags from panel to encoder/bridge (via drm_display_mode,
> nacked if I remember, I do not know if/how it is solved actually).
> 
> Another concern is that adjusted_mode used inside drm driver (ie.
> between encoder and crtc) is something private per drm driver. In this
> case we have bridge which theoretically should work with ANY video
> source with compatible video bus: encoder, or another bridge before it.
> So adjusted_mode is not private anymore, and will be problematic if two
> different bridges/encoders will use it differently.

I agree completely. I believe we'll need to introduce new bridge operations to 
report and negotiate timings along the pipeline. Ideally the same operations 
would also be implemented by panel drivers for easier handling of the 
pipeline, in which case we'll need a common data structure for both bridges 
and panels. We can however start with bridges and extend that to panels in a 
second step.

I'm currently reworking the bridge and panel code for the omapdrm driver, 
which uses omapdrm-specific drivers not based on the drm_bridge and drm_panel 
API. The goal is to replace them by standard bridge and panel drivers. As part 
of that work I plan to propose new operations for bridges as discussed above. 
I can't tell however when the first version will be ready, so if you want to 
give it a go, feel free to do so.

> >> I'm just a bit lost.
> > 
> > Once your un-lost, pls review the docs for drm_crtc_state and the various
> > mode_fixup functions, to make sure they're clear on how this is supposed
> > to work. Might need a new overview DOC: comment that ties it all together.

-- 
Regards,

Laurent Pinchart

^ permalink raw reply

* [PATCH 2/4] clocksource: stm32: use prescaler to adjust the resolution
From: Benjamin Gaignard @ 2017-12-18 11:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <fb09288e-1893-d99a-d15b-5cbc33fcc9a0@linaro.org>

2017-12-18 11:54 GMT+01:00 Daniel Lezcano <daniel.lezcano@linaro.org>:
> On 18/12/2017 10:44, Benjamin Gaignard wrote:
>> 2017-12-18 10:26 GMT+01:00 Daniel Lezcano <daniel.lezcano@linaro.org>:
>>> On 15/12/2017 09:52, Benjamin Gaignard wrote:
>>>> Rather than use fixed prescaler values compute it to get a clock
>>>> as close as possible of 10KHz and a resolution of 0.1ms.
>>>>
>>>> Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com>
>>>> ---
>>>>  drivers/clocksource/timer-stm32.c | 23 ++++++++++++++++-------
>>>>  1 file changed, 16 insertions(+), 7 deletions(-)
>>>>
>>>> diff --git a/drivers/clocksource/timer-stm32.c b/drivers/clocksource/timer-stm32.c
>>>> index 23a321cca45b..de721d318065 100644
>>>> --- a/drivers/clocksource/timer-stm32.c
>>>> +++ b/drivers/clocksource/timer-stm32.c
>>>> @@ -37,6 +37,11 @@
>>>>
>>>>  #define TIM_EGR_UG   BIT(0)
>>>>
>>>> +#define MAX_TIM_PSC  0xFFFF
>>>> +
>>>> +/* Target a 10KHz clock to get a resolution of 0.1 ms */
>>>> +#define TARGETED_CLK_RATE 10000
>>>> +
>>>>  static int stm32_clock_event_shutdown(struct clock_event_device *evt)
>>>>  {
>>>>       struct timer_of *to = to_timer_of(evt);
>>>> @@ -83,7 +88,7 @@ static irqreturn_t stm32_clock_event_handler(int irq, void *dev_id)
>>>>  static void __init stm32_clockevent_init(struct timer_of *to)
>>>>  {
>>>>       unsigned long max_delta;
>>>> -     int prescaler;
>>>> +     unsigned long prescaler;
>>>>
>>>>       to->clkevt.name = "stm32_clockevent";
>>>>       to->clkevt.features = CLOCK_EVT_FEAT_PERIODIC;
>>>> @@ -96,13 +101,17 @@ static void __init stm32_clockevent_init(struct timer_of *to)
>>>>       /* Detect whether the timer is 16 or 32 bits */
>>>>       writel_relaxed(~0U, timer_of_base(to) + TIM_ARR);
>>>>       max_delta = readl_relaxed(timer_of_base(to) + TIM_ARR);
>>>> -     if (max_delta == ~0U) {
>>>> -             prescaler = 1;
>>>> +     to->clkevt.rating = 50;
>>>> +     if (max_delta == ~0U)
>>>>               to->clkevt.rating = 250;
>>>> -     } else {
>>>> -             prescaler = 1024;
>>>> -             to->clkevt.rating = 50;
>>>> -     }
>>>> +
>>>> +     /*
>>>> +      * Get the highest possible prescaler value to be as close
>>>> +      * as possible of TARGETED_CLK_RATE
>>>> +      */
>>>> +     prescaler = DIV_ROUND_CLOSEST(timer_of_rate(to), TARGETED_CLK_RATE);
>>>
>>> With a 90MHz or 125MHz, the prescaler will be 9000 or 12500, so much
>>> more than the 1024 we have today for 16b, and 1 for 32b.
>>>
>>> Shouldn't the computation be weighted with the bits width ?
>>
>> My goal was to get the same resolution (0.1ms) for all the timers so
>> the wrap will depend of the number of bits like you describe below.
>
> Do you really want 1ms resolution with a 32bits timer ?

I want a resolution of 0.1 ms (TARGETED_CLK_RATE = 10.000)
for all the timers or 0.01ms if you think is better.

>
>>> Otherwise the timer will wrap like:
>>>
>>> 32bits:
>>>
>>> before: (2^32 / 90e6) x 1 = 47.72 seconds
>>> after:  (2^32 / 90e6) x 9000 = 119.3 *hours* ~= 5days
>>>
>>> 16bits:
>>>
>>> before: (2^16 / 90e6) x 1024 = 0.745 seconds
>>> after:  (2^16 / 90e6) x 9000 = 6.55 seconds
>>>
>>> The patch is ok to target the 10KHz timer rate for 16b with a 1ms
>>> resolution wrapping up after 6.55 seconds. But not for the 32bits timer.
>>> Furthermore, we can't tell anymore the 32bits timers have a rating of
>>> 250 after this patch.
>>
>> What is the link between rating and resolution (or wrap) ?
>
> Low resolution => hardly suitable for real use case => bad rating.
>
> From include/linux/clocksource.h
>
> [ ... ]
>
>  *                      100-199: Base level usability.
>  *                              Functional for real use, but not desired.
>  *                      200-299: Good.
>  *                              A correct and usable clocksource.
>
> [ ... ]
>
> If you want to set a timer with a delta of 12.345ms and the resolution
> is 1ms. Then you end up with a timer expiring after 13ms.
>
>> Is it a problem to get a long wrap ?
>
> It is not a problem to go for a long wrap, it is usually interesting
> when the CPU has deep idle states. But it is not worth to sacrifice the
> resolution with the 32bits timer in order to have 5 days before wrap.
>
> Keeping 47secs is fine for the moment. If you want a coarser grain, that
> could be acceptable because the resolution is very high but we can
> postpone that for later after solving this 16b / 32b thing.

When the resolution is too high I have issues with min delta value because
CPU can handle interrupt each 11ns.

>
>>> Leave the 32bits part as it is and compute the prescaler only in case of
>>> 16bits with the target rate, which sounds a reasonable approach.
>>>
>>>> +     if (prescaler > MAX_TIM_PSC)
>>>> +             prescaler = MAX_TIM_PSC;
>>>
>>> That can happen only if the clock rate is greater than ~655MHz, that
>>> could not happen today as far as I can tell regarding the DT. So if we
>>> hit this condition, we should speak up in the log (pr_warn).
>>
>> It is to be futur proof for next possible SoC but even if prescaler
>> reach this limit
>> it is not a problem the only consequence would be that resolution and
>> wrap change.
>
> Got that, but that needs to be logged with a pr_warn or pr_info.

OK

>
>>>>       writel_relaxed(0, timer_of_base(to) + TIM_ARR);
>>>>       writel_relaxed(prescaler - 1, timer_of_base(to) + TIM_PSC);
>>>
>>> Can you fix this prescaler - 1 in order to be consistent with the
>>> computation with 16b ? (32b prescaler = 0, 16b prescaler = clk_rate /
>>> target ).
>>
>> In the hardware the clock is divise by " TIM_PSC value  1" so to be coherent
>> with that I need to do prescaler -1.
>
> Ah, ok.
>
>
> --
>  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs
>
> Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
> <http://twitter.com/#!/linaroorg> Twitter |
> <http://www.linaro.org/linaro-blog/> Blog
>



-- 
Benjamin Gaignard

Graphic Study Group

Linaro.org ? Open source software for ARM SoCs

Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* [PATCH] clk: sunxi: sun9i-mmc: Implement reset callback for reset controls
From: Philipp Zabel @ 2017-12-18 11:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171218035751.20661-1-wens@csie.org>

On Mon, 2017-12-18 at 11:57 +0800, Chen-Yu Tsai wrote:
> Our MMC host driver now issues a reset, instead of just deasserting
> the reset control, since commit c34eda69ad4c ("mmc: sunxi: Reset the
> device at probe time"). The sun9i-mmc clock driver does not support
> this, and will fail, which results in MMC not probing.
> 
> This patch implements the reset callback by asserting the reset control,
> then deasserting it after a small delay.
> 
> Fixes: 7a6fca879f59 ("clk: sunxi: Add driver for A80 MMC config clocks/resets")
> Cc: <stable@vger.kernel.org> # 4.14.x
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>

Acked-by: Philipp Zabel <p.zabel@pengutronix.de>

regards
Philipp

^ permalink raw reply

* [PATCH 2/3] arm64: dts: renesas: r8a7796: move nodes which have no reg property out of bus
From: Simon Horman @ 2017-12-18 11:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAMuHMdUx=MyFZypFpJPwXH-mz1Oz9W-UkEZP4QO3TSGnKEw0Fg@mail.gmail.com>

On Wed, Dec 13, 2017 at 09:34:15AM +0100, Geert Uytterhoeven wrote:
> Hi Simon,
> 
> On Wed, Dec 13, 2017 at 9:25 AM, Simon Horman <horms@verge.net.au> wrote:
> > For now I've applied the following:
> >
> > From: Simon Horman <horms+renesas@verge.net.au>
> > Date: Tue, 12 Dec 2017 09:24:35 +0100
> > Subject: [PATCH] arm64: dts: renesas: r8a7796: move nodes which have no reg
> >  property out of bus
> >
> > Move pmu_a5[73], timer and thermal-zones nodes from soc node to root node.
> > The nodes that have been moved do not have any register properties and thus
> > shouldn't be placed on the bus.
> 
> > index c1b0d0344329..e82b4db1ad1a 100644
> > --- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi
> > +++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
> > @@ -154,6 +154,23 @@
> >                 clock-frequency = <0>;
> >         };
> >
> > +       pmu_a57 {
> > +               compatible = "arm,cortex-a57-pmu";
> > +               interrupts-extended = <&gic GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
> > +                                     <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
> > +               interrupt-affinity = <&a57_0>,
> > +                                    <&a57_1>;
> 
> Merge?

Sure, sorry for missing that.

> 
> > +       };
> > +
> > +       pmu_a53 {
> > +               compatible = "arm,cortex-a53-pmu";
> > +               interrupts-extended = <&gic GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
> > +                                     <&gic GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
> > +                                     <&gic GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>,
> > +                                     <&gic GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
> > +               interrupt-affinity = <&a53_0>, <&a53_1>, <&a53_2>, <&a53_3>;
> 
> Thanks!
> 
> > +       };
> 
> > @@ -2027,4 +1968,56 @@
> >                         resets = <&cpg 822>;
> >                 };
> >         };
> > +
> > +       timer {
> > +               compatible = "arm,armv8-timer";
> > +               interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
> > +                                     <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
> > +                                     <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
> > +                                     <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>;
> 
> Much better!
> 
> Or even
> 
> > +               interrupts-extended =
> > +                       <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
> > +                       <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
> > +                       <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
> > +                       <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>;
> 
> I don't care that much, it extends beyond 80 characters anyway.

As its over 80 characters anyway lets go with my version.

^ permalink raw reply

* [PATCH 0/4 v5] Support bridge timings
From: Laurent Pinchart @ 2017-12-18 11:01 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20171215155415.GT26573@phenom.ffwll.local>

Hi Daniel,

On Friday, 15 December 2017 17:54:15 EET Daniel Vetter wrote:
> On Fri, Dec 15, 2017 at 01:30:24PM +0100, Linus Walleij wrote:
> > On Fri, Dec 15, 2017 at 1:10 PM, Linus Walleij <linus.walleij@linaro.org> 
wrote:
> >> - The connector is apparently not the right abstraction to carry
> >>   the detailed timings specification between DRI drivers and bridge
> >>   drivers.
> >> 
> >> - Instead put detailed timing data into the bridge itself as an
> >>   optional information pointer.
> > 
> > Notice that this is just my fumbling attempts to deal with the situation.
> > 
> > Laurent made me understand what the actual technical problem was,
> > how come my pixels were flickering.
> > 
> > Both Laurent and DVetter mentioned that we may need to convey
> > information between the bridge and the display engine in some
> > way.
> > 
> > Alternatively I could go and hack on adding this to e.g. drm_display_info
> > which was used in the previous patch sets by setting the negede flag
> > in bus_formats.
> > 
> > I don't know. struct drm_display_info is getting a bit heavy as
> > container of misc settings related to "some kind of display".
> > The bridge isn't even a display itself, that is on the other side
> > of it. So using the connector and treating a bridge as "some kind
> > of display" seems wrong too.
> > 
> > Is there a third way?
> 
> If you don't plan to nest bridges too deeply, there is. Atm we have 2
> modes in drm_crtc_state:
> 
> - mode, which is what userspace requested, and what it expects logically
>   to be the actual real thing. I.e. timing, resolution and all that that
>   userspace can observe (through plane positioning and vblank timestamps)
>   should match this mode. For external screens this should also match
>   what's physically going over the cable.
> 
> - adjusted_mode, which is something entirely undefined and to be used by
>   drivers internally. Most drivers use it as the thing that's actually
>   transported between the CRTC and the encoder.
> 
> There's a few common reasons for adjusted mode to be different:
> - integrated panel, and your CRTC has a scaler. In that case the
>   userspace-requested mode is what you feed into into the scaler, and the
>   adjusted mode is what comes out of your scaler and then goes down the
>   wire to the panel.
> 
> - your encoder is funky, and e.g. transcodes to the output mode itself,
>   but expects that you program the input mode always the same. Usual
>   reasons for this are transcoders that always want non-interlaced mode
>   (and do the interlacing themselves), if the transcoder has some scaler
>   itself (some TV-out transcoders had that), or if it has a strict
>   expectation about signalling edges and stuff (and then transcodes the
>   signal again). DACs are common doing that.
> 
> Anyway, sounds like your bridge is of the 2nd kind, so all you have to do
> is
> - in your bridge->mode_fixup function, adjust the adjusted_mode as needed
> - in your pl111 driver, program the adjusted mode, not the originally
>   requested mode
> 
> adjusted mode is set to be a copy of the requested mode by atomic helpers,
> so this should keep working as-is on any other bridge driver.

I don't think that's the right fix.

The problem here is that the display engine has to output data in a way that 
doesn't violate the DAC setup and hold times. Depending on the display engine, 
you can just select the output clock edge, or adjust the phase of the data 
compared to the pixel clock by a fraction of a clock cycle (1/4 is common, 
I've seen smaller steps too). Note that selecting the opposite clock edge is 
simple a 1/2 clock cycle delay.

The delay has to be computed based on the receiver's setup and hold times, but 
also take into account other components on the board (such as buffer or 
voltage shifters, or even inverters) and the PCB delay itself. This 
computation doesn't belong to the bridge driver, especially given than its 
goal is to compute a delay that depends on the display engine's capabilities 
(inverting the clock vs. smaller step delays for instance). For this reason I 
think the bridge driver should expose its timing parameters, and the display 
engine should then decide how to output its data accordingly.

> No idea why I didn't tell you this right away, or maybe I'm missing
> something this time around.
> 
> > I'm just a bit lost.
> 
> Once your un-lost, pls review the docs for drm_crtc_state and the various
> mode_fixup functions, to make sure they're clear on how this is supposed
> to work. Might need a new overview DOC: comment that ties it all together.

-- 
Regards,

Laurent Pinchart

^ 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