Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Use of GICv3/ITS with PCIe host-generic driver - resizing ITS MAPD?
From: Alan Douglas @ 2016-11-03 14:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <8637j9iomo.fsf@arm.com>

Hi Marc,
> >> > When setting up bus 0, the ITS device is created, and
> >> > its_build_map_cmd() sets the size of the ITS MAPD based on the
> >> > number of interrupts claimed by bus 0.  When subsequent buses are
> >> > enumerated, the ITS device will be reused, however we do not
> >> > increase the number of supported interrupts to allow for the
> >> > additional interrupts claimed by the additional devices being
> >> > enumerated.  (This can be seen in its_msi_prepare(), which is
> >> > called for each device which has MSI/MSI-X enabled, and will reuse
> >> > an existing ITS. )
> >>
> >> Am I right in understanding that all the PCIe devices in your system
> >> end-up aliasing to the same RequesterID? If so, that's a major issue.
> >> The ITS is designed so that each device exposes its *own* RID, and
> >> have its own Interrupt Translation Table (ITT).
> >>
> >> In your case, you seem to first discover the root port, which is not
> >> upstream of anything, so it doesn't alias with anything at that
> >> point. We allocate the corresponding ITT, and it's all fine. Until we
> >> start probing the rest, and ugly things happen.
> >>
> > Yes, your understanding is correct.  I will dig into this a bit
> > further to see what is wrong then send an update.  I suspect my DTS
> > msi mapping.
> 
> Right. That would explain a lot of what you're seeing. In general, and unless
> you have some funky remapping going on, you're better off having a very
> straightforward msi-map property in your RC node (such as example
> #1 in Documentation/devicetree/bindings/pci/pci-msi.txt).
The problem was that I had an msi-map-mask specified such that all
requester IDs were seen as zero.  Now fixed that and checked that the
requester ID for each device is being correctly provided by HW to the GIC, 
and all is now working correctly with without any patches required.
Thanks for your help.

Alan

^ permalink raw reply

* [RFC PATCH 0/3] ARM64: meson-gxbb: Add support for system suspend
From: Neil Armstrong @ 2016-11-03 14:29 UTC (permalink / raw)
  To: linux-arm-kernel

Thie patchset is a very experiment patchset to support the System Suspend
feature of the Amlogic Meson GX SoCs.

These SoCs implements system suspend using a non-standard PSCI CPU_SUSPEND
parameter to enter system suspend.
A small driver is added to properly fill the platform_suspend_ops and make
to correct SMC call.

In order to wake up from an alarm, these SoCs have a special memory mapped
register where an alarm time delay in seconds is stored.
In order to reuse the RTC wakealarm feature, implement a fake RTC device
that uses the system time to calculate a delay to write to the register.

Note that this RFC is here to seek a better way to handle these platform
specific features.

Neil Armstrong (3):
  ARM64: meson: Add Amlogic Meson GX PM Suspend
  rtc: Add Amlogic Virtual Wake RTC
  ARM64: dts: meson-gxbb: Add support for PM and Virtual RTC

 arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi |   9 ++
 drivers/firmware/meson/Kconfig              |   6 +
 drivers/firmware/meson/Makefile             |   1 +
 drivers/firmware/meson/meson_gx_pm.c        |  86 +++++++++++++++
 drivers/rtc/Kconfig                         |  10 ++
 drivers/rtc/Makefile                        |   1 +
 drivers/rtc/rtc-meson-vrtc.c                | 164 ++++++++++++++++++++++++++++
 7 files changed, 277 insertions(+)
 create mode 100644 drivers/firmware/meson/meson_gx_pm.c
 create mode 100644 drivers/rtc/rtc-meson-vrtc.c

-- 
1.9.1

^ permalink raw reply

* [RFC PATCH 1/3] ARM64: meson: Add Amlogic Meson GX PM Suspend
From: Neil Armstrong @ 2016-11-03 14:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478183365-23708-1-git-send-email-narmstrong@baylibre.com>

The Amlogic Meson GX SoCs uses a non-standard argument to the
PSCI CPU_SUSPEND call to enter system suspend.

Implement such call within platform_suspend_ops.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 drivers/firmware/meson/Kconfig       |  6 +++
 drivers/firmware/meson/Makefile      |  1 +
 drivers/firmware/meson/meson_gx_pm.c | 86 ++++++++++++++++++++++++++++++++++++
 3 files changed, 93 insertions(+)
 create mode 100644 drivers/firmware/meson/meson_gx_pm.c

diff --git a/drivers/firmware/meson/Kconfig b/drivers/firmware/meson/Kconfig
index 170d7e8..5b3fea3 100644
--- a/drivers/firmware/meson/Kconfig
+++ b/drivers/firmware/meson/Kconfig
@@ -7,3 +7,9 @@ config MESON_SM
 	depends on ARM64_4K_PAGES
 	help
 	  Say y here to enable the Amlogic secure monitor driver
+
+config MESON_GX_PM
+	bool
+	default ARCH_MESON if ARM64
+	help
+	  Say y here to enable the Amlogic GX SoC Power Management
diff --git a/drivers/firmware/meson/Makefile b/drivers/firmware/meson/Makefile
index 9ab3884..b6e285d 100644
--- a/drivers/firmware/meson/Makefile
+++ b/drivers/firmware/meson/Makefile
@@ -1 +1,2 @@
 obj-$(CONFIG_MESON_SM) +=	meson_sm.o
+obj-$(CONFIG_MESON_GX_PM) +=	meson_gx_pm.o
diff --git a/drivers/firmware/meson/meson_gx_pm.c b/drivers/firmware/meson/meson_gx_pm.c
new file mode 100644
index 0000000..c104c2e
--- /dev/null
+++ b/drivers/firmware/meson/meson_gx_pm.c
@@ -0,0 +1,86 @@
+/*
+ * Amlogic Meson GX Power Management
+ *
+ * Copyright (c) 2016 Baylibre, SAS.
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/suspend.h>
+#include <linux/arm-smccc.h>
+
+#include <uapi/linux/psci.h>
+
+#include <asm/suspend.h>
+
+/*
+ * The Amlogic GX SoCs uses a special argument value to the
+ * PSCI CPU_SUSPEND method to enter SUSPEND_MEM.
+ */
+
+#define MESON_SUSPEND_PARAM	0x0010000
+#define PSCI_FN_NATIVE(version, name)	PSCI_##version##_FN64_##name
+
+static int meson_gx_suspend_finish(unsigned long arg)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_smc(PSCI_FN_NATIVE(0_2, CPU_SUSPEND), arg,
+		      virt_to_phys(cpu_resume), 0, 0, 0, 0, 0, &res);
+
+	return res.a0;
+}
+
+static int meson_gx_suspend_enter(suspend_state_t state)
+{
+	switch (state) {
+	case PM_SUSPEND_MEM:
+		return cpu_suspend(MESON_SUSPEND_PARAM,
+				   meson_gx_suspend_finish);
+	}
+
+	return -EINVAL;
+}
+
+static const struct platform_suspend_ops meson_gx_pm_ops = {
+		.enter = meson_gx_suspend_enter,
+		.valid = suspend_valid_only_mem,
+};
+
+static const struct of_device_id meson_gx_pm_match[] = {
+	{ .compatible = "amlogic,meson-gx-pm", },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, meson_gx_pm_match);
+
+static int meson_gx_pm_probe(struct platform_device *pdev)
+{
+	suspend_set_ops(&meson_gx_pm_ops);
+
+	return 0;
+}
+
+static struct platform_driver meson_gx_pm_driver = {
+	.probe = meson_gx_pm_probe,
+	.driver = {
+		.name = "meson-gx-pm",
+		.of_match_table = meson_gx_pm_match,
+	},
+};
+
+module_platform_driver(meson_gx_pm_driver);
+
+MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
+MODULE_DESCRIPTION("Amlogic Meson GX PM driver");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1

^ permalink raw reply related

* [RFC PATCH 2/3] rtc: Add Amlogic Virtual Wake RTC
From: Neil Armstrong @ 2016-11-03 14:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478183365-23708-1-git-send-email-narmstrong@baylibre.com>

The Amlogic Meson GX SoCs uses a special register to store the
time in seconds to wakeup after a system suspend.

In order to be able to reuse the RTC wakealarm feature, this
driver implements a fake RTC device which uses the system time
to deduce a suspend delay.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 drivers/rtc/Kconfig          |  10 +++
 drivers/rtc/Makefile         |   1 +
 drivers/rtc/rtc-meson-vrtc.c | 164 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 175 insertions(+)
 create mode 100644 drivers/rtc/rtc-meson-vrtc.c

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index e859d14..d0f65fb 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -351,6 +351,16 @@ config RTC_DRV_MAX77686
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-max77686.
 
+config RTC_DRV_MESON_VRTC
+	tristate "Amlogic Meson Virtual RTC"
+	depends on ARCH_MESON
+	help
+	  If you say yes here you will get support for the
+	  Virtual RTC of Amlogic SoCs.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called rtc-meson-vrtc.
+
 config RTC_DRV_RK808
 	tristate "Rockchip RK808/RK818 RTC"
 	depends on MFD_RK808
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 1ac694a..feb83ad 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -92,6 +92,7 @@ obj-$(CONFIG_RTC_DRV_MAX8907)	+= rtc-max8907.o
 obj-$(CONFIG_RTC_DRV_MAX8925)	+= rtc-max8925.o
 obj-$(CONFIG_RTC_DRV_MAX8997)	+= rtc-max8997.o
 obj-$(CONFIG_RTC_DRV_MAX8998)	+= rtc-max8998.o
+obj-$(CONFIG_RTC_DRV_MESON_VRTC)+= rtc-meson-vrtc.o
 obj-$(CONFIG_RTC_DRV_MC13XXX)	+= rtc-mc13xxx.o
 obj-$(CONFIG_RTC_DRV_MCP795)	+= rtc-mcp795.o
 obj-$(CONFIG_RTC_DRV_MOXART)	+= rtc-moxart.o
diff --git a/drivers/rtc/rtc-meson-vrtc.c b/drivers/rtc/rtc-meson-vrtc.c
new file mode 100644
index 0000000..34c45bd
--- /dev/null
+++ b/drivers/rtc/rtc-meson-vrtc.c
@@ -0,0 +1,164 @@
+/*
+ * drivers/rtc/rtc-meson-vrtc.c
+ *
+ * Copyright (C) 2016 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/pm_wakeup.h>
+#include <linux/time64.h>
+
+struct meson_vrtc_data {
+	struct platform_device *pdev;
+	void __iomem *io_alarm;
+	struct rtc_device *rtc;
+	unsigned long alarm_time;
+};
+
+static int meson_vrtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	unsigned long local_time;
+	struct timeval time;
+
+	do_gettimeofday(&time);
+	local_time = time.tv_sec - (sys_tz.tz_minuteswest * 60);
+	rtc_time_to_tm(local_time, tm);
+
+	return 0;
+}
+
+static void meson_vrtc_set_wakeup_time(struct meson_vrtc_data *vrtc,
+				       unsigned long time)
+{
+	writel_relaxed(time, vrtc->io_alarm);
+
+	dev_dbg(&vrtc->pdev->dev, "set_wakeup_time: %lu\n", time);
+}
+
+static int meson_vrtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+	struct meson_vrtc_data *vrtc = dev_get_drvdata(dev);
+	struct timeval time;
+	unsigned long local_time;
+	unsigned long alarm_secs;
+	int ret;
+
+	if (alarm->enabled) {
+		ret = rtc_tm_to_time(&alarm->time, &alarm_secs);
+		if (ret)
+			return ret;
+
+		do_gettimeofday(&time);
+		local_time = time.tv_sec - (sys_tz.tz_minuteswest * 60);
+
+		vrtc->alarm_time = alarm_secs;
+
+		if (alarm_secs >= local_time) {
+			alarm_secs = alarm_secs - local_time;
+
+			meson_vrtc_set_wakeup_time(vrtc, alarm_secs);
+
+			pr_debug("system will wakeup %lus later\n", alarm_secs);
+		}
+	} else {
+		vrtc->alarm_time = 0;
+		meson_vrtc_set_wakeup_time(vrtc, 0);
+	}
+
+	return 0;
+}
+
+static int meson_vrtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+	struct meson_vrtc_data *vrtc = dev_get_drvdata(dev);
+
+	if (!vrtc->alarm_time) {
+		alm->enabled = true;
+
+		rtc_time_to_tm(vrtc->alarm_time, &alm->time);
+	}
+
+	return 0;
+}
+
+static const struct rtc_class_ops meson_vrtc_ops = {
+	.read_time = meson_vrtc_read_time,
+	.set_alarm = meson_vrtc_set_alarm,
+	.read_alarm = meson_vrtc_read_alarm,
+};
+
+static int meson_vrtc_probe(struct platform_device *pdev)
+{
+	struct meson_vrtc_data *vrtc;
+	struct resource *res;
+
+	vrtc = devm_kzalloc(&pdev->dev, sizeof(*vrtc), GFP_KERNEL);
+	if (!vrtc)
+		return -ENOMEM;
+
+	vrtc->pdev = pdev;
+
+	/* Alarm registers */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	vrtc->io_alarm = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(vrtc->io_alarm))
+		return PTR_ERR(vrtc->io_alarm);
+
+	device_init_wakeup(&pdev->dev, 1);
+
+	platform_set_drvdata(pdev, vrtc);
+
+	vrtc->rtc = devm_rtc_device_register(&pdev->dev, "meson-vrtc",
+			&meson_vrtc_ops, THIS_MODULE);
+	if (IS_ERR(vrtc->rtc))
+		return PTR_ERR(vrtc->rtc);
+
+	return 0;
+}
+
+int meson_vrtc_resume(struct platform_device *pdev)
+{
+	struct meson_vrtc_data *vrtc = platform_get_drvdata(pdev);
+
+	meson_vrtc_set_wakeup_time(vrtc, 0);
+
+	return 0;
+}
+
+static const struct of_device_id meson_vrtc_dt_match[] = {
+	{ .compatible = "amlogic,meson-vrtc"},
+	{},
+};
+MODULE_DEVICE_TABLE(of, meson_vrtc_dt_match);
+
+struct platform_driver meson_vrtc_driver = {
+	.driver = {
+		.name = "meson-vrtc",
+		.of_match_table = meson_vrtc_dt_match,
+	},
+	.probe = meson_vrtc_probe,
+	.resume = meson_vrtc_resume,
+};
+
+module_platform_driver(meson_vrtc_driver);
+
+MODULE_DESCRIPTION("Amlogic Virtual Wakeup RTC Timer driver");
+MODULE_LICENSE("GPL");
-- 
1.9.1

^ permalink raw reply related

* [RFC PATCH 3/3] ARM64: dts: meson-gxbb: Add support for PM and Virtual RTC
From: Neil Armstrong @ 2016-11-03 14:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478183365-23708-1-git-send-email-narmstrong@baylibre.com>

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
index 2d69a3b..6c08d21 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
@@ -56,6 +56,10 @@
 		};
 	};
 
+	system-suspend {
+		compatible = "amlogic,meson-gx-pm";
+	};
+
 	efuse: efuse {
 		compatible = "amlogic,meson-gxbb-efuse";
 		#address-cells = <1>;
@@ -355,6 +359,11 @@
 		#reset-cells = <1>;
 	};
 
+	vrtc: rtc at 0a8 {
+		compatible = "amlogic,meson-vrtc";
+		reg = <0x0 0x000a8 0x0 0x4>;
+	};
+
 	ir: ir at 580 {
 		compatible = "amlogic,meson-gxbb-ir";
 		reg = <0x0 0x00580 0x0 0x40>;
-- 
1.9.1

^ permalink raw reply related

* [PATCH 1/1] KVM: ARM64: Fix the issues when PMCCFILTR is configured
From: Wei Huang @ 2016-11-03 14:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <db2cdc7caf7dc40b0895e1b6f91c7758@codeaurora.org>



On 11/02/2016 11:11 PM, cov at codeaurora.org wrote:
> Hi Wei,
> 
> On 2016-11-02 14:55, Wei Huang wrote:
>> KVM calls kvm_pmu_set_counter_event_type() when PMCCFILTR is configured.
>> But this function can't deals with PMCCFILTR correctly because the
>> evtCount
>> bit of PMCCFILTR, which is reserved 0, conflits with the SW_INCR event
>> type of other PMXEVTYPER<n> registers. To fix it, when eventsel == 0, KVM
>> shouldn't return immediately, but instead it needs to check further if
>> select_idx is ARMV8_PMU_CYCLE_IDX.
>>
>> Another issue is that KVM shouldn't copy the eventsel bits of PMCCFILTER
>> directly to attr.config. Istead it shoudl convert the request to
>> perf_event of type 0x11 (i.e. the "cpu cycle" event type).
>>
>> Signed-off-by: Wei Huang <wei@redhat.com>
>> ---
>>  virt/kvm/arm/pmu.c | 5 +++--
>>  1 file changed, 3 insertions(+), 2 deletions(-)
>>
>> diff --git a/virt/kvm/arm/pmu.c b/virt/kvm/arm/pmu.c
>> index 6e9c40e..13cc812 100644
>> --- a/virt/kvm/arm/pmu.c
>> +++ b/virt/kvm/arm/pmu.c
>> @@ -379,7 +379,8 @@ void kvm_pmu_set_counter_event_type(struct
>> kvm_vcpu *vcpu, u64 data,
>>      eventsel = data & ARMV8_PMU_EVTYPE_EVENT;
>>
>>      /* Software increment event does't need to be backed by a perf
>> event */
>> -    if (eventsel == ARMV8_PMU_EVTYPE_EVENT_SW_INCR)
>> +    if (eventsel == ARMV8_PMU_EVTYPE_EVENT_SW_INCR &&
>> +        select_idx != ARMV8_PMU_CYCLE_IDX)
>>          return;
>>
>>      memset(&attr, 0, sizeof(struct perf_event_attr));
>> @@ -391,7 +392,7 @@ void kvm_pmu_set_counter_event_type(struct
>> kvm_vcpu *vcpu, u64 data,
>>      attr.exclude_kernel = data & ARMV8_PMU_EXCLUDE_EL1 ? 1 : 0;
>>      attr.exclude_hv = 1; /* Don't count EL2 events */
>>      attr.exclude_host = 1; /* Don't count host events */
>> -    attr.config = eventsel;
>> +    attr.config = (select_idx == ARMV8_PMU_CYCLE_IDX) ? 0x011 :
>> eventsel;
> 
> Nit: Is there some way you could use ARMV8_PMUV3_PERFCTR_CPU_CYCLES
> currently
> defined in arch/arm64/kernel/perf_event.c?

The event definitions in perf_event.c are local to this file. To use
them, I have to re-factor them out to a header file, which is bigger
than this patch intended. How about adding the following line to
arch/arm64/include/asm/perf_event.h (i.e. the same file of
ARMV8_PMU_EVTYPE_EVENT_SW_INCR)?

#define ARMV8_PMU_EVTYPE_EVENT_CPU_CYCLES  0x11



> 
> Thanks,
> Cov

^ permalink raw reply

* [PATCH] clk: rockchip: fix some clocks' name to be more standard style
From: Heiko Stübner @ 2016-11-03 14:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <763cad68-a068-9a4b-e26d-2c459c2d4808@rock-chips.com>

Am Donnerstag, 3. November 2016, 16:52:48 schrieb Shawn Lin:
> On 2016/11/2 15:04, Jianqun Xu wrote:
> > Fix aclk_emmcgrf to aclk_emmc_grf, and fix aclk_emmccore to be
> > aclk_emmc_core.
> 
> What is the standard style should be?
> 
> TRM uses aclk_emmccore but not aclk_emmc_core, so should it be more
> standrad to keep it as-is?

I tend to agree with Shawn. While it looks like the missing "_" is some sort 
of mistake, we should strive to follow TRM naming, so grepping so it becomes 
easier to look for informations in these things in the TRM.

Same reason for naming our regulators and pinctrl after the names used in 
device schematics, if available.


Heiko

^ permalink raw reply

* [PATCHv3 1/4] dt-bindings: mfd: Add Altera Arria10 SR Monitor
From: Lee Jones @ 2016-11-03 14:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478097178-24341-2-git-send-email-tthayer@opensource.altera.com>

On Wed, 02 Nov 2016, tthayer at opensource.altera.com wrote:

> From: Thor Thayer <tthayer@opensource.altera.com>
> 
> Add the Arria10 DevKit System Resource Chip register and state
> monitoring module to the MFD.
> 
> Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
> ---
> Note: This needs to be applied to the bindings document that
> was Acked & Applied but didn't reach the for-next branch.
> See https://patchwork.ozlabs.org/patch/629397/
> ---
> v2  Change compatible string -mon to -monitor for clarity
> v3  Replace node name a10sr_monitor with just monitor.
>     Replace node name a10sr_gpio with just gpio.
> ---
>  Documentation/devicetree/bindings/mfd/altera-a10sr.txt | 11 ++++++++++-
>  1 file changed, 10 insertions(+), 1 deletion(-)

For my own reference:
  Acked-for-MFD-by: Lee Jones <lee.jones@linaro.org>

> diff --git a/Documentation/devicetree/bindings/mfd/altera-a10sr.txt b/Documentation/devicetree/bindings/mfd/altera-a10sr.txt
> index ea151f2..69243d2 100644
> --- a/Documentation/devicetree/bindings/mfd/altera-a10sr.txt
> +++ b/Documentation/devicetree/bindings/mfd/altera-a10sr.txt
> @@ -17,7 +17,8 @@ The A10SR consists of these sub-devices:
>  
>  Device                   Description
>  ------                   ----------
> -a10sr_gpio               GPIO Controller
> +gpio                     GPIO Controller
> +monitor                  Register and State Monitoring
>  
>  Arria10 GPIO
>  Required Properties:
> @@ -27,6 +28,10 @@ Required Properties:
>                        the second cell is used to specify flags.
>                        See ../gpio/gpio.txt for more information.
>  
> +Arria10 Register and State Monitor
> +Required Properties:
> +- compatible        : Should be "altr,a10sr-monitor"
> +
>  Example:
>  
>          resource-manager at 0 {
> @@ -43,4 +48,8 @@ Example:
>  			gpio-controller;
>  			#gpio-cells = <2>;
>  		};
> +
> +		monitor {
> +			compatible = "altr,a10sr-monitor";
> +		};
>  	};

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* [PATCH v2 1/2] PM/devfreq: add suspend frequency support
From: kbuild test robot @ 2016-11-03 14:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478153770-8433-2-git-send-email-hl@rock-chips.com>

Hi Lin,

[auto build test ERROR on linus/master]
[also build test ERROR on v4.9-rc3 next-20161028]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Lin-Huang/set-specific-ddr-frequency-when-stop-ddr-dvfs/20161103-142055
config: x86_64-randconfig-x015-201644 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   drivers/devfreq/devfreq.c: In function 'devfreq_monitor_suspend':
>> drivers/devfreq/devfreq.c:368:3: error: too many arguments to function 'update_devfreq'
      update_devfreq(devfreq, devfreq->suspend_freq);
      ^~~~~~~~~~~~~~
   drivers/devfreq/devfreq.c:228:5: note: declared here
    int update_devfreq(struct devfreq *devfreq)
        ^~~~~~~~~~~~~~

vim +/update_devfreq +368 drivers/devfreq/devfreq.c

   362		if (devfreq->stop_polling) {
   363			mutex_unlock(&devfreq->lock);
   364			return;
   365		}
   366	
   367		if (devfreq->suspend_freq)
 > 368			update_devfreq(devfreq, devfreq->suspend_freq);
   369		else
   370			devfreq_update_status(devfreq, devfreq->previous_freq);
   371		devfreq->stop_polling = true;

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 23592 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161103/9251898a/attachment-0001.gz>

^ permalink raw reply

* [PATCH v7 3/3] iio: adc: add support for Allwinner SoCs ADC
From: Lee Jones @ 2016-11-03 14:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161103101601.24529-4-quentin.schulz@free-electrons.com>

On Thu, 03 Nov 2016, Quentin Schulz wrote:

> The Allwinner SoCs all have an ADC that can also act as a touchscreen
> controller and a thermal sensor. This patch adds the ADC driver which is
> based on the MFD for the same SoCs ADC.
> 
> This also registers the thermal adc channel in the iio map array so
> iio_hwmon could use it without modifying the Device Tree. This registers
> the driver in the thermal framework.
> 
> The thermal sensor requires the IP to be in touchscreen mode to return correct
> values. Therefore, if the user is continuously reading the ADC channel(s), the
> thermal framework in which the thermal sensor is registered will switch the IP
> in touchscreen mode to get a temperature value and requires a delay of 100ms
> (because of the mode switching), then the ADC will switch back to ADC mode and
> requires also a delay of 100ms. If the ADC readings are critical to user and the
> SoC temperature is not, this driver is capable of not registering the thermal
> sensor in the thermal framework and thus, "quicken" the ADC readings.
> 
> This driver probes on three different platform_device_id to take into
> account slight differences (registers bit and temperature computation)
> between Allwinner SoCs ADCs.
> 
> Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
> Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> Acked-by: Jonathan Cameron <jic23@kernel.org>
> ---
> 
> v7:
>  - add Kconfig depends on !TOUCHSCREEN_SUN4I,
>  - remove Kconfig selects THERMAL_OF,
>  - do not register thermal sensor if CONFIG_THERMAL_OF is disabled,
>  - disable irq in irq_handler rather than in read_raw,
>  - add delay when switching the IP's mode or channel (delay empirically found),
>  - quicken thermal sensor interrupt period,
>  - add masks for channel bits,
>  - fix deadlock in sun4i_gpadc_read if regmap_read/write fails,
>  - move some logic from sun4i_gpadc_read to sun4i_prepare_for_irq,
>  - mark last busy for runtime_pm only on success in sun4i_gpadc_read,
>  - remove cached values,
>  - increase wait_for_completion_timeout timeout to 1s to be sure to not miss the
>  thermal interrupt,
>  - add voltage scale,
>  - use devm_iio_device_register,
> 
> v6:
>  - remove "-mfd" from filenames and variables inside MFD driver,
>  - use DEFINE_RES_IRQ_NAMED instead of setting resources manually,
>  - cosmetic changes,
>  - use IDs and switch over ID to get cells specific to an architecture, instead
>  of using cells direclty, in of_device_id.data,
>  - compute size of mfd_cells array instead of hardcoded one,
> 
> v5:
>  - correct mail address,
> 
> v4:
>  - rename files and variables from sunxi* to sun4i*,
>  - rename defines from SUNXI_* to SUN4I_* or SUN6I_*,
>  - remove TP in defines name,
>  - rename SUNXI_IRQ_* to SUN4I_GPADC_IRQ_* for consistency,
>  - use devm functions for regmap_add_irq_chip and mfd_add_devices,
>  - remove remove functions (now empty thanks to devm functions),
> 
> v3:
>  - use defines in regmap_irq instead of hard coded BITs,
>  - use of_device_id data field to chose which MFD cells to add considering
>    the compatible responsible of the MFD probe,
>  - remove useless initializations,
>  - disable all interrupts before adding them to regmap_irqchip,
>  - add goto error label in probe,
>  - correct wrapping in header license,
>  - move defines from IIO driver to header,
>  - use GENMASK to limit the size of the variable passed to a macro,
>  - prefix register BIT defines with the name of the register,
>  - reorder defines,
> 
> v2:
>  - add license headers,
>  - reorder alphabetically includes,
>  - add SUNXI_GPADC_ prefixes for defines,
> 
>  drivers/iio/adc/Kconfig           |  17 ++
>  drivers/iio/adc/Makefile          |   1 +
>  drivers/iio/adc/sun4i-gpadc-iio.c | 605 ++++++++++++++++++++++++++++++++++++++
>  include/linux/mfd/sun4i-gpadc.h   |   2 +
>  4 files changed, 625 insertions(+)
>  create mode 100644 drivers/iio/adc/sun4i-gpadc-iio.c

For my own reference:
  Acked-for-MFD-by: Lee Jones <lee.jones@linaro.org>

> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> index 7edcf32..9aa3c945 100644
> --- a/drivers/iio/adc/Kconfig
> +++ b/drivers/iio/adc/Kconfig
> @@ -434,6 +434,23 @@ config STX104
>  	  The base port addresses for the devices may be configured via the base
>  	  array module parameter.
>  
> +config SUN4I_GPADC
> +	tristate "Support for the Allwinner SoCs GPADC"
> +	depends on IIO
> +	depends on MFD_SUN4I_GPADC
> +	depends on !TOUCHSCREEN_SUN4I
> +	help
> +	  Say yes here to build support for Allwinner (A10, A13 and A31) SoCs
> +	  GPADC. This ADC provides 4 channels which can be used as an ADC or as
> +	  a touchscreen input and one channel for thermal sensor.
> +
> +	  The thermal sensor is activated by default but slows down ADC
> +	  readings. You can disable CONFIG_THERMAL_OF to disable the CPU thermal
> +	  sensor if you want faster ADC readings.
> +
> +	  To compile this driver as a module, choose M here: the module will be
> +	  called sun4i-gpadc-iio.
> +
>  config TI_ADC081C
>  	tristate "Texas Instruments ADC081C/ADC101C/ADC121C family"
>  	depends on I2C
> diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
> index 7a40c04..18ce8d6 100644
> --- a/drivers/iio/adc/Makefile
> +++ b/drivers/iio/adc/Makefile
> @@ -41,6 +41,7 @@ obj-$(CONFIG_QCOM_SPMI_IADC) += qcom-spmi-iadc.o
>  obj-$(CONFIG_QCOM_SPMI_VADC) += qcom-spmi-vadc.o
>  obj-$(CONFIG_ROCKCHIP_SARADC) += rockchip_saradc.o
>  obj-$(CONFIG_STX104) += stx104.o
> +obj-$(CONFIG_SUN4I_GPADC) += sun4i-gpadc-iio.o
>  obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
>  obj-$(CONFIG_TI_ADC0832) += ti-adc0832.o
>  obj-$(CONFIG_TI_ADC12138) += ti-adc12138.o
> diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c
> new file mode 100644
> index 0000000..f275ccb
> --- /dev/null
> +++ b/drivers/iio/adc/sun4i-gpadc-iio.c
> @@ -0,0 +1,605 @@
> +/* ADC driver for sunxi platforms' (A10, A13 and A31) GPADC
> + *
> + * Copyright (c) 2016 Quentin Schulz <quentin.schulz@free-electrons.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it under
> + * the terms of the GNU General Public License version 2 as published by the
> + * Free Software Foundation.
> + *
> + * The Allwinner SoCs all have an ADC that can also act as a touchscreen
> + * controller and a thermal sensor.
> + * The thermal sensor works only when the ADC acts as a touchscreen controller
> + * and is configured to throw an interrupt every fixed periods of time (let say
> + * every X seconds).
> + * One would be tempted to disable the IP on the hardware side rather than
> + * disabling interrupts to save some power but that resets the internal clock of
> + * the IP, resulting in having to wait X seconds every time we want to read the
> + * value of the thermal sensor.
> + * This is also the reason of using autosuspend in pm_runtime. If there was no
> + * autosuspend, the thermal sensor would need X seconds after every
> + * pm_runtime_get_sync to get a value from the ADC. The autosuspend allows the
> + * thermal sensor to be requested again in a certain time span before it gets
> + * shutdown for not being used.
> + */
> +
> +#include <linux/completion.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/regmap.h>
> +#include <linux/thermal.h>
> +#include <linux/delay.h>
> +
> +#include <linux/iio/iio.h>
> +#include <linux/iio/driver.h>
> +#include <linux/iio/machine.h>
> +#include <linux/mfd/sun4i-gpadc.h>
> +
> +static unsigned int sun4i_gpadc_chan_select(unsigned int chan)
> +{
> +	return SUN4I_GPADC_CTRL1_ADC_CHAN_SELECT(chan);
> +}
> +
> +static unsigned int sun6i_gpadc_chan_select(unsigned int chan)
> +{
> +	return SUN6I_GPADC_CTRL1_ADC_CHAN_SELECT(chan);
> +}
> +
> +struct gpadc_data {
> +	int		temp_offset;
> +	int		temp_scale;
> +	unsigned int	tp_mode_en;
> +	unsigned int	tp_adc_select;
> +	unsigned int	(*adc_chan_select)(unsigned int chan);
> +	unsigned int	adc_chan_mask;
> +};
> +
> +static const struct gpadc_data sun4i_gpadc_data = {
> +	.temp_offset = -1932,
> +	.temp_scale = 133,
> +	.tp_mode_en = SUN4I_GPADC_CTRL1_TP_MODE_EN,
> +	.tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
> +	.adc_chan_select = &sun4i_gpadc_chan_select,
> +	.adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
> +};
> +
> +static const struct gpadc_data sun5i_gpadc_data = {
> +	.temp_offset = -1447,
> +	.temp_scale = 100,
> +	.tp_mode_en = SUN4I_GPADC_CTRL1_TP_MODE_EN,
> +	.tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
> +	.adc_chan_select = &sun4i_gpadc_chan_select,
> +	.adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
> +};
> +
> +static const struct gpadc_data sun6i_gpadc_data = {
> +	.temp_offset = -1623,
> +	.temp_scale = 167,
> +	.tp_mode_en = SUN6I_GPADC_CTRL1_TP_MODE_EN,
> +	.tp_adc_select = SUN6I_GPADC_CTRL1_TP_ADC_SELECT,
> +	.adc_chan_select = &sun6i_gpadc_chan_select,
> +	.adc_chan_mask = SUN6I_GPADC_CTRL1_ADC_CHAN_MASK,
> +};
> +
> +struct sun4i_gpadc_iio {
> +	struct iio_dev			*indio_dev;
> +	struct completion		completion;
> +	int				temp_data;
> +	u32				adc_data;
> +	struct regmap			*regmap;
> +	unsigned int			fifo_data_irq;
> +	atomic_t			ignore_fifo_data_irq;
> +	unsigned int			temp_data_irq;
> +	atomic_t			ignore_temp_data_irq;
> +	const struct gpadc_data		*data;
> +	/* prevents concurrent reads of temperature and ADC */
> +	struct mutex			mutex;
> +};
> +
> +#define SUN4I_GPADC_ADC_CHANNEL(_channel, _name) {		\
> +	.type = IIO_VOLTAGE,					\
> +	.indexed = 1,						\
> +	.channel = _channel,					\
> +	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
> +	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
> +	.datasheet_name = _name,				\
> +}
> +
> +static struct iio_map sun4i_gpadc_hwmon_maps[] = {
> +	{
> +		.adc_channel_label = "temp_adc",
> +		.consumer_dev_name = "iio_hwmon.0",
> +	},
> +	{ /* sentinel */ },
> +};
> +
> +static const struct iio_chan_spec sun4i_gpadc_channels[] = {
> +	SUN4I_GPADC_ADC_CHANNEL(0, "adc_chan0"),
> +	SUN4I_GPADC_ADC_CHANNEL(1, "adc_chan1"),
> +	SUN4I_GPADC_ADC_CHANNEL(2, "adc_chan2"),
> +	SUN4I_GPADC_ADC_CHANNEL(3, "adc_chan3"),
> +	{
> +		.type = IIO_TEMP,
> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> +				      BIT(IIO_CHAN_INFO_SCALE) |
> +				      BIT(IIO_CHAN_INFO_OFFSET),
> +		.datasheet_name = "temp_adc",
> +	},
> +};
> +
> +static const struct iio_chan_spec sun4i_gpadc_channels_no_temp[] = {
> +	SUN4I_GPADC_ADC_CHANNEL(0, "adc_chan0"),
> +	SUN4I_GPADC_ADC_CHANNEL(1, "adc_chan1"),
> +	SUN4I_GPADC_ADC_CHANNEL(2, "adc_chan2"),
> +	SUN4I_GPADC_ADC_CHANNEL(3, "adc_chan3"),
> +};
> +
> +static int sun4i_prepare_for_irq(struct iio_dev *indio_dev, int channel,
> +				 unsigned int irq)
> +{
> +	struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
> +	int ret;
> +	u32 reg;
> +
> +	pm_runtime_get_sync(indio_dev->dev.parent);
> +
> +	reinit_completion(&info->completion);
> +
> +	ret = regmap_write(info->regmap, SUN4I_GPADC_INT_FIFOC,
> +			   SUN4I_GPADC_INT_FIFOC_TP_FIFO_TRIG_LEVEL(1) |
> +			   SUN4I_GPADC_INT_FIFOC_TP_FIFO_FLUSH);
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_read(info->regmap, SUN4I_GPADC_CTRL1, &reg);
> +	if (ret)
> +		return ret;
> +
> +	if (irq == info->fifo_data_irq) {
> +		ret = regmap_write(info->regmap, SUN4I_GPADC_CTRL1,
> +				   info->data->tp_mode_en |
> +				   info->data->tp_adc_select |
> +				   info->data->adc_chan_select(channel));
> +		/*
> +		 * When the IP changes channel, it needs a bit of time to get
> +		 * correct values.
> +		 */
> +		if ((reg & info->data->adc_chan_mask) !=
> +			 info->data->adc_chan_select(channel))
> +			mdelay(10);
> +
> +	} else {
> +		/*
> +		 * The temperature sensor returns valid data only when the ADC
> +		 * operates in touchscreen mode.
> +		 */
> +		ret = regmap_write(info->regmap, SUN4I_GPADC_CTRL1,
> +				   info->data->tp_mode_en);
> +	}
> +
> +	if (ret)
> +		return ret;
> +
> +	/*
> +	 * When the IP changes mode between ADC or touchscreen, it
> +	 * needs a bit of time to get correct values.
> +	 */
> +	if ((reg & info->data->tp_adc_select) != info->data->tp_adc_select)
> +		mdelay(100);
> +
> +	return 0;
> +}
> +
> +static int sun4i_gpadc_read(struct iio_dev *indio_dev, int channel, int *val,
> +			    unsigned int irq)
> +{
> +	struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
> +	int ret;
> +
> +	mutex_lock(&info->mutex);
> +
> +	ret = sun4i_prepare_for_irq(indio_dev, channel, irq);
> +	if (ret)
> +		goto err;
> +
> +	enable_irq(irq);
> +
> +	/*
> +	 * The temperature sensor throws an interruption periodically (currently
> +	 * set at periods of ~0.6s in sun4i_gpadc_runtime_resume). A 1s delay
> +	 * makes sure an interruption occurs in normal conditions. If it doesn't
> +	 * occur, then there is a timeout.
> +	 */
> +	if (!wait_for_completion_timeout(&info->completion,
> +					 msecs_to_jiffies(1000))) {
> +		ret = -ETIMEDOUT;
> +		goto err;
> +	}
> +
> +	if (irq == info->fifo_data_irq)
> +		*val = info->adc_data;
> +	else
> +		*val = info->temp_data;
> +
> +	ret = 0;
> +	pm_runtime_mark_last_busy(indio_dev->dev.parent);
> +
> +err:
> +	pm_runtime_put_autosuspend(indio_dev->dev.parent);
> +	mutex_unlock(&info->mutex);
> +
> +	return ret;
> +}
> +
> +static int sun4i_gpadc_adc_read(struct iio_dev *indio_dev, int channel,
> +				int *val)
> +{
> +	struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
> +
> +	return sun4i_gpadc_read(indio_dev, channel, val, info->fifo_data_irq);
> +}
> +
> +static int sun4i_gpadc_temp_read(struct iio_dev *indio_dev, int *val)
> +{
> +	struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
> +
> +	return sun4i_gpadc_read(indio_dev, 0, val, info->temp_data_irq);
> +}
> +
> +static int sun4i_gpadc_temp_offset(struct iio_dev *indio_dev, int *val)
> +{
> +	struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
> +
> +	*val = info->data->temp_offset;
> +
> +	return 0;
> +}
> +
> +static int sun4i_gpadc_temp_scale(struct iio_dev *indio_dev, int *val)
> +{
> +	struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
> +
> +	*val = info->data->temp_scale;
> +
> +	return 0;
> +}
> +
> +static int sun4i_gpadc_read_raw(struct iio_dev *indio_dev,
> +				struct iio_chan_spec const *chan, int *val,
> +				int *val2, long mask)
> +{
> +	int ret;
> +
> +	switch (mask) {
> +	case IIO_CHAN_INFO_OFFSET:
> +		ret = sun4i_gpadc_temp_offset(indio_dev, val);
> +		if (ret)
> +			return ret;
> +
> +		return IIO_VAL_INT;
> +	case IIO_CHAN_INFO_RAW:
> +		if (chan->type == IIO_VOLTAGE)
> +			ret = sun4i_gpadc_adc_read(indio_dev, chan->channel,
> +						   val);
> +		else
> +			ret = sun4i_gpadc_temp_read(indio_dev, val);
> +
> +		if (ret)
> +			return ret;
> +
> +		return IIO_VAL_INT;
> +	case IIO_CHAN_INFO_SCALE:
> +		if (chan->type == IIO_VOLTAGE) {
> +			/* 3000mV / 4096 * raw */
> +			*val = 0;
> +			*val2 = 732421875;
> +			return IIO_VAL_INT_PLUS_MICRO;
> +		}
> +
> +		ret = sun4i_gpadc_temp_scale(indio_dev, val);
> +		if (ret)
> +			return ret;
> +
> +		return IIO_VAL_INT;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static const struct iio_info sun4i_gpadc_iio_info = {
> +	.read_raw = sun4i_gpadc_read_raw,
> +	.driver_module = THIS_MODULE,
> +};
> +
> +static irqreturn_t sun4i_gpadc_temp_data_irq_handler(int irq, void *dev_id)
> +{
> +	struct sun4i_gpadc_iio *info = dev_id;
> +
> +	if (atomic_read(&info->ignore_temp_data_irq))
> +		goto out;
> +
> +	if (!regmap_read(info->regmap, SUN4I_GPADC_TEMP_DATA, &info->temp_data))
> +		complete(&info->completion);
> +
> +out:
> +	disable_irq_nosync(info->temp_data_irq);
> +	return IRQ_HANDLED;
> +}
> +
> +static irqreturn_t sun4i_gpadc_fifo_data_irq_handler(int irq, void *dev_id)
> +{
> +	struct sun4i_gpadc_iio *info = dev_id;
> +
> +	if (atomic_read(&info->ignore_fifo_data_irq))
> +		goto out;
> +
> +	if (!regmap_read(info->regmap, SUN4I_GPADC_DATA, &info->adc_data))
> +		complete(&info->completion);
> +
> +out:
> +	disable_irq_nosync(info->fifo_data_irq);
> +	return IRQ_HANDLED;
> +}
> +
> +static int sun4i_gpadc_runtime_suspend(struct device *dev)
> +{
> +	struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev));
> +
> +	/* Disable the ADC on IP */
> +	regmap_write(info->regmap, SUN4I_GPADC_CTRL1, 0);
> +	/* Disable temperature sensor on IP */
> +	regmap_write(info->regmap, SUN4I_GPADC_TPR, 0);
> +
> +	return 0;
> +}
> +
> +static int sun4i_gpadc_runtime_resume(struct device *dev)
> +{
> +	struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev));
> +
> +	/* clkin = 6MHz */
> +	regmap_write(info->regmap, SUN4I_GPADC_CTRL0,
> +		     SUN4I_GPADC_CTRL0_ADC_CLK_DIVIDER(2) |
> +		     SUN4I_GPADC_CTRL0_FS_DIV(7) |
> +		     SUN4I_GPADC_CTRL0_T_ACQ(63));
> +	regmap_write(info->regmap, SUN4I_GPADC_CTRL1, info->data->tp_mode_en);
> +	regmap_write(info->regmap, SUN4I_GPADC_CTRL3,
> +		     SUN4I_GPADC_CTRL3_FILTER_EN |
> +		     SUN4I_GPADC_CTRL3_FILTER_TYPE(1));
> +	/* period = SUN4I_GPADC_TPR_TEMP_PERIOD * 256 * 16 / clkin; ~0.6s */
> +	regmap_write(info->regmap, SUN4I_GPADC_TPR,
> +		     SUN4I_GPADC_TPR_TEMP_ENABLE |
> +		     SUN4I_GPADC_TPR_TEMP_PERIOD(800));
> +
> +	return 0;
> +}
> +
> +static int sun4i_gpadc_get_temp(void *data, int *temp)
> +{
> +	struct sun4i_gpadc_iio *info = (struct sun4i_gpadc_iio *)data;
> +	int val, scale, offset;
> +
> +	if (sun4i_gpadc_temp_read(info->indio_dev, &val))
> +		return -ETIMEDOUT;
> +
> +	sun4i_gpadc_temp_scale(info->indio_dev, &scale);
> +	sun4i_gpadc_temp_offset(info->indio_dev, &offset);
> +
> +	*temp = (val + offset) * scale;
> +
> +	return 0;
> +}
> +
> +static const struct thermal_zone_of_device_ops sun4i_ts_tz_ops = {
> +	.get_temp = &sun4i_gpadc_get_temp,
> +};
> +
> +static const struct dev_pm_ops sun4i_gpadc_pm_ops = {
> +	.runtime_suspend = &sun4i_gpadc_runtime_suspend,
> +	.runtime_resume = &sun4i_gpadc_runtime_resume,
> +};
> +
> +static int sun4i_irq_init(struct platform_device *pdev, const char *name,
> +			  irq_handler_t handler, const char *devname,
> +			  unsigned int *irq, atomic_t *atomic)
> +{
> +	int ret;
> +	struct sun4i_gpadc_dev *mfd_dev = dev_get_drvdata(pdev->dev.parent);
> +	struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(&pdev->dev));
> +
> +	/*
> +	 * Once the interrupt is activated, the IP continuously performs
> +	 * conversions thus throws interrupts. The interrupt is activated right
> +	 * after being requested but we want to control when these interrupts
> +	 * occur thus we disable it right after being requested. However, an
> +	 * interrupt might occur between these two instructions and we have to
> +	 * make sure that does not happen, by using atomic flags. We set the
> +	 * flag before requesting the interrupt and unset it right after
> +	 * disabling the interrupt. When an interrupt occurs between these two
> +	 * instructions, reading the atomic flag will tell us to ignore the
> +	 * interrupt.
> +	 */
> +	atomic_set(atomic, 1);
> +
> +	*irq = platform_get_irq_byname(pdev, name);
> +	if (*irq < 0) {
> +		dev_err(&pdev->dev, "no %s interrupt registered\n", name);
> +		return *irq;
> +	}
> +
> +	*irq = regmap_irq_get_virq(mfd_dev->regmap_irqc, *irq);
> +	ret = devm_request_any_context_irq(&pdev->dev, *irq, handler, 0,
> +					   devname, info);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "could not request %s interrupt: %d\n",
> +			name, ret);
> +		return ret;
> +	}
> +
> +	disable_irq(*irq);
> +	atomic_set(atomic, 0);
> +
> +	return 0;
> +}
> +
> +static int sun4i_gpadc_probe(struct platform_device *pdev)
> +{
> +	struct sun4i_gpadc_iio *info;
> +	struct iio_dev *indio_dev;
> +	int ret;
> +	struct sun4i_gpadc_dev *sun4i_gpadc_dev;
> +	struct thermal_zone_device *tzd;
> +
> +	sun4i_gpadc_dev = dev_get_drvdata(pdev->dev.parent);
> +
> +	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info));
> +	if (!indio_dev)
> +		return -ENOMEM;
> +
> +	info = iio_priv(indio_dev);
> +	platform_set_drvdata(pdev, indio_dev);
> +
> +	mutex_init(&info->mutex);
> +	info->regmap = sun4i_gpadc_dev->regmap;
> +	info->indio_dev = indio_dev;
> +	init_completion(&info->completion);
> +	indio_dev->name = dev_name(&pdev->dev);
> +	indio_dev->dev.parent = &pdev->dev;
> +	indio_dev->dev.of_node = pdev->dev.of_node;
> +	indio_dev->info = &sun4i_gpadc_iio_info;
> +	indio_dev->modes = INDIO_DIRECT_MODE;
> +	indio_dev->num_channels = ARRAY_SIZE(sun4i_gpadc_channels);
> +	indio_dev->channels = sun4i_gpadc_channels;
> +
> +	info->data = (struct gpadc_data *)platform_get_device_id(pdev)->driver_data;
> +
> +	/*
> +	 * Since the thermal sensor needs the IP to be in touchscreen mode and
> +	 * there is no register to know if the IP has finished its transition
> +	 * between the two modes, a delay is required when switching modes. This
> +	 * slows down ADC readings while the latter are critical data to the
> +	 * user. Disabling CONFIG_THERMAL_OF in kernel configuration allows the
> +	 * user to avoid registering the thermal sensor (thus unavailable) and
> +	 * does not switch between modes thus "quicken" the ADC readings.
> +	 * The thermal sensor should be enabled by default since the SoC
> +	 * temperature is usually more critical than ADC readings.
> +	 */
> +
> +	if (IS_ENABLED(CONFIG_THERMAL_OF)) {
> +	/*
> +	 * This driver is a child of an MFD which has a node in the DT but not
> +	 * its children. Therefore, the resulting devices of this driver do not
> +	 * have an of_node variable.
> +	 * However, its parent (the MFD driver) has an of_node variable and
> +	 * since devm_thermal_zone_of_sensor_register uses its first argument to
> +	 * match the phandle defined in the node of the thermal driver with the
> +	 * of_node of the device passed as first argument and the third argument
> +	 * to call ops from thermal_zone_of_device_ops, the solution is to use
> +	 * the parent device as first argument to match the phandle with its
> +	 * of_node, and the device from this driver as third argument to return
> +	 * the temperature.
> +	 */
> +		tzd = devm_thermal_zone_of_sensor_register(pdev->dev.parent, 0,
> +							   info,
> +							   &sun4i_ts_tz_ops);
> +		if (IS_ERR(tzd)) {
> +			dev_err(&pdev->dev,
> +				"could not register thermal sensor: %ld\n",
> +				PTR_ERR(tzd));
> +			goto err;
> +		}
> +	} else {
> +		indio_dev->num_channels =
> +			ARRAY_SIZE(sun4i_gpadc_channels_no_temp);
> +		indio_dev->channels = sun4i_gpadc_channels_no_temp;
> +	}
> +
> +	pm_runtime_set_autosuspend_delay(&pdev->dev,
> +					 SUN4I_GPADC_AUTOSUSPEND_DELAY);
> +	pm_runtime_use_autosuspend(&pdev->dev);
> +	pm_runtime_set_suspended(&pdev->dev);
> +	pm_runtime_enable(&pdev->dev);
> +
> +	if (IS_ENABLED(CONFIG_THERMAL_OF)) {
> +		ret = sun4i_irq_init(pdev, "TEMP_DATA_PENDING",
> +				     sun4i_gpadc_temp_data_irq_handler,
> +				     "temp_data", &info->temp_data_irq,
> +				     &info->ignore_temp_data_irq);
> +		if (ret < 0)
> +			goto err;
> +	}
> +
> +	ret = sun4i_irq_init(pdev, "FIFO_DATA_PENDING",
> +			     sun4i_gpadc_fifo_data_irq_handler, "fifo_data",
> +			     &info->fifo_data_irq, &info->ignore_fifo_data_irq);
> +	if (ret < 0)
> +		goto err;
> +
> +	if (IS_ENABLED(CONFIG_THERMAL_OF)) {
> +		ret = iio_map_array_register(indio_dev, sun4i_gpadc_hwmon_maps);
> +		if (ret < 0) {
> +			dev_err(&pdev->dev,
> +				"failed to register iio map array\n");
> +			goto err;
> +		}
> +	}
> +
> +	ret = devm_iio_device_register(&pdev->dev, indio_dev);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "could not register the device\n");
> +		goto err_map;
> +	}
> +
> +	return 0;
> +
> +err_map:
> +	if (IS_ENABLED(CONFIG_THERMAL_OF))
> +		iio_map_array_unregister(indio_dev);
> +
> +err:
> +	pm_runtime_put(&pdev->dev);
> +	pm_runtime_disable(&pdev->dev);
> +
> +	return ret;
> +}
> +
> +static int sun4i_gpadc_remove(struct platform_device *pdev)
> +{
> +	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
> +
> +	pm_runtime_put(&pdev->dev);
> +	pm_runtime_disable(&pdev->dev);
> +	if (IS_ENABLED(CONFIG_THERMAL_OF))
> +		iio_map_array_unregister(indio_dev);
> +
> +	return 0;
> +}
> +
> +static const struct platform_device_id sun4i_gpadc_id[] = {
> +	{ "sun4i-a10-gpadc-iio", (kernel_ulong_t)&sun4i_gpadc_data },
> +	{ "sun5i-a13-gpadc-iio", (kernel_ulong_t)&sun5i_gpadc_data },
> +	{ "sun6i-a31-gpadc-iio", (kernel_ulong_t)&sun6i_gpadc_data },
> +	{ /* sentinel */ },
> +};
> +
> +static struct platform_driver sun4i_gpadc_driver = {
> +	.driver = {
> +		.name = "sun4i-gpadc-iio",
> +		.pm = &sun4i_gpadc_pm_ops,
> +	},
> +	.id_table = sun4i_gpadc_id,
> +	.probe = sun4i_gpadc_probe,
> +	.remove = sun4i_gpadc_remove,
> +};
> +
> +module_platform_driver(sun4i_gpadc_driver);
> +
> +MODULE_DESCRIPTION("ADC driver for sunxi platforms");
> +MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");
> +MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/mfd/sun4i-gpadc.h b/include/linux/mfd/sun4i-gpadc.h
> index d7a29f2..509e736 100644
> --- a/include/linux/mfd/sun4i-gpadc.h
> +++ b/include/linux/mfd/sun4i-gpadc.h
> @@ -28,6 +28,7 @@
>  #define SUN4I_GPADC_CTRL1_TP_MODE_EN			BIT(4)
>  #define SUN4I_GPADC_CTRL1_TP_ADC_SELECT			BIT(3)
>  #define SUN4I_GPADC_CTRL1_ADC_CHAN_SELECT(x)		(GENMASK(2, 0) & (x))
> +#define SUN4I_GPADC_CTRL1_ADC_CHAN_MASK			GENMASK(2, 0)
>  
>  /* TP_CTRL1 bits for sun6i SOCs */
>  #define SUN6I_GPADC_CTRL1_TOUCH_PAN_CALI_EN		BIT(7)
> @@ -35,6 +36,7 @@
>  #define SUN6I_GPADC_CTRL1_TP_MODE_EN			BIT(5)
>  #define SUN6I_GPADC_CTRL1_TP_ADC_SELECT			BIT(4)
>  #define SUN6I_GPADC_CTRL1_ADC_CHAN_SELECT(x)		(GENMASK(3, 0) & BIT(x))
> +#define SUN6I_GPADC_CTRL1_ADC_CHAN_MASK			GENMASK(3, 0)
>  
>  #define SUN4I_GPADC_CTRL2				0x08
>  

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* [PATCH v8 0/3] ARM, arm64: renesas: Enable UHS-I SDR-104
From: Simon Horman @ 2016-11-03 15:07 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

this series enables SDHI UHS-I SDR-104 on:
* r8a7790/lager
* r8a7791/koelsch
* r8a7794/alt

It is based on renesas-next-20161102-v4.9-rc1.

For functional SDR-104 support the following dependencies are needed:
* [PATCH v8 0/6] UHS-I SDR-104 support for sh_mobile_sdhi

To aid review the following git branches are provided:
* This patchset:
  https:://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git topic/sdr104-integration-v8
* This patch-set and above dependency
  https:://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git topic/sdr104-v8

Changes since v7:
* Dropped merged matches
* Dropped r8a779[56]/salvator-x patches for now as it seems further work is
  required in order to reliably enable SDR104 on those SoCs.

Simon Horman (3):
  ARM: dts: lager: Enable UHS-I SDR-104
  ARM: dts: koelsch: Enable UHS-I SDR-104
  ARM: dts: alt: Enable UHS-I SDR-104

 arch/arm/boot/dts/r8a7790-lager.dts   | 1 +
 arch/arm/boot/dts/r8a7791-koelsch.dts | 1 +
 arch/arm/boot/dts/r8a7794-alt.dts     | 1 +
 3 files changed, 3 insertions(+)

-- 
2.7.0.rc3.207.g0ac5344

^ permalink raw reply

* [PATCH v8 1/3] ARM: dts: lager: Enable UHS-I SDR-104
From: Simon Horman @ 2016-11-03 15:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478185645-25556-1-git-send-email-horms+renesas@verge.net.au>

Add the sd-uhs-sdr104 property to SDHI0.

Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
 arch/arm/boot/dts/r8a7790-lager.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/r8a7790-lager.dts b/arch/arm/boot/dts/r8a7790-lager.dts
index 434268262d88..e42748a5fe10 100644
--- a/arch/arm/boot/dts/r8a7790-lager.dts
+++ b/arch/arm/boot/dts/r8a7790-lager.dts
@@ -575,6 +575,7 @@
 	vqmmc-supply = <&vccq_sdhi0>;
 	cd-gpios = <&gpio3 6 GPIO_ACTIVE_LOW>;
 	sd-uhs-sdr50;
+	sd-uhs-sdr104;
 	status = "okay";
 };
 
-- 
2.7.0.rc3.207.g0ac5344

^ permalink raw reply related

* [PATCH v8 2/3] ARM: dts: koelsch: Enable UHS-I SDR-104
From: Simon Horman @ 2016-11-03 15:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478185645-25556-1-git-send-email-horms+renesas@verge.net.au>

And the sd-uhs-sdr104 property to SDHI0.

Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
 arch/arm/boot/dts/r8a7791-koelsch.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts
index c457b43deb7d..57e69af65136 100644
--- a/arch/arm/boot/dts/r8a7791-koelsch.dts
+++ b/arch/arm/boot/dts/r8a7791-koelsch.dts
@@ -499,6 +499,7 @@
 	cd-gpios = <&gpio6 6 GPIO_ACTIVE_LOW>;
 	wp-gpios = <&gpio6 7 GPIO_ACTIVE_HIGH>;
 	sd-uhs-sdr50;
+	sd-uhs-sdr104;
 	status = "okay";
 };
 
-- 
2.7.0.rc3.207.g0ac5344

^ permalink raw reply related

* [PATCH v8 3/3] ARM: dts: alt: Enable UHS-I SDR-104
From: Simon Horman @ 2016-11-03 15:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478185645-25556-1-git-send-email-horms+renesas@verge.net.au>

And the sd-uhs-sdr104 property to SDHI0.

Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
 arch/arm/boot/dts/r8a7794-alt.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/r8a7794-alt.dts b/arch/arm/boot/dts/r8a7794-alt.dts
index 325d3f972c57..ccb80d66076f 100644
--- a/arch/arm/boot/dts/r8a7794-alt.dts
+++ b/arch/arm/boot/dts/r8a7794-alt.dts
@@ -277,6 +277,7 @@
 	cd-gpios = <&gpio6 6 GPIO_ACTIVE_LOW>;
 	wp-gpios = <&gpio6 7 GPIO_ACTIVE_LOW>;
 	sd-uhs-sdr50;
+	sd-uhs-sdr104;
 	status = "okay";
 };
 
-- 
2.7.0.rc3.207.g0ac5344

^ permalink raw reply related

* [PATCH v2] of, numa: Return NUMA_NO_NODE from disable of_node_to_nid() if nid not possible.
From: David Daney @ 2016-11-03 15:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAL_JsqKnXk99SUa1cjC2QFA9rizjn4=JHZh3ua_gvcOtpGx8jg@mail.gmail.com>

On 11/02/2016 08:37 PM, Rob Herring wrote:
> On Fri, Oct 28, 2016 at 4:15 PM, David Daney <ddaney.cavm@gmail.com> wrote:
>> From: David Daney <david.daney@cavium.com>
>>
>> On arm64 NUMA kernels we can pass "numa=off" on the command line to
>> disable NUMA.  A side effect of this is that kmalloc_node() calls to
>> non-zero nodes will crash the system with an OOPS:
>>
>> [    0.000000] ITS at 0x0000901000020000: allocated 2097152 Devices @10002000000 (flat, esz 8, psz 64K, shr 1)
>> [    0.000000] Unable to handle kernel NULL pointer dereference at virtual address 00001680
>> [    0.000000] pgd = fffffc0009470000
>> [    0.000000] [00001680] *pgd=0000010ffff90003, *pud=0000010ffff90003, *pmd=0000010ffff90003, *pte=0000000000000000
>> [    0.000000] Internal error: Oops: 96000006 [#1] SMP
>> .
>> .
>> .
>> [    0.000000] [<fffffc00081c8950>] __alloc_pages_nodemask+0xa4/0xe68
>> [    0.000000] [<fffffc000821fa70>] new_slab+0xd0/0x564
>> [    0.000000] [<fffffc0008221e24>] ___slab_alloc+0x2e4/0x514
>> [    0.000000] [<fffffc0008239498>] __slab_alloc+0x48/0x58
>> [    0.000000] [<fffffc0008222c20>] __kmalloc_node+0xd0/0x2dc
>> [    0.000000] [<fffffc0008115374>] __irq_domain_add+0x7c/0x164
>> [    0.000000] [<fffffc0008b461dc>] its_probe+0x784/0x81c
>> [    0.000000] [<fffffc0008b462bc>] its_init+0x48/0x1b0
>> [    0.000000] [<fffffc0008b4543c>] gic_init_bases+0x228/0x360
>> [    0.000000] [<fffffc0008b456bc>] gic_of_init+0x148/0x1cc
>> [    0.000000] [<fffffc0008b5aec8>] of_irq_init+0x184/0x298
>> [    0.000000] [<fffffc0008b43f9c>] irqchip_init+0x14/0x38
>> [    0.000000] [<fffffc0008b12d60>] init_IRQ+0xc/0x30
>> [    0.000000] [<fffffc0008b10a3c>] start_kernel+0x240/0x3b8
>> [    0.000000] [<fffffc0008b101c4>] __primary_switched+0x30/0x6c
>> [    0.000000] Code: 912ec2a0 b9403809 0a0902fb 37b007db (f9400300)
>> .
>> .
>> .
>>
>> This is caused by code like this in kernel/irq/irqdomain.c
>>
>>     domain = kzalloc_node(sizeof(*domain) + (sizeof(unsigned int) * size),
>>                   GFP_KERNEL, of_node_to_nid(of_node));
>>
>> When NUMA is disabled, the concept of a node is really undefined, so
>> of_node_to_nid() should unconditionally return NUMA_NO_NODE.
>>
>> Fix by returning NUMA_NO_NODE when the nid is not in the set of
>> possible nodes.
>>
>> Reported-by: Gilbert Netzer <noname@pdc.kth.se>
>> Signed-off-by: David Daney <david.daney@cavium.com>
>
> Does this need to go in 4.9?

That would be my preference.

> stable? If so, since what kernel version?
>

v4.7 and later would be nice.

I guess if you merge it, you could add the Cc: stable@ tag


Thanks for looking at this,
David Daney

^ permalink raw reply

* [RFC PATCH 0/3] ARM64: meson-gxbb: Add support for system suspend
From: Mark Rutland @ 2016-11-03 15:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478183365-23708-1-git-send-email-narmstrong@baylibre.com>

On Thu, Nov 03, 2016 at 03:29:22PM +0100, Neil Armstrong wrote:
> Thie patchset is a very experiment patchset to support the System Suspend
> feature of the Amlogic Meson GX SoCs.
> 
> These SoCs implements system suspend using a non-standard PSCI CPU_SUSPEND
> parameter to enter system suspend.

This sounds like a violation of the CPU_SUSPEND semantics.

> A small driver is added to properly fill the platform_suspend_ops and make
> to correct SMC call.

Ignoring the fact that this is a blatant violation of the PSCI CPU_SUSPEND
semantics, this certainly should not be a separate driver.

> In order to wake up from an alarm, these SoCs have a special memory mapped
> register where an alarm time delay in seconds is stored.
> In order to reuse the RTC wakealarm feature, implement a fake RTC device
> that uses the system time to calculate a delay to write to the register.
> 
> Note that this RFC is here to seek a better way to handle these platform
> specific features.
> 
> Neil Armstrong (3):
>   ARM64: meson: Add Amlogic Meson GX PM Suspend
>   rtc: Add Amlogic Virtual Wake RTC
>   ARM64: dts: meson-gxbb: Add support for PM and Virtual RTC
> 
>  arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi |   9 ++
>  drivers/firmware/meson/Kconfig              |   6 +
>  drivers/firmware/meson/Makefile             |   1 +
>  drivers/firmware/meson/meson_gx_pm.c        |  86 +++++++++++++++
>  drivers/rtc/Kconfig                         |  10 ++
>  drivers/rtc/Makefile                        |   1 +
>  drivers/rtc/rtc-meson-vrtc.c                | 164 ++++++++++++++++++++++++++++
>  7 files changed, 277 insertions(+)
>  create mode 100644 drivers/firmware/meson/meson_gx_pm.c
>  create mode 100644 drivers/rtc/rtc-meson-vrtc.c
> 
> -- 
> 1.9.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [RFC PATCH 1/3] ARM64: meson: Add Amlogic Meson GX PM Suspend
From: Mark Rutland @ 2016-11-03 15:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478183365-23708-2-git-send-email-narmstrong@baylibre.com>

On Thu, Nov 03, 2016 at 03:29:23PM +0100, Neil Armstrong wrote:
> The Amlogic Meson GX SoCs uses a non-standard argument to the
> PSCI CPU_SUSPEND call to enter system suspend.
> 
> Implement such call within platform_suspend_ops.

While I am very much not happy with platform-specific extensions to PSCI, if
this needs to go anywhere, it should live in the existing PSCI driver.

That is to say, NAK to other driver invoking PSCI functions.

Thanks,
Mark.

> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---
>  drivers/firmware/meson/Kconfig       |  6 +++
>  drivers/firmware/meson/Makefile      |  1 +
>  drivers/firmware/meson/meson_gx_pm.c | 86 ++++++++++++++++++++++++++++++++++++
>  3 files changed, 93 insertions(+)
>  create mode 100644 drivers/firmware/meson/meson_gx_pm.c
> 
> diff --git a/drivers/firmware/meson/Kconfig b/drivers/firmware/meson/Kconfig
> index 170d7e8..5b3fea3 100644
> --- a/drivers/firmware/meson/Kconfig
> +++ b/drivers/firmware/meson/Kconfig
> @@ -7,3 +7,9 @@ config MESON_SM
>  	depends on ARM64_4K_PAGES
>  	help
>  	  Say y here to enable the Amlogic secure monitor driver
> +
> +config MESON_GX_PM
> +	bool
> +	default ARCH_MESON if ARM64
> +	help
> +	  Say y here to enable the Amlogic GX SoC Power Management
> diff --git a/drivers/firmware/meson/Makefile b/drivers/firmware/meson/Makefile
> index 9ab3884..b6e285d 100644
> --- a/drivers/firmware/meson/Makefile
> +++ b/drivers/firmware/meson/Makefile
> @@ -1 +1,2 @@
>  obj-$(CONFIG_MESON_SM) +=	meson_sm.o
> +obj-$(CONFIG_MESON_GX_PM) +=	meson_gx_pm.o
> diff --git a/drivers/firmware/meson/meson_gx_pm.c b/drivers/firmware/meson/meson_gx_pm.c
> new file mode 100644
> index 0000000..c104c2e
> --- /dev/null
> +++ b/drivers/firmware/meson/meson_gx_pm.c
> @@ -0,0 +1,86 @@
> +/*
> + * Amlogic Meson GX Power Management
> + *
> + * Copyright (c) 2016 Baylibre, SAS.
> + * Author: Neil Armstrong <narmstrong@baylibre.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of version 2 of the GNU General Public License as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> + * more details.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/suspend.h>
> +#include <linux/arm-smccc.h>
> +
> +#include <uapi/linux/psci.h>
> +
> +#include <asm/suspend.h>
> +
> +/*
> + * The Amlogic GX SoCs uses a special argument value to the
> + * PSCI CPU_SUSPEND method to enter SUSPEND_MEM.
> + */
> +
> +#define MESON_SUSPEND_PARAM	0x0010000
> +#define PSCI_FN_NATIVE(version, name)	PSCI_##version##_FN64_##name
> +
> +static int meson_gx_suspend_finish(unsigned long arg)
> +{
> +	struct arm_smccc_res res;
> +
> +	arm_smccc_smc(PSCI_FN_NATIVE(0_2, CPU_SUSPEND), arg,
> +		      virt_to_phys(cpu_resume), 0, 0, 0, 0, 0, &res);
> +
> +	return res.a0;
> +}
> +
> +static int meson_gx_suspend_enter(suspend_state_t state)
> +{
> +	switch (state) {
> +	case PM_SUSPEND_MEM:
> +		return cpu_suspend(MESON_SUSPEND_PARAM,
> +				   meson_gx_suspend_finish);
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static const struct platform_suspend_ops meson_gx_pm_ops = {
> +		.enter = meson_gx_suspend_enter,
> +		.valid = suspend_valid_only_mem,
> +};
> +
> +static const struct of_device_id meson_gx_pm_match[] = {
> +	{ .compatible = "amlogic,meson-gx-pm", },
> +	{ /* sentinel */ },
> +};
> +MODULE_DEVICE_TABLE(of, meson_gx_pm_match);
> +
> +static int meson_gx_pm_probe(struct platform_device *pdev)
> +{
> +	suspend_set_ops(&meson_gx_pm_ops);
> +
> +	return 0;
> +}
> +
> +static struct platform_driver meson_gx_pm_driver = {
> +	.probe = meson_gx_pm_probe,
> +	.driver = {
> +		.name = "meson-gx-pm",
> +		.of_match_table = meson_gx_pm_match,
> +	},
> +};
> +
> +module_platform_driver(meson_gx_pm_driver);
> +
> +MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
> +MODULE_DESCRIPTION("Amlogic Meson GX PM driver");
> +MODULE_LICENSE("GPL v2");
> -- 
> 1.9.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v7 3/3] iio: adc: add support for Allwinner SoCs ADC
From: Julia Lawall @ 2016-11-03 15:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <201611032049.auU2FIXo%fengguang.wu@intel.com>

I haven't checked the complete context, but it seems that *irq that is
tested on line 431 is unsigned.

julia

On Thu, 3 Nov 2016, kbuild test robot wrote:

> Hi Quentin,
>
> [auto build test WARNING on next-20161028]
> [cannot apply to iio/togreg input/next linus/master v4.9-rc3 v4.9-rc2 v4.9-rc1 v4.9-rc3]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>
> url:    https://github.com/0day-ci/linux/commits/Quentin-Schulz/add-support-for-Allwinner-SoCs-ADC/20161103-182828
> :::::: branch date: 2 hours ago
> :::::: commit date: 2 hours ago
>
> >> drivers/iio/adc/sun4i-gpadc-iio.c:431:5-9: WARNING: Unsigned expression compared with zero: * irq < 0
>
> git remote add linux-review https://github.com/0day-ci/linux
> git remote update linux-review
> git checkout 0068e4d1386fff54958ef3b8b304239982feaa8a
> vim +431 drivers/iio/adc/sun4i-gpadc-iio.c
>
> 0068e4d1 Quentin Schulz 2016-11-03  415
> 0068e4d1 Quentin Schulz 2016-11-03  416  	/*
> 0068e4d1 Quentin Schulz 2016-11-03  417  	 * Once the interrupt is activated, the IP continuously performs
> 0068e4d1 Quentin Schulz 2016-11-03  418  	 * conversions thus throws interrupts. The interrupt is activated right
> 0068e4d1 Quentin Schulz 2016-11-03  419  	 * after being requested but we want to control when these interrupts
> 0068e4d1 Quentin Schulz 2016-11-03  420  	 * occur thus we disable it right after being requested. However, an
> 0068e4d1 Quentin Schulz 2016-11-03  421  	 * interrupt might occur between these two instructions and we have to
> 0068e4d1 Quentin Schulz 2016-11-03  422  	 * make sure that does not happen, by using atomic flags. We set the
> 0068e4d1 Quentin Schulz 2016-11-03  423  	 * flag before requesting the interrupt and unset it right after
> 0068e4d1 Quentin Schulz 2016-11-03  424  	 * disabling the interrupt. When an interrupt occurs between these two
> 0068e4d1 Quentin Schulz 2016-11-03  425  	 * instructions, reading the atomic flag will tell us to ignore the
> 0068e4d1 Quentin Schulz 2016-11-03  426  	 * interrupt.
> 0068e4d1 Quentin Schulz 2016-11-03  427  	 */
> 0068e4d1 Quentin Schulz 2016-11-03  428  	atomic_set(atomic, 1);
> 0068e4d1 Quentin Schulz 2016-11-03  429
> 0068e4d1 Quentin Schulz 2016-11-03  430  	*irq = platform_get_irq_byname(pdev, name);
> 0068e4d1 Quentin Schulz 2016-11-03 @431  	if (*irq < 0) {
> 0068e4d1 Quentin Schulz 2016-11-03  432  		dev_err(&pdev->dev, "no %s interrupt registered\n", name);
> 0068e4d1 Quentin Schulz 2016-11-03  433  		return *irq;
> 0068e4d1 Quentin Schulz 2016-11-03  434  	}
> 0068e4d1 Quentin Schulz 2016-11-03  435
> 0068e4d1 Quentin Schulz 2016-11-03  436  	*irq = regmap_irq_get_virq(mfd_dev->regmap_irqc, *irq);
> 0068e4d1 Quentin Schulz 2016-11-03  437  	ret = devm_request_any_context_irq(&pdev->dev, *irq, handler, 0,
> 0068e4d1 Quentin Schulz 2016-11-03  438  					   devname, info);
> 0068e4d1 Quentin Schulz 2016-11-03  439  	if (ret < 0) {
>
> ---
> 0-DAY kernel test infrastructure                Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
>

^ permalink raw reply

* [PATCH] ASoC: sun4i-i2s: Implement capture support
From: Mark Brown @ 2016-11-03 15:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161103102048.17125-1-maxime.ripard@free-electrons.com>

On Thu, Nov 03, 2016 at 11:20:48AM +0100, Maxime Ripard wrote:
> The i2s driver was only implementing playback for now. Implement capture to
> make sure that's not a limitation anymore.

This doesn't apply against current code, please check and resend.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 455 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161103/c93129f6/attachment.sig>

^ permalink raw reply

* [GIT PULL] iommu/arm-smmu: Fixes for 4.9
From: Joerg Roedel @ 2016-11-03 15:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161028160148.GD1076@arm.com>

On Fri, Oct 28, 2016 at 05:01:48PM +0100, Will Deacon wrote:
>       iommu/arm-smmu: Don't inadvertently reject multiple SMMUv3s

Hmm, this patch is pretty ugly. Wouldn't it be better to have
hardware-independent init-routine in the arm-smmu-v3 driver that checks
DT whether there is an SMMU at all and if yes, sets the per-bus
iommu-ops?



	Joerg

^ permalink raw reply

* [RFC PATCH 2/3] rtc: Add Amlogic Virtual Wake RTC
From: Mark Rutland @ 2016-11-03 15:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478183365-23708-3-git-send-email-narmstrong@baylibre.com>

On Thu, Nov 03, 2016 at 03:29:24PM +0100, Neil Armstrong wrote:
> The Amlogic Meson GX SoCs uses a special register to store the
> time in seconds to wakeup after a system suspend.

Where does this register live, exactly? What IP block is it part of?

> In order to be able to reuse the RTC wakealarm feature, this
> driver implements a fake RTC device which uses the system time
> to deduce a suspend delay.

This sounds like an always-on oneshot timer device, not an RTC.

> +static int meson_vrtc_read_time(struct device *dev, struct rtc_time *tm)
> +{
> +	unsigned long local_time;
> +	struct timeval time;
> +
> +	do_gettimeofday(&time);
> +	local_time = time.tv_sec - (sys_tz.tz_minuteswest * 60);
> +	rtc_time_to_tm(local_time, tm);
> +
> +	return 0;
> +}

... if this were a timer, you wouldn't need this hack.

> +static int meson_vrtc_probe(struct platform_device *pdev)
> +{
> +	struct meson_vrtc_data *vrtc;
> +	struct resource *res;
> +
> +	vrtc = devm_kzalloc(&pdev->dev, sizeof(*vrtc), GFP_KERNEL);
> +	if (!vrtc)
> +		return -ENOMEM;
> +
> +	vrtc->pdev = pdev;
> +
> +	/* Alarm registers */
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	vrtc->io_alarm = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(vrtc->io_alarm))
> +		return PTR_ERR(vrtc->io_alarm);
> +
> +	device_init_wakeup(&pdev->dev, 1);
> +
> +	platform_set_drvdata(pdev, vrtc);
> +
> +	vrtc->rtc = devm_rtc_device_register(&pdev->dev, "meson-vrtc",
> +			&meson_vrtc_ops, THIS_MODULE);
> +	if (IS_ERR(vrtc->rtc))
> +		return PTR_ERR(vrtc->rtc);
> +
> +	return 0;
> +}

I see that no interrupt is described. How exactly does this wake the system
from suspend? Is there some interrupt managed by FW for this, for example?

> +static const struct of_device_id meson_vrtc_dt_match[] = {
> +	{ .compatible = "amlogic,meson-vrtc"},

There was no binding documentation in this patch series.

Thanks,
Mark.

^ permalink raw reply

* [PATCH 1/1] KVM: ARM64: Fix the issues when PMCCFILTR is configured
From: Marc Zyngier @ 2016-11-03 15:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <c083c21c-1395-6674-8c66-3fe7d0aa4917@redhat.com>

On Thu, Nov 03 2016 at 02:29:26 PM, Wei Huang <wei@redhat.com> wrote:
> On 11/02/2016 11:11 PM, cov at codeaurora.org wrote:
>> Hi Wei,
>> 
>> On 2016-11-02 14:55, Wei Huang wrote:
>>> KVM calls kvm_pmu_set_counter_event_type() when PMCCFILTR is configured.
>>> But this function can't deals with PMCCFILTR correctly because the
>>> evtCount
>>> bit of PMCCFILTR, which is reserved 0, conflits with the SW_INCR event
>>> type of other PMXEVTYPER<n> registers. To fix it, when eventsel == 0, KVM
>>> shouldn't return immediately, but instead it needs to check further if
>>> select_idx is ARMV8_PMU_CYCLE_IDX.
>>>
>>> Another issue is that KVM shouldn't copy the eventsel bits of PMCCFILTER
>>> directly to attr.config. Istead it shoudl convert the request to
>>> perf_event of type 0x11 (i.e. the "cpu cycle" event type).
>>>
>>> Signed-off-by: Wei Huang <wei@redhat.com>
>>> ---
>>>  virt/kvm/arm/pmu.c | 5 +++--
>>>  1 file changed, 3 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/virt/kvm/arm/pmu.c b/virt/kvm/arm/pmu.c
>>> index 6e9c40e..13cc812 100644
>>> --- a/virt/kvm/arm/pmu.c
>>> +++ b/virt/kvm/arm/pmu.c
>>> @@ -379,7 +379,8 @@ void kvm_pmu_set_counter_event_type(struct
>>> kvm_vcpu *vcpu, u64 data,
>>>      eventsel = data & ARMV8_PMU_EVTYPE_EVENT;
>>>
>>>      /* Software increment event does't need to be backed by a perf
>>> event */
>>> -    if (eventsel == ARMV8_PMU_EVTYPE_EVENT_SW_INCR)
>>> +    if (eventsel == ARMV8_PMU_EVTYPE_EVENT_SW_INCR &&
>>> +        select_idx != ARMV8_PMU_CYCLE_IDX)
>>>          return;
>>>
>>>      memset(&attr, 0, sizeof(struct perf_event_attr));
>>> @@ -391,7 +392,7 @@ void kvm_pmu_set_counter_event_type(struct
>>> kvm_vcpu *vcpu, u64 data,
>>>      attr.exclude_kernel = data & ARMV8_PMU_EXCLUDE_EL1 ? 1 : 0;
>>>      attr.exclude_hv = 1; /* Don't count EL2 events */
>>>      attr.exclude_host = 1; /* Don't count host events */
>>> -    attr.config = eventsel;
>>> +    attr.config = (select_idx == ARMV8_PMU_CYCLE_IDX) ? 0x011 :
>>> eventsel;
>> 
>> Nit: Is there some way you could use ARMV8_PMUV3_PERFCTR_CPU_CYCLES
>> currently
>> defined in arch/arm64/kernel/perf_event.c?
>
> The event definitions in perf_event.c are local to this file. To use
> them, I have to re-factor them out to a header file, which is bigger
> than this patch intended. How about adding the following line to
> arch/arm64/include/asm/perf_event.h (i.e. the same file of
> ARMV8_PMU_EVTYPE_EVENT_SW_INCR)?
>
> #define ARMV8_PMU_EVTYPE_EVENT_CPU_CYCLES  0x11

Patch size is not relevant, and I'd rather avoid both magic numbers and
duplicate definitions. It would make sense to me to move all the
required events to this header file, and fix the SW_INCR duplication.

Please CC the ARM perf maintainers when you repost this patch.

Thanks,

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

^ permalink raw reply

* Applied "spi: sun6i: Support Allwinner H3 SPI controller" to the spi tree
From: Mark Brown @ 2016-11-03 15:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161028065412.23008-5-woogyom.kim@gmail.com>

The patch

   spi: sun6i: Support Allwinner H3 SPI controller

has been applied to the spi tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 10565dfd35488c45826201b4ce28597d6b5de3dd Mon Sep 17 00:00:00 2001
From: Milo Kim <woogyom.kim@gmail.com>
Date: Fri, 28 Oct 2016 15:54:12 +0900
Subject: [PATCH] spi: sun6i: Support Allwinner H3 SPI controller

H3 has two SPI controllers. The size of the buffer is 64 * 8.
(8 bit transfer by 64 entry FIFO)
A31 has four controllers. The size of the buffer is 128 * 8.
(8 bit transfer by 128 entry FIFO)

Register maps are sharable, so sun6i SPI driver is reusable with
device configuration.

Use the variable, 'fifo_depth' instead of fixed value to support both SPI
controllers.

Signed-off-by: Milo Kim <woogyom.kim@gmail.com>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 drivers/spi/spi-sun6i.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c
index 9918a57a6a6e..e3114832c485 100644
--- a/drivers/spi/spi-sun6i.c
+++ b/drivers/spi/spi-sun6i.c
@@ -17,6 +17,7 @@
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/module.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/reset.h>
@@ -24,6 +25,7 @@
 #include <linux/spi/spi.h>
 
 #define SUN6I_FIFO_DEPTH		128
+#define SUN8I_FIFO_DEPTH		64
 
 #define SUN6I_GBL_CTL_REG		0x04
 #define SUN6I_GBL_CTL_BUS_ENABLE		BIT(0)
@@ -90,6 +92,7 @@ struct sun6i_spi {
 	const u8		*tx_buf;
 	u8			*rx_buf;
 	int			len;
+	unsigned long		fifo_depth;
 };
 
 static inline u32 sun6i_spi_read(struct sun6i_spi *sspi, u32 reg)
@@ -155,7 +158,9 @@ static void sun6i_spi_set_cs(struct spi_device *spi, bool enable)
 
 static size_t sun6i_spi_max_transfer_size(struct spi_device *spi)
 {
-	return SUN6I_FIFO_DEPTH - 1;
+	struct sun6i_spi *sspi = spi_master_get_devdata(spi->master);
+
+	return sspi->fifo_depth - 1;
 }
 
 static int sun6i_spi_transfer_one(struct spi_master *master,
@@ -170,7 +175,7 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
 	u32 reg;
 
 	/* We don't support transfer larger than the FIFO */
-	if (tfr->len > SUN6I_FIFO_DEPTH)
+	if (tfr->len > sspi->fifo_depth)
 		return -EINVAL;
 
 	reinit_completion(&sspi->done);
@@ -265,7 +270,7 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
 			SUN6I_BURST_CTL_CNT_STC(tx_len));
 
 	/* Fill the TX FIFO */
-	sun6i_spi_fill_fifo(sspi, SUN6I_FIFO_DEPTH);
+	sun6i_spi_fill_fifo(sspi, sspi->fifo_depth);
 
 	/* Enable the interrupts */
 	sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, SUN6I_INT_CTL_TC);
@@ -288,7 +293,7 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
 		goto out;
 	}
 
-	sun6i_spi_drain_fifo(sspi, SUN6I_FIFO_DEPTH);
+	sun6i_spi_drain_fifo(sspi, sspi->fifo_depth);
 
 out:
 	sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, 0);
@@ -398,6 +403,8 @@ static int sun6i_spi_probe(struct platform_device *pdev)
 	}
 
 	sspi->master = master;
+	sspi->fifo_depth = (unsigned long)of_device_get_match_data(&pdev->dev);
+
 	master->max_speed_hz = 100 * 1000 * 1000;
 	master->min_speed_hz = 3 * 1000;
 	master->set_cs = sun6i_spi_set_cs;
@@ -470,7 +477,8 @@ static int sun6i_spi_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id sun6i_spi_match[] = {
-	{ .compatible = "allwinner,sun6i-a31-spi", },
+	{ .compatible = "allwinner,sun6i-a31-spi", .data = (void *)SUN6I_FIFO_DEPTH },
+	{ .compatible = "allwinner,sun8i-h3-spi",  .data = (void *)SUN8I_FIFO_DEPTH },
 	{}
 };
 MODULE_DEVICE_TABLE(of, sun6i_spi_match);
-- 
2.10.1

^ permalink raw reply related

* [RFC PATCH 0/3] ARM64: meson-gxbb: Add support for system suspend
From: Mark Rutland @ 2016-11-03 15:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161103152545.GB25852@remoulade>

Urrgh, I accidentally sent this when trying to save this to my drafts folder;
sorry for the half-finished reply.

On Thu, Nov 03, 2016 at 03:25:46PM +0000, Mark Rutland wrote:
> On Thu, Nov 03, 2016 at 03:29:22PM +0100, Neil Armstrong wrote:
> > Thie patchset is a very experiment patchset to support the System Suspend
> > feature of the Amlogic Meson GX SoCs.
> > 
> > These SoCs implements system suspend using a non-standard PSCI CPU_SUSPEND
> > parameter to enter system suspend.

> > Note that this RFC is here to seek a better way to handle these platform
> > specific features.

One of the reasons that we want PSCI is that it is a standard interface across
platforms. Generally, we do not want platform-specific interfaces.

In this case, PSCI 1.0+ has SYSTEM_SUSPEND for this purpose.

If PSCI is lacking functionality that vendors want, they should speak to ARM
w.r.t. the PSCI specification -- it can be extended with new functionality as
has already happened with PSCI 0.2 and PSCI 1.0.

Thanks,
Mark.

^ permalink raw reply

* [RFC PATCH 2/3] rtc: Add Amlogic Virtual Wake RTC
From: Neil Armstrong @ 2016-11-03 15:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161103153647.GD25852@remoulade>

On 11/03/2016 04:36 PM, Mark Rutland wrote:
> On Thu, Nov 03, 2016 at 03:29:24PM +0100, Neil Armstrong wrote:
>> The Amlogic Meson GX SoCs uses a special register to store the
>> time in seconds to wakeup after a system suspend.
> 
> Where does this register live, exactly? What IP block is it part of?

It's part of the Always-ON APB registers, there is no clear IP block here,
but it seems to be like a scratch register shared with the BL3 FW.

> 
>> In order to be able to reuse the RTC wakealarm feature, this
>> driver implements a fake RTC device which uses the system time
>> to deduce a suspend delay.
> 
> This sounds like an always-on oneshot timer device, not an RTC.

The register seems to never change, and it seems to be an indication for the
FW when it enters the suspend mode.

> 
>> +static int meson_vrtc_read_time(struct device *dev, struct rtc_time *tm)
>> +{
>> +	unsigned long local_time;
>> +	struct timeval time;
>> +
>> +	do_gettimeofday(&time);
>> +	local_time = time.tv_sec - (sys_tz.tz_minuteswest * 60);
>> +	rtc_time_to_tm(local_time, tm);
>> +
>> +	return 0;
>> +}
> 
> ... if this were a timer, you wouldn't need this hack.

Actually the vendor tree uses a 64bit running counter to provide this
but with a fixed start date.

> 
>> +static int meson_vrtc_probe(struct platform_device *pdev)
>> +{
>> +	struct meson_vrtc_data *vrtc;
>> +	struct resource *res;
>> +
>> +	vrtc = devm_kzalloc(&pdev->dev, sizeof(*vrtc), GFP_KERNEL);
>> +	if (!vrtc)
>> +		return -ENOMEM;
>> +
>> +	vrtc->pdev = pdev;
>> +
>> +	/* Alarm registers */
>> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> +	vrtc->io_alarm = devm_ioremap_resource(&pdev->dev, res);
>> +	if (IS_ERR(vrtc->io_alarm))
>> +		return PTR_ERR(vrtc->io_alarm);
>> +
>> +	device_init_wakeup(&pdev->dev, 1);
>> +
>> +	platform_set_drvdata(pdev, vrtc);
>> +
>> +	vrtc->rtc = devm_rtc_device_register(&pdev->dev, "meson-vrtc",
>> +			&meson_vrtc_ops, THIS_MODULE);
>> +	if (IS_ERR(vrtc->rtc))
>> +		return PTR_ERR(vrtc->rtc);
>> +
>> +	return 0;
>> +}
> 
> I see that no interrupt is described. How exactly does this wake the system
> from suspend? Is there some interrupt managed by FW for this, for example?

It seems to be managed by the BL3 FW. We have no details on the underlying implementation.

> 
>> +static const struct of_device_id meson_vrtc_dt_match[] = {
>> +	{ .compatible = "amlogic,meson-vrtc"},
> 
> There was no binding documentation in this patch series.
> 
> Thanks,
> Mark.
> 

^ 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