mirror of
https://github.com/torvalds/linux.git
synced 2026-03-14 02:06:15 +01:00
soc/tegra: pmc: Add PMC contextual functions
Add implementations that take as argument a struct tegra_pmc * for most public APIs, as well as a function to obtain the PMC for any given device. This will allow transitioning away users from relying on a global variable storing the PMC context. Signed-off-by: Thierry Reding <treding@nvidia.com>
This commit is contained in:
parent
e1fd5ad68a
commit
70f752ebb0
2 changed files with 221 additions and 17 deletions
|
|
@ -957,29 +957,121 @@ static int tegra_genpd_power_off(struct generic_pm_domain *domain)
|
|||
return err;
|
||||
}
|
||||
|
||||
static void tegra_pmc_put_device(void *data)
|
||||
{
|
||||
struct tegra_pmc *pmc = data;
|
||||
|
||||
put_device(pmc->dev);
|
||||
}
|
||||
|
||||
static const struct of_device_id tegra_pmc_match[];
|
||||
|
||||
static struct tegra_pmc *tegra_pmc_get(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
struct device_node *np;
|
||||
struct tegra_pmc *pmc;
|
||||
|
||||
np = of_parse_phandle(dev->of_node, "nvidia,pmc", 0);
|
||||
if (!np) {
|
||||
struct device_node *parent = of_node_get(dev->of_node);
|
||||
|
||||
while ((parent = of_get_next_parent(parent)) != NULL) {
|
||||
np = of_find_matching_node(parent, tegra_pmc_match);
|
||||
if (np)
|
||||
break;
|
||||
}
|
||||
|
||||
of_node_put(parent);
|
||||
|
||||
if (!np)
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
pdev = of_find_device_by_node(np);
|
||||
of_node_put(np);
|
||||
|
||||
if (!pdev)
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
pmc = platform_get_drvdata(pdev);
|
||||
if (!pmc) {
|
||||
put_device(&pdev->dev);
|
||||
return ERR_PTR(-EPROBE_DEFER);
|
||||
}
|
||||
|
||||
return pmc;
|
||||
}
|
||||
|
||||
/**
|
||||
* tegra_powergate_power_on() - power on partition
|
||||
* tegra_pmc_get() - find the PMC for a given device
|
||||
* @dev: device for which to find the PMC
|
||||
*
|
||||
* Returns a pointer to the PMC on success or an ERR_PTR()-encoded error code
|
||||
* otherwise.
|
||||
*/
|
||||
struct tegra_pmc *devm_tegra_pmc_get(struct device *dev)
|
||||
{
|
||||
struct tegra_pmc *pmc;
|
||||
int err;
|
||||
|
||||
pmc = tegra_pmc_get(dev);
|
||||
if (IS_ERR(pmc))
|
||||
return pmc;
|
||||
|
||||
err = devm_add_action_or_reset(dev, tegra_pmc_put_device, pmc);
|
||||
if (err < 0)
|
||||
return ERR_PTR(err);
|
||||
|
||||
return pmc;
|
||||
}
|
||||
EXPORT_SYMBOL(devm_tegra_pmc_get);
|
||||
|
||||
/**
|
||||
* tegra_pmc_powergate_power_on() - power on partition
|
||||
* @pmc: power management controller
|
||||
* @id: partition ID
|
||||
*/
|
||||
int tegra_powergate_power_on(unsigned int id)
|
||||
int tegra_pmc_powergate_power_on(struct tegra_pmc *pmc, unsigned int id)
|
||||
{
|
||||
if (!tegra_powergate_is_available(pmc, id))
|
||||
return -EINVAL;
|
||||
|
||||
return tegra_powergate_set(pmc, id, true);
|
||||
}
|
||||
EXPORT_SYMBOL(tegra_pmc_powergate_power_on);
|
||||
|
||||
/**
|
||||
* tegra_powergate_power_on() - power on partition
|
||||
* @id: partition ID
|
||||
*/
|
||||
int tegra_powergate_power_on(unsigned int id)
|
||||
{
|
||||
return tegra_pmc_powergate_power_on(pmc, id);
|
||||
}
|
||||
EXPORT_SYMBOL(tegra_powergate_power_on);
|
||||
|
||||
/**
|
||||
* tegra_pmc_powergate_power_off() - power off partition
|
||||
* @pmc: power management controller
|
||||
* @id: partition ID
|
||||
*/
|
||||
int tegra_pmc_powergate_power_off(struct tegra_pmc *pmc, unsigned int id)
|
||||
{
|
||||
if (!tegra_powergate_is_available(pmc, id))
|
||||
return -EINVAL;
|
||||
|
||||
return tegra_powergate_set(pmc, id, false);
|
||||
}
|
||||
EXPORT_SYMBOL(tegra_pmc_powergate_power_off);
|
||||
|
||||
/**
|
||||
* tegra_powergate_power_off() - power off partition
|
||||
* @id: partition ID
|
||||
*/
|
||||
int tegra_powergate_power_off(unsigned int id)
|
||||
{
|
||||
if (!tegra_powergate_is_available(pmc, id))
|
||||
return -EINVAL;
|
||||
|
||||
return tegra_powergate_set(pmc, id, false);
|
||||
return tegra_pmc_powergate_power_off(pmc, id);
|
||||
}
|
||||
EXPORT_SYMBOL(tegra_powergate_power_off);
|
||||
|
||||
|
|
@ -997,28 +1089,41 @@ static int tegra_powergate_is_powered(struct tegra_pmc *pmc, unsigned int id)
|
|||
}
|
||||
|
||||
/**
|
||||
* tegra_powergate_remove_clamping() - remove power clamps for partition
|
||||
* tegra_pmc_powergate_remove_clamping() - remove power clamps for partition
|
||||
* @pmc: power management controller
|
||||
* @id: partition ID
|
||||
*/
|
||||
int tegra_powergate_remove_clamping(unsigned int id)
|
||||
int tegra_pmc_powergate_remove_clamping(struct tegra_pmc *pmc, unsigned int id)
|
||||
{
|
||||
if (!tegra_powergate_is_available(pmc, id))
|
||||
return -EINVAL;
|
||||
|
||||
return __tegra_powergate_remove_clamping(pmc, id);
|
||||
}
|
||||
EXPORT_SYMBOL(tegra_pmc_powergate_remove_clamping);
|
||||
|
||||
/**
|
||||
* tegra_powergate_remove_clamping() - remove power clamps for partition
|
||||
* @id: partition ID
|
||||
*/
|
||||
int tegra_powergate_remove_clamping(unsigned int id)
|
||||
{
|
||||
return tegra_pmc_powergate_remove_clamping(pmc, id);
|
||||
}
|
||||
EXPORT_SYMBOL(tegra_powergate_remove_clamping);
|
||||
|
||||
/**
|
||||
* tegra_powergate_sequence_power_up() - power up partition
|
||||
* tegra_pmc_powergate_sequence_power_up() - power up partition
|
||||
* @pmc: power management controller
|
||||
* @id: partition ID
|
||||
* @clk: clock for partition
|
||||
* @rst: reset for partition
|
||||
*
|
||||
* Must be called with clk disabled, and returns with clk enabled.
|
||||
*/
|
||||
int tegra_powergate_sequence_power_up(unsigned int id, struct clk *clk,
|
||||
struct reset_control *rst)
|
||||
int tegra_pmc_powergate_sequence_power_up(struct tegra_pmc *pmc,
|
||||
unsigned int id, struct clk *clk,
|
||||
struct reset_control *rst)
|
||||
{
|
||||
struct tegra_powergate *pg;
|
||||
int err;
|
||||
|
|
@ -1052,6 +1157,21 @@ int tegra_powergate_sequence_power_up(unsigned int id, struct clk *clk,
|
|||
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(tegra_pmc_powergate_sequence_power_up);
|
||||
|
||||
/**
|
||||
* tegra_powergate_sequence_power_up() - power up partition
|
||||
* @id: partition ID
|
||||
* @clk: clock for partition
|
||||
* @rst: reset for partition
|
||||
*
|
||||
* Must be called with clk disabled, and returns with clk enabled.
|
||||
*/
|
||||
int tegra_powergate_sequence_power_up(unsigned int id, struct clk *clk,
|
||||
struct reset_control *rst)
|
||||
{
|
||||
return tegra_pmc_powergate_sequence_power_up(pmc, id, clk, rst);
|
||||
}
|
||||
EXPORT_SYMBOL(tegra_powergate_sequence_power_up);
|
||||
|
||||
/**
|
||||
|
|
@ -1627,11 +1747,12 @@ static void tegra_io_pad_unprepare(struct tegra_pmc *pmc)
|
|||
|
||||
/**
|
||||
* tegra_io_pad_power_enable() - enable power to I/O pad
|
||||
* @pmc: power management controller
|
||||
* @id: Tegra I/O pad ID for which to enable power
|
||||
*
|
||||
* Returns: 0 on success or a negative error code on failure.
|
||||
*/
|
||||
int tegra_io_pad_power_enable(enum tegra_io_pad id)
|
||||
int tegra_pmc_io_pad_power_enable(struct tegra_pmc *pmc, enum tegra_io_pad id)
|
||||
{
|
||||
const struct tegra_io_pad_soc *pad;
|
||||
unsigned long request, status;
|
||||
|
|
@ -1666,15 +1787,28 @@ unlock:
|
|||
mutex_unlock(&pmc->powergates_lock);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(tegra_pmc_io_pad_power_enable);
|
||||
|
||||
/**
|
||||
* tegra_io_pad_power_enable() - enable power to I/O pad
|
||||
* @id: Tegra I/O pad ID for which to enable power
|
||||
*
|
||||
* Returns: 0 on success or a negative error code on failure.
|
||||
*/
|
||||
int tegra_io_pad_power_enable(enum tegra_io_pad id)
|
||||
{
|
||||
return tegra_pmc_io_pad_power_enable(pmc, id);
|
||||
}
|
||||
EXPORT_SYMBOL(tegra_io_pad_power_enable);
|
||||
|
||||
/**
|
||||
* tegra_io_pad_power_disable() - disable power to I/O pad
|
||||
* tegra_pmc_io_pad_power_disable() - disable power to I/O pad
|
||||
* @pmc: power management controller
|
||||
* @id: Tegra I/O pad ID for which to disable power
|
||||
*
|
||||
* Returns: 0 on success or a negative error code on failure.
|
||||
*/
|
||||
int tegra_io_pad_power_disable(enum tegra_io_pad id)
|
||||
int tegra_pmc_io_pad_power_disable(struct tegra_pmc *pmc, enum tegra_io_pad id)
|
||||
{
|
||||
const struct tegra_io_pad_soc *pad;
|
||||
unsigned long request, status;
|
||||
|
|
@ -1709,6 +1843,18 @@ unlock:
|
|||
mutex_unlock(&pmc->powergates_lock);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(tegra_pmc_io_pad_power_disable);
|
||||
|
||||
/**
|
||||
* tegra_io_pad_power_disable() - disable power to I/O pad
|
||||
* @id: Tegra I/O pad ID for which to disable power
|
||||
*
|
||||
* Returns: 0 on success or a negative error code on failure.
|
||||
*/
|
||||
int tegra_io_pad_power_disable(enum tegra_io_pad id)
|
||||
{
|
||||
return tegra_pmc_io_pad_power_disable(pmc, id);
|
||||
}
|
||||
EXPORT_SYMBOL(tegra_io_pad_power_disable);
|
||||
|
||||
static int tegra_io_pad_is_powered(struct tegra_pmc *pmc, enum tegra_io_pad id)
|
||||
|
|
@ -2184,9 +2330,9 @@ static int tegra_io_pad_pinconf_set(struct pinctrl_dev *pctl_dev,
|
|||
switch (param) {
|
||||
case PIN_CONFIG_MODE_LOW_POWER:
|
||||
if (arg)
|
||||
err = tegra_io_pad_power_disable(pad->id);
|
||||
err = tegra_pmc_io_pad_power_disable(pmc, pad->id);
|
||||
else
|
||||
err = tegra_io_pad_power_enable(pad->id);
|
||||
err = tegra_pmc_io_pad_power_enable(pmc, pad->id);
|
||||
if (err)
|
||||
return err;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
struct clk;
|
||||
struct reset_control;
|
||||
struct tegra_pmc;
|
||||
|
||||
bool tegra_pmc_cpu_is_powered(unsigned int cpuid);
|
||||
int tegra_pmc_cpu_power_on(unsigned int cpuid);
|
||||
|
|
@ -149,11 +150,24 @@ enum tegra_io_pad {
|
|||
};
|
||||
|
||||
#ifdef CONFIG_SOC_TEGRA_PMC
|
||||
struct tegra_pmc *devm_tegra_pmc_get(struct device *dev);
|
||||
|
||||
int tegra_pmc_powergate_power_on(struct tegra_pmc *pmc, unsigned int id);
|
||||
int tegra_pmc_powergate_power_off(struct tegra_pmc *pmc, unsigned int id);
|
||||
int tegra_pmc_powergate_remove_clamping(struct tegra_pmc *pmc, unsigned int id);
|
||||
|
||||
/* Must be called with clk disabled, and returns with clk enabled */
|
||||
int tegra_pmc_powergate_sequence_power_up(struct tegra_pmc *pmc,
|
||||
unsigned int id, struct clk *clk,
|
||||
struct reset_control *rst);
|
||||
int tegra_pmc_io_pad_power_enable(struct tegra_pmc *pmc, enum tegra_io_pad id);
|
||||
int tegra_pmc_io_pad_power_disable(struct tegra_pmc *pmc, enum tegra_io_pad id);
|
||||
|
||||
/* legacy */
|
||||
int tegra_powergate_power_on(unsigned int id);
|
||||
int tegra_powergate_power_off(unsigned int id);
|
||||
int tegra_powergate_remove_clamping(unsigned int id);
|
||||
|
||||
/* Must be called with clk disabled, and returns with clk enabled */
|
||||
int tegra_powergate_sequence_power_up(unsigned int id, struct clk *clk,
|
||||
struct reset_control *rst);
|
||||
|
||||
|
|
@ -166,6 +180,50 @@ void tegra_pmc_enter_suspend_mode(enum tegra_suspend_mode mode);
|
|||
bool tegra_pmc_core_domain_state_synced(void);
|
||||
|
||||
#else
|
||||
static inline struct tegra_pmc *devm_tegra_pmc_get(struct device *dev)
|
||||
{
|
||||
return ERR_PTR(-ENOSYS);
|
||||
}
|
||||
|
||||
static inline int
|
||||
tegra_pmc_powergate_power_on(struct tegra_pmc *pmc, unsigned int id)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
static inline int
|
||||
tegra_pmc_powergate_power_off(struct tegra_pmc *pmc, unsigned int id)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
static inline int
|
||||
tegra_pmc_powergate_remove_clamping(struct tegra_pmc *pmc, unsigned int id)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/* Must be called with clk disabled, and returns with clk enabled */
|
||||
static inline int
|
||||
tegra_pmc_powergate_sequence_power_up(struct tegra_pmc *pmc, unsigned int id,
|
||||
struct clk *clk,
|
||||
struct reset_control *rst)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
static inline int
|
||||
tegra_pmc_io_pad_power_enable(struct tegra_pmc *pmc, enum tegra_io_pad id)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
static inline int
|
||||
tegra_pmc_io_pad_power_disable(struct tegra_pmc *pmc, enum tegra_io_pad id)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
static inline int tegra_powergate_power_on(unsigned int id)
|
||||
{
|
||||
return -ENOSYS;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue