diff options
author | Tony Lindgren <tony@atomide.com> | 2012-07-05 05:13:04 -0400 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2012-07-05 05:13:04 -0400 |
commit | ac5b0ea3d00d231dd9cedd45636b29defc368a4c (patch) | |
tree | 9649d193558e7c662257063a77ab7422379ac45b /arch/arm/mach-omap2/omap_hwmod.c | |
parent | 3f96a2d90e6923e2dd1e35d2f149a70a4d0f678c (diff) | |
parent | 8cb8de5d87b75f2ecaa1189079764340ea366c0e (diff) |
Merge tag 'omap-devel-f-for-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/pjw/omap-pending into cleanup-part2
Miscellaneous OMAP clock, hwmod, clockdomain, and powerdomain patches
for 3.6. Mostly small infrastructure improvements, and preparation
for OMAP5 and AM33xx code.
Conflicts:
arch/arm/mach-omap2/omap_hwmod.c
arch/arm/plat-omap/include/plat/omap_hwmod.h
Diffstat (limited to 'arch/arm/mach-omap2/omap_hwmod.c')
-rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.c | 61 |
1 files changed, 56 insertions, 5 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index f97f0624bca0..ebdf0016e536 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c | |||
@@ -416,6 +416,49 @@ static int _set_softreset(struct omap_hwmod *oh, u32 *v) | |||
416 | } | 416 | } |
417 | 417 | ||
418 | /** | 418 | /** |
419 | * _set_dmadisable: set OCP_SYSCONFIG.DMADISABLE bit in @v | ||
420 | * @oh: struct omap_hwmod * | ||
421 | * | ||
422 | * The DMADISABLE bit is a semi-automatic bit present in sysconfig register | ||
423 | * of some modules. When the DMA must perform read/write accesses, the | ||
424 | * DMADISABLE bit is cleared by the hardware. But when the DMA must stop | ||
425 | * for power management, software must set the DMADISABLE bit back to 1. | ||
426 | * | ||
427 | * Set the DMADISABLE bit in @v for hwmod @oh. Returns -EINVAL upon | ||
428 | * error or 0 upon success. | ||
429 | */ | ||
430 | static int _set_dmadisable(struct omap_hwmod *oh) | ||
431 | { | ||
432 | u32 v; | ||
433 | u32 dmadisable_mask; | ||
434 | |||
435 | if (!oh->class->sysc || | ||
436 | !(oh->class->sysc->sysc_flags & SYSC_HAS_DMADISABLE)) | ||
437 | return -EINVAL; | ||
438 | |||
439 | if (!oh->class->sysc->sysc_fields) { | ||
440 | WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name); | ||
441 | return -EINVAL; | ||
442 | } | ||
443 | |||
444 | /* clocks must be on for this operation */ | ||
445 | if (oh->_state != _HWMOD_STATE_ENABLED) { | ||
446 | pr_warn("omap_hwmod: %s: dma can be disabled only from enabled state\n", oh->name); | ||
447 | return -EINVAL; | ||
448 | } | ||
449 | |||
450 | pr_debug("omap_hwmod: %s: setting DMADISABLE\n", oh->name); | ||
451 | |||
452 | v = oh->_sysc_cache; | ||
453 | dmadisable_mask = | ||
454 | (0x1 << oh->class->sysc->sysc_fields->dmadisable_shift); | ||
455 | v |= dmadisable_mask; | ||
456 | _write_sysconfig(v, oh); | ||
457 | |||
458 | return 0; | ||
459 | } | ||
460 | |||
461 | /** | ||
419 | * _set_module_autoidle: set the OCP_SYSCONFIG AUTOIDLE field in @v | 462 | * _set_module_autoidle: set the OCP_SYSCONFIG AUTOIDLE field in @v |
420 | * @oh: struct omap_hwmod * | 463 | * @oh: struct omap_hwmod * |
421 | * @autoidle: desired AUTOIDLE bitfield value (0 or 1) | 464 | * @autoidle: desired AUTOIDLE bitfield value (0 or 1) |
@@ -1652,11 +1695,17 @@ dis_opt_clks: | |||
1652 | * therefore have no OCP header registers to access. Others (like the | 1695 | * therefore have no OCP header registers to access. Others (like the |
1653 | * IVA) have idiosyncratic reset sequences. So for these relatively | 1696 | * IVA) have idiosyncratic reset sequences. So for these relatively |
1654 | * rare cases, custom reset code can be supplied in the struct | 1697 | * rare cases, custom reset code can be supplied in the struct |
1655 | * omap_hwmod_class .reset function pointer. Passes along the return | 1698 | * omap_hwmod_class .reset function pointer. |
1656 | * value from either _ocp_softreset() or the custom reset function - | 1699 | * |
1657 | * these must return -EINVAL if the hwmod cannot be reset this way or | 1700 | * _set_dmadisable() is called to set the DMADISABLE bit so that it |
1658 | * if the hwmod is in the wrong state, -ETIMEDOUT if the module did | 1701 | * does not prevent idling of the system. This is necessary for cases |
1659 | * not reset in time, or 0 upon success. | 1702 | * where ROMCODE/BOOTLOADER uses dma and transfers control to the |
1703 | * kernel without disabling dma. | ||
1704 | * | ||
1705 | * Passes along the return value from either _ocp_softreset() or the | ||
1706 | * custom reset function - these must return -EINVAL if the hwmod | ||
1707 | * cannot be reset this way or if the hwmod is in the wrong state, | ||
1708 | * -ETIMEDOUT if the module did not reset in time, or 0 upon success. | ||
1660 | */ | 1709 | */ |
1661 | static int _reset(struct omap_hwmod *oh) | 1710 | static int _reset(struct omap_hwmod *oh) |
1662 | { | 1711 | { |
@@ -1678,6 +1727,8 @@ static int _reset(struct omap_hwmod *oh) | |||
1678 | } | 1727 | } |
1679 | } | 1728 | } |
1680 | 1729 | ||
1730 | _set_dmadisable(oh); | ||
1731 | |||
1681 | /* | 1732 | /* |
1682 | * OCP_SYSCONFIG bits need to be reprogrammed after a | 1733 | * OCP_SYSCONFIG bits need to be reprogrammed after a |
1683 | * softreset. The _enable() function should be split to avoid | 1734 | * softreset. The _enable() function should be split to avoid |