pinctrl: add sleep mode management for hogs

This fix allows handling sleep mode for hogged
pins in pinctrl. It provides functions to set pins
to sleep/default configurations according to their
current state.

Signed-off-by: Julien Delacou <julien.delacou@stericsson.com>
Reviewed-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
Julien Delacou 2012-12-10 14:47:33 +01:00 committed by Linus Walleij
parent 89216494ae
commit 840a47ba43
2 changed files with 41 additions and 3 deletions

View File

@ -1076,6 +1076,30 @@ void pinctrl_unregister_map(struct pinctrl_map const *map)
}
}
/**
* pinctrl_force_sleep() - turn a given controller device into sleep state
* @pctldev: pin controller device
*/
int pinctrl_force_sleep(struct pinctrl_dev *pctldev)
{
if (!IS_ERR(pctldev->p) && !IS_ERR(pctldev->hog_sleep))
return pinctrl_select_state(pctldev->p, pctldev->hog_sleep);
return 0;
}
EXPORT_SYMBOL_GPL(pinctrl_force_sleep);
/**
* pinctrl_force_default() - turn a given controller device into default state
* @pctldev: pin controller device
*/
int pinctrl_force_default(struct pinctrl_dev *pctldev)
{
if (!IS_ERR(pctldev->p) && !IS_ERR(pctldev->hog_default))
return pinctrl_select_state(pctldev->p, pctldev->hog_default);
return 0;
}
EXPORT_SYMBOL_GPL(pinctrl_force_default);
#ifdef CONFIG_DEBUG_FS
static int pinctrl_pins_show(struct seq_file *s, void *what)
@ -1521,16 +1545,23 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
pctldev->p = pinctrl_get_locked(pctldev->dev);
if (!IS_ERR(pctldev->p)) {
struct pinctrl_state *s =
pctldev->hog_default =
pinctrl_lookup_state_locked(pctldev->p,
PINCTRL_STATE_DEFAULT);
if (IS_ERR(s)) {
if (IS_ERR(pctldev->hog_default)) {
dev_dbg(dev, "failed to lookup the default state\n");
} else {
if (pinctrl_select_state_locked(pctldev->p, s))
if (pinctrl_select_state_locked(pctldev->p,
pctldev->hog_default))
dev_err(dev,
"failed to select default state\n");
}
pctldev->hog_sleep =
pinctrl_lookup_state_locked(pctldev->p,
PINCTRL_STATE_SLEEP);
if (IS_ERR(pctldev->hog_sleep))
dev_dbg(dev, "failed to lookup the sleep state\n");
}
mutex_unlock(&pinctrl_mutex);

View File

@ -30,6 +30,8 @@ struct pinctrl_gpio_range;
* @driver_data: driver data for drivers registering to the pin controller
* subsystem
* @p: result of pinctrl_get() for this device
* @hog_default: default state for pins hogged by this device
* @hog_sleep: sleep state for pins hogged by this device
* @device_root: debugfs root for this device
*/
struct pinctrl_dev {
@ -41,6 +43,8 @@ struct pinctrl_dev {
struct module *owner;
void *driver_data;
struct pinctrl *p;
struct pinctrl_state *hog_default;
struct pinctrl_state *hog_sleep;
#ifdef CONFIG_DEBUG_FS
struct dentry *device_root;
#endif
@ -164,5 +168,8 @@ int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps,
bool dup, bool locked);
void pinctrl_unregister_map(struct pinctrl_map const *map);
extern int pinctrl_force_sleep(struct pinctrl_dev *pctldev);
extern int pinctrl_force_default(struct pinctrl_dev *pctldev);
extern struct mutex pinctrl_mutex;
extern struct list_head pinctrldev_list;