diff options
| author | Tony Lindgren <tony@atomide.com> | 2012-11-26 12:32:50 -0800 | 
|---|---|---|
| committer | Tony Lindgren <tony@atomide.com> | 2012-11-26 12:32:50 -0800 | 
| commit | 8b9c1ac2e11a9fb3a5a8860fb7570ff7633aa7f7 (patch) | |
| tree | 282feb4b7a0f4b430b363048616f50e27f656594 | |
| parent | 558a0780b0a04862a678f7823215424b4e5501f9 (diff) | |
| parent | c567b0584c352e7f97ced003be46bed8581ddd5b (diff) | |
| download | olio-linux-3.10-8b9c1ac2e11a9fb3a5a8860fb7570ff7633aa7f7.tar.xz olio-linux-3.10-8b9c1ac2e11a9fb3a5a8860fb7570ff7633aa7f7.zip  | |
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 | 85 | ||||
| -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, 248 insertions, 69 deletions
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 924bf24693c..007dc4d85d5 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -51,6 +51,10 @@  #include "prcm_mpu44xx.h"  #include "prminst44xx.h"  #include "cminst44xx.h" +#include "prm2xxx.h" +#include "prm3xxx.h" +#include "prm44xx.h" +  /*   * The machine specific code may provide the extra mapping besides the   * default mapping provided here. @@ -392,6 +396,7 @@ void __init omap2420_init_early(void)  	omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP2420_PRM_BASE));  	omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP2420_CM_BASE), NULL);  	omap2xxx_check_revision(); +	omap2xxx_prm_init();  	omap2xxx_cm_init();  	omap_common_init_early();  	omap2xxx_voltagedomains_init(); @@ -422,6 +427,7 @@ void __init omap2430_init_early(void)  	omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP2430_PRM_BASE));  	omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP2430_CM_BASE), NULL);  	omap2xxx_check_revision(); +	omap2xxx_prm_init();  	omap2xxx_cm_init();  	omap_common_init_early();  	omap2xxx_voltagedomains_init(); @@ -457,6 +463,7 @@ void __init omap3_init_early(void)  	omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE), NULL);  	omap3xxx_check_revision();  	omap3xxx_check_features(); +	omap3xxx_prm_init();  	omap3xxx_cm_init();  	omap_common_init_early();  	omap3xxx_voltagedomains_init(); @@ -591,6 +598,7 @@ void __init omap4430_init_early(void)  	omap_cm_base_init();  	omap4xxx_check_revision();  	omap4xxx_check_features(); +	omap44xx_prm_init();  	omap_common_init_early();  	omap44xx_voltagedomains_init();  	omap44xx_powerdomains_init(); diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c index 0ef934fec36..e065daa537c 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)  /**   * omap_device_count_resources - count number of struct resource entries needed   * @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   * omap_device @od.  Used by omap_device_build_ss() to determine how   * much memory to allocate before calling   * 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 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",  		 od->pdev->name, c, od->hwmods_cnt); @@ -557,52 +559,73 @@ struct omap_device *omap_device_alloc(struct platform_device *pdev,  	od->hwmods = hwmods;  	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:  	 *   OF framework will construct the resource structure (currently  	 *   does for MEM & IRQ resource) and we should respect/use these  	 *   resources, killing hwmod dependency.  	 *   If pdev->num_resources > 0, we assume that MEM & IRQ resources  	 *   have been allocated by OF layer already (through DTB). -	 * -	 * Non-DT Boot: -	 *   Here, pdev->num_resources = 0, and we should get all the -	 *   resources from hwmod. +	 *   As preparation for the future we examine the OF provided resources +	 *   to see if we have DMA resources provided already. In this case +	 *   there is no need to update the resources for the device, we use the +	 *   OF provided ones.  	 *  	 * TODO: Once DMA resource is available from OF layer, we should  	 *   kill filling any resources from hwmod.  	 */ -	if (res_count > pdev->num_resources) { -		/* Allocate resources memory to account for new resources */ -		res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL); -		if (!res) -			goto oda_exit3; +	if (!pdev->num_resources) { +		/* Count all resources for the device */ +		res_count = omap_device_count_resources(od, IORESOURCE_IRQ | +							    IORESOURCE_DMA | +							    IORESOURCE_MEM); +	} else { +		/* Take a look if we already have DMA resource via DT */ +		for (i = 0; i < pdev->num_resources; i++) { +			struct resource *r = &pdev->resource[i]; -		/* -		 * If pdev->num_resources > 0, then assume that, -		 * MEM and IRQ resources will only come from DT and only -		 * fill DMA resource from hwmod layer. -		 */ -		if (pdev->num_resources && pdev->resource) { -			dev_dbg(&pdev->dev, "%s(): resources already allocated %d\n", -				__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); +			/* We have it, no need to touch the resources */ +			if (r->flags == IORESOURCE_DMA) +				goto have_everything;  		} +		/* 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); -		kfree(res); +		res_count += pdev->num_resources; +	} -		if (ret) -			goto oda_exit3; +	/* Allocate resources memory to account for new resources */ +	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) {  		pm_lats = omap_default_latency;  		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 68616b2b5b9..a8090907fe3 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 {  	int (*is_hardreset_asserted)(struct omap_hwmod *oh,  				     struct omap_hwmod_rst_info *ohri);  	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 */ @@ -1983,6 +1985,42 @@ static void _reconfigure_io_chain(void)  }  /** + * _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   * @oh: struct omap_hwmod *   * @@ -2065,6 +2103,9 @@ static int _enable(struct omap_hwmod *oh)  	if (soc_ops.enable_module)  		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) :  		-EINVAL;  	if (!r) { @@ -3386,7 +3427,7 @@ int omap_hwmod_reset(struct omap_hwmod *oh)  /**   * omap_hwmod_count_resources - count number of struct resources needed by 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   * contain omap_hwmod @oh resources.  Intended to be called by code @@ -3399,20 +3440,25 @@ int omap_hwmod_reset(struct omap_hwmod *oh)   * 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; -	struct list_head *p; -	int ret; -	int i = 0; +	int ret = 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) { -		os = _fetch_next_ocp_if(&p, &i); -		ret += _count_ocp_if_addr_spaces(os); +	if (flags & IORESOURCE_MEM) { +		int i = 0; +		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; @@ -3907,17 +3953,21 @@ ohsps_unlock:   * omap_hwmod_get_context_loss_count - get lost context count   * @oh: struct omap_hwmod *   * - * Query the powerdomain of of @oh to get the context loss - * count for this device. + * Returns the context loss count of associated @oh + * upon success, or zero if no context loss data is available.   * - * Returns the context loss count of the powerdomain assocated with @oh - * upon success, or zero if no powerdomain exists for @oh. + * On OMAP4, this queries the per-hwmod context loss register, + * 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)  {  	struct powerdomain *pwrdm;  	int ret = 0; +	if (soc_ops.get_context_lost) +		return soc_ops.get_context_lost(oh); +  	pwrdm = omap_hwmod_get_pwrdm(oh);  	if (pwrdm)  		ret = pwrdm_get_context_loss_count(pwrdm); @@ -4032,6 +4082,8 @@ void __init omap_hwmod_init(void)  		soc_ops.deassert_hardreset = _omap4_deassert_hardreset;  		soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;  		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()) {  		soc_ops.enable_module = _am33xx_enable_module;  		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 87b59b45c67..86b7414b583 100644 --- a/arch/arm/mach-omap2/omap_hwmod.h +++ b/arch/arm/mach-omap2/omap_hwmod.h @@ -2,7 +2,7 @@   * omap_hwmod macros, structures   *   * Copyright (C) 2009-2011 Nokia Corporation - * Copyright (C) 2012 Texas Instruments, Inc. + * Copyright (C) 2011-2012 Texas Instruments, Inc.   * Paul Walmsley   *   * Created in collaboration with (alphabetical order): BenoƮt Cousson, @@ -394,12 +394,15 @@ struct omap_hwmod_omap2_prcm {  /**   * struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data - * @clkctrl_reg: PRCM address of the clock control register - * @rstctrl_reg: address of the XXX_RSTCTRL register located in the PRM + * @clkctrl_offs: offset of the PRCM clock control register + * @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   * @rstst_reg: (AM33XX only) address of the XXX_RSTST register in the PRM   * @submodule_wkdep_bit: bit shift of the WKDEP range   * @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   * whole register without masking. @lostcontext_mask should only be @@ -415,6 +418,7 @@ struct omap_hwmod_omap4_prcm {  	u8		submodule_wkdep_bit;  	u8		modulemode;  	u8		flags; +	int		context_lost_counter;  }; @@ -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);  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_dma_resources(struct omap_hwmod *oh, struct resource *res);  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 a1a266ce90d..ac25ae6667c 100644 --- a/arch/arm/mach-omap2/prm.h +++ b/arch/arm/mach-omap2/prm.h @@ -114,16 +114,25 @@ struct prm_reset_src_map {  /**   * 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 {  	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_unregister(struct prm_ll_data *pld);  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 diff --git a/arch/arm/mach-omap2/prm2xxx.c b/arch/arm/mach-omap2/prm2xxx.c index bf24fc47603..faeab18696d 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 = {  	.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())  		return 0;  	return prm_register(&omap2xxx_prm_ll_data);  } -subsys_initcall(omap2xxx_prm_init);  static void __exit omap2xxx_prm_exit(void)  { diff --git a/arch/arm/mach-omap2/prm2xxx.h b/arch/arm/mach-omap2/prm2xxx.h index fe8a14f190a..3194dd87e0e 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);  extern void omap2xxx_prm_dpll_reset(void); -extern int __init prm2xxx_init(void); -extern int __exit prm2xxx_exit(void); +extern int __init omap2xxx_prm_init(void);  #endif diff --git a/arch/arm/mach-omap2/prm3xxx.c b/arch/arm/mach-omap2/prm3xxx.c index b86116cf0db..db198d05858 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 = {  	.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;  	if (!cpu_is_omap34xx())  		return 0; -	ret = prm_register(&omap3xxx_prm_ll_data); -	if (ret) -		return ret; -  	omap3xxx_prm_enable_io_wakeup();  	ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup);  	if (!ret)  		irq_set_status_flags(omap_prcm_event_to_irq("io"),  				     IRQ_NOAUTOEN); -  	return ret;  } -subsys_initcall(omap3xxx_prm_init); +subsys_initcall(omap3xxx_prm_late_init);  static void __exit omap3xxx_prm_exit(void)  { diff --git a/arch/arm/mach-omap2/prm3xxx.h b/arch/arm/mach-omap2/prm3xxx.h index 10cd41a8129..277f71794e6 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);  extern void omap3xxx_prm_dpll3_reset(void); +extern int __init omap3xxx_prm_init(void);  extern u32 omap3xxx_prm_get_reset_sources(void);  #endif /* __ASSEMBLER */ diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c index 6d3467af205..7498bc77fe8 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)  	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 */  static int omap4_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst) @@ -613,24 +644,28 @@ struct pwrdm_ops omap4_pwrdm_operations = {   */  static struct prm_ll_data omap44xx_prm_ll_data = {  	.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())  		return 0; -	ret = prm_register(&omap44xx_prm_ll_data); -	if (ret) -		return ret; +	return prm_register(&omap44xx_prm_ll_data); +} + +static int __init omap44xx_prm_late_init(void) +{ +	if (!cpu_is_omap44xx()) +		return 0;  	omap44xx_prm_enable_io_wakeup();  	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)  { diff --git a/arch/arm/mach-omap2/prm44xx.h b/arch/arm/mach-omap2/prm44xx.h index c8e1accdc90..22b0979206c 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);  extern void omap44xx_prm_save_and_clear_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);  # endif diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c index d2e0798a4c8..c6ae53ca822 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)  }  /** + * 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   * @pld: low-level per-SoC OMAP PRM data & function pointers to register   *  |