Commit 840a47ba authored by Julien Delacou's avatar Julien Delacou Committed by Linus Walleij

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: default avatarJulien Delacou <julien.delacou@stericsson.com>
Reviewed-by: default avatarStephen Warren <swarren@nvidia.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 89216494
...@@ -1076,6 +1076,30 @@ void pinctrl_unregister_map(struct pinctrl_map const *map) ...@@ -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 #ifdef CONFIG_DEBUG_FS
static int pinctrl_pins_show(struct seq_file *s, void *what) static int pinctrl_pins_show(struct seq_file *s, void *what)
...@@ -1521,16 +1545,23 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, ...@@ -1521,16 +1545,23 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
pctldev->p = pinctrl_get_locked(pctldev->dev); pctldev->p = pinctrl_get_locked(pctldev->dev);
if (!IS_ERR(pctldev->p)) { if (!IS_ERR(pctldev->p)) {
struct pinctrl_state *s = pctldev->hog_default =
pinctrl_lookup_state_locked(pctldev->p, pinctrl_lookup_state_locked(pctldev->p,
PINCTRL_STATE_DEFAULT); PINCTRL_STATE_DEFAULT);
if (IS_ERR(s)) { if (IS_ERR(pctldev->hog_default)) {
dev_dbg(dev, "failed to lookup the default state\n"); dev_dbg(dev, "failed to lookup the default state\n");
} else { } else {
if (pinctrl_select_state_locked(pctldev->p, s)) if (pinctrl_select_state_locked(pctldev->p,
pctldev->hog_default))
dev_err(dev, dev_err(dev,
"failed to select default state\n"); "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); mutex_unlock(&pinctrl_mutex);
......
...@@ -30,6 +30,8 @@ struct pinctrl_gpio_range; ...@@ -30,6 +30,8 @@ struct pinctrl_gpio_range;
* @driver_data: driver data for drivers registering to the pin controller * @driver_data: driver data for drivers registering to the pin controller
* subsystem * subsystem
* @p: result of pinctrl_get() for this device * @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 * @device_root: debugfs root for this device
*/ */
struct pinctrl_dev { struct pinctrl_dev {
...@@ -41,6 +43,8 @@ struct pinctrl_dev { ...@@ -41,6 +43,8 @@ struct pinctrl_dev {
struct module *owner; struct module *owner;
void *driver_data; void *driver_data;
struct pinctrl *p; struct pinctrl *p;
struct pinctrl_state *hog_default;
struct pinctrl_state *hog_sleep;
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
struct dentry *device_root; struct dentry *device_root;
#endif #endif
...@@ -164,5 +168,8 @@ int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps, ...@@ -164,5 +168,8 @@ int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps,
bool dup, bool locked); bool dup, bool locked);
void pinctrl_unregister_map(struct pinctrl_map const *map); 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 mutex pinctrl_mutex;
extern struct list_head pinctrldev_list; extern struct list_head pinctrldev_list;
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment