[PATCH 5/5] OMAP2/3 omapdev: add code to walk the omapdev records

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Register the omapdevs early in the boot process.  Also provide
functions for other code (primarily the OMAP PM layer at the moment)
to look up an omapdev given a platform_device name and id.

Signed-off-by: Paul Walmsley <paul@xxxxxxxxx>
---
 arch/arm/mach-omap2/Makefile              |    2 
 arch/arm/mach-omap2/io.c                  |    3 
 arch/arm/mach-omap2/omapdev.c             |  177 +++++++++++++++++++++++++++++
 arch/arm/plat-omap/include/mach/omapdev.h |    7 +
 4 files changed, 188 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-omap2/omapdev.c

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 33de217..25a4791 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -5,7 +5,7 @@
 # Common support
 obj-y := irq.o id.o io.o sdrc.o control.o prcm.o clock.o mux.o \
 		devices.o serial.o gpmc.o timer-gp.o powerdomain.o \
-		clockdomain.o
+		clockdomain.o omapdev.o
 
 obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
 
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 05d4f2d..1829c1b 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -29,6 +29,8 @@
 #include <mach/sdrc.h>
 #include <mach/gpmc.h>
 
+#include "omapdev-common.h"
+
 #include "clock.h"
 
 #include <mach/powerdomain.h>
@@ -202,6 +204,7 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sp)
 	omap_pm_if_early_init();
 	pwrdm_init(powerdomains_omap);
 	clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps);
+	omapdev_init(omapdevs);
 	omap2_clk_init();
 	omap_pm_if_init(NULL, NULL);
 	omap2_sdrc_init(sp);
diff --git a/arch/arm/mach-omap2/omapdev.c b/arch/arm/mach-omap2/omapdev.c
new file mode 100644
index 0000000..1488681
--- /dev/null
+++ b/arch/arm/mach-omap2/omapdev.c
@@ -0,0 +1,177 @@
+/*
+ * omapdev device registration and handling code
+ *
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2008 Nokia Corporation
+ * Paul Walmsley
+ *
+ * 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.
+ *
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+
+#include <mach/cpu.h>
+#include <mach/powerdomain.h>
+#include <mach/omapdev.h>
+
+/* odev_list contains all registered struct omapdevs */
+static LIST_HEAD(odev_list);
+
+
+/* Private functions */
+
+/*
+ * _omapdev_lookup - look up an OMAP module pointer by its name
+ * @name: name of the OMAP module to look up
+ *
+ * Finds a registered OMAP module by its name, returning a pointer to
+ * it.	Returns a pointer to the struct omapdev if found, or NULL
+ * otherwise.
+ */
+static struct omapdev *_omapdev_lookup(const char *name)
+{
+	struct omapdev *odev, *temp_odev;
+
+	if (!name)
+		return NULL;
+
+	odev = NULL;
+
+	list_for_each_entry(temp_odev, &odev_list, node) {
+		if (!strcmp(name, temp_odev->name)) {
+			odev = temp_odev;
+			break;
+		}
+	}
+
+	return odev;
+}
+
+/*
+ * _omapdev_register - register an OMAP module
+ * @odev: struct omapdev * to register
+ *
+ * Adds a OMAP module to the internal OMAP module list.  Returns
+ * -EINVAL if given a null pointer, -EEXIST if a OMAP module is
+ * already registered by the provided name, or 0 upon success.
+ */
+static int _omapdev_register(struct omapdev *odev)
+{
+	struct powerdomain *pwrdm;
+
+	if (!odev)
+		return -EINVAL;
+
+	if (!omap_chip_is(odev->omap_chip))
+		return -EINVAL;
+
+	if (_omapdev_lookup(odev->name))
+		return -EEXIST;
+
+	pwrdm = pwrdm_lookup(odev->pwrdm.name);
+	if (!pwrdm) {
+		pr_debug("omapdev: cannot register %s: bad powerdomain\n",
+			 odev->name);
+		return -EINVAL;
+	}
+	odev->pwrdm.ptr = pwrdm;
+
+	list_add(&odev->node, &odev_list);
+
+	pr_debug("omapdev: registered %s\n", odev->name);
+
+	return 0;
+}
+
+
+
+/* Public functions */
+
+
+/**
+ * omapdev_init - set up the OMAP module layer
+ * @odevs: ptr to a array of omapdev ptrs to register
+ *
+ * Loop through the list of OMAP modules, registering them all.  No
+ * return value.
+ */
+void omapdev_init(struct omapdev **odevs)
+{
+	struct omapdev **d = NULL;
+
+	if (!list_empty(&odev_list)) {
+		pr_debug("omapdev: init already called\n");
+		return;
+	}
+
+	for (d = odevs; *d; d++) {
+		int v;
+
+		if (!omap_chip_is((*d)->omap_chip))
+			continue;
+
+		v = _omapdev_register(*d);
+		if (ERR_PTR(v))
+			pr_err("omapdev: could not register %s\n",
+			       (*d)->name);
+	}
+}
+
+
+/**
+ * omapdev_get_pwrdm - return pwrdm pointer associated with the device
+ * @omapdev: omapdev *
+ *
+ */
+struct powerdomain *omapdev_get_pwrdm(struct omapdev *odev)
+{
+	if (!odev)
+		return NULL;
+
+	return odev->pwrdm.ptr;
+}
+
+
+/**
+ * omapdev_find_pdev - look up an OMAP module by platform_device
+ * @pdev_name: platform_device name to find
+ * @pdev_id: platform_device id to find
+ *
+ * Finds a registered OMAP module by the platform_device name and ID
+ * that is associated with it in the omapdev structure. If multiple
+ * records exist, simply returns the 'first' record that it finds -
+ * this is probably not optimal behavior, but should work for current
+ * purposes.  Returns a pointer to the struct omapdev if found, or
+ * NULL otherwise.
+ */
+struct omapdev *omapdev_find_pdev(struct platform_device *pdev)
+{
+	struct omapdev *odev, *temp_odev;
+
+	if (!pdev)
+		return NULL;
+
+	odev = NULL;
+
+	list_for_each_entry(temp_odev, &odev_list, node) {
+		if (temp_odev->pdev_name &&
+		    !strcmp(pdev->name, temp_odev->pdev_name) &&
+		    pdev->id == temp_odev->pdev_id) {
+			odev = temp_odev;
+			break;
+		}
+	}
+
+	return odev;
+}
+
diff --git a/arch/arm/plat-omap/include/mach/omapdev.h b/arch/arm/plat-omap/include/mach/omapdev.h
index ef91f00..4b379bc 100644
--- a/arch/arm/plat-omap/include/mach/omapdev.h
+++ b/arch/arm/plat-omap/include/mach/omapdev.h
@@ -15,6 +15,7 @@
 
 #include <linux/types.h>
 #include <linux/list.h>
+#include <linux/platform_device.h>
 
 #include <mach/cpu.h>
 #include <mach/powerdomain.h>
@@ -47,5 +48,11 @@ struct omapdev {
 };
 
 
+void omapdev_init(struct omapdev **odev_list);
+
+struct powerdomain *omapdev_get_pwrdm(struct omapdev *odev);
+
+struct omapdev *omapdev_find_pdev(struct platform_device *pdev);
+
 
 #endif


--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux