提交 8b9c1ac2 编写于 作者: T Tony Lindgren

Merge tag 'omap-devel-a-for-3.8' of...

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
558a0780 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.
...@@ -51,6 +51,10 @@ ...@@ -51,6 +51,10 @@
#include "prcm_mpu44xx.h" #include "prcm_mpu44xx.h"
#include "prminst44xx.h" #include "prminst44xx.h"
#include "cminst44xx.h" #include "cminst44xx.h"
#include "prm2xxx.h"
#include "prm3xxx.h"
#include "prm44xx.h"
/* /*
* The machine specific code may provide the extra mapping besides the * The machine specific code may provide the extra mapping besides the
* default mapping provided here. * default mapping provided here.
...@@ -392,6 +396,7 @@ void __init omap2420_init_early(void) ...@@ -392,6 +396,7 @@ void __init omap2420_init_early(void)
omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP2420_PRM_BASE)); omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP2420_PRM_BASE));
omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP2420_CM_BASE), NULL); omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP2420_CM_BASE), NULL);
omap2xxx_check_revision(); omap2xxx_check_revision();
omap2xxx_prm_init();
omap2xxx_cm_init(); omap2xxx_cm_init();
omap_common_init_early(); omap_common_init_early();
omap2xxx_voltagedomains_init(); omap2xxx_voltagedomains_init();
...@@ -422,6 +427,7 @@ void __init omap2430_init_early(void) ...@@ -422,6 +427,7 @@ void __init omap2430_init_early(void)
omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP2430_PRM_BASE)); omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP2430_PRM_BASE));
omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP2430_CM_BASE), NULL); omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP2430_CM_BASE), NULL);
omap2xxx_check_revision(); omap2xxx_check_revision();
omap2xxx_prm_init();
omap2xxx_cm_init(); omap2xxx_cm_init();
omap_common_init_early(); omap_common_init_early();
omap2xxx_voltagedomains_init(); omap2xxx_voltagedomains_init();
...@@ -457,6 +463,7 @@ void __init omap3_init_early(void) ...@@ -457,6 +463,7 @@ void __init omap3_init_early(void)
omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE), NULL); omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE), NULL);
omap3xxx_check_revision(); omap3xxx_check_revision();
omap3xxx_check_features(); omap3xxx_check_features();
omap3xxx_prm_init();
omap3xxx_cm_init(); omap3xxx_cm_init();
omap_common_init_early(); omap_common_init_early();
omap3xxx_voltagedomains_init(); omap3xxx_voltagedomains_init();
...@@ -591,6 +598,7 @@ void __init omap4430_init_early(void) ...@@ -591,6 +598,7 @@ void __init omap4430_init_early(void)
omap_cm_base_init(); omap_cm_base_init();
omap4xxx_check_revision(); omap4xxx_check_revision();
omap4xxx_check_features(); omap4xxx_check_features();
omap44xx_prm_init();
omap_common_init_early(); omap_common_init_early();
omap44xx_voltagedomains_init(); omap44xx_voltagedomains_init();
omap44xx_powerdomains_init(); omap44xx_powerdomains_init();
......
...@@ -441,19 +441,21 @@ int omap_device_get_context_loss_count(struct platform_device *pdev) ...@@ -441,19 +441,21 @@ int omap_device_get_context_loss_count(struct platform_device *pdev)
/** /**
* omap_device_count_resources - count number of struct resource entries needed * omap_device_count_resources - count number of struct resource entries needed
* @od: struct omap_device * * @od: struct omap_device *
* @flags: Type of resources to include when counting (IRQ/DMA/MEM)
* *
* Count the number of struct resource entries needed for this * Count the number of struct resource entries needed for this
* omap_device @od. Used by omap_device_build_ss() to determine how * omap_device @od. Used by omap_device_build_ss() to determine how
* much memory to allocate before calling * much memory to allocate before calling
* omap_device_fill_resources(). Returns the count. * omap_device_fill_resources(). Returns the count.
*/ */
static int omap_device_count_resources(struct omap_device *od) static int omap_device_count_resources(struct omap_device *od,
unsigned long flags)
{ {
int c = 0; int c = 0;
int i; int i;
for (i = 0; i < od->hwmods_cnt; i++) for (i = 0; i < od->hwmods_cnt; i++)
c += omap_hwmod_count_resources(od->hwmods[i]); c += omap_hwmod_count_resources(od->hwmods[i], flags);
pr_debug("omap_device: %s: counted %d total resources across %d hwmods\n", pr_debug("omap_device: %s: counted %d total resources across %d hwmods\n",
od->pdev->name, c, od->hwmods_cnt); od->pdev->name, c, od->hwmods_cnt);
...@@ -557,52 +559,73 @@ struct omap_device *omap_device_alloc(struct platform_device *pdev, ...@@ -557,52 +559,73 @@ struct omap_device *omap_device_alloc(struct platform_device *pdev,
od->hwmods = hwmods; od->hwmods = hwmods;
od->pdev = pdev; od->pdev = pdev;
res_count = omap_device_count_resources(od);
/* /*
* Non-DT Boot:
* Here, pdev->num_resources = 0, and we should get all the
* resources from hwmod.
*
* DT Boot: * DT Boot:
* OF framework will construct the resource structure (currently * OF framework will construct the resource structure (currently
* does for MEM & IRQ resource) and we should respect/use these * does for MEM & IRQ resource) and we should respect/use these
* resources, killing hwmod dependency. * resources, killing hwmod dependency.
* If pdev->num_resources > 0, we assume that MEM & IRQ resources * If pdev->num_resources > 0, we assume that MEM & IRQ resources
* have been allocated by OF layer already (through DTB). * have been allocated by OF layer already (through DTB).
* * As preparation for the future we examine the OF provided resources
* Non-DT Boot: * to see if we have DMA resources provided already. In this case
* Here, pdev->num_resources = 0, and we should get all the * there is no need to update the resources for the device, we use the
* resources from hwmod. * OF provided ones.
* *
* TODO: Once DMA resource is available from OF layer, we should * TODO: Once DMA resource is available from OF layer, we should
* kill filling any resources from hwmod. * kill filling any resources from hwmod.
*/ */
if (res_count > pdev->num_resources) { if (!pdev->num_resources) {
/* Allocate resources memory to account for new resources */ /* Count all resources for the device */
res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL); res_count = omap_device_count_resources(od, IORESOURCE_IRQ |
if (!res) IORESOURCE_DMA |
goto oda_exit3; IORESOURCE_MEM);
} else {
/* /* Take a look if we already have DMA resource via DT */
* If pdev->num_resources > 0, then assume that, for (i = 0; i < pdev->num_resources; i++) {
* MEM and IRQ resources will only come from DT and only struct resource *r = &pdev->resource[i];
* fill DMA resource from hwmod layer.
*/ /* We have it, no need to touch the resources */
if (pdev->num_resources && pdev->resource) { if (r->flags == IORESOURCE_DMA)
dev_dbg(&pdev->dev, "%s(): resources already allocated %d\n", goto have_everything;
__func__, res_count);
memcpy(res, pdev->resource,
sizeof(struct resource) * pdev->num_resources);
_od_fill_dma_resources(od, &res[pdev->num_resources]);
} else {
dev_dbg(&pdev->dev, "%s(): using resources from hwmod %d\n",
__func__, res_count);
omap_device_fill_resources(od, res);
} }
/* Count only DMA resources for the device */
res_count = omap_device_count_resources(od, IORESOURCE_DMA);
/* The device has no DMA resource, no need for update */
if (!res_count)
goto have_everything;
ret = platform_device_add_resources(pdev, res, res_count); res_count += pdev->num_resources;
kfree(res); }
if (ret) /* Allocate resources memory to account for new resources */
goto oda_exit3; res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL);
if (!res)
goto oda_exit3;
if (!pdev->num_resources) {
dev_dbg(&pdev->dev, "%s: using %d resources from hwmod\n",
__func__, res_count);
omap_device_fill_resources(od, res);
} else {
dev_dbg(&pdev->dev,
"%s: appending %d DMA resources from hwmod\n",
__func__, res_count - pdev->num_resources);
memcpy(res, pdev->resource,
sizeof(struct resource) * pdev->num_resources);
_od_fill_dma_resources(od, &res[pdev->num_resources]);
} }
ret = platform_device_add_resources(pdev, res, res_count);
kfree(res);
if (ret)
goto oda_exit3;
have_everything:
if (!pm_lats) { if (!pm_lats) {
pm_lats = omap_default_latency; pm_lats = omap_default_latency;
pm_lats_cnt = ARRAY_SIZE(omap_default_latency); pm_lats_cnt = ARRAY_SIZE(omap_default_latency);
......
...@@ -187,6 +187,8 @@ struct omap_hwmod_soc_ops { ...@@ -187,6 +187,8 @@ struct omap_hwmod_soc_ops {
int (*is_hardreset_asserted)(struct omap_hwmod *oh, int (*is_hardreset_asserted)(struct omap_hwmod *oh,
struct omap_hwmod_rst_info *ohri); struct omap_hwmod_rst_info *ohri);
int (*init_clkdm)(struct omap_hwmod *oh); int (*init_clkdm)(struct omap_hwmod *oh);
void (*update_context_lost)(struct omap_hwmod *oh);
int (*get_context_lost)(struct omap_hwmod *oh);
}; };
/* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */ /* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */
...@@ -1982,6 +1984,42 @@ static void _reconfigure_io_chain(void) ...@@ -1982,6 +1984,42 @@ static void _reconfigure_io_chain(void)
spin_unlock_irqrestore(&io_chain_lock, flags); spin_unlock_irqrestore(&io_chain_lock, flags);
} }
/**
* _omap4_update_context_lost - increment hwmod context loss counter if
* hwmod context was lost, and clear hardware context loss reg
* @oh: hwmod to check for context loss
*
* If the PRCM indicates that the hwmod @oh lost context, increment
* our in-memory context loss counter, and clear the RM_*_CONTEXT
* bits. No return value.
*/
static void _omap4_update_context_lost(struct omap_hwmod *oh)
{
if (oh->prcm.omap4.flags & HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT)
return;
if (!prm_was_any_context_lost_old(oh->clkdm->pwrdm.ptr->prcm_partition,
oh->clkdm->pwrdm.ptr->prcm_offs,
oh->prcm.omap4.context_offs))
return;
oh->prcm.omap4.context_lost_counter++;
prm_clear_context_loss_flags_old(oh->clkdm->pwrdm.ptr->prcm_partition,
oh->clkdm->pwrdm.ptr->prcm_offs,
oh->prcm.omap4.context_offs);
}
/**
* _omap4_get_context_lost - get context loss counter for a hwmod
* @oh: hwmod to get context loss counter for
*
* Returns the in-memory context loss counter for a hwmod.
*/
static int _omap4_get_context_lost(struct omap_hwmod *oh)
{
return oh->prcm.omap4.context_lost_counter;
}
/** /**
* _enable - enable an omap_hwmod * _enable - enable an omap_hwmod
* @oh: struct omap_hwmod * * @oh: struct omap_hwmod *
...@@ -2065,6 +2103,9 @@ static int _enable(struct omap_hwmod *oh) ...@@ -2065,6 +2103,9 @@ static int _enable(struct omap_hwmod *oh)
if (soc_ops.enable_module) if (soc_ops.enable_module)
soc_ops.enable_module(oh); soc_ops.enable_module(oh);
if (soc_ops.update_context_lost)
soc_ops.update_context_lost(oh);
r = (soc_ops.wait_target_ready) ? soc_ops.wait_target_ready(oh) : r = (soc_ops.wait_target_ready) ? soc_ops.wait_target_ready(oh) :
-EINVAL; -EINVAL;
if (!r) { if (!r) {
...@@ -3386,7 +3427,7 @@ int omap_hwmod_reset(struct omap_hwmod *oh) ...@@ -3386,7 +3427,7 @@ int omap_hwmod_reset(struct omap_hwmod *oh)
/** /**
* omap_hwmod_count_resources - count number of struct resources needed by hwmod * omap_hwmod_count_resources - count number of struct resources needed by hwmod
* @oh: struct omap_hwmod * * @oh: struct omap_hwmod *
* @res: pointer to the first element of an array of struct resource to fill * @flags: Type of resources to include when counting (IRQ/DMA/MEM)
* *
* Count the number of struct resource array elements necessary to * Count the number of struct resource array elements necessary to
* contain omap_hwmod @oh resources. Intended to be called by code * contain omap_hwmod @oh resources. Intended to be called by code
...@@ -3399,20 +3440,25 @@ int omap_hwmod_reset(struct omap_hwmod *oh) ...@@ -3399,20 +3440,25 @@ int omap_hwmod_reset(struct omap_hwmod *oh)
* resource IDs. * resource IDs.
* *
*/ */
int omap_hwmod_count_resources(struct omap_hwmod *oh) int omap_hwmod_count_resources(struct omap_hwmod *oh, unsigned long flags)
{ {
struct omap_hwmod_ocp_if *os; int ret = 0;
struct list_head *p;
int ret;
int i = 0;
ret = _count_mpu_irqs(oh) + _count_sdma_reqs(oh); if (flags & IORESOURCE_IRQ)
ret += _count_mpu_irqs(oh);
p = oh->slave_ports.next; if (flags & IORESOURCE_DMA)
ret += _count_sdma_reqs(oh);
while (i < oh->slaves_cnt) { if (flags & IORESOURCE_MEM) {
os = _fetch_next_ocp_if(&p, &i); int i = 0;
ret += _count_ocp_if_addr_spaces(os); struct omap_hwmod_ocp_if *os;
struct list_head *p = oh->slave_ports.next;
while (i < oh->slaves_cnt) {
os = _fetch_next_ocp_if(&p, &i);
ret += _count_ocp_if_addr_spaces(os);
}
} }
return ret; return ret;
...@@ -3907,17 +3953,21 @@ int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state) ...@@ -3907,17 +3953,21 @@ int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state)
* omap_hwmod_get_context_loss_count - get lost context count * omap_hwmod_get_context_loss_count - get lost context count
* @oh: struct omap_hwmod * * @oh: struct omap_hwmod *
* *
* Query the powerdomain of of @oh to get the context loss * Returns the context loss count of associated @oh
* count for this device. * upon success, or zero if no context loss data is available.
* *
* Returns the context loss count of the powerdomain assocated with @oh * On OMAP4, this queries the per-hwmod context loss register,
* upon success, or zero if no powerdomain exists for @oh. * assuming one exists. If not, or on OMAP2/3, this queries the
* enclosing powerdomain context loss count.
*/ */
int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh) int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh)
{ {
struct powerdomain *pwrdm; struct powerdomain *pwrdm;
int ret = 0; int ret = 0;
if (soc_ops.get_context_lost)
return soc_ops.get_context_lost(oh);
pwrdm = omap_hwmod_get_pwrdm(oh); pwrdm = omap_hwmod_get_pwrdm(oh);
if (pwrdm) if (pwrdm)
ret = pwrdm_get_context_loss_count(pwrdm); ret = pwrdm_get_context_loss_count(pwrdm);
...@@ -4032,6 +4082,8 @@ void __init omap_hwmod_init(void) ...@@ -4032,6 +4082,8 @@ void __init omap_hwmod_init(void)
soc_ops.deassert_hardreset = _omap4_deassert_hardreset; soc_ops.deassert_hardreset = _omap4_deassert_hardreset;
soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted; soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
soc_ops.init_clkdm = _init_clkdm; soc_ops.init_clkdm = _init_clkdm;
soc_ops.update_context_lost = _omap4_update_context_lost;
soc_ops.get_context_lost = _omap4_get_context_lost;
} else if (soc_is_am33xx()) { } else if (soc_is_am33xx()) {
soc_ops.enable_module = _am33xx_enable_module; soc_ops.enable_module = _am33xx_enable_module;
soc_ops.disable_module = _am33xx_disable_module; soc_ops.disable_module = _am33xx_disable_module;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* omap_hwmod macros, structures * omap_hwmod macros, structures
* *
* Copyright (C) 2009-2011 Nokia Corporation * Copyright (C) 2009-2011 Nokia Corporation
* Copyright (C) 2012 Texas Instruments, Inc. * Copyright (C) 2011-2012 Texas Instruments, Inc.
* Paul Walmsley * Paul Walmsley
* *
* Created in collaboration with (alphabetical order): Benoît Cousson, * Created in collaboration with (alphabetical order): Benoît Cousson,
...@@ -394,12 +394,15 @@ struct omap_hwmod_omap2_prcm { ...@@ -394,12 +394,15 @@ struct omap_hwmod_omap2_prcm {
/** /**
* struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data * struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data
* @clkctrl_reg: PRCM address of the clock control register * @clkctrl_offs: offset of the PRCM clock control register
* @rstctrl_reg: address of the XXX_RSTCTRL register located in the PRM * @rstctrl_offs: offset of the XXX_RSTCTRL register located in the PRM
* @context_offs: offset of the RM_*_CONTEXT register
* @lostcontext_mask: bitmask for selecting bits from RM_*_CONTEXT register * @lostcontext_mask: bitmask for selecting bits from RM_*_CONTEXT register
* @rstst_reg: (AM33XX only) address of the XXX_RSTST register in the PRM * @rstst_reg: (AM33XX only) address of the XXX_RSTST register in the PRM
* @submodule_wkdep_bit: bit shift of the WKDEP range * @submodule_wkdep_bit: bit shift of the WKDEP range
* @flags: PRCM register capabilities for this IP block * @flags: PRCM register capabilities for this IP block
* @modulemode: allowable modulemodes
* @context_lost_counter: Count of module level context lost
* *
* If @lostcontext_mask is not defined, context loss check code uses * If @lostcontext_mask is not defined, context loss check code uses
* whole register without masking. @lostcontext_mask should only be * whole register without masking. @lostcontext_mask should only be
...@@ -415,6 +418,7 @@ struct omap_hwmod_omap4_prcm { ...@@ -415,6 +418,7 @@ struct omap_hwmod_omap4_prcm {
u8 submodule_wkdep_bit; u8 submodule_wkdep_bit;
u8 modulemode; u8 modulemode;
u8 flags; u8 flags;
int context_lost_counter;
}; };
...@@ -627,7 +631,7 @@ void omap_hwmod_write(u32 v, struct omap_hwmod *oh, u16 reg_offs); ...@@ -627,7 +631,7 @@ void omap_hwmod_write(u32 v, struct omap_hwmod *oh, u16 reg_offs);
u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs); u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs);
int omap_hwmod_softreset(struct omap_hwmod *oh); int omap_hwmod_softreset(struct omap_hwmod *oh);
int omap_hwmod_count_resources(struct omap_hwmod *oh); int omap_hwmod_count_resources(struct omap_hwmod *oh, unsigned long flags);
int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res); int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res);
int omap_hwmod_fill_dma_resources(struct omap_hwmod *oh, struct resource *res); int omap_hwmod_fill_dma_resources(struct omap_hwmod *oh, struct resource *res);
int omap_hwmod_get_resource_byname(struct omap_hwmod *oh, unsigned int type, int omap_hwmod_get_resource_byname(struct omap_hwmod *oh, unsigned int type,
......
...@@ -114,16 +114,25 @@ struct prm_reset_src_map { ...@@ -114,16 +114,25 @@ struct prm_reset_src_map {
/** /**
* struct prm_ll_data - fn ptrs to per-SoC PRM function implementations * struct prm_ll_data - fn ptrs to per-SoC PRM function implementations
* @read_reset_sources: ptr to the Soc PRM-specific get_reset_source impl * @read_reset_sources: ptr to the SoC PRM-specific get_reset_source impl
* @was_any_context_lost_old: ptr to the SoC PRM context loss test fn
* @clear_context_loss_flags_old: ptr to the SoC PRM context loss flag clear fn
*
* XXX @was_any_context_lost_old and @clear_context_loss_flags_old are
* deprecated.
*/ */
struct prm_ll_data { struct prm_ll_data {
u32 (*read_reset_sources)(void); u32 (*read_reset_sources)(void);
bool (*was_any_context_lost_old)(u8 part, s16 inst, u16 idx);
void (*clear_context_loss_flags_old)(u8 part, s16 inst, u16 idx);
}; };
extern int prm_register(struct prm_ll_data *pld); extern int prm_register(struct prm_ll_data *pld);
extern int prm_unregister(struct prm_ll_data *pld); extern int prm_unregister(struct prm_ll_data *pld);
extern u32 prm_read_reset_sources(void); extern u32 prm_read_reset_sources(void);
extern bool prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx);
extern void prm_clear_context_loss_flags_old(u8 part, s16 inst, u16 idx);
#endif #endif
......
...@@ -118,14 +118,13 @@ static struct prm_ll_data omap2xxx_prm_ll_data = { ...@@ -118,14 +118,13 @@ static struct prm_ll_data omap2xxx_prm_ll_data = {
.read_reset_sources = &omap2xxx_prm_read_reset_sources, .read_reset_sources = &omap2xxx_prm_read_reset_sources,
}; };
static int __init omap2xxx_prm_init(void) int __init omap2xxx_prm_init(void)
{ {
if (!cpu_is_omap24xx()) if (!cpu_is_omap24xx())
return 0; return 0;
return prm_register(&omap2xxx_prm_ll_data); return prm_register(&omap2xxx_prm_ll_data);
} }
subsys_initcall(omap2xxx_prm_init);
static void __exit omap2xxx_prm_exit(void) static void __exit omap2xxx_prm_exit(void)
{ {
......
...@@ -126,8 +126,7 @@ extern int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm); ...@@ -126,8 +126,7 @@ extern int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm);
extern void omap2xxx_prm_dpll_reset(void); extern void omap2xxx_prm_dpll_reset(void);
extern int __init prm2xxx_init(void); extern int __init omap2xxx_prm_init(void);
extern int __exit prm2xxx_exit(void);
#endif #endif
......
...@@ -383,27 +383,30 @@ static struct prm_ll_data omap3xxx_prm_ll_data = { ...@@ -383,27 +383,30 @@ static struct prm_ll_data omap3xxx_prm_ll_data = {
.read_reset_sources = &omap3xxx_prm_read_reset_sources, .read_reset_sources = &omap3xxx_prm_read_reset_sources,
}; };
static int __init omap3xxx_prm_init(void) int __init omap3xxx_prm_init(void)
{
if (!cpu_is_omap34xx())
return 0;
return prm_register(&omap3xxx_prm_ll_data);
}
static int __init omap3xxx_prm_late_init(void)
{ {
int ret; int ret;
if (!cpu_is_omap34xx()) if (!cpu_is_omap34xx())
return 0; return 0;
ret = prm_register(&omap3xxx_prm_ll_data);
if (ret)
return ret;
omap3xxx_prm_enable_io_wakeup(); omap3xxx_prm_enable_io_wakeup();
ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup); ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup);
if (!ret) if (!ret)
irq_set_status_flags(omap_prcm_event_to_irq("io"), irq_set_status_flags(omap_prcm_event_to_irq("io"),
IRQ_NOAUTOEN); IRQ_NOAUTOEN);
return ret; return ret;
} }
subsys_initcall(omap3xxx_prm_init); subsys_initcall(omap3xxx_prm_late_init);
static void __exit omap3xxx_prm_exit(void) static void __exit omap3xxx_prm_exit(void)
{ {
......
...@@ -154,6 +154,7 @@ extern void omap3xxx_prm_restore_irqen(u32 *saved_mask); ...@@ -154,6 +154,7 @@ extern void omap3xxx_prm_restore_irqen(u32 *saved_mask);
extern void omap3xxx_prm_dpll3_reset(void); extern void omap3xxx_prm_dpll3_reset(void);
extern int __init omap3xxx_prm_init(void);
extern u32 omap3xxx_prm_get_reset_sources(void); extern u32 omap3xxx_prm_get_reset_sources(void);
#endif /* __ASSEMBLER */ #endif /* __ASSEMBLER */
......
...@@ -346,6 +346,37 @@ static u32 omap44xx_prm_read_reset_sources(void) ...@@ -346,6 +346,37 @@ static u32 omap44xx_prm_read_reset_sources(void)
return r; return r;
} }
/**
* omap44xx_prm_was_any_context_lost_old - was module hardware context lost?
* @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
* @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
* @idx: CONTEXT register offset
*
* Return 1 if any bits were set in the *_CONTEXT_* register
* identified by (@part, @inst, @idx), which means that some context
* was lost for that module; otherwise, return 0.
*/
static bool omap44xx_prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx)
{
return (omap4_prminst_read_inst_reg(part, inst, idx)) ? 1 : 0;
}
/**
* omap44xx_prm_clear_context_lost_flags_old - clear context loss flags
* @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
* @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
* @idx: CONTEXT register offset
*
* Clear hardware context loss bits for the module identified by
* (@part, @inst, @idx). No return value. XXX Writes to reserved bits;
* is there a way to avoid this?
*/
static void omap44xx_prm_clear_context_loss_flags_old(u8 part, s16 inst,
u16 idx)
{
omap4_prminst_write_inst_reg(0xffffffff, part, inst, idx);
}
/* Powerdomain low-level functions */ /* Powerdomain low-level functions */
static int omap4_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst) static int omap4_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
...@@ -613,24 +644,28 @@ struct pwrdm_ops omap4_pwrdm_operations = { ...@@ -613,24 +644,28 @@ struct pwrdm_ops omap4_pwrdm_operations = {
*/ */
static struct prm_ll_data omap44xx_prm_ll_data = { static struct prm_ll_data omap44xx_prm_ll_data = {
.read_reset_sources = &omap44xx_prm_read_reset_sources, .read_reset_sources = &omap44xx_prm_read_reset_sources,
.was_any_context_lost_old = &omap44xx_prm_was_any_context_lost_old,
.clear_context_loss_flags_old = &omap44xx_prm_clear_context_loss_flags_old,
}; };
static int __init omap44xx_prm_init(void) int __init omap44xx_prm_init(void)
{ {
int ret;
if (!cpu_is_omap44xx()) if (!cpu_is_omap44xx())
return 0; return 0;
ret = prm_register(&omap44xx_prm_ll_data); return prm_register(&omap44xx_prm_ll_data);
if (ret) }
return ret;
static int __init omap44xx_prm_late_init(void)
{
if (!cpu_is_omap44xx())
return 0;
omap44xx_prm_enable_io_wakeup(); omap44xx_prm_enable_io_wakeup();
return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup); return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup);
} }
subsys_initcall(omap44xx_prm_init); subsys_initcall(omap44xx_prm_late_init);
static void __exit omap44xx_prm_exit(void) static void __exit omap44xx_prm_exit(void)
{ {
......
...@@ -771,6 +771,7 @@ extern void omap44xx_prm_ocp_barrier(void); ...@@ -771,6 +771,7 @@ extern void omap44xx_prm_ocp_barrier(void);
extern void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask); extern void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask);
extern void omap44xx_prm_restore_irqen(u32 *saved_mask); extern void omap44xx_prm_restore_irqen(u32 *saved_mask);
extern int __init omap44xx_prm_init(void);
extern u32 omap44xx_prm_get_reset_sources(void); extern u32 omap44xx_prm_get_reset_sources(void);
# endif # endif
......
...@@ -366,6 +366,51 @@ u32 prm_read_reset_sources(void) ...@@ -366,6 +366,51 @@ u32 prm_read_reset_sources(void)
return ret; return ret;
} }
/**
* prm_was_any_context_lost_old - was device context lost? (old API)
* @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
* @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
* @idx: CONTEXT register offset
*
* Return 1 if any bits were set in the *_CONTEXT_* register
* identified by (@part, @inst, @idx), which means that some context
* was lost for that module; otherwise, return 0. XXX Deprecated;
* callers need to use a less-SoC-dependent way to identify hardware
* IP blocks.
*/
bool prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx)
{
bool ret = true;
if (prm_ll_data->was_any_context_lost_old)
ret = prm_ll_data->was_any_context_lost_old(part, inst, idx);
else
WARN_ONCE(1, "prm: %s: no mapping function defined\n",
__func__);
return ret;
}
/**
* prm_clear_context_lost_flags_old - clear context loss flags (old API)
* @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
* @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
* @idx: CONTEXT register offset
*
* Clear hardware context loss bits for the module identified by
* (@part, @inst, @idx). No return value. XXX Deprecated; callers
* need to use a less-SoC-dependent way to identify hardware IP
* blocks.
*/
void prm_clear_context_loss_flags_old(u8 part, s16 inst, u16 idx)
{
if (prm_ll_data->clear_context_loss_flags_old)
prm_ll_data->clear_context_loss_flags_old(part, inst, idx);
else
WARN_ONCE(1, "prm: %s: no mapping function defined\n",
__func__);
}
/** /**
* prm_register - register per-SoC low-level data with the PRM * prm_register - register per-SoC low-level data with the PRM
* @pld: low-level per-SoC OMAP PRM data & function pointers to register * @pld: low-level per-SoC OMAP PRM data & function pointers to register
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册