Skip to content

Commit

Permalink
pinctrl: add sleep mode management for hogs
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Julien Delacou authored and Linus Walleij committed Jan 11, 2013
1 parent 8921649 commit 840a47b
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 3 deletions.
37 changes: 34 additions & 3 deletions drivers/pinctrl/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand Down
7 changes: 7 additions & 0 deletions drivers/pinctrl/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
Expand Down Expand Up @@ -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;

0 comments on commit 840a47b

Please sign in to comment.