* [PATCH v4 0/6] Change snvs rtc and poweroff to use syscon add pwrkey driver
@ 2015-05-22 14:36 Frank.Li
2015-05-22 14:36 ` [PATCH v4 1/6] rtc: arm: imx: snvs: change use syscon to access register Frank.Li
` (6 more replies)
0 siblings, 7 replies; 14+ messages in thread
From: Frank.Li @ 2015-05-22 14:36 UTC (permalink / raw)
To: lznuaa, shawn.guo, dmitry.torokhov, robh+dt, alexandre.belloni,
linux
Cc: linux-arm-kernel, linux-input, rtc-linux, devicetree, Frank Li
From: Frank Li <Frank.Li@freescale.com>
Change from v3 to v4
- fix align
- change to pr_warn
Change from v2 to v3
- Keep snvs rtc compatiblity with old dts file
- use general syscon-poweroff instead of modifying snvs-poweroff.c
Change from v1 to v2
- Change simple-bus to simple-mfd
- RTC remove lock.
- RTC remove comments "These register offsets are relative to LP (Low Power) range"
- power off, remove extra space
Frank Li (5):
rtc: arm: imx: snvs: change use syscon to access register
Document: dt: fsl: snvs: change support syscon
arm: dts: imx: update snvs to use syscon access register
document: devicetree: input: imx: i.mx snvs power device tree bindings
arm: dts: imx6sx: enable snvs power key
Robin Gong (1):
input: keyboard: imx: add snvs power key driver
.../devicetree/bindings/crypto/fsl-sec4.txt | 70 +++++--
.../devicetree/bindings/input/snvs-pwrkey.txt | 1 +
arch/arm/boot/dts/imx6qdl.dtsi | 19 +-
arch/arm/boot/dts/imx6sl.dtsi | 19 +-
arch/arm/boot/dts/imx6sx.dtsi | 24 ++-
arch/arm/boot/dts/vfxxx.dtsi | 9 +-
drivers/input/keyboard/Kconfig | 11 +
drivers/input/keyboard/Makefile | 1 +
drivers/input/keyboard/snvs_pwrkey.c | 232 +++++++++++++++++++++
drivers/rtc/rtc-snvs.c | 136 ++++++------
10 files changed, 408 insertions(+), 114 deletions(-)
create mode 100644 Documentation/devicetree/bindings/input/snvs-pwrkey.txt
create mode 100644 drivers/input/keyboard/snvs_pwrkey.c
--
1.9.1
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v4 1/6] rtc: arm: imx: snvs: change use syscon to access register
2015-05-22 14:36 [PATCH v4 0/6] Change snvs rtc and poweroff to use syscon add pwrkey driver Frank.Li
@ 2015-05-22 14:36 ` Frank.Li
2015-05-25 6:18 ` Shawn Guo
2015-05-25 6:44 ` Shawn Guo
2015-05-22 14:36 ` [PATCH v4 2/6] Document: dt: fsl: snvs: change support syscon Frank.Li
` (5 subsequent siblings)
6 siblings, 2 replies; 14+ messages in thread
From: Frank.Li @ 2015-05-22 14:36 UTC (permalink / raw)
To: lznuaa, shawn.guo, dmitry.torokhov, robh+dt, alexandre.belloni,
linux
Cc: linux-arm-kernel, linux-input, rtc-linux, devicetree, Frank Li
From: Frank Li <Frank.Li@freescale.com>
snvs included rtc, on/off key, power-off module
change to syscon to access register
Signed-off-by: Frank Li <Frank.Li@freescale.com>
---
drivers/rtc/rtc-snvs.c | 136 +++++++++++++++++++++++++------------------------
1 file changed, 70 insertions(+), 66 deletions(-)
diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c
index 0479e80..42e55da 100644
--- a/drivers/rtc/rtc-snvs.c
+++ b/drivers/rtc/rtc-snvs.c
@@ -18,6 +18,8 @@
#include <linux/platform_device.h>
#include <linux/rtc.h>
#include <linux/clk.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
/* These register offsets are relative to LP (Low Power) range */
#define SNVS_LPCR 0x04
@@ -37,31 +39,35 @@
struct snvs_rtc_data {
struct rtc_device *rtc;
- void __iomem *ioaddr;
+ struct regmap *regmap;
+ int offset;
int irq;
- spinlock_t lock;
struct clk *clk;
};
-static u32 rtc_read_lp_counter(void __iomem *ioaddr)
+static u32 rtc_read_lp_counter(struct snvs_rtc_data *snvs)
{
u64 read1, read2;
-
+ u32 val;
do {
- read1 = readl(ioaddr + SNVS_LPSRTCMR);
+ regmap_read(snvs->regmap, snvs->offset + SNVS_LPSRTCMR, &val);
+ read1 = val;
read1 <<= 32;
- read1 |= readl(ioaddr + SNVS_LPSRTCLR);
+ regmap_read(snvs->regmap, snvs->offset + SNVS_LPSRTCLR, &val);
+ read1 |= val;
- read2 = readl(ioaddr + SNVS_LPSRTCMR);
+ regmap_read(snvs->regmap, snvs->offset + SNVS_LPSRTCMR, &val);
+ read2 = val;
read2 <<= 32;
- read2 |= readl(ioaddr + SNVS_LPSRTCLR);
+ regmap_read(snvs->regmap, snvs->offset + SNVS_LPSRTCLR, &val);
+ read2 |= val;
} while (read1 != read2);
/* Convert 47-bit counter to 32-bit raw second count */
return (u32) (read1 >> CNTR_TO_SECS_SH);
}
-static void rtc_write_sync_lp(void __iomem *ioaddr)
+static void rtc_write_sync_lp(struct snvs_rtc_data *snvs)
{
u32 count1, count2, count3;
int i;
@@ -69,15 +75,15 @@ static void rtc_write_sync_lp(void __iomem *ioaddr)
/* Wait for 3 CKIL cycles */
for (i = 0; i < 3; i++) {
do {
- count1 = readl(ioaddr + SNVS_LPSRTCLR);
- count2 = readl(ioaddr + SNVS_LPSRTCLR);
+ regmap_read(snvs->regmap, snvs->offset + SNVS_LPSRTCLR, &count1);
+ regmap_read(snvs->regmap, snvs->offset + SNVS_LPSRTCLR, &count2);
} while (count1 != count2);
/* Now wait until counter value changes */
do {
do {
- count2 = readl(ioaddr + SNVS_LPSRTCLR);
- count3 = readl(ioaddr + SNVS_LPSRTCLR);
+ regmap_read(snvs->regmap, snvs->offset + SNVS_LPSRTCLR, &count2);
+ regmap_read(snvs->regmap, snvs->offset + SNVS_LPSRTCLR, &count3);
} while (count2 != count3);
} while (count3 == count1);
}
@@ -85,23 +91,14 @@ static void rtc_write_sync_lp(void __iomem *ioaddr)
static int snvs_rtc_enable(struct snvs_rtc_data *data, bool enable)
{
- unsigned long flags;
int timeout = 1000;
u32 lpcr;
- spin_lock_irqsave(&data->lock, flags);
-
- lpcr = readl(data->ioaddr + SNVS_LPCR);
- if (enable)
- lpcr |= SNVS_LPCR_SRTC_ENV;
- else
- lpcr &= ~SNVS_LPCR_SRTC_ENV;
- writel(lpcr, data->ioaddr + SNVS_LPCR);
-
- spin_unlock_irqrestore(&data->lock, flags);
+ regmap_update_bits(data->regmap, data->offset + SNVS_LPCR, SNVS_LPCR_SRTC_ENV,
+ enable ? SNVS_LPCR_SRTC_ENV : 0);
while (--timeout) {
- lpcr = readl(data->ioaddr + SNVS_LPCR);
+ regmap_read(data->regmap, data->offset + SNVS_LPCR, &lpcr);
if (enable) {
if (lpcr & SNVS_LPCR_SRTC_ENV)
@@ -121,7 +118,7 @@ static int snvs_rtc_enable(struct snvs_rtc_data *data, bool enable)
static int snvs_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct snvs_rtc_data *data = dev_get_drvdata(dev);
- unsigned long time = rtc_read_lp_counter(data->ioaddr);
+ unsigned long time = rtc_read_lp_counter(data);
rtc_time_to_tm(time, tm);
@@ -139,8 +136,8 @@ static int snvs_rtc_set_time(struct device *dev, struct rtc_time *tm)
snvs_rtc_enable(data, false);
/* Write 32-bit time to 47-bit timer, leaving 15 LSBs blank */
- writel(time << CNTR_TO_SECS_SH, data->ioaddr + SNVS_LPSRTCLR);
- writel(time >> (32 - CNTR_TO_SECS_SH), data->ioaddr + SNVS_LPSRTCMR);
+ regmap_write(data->regmap, data->offset + SNVS_LPSRTCLR, time << CNTR_TO_SECS_SH);
+ regmap_write(data->regmap, data->offset + SNVS_LPSRTCMR, time >> (32 - CNTR_TO_SECS_SH));
/* Enable RTC again */
snvs_rtc_enable(data, true);
@@ -153,10 +150,10 @@ static int snvs_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
struct snvs_rtc_data *data = dev_get_drvdata(dev);
u32 lptar, lpsr;
- lptar = readl(data->ioaddr + SNVS_LPTAR);
+ regmap_read(data->regmap, data->offset + SNVS_LPTAR, &lptar);
rtc_time_to_tm(lptar, &alrm->time);
- lpsr = readl(data->ioaddr + SNVS_LPSR);
+ regmap_read(data->regmap, data->offset + SNVS_LPSR, &lpsr);
alrm->pending = (lpsr & SNVS_LPSR_LPTA) ? 1 : 0;
return 0;
@@ -165,21 +162,12 @@ static int snvs_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
static int snvs_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
{
struct snvs_rtc_data *data = dev_get_drvdata(dev);
- u32 lpcr;
- unsigned long flags;
-
- spin_lock_irqsave(&data->lock, flags);
-
- lpcr = readl(data->ioaddr + SNVS_LPCR);
- if (enable)
- lpcr |= (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN);
- else
- lpcr &= ~(SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN);
- writel(lpcr, data->ioaddr + SNVS_LPCR);
- spin_unlock_irqrestore(&data->lock, flags);
+ regmap_update_bits(data->regmap, data->offset + SNVS_LPCR,
+ (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN),
+ enable ? (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN) : 0);
- rtc_write_sync_lp(data->ioaddr);
+ rtc_write_sync_lp(data);
return 0;
}
@@ -189,24 +177,14 @@ static int snvs_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
struct snvs_rtc_data *data = dev_get_drvdata(dev);
struct rtc_time *alrm_tm = &alrm->time;
unsigned long time;
- unsigned long flags;
- u32 lpcr;
rtc_tm_to_time(alrm_tm, &time);
- spin_lock_irqsave(&data->lock, flags);
-
- /* Have to clear LPTA_EN before programming new alarm time in LPTAR */
- lpcr = readl(data->ioaddr + SNVS_LPCR);
- lpcr &= ~SNVS_LPCR_LPTA_EN;
- writel(lpcr, data->ioaddr + SNVS_LPCR);
-
- spin_unlock_irqrestore(&data->lock, flags);
-
- writel(time, data->ioaddr + SNVS_LPTAR);
+ regmap_update_bits(data->regmap, data->offset + SNVS_LPCR, SNVS_LPCR_LPTA_EN, 0);
+ regmap_write(data->regmap, data->offset + SNVS_LPTAR, time);
/* Clear alarm interrupt status bit */
- writel(SNVS_LPSR_LPTA, data->ioaddr + SNVS_LPSR);
+ regmap_write(data->regmap, data->offset + SNVS_LPSR, SNVS_LPSR_LPTA);
return snvs_rtc_alarm_irq_enable(dev, alrm->enabled);
}
@@ -226,7 +204,7 @@ static irqreturn_t snvs_rtc_irq_handler(int irq, void *dev_id)
u32 lpsr;
u32 events = 0;
- lpsr = readl(data->ioaddr + SNVS_LPSR);
+ regmap_read(data->regmap, data->offset + SNVS_LPSR, &lpsr);
if (lpsr & SNVS_LPSR_LPTA) {
events |= (RTC_AF | RTC_IRQF);
@@ -238,25 +216,53 @@ static irqreturn_t snvs_rtc_irq_handler(int irq, void *dev_id)
}
/* clear interrupt status */
- writel(lpsr, data->ioaddr + SNVS_LPSR);
+ regmap_write(data->regmap, data->offset + SNVS_LPSR, lpsr);
return events ? IRQ_HANDLED : IRQ_NONE;
}
+static const struct regmap_config snvs_rtc_config = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+};
+
static int snvs_rtc_probe(struct platform_device *pdev)
{
struct snvs_rtc_data *data;
struct resource *res;
int ret;
+ struct device_node *snvs_np;
+ void __iomem *mmio;
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- data->ioaddr = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(data->ioaddr))
- return PTR_ERR(data->ioaddr);
+ snvs_np = of_get_parent(pdev->dev.of_node);
+ if (!snvs_np)
+ return -ENODEV;
+
+ if (of_device_is_compatible(snvs_np, "syscon")) {
+ data->regmap = syscon_node_to_regmap(snvs_np);
+ data->offset = 0x34;
+ } else {
+ pr_warn("snvs rtc: you use old dts file, please update it\n");
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ mmio = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(mmio))
+ return PTR_ERR(mmio);
+
+ data->regmap = devm_regmap_init_mmio(&pdev->dev, mmio, &snvs_rtc_config);
+ }
+
+ of_node_put(snvs_np);
+
+ if (!data->regmap) {
+ pr_err("Can't snvs syscon\n");
+ return -ENODEV;
+ }
data->irq = platform_get_irq(pdev, 0);
if (data->irq < 0)
@@ -276,13 +282,11 @@ static int snvs_rtc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, data);
- spin_lock_init(&data->lock);
-
/* Initialize glitch detect */
- writel(SNVS_LPPGDR_INIT, data->ioaddr + SNVS_LPPGDR);
+ regmap_write(data->regmap, data->offset + SNVS_LPPGDR, SNVS_LPPGDR_INIT);
/* Clear interrupt status */
- writel(0xffffffff, data->ioaddr + SNVS_LPSR);
+ regmap_write(data->regmap, data->offset + SNVS_LPSR, 0xffffffff);
/* Enable RTC */
snvs_rtc_enable(data, true);
--
1.9.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v4 2/6] Document: dt: fsl: snvs: change support syscon
2015-05-22 14:36 [PATCH v4 0/6] Change snvs rtc and poweroff to use syscon add pwrkey driver Frank.Li
2015-05-22 14:36 ` [PATCH v4 1/6] rtc: arm: imx: snvs: change use syscon to access register Frank.Li
@ 2015-05-22 14:36 ` Frank.Li
2015-05-25 6:26 ` Shawn Guo
2015-05-22 14:36 ` [PATCH v4 3/6] arm: dts: imx: update snvs to use syscon access register Frank.Li
` (4 subsequent siblings)
6 siblings, 1 reply; 14+ messages in thread
From: Frank.Li @ 2015-05-22 14:36 UTC (permalink / raw)
To: lznuaa, shawn.guo, dmitry.torokhov, robh+dt, alexandre.belloni,
linux
Cc: linux-arm-kernel, linux-input, rtc-linux, devicetree, Frank Li
From: Frank Li <Frank.Li@freescale.com>
snvs actually is multi fucntion driver.
Change to use syscon to access register.
Signed-off-by: Frank Li <Frank.Li@freescale.com>
---
.../devicetree/bindings/crypto/fsl-sec4.txt | 28 ++++++++++++----------
1 file changed, 15 insertions(+), 13 deletions(-)
diff --git a/Documentation/devicetree/bindings/crypto/fsl-sec4.txt b/Documentation/devicetree/bindings/crypto/fsl-sec4.txt
index e402277..87f5921 100644
--- a/Documentation/devicetree/bindings/crypto/fsl-sec4.txt
+++ b/Documentation/devicetree/bindings/crypto/fsl-sec4.txt
@@ -288,12 +288,13 @@ Secure Non-Volatile Storage (SNVS) Node
Node defines address range and the associated
interrupt for the SNVS function. This function
monitors security state information & reports
- security violations.
+ security violations. This also included rtc,
+ system power off and ON/OFF key.
- compatible
Usage: required
Value type: <string>
- Definition: Must include "fsl,sec-v4.0-mon".
+ Definition: Must include "fsl,sec-v4.0-mon" and "syscon".
- reg
Usage: required
@@ -324,7 +325,7 @@ Secure Non-Volatile Storage (SNVS) Node
the child address, parent address, & length.
- interrupts
- Usage: required
+ Usage: optional
Value type: <prop_encoded-array>
Definition: Specifies the interrupts generated by this
device. The value of the interrupts property
@@ -341,7 +342,7 @@ Secure Non-Volatile Storage (SNVS) Node
EXAMPLE
sec_mon@314000 {
- compatible = "fsl,sec-v4.0-mon";
+ compatible = "fsl,sec-v4.0-mon", "syscon";
reg = <0x314000 0x1000>;
ranges = <0 0x314000 0x1000>;
interrupt-parent = <&mpic>;
@@ -358,16 +359,19 @@ Secure Non-Volatile Storage (SNVS) Low Power (LP) RTC Node
Value type: <string>
Definition: Must include "fsl,sec-v4.0-mon-rtc-lp".
- - reg
+ - interrupts
Usage: required
- Value type: <prop-encoded-array>
- Definition: A standard property. Specifies the physical
- address and length of the SNVS LP configuration registers.
+ Value type: <prop_encoded-array>
+ Definition: Specifies the interrupts generated by this
+ device. The value of the interrupts property
+ consists of one interrupt specifier. The format
+ of the specifier is defined by the binding document
+ describing the node's interrupt parent.
EXAMPLE
- sec_mon_rtc_lp@314000 {
+ sec_mon_rtc_lp@1 {
compatible = "fsl,sec-v4.0-mon-rtc-lp";
- reg = <0x34 0x58>;
+ interrupts = <93 2>;
};
=====================================================================
@@ -443,12 +447,10 @@ FULL EXAMPLE
compatible = "fsl,sec-v4.0-mon";
reg = <0x314000 0x1000>;
ranges = <0 0x314000 0x1000>;
- interrupt-parent = <&mpic>;
- interrupts = <93 2>;
sec_mon_rtc_lp@34 {
compatible = "fsl,sec-v4.0-mon-rtc-lp";
- reg = <0x34 0x58>;
+ interrupts = <93 2>;
};
};
--
1.9.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v4 3/6] arm: dts: imx: update snvs to use syscon access register
2015-05-22 14:36 [PATCH v4 0/6] Change snvs rtc and poweroff to use syscon add pwrkey driver Frank.Li
2015-05-22 14:36 ` [PATCH v4 1/6] rtc: arm: imx: snvs: change use syscon to access register Frank.Li
2015-05-22 14:36 ` [PATCH v4 2/6] Document: dt: fsl: snvs: change support syscon Frank.Li
@ 2015-05-22 14:36 ` Frank.Li
2015-05-25 6:39 ` Shawn Guo
2015-05-22 14:36 ` [PATCH v4 4/6] input: keyboard: imx: add snvs power key driver Frank.Li
` (3 subsequent siblings)
6 siblings, 1 reply; 14+ messages in thread
From: Frank.Li @ 2015-05-22 14:36 UTC (permalink / raw)
To: lznuaa, shawn.guo, dmitry.torokhov, robh+dt, alexandre.belloni,
linux
Cc: linux-arm-kernel, linux-input, rtc-linux, devicetree, Frank Li
From: Frank Li <Frank.Li@freescale.com>
snvs is MFP device. Change dts to use syscon to allocate register resource.
snvs power off also switch to common syscon-poweroff
Signed-off-by: Frank Li <Frank.Li@freescale.com>
---
arch/arm/boot/dts/imx6qdl.dtsi | 19 +++++++++----------
arch/arm/boot/dts/imx6sl.dtsi | 19 +++++++++----------
arch/arm/boot/dts/imx6sx.dtsi | 17 ++++++++---------
arch/arm/boot/dts/vfxxx.dtsi | 9 +++------
4 files changed, 29 insertions(+), 35 deletions(-)
diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index 0482a66..4f3f5f4 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -686,22 +686,21 @@
fsl,anatop = <&anatop>;
};
- snvs@020cc000 {
- compatible = "fsl,sec-v4.0-mon", "simple-bus";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0 0x020cc000 0x4000>;
+ snvs:snvs@020cc000 {
+ compatible = "fsl,sec-v4.0-mon", "syscon", "simple-mfd";
+ reg = <0x020cc000 0x4000>;
- snvs_rtc: snvs-rtc-lp@34 {
+ snvs_rtc: snvs-rtc-lp {
compatible = "fsl,sec-v4.0-mon-rtc-lp";
- reg = <0x34 0x58>;
interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>,
<0 20 IRQ_TYPE_LEVEL_HIGH>;
};
- snvs_poweroff: snvs-poweroff@38 {
- compatible = "fsl,sec-v4.0-poweroff";
- reg = <0x38 0x4>;
+ snvs_poweroff: snvs-poweroff {
+ compatible = "syscon-poweroff";
+ regmap = <&snvs>;
+ offset = <0x38>;
+ mask = <0x60>;
status = "disabled";
};
};
diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi
index a78e715..2de6d46 100644
--- a/arch/arm/boot/dts/imx6sl.dtsi
+++ b/arch/arm/boot/dts/imx6sl.dtsi
@@ -563,22 +563,21 @@
fsl,anatop = <&anatop>;
};
- snvs@020cc000 {
- compatible = "fsl,sec-v4.0-mon", "simple-bus";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0 0x020cc000 0x4000>;
+ snvs:snvs@020cc000 {
+ compatible = "fsl,sec-v4.0-mon", "syscon", "simple-mfd";
+ reg = <0x020cc000 0x4000>;
- snvs_rtc: snvs-rtc-lp@34 {
+ snvs_rtc: snvs-rtc-lp {
compatible = "fsl,sec-v4.0-mon-rtc-lp";
- reg = <0x34 0x58>;
interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>,
<0 20 IRQ_TYPE_LEVEL_HIGH>;
};
- snvs_poweroff: snvs-poweroff@38 {
- compatible = "fsl,sec-v4.0-poweroff";
- reg = <0x38 0x4>;
+ snvs_poweroff: snvs-poweroff {
+ compatible = "syscon-poweroff";
+ regmap = <&snvs>;
+ offset = <0x38>;
+ mask = <0x60>;
status = "disabled";
};
};
diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
index 708175d..3cb3b5b 100644
--- a/arch/arm/boot/dts/imx6sx.dtsi
+++ b/arch/arm/boot/dts/imx6sx.dtsi
@@ -662,20 +662,19 @@
};
snvs: snvs@020cc000 {
- compatible = "fsl,sec-v4.0-mon", "simple-bus";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0 0x020cc000 0x4000>;
+ compatible = "fsl,sec-v4.0-mon", "syscon", "simple-mfd";
+ reg = <0x020cc000 0x4000>;
- snvs_rtc: snvs-rtc-lp@34 {
+ snvs_rtc: snvs-rtc-lp {
compatible = "fsl,sec-v4.0-mon-rtc-lp";
- reg = <0x34 0x58>;
interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
};
- snvs_poweroff: snvs-poweroff@38 {
- compatible = "fsl,sec-v4.0-poweroff";
- reg = <0x38 0x4>;
+ snvs_poweroff: snvs-poweroff {
+ compatible = "syscon-poweroff";
+ regmap = <&snvs>;
+ offset = <0x38>;
+ mask = <0x60>;
status = "disabled";
};
};
diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 4aa3351..fccfc01 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -404,14 +404,11 @@
};
snvs0: snvs@400a7000 {
- compatible = "fsl,sec-v4.0-mon", "simple-bus";
- #address-cells = <1>;
- #size-cells = <1>;
- ranges = <0 0x400a7000 0x2000>;
+ compatible = "fsl,sec-v4.0-mon", "syscon", "simple-mfd";
+ reg = <0x400a7000 0x2000>;
- snvsrtc: snvs-rtc-lp@34 {
+ snvsrtc: snvs-rtc-lp {
compatible = "fsl,sec-v4.0-mon-rtc-lp";
- reg = <0x34 0x58>;
interrupts = <100 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks VF610_CLK_SNVS>;
clock-names = "snvs-rtc";
--
1.9.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v4 4/6] input: keyboard: imx: add snvs power key driver
2015-05-22 14:36 [PATCH v4 0/6] Change snvs rtc and poweroff to use syscon add pwrkey driver Frank.Li
` (2 preceding siblings ...)
2015-05-22 14:36 ` [PATCH v4 3/6] arm: dts: imx: update snvs to use syscon access register Frank.Li
@ 2015-05-22 14:36 ` Frank.Li
2015-05-25 7:35 ` Shawn Guo
2015-05-22 14:36 ` [PATCH v4 5/6] document: devicetree: input: imx: i.mx snvs power device tree bindings Frank.Li
` (2 subsequent siblings)
6 siblings, 1 reply; 14+ messages in thread
From: Frank.Li @ 2015-05-22 14:36 UTC (permalink / raw)
To: lznuaa, shawn.guo, dmitry.torokhov, robh+dt, alexandre.belloni,
linux
Cc: linux-arm-kernel, linux-input, rtc-linux, devicetree, Robin Gong,
Frank Li
From: Robin Gong <b38343@freescale.com>
add snvs power key driver.
It work in imx chips after i.mx6sx
ON/OFF key used power on/off whole system.
This driver make it wakeup from suspend state when short press
ON/OFF key.
Long time press will trig SNVS power off chip without software
intervention.
Signed-off-by: Robin Gong <b38343@freescale.com>
Signed-off-by: Frank Li <Frank.Li@freescale.com>
---
drivers/input/keyboard/Kconfig | 11 ++
drivers/input/keyboard/Makefile | 1 +
drivers/input/keyboard/snvs_pwrkey.c | 232 +++++++++++++++++++++++++++++++++++
3 files changed, 244 insertions(+)
create mode 100644 drivers/input/keyboard/snvs_pwrkey.c
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 106fbac..61b3fab 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -400,6 +400,17 @@ config KEYBOARD_MPR121
To compile this driver as a module, choose M here: the
module will be called mpr121_touchkey.
+config KEYBOARD_SNVS_PWRKEY
+ tristate "IMX SNVS Power Key Driver"
+ depends on SOC_IMX6SX
+ depends on OF
+ help
+ This is the snvs powerkey driver for the Freescale i.MX application
+ processors that are newer than i.MX6 SX.
+
+ To compile this driver as a module, choose M here; the
+ module will be called snvs_pwrkey.
+
config KEYBOARD_IMX
tristate "IMX keypad support"
depends on ARCH_MXC
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index df28d55..1d416dd 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -51,6 +51,7 @@ obj-$(CONFIG_KEYBOARD_QT1070) += qt1070.o
obj-$(CONFIG_KEYBOARD_QT2160) += qt2160.o
obj-$(CONFIG_KEYBOARD_SAMSUNG) += samsung-keypad.o
obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o
+obj-$(CONFIG_KEYBOARD_SNVS_PWRKEY) += snvs_pwrkey.o
obj-$(CONFIG_KEYBOARD_SPEAR) += spear-keyboard.o
obj-$(CONFIG_KEYBOARD_STMPE) += stmpe-keypad.o
obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o
diff --git a/drivers/input/keyboard/snvs_pwrkey.c b/drivers/input/keyboard/snvs_pwrkey.c
new file mode 100644
index 0000000..98c340e
--- /dev/null
+++ b/drivers/input/keyboard/snvs_pwrkey.c
@@ -0,0 +1,232 @@
+/*
+ * Driver for the IMX SNVS ON/OFF Power Key
+ * Copyright (C) 2015 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+
+#define SNVS_LPSR_REG 0x4C /* LP Status Register */
+#define SNVS_LPCR_REG 0x38 /* LP Control Register */
+#define SNVS_HPSR_REG 0x14
+#define SNVS_HPSR_BTN BIT(6)
+#define SNVS_LPSR_SPO BIT(18)
+#define SNVS_LPCR_DEP_EN BIT(5)
+
+#define DEBOUNCE_TIME 30
+#define REPEAT_INTERVAL 60
+
+struct pwrkey_drv_data {
+ struct regmap *snvs;
+ int irq;
+ int keycode;
+ int keystate; /* 1:pressed */
+ int wakeup;
+ struct timer_list check_timer;
+ struct input_dev *input;
+};
+
+static void imx_imx_snvs_check_for_events(unsigned long data)
+{
+ struct pwrkey_drv_data *pdata = (struct pwrkey_drv_data *) data;
+ struct input_dev *input = pdata->input;
+ u32 state;
+
+ regmap_read(pdata->snvs, SNVS_HPSR_REG, &state);
+ state = state & SNVS_HPSR_BTN ? 1 : 0;
+
+ /* only report new event if status changed */
+ if (state ^ pdata->keystate) {
+ pdata->keystate = state;
+ input_event(input, EV_KEY, pdata->keycode, state);
+ input_sync(input);
+ pm_relax(pdata->input->dev.parent);
+ }
+
+ /* repeat check if pressed long */
+ if (state) {
+ mod_timer(&pdata->check_timer,
+ jiffies + msecs_to_jiffies(REPEAT_INTERVAL));
+ }
+}
+
+static irqreturn_t imx_snvs_pwrkey_interrupt(int irq, void *dev_id)
+{
+ struct platform_device *pdev = dev_id;
+ struct pwrkey_drv_data *pdata = platform_get_drvdata(pdev);
+ u32 lp_status;
+
+ pm_wakeup_event(pdata->input->dev.parent, 0);
+
+ regmap_read(pdata->snvs, SNVS_LPSR_REG, &lp_status);
+ if (lp_status & SNVS_LPSR_SPO)
+ mod_timer(&pdata->check_timer, jiffies + msecs_to_jiffies(DEBOUNCE_TIME));
+
+ /* clear SPO status */
+ regmap_write(pdata->snvs, SNVS_LPSR_REG, SNVS_LPSR_SPO);
+
+ return IRQ_HANDLED;
+}
+
+static void imx_snvs_pwrkey_act(void *pdata)
+{
+ struct pwrkey_drv_data *pd = pdata;
+
+ del_timer_sync(&pd->check_timer);
+}
+
+static int imx_snvs_pwrkey_probe(struct platform_device *pdev)
+{
+ struct pwrkey_drv_data *pdata = NULL;
+ struct input_dev *input = NULL;
+ struct device_node *np, *snvs_np;
+ int error;
+
+ /* Get SNVS register Page */
+ np = pdev->dev.of_node;
+ if (!np)
+ return -ENODEV;
+
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ snvs_np = of_get_parent(pdev->dev.of_node);
+ if (!snvs_np)
+ return -ENODEV;
+
+ pdata->snvs = syscon_node_to_regmap(snvs_np);
+ of_node_put(snvs_np);
+
+ if (!pdata->snvs) {
+ pr_err("Can't get snvs syscon\n");
+ return -ENODEV;
+ }
+
+ if (of_property_read_u32(np, "linux,keycode", &pdata->keycode)) {
+ pdata->keycode = KEY_POWER;
+ dev_warn(&pdev->dev, "KEY_POWER without setting in dts\n");
+ }
+
+ pdata->wakeup = of_property_read_bool(np, "wakeup");
+
+ pdata->irq = platform_get_irq(pdev, 0);
+ if (pdata->irq < 0) {
+ dev_err(&pdev->dev, "no irq defined in platform data\n");
+ return -EINVAL;
+ }
+
+ regmap_update_bits(pdata->snvs, SNVS_LPCR_REG, SNVS_LPCR_DEP_EN, SNVS_LPCR_DEP_EN);
+
+ /* clear the unexpected interrupt before driver ready */
+ regmap_write(pdata->snvs, SNVS_LPSR_REG, SNVS_LPSR_SPO);
+
+ setup_timer(&pdata->check_timer,
+ imx_imx_snvs_check_for_events, (unsigned long) pdata);
+
+ input = devm_input_allocate_device(&pdev->dev);
+ if (!input) {
+ dev_err(&pdev->dev, "failed to allocate the input device\n");
+ return -ENOMEM;
+ }
+
+ input->name = pdev->name;
+ input->phys = "snvs-pwrkey/input0";
+ input->id.bustype = BUS_HOST;
+
+ input_set_capability(input, EV_KEY, pdata->keycode);
+
+ /* input customer action to cancel release timer */
+ error = devm_add_action(&pdev->dev, imx_snvs_pwrkey_act, pdata);
+ if (error) {
+ dev_err(&pdev->dev, "failed to register remove action\n");
+ return error;
+ }
+
+ error = devm_request_irq(&pdev->dev, pdata->irq,
+ imx_snvs_pwrkey_interrupt,
+ 0, pdev->name, pdev);
+
+ if (error) {
+ dev_err(&pdev->dev, "interrupt not available.\n");
+ return error;
+ }
+
+ error = input_register_device(input);
+ if (error < 0) {
+ dev_err(&pdev->dev, "failed to register input device\n");
+ input_free_device(input);
+ return error;
+ }
+
+ pdata->input = input;
+ platform_set_drvdata(pdev, pdata);
+
+ device_init_wakeup(&pdev->dev, pdata->wakeup);
+
+ return 0;
+}
+
+static int imx_snvs_pwrkey_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct pwrkey_drv_data *pdata = platform_get_drvdata(pdev);
+
+ if (device_may_wakeup(&pdev->dev))
+ enable_irq_wake(pdata->irq);
+
+ return 0;
+}
+
+static int imx_snvs_pwrkey_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct pwrkey_drv_data *pdata = platform_get_drvdata(pdev);
+
+ if (device_may_wakeup(&pdev->dev))
+ disable_irq_wake(pdata->irq);
+
+ return 0;
+}
+
+static const struct of_device_id imx_snvs_pwrkey_ids[] = {
+ { .compatible = "fsl,sec-v4.0-pwrkey" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_snvs_pwrkey_ids);
+
+static SIMPLE_DEV_PM_OPS(imx_snvs_pwrkey_pm_ops, imx_snvs_pwrkey_suspend,
+ imx_snvs_pwrkey_resume);
+
+static struct platform_driver imx_snvs_pwrkey_driver = {
+ .driver = {
+ .name = "snvs_pwrkey",
+ .pm = &imx_snvs_pwrkey_pm_ops,
+ .of_match_table = imx_snvs_pwrkey_ids,
+ },
+ .probe = imx_snvs_pwrkey_probe,
+};
+module_platform_driver(imx_snvs_pwrkey_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor");
+MODULE_DESCRIPTION("i.MX snvs power key Driver");
+MODULE_LICENSE("GPL");
--
1.9.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v4 5/6] document: devicetree: input: imx: i.mx snvs power device tree bindings
2015-05-22 14:36 [PATCH v4 0/6] Change snvs rtc and poweroff to use syscon add pwrkey driver Frank.Li
` (3 preceding siblings ...)
2015-05-22 14:36 ` [PATCH v4 4/6] input: keyboard: imx: add snvs power key driver Frank.Li
@ 2015-05-22 14:36 ` Frank.Li
[not found] ` <1432305399-30571-1-git-send-email-Frank.Li-KZfg59tc24xl57MIdRCFDg@public.gmane.org>
2015-05-25 6:47 ` [PATCH v4 0/6] Change snvs rtc and poweroff to use syscon add pwrkey driver Shawn Guo
6 siblings, 0 replies; 14+ messages in thread
From: Frank.Li @ 2015-05-22 14:36 UTC (permalink / raw)
To: lznuaa, shawn.guo, dmitry.torokhov, robh+dt, alexandre.belloni,
linux
Cc: linux-arm-kernel, linux-input, rtc-linux, devicetree, Frank Li,
Robin Gong
From: Frank Li <Frank.Li@freescale.com>
The snvs-pwrkey is designed to enable POWER key function which controlled
by SNVS ONOFF. the driver can report the status of POWER key and wakeup
system if pressed after system suspend.
Signed-off-by: Frank Li <Frank.Li@freescale.com>
Signed-off-by: Robin Gong <b38343@freescale.com>
---
.../devicetree/bindings/crypto/fsl-sec4.txt | 42 ++++++++++++++++++++++
.../devicetree/bindings/input/snvs-pwrkey.txt | 1 +
2 files changed, 43 insertions(+)
create mode 100644 Documentation/devicetree/bindings/input/snvs-pwrkey.txt
diff --git a/Documentation/devicetree/bindings/crypto/fsl-sec4.txt b/Documentation/devicetree/bindings/crypto/fsl-sec4.txt
index 87f5921..b2a417d 100644
--- a/Documentation/devicetree/bindings/crypto/fsl-sec4.txt
+++ b/Documentation/devicetree/bindings/crypto/fsl-sec4.txt
@@ -375,6 +375,41 @@ EXAMPLE
};
=====================================================================
+System ON/OFF key driver
+
+ The snvs-pwrkey is designed to enable POWER key function which controlled
+ by SNVS ONOFF, the driver can report the status of POWER key and wakeup
+ system if pressed after system suspend.
+
+ - compatible:
+ Usage: required
+ Value type: <string>
+ Definition: Mush include "fsl,sec-v4.0-pwrkey".
+
+ - interrupts:
+ Usage: required
+ Value type: <prop_encoded-array>
+ Definition: The SNVS ON/OFF interrupt number to the CPU(s).
+
+ - linux,keycode:
+ Usage: option
+ Value type: <int>
+ Definition: Keycode to emit, KEY_POWER by default.
+
+ - wakeup:
+ Usage: option
+ Value type: <boo>
+ Definition: Button can wake-up the system
+
+EXAMPLE:
+ snvs-pwrkey@0x020cc000 {
+ compatible = "fsl,sec-v4.0-pwrkey";
+ interrupts = <0 4 0x4>
+ linux,keycode = <116>; /* KEY_POWER */
+ wakeup;
+ };
+
+=====================================================================
FULL EXAMPLE
crypto: crypto@300000 {
@@ -452,6 +487,13 @@ FULL EXAMPLE
compatible = "fsl,sec-v4.0-mon-rtc-lp";
interrupts = <93 2>;
};
+
+ snvs-pwrkey@0x020cc000 {
+ compatible = "fsl,sec-v4.0-pwrkey";
+ interrupts = <0 4 0x4>;
+ linux,keycode = <116>; /* KEY_POWER */
+ wakeup;
+ };
};
=====================================================================
diff --git a/Documentation/devicetree/bindings/input/snvs-pwrkey.txt b/Documentation/devicetree/bindings/input/snvs-pwrkey.txt
new file mode 100644
index 0000000..70c1425
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/snvs-pwrkey.txt
@@ -0,0 +1 @@
+See Documentation/devicetree/bindings/crypto/fsl-sec4.txt
--
1.9.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v4 6/6] arm: dts: imx6sx: enable snvs power key
[not found] ` <1432305399-30571-1-git-send-email-Frank.Li-KZfg59tc24xl57MIdRCFDg@public.gmane.org>
@ 2015-05-22 14:36 ` Frank.Li-KZfg59tc24xl57MIdRCFDg
2015-05-25 7:39 ` Shawn Guo
0 siblings, 1 reply; 14+ messages in thread
From: Frank.Li-KZfg59tc24xl57MIdRCFDg @ 2015-05-22 14:36 UTC (permalink / raw)
To: lznuaa-Re5JQEeQqe8AvxtiuMwx3w, shawn.guo-QSEj5FYQhm4dnm+yROfE0A,
dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
linux-lFZ/pmaqli7XmaaqVzeoHQ
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-input-u79uwXL29TY76Z2rM5mHXA,
rtc-linux-/JYPxA39Uh5TLH3MbocFFw,
devicetree-u79uwXL29TY76Z2rM5mHXA, Frank Li
From: Frank Li <Frank.Li-KZfg59tc24xl57MIdRCFDg@public.gmane.org>
enable snvs ONOFF power key support
Signed-off-by: Frank Li <Frank.Li-KZfg59tc24xl57MIdRCFDg@public.gmane.org>
---
arch/arm/boot/dts/imx6sx.dtsi | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
index 3cb3b5b..ad38aea 100644
--- a/arch/arm/boot/dts/imx6sx.dtsi
+++ b/arch/arm/boot/dts/imx6sx.dtsi
@@ -677,6 +677,13 @@
mask = <0x60>;
status = "disabled";
};
+
+ snvs_pwrkey: snvs-powerkey {
+ compatible = "fsl,sec-v4.0-pwrkey";
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+ linux,keycode = <116>; /* KEY_POWER */
+ wakeup;
+ };
};
epit1: epit@020d0000 {
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH v4 1/6] rtc: arm: imx: snvs: change use syscon to access register
2015-05-22 14:36 ` [PATCH v4 1/6] rtc: arm: imx: snvs: change use syscon to access register Frank.Li
@ 2015-05-25 6:18 ` Shawn Guo
2015-05-25 6:44 ` Shawn Guo
1 sibling, 0 replies; 14+ messages in thread
From: Shawn Guo @ 2015-05-25 6:18 UTC (permalink / raw)
To: Frank.Li
Cc: lznuaa, dmitry.torokhov, robh+dt, alexandre.belloni, linux,
linux-arm-kernel, linux-input, rtc-linux, devicetree
On Fri, May 22, 2015 at 10:36:34PM +0800, Frank.Li@freescale.com wrote:
> From: Frank Li <Frank.Li@freescale.com>
>
> snvs included rtc, on/off key, power-off module
> change to syscon to access register
>
> Signed-off-by: Frank Li <Frank.Li@freescale.com>
Did you test it with both existing and new DTBs?
> ---
> drivers/rtc/rtc-snvs.c | 136 +++++++++++++++++++++++++------------------------
> 1 file changed, 70 insertions(+), 66 deletions(-)
>
> diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c
> index 0479e80..42e55da 100644
> --- a/drivers/rtc/rtc-snvs.c
> +++ b/drivers/rtc/rtc-snvs.c
> @@ -18,6 +18,8 @@
> #include <linux/platform_device.h>
> #include <linux/rtc.h>
> #include <linux/clk.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/regmap.h>
>
> /* These register offsets are relative to LP (Low Power) range */
> #define SNVS_LPCR 0x04
> @@ -37,31 +39,35 @@
>
> struct snvs_rtc_data {
> struct rtc_device *rtc;
> - void __iomem *ioaddr;
> + struct regmap *regmap;
> + int offset;
> int irq;
> - spinlock_t lock;
> struct clk *clk;
> };
>
> -static u32 rtc_read_lp_counter(void __iomem *ioaddr)
> +static u32 rtc_read_lp_counter(struct snvs_rtc_data *snvs)
All the pointers to struct snvs_rtc_data are named 'data'. Please keep
it consistent.
> {
> u64 read1, read2;
> -
> + u32 val;
Please keep the new line here.
> do {
> - read1 = readl(ioaddr + SNVS_LPSRTCMR);
> + regmap_read(snvs->regmap, snvs->offset + SNVS_LPSRTCMR, &val);
> + read1 = val;
> read1 <<= 32;
> - read1 |= readl(ioaddr + SNVS_LPSRTCLR);
> + regmap_read(snvs->regmap, snvs->offset + SNVS_LPSRTCLR, &val);
> + read1 |= val;
>
> - read2 = readl(ioaddr + SNVS_LPSRTCMR);
> + regmap_read(snvs->regmap, snvs->offset + SNVS_LPSRTCMR, &val);
> + read2 = val;
> read2 <<= 32;
> - read2 |= readl(ioaddr + SNVS_LPSRTCLR);
> + regmap_read(snvs->regmap, snvs->offset + SNVS_LPSRTCLR, &val);
> + read2 |= val;
> } while (read1 != read2);
>
> /* Convert 47-bit counter to 32-bit raw second count */
> return (u32) (read1 >> CNTR_TO_SECS_SH);
> }
>
> -static void rtc_write_sync_lp(void __iomem *ioaddr)
> +static void rtc_write_sync_lp(struct snvs_rtc_data *snvs)
> {
> u32 count1, count2, count3;
> int i;
> @@ -69,15 +75,15 @@ static void rtc_write_sync_lp(void __iomem *ioaddr)
> /* Wait for 3 CKIL cycles */
> for (i = 0; i < 3; i++) {
> do {
> - count1 = readl(ioaddr + SNVS_LPSRTCLR);
> - count2 = readl(ioaddr + SNVS_LPSRTCLR);
> + regmap_read(snvs->regmap, snvs->offset + SNVS_LPSRTCLR, &count1);
> + regmap_read(snvs->regmap, snvs->offset + SNVS_LPSRTCLR, &count2);
> } while (count1 != count2);
>
> /* Now wait until counter value changes */
> do {
> do {
> - count2 = readl(ioaddr + SNVS_LPSRTCLR);
> - count3 = readl(ioaddr + SNVS_LPSRTCLR);
> + regmap_read(snvs->regmap, snvs->offset + SNVS_LPSRTCLR, &count2);
> + regmap_read(snvs->regmap, snvs->offset + SNVS_LPSRTCLR, &count3);
> } while (count2 != count3);
> } while (count3 == count1);
> }
> @@ -85,23 +91,14 @@ static void rtc_write_sync_lp(void __iomem *ioaddr)
>
> static int snvs_rtc_enable(struct snvs_rtc_data *data, bool enable)
> {
> - unsigned long flags;
> int timeout = 1000;
> u32 lpcr;
>
> - spin_lock_irqsave(&data->lock, flags);
> -
> - lpcr = readl(data->ioaddr + SNVS_LPCR);
> - if (enable)
> - lpcr |= SNVS_LPCR_SRTC_ENV;
> - else
> - lpcr &= ~SNVS_LPCR_SRTC_ENV;
> - writel(lpcr, data->ioaddr + SNVS_LPCR);
> -
> - spin_unlock_irqrestore(&data->lock, flags);
> + regmap_update_bits(data->regmap, data->offset + SNVS_LPCR, SNVS_LPCR_SRTC_ENV,
> + enable ? SNVS_LPCR_SRTC_ENV : 0);
>
> while (--timeout) {
> - lpcr = readl(data->ioaddr + SNVS_LPCR);
> + regmap_read(data->regmap, data->offset + SNVS_LPCR, &lpcr);
>
> if (enable) {
> if (lpcr & SNVS_LPCR_SRTC_ENV)
> @@ -121,7 +118,7 @@ static int snvs_rtc_enable(struct snvs_rtc_data *data, bool enable)
> static int snvs_rtc_read_time(struct device *dev, struct rtc_time *tm)
> {
> struct snvs_rtc_data *data = dev_get_drvdata(dev);
> - unsigned long time = rtc_read_lp_counter(data->ioaddr);
> + unsigned long time = rtc_read_lp_counter(data);
>
> rtc_time_to_tm(time, tm);
>
> @@ -139,8 +136,8 @@ static int snvs_rtc_set_time(struct device *dev, struct rtc_time *tm)
> snvs_rtc_enable(data, false);
>
> /* Write 32-bit time to 47-bit timer, leaving 15 LSBs blank */
> - writel(time << CNTR_TO_SECS_SH, data->ioaddr + SNVS_LPSRTCLR);
> - writel(time >> (32 - CNTR_TO_SECS_SH), data->ioaddr + SNVS_LPSRTCMR);
> + regmap_write(data->regmap, data->offset + SNVS_LPSRTCLR, time << CNTR_TO_SECS_SH);
> + regmap_write(data->regmap, data->offset + SNVS_LPSRTCMR, time >> (32 - CNTR_TO_SECS_SH));
>
> /* Enable RTC again */
> snvs_rtc_enable(data, true);
> @@ -153,10 +150,10 @@ static int snvs_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
> struct snvs_rtc_data *data = dev_get_drvdata(dev);
> u32 lptar, lpsr;
>
> - lptar = readl(data->ioaddr + SNVS_LPTAR);
> + regmap_read(data->regmap, data->offset + SNVS_LPTAR, &lptar);
> rtc_time_to_tm(lptar, &alrm->time);
>
> - lpsr = readl(data->ioaddr + SNVS_LPSR);
> + regmap_read(data->regmap, data->offset + SNVS_LPSR, &lpsr);
> alrm->pending = (lpsr & SNVS_LPSR_LPTA) ? 1 : 0;
>
> return 0;
> @@ -165,21 +162,12 @@ static int snvs_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
> static int snvs_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
> {
> struct snvs_rtc_data *data = dev_get_drvdata(dev);
> - u32 lpcr;
> - unsigned long flags;
> -
> - spin_lock_irqsave(&data->lock, flags);
> -
> - lpcr = readl(data->ioaddr + SNVS_LPCR);
> - if (enable)
> - lpcr |= (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN);
> - else
> - lpcr &= ~(SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN);
> - writel(lpcr, data->ioaddr + SNVS_LPCR);
>
> - spin_unlock_irqrestore(&data->lock, flags);
> + regmap_update_bits(data->regmap, data->offset + SNVS_LPCR,
> + (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN),
> + enable ? (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN) : 0);
>
> - rtc_write_sync_lp(data->ioaddr);
> + rtc_write_sync_lp(data);
>
> return 0;
> }
> @@ -189,24 +177,14 @@ static int snvs_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
> struct snvs_rtc_data *data = dev_get_drvdata(dev);
> struct rtc_time *alrm_tm = &alrm->time;
> unsigned long time;
> - unsigned long flags;
> - u32 lpcr;
>
> rtc_tm_to_time(alrm_tm, &time);
>
> - spin_lock_irqsave(&data->lock, flags);
> -
> - /* Have to clear LPTA_EN before programming new alarm time in LPTAR */
> - lpcr = readl(data->ioaddr + SNVS_LPCR);
> - lpcr &= ~SNVS_LPCR_LPTA_EN;
> - writel(lpcr, data->ioaddr + SNVS_LPCR);
> -
> - spin_unlock_irqrestore(&data->lock, flags);
> -
> - writel(time, data->ioaddr + SNVS_LPTAR);
> + regmap_update_bits(data->regmap, data->offset + SNVS_LPCR, SNVS_LPCR_LPTA_EN, 0);
> + regmap_write(data->regmap, data->offset + SNVS_LPTAR, time);
>
> /* Clear alarm interrupt status bit */
> - writel(SNVS_LPSR_LPTA, data->ioaddr + SNVS_LPSR);
> + regmap_write(data->regmap, data->offset + SNVS_LPSR, SNVS_LPSR_LPTA);
>
> return snvs_rtc_alarm_irq_enable(dev, alrm->enabled);
> }
> @@ -226,7 +204,7 @@ static irqreturn_t snvs_rtc_irq_handler(int irq, void *dev_id)
> u32 lpsr;
> u32 events = 0;
>
> - lpsr = readl(data->ioaddr + SNVS_LPSR);
> + regmap_read(data->regmap, data->offset + SNVS_LPSR, &lpsr);
>
> if (lpsr & SNVS_LPSR_LPTA) {
> events |= (RTC_AF | RTC_IRQF);
> @@ -238,25 +216,53 @@ static irqreturn_t snvs_rtc_irq_handler(int irq, void *dev_id)
> }
>
> /* clear interrupt status */
> - writel(lpsr, data->ioaddr + SNVS_LPSR);
> + regmap_write(data->regmap, data->offset + SNVS_LPSR, lpsr);
>
> return events ? IRQ_HANDLED : IRQ_NONE;
> }
>
> +static const struct regmap_config snvs_rtc_config = {
> + .reg_bits = 32,
> + .val_bits = 32,
> + .reg_stride = 4,
> +};
> +
> static int snvs_rtc_probe(struct platform_device *pdev)
> {
> struct snvs_rtc_data *data;
> struct resource *res;
> int ret;
> + struct device_node *snvs_np;
Since you have only one pointer to device_node in this function, name
'np' is probably just fine.
> + void __iomem *mmio;
>
> data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
> if (!data)
> return -ENOMEM;
>
> - res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> - data->ioaddr = devm_ioremap_resource(&pdev->dev, res);
> - if (IS_ERR(data->ioaddr))
> - return PTR_ERR(data->ioaddr);
> + snvs_np = of_get_parent(pdev->dev.of_node);
> + if (!snvs_np)
> + return -ENODEV;
> +
> + if (of_device_is_compatible(snvs_np, "syscon")) {
> + data->regmap = syscon_node_to_regmap(snvs_np);
> + data->offset = 0x34;
You should at least have a macro for this magic number to tell what it
is?
> + } else {
> + pr_warn("snvs rtc: you use old dts file, please update it\n");
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +
> + mmio = devm_ioremap_resource(&pdev->dev, res);
> + if (IS_ERR(mmio))
> + return PTR_ERR(mmio);
So if it fails out from here, of_node_put() call will be skipped.
> +
> + data->regmap = devm_regmap_init_mmio(&pdev->dev, mmio, &snvs_rtc_config);
> + }
> +
> + of_node_put(snvs_np);
> +
> + if (!data->regmap) {
> + pr_err("Can't snvs syscon\n");
dev_err(), and "Can't find" or something?
Shawn
> + return -ENODEV;
> + }
>
> data->irq = platform_get_irq(pdev, 0);
> if (data->irq < 0)
> @@ -276,13 +282,11 @@ static int snvs_rtc_probe(struct platform_device *pdev)
>
> platform_set_drvdata(pdev, data);
>
> - spin_lock_init(&data->lock);
> -
> /* Initialize glitch detect */
> - writel(SNVS_LPPGDR_INIT, data->ioaddr + SNVS_LPPGDR);
> + regmap_write(data->regmap, data->offset + SNVS_LPPGDR, SNVS_LPPGDR_INIT);
>
> /* Clear interrupt status */
> - writel(0xffffffff, data->ioaddr + SNVS_LPSR);
> + regmap_write(data->regmap, data->offset + SNVS_LPSR, 0xffffffff);
>
> /* Enable RTC */
> snvs_rtc_enable(data, true);
> --
> 1.9.1
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v4 2/6] Document: dt: fsl: snvs: change support syscon
2015-05-22 14:36 ` [PATCH v4 2/6] Document: dt: fsl: snvs: change support syscon Frank.Li
@ 2015-05-25 6:26 ` Shawn Guo
0 siblings, 0 replies; 14+ messages in thread
From: Shawn Guo @ 2015-05-25 6:26 UTC (permalink / raw)
To: Frank.Li
Cc: lznuaa, dmitry.torokhov, robh+dt, alexandre.belloni, linux,
linux-arm-kernel, linux-input, rtc-linux, devicetree
On Fri, May 22, 2015 at 10:36:35PM +0800, Frank.Li@freescale.com wrote:
> From: Frank Li <Frank.Li@freescale.com>
>
> snvs actually is multi fucntion driver.
> Change to use syscon to access register.
The rationale of 'interrupts' change did not get covered in the commit
log.
Shawn
>
> Signed-off-by: Frank Li <Frank.Li@freescale.com>
> ---
> .../devicetree/bindings/crypto/fsl-sec4.txt | 28 ++++++++++++----------
> 1 file changed, 15 insertions(+), 13 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/crypto/fsl-sec4.txt b/Documentation/devicetree/bindings/crypto/fsl-sec4.txt
> index e402277..87f5921 100644
> --- a/Documentation/devicetree/bindings/crypto/fsl-sec4.txt
> +++ b/Documentation/devicetree/bindings/crypto/fsl-sec4.txt
> @@ -288,12 +288,13 @@ Secure Non-Volatile Storage (SNVS) Node
> Node defines address range and the associated
> interrupt for the SNVS function. This function
> monitors security state information & reports
> - security violations.
> + security violations. This also included rtc,
> + system power off and ON/OFF key.
>
> - compatible
> Usage: required
> Value type: <string>
> - Definition: Must include "fsl,sec-v4.0-mon".
> + Definition: Must include "fsl,sec-v4.0-mon" and "syscon".
>
> - reg
> Usage: required
> @@ -324,7 +325,7 @@ Secure Non-Volatile Storage (SNVS) Node
> the child address, parent address, & length.
>
> - interrupts
> - Usage: required
> + Usage: optional
> Value type: <prop_encoded-array>
> Definition: Specifies the interrupts generated by this
> device. The value of the interrupts property
> @@ -341,7 +342,7 @@ Secure Non-Volatile Storage (SNVS) Node
>
> EXAMPLE
> sec_mon@314000 {
> - compatible = "fsl,sec-v4.0-mon";
> + compatible = "fsl,sec-v4.0-mon", "syscon";
> reg = <0x314000 0x1000>;
> ranges = <0 0x314000 0x1000>;
> interrupt-parent = <&mpic>;
> @@ -358,16 +359,19 @@ Secure Non-Volatile Storage (SNVS) Low Power (LP) RTC Node
> Value type: <string>
> Definition: Must include "fsl,sec-v4.0-mon-rtc-lp".
>
> - - reg
> + - interrupts
> Usage: required
> - Value type: <prop-encoded-array>
> - Definition: A standard property. Specifies the physical
> - address and length of the SNVS LP configuration registers.
> + Value type: <prop_encoded-array>
> + Definition: Specifies the interrupts generated by this
> + device. The value of the interrupts property
> + consists of one interrupt specifier. The format
> + of the specifier is defined by the binding document
> + describing the node's interrupt parent.
>
> EXAMPLE
> - sec_mon_rtc_lp@314000 {
> + sec_mon_rtc_lp@1 {
> compatible = "fsl,sec-v4.0-mon-rtc-lp";
> - reg = <0x34 0x58>;
> + interrupts = <93 2>;
> };
>
> =====================================================================
> @@ -443,12 +447,10 @@ FULL EXAMPLE
> compatible = "fsl,sec-v4.0-mon";
> reg = <0x314000 0x1000>;
> ranges = <0 0x314000 0x1000>;
> - interrupt-parent = <&mpic>;
> - interrupts = <93 2>;
>
> sec_mon_rtc_lp@34 {
> compatible = "fsl,sec-v4.0-mon-rtc-lp";
> - reg = <0x34 0x58>;
> + interrupts = <93 2>;
> };
> };
>
> --
> 1.9.1
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v4 3/6] arm: dts: imx: update snvs to use syscon access register
2015-05-22 14:36 ` [PATCH v4 3/6] arm: dts: imx: update snvs to use syscon access register Frank.Li
@ 2015-05-25 6:39 ` Shawn Guo
0 siblings, 0 replies; 14+ messages in thread
From: Shawn Guo @ 2015-05-25 6:39 UTC (permalink / raw)
To: Frank.Li
Cc: lznuaa, dmitry.torokhov, robh+dt, alexandre.belloni, linux,
linux-arm-kernel, linux-input, rtc-linux, devicetree
On Fri, May 22, 2015 at 10:36:36PM +0800, Frank.Li@freescale.com wrote:
> From: Frank Li <Frank.Li@freescale.com>
>
> snvs is MFP device. Change dts to use syscon to allocate register resource.
> snvs power off also switch to common syscon-poweroff
>
> Signed-off-by: Frank Li <Frank.Li@freescale.com>
> ---
> arch/arm/boot/dts/imx6qdl.dtsi | 19 +++++++++----------
> arch/arm/boot/dts/imx6sl.dtsi | 19 +++++++++----------
> arch/arm/boot/dts/imx6sx.dtsi | 17 ++++++++---------
> arch/arm/boot/dts/vfxxx.dtsi | 9 +++------
> 4 files changed, 29 insertions(+), 35 deletions(-)
>
> diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
> index 0482a66..4f3f5f4 100644
> --- a/arch/arm/boot/dts/imx6qdl.dtsi
> +++ b/arch/arm/boot/dts/imx6qdl.dtsi
> @@ -686,22 +686,21 @@
> fsl,anatop = <&anatop>;
> };
>
> - snvs@020cc000 {
> - compatible = "fsl,sec-v4.0-mon", "simple-bus";
> - #address-cells = <1>;
> - #size-cells = <1>;
> - ranges = <0 0x020cc000 0x4000>;
> + snvs:snvs@020cc000 {
There should be a space between label and node.
> + compatible = "fsl,sec-v4.0-mon", "syscon", "simple-mfd";
One space is enough in between.
> + reg = <0x020cc000 0x4000>;
>
> - snvs_rtc: snvs-rtc-lp@34 {
> + snvs_rtc: snvs-rtc-lp {
> compatible = "fsl,sec-v4.0-mon-rtc-lp";
> - reg = <0x34 0x58>;
I think rtc node should have a similar property list like snvs-poweroff,
i.e. regmap and offset.
Shawn
> interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>,
> <0 20 IRQ_TYPE_LEVEL_HIGH>;
> };
>
> - snvs_poweroff: snvs-poweroff@38 {
> - compatible = "fsl,sec-v4.0-poweroff";
> - reg = <0x38 0x4>;
> + snvs_poweroff: snvs-poweroff {
> + compatible = "syscon-poweroff";
> + regmap = <&snvs>;
> + offset = <0x38>;
> + mask = <0x60>;
> status = "disabled";
> };
> };
> diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi
> index a78e715..2de6d46 100644
> --- a/arch/arm/boot/dts/imx6sl.dtsi
> +++ b/arch/arm/boot/dts/imx6sl.dtsi
> @@ -563,22 +563,21 @@
> fsl,anatop = <&anatop>;
> };
>
> - snvs@020cc000 {
> - compatible = "fsl,sec-v4.0-mon", "simple-bus";
> - #address-cells = <1>;
> - #size-cells = <1>;
> - ranges = <0 0x020cc000 0x4000>;
> + snvs:snvs@020cc000 {
> + compatible = "fsl,sec-v4.0-mon", "syscon", "simple-mfd";
> + reg = <0x020cc000 0x4000>;
>
> - snvs_rtc: snvs-rtc-lp@34 {
> + snvs_rtc: snvs-rtc-lp {
> compatible = "fsl,sec-v4.0-mon-rtc-lp";
> - reg = <0x34 0x58>;
> interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>,
> <0 20 IRQ_TYPE_LEVEL_HIGH>;
> };
>
> - snvs_poweroff: snvs-poweroff@38 {
> - compatible = "fsl,sec-v4.0-poweroff";
> - reg = <0x38 0x4>;
> + snvs_poweroff: snvs-poweroff {
> + compatible = "syscon-poweroff";
> + regmap = <&snvs>;
> + offset = <0x38>;
> + mask = <0x60>;
> status = "disabled";
> };
> };
> diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
> index 708175d..3cb3b5b 100644
> --- a/arch/arm/boot/dts/imx6sx.dtsi
> +++ b/arch/arm/boot/dts/imx6sx.dtsi
> @@ -662,20 +662,19 @@
> };
>
> snvs: snvs@020cc000 {
> - compatible = "fsl,sec-v4.0-mon", "simple-bus";
> - #address-cells = <1>;
> - #size-cells = <1>;
> - ranges = <0 0x020cc000 0x4000>;
> + compatible = "fsl,sec-v4.0-mon", "syscon", "simple-mfd";
> + reg = <0x020cc000 0x4000>;
>
> - snvs_rtc: snvs-rtc-lp@34 {
> + snvs_rtc: snvs-rtc-lp {
> compatible = "fsl,sec-v4.0-mon-rtc-lp";
> - reg = <0x34 0x58>;
> interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
> };
>
> - snvs_poweroff: snvs-poweroff@38 {
> - compatible = "fsl,sec-v4.0-poweroff";
> - reg = <0x38 0x4>;
> + snvs_poweroff: snvs-poweroff {
> + compatible = "syscon-poweroff";
> + regmap = <&snvs>;
> + offset = <0x38>;
> + mask = <0x60>;
> status = "disabled";
> };
> };
> diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
> index 4aa3351..fccfc01 100644
> --- a/arch/arm/boot/dts/vfxxx.dtsi
> +++ b/arch/arm/boot/dts/vfxxx.dtsi
> @@ -404,14 +404,11 @@
> };
>
> snvs0: snvs@400a7000 {
> - compatible = "fsl,sec-v4.0-mon", "simple-bus";
> - #address-cells = <1>;
> - #size-cells = <1>;
> - ranges = <0 0x400a7000 0x2000>;
> + compatible = "fsl,sec-v4.0-mon", "syscon", "simple-mfd";
> + reg = <0x400a7000 0x2000>;
>
> - snvsrtc: snvs-rtc-lp@34 {
> + snvsrtc: snvs-rtc-lp {
> compatible = "fsl,sec-v4.0-mon-rtc-lp";
> - reg = <0x34 0x58>;
> interrupts = <100 IRQ_TYPE_LEVEL_HIGH>;
> clocks = <&clks VF610_CLK_SNVS>;
> clock-names = "snvs-rtc";
> --
> 1.9.1
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v4 1/6] rtc: arm: imx: snvs: change use syscon to access register
2015-05-22 14:36 ` [PATCH v4 1/6] rtc: arm: imx: snvs: change use syscon to access register Frank.Li
2015-05-25 6:18 ` Shawn Guo
@ 2015-05-25 6:44 ` Shawn Guo
1 sibling, 0 replies; 14+ messages in thread
From: Shawn Guo @ 2015-05-25 6:44 UTC (permalink / raw)
To: Frank.Li
Cc: lznuaa, dmitry.torokhov, robh+dt, alexandre.belloni, linux,
linux-arm-kernel, linux-input, rtc-linux, devicetree
On Fri, May 22, 2015 at 10:36:34PM +0800, Frank.Li@freescale.com wrote:
> static int snvs_rtc_probe(struct platform_device *pdev)
> {
> struct snvs_rtc_data *data;
> struct resource *res;
> int ret;
> + struct device_node *snvs_np;
> + void __iomem *mmio;
>
> data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
> if (!data)
> return -ENOMEM;
>
> - res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> - data->ioaddr = devm_ioremap_resource(&pdev->dev, res);
> - if (IS_ERR(data->ioaddr))
> - return PTR_ERR(data->ioaddr);
> + snvs_np = of_get_parent(pdev->dev.of_node);
> + if (!snvs_np)
> + return -ENODEV;
> +
> + if (of_device_is_compatible(snvs_np, "syscon")) {
> + data->regmap = syscon_node_to_regmap(snvs_np);
> + data->offset = 0x34;
As I commented on dts patch, we should probably follow syscon-poweroff
to have 'regmap' and 'offset' properties.
Shawn
> + } else {
> + pr_warn("snvs rtc: you use old dts file, please update it\n");
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +
> + mmio = devm_ioremap_resource(&pdev->dev, res);
> + if (IS_ERR(mmio))
> + return PTR_ERR(mmio);
> +
> + data->regmap = devm_regmap_init_mmio(&pdev->dev, mmio, &snvs_rtc_config);
> + }
> +
> + of_node_put(snvs_np);
> +
> + if (!data->regmap) {
> + pr_err("Can't snvs syscon\n");
> + return -ENODEV;
> + }
>
> data->irq = platform_get_irq(pdev, 0);
> if (data->irq < 0)
> @@ -276,13 +282,11 @@ static int snvs_rtc_probe(struct platform_device *pdev)
>
> platform_set_drvdata(pdev, data);
>
> - spin_lock_init(&data->lock);
> -
> /* Initialize glitch detect */
> - writel(SNVS_LPPGDR_INIT, data->ioaddr + SNVS_LPPGDR);
> + regmap_write(data->regmap, data->offset + SNVS_LPPGDR, SNVS_LPPGDR_INIT);
>
> /* Clear interrupt status */
> - writel(0xffffffff, data->ioaddr + SNVS_LPSR);
> + regmap_write(data->regmap, data->offset + SNVS_LPSR, 0xffffffff);
>
> /* Enable RTC */
> snvs_rtc_enable(data, true);
> --
> 1.9.1
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v4 0/6] Change snvs rtc and poweroff to use syscon add pwrkey driver
2015-05-22 14:36 [PATCH v4 0/6] Change snvs rtc and poweroff to use syscon add pwrkey driver Frank.Li
` (5 preceding siblings ...)
[not found] ` <1432305399-30571-1-git-send-email-Frank.Li-KZfg59tc24xl57MIdRCFDg@public.gmane.org>
@ 2015-05-25 6:47 ` Shawn Guo
6 siblings, 0 replies; 14+ messages in thread
From: Shawn Guo @ 2015-05-25 6:47 UTC (permalink / raw)
To: Frank.Li
Cc: lznuaa, dmitry.torokhov, robh+dt, alexandre.belloni, linux,
linux-arm-kernel, linux-input, rtc-linux, devicetree
On Fri, May 22, 2015 at 10:36:33PM +0800, Frank.Li@freescale.com wrote:
> Frank Li (5):
> rtc: arm: imx: snvs: change use syscon to access register
> Document: dt: fsl: snvs: change support syscon
> arm: dts: imx: update snvs to use syscon access register
> document: devicetree: input: imx: i.mx snvs power device tree bindings
> arm: dts: imx6sx: enable snvs power key
>
> Robin Gong (1):
> input: keyboard: imx: add snvs power key driver
For patch subject prefix, I suggest you use some help from 'git log' to
find out what the best practice is for the files you are patching.
Shawn
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v4 4/6] input: keyboard: imx: add snvs power key driver
2015-05-22 14:36 ` [PATCH v4 4/6] input: keyboard: imx: add snvs power key driver Frank.Li
@ 2015-05-25 7:35 ` Shawn Guo
0 siblings, 0 replies; 14+ messages in thread
From: Shawn Guo @ 2015-05-25 7:35 UTC (permalink / raw)
To: Frank.Li
Cc: lznuaa, dmitry.torokhov, robh+dt, alexandre.belloni, linux,
linux-arm-kernel, linux-input, rtc-linux, devicetree, Robin Gong
On Fri, May 22, 2015 at 10:36:37PM +0800, Frank.Li@freescale.com wrote:
> +static int imx_snvs_pwrkey_probe(struct platform_device *pdev)
> +{
> + struct pwrkey_drv_data *pdata = NULL;
> + struct input_dev *input = NULL;
> + struct device_node *np, *snvs_np;
> + int error;
> +
> + /* Get SNVS register Page */
> + np = pdev->dev.of_node;
> + if (!np)
> + return -ENODEV;
> +
> + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
> + if (!pdata)
> + return -ENOMEM;
> +
> + snvs_np = of_get_parent(pdev->dev.of_node);
> + if (!snvs_np)
> + return -ENODEV;
> +
> + pdata->snvs = syscon_node_to_regmap(snvs_np);
Same here, I suggest you have a 'regmap' property and call
syscon_regmap_lookup_by_phandle() to get regmap.
Shawn
> + of_node_put(snvs_np);
> +
> + if (!pdata->snvs) {
> + pr_err("Can't get snvs syscon\n");
> + return -ENODEV;
> + }
> +
> + if (of_property_read_u32(np, "linux,keycode", &pdata->keycode)) {
> + pdata->keycode = KEY_POWER;
> + dev_warn(&pdev->dev, "KEY_POWER without setting in dts\n");
> + }
> +
> + pdata->wakeup = of_property_read_bool(np, "wakeup");
> +
> + pdata->irq = platform_get_irq(pdev, 0);
> + if (pdata->irq < 0) {
> + dev_err(&pdev->dev, "no irq defined in platform data\n");
> + return -EINVAL;
> + }
> +
> + regmap_update_bits(pdata->snvs, SNVS_LPCR_REG, SNVS_LPCR_DEP_EN, SNVS_LPCR_DEP_EN);
> +
> + /* clear the unexpected interrupt before driver ready */
> + regmap_write(pdata->snvs, SNVS_LPSR_REG, SNVS_LPSR_SPO);
> +
> + setup_timer(&pdata->check_timer,
> + imx_imx_snvs_check_for_events, (unsigned long) pdata);
> +
> + input = devm_input_allocate_device(&pdev->dev);
> + if (!input) {
> + dev_err(&pdev->dev, "failed to allocate the input device\n");
> + return -ENOMEM;
> + }
> +
> + input->name = pdev->name;
> + input->phys = "snvs-pwrkey/input0";
> + input->id.bustype = BUS_HOST;
> +
> + input_set_capability(input, EV_KEY, pdata->keycode);
> +
> + /* input customer action to cancel release timer */
> + error = devm_add_action(&pdev->dev, imx_snvs_pwrkey_act, pdata);
> + if (error) {
> + dev_err(&pdev->dev, "failed to register remove action\n");
> + return error;
> + }
> +
> + error = devm_request_irq(&pdev->dev, pdata->irq,
> + imx_snvs_pwrkey_interrupt,
> + 0, pdev->name, pdev);
> +
> + if (error) {
> + dev_err(&pdev->dev, "interrupt not available.\n");
> + return error;
> + }
> +
> + error = input_register_device(input);
> + if (error < 0) {
> + dev_err(&pdev->dev, "failed to register input device\n");
> + input_free_device(input);
> + return error;
> + }
> +
> + pdata->input = input;
> + platform_set_drvdata(pdev, pdata);
> +
> + device_init_wakeup(&pdev->dev, pdata->wakeup);
> +
> + return 0;
> +}
> +
> +static int imx_snvs_pwrkey_suspend(struct device *dev)
> +{
> + struct platform_device *pdev = to_platform_device(dev);
> + struct pwrkey_drv_data *pdata = platform_get_drvdata(pdev);
> +
> + if (device_may_wakeup(&pdev->dev))
> + enable_irq_wake(pdata->irq);
> +
> + return 0;
> +}
> +
> +static int imx_snvs_pwrkey_resume(struct device *dev)
> +{
> + struct platform_device *pdev = to_platform_device(dev);
> + struct pwrkey_drv_data *pdata = platform_get_drvdata(pdev);
> +
> + if (device_may_wakeup(&pdev->dev))
> + disable_irq_wake(pdata->irq);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id imx_snvs_pwrkey_ids[] = {
> + { .compatible = "fsl,sec-v4.0-pwrkey" },
> + { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, imx_snvs_pwrkey_ids);
> +
> +static SIMPLE_DEV_PM_OPS(imx_snvs_pwrkey_pm_ops, imx_snvs_pwrkey_suspend,
> + imx_snvs_pwrkey_resume);
> +
> +static struct platform_driver imx_snvs_pwrkey_driver = {
> + .driver = {
> + .name = "snvs_pwrkey",
> + .pm = &imx_snvs_pwrkey_pm_ops,
> + .of_match_table = imx_snvs_pwrkey_ids,
> + },
> + .probe = imx_snvs_pwrkey_probe,
> +};
> +module_platform_driver(imx_snvs_pwrkey_driver);
> +
> +MODULE_AUTHOR("Freescale Semiconductor");
> +MODULE_DESCRIPTION("i.MX snvs power key Driver");
> +MODULE_LICENSE("GPL");
> --
> 1.9.1
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v4 6/6] arm: dts: imx6sx: enable snvs power key
2015-05-22 14:36 ` [PATCH v4 6/6] arm: dts: imx6sx: enable snvs power key Frank.Li-KZfg59tc24xl57MIdRCFDg
@ 2015-05-25 7:39 ` Shawn Guo
0 siblings, 0 replies; 14+ messages in thread
From: Shawn Guo @ 2015-05-25 7:39 UTC (permalink / raw)
To: Frank.Li
Cc: lznuaa, dmitry.torokhov, robh+dt, alexandre.belloni, linux,
linux-arm-kernel, linux-input, rtc-linux, devicetree
On Fri, May 22, 2015 at 10:36:39PM +0800, Frank.Li@freescale.com wrote:
> From: Frank Li <Frank.Li@freescale.com>
>
> enable snvs ONOFF power key support
>
> Signed-off-by: Frank Li <Frank.Li@freescale.com>
Please use 'ARM: dts: imx6sx: ...' for the patch subject.
> ---
> arch/arm/boot/dts/imx6sx.dtsi | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
> index 3cb3b5b..ad38aea 100644
> --- a/arch/arm/boot/dts/imx6sx.dtsi
> +++ b/arch/arm/boot/dts/imx6sx.dtsi
> @@ -677,6 +677,13 @@
> mask = <0x60>;
> status = "disabled";
> };
> +
> + snvs_pwrkey: snvs-powerkey {
> + compatible = "fsl,sec-v4.0-pwrkey";
> + interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
> + linux,keycode = <116>; /* KEY_POWER */
With include/dt-bindings/input/input.h, you can use KEY_POWER directly
and save the comment.
Shawn
> + wakeup;
> + };
> };
>
> epit1: epit@020d0000 {
> --
> 1.9.1
>
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2015-05-25 7:39 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-22 14:36 [PATCH v4 0/6] Change snvs rtc and poweroff to use syscon add pwrkey driver Frank.Li
2015-05-22 14:36 ` [PATCH v4 1/6] rtc: arm: imx: snvs: change use syscon to access register Frank.Li
2015-05-25 6:18 ` Shawn Guo
2015-05-25 6:44 ` Shawn Guo
2015-05-22 14:36 ` [PATCH v4 2/6] Document: dt: fsl: snvs: change support syscon Frank.Li
2015-05-25 6:26 ` Shawn Guo
2015-05-22 14:36 ` [PATCH v4 3/6] arm: dts: imx: update snvs to use syscon access register Frank.Li
2015-05-25 6:39 ` Shawn Guo
2015-05-22 14:36 ` [PATCH v4 4/6] input: keyboard: imx: add snvs power key driver Frank.Li
2015-05-25 7:35 ` Shawn Guo
2015-05-22 14:36 ` [PATCH v4 5/6] document: devicetree: input: imx: i.mx snvs power device tree bindings Frank.Li
[not found] ` <1432305399-30571-1-git-send-email-Frank.Li-KZfg59tc24xl57MIdRCFDg@public.gmane.org>
2015-05-22 14:36 ` [PATCH v4 6/6] arm: dts: imx6sx: enable snvs power key Frank.Li-KZfg59tc24xl57MIdRCFDg
2015-05-25 7:39 ` Shawn Guo
2015-05-25 6:47 ` [PATCH v4 0/6] Change snvs rtc and poweroff to use syscon add pwrkey driver Shawn Guo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).