pinctrl: add sleep mode management for hogs
authorJulien Delacou <julien.delacou@stericsson.com>
Mon, 10 Dec 2012 13:47:33 +0000 (14:47 +0100)
committerLinus Walleij <linus.walleij@linaro.org>
Fri, 11 Jan 2013 20:48:05 +0000 (21:48 +0100)
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>
drivers/pinctrl/core.c
drivers/pinctrl/core.h

index 5b4885c..3611753 100644 (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);
index 12f5694..232a9f6 100644 (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;