diff options
author | Tony Lindgren <tony@atomide.com> | 2012-11-26 15:32:50 -0500 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2012-11-26 15:32:50 -0500 |
commit | 8b9c1ac2e11a9fb3a5a8860fb7570ff7633aa7f7 (patch) | |
tree | 282feb4b7a0f4b430b363048616f50e27f656594 | |
parent | 558a0780b0a04862a678f7823215424b4e5501f9 (diff) | |
parent | c567b0584c352e7f97ced003be46bed8581ddd5b (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.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap_device.c | 87 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.c | 82 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.h | 12 | ||||
-rw-r--r-- | arch/arm/mach-omap2/prm.h | 11 | ||||
-rw-r--r-- | arch/arm/mach-omap2/prm2xxx.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-omap2/prm2xxx.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-omap2/prm3xxx.c | 17 | ||||
-rw-r--r-- | arch/arm/mach-omap2/prm3xxx.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-omap2/prm44xx.c | 49 | ||||
-rw-r--r-- | arch/arm/mach-omap2/prm44xx.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-omap2/prm_common.c | 45 |
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 | */ |
450 | static int omap_device_count_resources(struct omap_device *od) | 451 | static 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 | |||
628 | have_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 | */ | ||
1996 | static 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 | */ | ||
2018 | static 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 | */ |
3402 | int omap_hwmod_count_resources(struct omap_hwmod *oh) | 3443 | int 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 | */ |
3916 | int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh) | 3963 | int 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); | |||
627 | u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs); | 631 | u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs); |
628 | int omap_hwmod_softreset(struct omap_hwmod *oh); | 632 | int omap_hwmod_softreset(struct omap_hwmod *oh); |
629 | 633 | ||
630 | int omap_hwmod_count_resources(struct omap_hwmod *oh); | 634 | int omap_hwmod_count_resources(struct omap_hwmod *oh, unsigned long flags); |
631 | int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res); | 635 | int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res); |
632 | int omap_hwmod_fill_dma_resources(struct omap_hwmod *oh, struct resource *res); | 636 | int omap_hwmod_fill_dma_resources(struct omap_hwmod *oh, struct resource *res); |
633 | int omap_hwmod_get_resource_byname(struct omap_hwmod *oh, unsigned int type, | 637 | int 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 | */ |
119 | struct prm_ll_data { | 124 | struct 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 | ||
123 | extern int prm_register(struct prm_ll_data *pld); | 130 | extern int prm_register(struct prm_ll_data *pld); |
124 | extern int prm_unregister(struct prm_ll_data *pld); | 131 | extern int prm_unregister(struct prm_ll_data *pld); |
125 | 132 | ||
126 | extern u32 prm_read_reset_sources(void); | 133 | extern u32 prm_read_reset_sources(void); |
134 | extern bool prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx); | ||
135 | extern 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 | ||
121 | static int __init omap2xxx_prm_init(void) | 121 | int __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 | } |
128 | subsys_initcall(omap2xxx_prm_init); | ||
129 | 128 | ||
130 | static void __exit omap2xxx_prm_exit(void) | 129 | static 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 | ||
127 | extern void omap2xxx_prm_dpll_reset(void); | 127 | extern void omap2xxx_prm_dpll_reset(void); |
128 | 128 | ||
129 | extern int __init prm2xxx_init(void); | 129 | extern int __init omap2xxx_prm_init(void); |
130 | extern 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 | ||
386 | static int __init omap3xxx_prm_init(void) | 386 | int __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 | |||
394 | static 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 | } |
406 | subsys_initcall(omap3xxx_prm_init); | 409 | subsys_initcall(omap3xxx_prm_late_init); |
407 | 410 | ||
408 | static void __exit omap3xxx_prm_exit(void) | 411 | static 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 | ||
155 | extern void omap3xxx_prm_dpll3_reset(void); | 155 | extern void omap3xxx_prm_dpll3_reset(void); |
156 | 156 | ||
157 | extern int __init omap3xxx_prm_init(void); | ||
157 | extern u32 omap3xxx_prm_get_reset_sources(void); | 158 | extern 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 | */ | ||
359 | static 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 | */ | ||
374 | static 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 | ||
351 | static int omap4_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst) | 382 | static int omap4_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst) |
@@ -613,24 +644,28 @@ struct pwrdm_ops omap4_pwrdm_operations = { | |||
613 | */ | 644 | */ |
614 | static struct prm_ll_data omap44xx_prm_ll_data = { | 645 | static 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 | ||
618 | static int __init omap44xx_prm_init(void) | 651 | int __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 | |
659 | static 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 | } |
633 | subsys_initcall(omap44xx_prm_init); | 668 | subsys_initcall(omap44xx_prm_late_init); |
634 | 669 | ||
635 | static void __exit omap44xx_prm_exit(void) | 670 | static 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); | |||
771 | extern void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask); | 771 | extern void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask); |
772 | extern void omap44xx_prm_restore_irqen(u32 *saved_mask); | 772 | extern void omap44xx_prm_restore_irqen(u32 *saved_mask); |
773 | 773 | ||
774 | extern int __init omap44xx_prm_init(void); | ||
774 | extern u32 omap44xx_prm_get_reset_sources(void); | 775 | extern 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 | */ | ||
381 | bool 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 | */ | ||
405 | void 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 | * |