All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/8] Atmel System Timer cleanups
@ 2015-01-09  9:51 ` Alexandre Belloni
  0 siblings, 0 replies; 26+ messages in thread
From: Alexandre Belloni @ 2015-01-09  9:51 UTC (permalink / raw)
  To: Nicolas Ferre
  Cc: Boris Brezillon, Jean-Christophe Plagniol-Villard,
	Daniel Lezcano, Thomas Gleixner, Samuel Ortiz, Lee Jones,
	Wim Van Sebroeck, linux-kernel, linux-arm-kernel, linux-watchdog,
	Alexandre Belloni

This patch sets cleans up the system timer driver.

The main goal is to get rid of the mach/ headers dependency. At the same time,
it introduces proper probing and locking (using a regmap) for the watchdog
driver.

Changes in v2:
 - cleaned up more includes in the watchdog driver
 - stop using if OF when selecting CLKSRC_OF
 - stop initializing .owner

Alexandre Belloni (8):
  ARM: at91/dt: declare atmel,at91rm9200-st as a syscon
  mfd: Add atmel-st driver
  watchdog: at91rm9200: use the regmap from mfd
  ARM: at91: time: move the system timer driver to drivers/clocksource
  ARM: at91: move the restart function to the system timer driver
  clocksource: atmel-st: properly initialize driver
  clocksource: atmel-st: use syscon/regmap
  ARM: at91: remove useless include

 .../devicetree/bindings/arm/atmel-at91.txt         |   2 +-
 arch/arm/boot/dts/at91rm9200.dtsi                  |   2 +-
 arch/arm/mach-at91/Makefile                        |   2 +-
 arch/arm/mach-at91/at91rm9200.c                    |  11 ---
 arch/arm/mach-at91/board-dt-rm9200.c               |   7 --
 arch/arm/mach-at91/generic.h                       |   3 -
 drivers/clocksource/Kconfig                        |   4 +
 drivers/clocksource/Makefile                       |   1 +
 .../clocksource/timer-atmel-st.c                   | 109 +++++++++------------
 drivers/mfd/Kconfig                                |   7 ++
 drivers/mfd/Makefile                               |   1 +
 drivers/mfd/atmel-st.c                             |  76 ++++++++++++++
 drivers/watchdog/Kconfig                           |   2 +-
 drivers/watchdog/at91rm9200_wdt.c                  |  27 ++---
 .../mach/at91_st.h => include/linux/mfd/atmel-st.h |  20 +---
 15 files changed, 154 insertions(+), 120 deletions(-)
 rename arch/arm/mach-at91/at91rm9200_time.c => drivers/clocksource/timer-atmel-st.c (74%)
 create mode 100644 drivers/mfd/atmel-st.c
 rename arch/arm/mach-at91/include/mach/at91_st.h => include/linux/mfd/atmel-st.h (84%)

-- 
2.1.0


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 0/8] Atmel System Timer cleanups
@ 2015-01-09  9:51 ` Alexandre Belloni
  0 siblings, 0 replies; 26+ messages in thread
From: Alexandre Belloni @ 2015-01-09  9:51 UTC (permalink / raw)
  To: linux-arm-kernel

This patch sets cleans up the system timer driver.

The main goal is to get rid of the mach/ headers dependency. At the same time,
it introduces proper probing and locking (using a regmap) for the watchdog
driver.

Changes in v2:
 - cleaned up more includes in the watchdog driver
 - stop using if OF when selecting CLKSRC_OF
 - stop initializing .owner

Alexandre Belloni (8):
  ARM: at91/dt: declare atmel,at91rm9200-st as a syscon
  mfd: Add atmel-st driver
  watchdog: at91rm9200: use the regmap from mfd
  ARM: at91: time: move the system timer driver to drivers/clocksource
  ARM: at91: move the restart function to the system timer driver
  clocksource: atmel-st: properly initialize driver
  clocksource: atmel-st: use syscon/regmap
  ARM: at91: remove useless include

 .../devicetree/bindings/arm/atmel-at91.txt         |   2 +-
 arch/arm/boot/dts/at91rm9200.dtsi                  |   2 +-
 arch/arm/mach-at91/Makefile                        |   2 +-
 arch/arm/mach-at91/at91rm9200.c                    |  11 ---
 arch/arm/mach-at91/board-dt-rm9200.c               |   7 --
 arch/arm/mach-at91/generic.h                       |   3 -
 drivers/clocksource/Kconfig                        |   4 +
 drivers/clocksource/Makefile                       |   1 +
 .../clocksource/timer-atmel-st.c                   | 109 +++++++++------------
 drivers/mfd/Kconfig                                |   7 ++
 drivers/mfd/Makefile                               |   1 +
 drivers/mfd/atmel-st.c                             |  76 ++++++++++++++
 drivers/watchdog/Kconfig                           |   2 +-
 drivers/watchdog/at91rm9200_wdt.c                  |  27 ++---
 .../mach/at91_st.h => include/linux/mfd/atmel-st.h |  20 +---
 15 files changed, 154 insertions(+), 120 deletions(-)
 rename arch/arm/mach-at91/at91rm9200_time.c => drivers/clocksource/timer-atmel-st.c (74%)
 create mode 100644 drivers/mfd/atmel-st.c
 rename arch/arm/mach-at91/include/mach/at91_st.h => include/linux/mfd/atmel-st.h (84%)

-- 
2.1.0

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 1/8] ARM: at91/dt: declare atmel,at91rm9200-st as a syscon
  2015-01-09  9:51 ` Alexandre Belloni
@ 2015-01-09  9:51   ` Alexandre Belloni
  -1 siblings, 0 replies; 26+ messages in thread
From: Alexandre Belloni @ 2015-01-09  9:51 UTC (permalink / raw)
  To: Nicolas Ferre
  Cc: Boris Brezillon, Jean-Christophe Plagniol-Villard,
	Daniel Lezcano, Thomas Gleixner, Samuel Ortiz, Lee Jones,
	Wim Van Sebroeck, linux-kernel, linux-arm-kernel, linux-watchdog,
	Alexandre Belloni

The system timer register range is also used for the watchdog. Declare it as a
syscon to be able to get a regmap early enough in the boot process

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 Documentation/devicetree/bindings/arm/atmel-at91.txt | 2 +-
 arch/arm/boot/dts/at91rm9200.dtsi                    | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.txt b/Documentation/devicetree/bindings/arm/atmel-at91.txt
index 562cda9d86d9..938592a3c4e2 100644
--- a/Documentation/devicetree/bindings/arm/atmel-at91.txt
+++ b/Documentation/devicetree/bindings/arm/atmel-at91.txt
@@ -45,7 +45,7 @@ PIT Timer required properties:
   shared across all System Controller members.
 
 System Timer (ST) required properties:
-- compatible: Should be "atmel,at91rm9200-st"
+- compatible: Should be "atmel,at91rm9200-st", "syscon"
 - reg: Should contain registers location and length
 - interrupts: Should contain interrupt for the ST which is the IRQ line
   shared across all System Controller members.
diff --git a/arch/arm/boot/dts/at91rm9200.dtsi b/arch/arm/boot/dts/at91rm9200.dtsi
index 6c97d4af61ee..f77b15c0b1d1 100644
--- a/arch/arm/boot/dts/at91rm9200.dtsi
+++ b/arch/arm/boot/dts/at91rm9200.dtsi
@@ -351,7 +351,7 @@
 			};
 
 			st: timer@fffffd00 {
-				compatible = "atmel,at91rm9200-st";
+				compatible = "atmel,at91rm9200-st", "syscon";
 				reg = <0xfffffd00 0x100>;
 				interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
 			};
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 1/8] ARM: at91/dt: declare atmel,at91rm9200-st as a syscon
@ 2015-01-09  9:51   ` Alexandre Belloni
  0 siblings, 0 replies; 26+ messages in thread
From: Alexandre Belloni @ 2015-01-09  9:51 UTC (permalink / raw)
  To: linux-arm-kernel

The system timer register range is also used for the watchdog. Declare it as a
syscon to be able to get a regmap early enough in the boot process

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 Documentation/devicetree/bindings/arm/atmel-at91.txt | 2 +-
 arch/arm/boot/dts/at91rm9200.dtsi                    | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.txt b/Documentation/devicetree/bindings/arm/atmel-at91.txt
index 562cda9d86d9..938592a3c4e2 100644
--- a/Documentation/devicetree/bindings/arm/atmel-at91.txt
+++ b/Documentation/devicetree/bindings/arm/atmel-at91.txt
@@ -45,7 +45,7 @@ PIT Timer required properties:
   shared across all System Controller members.
 
 System Timer (ST) required properties:
-- compatible: Should be "atmel,at91rm9200-st"
+- compatible: Should be "atmel,at91rm9200-st", "syscon"
 - reg: Should contain registers location and length
 - interrupts: Should contain interrupt for the ST which is the IRQ line
   shared across all System Controller members.
diff --git a/arch/arm/boot/dts/at91rm9200.dtsi b/arch/arm/boot/dts/at91rm9200.dtsi
index 6c97d4af61ee..f77b15c0b1d1 100644
--- a/arch/arm/boot/dts/at91rm9200.dtsi
+++ b/arch/arm/boot/dts/at91rm9200.dtsi
@@ -351,7 +351,7 @@
 			};
 
 			st: timer at fffffd00 {
-				compatible = "atmel,at91rm9200-st";
+				compatible = "atmel,at91rm9200-st", "syscon";
 				reg = <0xfffffd00 0x100>;
 				interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
 			};
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 2/8] mfd: Add atmel-st driver
  2015-01-09  9:51 ` Alexandre Belloni
@ 2015-01-09  9:51   ` Alexandre Belloni
  -1 siblings, 0 replies; 26+ messages in thread
From: Alexandre Belloni @ 2015-01-09  9:51 UTC (permalink / raw)
  To: Nicolas Ferre
  Cc: Boris Brezillon, Jean-Christophe Plagniol-Villard,
	Daniel Lezcano, Thomas Gleixner, Samuel Ortiz, Lee Jones,
	Wim Van Sebroeck, linux-kernel, linux-arm-kernel, linux-watchdog,
	Alexandre Belloni

The Atmel System Timer IP available on the at91rm9200 exposes both a timer and a
watchdog.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 drivers/mfd/Kconfig          |  7 ++++
 drivers/mfd/Makefile         |  1 +
 drivers/mfd/atmel-st.c       | 76 ++++++++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/atmel-st.h | 47 +++++++++++++++++++++++++++
 4 files changed, 131 insertions(+)
 create mode 100644 drivers/mfd/atmel-st.c
 create mode 100644 include/linux/mfd/atmel-st.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 2e6b7311fabc..3c5185c0cf06 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -78,6 +78,13 @@ config MFD_BCM590XX
 	help
 	  Support for the BCM590xx PMUs from Broadcom
 
+config MFD_ATMEL_ST
+	bool "Atmel System Timer"
+	select MFD_CORE
+	default SOC_AT91RM9200
+	help
+	  If you say Y here you get support for the Atmel System Timer.
+
 config MFD_AXP20X
 	bool "X-Powers AXP20X"
 	select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 53467e211381..1ecd416f25c5 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -104,6 +104,7 @@ obj-$(CONFIG_PMIC_DA9052)	+= da9052-core.o
 obj-$(CONFIG_MFD_DA9052_SPI)	+= da9052-spi.o
 obj-$(CONFIG_MFD_DA9052_I2C)	+= da9052-i2c.o
 obj-$(CONFIG_MFD_AXP20X)	+= axp20x.o
+obj-$(CONFIG_MFD_ATMEL_ST)	+= atmel-st.o
 
 obj-$(CONFIG_MFD_LP3943)	+= lp3943.o
 obj-$(CONFIG_MFD_LP8788)	+= lp8788.o lp8788-irq.o
diff --git a/drivers/mfd/atmel-st.c b/drivers/mfd/atmel-st.c
new file mode 100644
index 000000000000..5af83cbfe404
--- /dev/null
+++ b/drivers/mfd/atmel-st.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2014 Free Electrons
+ * Copyright (C) 2014 Atmel
+ *
+ * Author: Alexandre Belloni <alexandre.belloni@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.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/mfd/atmel-st.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+static const struct mfd_cell atmel_st_cells[] = {
+	{
+		.name = "atmel_st_timer",
+	},
+	{
+		.name = "atmel_st_watchdog",
+	},
+};
+
+static int atmel_st_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct regmap *regmap_st;
+
+	regmap_st = syscon_node_to_regmap(dev->of_node);
+	if (IS_ERR(regmap_st))
+		return PTR_ERR(regmap_st);
+	dev_set_drvdata(dev, regmap_st);
+
+	return mfd_add_devices(dev, -1, atmel_st_cells,
+			       ARRAY_SIZE(atmel_st_cells),
+			       NULL, 0, NULL);
+}
+
+static int atmel_st_remove(struct platform_device *pdev)
+{
+	mfd_remove_devices(&pdev->dev);
+
+	return 0;
+}
+
+static const struct of_device_id atmel_st_match[] = {
+	{ .compatible = "atmel,at91rm9200-st" },
+	{ /* sentinel */ },
+};
+
+static struct platform_driver atmel_st_driver = {
+	.probe = atmel_st_probe,
+	.remove = atmel_st_remove,
+	.driver = {
+		.name = "atmel-system-timer",
+		.of_match_table = atmel_st_match,
+	},
+};
+module_platform_driver(atmel_st_driver);
+
+MODULE_ALIAS("platform:atmel-st");
+MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@free-electrons.com>");
+MODULE_DESCRIPTION("Atmel ST (System Timer) driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/atmel-st.h b/include/linux/mfd/atmel-st.h
new file mode 100644
index 000000000000..88c6cf8eeb2b
--- /dev/null
+++ b/include/linux/mfd/atmel-st.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2005 Ivan Kokshaysky
+ * Copyright (C) SAN People
+ *
+ * System Timer (ST) - System peripherals registers.
+ * Based on AT91RM9200 datasheet revision E.
+ *
+ * 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.
+ */
+
+#ifndef __LINUX_MFD_ATMEL_ST_H
+#define __LINUX_MFD_ATMEL_ST_H
+
+#define	AT91_ST_CR		0x00			/* Control Register */
+#define 	AT91_ST_WDRST		(1 << 0)		/* Watchdog Timer Restart */
+
+#define	AT91_ST_PIMR		0x04			/* Period Interval Mode Register */
+#define		AT91_ST_PIV		(0xffff <<  0)		/* Period Interval Value */
+
+#define	AT91_ST_WDMR		0x08			/* Watchdog Mode Register */
+#define		AT91_ST_WDV		(0xffff <<  0)		/* Watchdog Counter Value */
+#define		AT91_ST_RSTEN		(1	<< 16)		/* Reset Enable */
+#define		AT91_ST_EXTEN		(1	<< 17)		/* External Signal Assertion Enable */
+
+#define	AT91_ST_RTMR		0x0c			/* Real-time Mode Register */
+#define		AT91_ST_RTPRES		(0xffff <<  0)		/* Real-time Prescalar Value */
+
+#define	AT91_ST_SR		0x10			/* Status Register */
+#define		AT91_ST_PITS		(1 << 0)		/* Period Interval Timer Status */
+#define		AT91_ST_WDOVF		(1 << 1) 		/* Watchdog Overflow */
+#define		AT91_ST_RTTINC		(1 << 2) 		/* Real-time Timer Increment */
+#define		AT91_ST_ALMS		(1 << 3) 		/* Alarm Status */
+
+#define	AT91_ST_IER		0x14			/* Interrupt Enable Register */
+#define	AT91_ST_IDR		0x18			/* Interrupt Disable Register */
+#define	AT91_ST_IMR		0x1c			/* Interrupt Mask Register */
+
+#define	AT91_ST_RTAR		0x20			/* Real-time Alarm Register */
+#define		AT91_ST_ALMV		(0xfffff << 0)		/* Alarm Value */
+
+#define	AT91_ST_CRTR		0x24			/* Current Real-time Register */
+#define		AT91_ST_CRTV		(0xfffff << 0)		/* Current Real-Time Value */
+
+#endif /* __LINUX_MFD_ATMEL_ST_H */
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 2/8] mfd: Add atmel-st driver
@ 2015-01-09  9:51   ` Alexandre Belloni
  0 siblings, 0 replies; 26+ messages in thread
From: Alexandre Belloni @ 2015-01-09  9:51 UTC (permalink / raw)
  To: linux-arm-kernel

The Atmel System Timer IP available on the at91rm9200 exposes both a timer and a
watchdog.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 drivers/mfd/Kconfig          |  7 ++++
 drivers/mfd/Makefile         |  1 +
 drivers/mfd/atmel-st.c       | 76 ++++++++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/atmel-st.h | 47 +++++++++++++++++++++++++++
 4 files changed, 131 insertions(+)
 create mode 100644 drivers/mfd/atmel-st.c
 create mode 100644 include/linux/mfd/atmel-st.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 2e6b7311fabc..3c5185c0cf06 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -78,6 +78,13 @@ config MFD_BCM590XX
 	help
 	  Support for the BCM590xx PMUs from Broadcom
 
+config MFD_ATMEL_ST
+	bool "Atmel System Timer"
+	select MFD_CORE
+	default SOC_AT91RM9200
+	help
+	  If you say Y here you get support for the Atmel System Timer.
+
 config MFD_AXP20X
 	bool "X-Powers AXP20X"
 	select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 53467e211381..1ecd416f25c5 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -104,6 +104,7 @@ obj-$(CONFIG_PMIC_DA9052)	+= da9052-core.o
 obj-$(CONFIG_MFD_DA9052_SPI)	+= da9052-spi.o
 obj-$(CONFIG_MFD_DA9052_I2C)	+= da9052-i2c.o
 obj-$(CONFIG_MFD_AXP20X)	+= axp20x.o
+obj-$(CONFIG_MFD_ATMEL_ST)	+= atmel-st.o
 
 obj-$(CONFIG_MFD_LP3943)	+= lp3943.o
 obj-$(CONFIG_MFD_LP8788)	+= lp8788.o lp8788-irq.o
diff --git a/drivers/mfd/atmel-st.c b/drivers/mfd/atmel-st.c
new file mode 100644
index 000000000000..5af83cbfe404
--- /dev/null
+++ b/drivers/mfd/atmel-st.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2014 Free Electrons
+ * Copyright (C) 2014 Atmel
+ *
+ * Author: Alexandre Belloni <alexandre.belloni@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.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/mfd/atmel-st.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+static const struct mfd_cell atmel_st_cells[] = {
+	{
+		.name = "atmel_st_timer",
+	},
+	{
+		.name = "atmel_st_watchdog",
+	},
+};
+
+static int atmel_st_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct regmap *regmap_st;
+
+	regmap_st = syscon_node_to_regmap(dev->of_node);
+	if (IS_ERR(regmap_st))
+		return PTR_ERR(regmap_st);
+	dev_set_drvdata(dev, regmap_st);
+
+	return mfd_add_devices(dev, -1, atmel_st_cells,
+			       ARRAY_SIZE(atmel_st_cells),
+			       NULL, 0, NULL);
+}
+
+static int atmel_st_remove(struct platform_device *pdev)
+{
+	mfd_remove_devices(&pdev->dev);
+
+	return 0;
+}
+
+static const struct of_device_id atmel_st_match[] = {
+	{ .compatible = "atmel,at91rm9200-st" },
+	{ /* sentinel */ },
+};
+
+static struct platform_driver atmel_st_driver = {
+	.probe = atmel_st_probe,
+	.remove = atmel_st_remove,
+	.driver = {
+		.name = "atmel-system-timer",
+		.of_match_table = atmel_st_match,
+	},
+};
+module_platform_driver(atmel_st_driver);
+
+MODULE_ALIAS("platform:atmel-st");
+MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@free-electrons.com>");
+MODULE_DESCRIPTION("Atmel ST (System Timer) driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/atmel-st.h b/include/linux/mfd/atmel-st.h
new file mode 100644
index 000000000000..88c6cf8eeb2b
--- /dev/null
+++ b/include/linux/mfd/atmel-st.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2005 Ivan Kokshaysky
+ * Copyright (C) SAN People
+ *
+ * System Timer (ST) - System peripherals registers.
+ * Based on AT91RM9200 datasheet revision E.
+ *
+ * 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.
+ */
+
+#ifndef __LINUX_MFD_ATMEL_ST_H
+#define __LINUX_MFD_ATMEL_ST_H
+
+#define	AT91_ST_CR		0x00			/* Control Register */
+#define 	AT91_ST_WDRST		(1 << 0)		/* Watchdog Timer Restart */
+
+#define	AT91_ST_PIMR		0x04			/* Period Interval Mode Register */
+#define		AT91_ST_PIV		(0xffff <<  0)		/* Period Interval Value */
+
+#define	AT91_ST_WDMR		0x08			/* Watchdog Mode Register */
+#define		AT91_ST_WDV		(0xffff <<  0)		/* Watchdog Counter Value */
+#define		AT91_ST_RSTEN		(1	<< 16)		/* Reset Enable */
+#define		AT91_ST_EXTEN		(1	<< 17)		/* External Signal Assertion Enable */
+
+#define	AT91_ST_RTMR		0x0c			/* Real-time Mode Register */
+#define		AT91_ST_RTPRES		(0xffff <<  0)		/* Real-time Prescalar Value */
+
+#define	AT91_ST_SR		0x10			/* Status Register */
+#define		AT91_ST_PITS		(1 << 0)		/* Period Interval Timer Status */
+#define		AT91_ST_WDOVF		(1 << 1) 		/* Watchdog Overflow */
+#define		AT91_ST_RTTINC		(1 << 2) 		/* Real-time Timer Increment */
+#define		AT91_ST_ALMS		(1 << 3) 		/* Alarm Status */
+
+#define	AT91_ST_IER		0x14			/* Interrupt Enable Register */
+#define	AT91_ST_IDR		0x18			/* Interrupt Disable Register */
+#define	AT91_ST_IMR		0x1c			/* Interrupt Mask Register */
+
+#define	AT91_ST_RTAR		0x20			/* Real-time Alarm Register */
+#define		AT91_ST_ALMV		(0xfffff << 0)		/* Alarm Value */
+
+#define	AT91_ST_CRTR		0x24			/* Current Real-time Register */
+#define		AT91_ST_CRTV		(0xfffff << 0)		/* Current Real-Time Value */
+
+#endif /* __LINUX_MFD_ATMEL_ST_H */
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 3/8] watchdog: at91rm9200: use the regmap from mfd
  2015-01-09  9:51 ` Alexandre Belloni
@ 2015-01-09  9:51   ` Alexandre Belloni
  -1 siblings, 0 replies; 26+ messages in thread
From: Alexandre Belloni @ 2015-01-09  9:51 UTC (permalink / raw)
  To: Nicolas Ferre
  Cc: Boris Brezillon, Jean-Christophe Plagniol-Villard,
	Daniel Lezcano, Thomas Gleixner, Samuel Ortiz, Lee Jones,
	Wim Van Sebroeck, linux-kernel, linux-arm-kernel, linux-watchdog,
	Alexandre Belloni

The system timer MFD driver is providing a regmap. Use it to access the
registers.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 drivers/watchdog/Kconfig          |  2 +-
 drivers/watchdog/at91rm9200_wdt.c | 27 +++++++++------------------
 2 files changed, 10 insertions(+), 19 deletions(-)

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 08f41add1461..18c73bc159fc 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -154,7 +154,7 @@ config ARM_SP805_WATCHDOG
 
 config AT91RM9200_WATCHDOG
 	tristate "AT91RM9200 watchdog"
-	depends on SOC_AT91RM9200
+	depends on SOC_AT91RM9200 && MFD_ATMEL_ST
 	help
 	  Watchdog timer embedded into AT91RM9200 chips. This will reboot your
 	  system when the timeout is reached.
diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c
index d244112d5b6f..a493fe4b0dfc 100644
--- a/drivers/watchdog/at91rm9200_wdt.c
+++ b/drivers/watchdog/at91rm9200_wdt.c
@@ -14,25 +14,22 @@
 #include <linux/bitops.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
-#include <linux/init.h>
-#include <linux/io.h>
 #include <linux/kernel.h>
+#include <linux/mfd/atmel-st.h>
 #include <linux/miscdevice.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/platform_device.h>
-#include <linux/types.h>
+#include <linux/regmap.h>
 #include <linux/watchdog.h>
 #include <linux/uaccess.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <mach/at91_st.h>
 
 #define WDT_DEFAULT_TIME	5	/* seconds */
 #define WDT_MAX_TIME		256	/* seconds */
 
 static int wdt_time = WDT_DEFAULT_TIME;
 static bool nowayout = WATCHDOG_NOWAYOUT;
+static struct regmap *regmap_st;
 
 module_param(wdt_time, int, 0);
 MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="
@@ -55,7 +52,7 @@ static unsigned long at91wdt_busy;
  */
 static inline void at91_wdt_stop(void)
 {
-	at91_st_write(AT91_ST_WDMR, AT91_ST_EXTEN);
+	regmap_write(regmap_st, AT91_ST_WDMR, AT91_ST_EXTEN);
 }
 
 /*
@@ -63,9 +60,9 @@ static inline void at91_wdt_stop(void)
  */
 static inline void at91_wdt_start(void)
 {
-	at91_st_write(AT91_ST_WDMR, AT91_ST_EXTEN | AT91_ST_RSTEN |
+	regmap_write(regmap_st, AT91_ST_WDMR, AT91_ST_EXTEN | AT91_ST_RSTEN |
 				(((65536 * wdt_time) >> 8) & AT91_ST_WDV));
-	at91_st_write(AT91_ST_CR, AT91_ST_WDRST);
+	regmap_write(regmap_st, AT91_ST_CR, AT91_ST_WDRST);
 }
 
 /*
@@ -73,7 +70,7 @@ static inline void at91_wdt_start(void)
  */
 static inline void at91_wdt_reload(void)
 {
-	at91_st_write(AT91_ST_CR, AT91_ST_WDRST);
+	regmap_write(regmap_st, AT91_ST_CR, AT91_ST_WDRST);
 }
 
 /* ......................................................................... */
@@ -204,6 +201,7 @@ static struct miscdevice at91wdt_miscdev = {
 static int at91wdt_probe(struct platform_device *pdev)
 {
 	int res;
+	regmap_st = dev_get_drvdata(pdev->dev.parent);
 
 	if (at91wdt_miscdev.parent)
 		return -EBUSY;
@@ -254,12 +252,6 @@ static int at91wdt_resume(struct platform_device *pdev)
 #define at91wdt_resume	NULL
 #endif
 
-static const struct of_device_id at91_wdt_dt_ids[] = {
-	{ .compatible = "atmel,at91rm9200-wdt" },
-	{ /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, at91_wdt_dt_ids);
-
 static struct platform_driver at91wdt_driver = {
 	.probe		= at91wdt_probe,
 	.remove		= at91wdt_remove,
@@ -267,8 +259,7 @@ static struct platform_driver at91wdt_driver = {
 	.suspend	= at91wdt_suspend,
 	.resume		= at91wdt_resume,
 	.driver		= {
-		.name	= "at91_wdt",
-		.of_match_table = at91_wdt_dt_ids,
+		.name	= "atmel_st_watchdog",
 	},
 };
 
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 3/8] watchdog: at91rm9200: use the regmap from mfd
@ 2015-01-09  9:51   ` Alexandre Belloni
  0 siblings, 0 replies; 26+ messages in thread
From: Alexandre Belloni @ 2015-01-09  9:51 UTC (permalink / raw)
  To: linux-arm-kernel

The system timer MFD driver is providing a regmap. Use it to access the
registers.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 drivers/watchdog/Kconfig          |  2 +-
 drivers/watchdog/at91rm9200_wdt.c | 27 +++++++++------------------
 2 files changed, 10 insertions(+), 19 deletions(-)

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 08f41add1461..18c73bc159fc 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -154,7 +154,7 @@ config ARM_SP805_WATCHDOG
 
 config AT91RM9200_WATCHDOG
 	tristate "AT91RM9200 watchdog"
-	depends on SOC_AT91RM9200
+	depends on SOC_AT91RM9200 && MFD_ATMEL_ST
 	help
 	  Watchdog timer embedded into AT91RM9200 chips. This will reboot your
 	  system when the timeout is reached.
diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c
index d244112d5b6f..a493fe4b0dfc 100644
--- a/drivers/watchdog/at91rm9200_wdt.c
+++ b/drivers/watchdog/at91rm9200_wdt.c
@@ -14,25 +14,22 @@
 #include <linux/bitops.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
-#include <linux/init.h>
-#include <linux/io.h>
 #include <linux/kernel.h>
+#include <linux/mfd/atmel-st.h>
 #include <linux/miscdevice.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/platform_device.h>
-#include <linux/types.h>
+#include <linux/regmap.h>
 #include <linux/watchdog.h>
 #include <linux/uaccess.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <mach/at91_st.h>
 
 #define WDT_DEFAULT_TIME	5	/* seconds */
 #define WDT_MAX_TIME		256	/* seconds */
 
 static int wdt_time = WDT_DEFAULT_TIME;
 static bool nowayout = WATCHDOG_NOWAYOUT;
+static struct regmap *regmap_st;
 
 module_param(wdt_time, int, 0);
 MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="
@@ -55,7 +52,7 @@ static unsigned long at91wdt_busy;
  */
 static inline void at91_wdt_stop(void)
 {
-	at91_st_write(AT91_ST_WDMR, AT91_ST_EXTEN);
+	regmap_write(regmap_st, AT91_ST_WDMR, AT91_ST_EXTEN);
 }
 
 /*
@@ -63,9 +60,9 @@ static inline void at91_wdt_stop(void)
  */
 static inline void at91_wdt_start(void)
 {
-	at91_st_write(AT91_ST_WDMR, AT91_ST_EXTEN | AT91_ST_RSTEN |
+	regmap_write(regmap_st, AT91_ST_WDMR, AT91_ST_EXTEN | AT91_ST_RSTEN |
 				(((65536 * wdt_time) >> 8) & AT91_ST_WDV));
-	at91_st_write(AT91_ST_CR, AT91_ST_WDRST);
+	regmap_write(regmap_st, AT91_ST_CR, AT91_ST_WDRST);
 }
 
 /*
@@ -73,7 +70,7 @@ static inline void at91_wdt_start(void)
  */
 static inline void at91_wdt_reload(void)
 {
-	at91_st_write(AT91_ST_CR, AT91_ST_WDRST);
+	regmap_write(regmap_st, AT91_ST_CR, AT91_ST_WDRST);
 }
 
 /* ......................................................................... */
@@ -204,6 +201,7 @@ static struct miscdevice at91wdt_miscdev = {
 static int at91wdt_probe(struct platform_device *pdev)
 {
 	int res;
+	regmap_st = dev_get_drvdata(pdev->dev.parent);
 
 	if (at91wdt_miscdev.parent)
 		return -EBUSY;
@@ -254,12 +252,6 @@ static int at91wdt_resume(struct platform_device *pdev)
 #define at91wdt_resume	NULL
 #endif
 
-static const struct of_device_id at91_wdt_dt_ids[] = {
-	{ .compatible = "atmel,at91rm9200-wdt" },
-	{ /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, at91_wdt_dt_ids);
-
 static struct platform_driver at91wdt_driver = {
 	.probe		= at91wdt_probe,
 	.remove		= at91wdt_remove,
@@ -267,8 +259,7 @@ static struct platform_driver at91wdt_driver = {
 	.suspend	= at91wdt_suspend,
 	.resume		= at91wdt_resume,
 	.driver		= {
-		.name	= "at91_wdt",
-		.of_match_table = at91_wdt_dt_ids,
+		.name	= "atmel_st_watchdog",
 	},
 };
 
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 4/8] ARM: at91: time: move the system timer driver to drivers/clocksource
  2015-01-09  9:51 ` Alexandre Belloni
@ 2015-01-09  9:51   ` Alexandre Belloni
  -1 siblings, 0 replies; 26+ messages in thread
From: Alexandre Belloni @ 2015-01-09  9:51 UTC (permalink / raw)
  To: Nicolas Ferre
  Cc: Boris Brezillon, Jean-Christophe Plagniol-Villard,
	Daniel Lezcano, Thomas Gleixner, Samuel Ortiz, Lee Jones,
	Wim Van Sebroeck, linux-kernel, linux-arm-kernel, linux-watchdog,
	Alexandre Belloni

Import at91rm9200_time.c from mach-at91 as timer-atmel-st.c. Further cleanup is
required to get rid of the mach-at91 headers.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/Makefile                                           | 2 +-
 drivers/clocksource/Kconfig                                           | 4 ++++
 drivers/clocksource/Makefile                                          | 1 +
 .../at91rm9200_time.c => drivers/clocksource/timer-atmel-st.c         | 0
 4 files changed, 6 insertions(+), 1 deletion(-)
 rename arch/arm/mach-at91/at91rm9200_time.c => drivers/clocksource/timer-atmel-st.c (100%)

diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index 7b6424d40764..5d1ee3a6f115 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -7,7 +7,7 @@ obj-y		:= setup.o sysirq_mask.o
 obj-$(CONFIG_SOC_AT91SAM9)	+= sam9_smc.o
 
 # CPU-specific support
-obj-$(CONFIG_SOC_AT91RM9200)	+= at91rm9200.o at91rm9200_time.o
+obj-$(CONFIG_SOC_AT91RM9200)	+= at91rm9200.o
 obj-$(CONFIG_SOC_AT91SAM9260)	+= at91sam9260.o
 obj-$(CONFIG_SOC_AT91SAM9261)	+= at91sam9261.o
 obj-$(CONFIG_SOC_AT91SAM9263)	+= at91sam9263.o
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index fc01ec27d3c8..f550f16a176d 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -128,6 +128,10 @@ config ATMEL_PIT
 	select CLKSRC_OF if OF
 	def_bool SOC_AT91SAM9 || SOC_SAMA5
 
+config ATMEL_ST
+	select CLKSRC_OF
+	def_bool SOC_AT91RM9200
+
 config CLKSRC_METAG_GENERIC
 	def_bool y if METAG
 	help
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 94d90b24b56b..b7380ded4e4c 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -1,5 +1,6 @@
 obj-$(CONFIG_CLKSRC_OF)	+= clksrc-of.o
 obj-$(CONFIG_ATMEL_PIT)		+= timer-atmel-pit.o
+obj-$(CONFIG_ATMEL_ST)		+= timer-atmel-st.o
 obj-$(CONFIG_ATMEL_TCB_CLKSRC)	+= tcb_clksrc.o
 obj-$(CONFIG_X86_PM_TIMER)	+= acpi_pm.o
 obj-$(CONFIG_SCx200HR_TIMER)	+= scx200_hrt.o
diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/drivers/clocksource/timer-atmel-st.c
similarity index 100%
rename from arch/arm/mach-at91/at91rm9200_time.c
rename to drivers/clocksource/timer-atmel-st.c
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 4/8] ARM: at91: time: move the system timer driver to drivers/clocksource
@ 2015-01-09  9:51   ` Alexandre Belloni
  0 siblings, 0 replies; 26+ messages in thread
From: Alexandre Belloni @ 2015-01-09  9:51 UTC (permalink / raw)
  To: linux-arm-kernel

Import at91rm9200_time.c from mach-at91 as timer-atmel-st.c. Further cleanup is
required to get rid of the mach-at91 headers.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/Makefile                                           | 2 +-
 drivers/clocksource/Kconfig                                           | 4 ++++
 drivers/clocksource/Makefile                                          | 1 +
 .../at91rm9200_time.c => drivers/clocksource/timer-atmel-st.c         | 0
 4 files changed, 6 insertions(+), 1 deletion(-)
 rename arch/arm/mach-at91/at91rm9200_time.c => drivers/clocksource/timer-atmel-st.c (100%)

diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index 7b6424d40764..5d1ee3a6f115 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -7,7 +7,7 @@ obj-y		:= setup.o sysirq_mask.o
 obj-$(CONFIG_SOC_AT91SAM9)	+= sam9_smc.o
 
 # CPU-specific support
-obj-$(CONFIG_SOC_AT91RM9200)	+= at91rm9200.o at91rm9200_time.o
+obj-$(CONFIG_SOC_AT91RM9200)	+= at91rm9200.o
 obj-$(CONFIG_SOC_AT91SAM9260)	+= at91sam9260.o
 obj-$(CONFIG_SOC_AT91SAM9261)	+= at91sam9261.o
 obj-$(CONFIG_SOC_AT91SAM9263)	+= at91sam9263.o
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index fc01ec27d3c8..f550f16a176d 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -128,6 +128,10 @@ config ATMEL_PIT
 	select CLKSRC_OF if OF
 	def_bool SOC_AT91SAM9 || SOC_SAMA5
 
+config ATMEL_ST
+	select CLKSRC_OF
+	def_bool SOC_AT91RM9200
+
 config CLKSRC_METAG_GENERIC
 	def_bool y if METAG
 	help
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 94d90b24b56b..b7380ded4e4c 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -1,5 +1,6 @@
 obj-$(CONFIG_CLKSRC_OF)	+= clksrc-of.o
 obj-$(CONFIG_ATMEL_PIT)		+= timer-atmel-pit.o
+obj-$(CONFIG_ATMEL_ST)		+= timer-atmel-st.o
 obj-$(CONFIG_ATMEL_TCB_CLKSRC)	+= tcb_clksrc.o
 obj-$(CONFIG_X86_PM_TIMER)	+= acpi_pm.o
 obj-$(CONFIG_SCx200HR_TIMER)	+= scx200_hrt.o
diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/drivers/clocksource/timer-atmel-st.c
similarity index 100%
rename from arch/arm/mach-at91/at91rm9200_time.c
rename to drivers/clocksource/timer-atmel-st.c
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 5/8] ARM: at91: move the restart function to the system timer driver
  2015-01-09  9:51 ` Alexandre Belloni
@ 2015-01-09  9:51   ` Alexandre Belloni
  -1 siblings, 0 replies; 26+ messages in thread
From: Alexandre Belloni @ 2015-01-09  9:51 UTC (permalink / raw)
  To: Nicolas Ferre
  Cc: Boris Brezillon, Jean-Christophe Plagniol-Villard,
	Daniel Lezcano, Thomas Gleixner, Samuel Ortiz, Lee Jones,
	Wim Van Sebroeck, linux-kernel, linux-arm-kernel, linux-watchdog,
	Alexandre Belloni

Restarting on an at91rm9200 is handled by using the system timer. Move that
function to the system timer driver.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/at91rm9200.c      | 11 -----------
 drivers/clocksource/timer-atmel-st.c | 12 ++++++++++++
 2 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c
index b52916947535..4ea889cd6091 100644
--- a/arch/arm/mach-at91/at91rm9200.c
+++ b/arch/arm/mach-at91/at91rm9200.c
@@ -15,7 +15,6 @@
 
 #include <asm/mach/map.h>
 #include <asm/system_misc.h>
-#include <mach/at91_st.h>
 #include <mach/hardware.h>
 
 #include "soc.h"
@@ -30,15 +29,6 @@ static void at91rm9200_idle(void)
 	at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK);
 }
 
-static void at91rm9200_restart(enum reboot_mode reboot_mode, const char *cmd)
-{
-	/*
-	 * Perform a hardware reset with the use of the Watchdog timer.
-	 */
-	at91_st_write(AT91_ST_WDMR, AT91_ST_RSTEN | AT91_ST_EXTEN | 1);
-	at91_st_write(AT91_ST_CR, AT91_ST_WDRST);
-}
-
 /* --------------------------------------------------------------------
  *  AT91RM9200 processor initialization
  * -------------------------------------------------------------------- */
@@ -51,7 +41,6 @@ static void __init at91rm9200_map_io(void)
 static void __init at91rm9200_initialize(void)
 {
 	arm_pm_idle = at91rm9200_idle;
-	arm_pm_restart = at91rm9200_restart;
 }
 
 
diff --git a/drivers/clocksource/timer-atmel-st.c b/drivers/clocksource/timer-atmel-st.c
index 51761f8927b7..522583d6cc78 100644
--- a/drivers/clocksource/timer-atmel-st.c
+++ b/drivers/clocksource/timer-atmel-st.c
@@ -29,6 +29,7 @@
 #include <linux/of_irq.h>
 
 #include <asm/mach/time.h>
+#include <asm/system_misc.h>
 
 #include <mach/at91_st.h>
 #include <mach/hardware.h>
@@ -180,6 +181,15 @@ static struct clock_event_device clkevt = {
 	.set_mode	= clkevt32k_mode,
 };
 
+static void at91rm9200_restart(enum reboot_mode reboot_mode, const char *cmd)
+{
+	/*
+	 * Perform a hardware reset with the use of the Watchdog timer.
+	 */
+	at91_st_write(AT91_ST_WDMR, AT91_ST_RSTEN | AT91_ST_EXTEN | 1);
+	at91_st_write(AT91_ST_CR, AT91_ST_WDRST);
+}
+
 void __iomem *at91_st_base;
 EXPORT_SYMBOL_GPL(at91_st_base);
 
@@ -248,4 +258,6 @@ void __init at91rm9200_timer_init(void)
 
 	/* register clocksource */
 	clocksource_register_hz(&clk32k, AT91_SLOW_CLOCK);
+
+	arm_pm_restart = at91rm9200_restart;
 }
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 5/8] ARM: at91: move the restart function to the system timer driver
@ 2015-01-09  9:51   ` Alexandre Belloni
  0 siblings, 0 replies; 26+ messages in thread
From: Alexandre Belloni @ 2015-01-09  9:51 UTC (permalink / raw)
  To: linux-arm-kernel

Restarting on an at91rm9200 is handled by using the system timer. Move that
function to the system timer driver.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/at91rm9200.c      | 11 -----------
 drivers/clocksource/timer-atmel-st.c | 12 ++++++++++++
 2 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c
index b52916947535..4ea889cd6091 100644
--- a/arch/arm/mach-at91/at91rm9200.c
+++ b/arch/arm/mach-at91/at91rm9200.c
@@ -15,7 +15,6 @@
 
 #include <asm/mach/map.h>
 #include <asm/system_misc.h>
-#include <mach/at91_st.h>
 #include <mach/hardware.h>
 
 #include "soc.h"
@@ -30,15 +29,6 @@ static void at91rm9200_idle(void)
 	at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK);
 }
 
-static void at91rm9200_restart(enum reboot_mode reboot_mode, const char *cmd)
-{
-	/*
-	 * Perform a hardware reset with the use of the Watchdog timer.
-	 */
-	at91_st_write(AT91_ST_WDMR, AT91_ST_RSTEN | AT91_ST_EXTEN | 1);
-	at91_st_write(AT91_ST_CR, AT91_ST_WDRST);
-}
-
 /* --------------------------------------------------------------------
  *  AT91RM9200 processor initialization
  * -------------------------------------------------------------------- */
@@ -51,7 +41,6 @@ static void __init at91rm9200_map_io(void)
 static void __init at91rm9200_initialize(void)
 {
 	arm_pm_idle = at91rm9200_idle;
-	arm_pm_restart = at91rm9200_restart;
 }
 
 
diff --git a/drivers/clocksource/timer-atmel-st.c b/drivers/clocksource/timer-atmel-st.c
index 51761f8927b7..522583d6cc78 100644
--- a/drivers/clocksource/timer-atmel-st.c
+++ b/drivers/clocksource/timer-atmel-st.c
@@ -29,6 +29,7 @@
 #include <linux/of_irq.h>
 
 #include <asm/mach/time.h>
+#include <asm/system_misc.h>
 
 #include <mach/at91_st.h>
 #include <mach/hardware.h>
@@ -180,6 +181,15 @@ static struct clock_event_device clkevt = {
 	.set_mode	= clkevt32k_mode,
 };
 
+static void at91rm9200_restart(enum reboot_mode reboot_mode, const char *cmd)
+{
+	/*
+	 * Perform a hardware reset with the use of the Watchdog timer.
+	 */
+	at91_st_write(AT91_ST_WDMR, AT91_ST_RSTEN | AT91_ST_EXTEN | 1);
+	at91_st_write(AT91_ST_CR, AT91_ST_WDRST);
+}
+
 void __iomem *at91_st_base;
 EXPORT_SYMBOL_GPL(at91_st_base);
 
@@ -248,4 +258,6 @@ void __init at91rm9200_timer_init(void)
 
 	/* register clocksource */
 	clocksource_register_hz(&clk32k, AT91_SLOW_CLOCK);
+
+	arm_pm_restart = at91rm9200_restart;
 }
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 6/8] clocksource: atmel-st: properly initialize driver
  2015-01-09  9:51 ` Alexandre Belloni
@ 2015-01-09  9:51   ` Alexandre Belloni
  -1 siblings, 0 replies; 26+ messages in thread
From: Alexandre Belloni @ 2015-01-09  9:51 UTC (permalink / raw)
  To: Nicolas Ferre
  Cc: Boris Brezillon, Jean-Christophe Plagniol-Villard,
	Daniel Lezcano, Thomas Gleixner, Samuel Ortiz, Lee Jones,
	Wim Van Sebroeck, linux-kernel, linux-arm-kernel, linux-watchdog,
	Alexandre Belloni

Use clocksource_of_init to initialize the system timer instead of relying on a
custom function.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/board-dt-rm9200.c | 7 -------
 arch/arm/mach-at91/generic.h         | 3 ---
 drivers/clocksource/timer-atmel-st.c | 4 +++-
 3 files changed, 3 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-at91/board-dt-rm9200.c b/arch/arm/mach-at91/board-dt-rm9200.c
index 76dfe8f9af50..d9a45f49c208 100644
--- a/arch/arm/mach-at91/board-dt-rm9200.c
+++ b/arch/arm/mach-at91/board-dt-rm9200.c
@@ -24,19 +24,12 @@
 
 #include "generic.h"
 
-static void __init at91rm9200_dt_timer_init(void)
-{
-	of_clk_init(NULL);
-	at91rm9200_timer_init();
-}
-
 static const char *at91rm9200_dt_board_compat[] __initdata = {
 	"atmel,at91rm9200",
 	NULL
 };
 
 DT_MACHINE_START(at91rm9200_dt, "Atmel AT91RM9200 (Device Tree)")
-	.init_time      = at91rm9200_dt_timer_init,
 	.map_io		= at91_map_io,
 	.init_early	= at91rm9200_dt_initialize,
 	.dt_compat	= at91rm9200_dt_board_compat,
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index d53324210adf..fc12f3d4b93c 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -29,9 +29,6 @@ extern void __init at91_dt_initialize(void);
 extern void __init at91_sysirq_mask_rtc(u32 rtc_base);
 extern void __init at91_sysirq_mask_rtt(u32 rtt_base);
 
- /* Timer */
-extern void at91rm9200_timer_init(void);
-
 /* idle */
 extern void at91sam9_idle(void);
 
diff --git a/drivers/clocksource/timer-atmel-st.c b/drivers/clocksource/timer-atmel-st.c
index 522583d6cc78..ed0267f1c892 100644
--- a/drivers/clocksource/timer-atmel-st.c
+++ b/drivers/clocksource/timer-atmel-st.c
@@ -232,7 +232,7 @@ err:
 /*
  * ST (system timer) module supports both clockevents and clocksource.
  */
-void __init at91rm9200_timer_init(void)
+static void __init atmel_st_timer_init(struct device_node *node)
 {
 	/* For device tree enabled device: initialize here */
 	of_at91rm9200_st_init();
@@ -261,3 +261,5 @@ void __init at91rm9200_timer_init(void)
 
 	arm_pm_restart = at91rm9200_restart;
 }
+CLOCKSOURCE_OF_DECLARE(atmel_st_timer, "atmel,at91rm9200-st",
+		       atmel_st_timer_init);
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 6/8] clocksource: atmel-st: properly initialize driver
@ 2015-01-09  9:51   ` Alexandre Belloni
  0 siblings, 0 replies; 26+ messages in thread
From: Alexandre Belloni @ 2015-01-09  9:51 UTC (permalink / raw)
  To: linux-arm-kernel

Use clocksource_of_init to initialize the system timer instead of relying on a
custom function.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/board-dt-rm9200.c | 7 -------
 arch/arm/mach-at91/generic.h         | 3 ---
 drivers/clocksource/timer-atmel-st.c | 4 +++-
 3 files changed, 3 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-at91/board-dt-rm9200.c b/arch/arm/mach-at91/board-dt-rm9200.c
index 76dfe8f9af50..d9a45f49c208 100644
--- a/arch/arm/mach-at91/board-dt-rm9200.c
+++ b/arch/arm/mach-at91/board-dt-rm9200.c
@@ -24,19 +24,12 @@
 
 #include "generic.h"
 
-static void __init at91rm9200_dt_timer_init(void)
-{
-	of_clk_init(NULL);
-	at91rm9200_timer_init();
-}
-
 static const char *at91rm9200_dt_board_compat[] __initdata = {
 	"atmel,at91rm9200",
 	NULL
 };
 
 DT_MACHINE_START(at91rm9200_dt, "Atmel AT91RM9200 (Device Tree)")
-	.init_time      = at91rm9200_dt_timer_init,
 	.map_io		= at91_map_io,
 	.init_early	= at91rm9200_dt_initialize,
 	.dt_compat	= at91rm9200_dt_board_compat,
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index d53324210adf..fc12f3d4b93c 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -29,9 +29,6 @@ extern void __init at91_dt_initialize(void);
 extern void __init at91_sysirq_mask_rtc(u32 rtc_base);
 extern void __init at91_sysirq_mask_rtt(u32 rtt_base);
 
- /* Timer */
-extern void at91rm9200_timer_init(void);
-
 /* idle */
 extern void at91sam9_idle(void);
 
diff --git a/drivers/clocksource/timer-atmel-st.c b/drivers/clocksource/timer-atmel-st.c
index 522583d6cc78..ed0267f1c892 100644
--- a/drivers/clocksource/timer-atmel-st.c
+++ b/drivers/clocksource/timer-atmel-st.c
@@ -232,7 +232,7 @@ err:
 /*
  * ST (system timer) module supports both clockevents and clocksource.
  */
-void __init at91rm9200_timer_init(void)
+static void __init atmel_st_timer_init(struct device_node *node)
 {
 	/* For device tree enabled device: initialize here */
 	of_at91rm9200_st_init();
@@ -261,3 +261,5 @@ void __init at91rm9200_timer_init(void)
 
 	arm_pm_restart = at91rm9200_restart;
 }
+CLOCKSOURCE_OF_DECLARE(atmel_st_timer, "atmel,at91rm9200-st",
+		       atmel_st_timer_init);
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 7/8] clocksource: atmel-st: use syscon/regmap
  2015-01-09  9:51 ` Alexandre Belloni
@ 2015-01-09  9:51   ` Alexandre Belloni
  -1 siblings, 0 replies; 26+ messages in thread
From: Alexandre Belloni @ 2015-01-09  9:51 UTC (permalink / raw)
  To: Nicolas Ferre
  Cc: Boris Brezillon, Jean-Christophe Plagniol-Villard,
	Daniel Lezcano, Thomas Gleixner, Samuel Ortiz, Lee Jones,
	Wim Van Sebroeck, linux-kernel, linux-arm-kernel, linux-watchdog,
	Alexandre Belloni

The register range from the system timer is also used by the watchdog driver.
Use a regmap to handle concurrent accesses.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 drivers/clocksource/timer-atmel-st.c | 103 +++++++++++++----------------------
 1 file changed, 39 insertions(+), 64 deletions(-)

diff --git a/drivers/clocksource/timer-atmel-st.c b/drivers/clocksource/timer-atmel-st.c
index ed0267f1c892..557389306be5 100644
--- a/drivers/clocksource/timer-atmel-st.c
+++ b/drivers/clocksource/timer-atmel-st.c
@@ -24,20 +24,20 @@
 #include <linux/irq.h>
 #include <linux/clockchips.h>
 #include <linux/export.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
+#include <linux/mfd/atmel-st.h>
+#include <linux/mfd/syscon.h>
 #include <linux/of_irq.h>
+#include <linux/regmap.h>
 
 #include <asm/mach/time.h>
 #include <asm/system_misc.h>
 
-#include <mach/at91_st.h>
-#include <mach/hardware.h>
-
 static unsigned long last_crtr;
 static u32 irqmask;
 static struct clock_event_device clkevt;
+static struct regmap *regmap_st;
 
+#define AT91_SLOW_CLOCK		32768 /* DT compatibility */
 #define RM9200_TIMER_LATCH	((AT91_SLOW_CLOCK + HZ/2) / HZ)
 
 /*
@@ -47,11 +47,11 @@ static struct clock_event_device clkevt;
  */
 static inline unsigned long read_CRTR(void)
 {
-	unsigned long x1, x2;
+	unsigned int x1, x2;
 
-	x1 = at91_st_read(AT91_ST_CRTR);
+	regmap_read(regmap_st, AT91_ST_CRTR, &x1);
 	do {
-		x2 = at91_st_read(AT91_ST_CRTR);
+		regmap_read(regmap_st, AT91_ST_CRTR, &x2);
 		if (x1 == x2)
 			break;
 		x1 = x2;
@@ -64,7 +64,10 @@ static inline unsigned long read_CRTR(void)
  */
 static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id)
 {
-	u32	sr = at91_st_read(AT91_ST_SR) & irqmask;
+	u32 sr;
+
+	regmap_read(regmap_st, AT91_ST_SR, &sr);
+	sr &= irqmask;
 
 	/*
 	 * irqs should be disabled here, but as the irq is shared they are only
@@ -97,7 +100,7 @@ static struct irqaction at91rm9200_timer_irq = {
 	.name		= "at91_tick",
 	.flags		= IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL,
 	.handler	= at91rm9200_timer_interrupt,
-	.irq		= NR_IRQS_LEGACY + AT91_ID_SYS,
+	.irq		= 0,
 };
 
 static cycle_t read_clk32k(struct clocksource *cs)
@@ -116,23 +119,25 @@ static struct clocksource clk32k = {
 static void
 clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev)
 {
+	unsigned int val;
+
 	/* Disable and flush pending timer interrupts */
-	at91_st_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_ALMS);
-	at91_st_read(AT91_ST_SR);
+	regmap_write(regmap_st, AT91_ST_IDR, AT91_ST_PITS | AT91_ST_ALMS);
+	regmap_read(regmap_st, AT91_ST_SR, &val);
 
 	last_crtr = read_CRTR();
 	switch (mode) {
 	case CLOCK_EVT_MODE_PERIODIC:
 		/* PIT for periodic irqs; fixed rate of 1/HZ */
 		irqmask = AT91_ST_PITS;
-		at91_st_write(AT91_ST_PIMR, RM9200_TIMER_LATCH);
+		regmap_write(regmap_st, AT91_ST_PIMR, RM9200_TIMER_LATCH);
 		break;
 	case CLOCK_EVT_MODE_ONESHOT:
 		/* ALM for oneshot irqs, set by next_event()
 		 * before 32 seconds have passed
 		 */
 		irqmask = AT91_ST_ALMS;
-		at91_st_write(AT91_ST_RTAR, last_crtr);
+		regmap_write(regmap_st, AT91_ST_RTAR, last_crtr);
 		break;
 	case CLOCK_EVT_MODE_SHUTDOWN:
 	case CLOCK_EVT_MODE_UNUSED:
@@ -140,7 +145,7 @@ clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev)
 		irqmask = 0;
 		break;
 	}
-	at91_st_write(AT91_ST_IER, irqmask);
+	regmap_write(regmap_st, AT91_ST_IER, irqmask);
 }
 
 static int
@@ -148,6 +153,7 @@ clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev)
 {
 	u32		alm;
 	int		status = 0;
+	unsigned int	val;
 
 	BUG_ON(delta < 2);
 
@@ -163,12 +169,12 @@ clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev)
 	alm = read_CRTR();
 
 	/* Cancel any pending alarm; flush any pending IRQ */
-	at91_st_write(AT91_ST_RTAR, alm);
-	at91_st_read(AT91_ST_SR);
+	regmap_write(regmap_st, AT91_ST_RTAR, alm);
+	regmap_read(regmap_st, AT91_ST_SR, &val);
 
 	/* Schedule alarm by writing RTAR. */
 	alm += delta;
-	at91_st_write(AT91_ST_RTAR, alm);
+	regmap_write(regmap_st, AT91_ST_RTAR, alm);
 
 	return status;
 }
@@ -186,47 +192,8 @@ static void at91rm9200_restart(enum reboot_mode reboot_mode, const char *cmd)
 	/*
 	 * Perform a hardware reset with the use of the Watchdog timer.
 	 */
-	at91_st_write(AT91_ST_WDMR, AT91_ST_RSTEN | AT91_ST_EXTEN | 1);
-	at91_st_write(AT91_ST_CR, AT91_ST_WDRST);
-}
-
-void __iomem *at91_st_base;
-EXPORT_SYMBOL_GPL(at91_st_base);
-
-static struct of_device_id at91rm9200_st_timer_ids[] = {
-	{ .compatible = "atmel,at91rm9200-st" },
-	{ /* sentinel */ }
-};
-
-static int __init of_at91rm9200_st_init(void)
-{
-	struct device_node *np;
-	int ret;
-
-	np = of_find_matching_node(NULL, at91rm9200_st_timer_ids);
-	if (!np)
-		goto err;
-
-	at91_st_base = of_iomap(np, 0);
-	if (!at91_st_base)
-		goto node_err;
-
-	/* Get the interrupts property */
-	ret = irq_of_parse_and_map(np, 0);
-	if (!ret)
-		goto ioremap_err;
-	at91rm9200_timer_irq.irq = ret;
-
-	of_node_put(np);
-
-	return 0;
-
-ioremap_err:
-	iounmap(at91_st_base);
-node_err:
-	of_node_put(np);
-err:
-	return -EINVAL;
+	regmap_write(regmap_st, AT91_ST_WDMR, AT91_ST_RSTEN | AT91_ST_EXTEN | 1);
+	regmap_write(regmap_st, AT91_ST_CR, AT91_ST_WDRST);
 }
 
 /*
@@ -234,13 +201,21 @@ err:
  */
 static void __init atmel_st_timer_init(struct device_node *node)
 {
-	/* For device tree enabled device: initialize here */
-	of_at91rm9200_st_init();
+	unsigned int val;
+
+	regmap_st = syscon_node_to_regmap(node);
+	if (IS_ERR(regmap_st))
+		panic(pr_fmt("Unable to get regmap\n"));
 
 	/* Disable all timer interrupts, and clear any pending ones */
-	at91_st_write(AT91_ST_IDR,
+	regmap_write(regmap_st, AT91_ST_IDR,
 		AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS);
-	at91_st_read(AT91_ST_SR);
+	regmap_read(regmap_st, AT91_ST_SR, &val);
+
+	/* Get the interrupts property */
+	at91rm9200_timer_irq.irq  = irq_of_parse_and_map(node, 0);
+	if (!at91rm9200_timer_irq.irq)
+		panic(pr_fmt("Unable to get IRQ from DT\n"));
 
 	/* Make IRQs happen for the system timer */
 	setup_irq(at91rm9200_timer_irq.irq, &at91rm9200_timer_irq);
@@ -249,7 +224,7 @@ static void __init atmel_st_timer_init(struct device_node *node)
 	 * directly for the clocksource and all clockevents, after adjusting
 	 * its prescaler from the 1 Hz default.
 	 */
-	at91_st_write(AT91_ST_RTMR, 1);
+	regmap_write(regmap_st, AT91_ST_RTMR, 1);
 
 	/* Setup timer clockevent, with minimum of two ticks (important!!) */
 	clkevt.cpumask = cpumask_of(0);
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 7/8] clocksource: atmel-st: use syscon/regmap
@ 2015-01-09  9:51   ` Alexandre Belloni
  0 siblings, 0 replies; 26+ messages in thread
From: Alexandre Belloni @ 2015-01-09  9:51 UTC (permalink / raw)
  To: linux-arm-kernel

The register range from the system timer is also used by the watchdog driver.
Use a regmap to handle concurrent accesses.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 drivers/clocksource/timer-atmel-st.c | 103 +++++++++++++----------------------
 1 file changed, 39 insertions(+), 64 deletions(-)

diff --git a/drivers/clocksource/timer-atmel-st.c b/drivers/clocksource/timer-atmel-st.c
index ed0267f1c892..557389306be5 100644
--- a/drivers/clocksource/timer-atmel-st.c
+++ b/drivers/clocksource/timer-atmel-st.c
@@ -24,20 +24,20 @@
 #include <linux/irq.h>
 #include <linux/clockchips.h>
 #include <linux/export.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
+#include <linux/mfd/atmel-st.h>
+#include <linux/mfd/syscon.h>
 #include <linux/of_irq.h>
+#include <linux/regmap.h>
 
 #include <asm/mach/time.h>
 #include <asm/system_misc.h>
 
-#include <mach/at91_st.h>
-#include <mach/hardware.h>
-
 static unsigned long last_crtr;
 static u32 irqmask;
 static struct clock_event_device clkevt;
+static struct regmap *regmap_st;
 
+#define AT91_SLOW_CLOCK		32768 /* DT compatibility */
 #define RM9200_TIMER_LATCH	((AT91_SLOW_CLOCK + HZ/2) / HZ)
 
 /*
@@ -47,11 +47,11 @@ static struct clock_event_device clkevt;
  */
 static inline unsigned long read_CRTR(void)
 {
-	unsigned long x1, x2;
+	unsigned int x1, x2;
 
-	x1 = at91_st_read(AT91_ST_CRTR);
+	regmap_read(regmap_st, AT91_ST_CRTR, &x1);
 	do {
-		x2 = at91_st_read(AT91_ST_CRTR);
+		regmap_read(regmap_st, AT91_ST_CRTR, &x2);
 		if (x1 == x2)
 			break;
 		x1 = x2;
@@ -64,7 +64,10 @@ static inline unsigned long read_CRTR(void)
  */
 static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id)
 {
-	u32	sr = at91_st_read(AT91_ST_SR) & irqmask;
+	u32 sr;
+
+	regmap_read(regmap_st, AT91_ST_SR, &sr);
+	sr &= irqmask;
 
 	/*
 	 * irqs should be disabled here, but as the irq is shared they are only
@@ -97,7 +100,7 @@ static struct irqaction at91rm9200_timer_irq = {
 	.name		= "at91_tick",
 	.flags		= IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL,
 	.handler	= at91rm9200_timer_interrupt,
-	.irq		= NR_IRQS_LEGACY + AT91_ID_SYS,
+	.irq		= 0,
 };
 
 static cycle_t read_clk32k(struct clocksource *cs)
@@ -116,23 +119,25 @@ static struct clocksource clk32k = {
 static void
 clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev)
 {
+	unsigned int val;
+
 	/* Disable and flush pending timer interrupts */
-	at91_st_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_ALMS);
-	at91_st_read(AT91_ST_SR);
+	regmap_write(regmap_st, AT91_ST_IDR, AT91_ST_PITS | AT91_ST_ALMS);
+	regmap_read(regmap_st, AT91_ST_SR, &val);
 
 	last_crtr = read_CRTR();
 	switch (mode) {
 	case CLOCK_EVT_MODE_PERIODIC:
 		/* PIT for periodic irqs; fixed rate of 1/HZ */
 		irqmask = AT91_ST_PITS;
-		at91_st_write(AT91_ST_PIMR, RM9200_TIMER_LATCH);
+		regmap_write(regmap_st, AT91_ST_PIMR, RM9200_TIMER_LATCH);
 		break;
 	case CLOCK_EVT_MODE_ONESHOT:
 		/* ALM for oneshot irqs, set by next_event()
 		 * before 32 seconds have passed
 		 */
 		irqmask = AT91_ST_ALMS;
-		at91_st_write(AT91_ST_RTAR, last_crtr);
+		regmap_write(regmap_st, AT91_ST_RTAR, last_crtr);
 		break;
 	case CLOCK_EVT_MODE_SHUTDOWN:
 	case CLOCK_EVT_MODE_UNUSED:
@@ -140,7 +145,7 @@ clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev)
 		irqmask = 0;
 		break;
 	}
-	at91_st_write(AT91_ST_IER, irqmask);
+	regmap_write(regmap_st, AT91_ST_IER, irqmask);
 }
 
 static int
@@ -148,6 +153,7 @@ clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev)
 {
 	u32		alm;
 	int		status = 0;
+	unsigned int	val;
 
 	BUG_ON(delta < 2);
 
@@ -163,12 +169,12 @@ clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev)
 	alm = read_CRTR();
 
 	/* Cancel any pending alarm; flush any pending IRQ */
-	at91_st_write(AT91_ST_RTAR, alm);
-	at91_st_read(AT91_ST_SR);
+	regmap_write(regmap_st, AT91_ST_RTAR, alm);
+	regmap_read(regmap_st, AT91_ST_SR, &val);
 
 	/* Schedule alarm by writing RTAR. */
 	alm += delta;
-	at91_st_write(AT91_ST_RTAR, alm);
+	regmap_write(regmap_st, AT91_ST_RTAR, alm);
 
 	return status;
 }
@@ -186,47 +192,8 @@ static void at91rm9200_restart(enum reboot_mode reboot_mode, const char *cmd)
 	/*
 	 * Perform a hardware reset with the use of the Watchdog timer.
 	 */
-	at91_st_write(AT91_ST_WDMR, AT91_ST_RSTEN | AT91_ST_EXTEN | 1);
-	at91_st_write(AT91_ST_CR, AT91_ST_WDRST);
-}
-
-void __iomem *at91_st_base;
-EXPORT_SYMBOL_GPL(at91_st_base);
-
-static struct of_device_id at91rm9200_st_timer_ids[] = {
-	{ .compatible = "atmel,at91rm9200-st" },
-	{ /* sentinel */ }
-};
-
-static int __init of_at91rm9200_st_init(void)
-{
-	struct device_node *np;
-	int ret;
-
-	np = of_find_matching_node(NULL, at91rm9200_st_timer_ids);
-	if (!np)
-		goto err;
-
-	at91_st_base = of_iomap(np, 0);
-	if (!at91_st_base)
-		goto node_err;
-
-	/* Get the interrupts property */
-	ret = irq_of_parse_and_map(np, 0);
-	if (!ret)
-		goto ioremap_err;
-	at91rm9200_timer_irq.irq = ret;
-
-	of_node_put(np);
-
-	return 0;
-
-ioremap_err:
-	iounmap(at91_st_base);
-node_err:
-	of_node_put(np);
-err:
-	return -EINVAL;
+	regmap_write(regmap_st, AT91_ST_WDMR, AT91_ST_RSTEN | AT91_ST_EXTEN | 1);
+	regmap_write(regmap_st, AT91_ST_CR, AT91_ST_WDRST);
 }
 
 /*
@@ -234,13 +201,21 @@ err:
  */
 static void __init atmel_st_timer_init(struct device_node *node)
 {
-	/* For device tree enabled device: initialize here */
-	of_at91rm9200_st_init();
+	unsigned int val;
+
+	regmap_st = syscon_node_to_regmap(node);
+	if (IS_ERR(regmap_st))
+		panic(pr_fmt("Unable to get regmap\n"));
 
 	/* Disable all timer interrupts, and clear any pending ones */
-	at91_st_write(AT91_ST_IDR,
+	regmap_write(regmap_st, AT91_ST_IDR,
 		AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS);
-	at91_st_read(AT91_ST_SR);
+	regmap_read(regmap_st, AT91_ST_SR, &val);
+
+	/* Get the interrupts property */
+	at91rm9200_timer_irq.irq  = irq_of_parse_and_map(node, 0);
+	if (!at91rm9200_timer_irq.irq)
+		panic(pr_fmt("Unable to get IRQ from DT\n"));
 
 	/* Make IRQs happen for the system timer */
 	setup_irq(at91rm9200_timer_irq.irq, &at91rm9200_timer_irq);
@@ -249,7 +224,7 @@ static void __init atmel_st_timer_init(struct device_node *node)
 	 * directly for the clocksource and all clockevents, after adjusting
 	 * its prescaler from the 1 Hz default.
 	 */
-	at91_st_write(AT91_ST_RTMR, 1);
+	regmap_write(regmap_st, AT91_ST_RTMR, 1);
 
 	/* Setup timer clockevent, with minimum of two ticks (important!!) */
 	clkevt.cpumask = cpumask_of(0);
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 8/8] ARM: at91: remove useless include
  2015-01-09  9:51 ` Alexandre Belloni
@ 2015-01-09  9:51   ` Alexandre Belloni
  -1 siblings, 0 replies; 26+ messages in thread
From: Alexandre Belloni @ 2015-01-09  9:51 UTC (permalink / raw)
  To: Nicolas Ferre
  Cc: Boris Brezillon, Jean-Christophe Plagniol-Villard,
	Daniel Lezcano, Thomas Gleixner, Samuel Ortiz, Lee Jones,
	Wim Van Sebroeck, linux-kernel, linux-arm-kernel, linux-watchdog,
	Alexandre Belloni

Both drivers using the system timer are now converted to an MFD. mach/at91_st.h
is now useless.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/include/mach/at91_st.h | 61 -------------------------------
 1 file changed, 61 deletions(-)
 delete mode 100644 arch/arm/mach-at91/include/mach/at91_st.h

diff --git a/arch/arm/mach-at91/include/mach/at91_st.h b/arch/arm/mach-at91/include/mach/at91_st.h
deleted file mode 100644
index 67fdbd13c3ed..000000000000
--- a/arch/arm/mach-at91/include/mach/at91_st.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * arch/arm/mach-at91/include/mach/at91_st.h
- *
- * Copyright (C) 2005 Ivan Kokshaysky
- * Copyright (C) SAN People
- *
- * System Timer (ST) - System peripherals registers.
- * Based on AT91RM9200 datasheet revision E.
- *
- * 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.
- */
-
-#ifndef AT91_ST_H
-#define AT91_ST_H
-
-#ifndef __ASSEMBLY__
-extern void __iomem *at91_st_base;
-
-#define at91_st_read(field) \
-	__raw_readl(at91_st_base + field)
-
-#define at91_st_write(field, value) \
-	__raw_writel(value, at91_st_base + field)
-#else
-.extern at91_st_base
-#endif
-
-#define	AT91_ST_CR		0x00			/* Control Register */
-#define 	AT91_ST_WDRST		(1 << 0)		/* Watchdog Timer Restart */
-
-#define	AT91_ST_PIMR		0x04			/* Period Interval Mode Register */
-#define		AT91_ST_PIV		(0xffff <<  0)		/* Period Interval Value */
-
-#define	AT91_ST_WDMR		0x08			/* Watchdog Mode Register */
-#define		AT91_ST_WDV		(0xffff <<  0)		/* Watchdog Counter Value */
-#define		AT91_ST_RSTEN		(1	<< 16)		/* Reset Enable */
-#define		AT91_ST_EXTEN		(1	<< 17)		/* External Signal Assertion Enable */
-
-#define	AT91_ST_RTMR		0x0c			/* Real-time Mode Register */
-#define		AT91_ST_RTPRES		(0xffff <<  0)		/* Real-time Prescalar Value */
-
-#define	AT91_ST_SR		0x10			/* Status Register */
-#define		AT91_ST_PITS		(1 << 0)		/* Period Interval Timer Status */
-#define		AT91_ST_WDOVF		(1 << 1) 		/* Watchdog Overflow */
-#define		AT91_ST_RTTINC		(1 << 2) 		/* Real-time Timer Increment */
-#define		AT91_ST_ALMS		(1 << 3) 		/* Alarm Status */
-
-#define	AT91_ST_IER		0x14			/* Interrupt Enable Register */
-#define	AT91_ST_IDR		0x18			/* Interrupt Disable Register */
-#define	AT91_ST_IMR		0x1c			/* Interrupt Mask Register */
-
-#define	AT91_ST_RTAR		0x20			/* Real-time Alarm Register */
-#define		AT91_ST_ALMV		(0xfffff << 0)		/* Alarm Value */
-
-#define	AT91_ST_CRTR		0x24			/* Current Real-time Register */
-#define		AT91_ST_CRTV		(0xfffff << 0)		/* Current Real-Time Value */
-
-#endif
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 8/8] ARM: at91: remove useless include
@ 2015-01-09  9:51   ` Alexandre Belloni
  0 siblings, 0 replies; 26+ messages in thread
From: Alexandre Belloni @ 2015-01-09  9:51 UTC (permalink / raw)
  To: linux-arm-kernel

Both drivers using the system timer are now converted to an MFD. mach/at91_st.h
is now useless.

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
 arch/arm/mach-at91/include/mach/at91_st.h | 61 -------------------------------
 1 file changed, 61 deletions(-)
 delete mode 100644 arch/arm/mach-at91/include/mach/at91_st.h

diff --git a/arch/arm/mach-at91/include/mach/at91_st.h b/arch/arm/mach-at91/include/mach/at91_st.h
deleted file mode 100644
index 67fdbd13c3ed..000000000000
--- a/arch/arm/mach-at91/include/mach/at91_st.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * arch/arm/mach-at91/include/mach/at91_st.h
- *
- * Copyright (C) 2005 Ivan Kokshaysky
- * Copyright (C) SAN People
- *
- * System Timer (ST) - System peripherals registers.
- * Based on AT91RM9200 datasheet revision E.
- *
- * 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.
- */
-
-#ifndef AT91_ST_H
-#define AT91_ST_H
-
-#ifndef __ASSEMBLY__
-extern void __iomem *at91_st_base;
-
-#define at91_st_read(field) \
-	__raw_readl(at91_st_base + field)
-
-#define at91_st_write(field, value) \
-	__raw_writel(value, at91_st_base + field)
-#else
-.extern at91_st_base
-#endif
-
-#define	AT91_ST_CR		0x00			/* Control Register */
-#define 	AT91_ST_WDRST		(1 << 0)		/* Watchdog Timer Restart */
-
-#define	AT91_ST_PIMR		0x04			/* Period Interval Mode Register */
-#define		AT91_ST_PIV		(0xffff <<  0)		/* Period Interval Value */
-
-#define	AT91_ST_WDMR		0x08			/* Watchdog Mode Register */
-#define		AT91_ST_WDV		(0xffff <<  0)		/* Watchdog Counter Value */
-#define		AT91_ST_RSTEN		(1	<< 16)		/* Reset Enable */
-#define		AT91_ST_EXTEN		(1	<< 17)		/* External Signal Assertion Enable */
-
-#define	AT91_ST_RTMR		0x0c			/* Real-time Mode Register */
-#define		AT91_ST_RTPRES		(0xffff <<  0)		/* Real-time Prescalar Value */
-
-#define	AT91_ST_SR		0x10			/* Status Register */
-#define		AT91_ST_PITS		(1 << 0)		/* Period Interval Timer Status */
-#define		AT91_ST_WDOVF		(1 << 1) 		/* Watchdog Overflow */
-#define		AT91_ST_RTTINC		(1 << 2) 		/* Real-time Timer Increment */
-#define		AT91_ST_ALMS		(1 << 3) 		/* Alarm Status */
-
-#define	AT91_ST_IER		0x14			/* Interrupt Enable Register */
-#define	AT91_ST_IDR		0x18			/* Interrupt Disable Register */
-#define	AT91_ST_IMR		0x1c			/* Interrupt Mask Register */
-
-#define	AT91_ST_RTAR		0x20			/* Real-time Alarm Register */
-#define		AT91_ST_ALMV		(0xfffff << 0)		/* Alarm Value */
-
-#define	AT91_ST_CRTR		0x24			/* Current Real-time Register */
-#define		AT91_ST_CRTV		(0xfffff << 0)		/* Current Real-Time Value */
-
-#endif
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 3/8] watchdog: at91rm9200: use the regmap from mfd
  2015-01-09  9:51   ` Alexandre Belloni
@ 2015-01-10  0:39     ` Guenter Roeck
  -1 siblings, 0 replies; 26+ messages in thread
From: Guenter Roeck @ 2015-01-10  0:39 UTC (permalink / raw)
  To: Alexandre Belloni, Nicolas Ferre
  Cc: Boris Brezillon, Jean-Christophe Plagniol-Villard,
	Daniel Lezcano, Thomas Gleixner, Samuel Ortiz, Lee Jones,
	Wim Van Sebroeck, linux-kernel, linux-arm-kernel, linux-watchdog

On 01/09/2015 01:51 AM, Alexandre Belloni wrote:
> The system timer MFD driver is providing a regmap. Use it to access the
> registers.
>
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
> ---
>   drivers/watchdog/Kconfig          |  2 +-
>   drivers/watchdog/at91rm9200_wdt.c | 27 +++++++++------------------
>   2 files changed, 10 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
> index 08f41add1461..18c73bc159fc 100644
> --- a/drivers/watchdog/Kconfig
> +++ b/drivers/watchdog/Kconfig
> @@ -154,7 +154,7 @@ config ARM_SP805_WATCHDOG
>
>   config AT91RM9200_WATCHDOG
>   	tristate "AT91RM9200 watchdog"
> -	depends on SOC_AT91RM9200
> +	depends on SOC_AT91RM9200 && MFD_ATMEL_ST
>   	help
>   	  Watchdog timer embedded into AT91RM9200 chips. This will reboot your
>   	  system when the timeout is reached.
> diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c
> index d244112d5b6f..a493fe4b0dfc 100644
> --- a/drivers/watchdog/at91rm9200_wdt.c
> +++ b/drivers/watchdog/at91rm9200_wdt.c
> @@ -14,25 +14,22 @@
>   #include <linux/bitops.h>
>   #include <linux/errno.h>
>   #include <linux/fs.h>
> -#include <linux/init.h>
> -#include <linux/io.h>
>   #include <linux/kernel.h>
> +#include <linux/mfd/atmel-st.h>
>   #include <linux/miscdevice.h>
>   #include <linux/module.h>
>   #include <linux/moduleparam.h>
>   #include <linux/platform_device.h>
> -#include <linux/types.h>
> +#include <linux/regmap.h>
>   #include <linux/watchdog.h>
>   #include <linux/uaccess.h>
> -#include <linux/of.h>
> -#include <linux/of_device.h>
> -#include <mach/at91_st.h>
>
>   #define WDT_DEFAULT_TIME	5	/* seconds */
>   #define WDT_MAX_TIME		256	/* seconds */
>
>   static int wdt_time = WDT_DEFAULT_TIME;
>   static bool nowayout = WATCHDOG_NOWAYOUT;
> +static struct regmap *regmap_st;
>
>   module_param(wdt_time, int, 0);
>   MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="
> @@ -55,7 +52,7 @@ static unsigned long at91wdt_busy;
>    */
>   static inline void at91_wdt_stop(void)
>   {
> -	at91_st_write(AT91_ST_WDMR, AT91_ST_EXTEN);
> +	regmap_write(regmap_st, AT91_ST_WDMR, AT91_ST_EXTEN);
>   }
>
>   /*
> @@ -63,9 +60,9 @@ static inline void at91_wdt_stop(void)
>    */
>   static inline void at91_wdt_start(void)
>   {
> -	at91_st_write(AT91_ST_WDMR, AT91_ST_EXTEN | AT91_ST_RSTEN |
> +	regmap_write(regmap_st, AT91_ST_WDMR, AT91_ST_EXTEN | AT91_ST_RSTEN |
>   				(((65536 * wdt_time) >> 8) & AT91_ST_WDV));
> -	at91_st_write(AT91_ST_CR, AT91_ST_WDRST);
> +	regmap_write(regmap_st, AT91_ST_CR, AT91_ST_WDRST);
>   }
>
>   /*
> @@ -73,7 +70,7 @@ static inline void at91_wdt_start(void)
>    */
>   static inline void at91_wdt_reload(void)
>   {
> -	at91_st_write(AT91_ST_CR, AT91_ST_WDRST);
> +	regmap_write(regmap_st, AT91_ST_CR, AT91_ST_WDRST);
>   }
>
>   /* ......................................................................... */
> @@ -204,6 +201,7 @@ static struct miscdevice at91wdt_miscdev = {
>   static int at91wdt_probe(struct platform_device *pdev)
>   {
>   	int res;
> +	regmap_st = dev_get_drvdata(pdev->dev.parent);
>

Is it guaranteed that parent is never NULL, and that the parent's
drvdata is always set ?

Also, it seems that regmap_st will be overwritten if the device
is already open (see code below). That may not be a good idea.

Guenter

>   	if (at91wdt_miscdev.parent)
>   		return -EBUSY;
> @@ -254,12 +252,6 @@ static int at91wdt_resume(struct platform_device *pdev)
>   #define at91wdt_resume	NULL
>   #endif
>
> -static const struct of_device_id at91_wdt_dt_ids[] = {
> -	{ .compatible = "atmel,at91rm9200-wdt" },
> -	{ /* sentinel */ }
> -};
> -MODULE_DEVICE_TABLE(of, at91_wdt_dt_ids);
> -
>   static struct platform_driver at91wdt_driver = {
>   	.probe		= at91wdt_probe,
>   	.remove		= at91wdt_remove,
> @@ -267,8 +259,7 @@ static struct platform_driver at91wdt_driver = {
>   	.suspend	= at91wdt_suspend,
>   	.resume		= at91wdt_resume,
>   	.driver		= {
> -		.name	= "at91_wdt",
> -		.of_match_table = at91_wdt_dt_ids,
> +		.name	= "atmel_st_watchdog",
>   	},
>   };
>
>


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 3/8] watchdog: at91rm9200: use the regmap from mfd
@ 2015-01-10  0:39     ` Guenter Roeck
  0 siblings, 0 replies; 26+ messages in thread
From: Guenter Roeck @ 2015-01-10  0:39 UTC (permalink / raw)
  To: linux-arm-kernel

On 01/09/2015 01:51 AM, Alexandre Belloni wrote:
> The system timer MFD driver is providing a regmap. Use it to access the
> registers.
>
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
> ---
>   drivers/watchdog/Kconfig          |  2 +-
>   drivers/watchdog/at91rm9200_wdt.c | 27 +++++++++------------------
>   2 files changed, 10 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
> index 08f41add1461..18c73bc159fc 100644
> --- a/drivers/watchdog/Kconfig
> +++ b/drivers/watchdog/Kconfig
> @@ -154,7 +154,7 @@ config ARM_SP805_WATCHDOG
>
>   config AT91RM9200_WATCHDOG
>   	tristate "AT91RM9200 watchdog"
> -	depends on SOC_AT91RM9200
> +	depends on SOC_AT91RM9200 && MFD_ATMEL_ST
>   	help
>   	  Watchdog timer embedded into AT91RM9200 chips. This will reboot your
>   	  system when the timeout is reached.
> diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c
> index d244112d5b6f..a493fe4b0dfc 100644
> --- a/drivers/watchdog/at91rm9200_wdt.c
> +++ b/drivers/watchdog/at91rm9200_wdt.c
> @@ -14,25 +14,22 @@
>   #include <linux/bitops.h>
>   #include <linux/errno.h>
>   #include <linux/fs.h>
> -#include <linux/init.h>
> -#include <linux/io.h>
>   #include <linux/kernel.h>
> +#include <linux/mfd/atmel-st.h>
>   #include <linux/miscdevice.h>
>   #include <linux/module.h>
>   #include <linux/moduleparam.h>
>   #include <linux/platform_device.h>
> -#include <linux/types.h>
> +#include <linux/regmap.h>
>   #include <linux/watchdog.h>
>   #include <linux/uaccess.h>
> -#include <linux/of.h>
> -#include <linux/of_device.h>
> -#include <mach/at91_st.h>
>
>   #define WDT_DEFAULT_TIME	5	/* seconds */
>   #define WDT_MAX_TIME		256	/* seconds */
>
>   static int wdt_time = WDT_DEFAULT_TIME;
>   static bool nowayout = WATCHDOG_NOWAYOUT;
> +static struct regmap *regmap_st;
>
>   module_param(wdt_time, int, 0);
>   MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="
> @@ -55,7 +52,7 @@ static unsigned long at91wdt_busy;
>    */
>   static inline void at91_wdt_stop(void)
>   {
> -	at91_st_write(AT91_ST_WDMR, AT91_ST_EXTEN);
> +	regmap_write(regmap_st, AT91_ST_WDMR, AT91_ST_EXTEN);
>   }
>
>   /*
> @@ -63,9 +60,9 @@ static inline void at91_wdt_stop(void)
>    */
>   static inline void at91_wdt_start(void)
>   {
> -	at91_st_write(AT91_ST_WDMR, AT91_ST_EXTEN | AT91_ST_RSTEN |
> +	regmap_write(regmap_st, AT91_ST_WDMR, AT91_ST_EXTEN | AT91_ST_RSTEN |
>   				(((65536 * wdt_time) >> 8) & AT91_ST_WDV));
> -	at91_st_write(AT91_ST_CR, AT91_ST_WDRST);
> +	regmap_write(regmap_st, AT91_ST_CR, AT91_ST_WDRST);
>   }
>
>   /*
> @@ -73,7 +70,7 @@ static inline void at91_wdt_start(void)
>    */
>   static inline void at91_wdt_reload(void)
>   {
> -	at91_st_write(AT91_ST_CR, AT91_ST_WDRST);
> +	regmap_write(regmap_st, AT91_ST_CR, AT91_ST_WDRST);
>   }
>
>   /* ......................................................................... */
> @@ -204,6 +201,7 @@ static struct miscdevice at91wdt_miscdev = {
>   static int at91wdt_probe(struct platform_device *pdev)
>   {
>   	int res;
> +	regmap_st = dev_get_drvdata(pdev->dev.parent);
>

Is it guaranteed that parent is never NULL, and that the parent's
drvdata is always set ?

Also, it seems that regmap_st will be overwritten if the device
is already open (see code below). That may not be a good idea.

Guenter

>   	if (at91wdt_miscdev.parent)
>   		return -EBUSY;
> @@ -254,12 +252,6 @@ static int at91wdt_resume(struct platform_device *pdev)
>   #define at91wdt_resume	NULL
>   #endif
>
> -static const struct of_device_id at91_wdt_dt_ids[] = {
> -	{ .compatible = "atmel,at91rm9200-wdt" },
> -	{ /* sentinel */ }
> -};
> -MODULE_DEVICE_TABLE(of, at91_wdt_dt_ids);
> -
>   static struct platform_driver at91wdt_driver = {
>   	.probe		= at91wdt_probe,
>   	.remove		= at91wdt_remove,
> @@ -267,8 +259,7 @@ static struct platform_driver at91wdt_driver = {
>   	.suspend	= at91wdt_suspend,
>   	.resume		= at91wdt_resume,
>   	.driver		= {
> -		.name	= "at91_wdt",
> -		.of_match_table = at91_wdt_dt_ids,
> +		.name	= "atmel_st_watchdog",
>   	},
>   };
>
>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 3/8] watchdog: at91rm9200: use the regmap from mfd
  2015-01-10  0:39     ` Guenter Roeck
@ 2015-01-10 18:41       ` Alexandre Belloni
  -1 siblings, 0 replies; 26+ messages in thread
From: Alexandre Belloni @ 2015-01-10 18:41 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: Nicolas Ferre, Boris Brezillon, Jean-Christophe Plagniol-Villard,
	Daniel Lezcano, Thomas Gleixner, Samuel Ortiz, Lee Jones,
	Wim Van Sebroeck, linux-kernel, linux-arm-kernel, linux-watchdog

On 09/01/2015 at 16:39:21 -0800, Guenter Roeck wrote :
> On 01/09/2015 01:51 AM, Alexandre Belloni wrote:
> >  /* ......................................................................... */
> >@@ -204,6 +201,7 @@ static struct miscdevice at91wdt_miscdev = {
> >  static int at91wdt_probe(struct platform_device *pdev)
> >  {
> >  	int res;
> >+	regmap_st = dev_get_drvdata(pdev->dev.parent);
> >
> 
> Is it guaranteed that parent is never NULL, and that the parent's
> drvdata is always set ?
> 

The only way to probe the driver left is to use platform_data. It is
done from the MFD driver. If you prefer, I can test for NULL here and
return.

> Also, it seems that regmap_st will be overwritten if the device
> is already open (see code below). That may not be a good idea.
> 

I'm not sure what you meani, pdev->dev.parent and at91wdt_miscdev.parent
are not the same thing. I didn't touch the code below but I believe
there is no reason to pass in the probe twice and return -EBUSY.


-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 3/8] watchdog: at91rm9200: use the regmap from mfd
@ 2015-01-10 18:41       ` Alexandre Belloni
  0 siblings, 0 replies; 26+ messages in thread
From: Alexandre Belloni @ 2015-01-10 18:41 UTC (permalink / raw)
  To: linux-arm-kernel

On 09/01/2015 at 16:39:21 -0800, Guenter Roeck wrote :
> On 01/09/2015 01:51 AM, Alexandre Belloni wrote:
> >  /* ......................................................................... */
> >@@ -204,6 +201,7 @@ static struct miscdevice at91wdt_miscdev = {
> >  static int at91wdt_probe(struct platform_device *pdev)
> >  {
> >  	int res;
> >+	regmap_st = dev_get_drvdata(pdev->dev.parent);
> >
> 
> Is it guaranteed that parent is never NULL, and that the parent's
> drvdata is always set ?
> 

The only way to probe the driver left is to use platform_data. It is
done from the MFD driver. If you prefer, I can test for NULL here and
return.

> Also, it seems that regmap_st will be overwritten if the device
> is already open (see code below). That may not be a good idea.
> 

I'm not sure what you meani, pdev->dev.parent and at91wdt_miscdev.parent
are not the same thing. I didn't touch the code below but I believe
there is no reason to pass in the probe twice and return -EBUSY.


-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 3/8] watchdog: at91rm9200: use the regmap from mfd
  2015-01-10 18:41       ` Alexandre Belloni
@ 2015-01-11  1:14         ` Guenter Roeck
  -1 siblings, 0 replies; 26+ messages in thread
From: Guenter Roeck @ 2015-01-11  1:14 UTC (permalink / raw)
  To: Alexandre Belloni
  Cc: Nicolas Ferre, Boris Brezillon, Jean-Christophe Plagniol-Villard,
	Daniel Lezcano, Thomas Gleixner, Samuel Ortiz, Lee Jones,
	Wim Van Sebroeck, linux-kernel, linux-arm-kernel, linux-watchdog

On 01/10/2015 10:41 AM, Alexandre Belloni wrote:
> On 09/01/2015 at 16:39:21 -0800, Guenter Roeck wrote :
>> On 01/09/2015 01:51 AM, Alexandre Belloni wrote:
>>>   /* ......................................................................... */
>>> @@ -204,6 +201,7 @@ static struct miscdevice at91wdt_miscdev = {
>>>   static int at91wdt_probe(struct platform_device *pdev)
>>>   {
>>>   	int res;
>>> +	regmap_st = dev_get_drvdata(pdev->dev.parent);
>>>
>>
>> Is it guaranteed that parent is never NULL, and that the parent's
>> drvdata is always set ?
>>
>
> The only way to probe the driver left is to use platform_data. It is
> done from the MFD driver. If you prefer, I can test for NULL here and
> return.
>

I am fine if you are sure about that. The problem though is still the
check for double instantiation. Either the driver can not be instantiated
multiple times, and the check is no longer necessary, or it can, meaning
there must be some other means to instantiate it besides through the
mfd driver. And in that case you don't necessarily know if platform_data
is set.

>> Also, it seems that regmap_st will be overwritten if the device
>> is already open (see code below). That may not be a good idea.
>>
>
> I'm not sure what you meani, pdev->dev.parent and at91wdt_miscdev.parent
> are not the same thing. I didn't touch the code below but I believe
> there is no reason to pass in the probe twice and return -EBUSY.
>

Not sure I understand what my comment has to do with 'parent'.

The fact that the code checks if it has already been instantiated
suggests that the original author of the driver was concerned about
that case. Since you did not remove that check I have to assume that
this can still happen. If so, the second instantiation attempt will
overwrite regmap_st, since that variable is written prior to checking
for the dual instantiation.

Guenter


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 3/8] watchdog: at91rm9200: use the regmap from mfd
@ 2015-01-11  1:14         ` Guenter Roeck
  0 siblings, 0 replies; 26+ messages in thread
From: Guenter Roeck @ 2015-01-11  1:14 UTC (permalink / raw)
  To: linux-arm-kernel

On 01/10/2015 10:41 AM, Alexandre Belloni wrote:
> On 09/01/2015 at 16:39:21 -0800, Guenter Roeck wrote :
>> On 01/09/2015 01:51 AM, Alexandre Belloni wrote:
>>>   /* ......................................................................... */
>>> @@ -204,6 +201,7 @@ static struct miscdevice at91wdt_miscdev = {
>>>   static int at91wdt_probe(struct platform_device *pdev)
>>>   {
>>>   	int res;
>>> +	regmap_st = dev_get_drvdata(pdev->dev.parent);
>>>
>>
>> Is it guaranteed that parent is never NULL, and that the parent's
>> drvdata is always set ?
>>
>
> The only way to probe the driver left is to use platform_data. It is
> done from the MFD driver. If you prefer, I can test for NULL here and
> return.
>

I am fine if you are sure about that. The problem though is still the
check for double instantiation. Either the driver can not be instantiated
multiple times, and the check is no longer necessary, or it can, meaning
there must be some other means to instantiate it besides through the
mfd driver. And in that case you don't necessarily know if platform_data
is set.

>> Also, it seems that regmap_st will be overwritten if the device
>> is already open (see code below). That may not be a good idea.
>>
>
> I'm not sure what you meani, pdev->dev.parent and at91wdt_miscdev.parent
> are not the same thing. I didn't touch the code below but I believe
> there is no reason to pass in the probe twice and return -EBUSY.
>

Not sure I understand what my comment has to do with 'parent'.

The fact that the code checks if it has already been instantiated
suggests that the original author of the driver was concerned about
that case. Since you did not remove that check I have to assume that
this can still happen. If so, the second instantiation attempt will
overwrite regmap_st, since that variable is written prior to checking
for the dual instantiation.

Guenter

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 3/8] watchdog: at91rm9200: use the regmap from mfd
  2015-01-11  1:14         ` Guenter Roeck
@ 2015-01-12 14:08           ` Alexandre Belloni
  -1 siblings, 0 replies; 26+ messages in thread
From: Alexandre Belloni @ 2015-01-12 14:08 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: Nicolas Ferre, Boris Brezillon, Jean-Christophe Plagniol-Villard,
	Daniel Lezcano, Thomas Gleixner, Samuel Ortiz, Lee Jones,
	Wim Van Sebroeck, linux-kernel, linux-arm-kernel, linux-watchdog

On 10/01/2015 at 17:14:00 -0800, Guenter Roeck wrote :
> Not sure I understand what my comment has to do with 'parent'.
> 
> The fact that the code checks if it has already been instantiated
> suggests that the original author of the driver was concerned about
> that case. Since you did not remove that check I have to assume that
> this can still happen. If so, the second instantiation attempt will
> overwrite regmap_st, since that variable is written prior to checking
> for the dual instantiation.
> 

I'll move the regmap_st assignment after the check. But I really believe
it will never be probed more than once.

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 3/8] watchdog: at91rm9200: use the regmap from mfd
@ 2015-01-12 14:08           ` Alexandre Belloni
  0 siblings, 0 replies; 26+ messages in thread
From: Alexandre Belloni @ 2015-01-12 14:08 UTC (permalink / raw)
  To: linux-arm-kernel

On 10/01/2015 at 17:14:00 -0800, Guenter Roeck wrote :
> Not sure I understand what my comment has to do with 'parent'.
> 
> The fact that the code checks if it has already been instantiated
> suggests that the original author of the driver was concerned about
> that case. Since you did not remove that check I have to assume that
> this can still happen. If so, the second instantiation attempt will
> overwrite regmap_st, since that variable is written prior to checking
> for the dual instantiation.
> 

I'll move the regmap_st assignment after the check. But I really believe
it will never be probed more than once.

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2015-01-12 14:08 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-09  9:51 [PATCH v2 0/8] Atmel System Timer cleanups Alexandre Belloni
2015-01-09  9:51 ` Alexandre Belloni
2015-01-09  9:51 ` [PATCH v2 1/8] ARM: at91/dt: declare atmel,at91rm9200-st as a syscon Alexandre Belloni
2015-01-09  9:51   ` Alexandre Belloni
2015-01-09  9:51 ` [PATCH v2 2/8] mfd: Add atmel-st driver Alexandre Belloni
2015-01-09  9:51   ` Alexandre Belloni
2015-01-09  9:51 ` [PATCH v2 3/8] watchdog: at91rm9200: use the regmap from mfd Alexandre Belloni
2015-01-09  9:51   ` Alexandre Belloni
2015-01-10  0:39   ` Guenter Roeck
2015-01-10  0:39     ` Guenter Roeck
2015-01-10 18:41     ` Alexandre Belloni
2015-01-10 18:41       ` Alexandre Belloni
2015-01-11  1:14       ` Guenter Roeck
2015-01-11  1:14         ` Guenter Roeck
2015-01-12 14:08         ` Alexandre Belloni
2015-01-12 14:08           ` Alexandre Belloni
2015-01-09  9:51 ` [PATCH v2 4/8] ARM: at91: time: move the system timer driver to drivers/clocksource Alexandre Belloni
2015-01-09  9:51   ` Alexandre Belloni
2015-01-09  9:51 ` [PATCH v2 5/8] ARM: at91: move the restart function to the system timer driver Alexandre Belloni
2015-01-09  9:51   ` Alexandre Belloni
2015-01-09  9:51 ` [PATCH v2 6/8] clocksource: atmel-st: properly initialize driver Alexandre Belloni
2015-01-09  9:51   ` Alexandre Belloni
2015-01-09  9:51 ` [PATCH v2 7/8] clocksource: atmel-st: use syscon/regmap Alexandre Belloni
2015-01-09  9:51   ` Alexandre Belloni
2015-01-09  9:51 ` [PATCH v2 8/8] ARM: at91: remove useless include Alexandre Belloni
2015-01-09  9:51   ` Alexandre Belloni

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.