From: Tony Lindgren <tony@atomide.com>
To: linux-arm-kernel@lists.arm.linux.org.uk
Cc: linux-omap@vger.kernel.org, Paul Walmsley <paul@pwsan.com>,
Tony Lindgren <tony@atomide.com>
Subject: [PATCH 06/10] ARM: OMAP2: Clockdomain: Connect clockdomain code to powerdomain code
Date: Tue, 19 Aug 2008 11:39:57 +0300 [thread overview]
Message-ID: <1219135201-10282-7-git-send-email-tony@atomide.com> (raw)
In-Reply-To: <1219135201-10282-6-git-send-email-tony@atomide.com>
From: Paul Walmsley <paul@pwsan.com>
Thie patch adds code to the powerdomain layer to track the
clockdomains associated with each powerdomain.
It also modifies the clockdomain code to register clockdomains
with their corresponding powerdomain when the clockdomain is registered.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index f867d8f..b6ff5aa 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -219,6 +219,8 @@ int clkdm_register(struct clockdomain *clkdm)
list_add(&clkdm->node, &clkdm_list);
+ pwrdm_add_clkdm(pwrdm, clkdm);
+
pr_debug("clockdomain: registered %s\n", clkdm->name);
ret = 0;
@@ -240,6 +242,8 @@ int clkdm_unregister(struct clockdomain *clkdm)
if (!clkdm)
return -EINVAL;
+ pwrdm_del_clkdm(clkdm->pwrdm, clkdm);
+
mutex_lock(&clkdm_mutex);
list_del(&clkdm->node);
mutex_unlock(&clkdm_mutex);
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 1ec0038..9a80349 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -33,6 +33,7 @@
#include <mach/cpu.h>
#include <mach/powerdomain.h>
+#include <mach/clockdomain.h>
/* pwrdm_list contains all registered struct powerdomains */
static LIST_HEAD(pwrdm_list);
@@ -237,6 +238,141 @@ int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm))
}
/**
+ * pwrdm_add_clkdm - add a clockdomain to a powerdomain
+ * @pwrdm: struct powerdomain * to add the clockdomain to
+ * @clkdm: struct clockdomain * to associate with a powerdomain
+ *
+ * Associate the clockdomain 'clkdm' with a powerdomain 'pwrdm'. This
+ * enables the use of pwrdm_for_each_clkdm(). Returns -EINVAL if
+ * presented with invalid pointers; -ENOMEM if memory could not be allocated;
+ * or 0 upon success.
+ */
+int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
+{
+ unsigned long flags;
+ int i;
+ int ret = -EINVAL;
+
+ if (!pwrdm || !clkdm)
+ return -EINVAL;
+
+ pr_debug("powerdomain: associating clockdomain %s with powerdomain "
+ "%s\n", clkdm->name, pwrdm->name);
+
+ write_lock_irqsave(&pwrdm_rwlock, flags);
+
+ for (i = 0; i < PWRDM_MAX_CLKDMS; i++) {
+ if (!pwrdm->pwrdm_clkdms[i])
+ break;
+#ifdef DEBUG
+ if (pwrdm->pwrdm_clkdms[i] == clkdm) {
+ ret = -EINVAL;
+ goto pac_exit;
+ }
+#endif
+ }
+
+ if (i == PWRDM_MAX_CLKDMS) {
+ pr_debug("powerdomain: increase PWRDM_MAX_CLKDMS for "
+ "pwrdm %s clkdm %s\n", pwrdm->name, clkdm->name);
+ WARN_ON(1);
+ ret = -ENOMEM;
+ goto pac_exit;
+ }
+
+ pwrdm->pwrdm_clkdms[i] = clkdm;
+
+ ret = 0;
+
+pac_exit:
+ write_unlock_irqrestore(&pwrdm_rwlock, flags);
+
+ return ret;
+}
+
+/**
+ * pwrdm_del_clkdm - remove a clockdomain from a powerdomain
+ * @pwrdm: struct powerdomain * to add the clockdomain to
+ * @clkdm: struct clockdomain * to associate with a powerdomain
+ *
+ * Dissociate the clockdomain 'clkdm' from the powerdomain
+ * 'pwrdm'. Returns -EINVAL if presented with invalid pointers;
+ * -ENOENT if the clkdm was not associated with the powerdomain, or 0
+ * upon success.
+ */
+int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
+{
+ unsigned long flags;
+ int ret = -EINVAL;
+ int i;
+
+ if (!pwrdm || !clkdm)
+ return -EINVAL;
+
+ pr_debug("powerdomain: dissociating clockdomain %s from powerdomain "
+ "%s\n", clkdm->name, pwrdm->name);
+
+ write_lock_irqsave(&pwrdm_rwlock, flags);
+
+ for (i = 0; i < PWRDM_MAX_CLKDMS; i++)
+ if (pwrdm->pwrdm_clkdms[i] == clkdm)
+ break;
+
+ if (i == PWRDM_MAX_CLKDMS) {
+ pr_debug("powerdomain: clkdm %s not associated with pwrdm "
+ "%s ?!\n", clkdm->name, pwrdm->name);
+ ret = -ENOENT;
+ goto pdc_exit;
+ }
+
+ pwrdm->pwrdm_clkdms[i] = NULL;
+
+ ret = 0;
+
+pdc_exit:
+ write_unlock_irqrestore(&pwrdm_rwlock, flags);
+
+ return ret;
+}
+
+/**
+ * pwrdm_for_each_clkdm - call function on each clkdm in a pwrdm
+ * @pwrdm: struct powerdomain * to iterate over
+ * @fn: callback function *
+ *
+ * Call the supplied function for each clockdomain in the powerdomain
+ * 'pwrdm'. The callback function can return anything but 0 to bail
+ * out early from the iterator. The callback function is called with
+ * the pwrdm_rwlock held for reading, so no powerdomain structure
+ * manipulation functions should be called from the callback, although
+ * hardware powerdomain control functions are fine. Returns -EINVAL
+ * if presented with invalid pointers; or passes along the last return
+ * value of the callback function, which should be 0 for success or
+ * anything else to indicate failure.
+ */
+int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
+ int (*fn)(struct powerdomain *pwrdm,
+ struct clockdomain *clkdm))
+{
+ unsigned long flags;
+ int ret = 0;
+ int i;
+
+ if (!fn)
+ return -EINVAL;
+
+ read_lock_irqsave(&pwrdm_rwlock, flags);
+
+ for (i = 0; i < PWRDM_MAX_CLKDMS && !ret; i++)
+ ret = (*fn)(pwrdm, pwrdm->pwrdm_clkdms[i]);
+
+ read_unlock_irqrestore(&pwrdm_rwlock, flags);
+
+ return ret;
+}
+
+
+/**
* pwrdm_add_wkdep - add a wakeup dependency from pwrdm2 to pwrdm1
* @pwrdm1: wake this struct powerdomain * up (dependent)
* @pwrdm2: when this struct powerdomain * wakes up (source)
diff --git a/arch/arm/plat-omap/include/mach/powerdomain.h b/arch/arm/plat-omap/include/mach/powerdomain.h
index c8f52c6..5fa666f 100644
--- a/arch/arm/plat-omap/include/mach/powerdomain.h
+++ b/arch/arm/plat-omap/include/mach/powerdomain.h
@@ -44,9 +44,16 @@
*/
#define PWRDM_MAX_MEM_BANKS 4
+/*
+ * Maximum number of clockdomains that can be associated with a powerdomain.
+ * CORE powerdomain is probably the worst case.
+ */
+#define PWRDM_MAX_CLKDMS 3
+
/* XXX A completely arbitrary number. What is reasonable here? */
#define PWRDM_TRANSITION_BAILOUT 100000
+struct clockdomain;
struct powerdomain;
/* Encodes dependencies between powerdomains - statically defined */
@@ -98,6 +105,9 @@ struct powerdomain {
/* Possible memory bank pwrstates when pwrdm is ON */
const u8 pwrsts_mem_on[PWRDM_MAX_MEM_BANKS];
+ /* Clockdomains in this powerdomain */
+ struct clockdomain *pwrdm_clkdms[PWRDM_MAX_CLKDMS];
+
struct list_head node;
};
@@ -111,6 +121,12 @@ struct powerdomain *pwrdm_lookup(const char *name);
int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm));
+int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
+int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
+int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
+ int (*fn)(struct powerdomain *pwrdm,
+ struct clockdomain *clkdm));
+
int pwrdm_add_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
int pwrdm_del_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
int pwrdm_read_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
next prev parent reply other threads:[~2008-08-19 8:40 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-07-16 15:19 [PATCH 0/0] Power domain and clock domain patches for omap Tony Lindgren
2008-07-16 15:19 ` [PATCH 01/10] ARM: OMAP2: Powerdomain: Add base OMAP2/3 powerdomain code Tony Lindgren
2008-07-16 15:19 ` [PATCH 02/10] ARM: OMAP2: Powerdomain: Add OMAP2/3 common powerdomains Tony Lindgren
2008-07-16 15:19 ` [PATCH 03/10] ARM: OMAP2: Powerdomain: Add OMAP2 powerdomains Tony Lindgren
2008-07-16 15:19 ` [PATCH 04/10] ARM: OMAP: Powerdomain: Add OMAP3 powerdomains Tony Lindgren
2008-07-16 15:19 ` [PATCH 05/10] ARM: OMAP2: Clockdomain: Add base OMAP2/3 clockdomain code Tony Lindgren
2008-07-16 15:19 ` [PATCH 06/10] ARM: OMAP2: Clockdomain: Connect clockdomain code to powerdomain code Tony Lindgren
2008-07-16 15:19 ` [PATCH 07/10] ARM: OMAP2: Clockdomain: Encode OMAP2/3 clockdomains Tony Lindgren
2008-07-16 15:19 ` [PATCH 08/10] ARM: OMAP2: Clockdomain: Associate clocks with clockdomains Tony Lindgren
2008-07-16 15:19 ` [PATCH 09/10] ARM: OMAP2: Clockdomain: Integrate OMAP3 clocks with clockdomain code Tony Lindgren
2008-07-16 15:19 ` [PATCH 10/10] ARM: OMAP2: Clock: Combine 34xx l3_icks and l4_icks Tony Lindgren
2008-07-21 22:29 ` [PATCH 0/0] Power domain and clock domain patches for omap Russell King - ARM Linux
2008-07-25 0:53 ` David Brownell
2008-08-18 16:34 ` Russell King - ARM Linux
2008-08-19 8:39 ` git-pull request for omap2-clock branch Tony Lindgren
2008-08-19 8:39 ` [PATCH 01/10] ARM: OMAP2: Powerdomain: Add base OMAP2/3 powerdomain code Tony Lindgren
2008-08-19 8:39 ` [PATCH 02/10] ARM: OMAP2: Powerdomain: Add OMAP2/3 common powerdomains Tony Lindgren
2008-08-19 8:39 ` [PATCH 03/10] ARM: OMAP2: Powerdomain: Add OMAP2 powerdomains Tony Lindgren
2008-08-19 8:39 ` [PATCH 04/10] ARM: OMAP: Powerdomain: Add OMAP3 powerdomains Tony Lindgren
2008-08-19 8:39 ` [PATCH 05/10] ARM: OMAP2: Clockdomain: Add base OMAP2/3 clockdomain code Tony Lindgren
2008-08-19 8:39 ` Tony Lindgren [this message]
2008-08-19 8:39 ` [PATCH 07/10] ARM: OMAP2: Clockdomain: Encode OMAP2/3 clockdomains Tony Lindgren
2008-08-19 8:39 ` [PATCH 08/10] ARM: OMAP2: Clockdomain: Associate clocks with clockdomains Tony Lindgren
2008-08-19 8:40 ` [PATCH 09/10] ARM: OMAP2: Clockdomain: Integrate OMAP3 clocks with clockdomain code Tony Lindgren
2008-08-19 8:40 ` [PATCH 10/10] ARM: OMAP2: Clock: Combine 34xx l3_icks and l4_icks Tony Lindgren
2008-08-19 9:11 ` git-pull request for omap2-clock branch Russell King - ARM Linux
2008-08-19 21:46 ` [PATCH 0/0] Power domain and clock domain patches for omap Dmitry Baryshkov
2008-08-20 6:38 ` Paul Walmsley
2008-08-20 8:20 ` Dmitry Baryshkov
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=1219135201-10282-7-git-send-email-tony@atomide.com \
--to=tony@atomide.com \
--cc=linux-arm-kernel@lists.arm.linux.org.uk \
--cc=linux-omap@vger.kernel.org \
--cc=paul@pwsan.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