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); |
