diff options
Diffstat (limited to 'arch/arm/mach-omap2/omap_hwmod.c')
| -rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.c | 57 | 
1 files changed, 42 insertions, 15 deletions
| diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index d9ee0ff094d4..e3f0ecaf87dd 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -2357,25 +2357,29 @@ static struct device_node *of_dev_hwmod_lookup(struct device_node *np,  /**   * _init_mpu_rt_base - populate the virtual address for a hwmod   * @oh: struct omap_hwmod * to locate the virtual address + * @data: (unused, caller should pass NULL) + * @np: struct device_node * of the IP block's device node in the DT data   *   * Cache the virtual address used by the MPU to access this IP block's   * registers.  This address is needed early so the OCP registers that   * are part of the device's address space can be ioremapped properly. - * No return value. + * + * Returns 0 on success, -EINVAL if an invalid hwmod is passed, and + * -ENXIO on absent or invalid register target address space.   */ -static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data) +static int __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data, +				    struct device_node *np)  {  	struct omap_hwmod_addr_space *mem;  	void __iomem *va_start = NULL; -	struct device_node *np;  	if (!oh) -		return; +		return -EINVAL;  	_save_mpu_port_index(oh);  	if (oh->_int_flags & _HWMOD_NO_MPU_PORT) -		return; +		return -ENXIO;  	mem = _find_mpu_rt_addr_space(oh);  	if (!mem) { @@ -2383,25 +2387,24 @@ static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data)  			 oh->name);  		/* Extract the IO space from device tree blob */ -		if (!of_have_populated_dt()) -			return; +		if (!np) +			return -ENXIO; -		np = of_dev_hwmod_lookup(of_find_node_by_name(NULL, "ocp"), oh); -		if (np) -			va_start = of_iomap(np, oh->mpu_rt_idx); +		va_start = of_iomap(np, oh->mpu_rt_idx);  	} else {  		va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start);  	}  	if (!va_start) {  		pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name); -		return; +		return -ENXIO;  	}  	pr_debug("omap_hwmod: %s: MPU register target at va %p\n",  		 oh->name, va_start);  	oh->_mpu_rt_va = va_start; +	return 0;  }  /** @@ -2414,18 +2417,28 @@ static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data)   * registered at this point.  This is the first of two phases for   * hwmod initialization.  Code called here does not touch any hardware   * registers, it simply prepares internal data structures.  Returns 0 - * upon success or if the hwmod isn't registered, or -EINVAL upon - * failure. + * upon success or if the hwmod isn't registered or if the hwmod's + * address space is not defined, or -EINVAL upon failure.   */  static int __init _init(struct omap_hwmod *oh, void *data)  {  	int r; +	struct device_node *np = NULL;  	if (oh->_state != _HWMOD_STATE_REGISTERED)  		return 0; -	if (oh->class->sysc) -		_init_mpu_rt_base(oh, NULL); +	if (of_have_populated_dt()) +		np = of_dev_hwmod_lookup(of_find_node_by_name(NULL, "ocp"), oh); + +	if (oh->class->sysc) { +		r = _init_mpu_rt_base(oh, NULL, np); +		if (r < 0) { +			WARN(1, "omap_hwmod: %s: doesn't have mpu register target base\n", +			     oh->name); +			return 0; +		} +	}  	r = _init_clocks(oh, NULL);  	if (r < 0) { @@ -2433,6 +2446,12 @@ static int __init _init(struct omap_hwmod *oh, void *data)  		return -EINVAL;  	} +	if (np) +		if (of_find_property(np, "ti,no-reset-on-init", NULL)) +			oh->flags |= HWMOD_INIT_NO_RESET; +		if (of_find_property(np, "ti,no-idle-on-init", NULL)) +			oh->flags |= HWMOD_INIT_NO_IDLE; +  	oh->_state = _HWMOD_STATE_INITIALIZED;  	return 0; @@ -4125,6 +4144,14 @@ void __init omap_hwmod_init(void)  		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_am43xx()) { +		soc_ops.enable_module = _omap4_enable_module; +		soc_ops.disable_module = _omap4_disable_module; +		soc_ops.wait_target_ready = _omap4_wait_target_ready; +		soc_ops.assert_hardreset = _omap4_assert_hardreset; +		soc_ops.deassert_hardreset = _omap4_deassert_hardreset; +		soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted; +		soc_ops.init_clkdm = _init_clkdm;  	} else if (soc_is_am33xx()) {  		soc_ops.enable_module = _am33xx_enable_module;  		soc_ops.disable_module = _am33xx_disable_module; |