diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-26 20:42:18 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-26 20:42:18 -0400 |
commit | b0189cd087aa82bd23277cb5c8960ab030e13e5c (patch) | |
tree | 7b1a4c152cd62ce136fd5b0e4379d58eb2244e66 /arch/arm/plat-omap | |
parent | 69f1d1a6acbaa7d83ef3f4ee26209c58cd000204 (diff) | |
parent | bc574e190d3fbed37d724e33a16aee326d6f2ac4 (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.c | 39 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/irqs.h | 12 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/omap_hwmod.h | 14 | ||||
-rw-r--r-- | arch/arm/plat-omap/omap_device.c | 85 |
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) | |||
475 | /* | 475 | /* |
476 | * debugfs support to trace clock tree hierarchy and attributes | 476 | * debugfs support to trace clock tree hierarchy and attributes |
477 | */ | 477 | */ |
478 | |||
479 | #include <linux/debugfs.h> | ||
480 | #include <linux/seq_file.h> | ||
481 | |||
478 | static struct dentry *clk_debugfs_root; | 482 | static struct dentry *clk_debugfs_root; |
479 | 483 | ||
484 | static int clk_dbg_show_summary(struct seq_file *s, void *unused) | ||
485 | { | ||
486 | struct clk *c; | ||
487 | struct clk *pa; | ||
488 | |||
489 | seq_printf(s, "%-30s %-30s %-10s %s\n", | ||
490 | "clock-name", "parent-name", "rate", "use-count"); | ||
491 | |||
492 | list_for_each_entry(c, &clocks, node) { | ||
493 | pa = c->parent; | ||
494 | seq_printf(s, "%-30s %-30s %-10lu %d\n", | ||
495 | c->name, pa ? pa->name : "none", c->rate, c->usecount); | ||
496 | } | ||
497 | |||
498 | return 0; | ||
499 | } | ||
500 | |||
501 | static int clk_dbg_open(struct inode *inode, struct file *file) | ||
502 | { | ||
503 | return single_open(file, clk_dbg_show_summary, inode->i_private); | ||
504 | } | ||
505 | |||
506 | static const struct file_operations debug_clock_fops = { | ||
507 | .open = clk_dbg_open, | ||
508 | .read = seq_read, | ||
509 | .llseek = seq_lseek, | ||
510 | .release = single_release, | ||
511 | }; | ||
512 | |||
480 | static int clk_debugfs_register_one(struct clk *c) | 513 | static int clk_debugfs_register_one(struct clk *c) |
481 | { | 514 | { |
482 | int err; | 515 | int err; |
@@ -545,6 +578,12 @@ static int __init clk_debugfs_init(void) | |||
545 | if (err) | 578 | if (err) |
546 | goto err_out; | 579 | goto err_out; |
547 | } | 580 | } |
581 | |||
582 | d = debugfs_create_file("summary", S_IRUGO, | ||
583 | d, NULL, &debug_clock_fops); | ||
584 | if (!d) | ||
585 | return -ENOMEM; | ||
586 | |||
548 | return 0; | 587 | return 0; |
549 | err_out: | 588 | err_out: |
550 | debugfs_remove_recursive(clk_debugfs_root); | 589 | 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 @@ | |||
407 | #endif | 407 | #endif |
408 | #define TWL6030_IRQ_END (TWL6030_IRQ_BASE + TWL6030_BASE_NR_IRQS) | 408 | #define TWL6030_IRQ_END (TWL6030_IRQ_BASE + TWL6030_BASE_NR_IRQS) |
409 | 409 | ||
410 | #define TWL6040_CODEC_IRQ_BASE TWL6030_IRQ_END | ||
411 | #ifdef CONFIG_TWL6040_CODEC | ||
412 | #define TWL6040_CODEC_NR_IRQS 6 | ||
413 | #else | ||
414 | #define TWL6040_CODEC_NR_IRQS 0 | ||
415 | #endif | ||
416 | #define TWL6040_CODEC_IRQ_END (TWL6040_CODEC_IRQ_BASE + TWL6040_CODEC_NR_IRQS) | ||
417 | |||
410 | /* Total number of interrupts depends on the enabled blocks above */ | 418 | /* Total number of interrupts depends on the enabled blocks above */ |
411 | #if (TWL4030_GPIO_IRQ_END > TWL6030_IRQ_END) | 419 | #if (TWL4030_GPIO_IRQ_END > TWL6040_CODEC_IRQ_END) |
412 | #define TWL_IRQ_END TWL4030_GPIO_IRQ_END | 420 | #define TWL_IRQ_END TWL4030_GPIO_IRQ_END |
413 | #else | 421 | #else |
414 | #define TWL_IRQ_END TWL6030_IRQ_END | 422 | #define TWL_IRQ_END TWL6040_CODEC_IRQ_END |
415 | #endif | 423 | #endif |
416 | 424 | ||
417 | /* GPMC related */ | 425 | /* 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 @@ | |||
2 | * omap_hwmod macros, structures | 2 | * omap_hwmod macros, structures |
3 | * | 3 | * |
4 | * Copyright (C) 2009-2011 Nokia Corporation | 4 | * Copyright (C) 2009-2011 Nokia Corporation |
5 | * Copyright (C) 2011 Texas Instruments, Inc. | ||
5 | * Paul Walmsley | 6 | * Paul Walmsley |
6 | * | 7 | * |
7 | * Created in collaboration with (alphabetical order): Benoît Cousson, | 8 | * Created in collaboration with (alphabetical order): Benoît Cousson, |
@@ -79,6 +80,11 @@ extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2; | |||
79 | #define HWMOD_IDLEMODE_SMART (1 << 2) | 80 | #define HWMOD_IDLEMODE_SMART (1 << 2) |
80 | #define HWMOD_IDLEMODE_SMART_WKUP (1 << 3) | 81 | #define HWMOD_IDLEMODE_SMART_WKUP (1 << 3) |
81 | 82 | ||
83 | /* modulemode control type (SW or HW) */ | ||
84 | #define MODULEMODE_HWCTRL 1 | ||
85 | #define MODULEMODE_SWCTRL 2 | ||
86 | |||
87 | |||
82 | /** | 88 | /** |
83 | * struct omap_hwmod_mux_info - hwmod specific mux configuration | 89 | * struct omap_hwmod_mux_info - hwmod specific mux configuration |
84 | * @pads: array of omap_device_pad entries | 90 | * @pads: array of omap_device_pad entries |
@@ -360,9 +366,11 @@ struct omap_hwmod_omap2_prcm { | |||
360 | * @submodule_wkdep_bit: bit shift of the WKDEP range | 366 | * @submodule_wkdep_bit: bit shift of the WKDEP range |
361 | */ | 367 | */ |
362 | struct omap_hwmod_omap4_prcm { | 368 | struct omap_hwmod_omap4_prcm { |
363 | void __iomem *clkctrl_reg; | 369 | u16 clkctrl_offs; |
364 | void __iomem *rstctrl_reg; | 370 | u16 rstctrl_offs; |
371 | u16 context_offs; | ||
365 | u8 submodule_wkdep_bit; | 372 | u8 submodule_wkdep_bit; |
373 | u8 modulemode; | ||
366 | }; | 374 | }; |
367 | 375 | ||
368 | 376 | ||
@@ -515,6 +523,8 @@ struct omap_hwmod { | |||
515 | const char *main_clk; | 523 | const char *main_clk; |
516 | struct clk *_clk; | 524 | struct clk *_clk; |
517 | struct omap_hwmod_opt_clk *opt_clks; | 525 | struct omap_hwmod_opt_clk *opt_clks; |
526 | char *clkdm_name; | ||
527 | struct clockdomain *clkdm; | ||
518 | char *vdd_name; | 528 | char *vdd_name; |
519 | struct voltagedomain *voltdm; | 529 | struct voltagedomain *voltdm; |
520 | struct omap_hwmod_ocp_if **masters; /* connect to *_IA */ | 530 | 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) | |||
236 | return 0; | 236 | return 0; |
237 | } | 237 | } |
238 | 238 | ||
239 | static void _add_clkdev(struct omap_device *od, const char *clk_alias, | ||
240 | const char *clk_name) | ||
241 | { | ||
242 | struct clk *r; | ||
243 | struct clk_lookup *l; | ||
244 | |||
245 | if (!clk_alias || !clk_name) | ||
246 | return; | ||
247 | |||
248 | pr_debug("omap_device: %s: Creating %s -> %s\n", | ||
249 | dev_name(&od->pdev.dev), clk_alias, clk_name); | ||
250 | |||
251 | r = clk_get_sys(dev_name(&od->pdev.dev), clk_alias); | ||
252 | if (!IS_ERR(r)) { | ||
253 | pr_warning("omap_device: %s: alias %s already exists\n", | ||
254 | dev_name(&od->pdev.dev), clk_alias); | ||
255 | clk_put(r); | ||
256 | return; | ||
257 | } | ||
258 | |||
259 | r = omap_clk_get_by_name(clk_name); | ||
260 | if (IS_ERR(r)) { | ||
261 | pr_err("omap_device: %s: omap_clk_get_by_name for %s failed\n", | ||
262 | dev_name(&od->pdev.dev), clk_name); | ||
263 | return; | ||
264 | } | ||
265 | |||
266 | l = clkdev_alloc(r, clk_alias, dev_name(&od->pdev.dev)); | ||
267 | if (!l) { | ||
268 | pr_err("omap_device: %s: clkdev_alloc for %s failed\n", | ||
269 | dev_name(&od->pdev.dev), clk_alias); | ||
270 | return; | ||
271 | } | ||
272 | |||
273 | clkdev_add(l); | ||
274 | } | ||
275 | |||
239 | /** | 276 | /** |
240 | * _add_optional_clock_clkdev - Add clkdev entry for hwmod optional clocks | 277 | * _add_hwmod_clocks_clkdev - Add clkdev entry for hwmod optional clocks |
278 | * and main clock | ||
241 | * @od: struct omap_device *od | 279 | * @od: struct omap_device *od |
280 | * @oh: struct omap_hwmod *oh | ||
242 | * | 281 | * |
243 | * For every optional clock present per hwmod per omap_device, this function | 282 | * For the main clock and every optional clock present per hwmod per |
244 | * adds an entry in the clkdev table of the form <dev-id=dev_name, con-id=role> | 283 | * omap_device, this function adds an entry in the clkdev table of the |
245 | * if it does not exist already. | 284 | * form <dev-id=dev_name, con-id=role> if it does not exist already. |
246 | * | 285 | * |
247 | * The function is called from inside omap_device_build_ss(), after | 286 | * The function is called from inside omap_device_build_ss(), after |
248 | * omap_device_register. | 287 | * omap_device_register. |
249 | * | 288 | * |
250 | * This allows drivers to get a pointer to its optional clocks based on its role | 289 | * This allows drivers to get a pointer to its optional clocks based on its role |
251 | * by calling clk_get(<dev*>, <role>). | 290 | * by calling clk_get(<dev*>, <role>). |
291 | * In the case of the main clock, a "fck" alias is used. | ||
252 | * | 292 | * |
253 | * No return value. | 293 | * No return value. |
254 | */ | 294 | */ |
255 | static void _add_optional_clock_clkdev(struct omap_device *od, | 295 | static void _add_hwmod_clocks_clkdev(struct omap_device *od, |
256 | struct omap_hwmod *oh) | 296 | struct omap_hwmod *oh) |
257 | { | 297 | { |
258 | int i; | 298 | int i; |
259 | 299 | ||
260 | for (i = 0; i < oh->opt_clks_cnt; i++) { | 300 | _add_clkdev(od, "fck", oh->main_clk); |
261 | struct omap_hwmod_opt_clk *oc; | ||
262 | struct clk *r; | ||
263 | struct clk_lookup *l; | ||
264 | |||
265 | oc = &oh->opt_clks[i]; | ||
266 | |||
267 | if (!oc->_clk) | ||
268 | continue; | ||
269 | |||
270 | r = clk_get_sys(dev_name(&od->pdev.dev), oc->role); | ||
271 | if (!IS_ERR(r)) | ||
272 | continue; /* clkdev entry exists */ | ||
273 | 301 | ||
274 | r = omap_clk_get_by_name((char *)oc->clk); | 302 | for (i = 0; i < oh->opt_clks_cnt; i++) |
275 | if (IS_ERR(r)) { | 303 | _add_clkdev(od, oh->opt_clks[i].role, oh->opt_clks[i].clk); |
276 | pr_err("omap_device: %s: omap_clk_get_by_name for %s failed\n", | ||
277 | dev_name(&od->pdev.dev), oc->clk); | ||
278 | continue; | ||
279 | } | ||
280 | |||
281 | l = clkdev_alloc(r, oc->role, dev_name(&od->pdev.dev)); | ||
282 | if (!l) { | ||
283 | pr_err("omap_device: %s: clkdev_alloc for %s failed\n", | ||
284 | dev_name(&od->pdev.dev), oc->role); | ||
285 | return; | ||
286 | } | ||
287 | clkdev_add(l); | ||
288 | } | ||
289 | } | 304 | } |
290 | 305 | ||
291 | 306 | ||
@@ -492,7 +507,7 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id, | |||
492 | 507 | ||
493 | for (i = 0; i < oh_cnt; i++) { | 508 | for (i = 0; i < oh_cnt; i++) { |
494 | hwmods[i]->od = od; | 509 | hwmods[i]->od = od; |
495 | _add_optional_clock_clkdev(od, hwmods[i]); | 510 | _add_hwmod_clocks_clkdev(od, hwmods[i]); |
496 | } | 511 | } |
497 | 512 | ||
498 | if (ret) | 513 | if (ret) |