OMAP: hwmod/device: add omap_{device,hwmod}_get_mpu_rt_va

Add omap_device_get_mpu_rt_va().  This is intended to be used by
device drivers (currently, via a struct platform_data function
pointer) to retrieve their corresponding device's virtual base address
that the MPU should use to access the device.  This is needed because
the omap_hwmod code does its own ioremap(), in order to gain access to
the module's OCP_SYSCONFIG register.

Add omap_hwmod_get_mpu_rt_va().  omap_device_get_mpu_rt_va() calls this
function to do the real work.

While here, rename struct omap_hwmod._rt_va to struct
omap_hwmod._mpu_rt_va, to reinforce that it refers to the MPU's
register target virtual address base (as opposed to, for example, the
L3's).

In the future, this belongs as a function in an omap_bus, so it is not
necessary to call this through a platform_data function pointer.

The use-case for this function was originally presented by Santosh
Shilimkar <santosh.shilimkar@ti.com>.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
This commit is contained in:
Paul Walmsley 2010-07-26 16:34:33 -06:00
parent 08072acf3a
commit db2a60bf25
4 changed files with 53 additions and 8 deletions

View file

@ -1,7 +1,7 @@
/* /*
* omap_hwmod implementation for OMAP2/3/4 * omap_hwmod implementation for OMAP2/3/4
* *
* Copyright (C) 2009 Nokia Corporation * Copyright (C) 2009-2010 Nokia Corporation
* *
* Paul Walmsley, Benoît Cousson, Kevin Hilman * Paul Walmsley, Benoît Cousson, Kevin Hilman
* *
@ -1069,12 +1069,12 @@ static int _setup(struct omap_hwmod *oh, void *data)
u32 omap_hwmod_readl(struct omap_hwmod *oh, u16 reg_offs) u32 omap_hwmod_readl(struct omap_hwmod *oh, u16 reg_offs)
{ {
return __raw_readl(oh->_rt_va + reg_offs); return __raw_readl(oh->_mpu_rt_va + reg_offs);
} }
void omap_hwmod_writel(u32 v, struct omap_hwmod *oh, u16 reg_offs) void omap_hwmod_writel(u32 v, struct omap_hwmod *oh, u16 reg_offs)
{ {
__raw_writel(v, oh->_rt_va + reg_offs); __raw_writel(v, oh->_mpu_rt_va + reg_offs);
} }
int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode) int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode)
@ -1131,7 +1131,7 @@ int omap_hwmod_register(struct omap_hwmod *oh)
ms_id = _find_mpu_port_index(oh); ms_id = _find_mpu_port_index(oh);
if (!IS_ERR_VALUE(ms_id)) { if (!IS_ERR_VALUE(ms_id)) {
oh->_mpu_port_index = ms_id; oh->_mpu_port_index = ms_id;
oh->_rt_va = _find_mpu_rt_base(oh, oh->_mpu_port_index); oh->_mpu_rt_va = _find_mpu_rt_base(oh, oh->_mpu_port_index);
} else { } else {
oh->_int_flags |= _HWMOD_NO_MPU_PORT; oh->_int_flags |= _HWMOD_NO_MPU_PORT;
} }
@ -1283,7 +1283,7 @@ int omap_hwmod_unregister(struct omap_hwmod *oh)
pr_debug("omap_hwmod: %s: unregistering\n", oh->name); pr_debug("omap_hwmod: %s: unregistering\n", oh->name);
mutex_lock(&omap_hwmod_mutex); mutex_lock(&omap_hwmod_mutex);
iounmap(oh->_rt_va); iounmap(oh->_mpu_rt_va);
list_del(&oh->node); list_del(&oh->node);
mutex_unlock(&omap_hwmod_mutex); mutex_unlock(&omap_hwmod_mutex);
@ -1543,6 +1543,29 @@ struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh)
} }
/**
* omap_hwmod_get_mpu_rt_va - return the module's base address (for the MPU)
* @oh: struct omap_hwmod *
*
* Returns the virtual address corresponding to the beginning of the
* module's register target, in the address range that is intended to
* be used by the MPU. Returns the virtual address upon success or NULL
* upon error.
*/
void __iomem *omap_hwmod_get_mpu_rt_va(struct omap_hwmod *oh)
{
if (!oh)
return NULL;
if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
return NULL;
if (oh->_state == _HWMOD_STATE_UNKNOWN)
return NULL;
return oh->_mpu_rt_va;
}
/** /**
* omap_hwmod_add_initiator_dep - add sleepdep from @init_oh to @oh * omap_hwmod_add_initiator_dep - add sleepdep from @init_oh to @oh
* @oh: struct omap_hwmod * * @oh: struct omap_hwmod *

View file

@ -101,6 +101,8 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
int omap_device_register(struct omap_device *od); int omap_device_register(struct omap_device *od);
int omap_early_device_register(struct omap_device *od); int omap_early_device_register(struct omap_device *od);
void __iomem *omap_device_get_rt_va(struct omap_device *od);
/* OMAP PM interface */ /* OMAP PM interface */
int omap_device_align_pm_lat(struct platform_device *pdev, int omap_device_align_pm_lat(struct platform_device *pdev,
u32 new_wakeup_lat_limit); u32 new_wakeup_lat_limit);

View file

@ -1,7 +1,7 @@
/* /*
* omap_hwmod macros, structures * omap_hwmod macros, structures
* *
* Copyright (C) 2009 Nokia Corporation * Copyright (C) 2009-2010 Nokia Corporation
* Paul Walmsley * Paul Walmsley
* *
* Created in collaboration with (alphabetical order): Benoît Cousson, * Created in collaboration with (alphabetical order): Benoît Cousson,
@ -419,7 +419,7 @@ struct omap_hwmod_class {
* @slaves: ptr to array of OCP ifs that this hwmod can respond on * @slaves: ptr to array of OCP ifs that this hwmod can respond on
* @dev_attr: arbitrary device attributes that can be passed to the driver * @dev_attr: arbitrary device attributes that can be passed to the driver
* @_sysc_cache: internal-use hwmod flags * @_sysc_cache: internal-use hwmod flags
* @_rt_va: cached register target start address (internal use) * @_mpu_rt_va: cached register target start address (internal use)
* @_mpu_port_index: cached MPU register target slave ID (internal use) * @_mpu_port_index: cached MPU register target slave ID (internal use)
* @msuspendmux_reg_id: CONTROL_MSUSPENDMUX register ID (1-6) * @msuspendmux_reg_id: CONTROL_MSUSPENDMUX register ID (1-6)
* @msuspendmux_shift: CONTROL_MSUSPENDMUX register bit shift * @msuspendmux_shift: CONTROL_MSUSPENDMUX register bit shift
@ -460,7 +460,7 @@ struct omap_hwmod {
struct omap_hwmod_ocp_if **slaves; /* connect to *_TA */ struct omap_hwmod_ocp_if **slaves; /* connect to *_TA */
void *dev_attr; void *dev_attr;
u32 _sysc_cache; u32 _sysc_cache;
void __iomem *_rt_va; void __iomem *_mpu_rt_va;
struct list_head node; struct list_head node;
u16 flags; u16 flags;
u8 _mpu_port_index; u8 _mpu_port_index;
@ -507,6 +507,7 @@ int omap_hwmod_count_resources(struct omap_hwmod *oh);
int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res); int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res);
struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh); struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh);
void __iomem *omap_hwmod_get_mpu_rt_va(struct omap_hwmod *oh);
int omap_hwmod_add_initiator_dep(struct omap_hwmod *oh, int omap_hwmod_add_initiator_dep(struct omap_hwmod *oh,
struct omap_hwmod *init_oh); struct omap_hwmod *init_oh);

View file

@ -655,6 +655,25 @@ struct powerdomain *omap_device_get_pwrdm(struct omap_device *od)
return omap_hwmod_get_pwrdm(od->hwmods[0]); return omap_hwmod_get_pwrdm(od->hwmods[0]);
} }
/**
* omap_device_get_mpu_rt_va - return the MPU's virtual addr for the hwmod base
* @od: struct omap_device *
*
* Return the MPU's virtual address for the base of the hwmod, from
* the ioremap() that the hwmod code does. Only valid if there is one
* hwmod associated with this device. Returns NULL if there are zero
* or more than one hwmods associated with this omap_device;
* otherwise, passes along the return value from
* omap_hwmod_get_mpu_rt_va().
*/
void __iomem *omap_device_get_rt_va(struct omap_device *od)
{
if (od->hwmods_cnt != 1)
return NULL;
return omap_hwmod_get_mpu_rt_va(od->hwmods[0]);
}
/* /*
* Public functions intended for use in omap_device_pm_latency * Public functions intended for use in omap_device_pm_latency
* .activate_func and .deactivate_func function pointers * .activate_func and .deactivate_func function pointers