diff options
author | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2014-10-09 10:03:14 -0400 |
---|---|---|
committer | Paul Walmsley <paul@pwsan.com> | 2014-11-19 16:48:12 -0500 |
commit | f22d2545517a0ffb8da2879d3a0dbcae99848e6c (patch) | |
tree | 2be242c29d4b38a788fdfd5d58a51805a54082f9 | |
parent | 79005fbd3e1d671d08c45c9140ee9826efdc367c (diff) |
ARM: OMAP2+: hwmod: add parent_hwmod support
Add parent_hwmod pointer to omap_hwmod. This can be set to point to a
"parent" hwmod that needs to be enabled for the "child" hwmod to work.
This is used at hwmod setup time: when doing the initial setup and
reset, first enable the parent hwmod, and after setup and reset is done,
restore the parent hwmod to postsetup_state.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Reviewed-by: Archit Taneja <archit.taneja@gmail.com>
[paul@pwsan.com: add kerneldoc documentation for parent_hwmod; note that it
is a temporary workaround]
Signed-off-by: Paul Walmsley <paul@pwsan.com>
-rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.c | 22 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.h | 8 |
2 files changed, 30 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index acae6d5d1151..a2c7b300fe89 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c | |||
@@ -2719,11 +2719,33 @@ static int __init _setup(struct omap_hwmod *oh, void *data) | |||
2719 | if (oh->_state != _HWMOD_STATE_INITIALIZED) | 2719 | if (oh->_state != _HWMOD_STATE_INITIALIZED) |
2720 | return 0; | 2720 | return 0; |
2721 | 2721 | ||
2722 | if (oh->parent_hwmod) { | ||
2723 | int r; | ||
2724 | |||
2725 | r = _enable(oh->parent_hwmod); | ||
2726 | WARN(r, "hwmod: %s: setup: failed to enable parent hwmod %s\n", | ||
2727 | oh->name, oh->parent_hwmod->name); | ||
2728 | } | ||
2729 | |||
2722 | _setup_iclk_autoidle(oh); | 2730 | _setup_iclk_autoidle(oh); |
2723 | 2731 | ||
2724 | if (!_setup_reset(oh)) | 2732 | if (!_setup_reset(oh)) |
2725 | _setup_postsetup(oh); | 2733 | _setup_postsetup(oh); |
2726 | 2734 | ||
2735 | if (oh->parent_hwmod) { | ||
2736 | u8 postsetup_state; | ||
2737 | |||
2738 | postsetup_state = oh->parent_hwmod->_postsetup_state; | ||
2739 | |||
2740 | if (postsetup_state == _HWMOD_STATE_IDLE) | ||
2741 | _idle(oh->parent_hwmod); | ||
2742 | else if (postsetup_state == _HWMOD_STATE_DISABLED) | ||
2743 | _shutdown(oh->parent_hwmod); | ||
2744 | else if (postsetup_state != _HWMOD_STATE_ENABLED) | ||
2745 | WARN(1, "hwmod: %s: unknown postsetup state %d! defaulting to enabled\n", | ||
2746 | oh->parent_hwmod->name, postsetup_state); | ||
2747 | } | ||
2748 | |||
2727 | return 0; | 2749 | return 0; |
2728 | } | 2750 | } |
2729 | 2751 | ||
diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h index 512f809a3f4d..35ca6efbec31 100644 --- a/arch/arm/mach-omap2/omap_hwmod.h +++ b/arch/arm/mach-omap2/omap_hwmod.h | |||
@@ -633,6 +633,7 @@ struct omap_hwmod_link { | |||
633 | * @flags: hwmod flags (documented below) | 633 | * @flags: hwmod flags (documented below) |
634 | * @_lock: spinlock serializing operations on this hwmod | 634 | * @_lock: spinlock serializing operations on this hwmod |
635 | * @node: list node for hwmod list (internal use) | 635 | * @node: list node for hwmod list (internal use) |
636 | * @parent_hwmod: (temporary) a pointer to the hierarchical parent of this hwmod | ||
636 | * | 637 | * |
637 | * @main_clk refers to this module's "main clock," which for our | 638 | * @main_clk refers to this module's "main clock," which for our |
638 | * purposes is defined as "the functional clock needed for register | 639 | * purposes is defined as "the functional clock needed for register |
@@ -643,6 +644,12 @@ struct omap_hwmod_link { | |||
643 | * the omap_hwmod code and should not be set during initialization. | 644 | * the omap_hwmod code and should not be set during initialization. |
644 | * | 645 | * |
645 | * @masters and @slaves are now deprecated. | 646 | * @masters and @slaves are now deprecated. |
647 | * | ||
648 | * @parent_hwmod is temporary; there should be no need for it, as this | ||
649 | * information should already be expressed in the OCP interface | ||
650 | * structures. @parent_hwmod is present as a workaround until we improve | ||
651 | * handling for hwmods with multiple parents (e.g., OMAP4+ DSS with | ||
652 | * multiple register targets across different interconnects). | ||
646 | */ | 653 | */ |
647 | struct omap_hwmod { | 654 | struct omap_hwmod { |
648 | const char *name; | 655 | const char *name; |
@@ -680,6 +687,7 @@ struct omap_hwmod { | |||
680 | u8 _int_flags; | 687 | u8 _int_flags; |
681 | u8 _state; | 688 | u8 _state; |
682 | u8 _postsetup_state; | 689 | u8 _postsetup_state; |
690 | struct omap_hwmod *parent_hwmod; | ||
683 | }; | 691 | }; |
684 | 692 | ||
685 | struct omap_hwmod *omap_hwmod_lookup(const char *name); | 693 | struct omap_hwmod *omap_hwmod_lookup(const char *name); |