summaryrefslogtreecommitdiff
path: root/arch/arm/plat-omap
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-07-26 17:42:18 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-26 17:42:18 -0700
commitb0189cd087aa82bd23277cb5c8960ab030e13e5c (patch)
tree7b1a4c152cd62ce136fd5b0e4379d58eb2244e66 /arch/arm/plat-omap
parent69f1d1a6acbaa7d83ef3f4ee26209c58cd000204 (diff)
parentbc574e190d3fbed37d724e33a16aee326d6f2ac4 (diff)
Merge branch 'next/devel2' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/linux-arm-soc
* 'next/devel2' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/linux-arm-soc: (47 commits) OMAP: Add debugfs node to show the summary of all clocks OMAP2+: hwmod: Follow the recommended PRCM module enable sequence OMAP2+: clock: allow per-SoC clock init code to prevent clockdomain calls from clock code OMAP2+: clockdomain: Add per clkdm lock to prevent concurrent state programming OMAP2+: PM: idle clkdms only if already in idle OMAP2+: clockdomain: add clkdm_in_hwsup() OMAP2+: clockdomain: Add 2 APIs to control clockdomain from hwmod framework OMAP: clockdomain: Remove redundant call to pwrdm_wait_transition() OMAP4: hwmod: Introduce the module control in hwmod control OMAP4: cm: Add two new APIs for modulemode control OMAP4: hwmod data: Add modulemode entry in omap_hwmod structure OMAP4: hwmod data: Add PRM context register offset OMAP4: prm: Remove deprecated functions OMAP4: prm: Replace warm reset API with the offset based version OMAP4: hwmod: Replace RSTCTRL absolute address with offset macros OMAP: hwmod: Wait the idle status to be disabled OMAP4: hwmod: Replace CLKCTRL absolute address with offset macros OMAP2+: hwmod: Init clkdm field at boot time OMAP4: hwmod data: Add clock domain attribute OMAP4: clock data: Add missing divider selection for auxclks ...
Diffstat (limited to 'arch/arm/plat-omap')
-rw-r--r--arch/arm/plat-omap/clock.c39
-rw-r--r--arch/arm/plat-omap/include/plat/irqs.h12
-rw-r--r--arch/arm/plat-omap/include/plat/omap_hwmod.h14
-rw-r--r--arch/arm/plat-omap/omap_device.c85
4 files changed, 111 insertions, 39 deletions
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
index 964704f40bbe..3ba4d11ca73e 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -475,8 +475,41 @@ int __init clk_init(struct clk_functions * custom_clocks)
/*
* debugfs support to trace clock tree hierarchy and attributes
*/
+
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
static struct dentry *clk_debugfs_root;
+static int clk_dbg_show_summary(struct seq_file *s, void *unused)
+{
+ struct clk *c;
+ struct clk *pa;
+
+ seq_printf(s, "%-30s %-30s %-10s %s\n",
+ "clock-name", "parent-name", "rate", "use-count");
+
+ list_for_each_entry(c, &clocks, node) {
+ pa = c->parent;
+ seq_printf(s, "%-30s %-30s %-10lu %d\n",
+ c->name, pa ? pa->name : "none", c->rate, c->usecount);
+ }
+
+ return 0;
+}
+
+static int clk_dbg_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, clk_dbg_show_summary, inode->i_private);
+}
+
+static const struct file_operations debug_clock_fops = {
+ .open = clk_dbg_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
static int clk_debugfs_register_one(struct clk *c)
{
int err;
@@ -545,6 +578,12 @@ static int __init clk_debugfs_init(void)
if (err)
goto err_out;
}
+
+ d = debugfs_create_file("summary", S_IRUGO,
+ d, NULL, &debug_clock_fops);
+ if (!d)
+ return -ENOMEM;
+
return 0;
err_out:
debugfs_remove_recursive(clk_debugfs_root);
diff --git a/arch/arm/plat-omap/include/plat/irqs.h b/arch/arm/plat-omap/include/plat/irqs.h
index c88432005665..926d25c780f3 100644
--- a/arch/arm/plat-omap/include/plat/irqs.h
+++ b/arch/arm/plat-omap/include/plat/irqs.h
@@ -407,11 +407,19 @@
#endif
#define TWL6030_IRQ_END (TWL6030_IRQ_BASE + TWL6030_BASE_NR_IRQS)
+#define TWL6040_CODEC_IRQ_BASE TWL6030_IRQ_END
+#ifdef CONFIG_TWL6040_CODEC
+#define TWL6040_CODEC_NR_IRQS 6
+#else
+#define TWL6040_CODEC_NR_IRQS 0
+#endif
+#define TWL6040_CODEC_IRQ_END (TWL6040_CODEC_IRQ_BASE + TWL6040_CODEC_NR_IRQS)
+
/* Total number of interrupts depends on the enabled blocks above */
-#if (TWL4030_GPIO_IRQ_END > TWL6030_IRQ_END)
+#if (TWL4030_GPIO_IRQ_END > TWL6040_CODEC_IRQ_END)
#define TWL_IRQ_END TWL4030_GPIO_IRQ_END
#else
-#define TWL_IRQ_END TWL6030_IRQ_END
+#define TWL_IRQ_END TWL6040_CODEC_IRQ_END
#endif
/* GPMC related */
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index fafdfe3c8d4e..0e329ca88a70 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -2,6 +2,7 @@
* omap_hwmod macros, structures
*
* Copyright (C) 2009-2011 Nokia Corporation
+ * Copyright (C) 2011 Texas Instruments, Inc.
* Paul Walmsley
*
* Created in collaboration with (alphabetical order): BenoƮt Cousson,
@@ -79,6 +80,11 @@ extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2;
#define HWMOD_IDLEMODE_SMART (1 << 2)
#define HWMOD_IDLEMODE_SMART_WKUP (1 << 3)
+/* modulemode control type (SW or HW) */
+#define MODULEMODE_HWCTRL 1
+#define MODULEMODE_SWCTRL 2
+
+
/**
* struct omap_hwmod_mux_info - hwmod specific mux configuration
* @pads: array of omap_device_pad entries
@@ -360,9 +366,11 @@ struct omap_hwmod_omap2_prcm {
* @submodule_wkdep_bit: bit shift of the WKDEP range
*/
struct omap_hwmod_omap4_prcm {
- void __iomem *clkctrl_reg;
- void __iomem *rstctrl_reg;
+ u16 clkctrl_offs;
+ u16 rstctrl_offs;
+ u16 context_offs;
u8 submodule_wkdep_bit;
+ u8 modulemode;
};
@@ -515,6 +523,8 @@ struct omap_hwmod {
const char *main_clk;
struct clk *_clk;
struct omap_hwmod_opt_clk *opt_clks;
+ char *clkdm_name;
+ struct clockdomain *clkdm;
char *vdd_name;
struct voltagedomain *voltdm;
struct omap_hwmod_ocp_if **masters; /* connect to *_IA */
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index 3471c650743b..b6b409744954 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -236,56 +236,71 @@ static int _omap_device_deactivate(struct omap_device *od, u8 ignore_lat)
return 0;
}
+static void _add_clkdev(struct omap_device *od, const char *clk_alias,
+ const char *clk_name)
+{
+ struct clk *r;
+ struct clk_lookup *l;
+
+ if (!clk_alias || !clk_name)
+ return;
+
+ pr_debug("omap_device: %s: Creating %s -> %s\n",
+ dev_name(&od->pdev.dev), clk_alias, clk_name);
+
+ r = clk_get_sys(dev_name(&od->pdev.dev), clk_alias);
+ if (!IS_ERR(r)) {
+ pr_warning("omap_device: %s: alias %s already exists\n",
+ dev_name(&od->pdev.dev), clk_alias);
+ clk_put(r);
+ return;
+ }
+
+ r = omap_clk_get_by_name(clk_name);
+ if (IS_ERR(r)) {
+ pr_err("omap_device: %s: omap_clk_get_by_name for %s failed\n",
+ dev_name(&od->pdev.dev), clk_name);
+ return;
+ }
+
+ l = clkdev_alloc(r, clk_alias, dev_name(&od->pdev.dev));
+ if (!l) {
+ pr_err("omap_device: %s: clkdev_alloc for %s failed\n",
+ dev_name(&od->pdev.dev), clk_alias);
+ return;
+ }
+
+ clkdev_add(l);
+}
+
/**
- * _add_optional_clock_clkdev - Add clkdev entry for hwmod optional clocks
+ * _add_hwmod_clocks_clkdev - Add clkdev entry for hwmod optional clocks
+ * and main clock
* @od: struct omap_device *od
+ * @oh: struct omap_hwmod *oh
*
- * For every optional clock present per hwmod per omap_device, this function
- * adds an entry in the clkdev table of the form <dev-id=dev_name, con-id=role>
- * if it does not exist already.
+ * For the main clock and every optional clock present per hwmod per
+ * omap_device, this function adds an entry in the clkdev table of the
+ * form <dev-id=dev_name, con-id=role> if it does not exist already.
*
* The function is called from inside omap_device_build_ss(), after
* omap_device_register.
*
* This allows drivers to get a pointer to its optional clocks based on its role
* by calling clk_get(<dev*>, <role>).
+ * In the case of the main clock, a "fck" alias is used.
*
* No return value.
*/
-static void _add_optional_clock_clkdev(struct omap_device *od,
- struct omap_hwmod *oh)
+static void _add_hwmod_clocks_clkdev(struct omap_device *od,
+ struct omap_hwmod *oh)
{
int i;
- for (i = 0; i < oh->opt_clks_cnt; i++) {
- struct omap_hwmod_opt_clk *oc;
- struct clk *r;
- struct clk_lookup *l;
-
- oc = &oh->opt_clks[i];
-
- if (!oc->_clk)
- continue;
-
- r = clk_get_sys(dev_name(&od->pdev.dev), oc->role);
- if (!IS_ERR(r))
- continue; /* clkdev entry exists */
+ _add_clkdev(od, "fck", oh->main_clk);
- r = omap_clk_get_by_name((char *)oc->clk);
- if (IS_ERR(r)) {
- pr_err("omap_device: %s: omap_clk_get_by_name for %s failed\n",
- dev_name(&od->pdev.dev), oc->clk);
- continue;
- }
-
- l = clkdev_alloc(r, oc->role, dev_name(&od->pdev.dev));
- if (!l) {
- pr_err("omap_device: %s: clkdev_alloc for %s failed\n",
- dev_name(&od->pdev.dev), oc->role);
- return;
- }
- clkdev_add(l);
- }
+ for (i = 0; i < oh->opt_clks_cnt; i++)
+ _add_clkdev(od, oh->opt_clks[i].role, oh->opt_clks[i].clk);
}
@@ -492,7 +507,7 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
for (i = 0; i < oh_cnt; i++) {
hwmods[i]->od = od;
- _add_optional_clock_clkdev(od, hwmods[i]);
+ _add_hwmod_clocks_clkdev(od, hwmods[i]);
}
if (ret)