diff mbox

[v3] RTC: rtc-v3020.c: Added support for device-tree binding

Message ID 1307644769-25598-1-git-send-email-david@protonic.nl
State New, archived
Headers show

Commit Message

David Jander June 9, 2011, 6:39 p.m. UTC
Added support for fetching platform data from OF device-tree.

Signed-off-by: David Jander <david@protonic.nl>
---
 .../devicetree/bindings/rtc/rtc-v3020.txt          |   31 +++++++++++
 drivers/rtc/rtc-v3020.c                            |   57 ++++++++++++++++++++
 2 files changed, 88 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/rtc/rtc-v3020.txt
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/rtc/rtc-v3020.txt b/Documentation/devicetree/bindings/rtc/rtc-v3020.txt
new file mode 100644
index 0000000..1799a84
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/rtc-v3020.txt
@@ -0,0 +1,31 @@ 
+ EM Marin V3020 compatible RTC
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Required properties:
+  - compatible: "em,v3020", "v3020"
+  - reg: Memory address if mmio mode is used, otherwise not used.
+
+Optional properties:
+  - "leftshift": integer. Contains the leftshift parameter of 
+    struct v3020_platform_data.
+  - "gpios": gpios property. Array of 4 OF gpio specifiers, which if specified
+    select gpio mode. The four gpios are gpio_cs, gpio_wr, gpio_rd and
+    gpio_io in this order. See Documentation/devicetree/bindings/gpio/gpio.txt
+
+Example for MMIO on MPC5121 localbus:
+
+	localbus@80000020 {
+		compatible = "fsl,mpc5121-localbus";
+		#address-cells = <2>;
+		#size-cells = <1>;
+		reg = <0x80000020 0x40>;
+		ranges = <0x0 0x0 0xfe000000 0x02000000   /* Flash */
+			  0x1 0x0 0xf8000000 0x00000004>; /* V3020 */
+		...
+		v3020@1,0 {
+			compatible = "em,v3020", "v3020";
+			reg = <1 0 4>;
+			leftshift = <24>;
+		};
+		...
+
diff --git a/drivers/rtc/rtc-v3020.c b/drivers/rtc/rtc-v3020.c
index f71c3ce..b582448 100644
--- a/drivers/rtc/rtc-v3020.c
+++ b/drivers/rtc/rtc-v3020.c
@@ -11,6 +11,9 @@ 
  *
  * Changelog:
  *
+ *  31-May-2011: David Jander <david@protonic.nl>
+ *				- Added OF support
+ *
  *  10-May-2006: Raphael Assenat <raph@8d.com>
  *				- Converted to platform driver
  *				- Use the generic rtc class
@@ -29,6 +32,8 @@ 
 #include <linux/delay.h>
 #include <linux/gpio.h>
 #include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
 
 #include <linux/io.h>
 
@@ -301,9 +306,45 @@  static const struct rtc_class_ops v3020_rtc_ops = {
 	.set_time	= v3020_set_time,
 };
 
+#ifdef CONFIG_OF
+static void get_of_pdata(struct v3020_platform_data *pdata,
+			 struct platform_device *pdev)
+{
+	const unsigned int *val;
+	unsigned int gpio;
+
+	memset(pdata, 0, sizeof *pdata);
+	if (of_find_property(pdev->dev.of_node, "gpios", NULL) != NULL) {
+		pdata->use_gpio = 1;
+		gpio = of_get_gpio_flags(pdev->dev.of_node, 0, NULL);
+		if (gpio >= 0)
+			pdata->gpio_cs = gpio;
+		gpio = of_get_gpio_flags(pdev->dev.of_node, 1, NULL);
+		if (gpio >= 0)
+			pdata->gpio_wr = gpio;
+		gpio = of_get_gpio_flags(pdev->dev.of_node, 2, NULL);
+		if (gpio >= 0)
+			pdata->gpio_rd = gpio;
+		gpio = of_get_gpio_flags(pdev->dev.of_node, 3, NULL);
+		if (gpio >= 0)
+			pdata->gpio_io = gpio;
+	} else {
+		val = of_get_property(pdev->dev.of_node, "leftshift", NULL);
+		if (val)
+			pdata->leftshift = *val;
+	}
+}
+#else
+static void get_of_pdata(struct v3020_platform_data *pdata,
+			 struct platform_device *pdev)
+{
+}
+#endif
+
 static int rtc_probe(struct platform_device *pdev)
 {
 	struct v3020_platform_data *pdata = pdev->dev.platform_data;
+	struct v3020_platform_data alt_pdata;
 	struct v3020 *chip;
 	int retval = -EBUSY;
 	int i;
@@ -313,6 +354,11 @@  static int rtc_probe(struct platform_device *pdev)
 	if (!chip)
 		return -ENOMEM;
 
+	if (!pdata && pdev->dev.of_node) {
+		get_of_pdata(&alt_pdata, pdev);
+		pdata = &alt_pdata;
+	}
+
 	if (pdata->use_gpio)
 		chip->ops = &v3020_gpio_ops;
 	else
@@ -384,12 +430,23 @@  static int rtc_remove(struct platform_device *dev)
 	return 0;
 }
 
+#ifdef CONFIG_OF
+const struct of_device_id v3020_of_match[] = {
+	{
+		.compatible = "v3020",
+	},
+};
+#endif
+
 static struct platform_driver rtc_device_driver = {
 	.probe	= rtc_probe,
 	.remove = rtc_remove,
 	.driver = {
 		.name	= "v3020",
 		.owner	= THIS_MODULE,
+#ifdef CONFIG_OF
+		.of_match_table = v3020_of_match,
+#endif
 	},
 };