Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+34 −3
Original line number Diff line number Diff line
@@ -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);
+7 −0
Original line number Diff line number Diff line
@@ -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;