aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2012-11-26 15:32:50 -0500
committerTony Lindgren <tony@atomide.com>2012-11-26 15:32:50 -0500
commit8b9c1ac2e11a9fb3a5a8860fb7570ff7633aa7f7 (patch)
tree282feb4b7a0f4b430b363048616f50e27f656594
parent558a0780b0a04862a678f7823215424b4e5501f9 (diff)
parentc567b0584c352e7f97ced003be46bed8581ddd5b (diff)
Merge tag 'omap-devel-a-for-3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/pjw/omap-pending into omap-for-v3.8/devel-pcrm
Some miscellaneous OMAP hwmod changes for 3.8, along with a PRM change needed for one of the hwmod patches to function. Basic test logs for this branch on top of Tony's omap-for-v3.8/clock branch at commit 558a0780b0a04862a678f7823215424b4e5501f9 are here: http://www.pwsan.com/omap/testlogs/hwmod_devel_a_3.8/20121121161522/ However, omap-for-v3.8/clock at 558a0780 does not include some fixes that are needed for a successful test. With several reverts, fixes, and workarounds applied, the following test logs were obtained: http://www.pwsan.com/omap/testlogs/TEST_hwmod_devel_a_3.8/20121121162719/ which indicate that the series tests cleanly.
-rw-r--r--arch/arm/mach-omap2/io.c8
-rw-r--r--arch/arm/mach-omap2/omap_device.c87
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c82
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.h12
-rw-r--r--arch/arm/mach-omap2/prm.h11
-rw-r--r--arch/arm/mach-omap2/prm2xxx.c3
-rw-r--r--arch/arm/mach-omap2/prm2xxx.h3
-rw-r--r--arch/arm/mach-omap2/prm3xxx.c17
-rw-r--r--arch/arm/mach-omap2/prm3xxx.h1
-rw-r--r--arch/arm/mach-omap2/prm44xx.c49
-rw-r--r--arch/arm/mach-omap2/prm44xx.h1
-rw-r--r--arch/arm/mach-omap2/prm_common.c45
12 files changed, 249 insertions, 70 deletions
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 924bf24693cd..007dc4d85d54 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -51,6 +51,10 @@
51#include "prcm_mpu44xx.h" 51#include "prcm_mpu44xx.h"
52#include "prminst44xx.h" 52#include "prminst44xx.h"
53#include "cminst44xx.h" 53#include "cminst44xx.h"
54#include "prm2xxx.h"
55#include "prm3xxx.h"
56#include "prm44xx.h"
57
54/* 58/*
55 * The machine specific code may provide the extra mapping besides the 59 * The machine specific code may provide the extra mapping besides the
56 * default mapping provided here. 60 * default mapping provided here.
@@ -392,6 +396,7 @@ void __init omap2420_init_early(void)
392 omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP2420_PRM_BASE)); 396 omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP2420_PRM_BASE));
393 omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP2420_CM_BASE), NULL); 397 omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP2420_CM_BASE), NULL);
394 omap2xxx_check_revision(); 398 omap2xxx_check_revision();
399 omap2xxx_prm_init();
395 omap2xxx_cm_init(); 400 omap2xxx_cm_init();
396 omap_common_init_early(); 401 omap_common_init_early();
397 omap2xxx_voltagedomains_init(); 402 omap2xxx_voltagedomains_init();
@@ -422,6 +427,7 @@ void __init omap2430_init_early(void)
422 omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP2430_PRM_BASE)); 427 omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP2430_PRM_BASE));
423 omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP2430_CM_BASE), NULL); 428 omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP2430_CM_BASE), NULL);
424 omap2xxx_check_revision(); 429 omap2xxx_check_revision();
430 omap2xxx_prm_init();
425 omap2xxx_cm_init(); 431 omap2xxx_cm_init();
426 omap_common_init_early(); 432 omap_common_init_early();
427 omap2xxx_voltagedomains_init(); 433 omap2xxx_voltagedomains_init();
@@ -457,6 +463,7 @@ void __init omap3_init_early(void)
457 omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE), NULL); 463 omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE), NULL);
458 omap3xxx_check_revision(); 464 omap3xxx_check_revision();
459 omap3xxx_check_features(); 465 omap3xxx_check_features();
466 omap3xxx_prm_init();
460 omap3xxx_cm_init(); 467 omap3xxx_cm_init();
461 omap_common_init_early(); 468 omap_common_init_early();
462 omap3xxx_voltagedomains_init(); 469 omap3xxx_voltagedomains_init();
@@ -591,6 +598,7 @@ void __init omap4430_init_early(void)
591 omap_cm_base_init(); 598 omap_cm_base_init();
592 omap4xxx_check_revision(); 599 omap4xxx_check_revision();
593 omap4xxx_check_features(); 600 omap4xxx_check_features();
601 omap44xx_prm_init();
594 omap_common_init_early(); 602 omap_common_init_early();
595 omap44xx_voltagedomains_init(); 603 omap44xx_voltagedomains_init();
596 omap44xx_powerdomains_init(); 604 omap44xx_powerdomains_init();
diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c
index 0ef934fec364..e065daa537c0 100644
--- a/arch/arm/mach-omap2/omap_device.c
+++ b/arch/arm/mach-omap2/omap_device.c
@@ -441,19 +441,21 @@ int omap_device_get_context_loss_count(struct platform_device *pdev)
441/** 441/**
442 * omap_device_count_resources - count number of struct resource entries needed 442 * omap_device_count_resources - count number of struct resource entries needed
443 * @od: struct omap_device * 443 * @od: struct omap_device *
444 * @flags: Type of resources to include when counting (IRQ/DMA/MEM)
444 * 445 *
445 * Count the number of struct resource entries needed for this 446 * Count the number of struct resource entries needed for this
446 * omap_device @od. Used by omap_device_build_ss() to determine how 447 * omap_device @od. Used by omap_device_build_ss() to determine how
447 * much memory to allocate before calling 448 * much memory to allocate before calling
448 * omap_device_fill_resources(). Returns the count. 449 * omap_device_fill_resources(). Returns the count.
449 */ 450 */
450static int omap_device_count_resources(struct omap_device *od) 451static int omap_device_count_resources(struct omap_device *od,
452 unsigned long flags)
451{ 453{
452 int c = 0; 454 int c = 0;
453 int i; 455 int i;
454 456
455 for (i = 0; i < od->hwmods_cnt; i++) 457 for (i = 0; i < od->hwmods_cnt; i++)
456 c += omap_hwmod_count_resources(od->hwmods[i]); 458 c += omap_hwmod_count_resources(od->hwmods[i], flags);
457 459
458 pr_debug("omap_device: %s: counted %d total resources across %d hwmods\n", 460 pr_debug("omap_device: %s: counted %d total resources across %d hwmods\n",
459 od->pdev->name, c, od->hwmods_cnt); 461 od->pdev->name, c, od->hwmods_cnt);
@@ -557,52 +559,73 @@ struct omap_device *omap_device_alloc(struct platform_device *pdev,
557 od->hwmods = hwmods; 559 od->hwmods = hwmods;
558 od->pdev = pdev; 560 od->pdev = pdev;
559 561
560 res_count = omap_device_count_resources(od);
561 /* 562 /*
563 * Non-DT Boot:
564 * Here, pdev->num_resources = 0, and we should get all the
565 * resources from hwmod.
566 *
562 * DT Boot: 567 * DT Boot:
563 * OF framework will construct the resource structure (currently 568 * OF framework will construct the resource structure (currently
564 * does for MEM & IRQ resource) and we should respect/use these 569 * does for MEM & IRQ resource) and we should respect/use these
565 * resources, killing hwmod dependency. 570 * resources, killing hwmod dependency.
566 * If pdev->num_resources > 0, we assume that MEM & IRQ resources 571 * If pdev->num_resources > 0, we assume that MEM & IRQ resources
567 * have been allocated by OF layer already (through DTB). 572 * have been allocated by OF layer already (through DTB).
568 * 573 * As preparation for the future we examine the OF provided resources
569 * Non-DT Boot: 574 * to see if we have DMA resources provided already. In this case
570 * Here, pdev->num_resources = 0, and we should get all the 575 * there is no need to update the resources for the device, we use the
571 * resources from hwmod. 576 * OF provided ones.
572 * 577 *
573 * TODO: Once DMA resource is available from OF layer, we should 578 * TODO: Once DMA resource is available from OF layer, we should
574 * kill filling any resources from hwmod. 579 * kill filling any resources from hwmod.
575 */ 580 */
576 if (res_count > pdev->num_resources) { 581 if (!pdev->num_resources) {
577 /* Allocate resources memory to account for new resources */ 582 /* Count all resources for the device */
578 res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL); 583 res_count = omap_device_count_resources(od, IORESOURCE_IRQ |
579 if (!res) 584 IORESOURCE_DMA |
580 goto oda_exit3; 585 IORESOURCE_MEM);
581 586 } else {
582 /* 587 /* Take a look if we already have DMA resource via DT */
583 * If pdev->num_resources > 0, then assume that, 588 for (i = 0; i < pdev->num_resources; i++) {
584 * MEM and IRQ resources will only come from DT and only 589 struct resource *r = &pdev->resource[i];
585 * fill DMA resource from hwmod layer. 590
586 */ 591 /* We have it, no need to touch the resources */
587 if (pdev->num_resources && pdev->resource) { 592 if (r->flags == IORESOURCE_DMA)
588 dev_dbg(&pdev->dev, "%s(): resources already allocated %d\n", 593 goto have_everything;
589 __func__, res_count);
590 memcpy(res, pdev->resource,
591 sizeof(struct resource) * pdev->num_resources);
592 _od_fill_dma_resources(od, &res[pdev->num_resources]);
593 } else {
594 dev_dbg(&pdev->dev, "%s(): using resources from hwmod %d\n",
595 __func__, res_count);
596 omap_device_fill_resources(od, res);
597 } 594 }
595 /* Count only DMA resources for the device */
596 res_count = omap_device_count_resources(od, IORESOURCE_DMA);
597 /* The device has no DMA resource, no need for update */
598 if (!res_count)
599 goto have_everything;
598 600
599 ret = platform_device_add_resources(pdev, res, res_count); 601 res_count += pdev->num_resources;
600 kfree(res); 602 }
601 603
602 if (ret) 604 /* Allocate resources memory to account for new resources */
603 goto oda_exit3; 605 res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL);
606 if (!res)
607 goto oda_exit3;
608
609 if (!pdev->num_resources) {
610 dev_dbg(&pdev->dev, "%s: using %d resources from hwmod\n",
611 __func__, res_count);
612 omap_device_fill_resources(od, res);
613 } else {
614 dev_dbg(&pdev->dev,
615 "%s: appending %d DMA resources from hwmod\n",
616 __func__, res_count - pdev->num_resources);
617 memcpy(res, pdev->resource,
618 sizeof(struct resource) * pdev->num_resources);
619 _od_fill_dma_resources(od, &res[pdev->num_resources]);
604 } 620 }
605 621
622 ret = platform_device_add_resources(pdev, res, res_count);
623 kfree(res);
624
625 if (ret)
626 goto oda_exit3;
627
628have_everything:
606 if (!pm_lats) { 629 if (!pm_lats) {
607 pm_lats = omap_default_latency; 630 pm_lats = omap_default_latency;
608 pm_lats_cnt = ARRAY_SIZE(omap_default_latency); 631 pm_lats_cnt = ARRAY_SIZE(omap_default_latency);
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 68616b2b5b96..a8090907fe35 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -187,6 +187,8 @@ struct omap_hwmod_soc_ops {
187 int (*is_hardreset_asserted)(struct omap_hwmod *oh, 187 int (*is_hardreset_asserted)(struct omap_hwmod *oh,
188 struct omap_hwmod_rst_info *ohri); 188 struct omap_hwmod_rst_info *ohri);
189 int (*init_clkdm)(struct omap_hwmod *oh); 189 int (*init_clkdm)(struct omap_hwmod *oh);
190 void (*update_context_lost)(struct omap_hwmod *oh);
191 int (*get_context_lost)(struct omap_hwmod *oh);
190}; 192};
191 193
192/* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */ 194/* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */
@@ -1983,6 +1985,42 @@ static void _reconfigure_io_chain(void)
1983} 1985}
1984 1986
1985/** 1987/**
1988 * _omap4_update_context_lost - increment hwmod context loss counter if
1989 * hwmod context was lost, and clear hardware context loss reg
1990 * @oh: hwmod to check for context loss
1991 *
1992 * If the PRCM indicates that the hwmod @oh lost context, increment
1993 * our in-memory context loss counter, and clear the RM_*_CONTEXT
1994 * bits. No return value.
1995 */
1996static void _omap4_update_context_lost(struct omap_hwmod *oh)
1997{
1998 if (oh->prcm.omap4.flags & HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT)
1999 return;
2000
2001 if (!prm_was_any_context_lost_old(oh->clkdm->pwrdm.ptr->prcm_partition,
2002 oh->clkdm->pwrdm.ptr->prcm_offs,
2003 oh->prcm.omap4.context_offs))
2004 return;
2005
2006 oh->prcm.omap4.context_lost_counter++;
2007 prm_clear_context_loss_flags_old(oh->clkdm->pwrdm.ptr->prcm_partition,
2008 oh->clkdm->pwrdm.ptr->prcm_offs,
2009 oh->prcm.omap4.context_offs);
2010}
2011
2012/**
2013 * _omap4_get_context_lost - get context loss counter for a hwmod
2014 * @oh: hwmod to get context loss counter for
2015 *
2016 * Returns the in-memory context loss counter for a hwmod.
2017 */
2018static int _omap4_get_context_lost(struct omap_hwmod *oh)
2019{
2020 return oh->prcm.omap4.context_lost_counter;
2021}
2022
2023/**
1986 * _enable - enable an omap_hwmod 2024 * _enable - enable an omap_hwmod
1987 * @oh: struct omap_hwmod * 2025 * @oh: struct omap_hwmod *
1988 * 2026 *
@@ -2065,6 +2103,9 @@ static int _enable(struct omap_hwmod *oh)
2065 if (soc_ops.enable_module) 2103 if (soc_ops.enable_module)
2066 soc_ops.enable_module(oh); 2104 soc_ops.enable_module(oh);
2067 2105
2106 if (soc_ops.update_context_lost)
2107 soc_ops.update_context_lost(oh);
2108
2068 r = (soc_ops.wait_target_ready) ? soc_ops.wait_target_ready(oh) : 2109 r = (soc_ops.wait_target_ready) ? soc_ops.wait_target_ready(oh) :
2069 -EINVAL; 2110 -EINVAL;
2070 if (!r) { 2111 if (!r) {
@@ -3386,7 +3427,7 @@ int omap_hwmod_reset(struct omap_hwmod *oh)
3386/** 3427/**
3387 * omap_hwmod_count_resources - count number of struct resources needed by hwmod 3428 * omap_hwmod_count_resources - count number of struct resources needed by hwmod
3388 * @oh: struct omap_hwmod * 3429 * @oh: struct omap_hwmod *
3389 * @res: pointer to the first element of an array of struct resource to fill 3430 * @flags: Type of resources to include when counting (IRQ/DMA/MEM)
3390 * 3431 *
3391 * Count the number of struct resource array elements necessary to 3432 * Count the number of struct resource array elements necessary to
3392 * contain omap_hwmod @oh resources. Intended to be called by code 3433 * contain omap_hwmod @oh resources. Intended to be called by code
@@ -3399,20 +3440,25 @@ int omap_hwmod_reset(struct omap_hwmod *oh)
3399 * resource IDs. 3440 * resource IDs.
3400 * 3441 *
3401 */ 3442 */
3402int omap_hwmod_count_resources(struct omap_hwmod *oh) 3443int omap_hwmod_count_resources(struct omap_hwmod *oh, unsigned long flags)
3403{ 3444{
3404 struct omap_hwmod_ocp_if *os; 3445 int ret = 0;
3405 struct list_head *p;
3406 int ret;
3407 int i = 0;
3408 3446
3409 ret = _count_mpu_irqs(oh) + _count_sdma_reqs(oh); 3447 if (flags & IORESOURCE_IRQ)
3448 ret += _count_mpu_irqs(oh);
3410 3449
3411 p = oh->slave_ports.next; 3450 if (flags & IORESOURCE_DMA)
3451 ret += _count_sdma_reqs(oh);
3412 3452
3413 while (i < oh->slaves_cnt) { 3453 if (flags & IORESOURCE_MEM) {
3414 os = _fetch_next_ocp_if(&p, &i); 3454 int i = 0;
3415 ret += _count_ocp_if_addr_spaces(os); 3455 struct omap_hwmod_ocp_if *os;
3456 struct list_head *p = oh->slave_ports.next;
3457
3458 while (i < oh->slaves_cnt) {
3459 os = _fetch_next_ocp_if(&p, &i);
3460 ret += _count_ocp_if_addr_spaces(os);
3461 }
3416 } 3462 }
3417 3463
3418 return ret; 3464 return ret;
@@ -3907,17 +3953,21 @@ ohsps_unlock:
3907 * omap_hwmod_get_context_loss_count - get lost context count 3953 * omap_hwmod_get_context_loss_count - get lost context count
3908 * @oh: struct omap_hwmod * 3954 * @oh: struct omap_hwmod *
3909 * 3955 *
3910 * Query the powerdomain of of @oh to get the context loss 3956 * Returns the context loss count of associated @oh
3911 * count for this device. 3957 * upon success, or zero if no context loss data is available.
3912 * 3958 *
3913 * Returns the context loss count of the powerdomain assocated with @oh 3959 * On OMAP4, this queries the per-hwmod context loss register,
3914 * upon success, or zero if no powerdomain exists for @oh. 3960 * assuming one exists. If not, or on OMAP2/3, this queries the
3961 * enclosing powerdomain context loss count.
3915 */ 3962 */
3916int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh) 3963int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh)
3917{ 3964{
3918 struct powerdomain *pwrdm; 3965 struct powerdomain *pwrdm;
3919 int ret = 0; 3966 int ret = 0;
3920 3967
3968 if (soc_ops.get_context_lost)
3969 return soc_ops.get_context_lost(oh);
3970
3921 pwrdm = omap_hwmod_get_pwrdm(oh); 3971 pwrdm = omap_hwmod_get_pwrdm(oh);
3922 if (pwrdm) 3972 if (pwrdm)
3923 ret = pwrdm_get_context_loss_count(pwrdm); 3973 ret = pwrdm_get_context_loss_count(pwrdm);
@@ -4032,6 +4082,8 @@ void __init omap_hwmod_init(void)
4032 soc_ops.deassert_hardreset = _omap4_deassert_hardreset; 4082 soc_ops.deassert_hardreset = _omap4_deassert_hardreset;
4033 soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted; 4083 soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
4034 soc_ops.init_clkdm = _init_clkdm; 4084 soc_ops.init_clkdm = _init_clkdm;
4085 soc_ops.update_context_lost = _omap4_update_context_lost;
4086 soc_ops.get_context_lost = _omap4_get_context_lost;
4035 } else if (soc_is_am33xx()) { 4087 } else if (soc_is_am33xx()) {
4036 soc_ops.enable_module = _am33xx_enable_module; 4088 soc_ops.enable_module = _am33xx_enable_module;
4037 soc_ops.disable_module = _am33xx_disable_module; 4089 soc_ops.disable_module = _am33xx_disable_module;
diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h
index 87b59b45c678..86b7414b5835 100644
--- a/arch/arm/mach-omap2/omap_hwmod.h
+++ b/arch/arm/mach-omap2/omap_hwmod.h
@@ -2,7 +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) 2012 Texas Instruments, Inc. 5 * Copyright (C) 2011-2012 Texas Instruments, Inc.
6 * Paul Walmsley 6 * Paul Walmsley
7 * 7 *
8 * Created in collaboration with (alphabetical order): Benoît Cousson, 8 * Created in collaboration with (alphabetical order): Benoît Cousson,
@@ -394,12 +394,15 @@ struct omap_hwmod_omap2_prcm {
394 394
395/** 395/**
396 * struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data 396 * struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data
397 * @clkctrl_reg: PRCM address of the clock control register 397 * @clkctrl_offs: offset of the PRCM clock control register
398 * @rstctrl_reg: address of the XXX_RSTCTRL register located in the PRM 398 * @rstctrl_offs: offset of the XXX_RSTCTRL register located in the PRM
399 * @context_offs: offset of the RM_*_CONTEXT register
399 * @lostcontext_mask: bitmask for selecting bits from RM_*_CONTEXT register 400 * @lostcontext_mask: bitmask for selecting bits from RM_*_CONTEXT register
400 * @rstst_reg: (AM33XX only) address of the XXX_RSTST register in the PRM 401 * @rstst_reg: (AM33XX only) address of the XXX_RSTST register in the PRM
401 * @submodule_wkdep_bit: bit shift of the WKDEP range 402 * @submodule_wkdep_bit: bit shift of the WKDEP range
402 * @flags: PRCM register capabilities for this IP block 403 * @flags: PRCM register capabilities for this IP block
404 * @modulemode: allowable modulemodes
405 * @context_lost_counter: Count of module level context lost
403 * 406 *
404 * If @lostcontext_mask is not defined, context loss check code uses 407 * If @lostcontext_mask is not defined, context loss check code uses
405 * whole register without masking. @lostcontext_mask should only be 408 * whole register without masking. @lostcontext_mask should only be
@@ -415,6 +418,7 @@ struct omap_hwmod_omap4_prcm {
415 u8 submodule_wkdep_bit; 418 u8 submodule_wkdep_bit;
416 u8 modulemode; 419 u8 modulemode;
417 u8 flags; 420 u8 flags;
421 int context_lost_counter;
418}; 422};
419 423
420 424
@@ -627,7 +631,7 @@ void omap_hwmod_write(u32 v, struct omap_hwmod *oh, u16 reg_offs);
627u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs); 631u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs);
628int omap_hwmod_softreset(struct omap_hwmod *oh); 632int omap_hwmod_softreset(struct omap_hwmod *oh);
629 633
630int omap_hwmod_count_resources(struct omap_hwmod *oh); 634int omap_hwmod_count_resources(struct omap_hwmod *oh, unsigned long flags);
631int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res); 635int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res);
632int omap_hwmod_fill_dma_resources(struct omap_hwmod *oh, struct resource *res); 636int omap_hwmod_fill_dma_resources(struct omap_hwmod *oh, struct resource *res);
633int omap_hwmod_get_resource_byname(struct omap_hwmod *oh, unsigned int type, 637int omap_hwmod_get_resource_byname(struct omap_hwmod *oh, unsigned int type,
diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h
index a1a266ce90da..ac25ae6667cf 100644
--- a/arch/arm/mach-omap2/prm.h
+++ b/arch/arm/mach-omap2/prm.h
@@ -114,16 +114,25 @@ struct prm_reset_src_map {
114 114
115/** 115/**
116 * struct prm_ll_data - fn ptrs to per-SoC PRM function implementations 116 * struct prm_ll_data - fn ptrs to per-SoC PRM function implementations
117 * @read_reset_sources: ptr to the Soc PRM-specific get_reset_source impl 117 * @read_reset_sources: ptr to the SoC PRM-specific get_reset_source impl
118 * @was_any_context_lost_old: ptr to the SoC PRM context loss test fn
119 * @clear_context_loss_flags_old: ptr to the SoC PRM context loss flag clear fn
120 *
121 * XXX @was_any_context_lost_old and @clear_context_loss_flags_old are
122 * deprecated.
118 */ 123 */
119struct prm_ll_data { 124struct prm_ll_data {
120 u32 (*read_reset_sources)(void); 125 u32 (*read_reset_sources)(void);
126 bool (*was_any_context_lost_old)(u8 part, s16 inst, u16 idx);
127 void (*clear_context_loss_flags_old)(u8 part, s16 inst, u16 idx);
121}; 128};
122 129
123extern int prm_register(struct prm_ll_data *pld); 130extern int prm_register(struct prm_ll_data *pld);
124extern int prm_unregister(struct prm_ll_data *pld); 131extern int prm_unregister(struct prm_ll_data *pld);
125 132
126extern u32 prm_read_reset_sources(void); 133extern u32 prm_read_reset_sources(void);
134extern bool prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx);
135extern void prm_clear_context_loss_flags_old(u8 part, s16 inst, u16 idx);
127 136
128#endif 137#endif
129 138
diff --git a/arch/arm/mach-omap2/prm2xxx.c b/arch/arm/mach-omap2/prm2xxx.c
index bf24fc47603b..faeab18696df 100644
--- a/arch/arm/mach-omap2/prm2xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx.c
@@ -118,14 +118,13 @@ static struct prm_ll_data omap2xxx_prm_ll_data = {
118 .read_reset_sources = &omap2xxx_prm_read_reset_sources, 118 .read_reset_sources = &omap2xxx_prm_read_reset_sources,
119}; 119};
120 120
121static int __init omap2xxx_prm_init(void) 121int __init omap2xxx_prm_init(void)
122{ 122{
123 if (!cpu_is_omap24xx()) 123 if (!cpu_is_omap24xx())
124 return 0; 124 return 0;
125 125
126 return prm_register(&omap2xxx_prm_ll_data); 126 return prm_register(&omap2xxx_prm_ll_data);
127} 127}
128subsys_initcall(omap2xxx_prm_init);
129 128
130static void __exit omap2xxx_prm_exit(void) 129static void __exit omap2xxx_prm_exit(void)
131{ 130{
diff --git a/arch/arm/mach-omap2/prm2xxx.h b/arch/arm/mach-omap2/prm2xxx.h
index fe8a14f190ab..3194dd87e0e4 100644
--- a/arch/arm/mach-omap2/prm2xxx.h
+++ b/arch/arm/mach-omap2/prm2xxx.h
@@ -126,8 +126,7 @@ extern int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm);
126 126
127extern void omap2xxx_prm_dpll_reset(void); 127extern void omap2xxx_prm_dpll_reset(void);
128 128
129extern int __init prm2xxx_init(void); 129extern int __init omap2xxx_prm_init(void);
130extern int __exit prm2xxx_exit(void);
131 130
132#endif 131#endif
133 132
diff --git a/arch/arm/mach-omap2/prm3xxx.c b/arch/arm/mach-omap2/prm3xxx.c
index b86116cf0db9..db198d058584 100644
--- a/arch/arm/mach-omap2/prm3xxx.c
+++ b/arch/arm/mach-omap2/prm3xxx.c
@@ -383,27 +383,30 @@ static struct prm_ll_data omap3xxx_prm_ll_data = {
383 .read_reset_sources = &omap3xxx_prm_read_reset_sources, 383 .read_reset_sources = &omap3xxx_prm_read_reset_sources,
384}; 384};
385 385
386static int __init omap3xxx_prm_init(void) 386int __init omap3xxx_prm_init(void)
387{
388 if (!cpu_is_omap34xx())
389 return 0;
390
391 return prm_register(&omap3xxx_prm_ll_data);
392}
393
394static int __init omap3xxx_prm_late_init(void)
387{ 395{
388 int ret; 396 int ret;
389 397
390 if (!cpu_is_omap34xx()) 398 if (!cpu_is_omap34xx())
391 return 0; 399 return 0;
392 400
393 ret = prm_register(&omap3xxx_prm_ll_data);
394 if (ret)
395 return ret;
396
397 omap3xxx_prm_enable_io_wakeup(); 401 omap3xxx_prm_enable_io_wakeup();
398 ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup); 402 ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup);
399 if (!ret) 403 if (!ret)
400 irq_set_status_flags(omap_prcm_event_to_irq("io"), 404 irq_set_status_flags(omap_prcm_event_to_irq("io"),
401 IRQ_NOAUTOEN); 405 IRQ_NOAUTOEN);
402 406
403
404 return ret; 407 return ret;
405} 408}
406subsys_initcall(omap3xxx_prm_init); 409subsys_initcall(omap3xxx_prm_late_init);
407 410
408static void __exit omap3xxx_prm_exit(void) 411static void __exit omap3xxx_prm_exit(void)
409{ 412{
diff --git a/arch/arm/mach-omap2/prm3xxx.h b/arch/arm/mach-omap2/prm3xxx.h
index 10cd41a8129e..277f71794e61 100644
--- a/arch/arm/mach-omap2/prm3xxx.h
+++ b/arch/arm/mach-omap2/prm3xxx.h
@@ -154,6 +154,7 @@ extern void omap3xxx_prm_restore_irqen(u32 *saved_mask);
154 154
155extern void omap3xxx_prm_dpll3_reset(void); 155extern void omap3xxx_prm_dpll3_reset(void);
156 156
157extern int __init omap3xxx_prm_init(void);
157extern u32 omap3xxx_prm_get_reset_sources(void); 158extern u32 omap3xxx_prm_get_reset_sources(void);
158 159
159#endif /* __ASSEMBLER */ 160#endif /* __ASSEMBLER */
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index 6d3467af205d..7498bc77fe8b 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -346,6 +346,37 @@ static u32 omap44xx_prm_read_reset_sources(void)
346 return r; 346 return r;
347} 347}
348 348
349/**
350 * omap44xx_prm_was_any_context_lost_old - was module hardware context lost?
351 * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
352 * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
353 * @idx: CONTEXT register offset
354 *
355 * Return 1 if any bits were set in the *_CONTEXT_* register
356 * identified by (@part, @inst, @idx), which means that some context
357 * was lost for that module; otherwise, return 0.
358 */
359static bool omap44xx_prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx)
360{
361 return (omap4_prminst_read_inst_reg(part, inst, idx)) ? 1 : 0;
362}
363
364/**
365 * omap44xx_prm_clear_context_lost_flags_old - clear context loss flags
366 * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
367 * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
368 * @idx: CONTEXT register offset
369 *
370 * Clear hardware context loss bits for the module identified by
371 * (@part, @inst, @idx). No return value. XXX Writes to reserved bits;
372 * is there a way to avoid this?
373 */
374static void omap44xx_prm_clear_context_loss_flags_old(u8 part, s16 inst,
375 u16 idx)
376{
377 omap4_prminst_write_inst_reg(0xffffffff, part, inst, idx);
378}
379
349/* Powerdomain low-level functions */ 380/* Powerdomain low-level functions */
350 381
351static int omap4_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst) 382static int omap4_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
@@ -613,24 +644,28 @@ struct pwrdm_ops omap4_pwrdm_operations = {
613 */ 644 */
614static struct prm_ll_data omap44xx_prm_ll_data = { 645static struct prm_ll_data omap44xx_prm_ll_data = {
615 .read_reset_sources = &omap44xx_prm_read_reset_sources, 646 .read_reset_sources = &omap44xx_prm_read_reset_sources,
647 .was_any_context_lost_old = &omap44xx_prm_was_any_context_lost_old,
648 .clear_context_loss_flags_old = &omap44xx_prm_clear_context_loss_flags_old,
616}; 649};
617 650
618static int __init omap44xx_prm_init(void) 651int __init omap44xx_prm_init(void)
619{ 652{
620 int ret;
621
622 if (!cpu_is_omap44xx()) 653 if (!cpu_is_omap44xx())
623 return 0; 654 return 0;
624 655
625 ret = prm_register(&omap44xx_prm_ll_data); 656 return prm_register(&omap44xx_prm_ll_data);
626 if (ret) 657}
627 return ret; 658
659static int __init omap44xx_prm_late_init(void)
660{
661 if (!cpu_is_omap44xx())
662 return 0;
628 663
629 omap44xx_prm_enable_io_wakeup(); 664 omap44xx_prm_enable_io_wakeup();
630 665
631 return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup); 666 return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup);
632} 667}
633subsys_initcall(omap44xx_prm_init); 668subsys_initcall(omap44xx_prm_late_init);
634 669
635static void __exit omap44xx_prm_exit(void) 670static void __exit omap44xx_prm_exit(void)
636{ 671{
diff --git a/arch/arm/mach-omap2/prm44xx.h b/arch/arm/mach-omap2/prm44xx.h
index c8e1accdc90e..22b0979206ca 100644
--- a/arch/arm/mach-omap2/prm44xx.h
+++ b/arch/arm/mach-omap2/prm44xx.h
@@ -771,6 +771,7 @@ extern void omap44xx_prm_ocp_barrier(void);
771extern void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask); 771extern void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask);
772extern void omap44xx_prm_restore_irqen(u32 *saved_mask); 772extern void omap44xx_prm_restore_irqen(u32 *saved_mask);
773 773
774extern int __init omap44xx_prm_init(void);
774extern u32 omap44xx_prm_get_reset_sources(void); 775extern u32 omap44xx_prm_get_reset_sources(void);
775 776
776# endif 777# endif
diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c
index d2e0798a4c82..c6ae53ca8224 100644
--- a/arch/arm/mach-omap2/prm_common.c
+++ b/arch/arm/mach-omap2/prm_common.c
@@ -367,6 +367,51 @@ u32 prm_read_reset_sources(void)
367} 367}
368 368
369/** 369/**
370 * prm_was_any_context_lost_old - was device context lost? (old API)
371 * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
372 * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
373 * @idx: CONTEXT register offset
374 *
375 * Return 1 if any bits were set in the *_CONTEXT_* register
376 * identified by (@part, @inst, @idx), which means that some context
377 * was lost for that module; otherwise, return 0. XXX Deprecated;
378 * callers need to use a less-SoC-dependent way to identify hardware
379 * IP blocks.
380 */
381bool prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx)
382{
383 bool ret = true;
384
385 if (prm_ll_data->was_any_context_lost_old)
386 ret = prm_ll_data->was_any_context_lost_old(part, inst, idx);
387 else
388 WARN_ONCE(1, "prm: %s: no mapping function defined\n",
389 __func__);
390
391 return ret;
392}
393
394/**
395 * prm_clear_context_lost_flags_old - clear context loss flags (old API)
396 * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
397 * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
398 * @idx: CONTEXT register offset
399 *
400 * Clear hardware context loss bits for the module identified by
401 * (@part, @inst, @idx). No return value. XXX Deprecated; callers
402 * need to use a less-SoC-dependent way to identify hardware IP
403 * blocks.
404 */
405void prm_clear_context_loss_flags_old(u8 part, s16 inst, u16 idx)
406{
407 if (prm_ll_data->clear_context_loss_flags_old)
408 prm_ll_data->clear_context_loss_flags_old(part, inst, idx);
409 else
410 WARN_ONCE(1, "prm: %s: no mapping function defined\n",
411 __func__);
412}
413
414/**
370 * prm_register - register per-SoC low-level data with the PRM 415 * prm_register - register per-SoC low-level data with the PRM
371 * @pld: low-level per-SoC OMAP PRM data & function pointers to register 416 * @pld: low-level per-SoC OMAP PRM data & function pointers to register
372 * 417 *