devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jon Hunter <jon-hunter@ti.com>
To: Tony Lindgren <tony@atomide.com>, Benoit Cousson <b-cousson@ti.com>
Cc: device-tree <devicetree-discuss@lists.ozlabs.org>,
	linux-omap <linux-omap@vger.kernel.org>,
	linux-arm <linux-arm-kernel@lists.infradead.org>,
	Jon Hunter <jon-hunter@ti.com>
Subject: [PATCH 3/5] ARM: OMAP: Add function to request timer by node
Date: Tue, 19 Mar 2013 12:38:17 -0500	[thread overview]
Message-ID: <1363714699-29622-4-git-send-email-jon-hunter@ti.com> (raw)
In-Reply-To: <1363714699-29622-1-git-send-email-jon-hunter@ti.com>

Add a function so that OMAP dmtimers can be requested by device-tree
node. This allows for devices, such as the internal DSP, or drivers,
such as PWM, to reference a specific dmtimer node via the device-tree.

Given that there are several APIs available for requesting dmtimers
(by ID, by capability or by node) consolidate the code for all these
functions into a single helper function that can be used by these
request functions.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
---
 arch/arm/plat-omap/dmtimer.c              |  167 ++++++++++++++++-------------
 arch/arm/plat-omap/include/plat/dmtimer.h |    1 +
 2 files changed, 94 insertions(+), 74 deletions(-)

diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 725d972..05efb37 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -52,6 +52,13 @@ static u32 omap_reserved_systimers;
 static LIST_HEAD(omap_timer_list);
 static DEFINE_SPINLOCK(dm_timer_lock);
 
+enum {
+	REQUEST_ANY = 0,
+	REQUEST_BY_ID,
+	REQUEST_BY_CAP,
+	REQUEST_BY_NODE,
+};
+
 /**
  * omap_dm_timer_read_reg - read timer registers in posted and non-posted mode
  * @timer:      timer pointer over which read operation to perform
@@ -178,29 +185,82 @@ int omap_dm_timer_reserve_systimer(int id)
 	return 0;
 }
 
-struct omap_dm_timer *omap_dm_timer_request(void)
+static struct omap_dm_timer *_omap_dm_timer_request(int req_type, void *data)
 {
 	struct omap_dm_timer *timer = NULL, *t;
+	struct device_node *np = NULL;
 	unsigned long flags;
-	int ret = 0;
+	u32 cap = 0;
+	int id = 0;
+
+	switch (req_type) {
+	case REQUEST_BY_ID:
+		id = *(int *)data;
+		break;
+	case REQUEST_BY_CAP:
+		cap = *(u32 *)data;
+		break;
+	case REQUEST_BY_NODE:
+		np = (struct device_node *)data;
+		break;
+	default:
+		/* REQUEST_ANY */
+		break;
+	}
 
 	spin_lock_irqsave(&dm_timer_lock, flags);
 	list_for_each_entry(t, &omap_timer_list, node) {
 		if (t->reserved)
 			continue;
 
-		timer = t;
-		timer->reserved = 1;
-		break;
+		switch (req_type) {
+		case REQUEST_BY_ID:
+			if (id == t->pdev->id) {
+				timer = t;
+				timer->reserved = 1;
+				goto found;
+			}
+			break;
+		case REQUEST_BY_CAP:
+			if (cap == (t->capability & cap)) {
+				/*
+				 * If timer is not NULL, we have already found
+				 * one timer but it was not an exact match
+				 * because it had more capabilites that what
+				 * was required. Therefore, unreserve the last
+				 * timer found and see if this one is a better
+				 * match.
+				 */
+				if (timer)
+					timer->reserved = 0;
+				timer = t;
+				timer->reserved = 1;
+
+				/* Exit loop early if we find an exact match */
+				if (t->capability == cap)
+					goto found;
+			}
+			break;
+		case REQUEST_BY_NODE:
+			if (np == t->pdev->dev.of_node) {
+				timer = t;
+				timer->reserved = 1;
+				goto found;
+			}
+			break;
+		default:
+			/* REQUEST_ANY */
+			timer = t;
+			timer->reserved = 1;
+			goto found;
+		}
 	}
+found:
 	spin_unlock_irqrestore(&dm_timer_lock, flags);
 
-	if (timer) {
-		ret = omap_dm_timer_prepare(timer);
-		if (ret) {
-			timer->reserved = 0;
-			timer = NULL;
-		}
+	if (timer && omap_dm_timer_prepare(timer)) {
+		timer->reserved = 0;
+		timer = NULL;
 	}
 
 	if (!timer)
@@ -208,43 +268,23 @@ struct omap_dm_timer *omap_dm_timer_request(void)
 
 	return timer;
 }
+
+struct omap_dm_timer *omap_dm_timer_request(void)
+{
+	return _omap_dm_timer_request(REQUEST_ANY, NULL);
+}
 EXPORT_SYMBOL_GPL(omap_dm_timer_request);
 
 struct omap_dm_timer *omap_dm_timer_request_specific(int id)
 {
-	struct omap_dm_timer *timer = NULL, *t;
-	unsigned long flags;
-	int ret = 0;
-
 	/* Requesting timer by ID is not supported when device tree is used */
 	if (of_have_populated_dt()) {
-		pr_warn("%s: Please use omap_dm_timer_request_by_cap()\n",
+		pr_warn("%s: Please use omap_dm_timer_request_by_cap/node()\n",
 			__func__);
 		return NULL;
 	}
 
-	spin_lock_irqsave(&dm_timer_lock, flags);
-	list_for_each_entry(t, &omap_timer_list, node) {
-		if (t->pdev->id == id && !t->reserved) {
-			timer = t;
-			timer->reserved = 1;
-			break;
-		}
-	}
-	spin_unlock_irqrestore(&dm_timer_lock, flags);
-
-	if (timer) {
-		ret = omap_dm_timer_prepare(timer);
-		if (ret) {
-			timer->reserved = 0;
-			timer = NULL;
-		}
-	}
-
-	if (!timer)
-		pr_debug("%s: timer%d request failed!\n", __func__, id);
-
-	return timer;
+	return _omap_dm_timer_request(REQUEST_BY_ID, &id);
 }
 EXPORT_SYMBOL_GPL(omap_dm_timer_request_specific);
 
@@ -259,46 +299,25 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_request_specific);
  */
 struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap)
 {
-	struct omap_dm_timer *timer = NULL, *t;
-	unsigned long flags;
+	return _omap_dm_timer_request(REQUEST_BY_CAP, &cap);
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_request_by_cap);
 
-	if (!cap)
+/**
+ * omap_dm_timer_request_by_node - Request a timer by device-tree node
+ * @np:		Pointer to device-tree timer node
+ *
+ * Request a timer based upon a device node pointer. Returns pointer to
+ * timer handle on success and a NULL pointer on failure.
+ */
+struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np)
+{
+	if (!np)
 		return NULL;
 
-	spin_lock_irqsave(&dm_timer_lock, flags);
-	list_for_each_entry(t, &omap_timer_list, node) {
-		if ((!t->reserved) && ((t->capability & cap) == cap)) {
-			/*
-			 * If timer is not NULL, we have already found one timer
-			 * but it was not an exact match because it had more
-			 * capabilites that what was required. Therefore,
-			 * unreserve the last timer found and see if this one
-			 * is a better match.
-			 */
-			if (timer)
-				timer->reserved = 0;
-
-			timer = t;
-			timer->reserved = 1;
-
-			/* Exit loop early if we find an exact match */
-			if (t->capability == cap)
-				break;
-		}
-	}
-	spin_unlock_irqrestore(&dm_timer_lock, flags);
-
-	if (timer && omap_dm_timer_prepare(timer)) {
-		timer->reserved = 0;
-		timer = NULL;
-	}
-
-	if (!timer)
-		pr_debug("%s: timer request failed!\n", __func__);
-
-	return timer;
+	return _omap_dm_timer_request(REQUEST_BY_NODE, np);
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_request_by_cap);
+EXPORT_SYMBOL_GPL(omap_dm_timer_request_by_node);
 
 int omap_dm_timer_free(struct omap_dm_timer *timer)
 {
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
index a3fbc48..fb92abb 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -128,6 +128,7 @@ int omap_dm_timer_reserve_systimer(int id);
 struct omap_dm_timer *omap_dm_timer_request(void);
 struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id);
 struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap);
+struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np);
 int omap_dm_timer_free(struct omap_dm_timer *timer);
 void omap_dm_timer_enable(struct omap_dm_timer *timer);
 void omap_dm_timer_disable(struct omap_dm_timer *timer);
-- 
1.7.10.4


  parent reply	other threads:[~2013-03-19 17:38 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-03-19 17:38 [PATCH 0/5] ARM: OMAP: DMTIMER updates for v3.10 Jon Hunter
     [not found] ` <1363714699-29622-1-git-send-email-jon-hunter-l0cyMroinI0@public.gmane.org>
2013-03-19 17:38   ` [PATCH 1/5] ARM: OMAP: Simplify dmtimer context-loss handling Jon Hunter
2013-03-19 17:38 ` [PATCH 2/5] ARM: OMAP: Force dmtimer restore if context loss is not detectable Jon Hunter
2013-03-19 17:38 ` Jon Hunter [this message]
2013-03-19 17:38 ` [PATCH 4/5] ARM: dts: OMAP2+: Update DMTIMER compatibility property Jon Hunter
2013-03-19 17:38 ` [PATCH 5/5] ARM: OMAP2+: Populate DMTIMER errata when using device-tree Jon Hunter
2013-04-04 18:38 ` [PATCH 0/5] ARM: OMAP: DMTIMER updates for v3.10 Tony Lindgren
2013-04-05  8:05   ` Benoit Cousson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1363714699-29622-4-git-send-email-jon-hunter@ti.com \
    --to=jon-hunter@ti.com \
    --cc=b-cousson@ti.com \
    --cc=devicetree-discuss@lists.ozlabs.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-omap@vger.kernel.org \
    --cc=tony@atomide.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).