|
@@ -2010,29 +2010,57 @@ out_err:
|
|
|
return ERR_PTR(ret);
|
|
|
}
|
|
|
|
|
|
-static int pinctrl_create_and_start(struct pinctrl_dev *pctldev)
|
|
|
+static int pinctrl_claim_hogs(struct pinctrl_dev *pctldev)
|
|
|
{
|
|
|
pctldev->p = create_pinctrl(pctldev->dev, pctldev);
|
|
|
- if (!IS_ERR(pctldev->p)) {
|
|
|
- kref_get(&pctldev->p->users);
|
|
|
- pctldev->hog_default =
|
|
|
- pinctrl_lookup_state(pctldev->p, PINCTRL_STATE_DEFAULT);
|
|
|
- if (IS_ERR(pctldev->hog_default)) {
|
|
|
- dev_dbg(pctldev->dev,
|
|
|
- "failed to lookup the default state\n");
|
|
|
- } else {
|
|
|
- if (pinctrl_select_state(pctldev->p,
|
|
|
- pctldev->hog_default))
|
|
|
- dev_err(pctldev->dev,
|
|
|
- "failed to select default state\n");
|
|
|
- }
|
|
|
+ if (PTR_ERR(pctldev->p) == -ENODEV) {
|
|
|
+ dev_dbg(pctldev->dev, "no hogs found\n");
|
|
|
|
|
|
- pctldev->hog_sleep =
|
|
|
- pinctrl_lookup_state(pctldev->p,
|
|
|
- PINCTRL_STATE_SLEEP);
|
|
|
- if (IS_ERR(pctldev->hog_sleep))
|
|
|
- dev_dbg(pctldev->dev,
|
|
|
- "failed to lookup the sleep state\n");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (IS_ERR(pctldev->p)) {
|
|
|
+ dev_err(pctldev->dev, "error claiming hogs: %li\n",
|
|
|
+ PTR_ERR(pctldev->p));
|
|
|
+
|
|
|
+ return PTR_ERR(pctldev->p);
|
|
|
+ }
|
|
|
+
|
|
|
+ kref_get(&pctldev->p->users);
|
|
|
+ pctldev->hog_default =
|
|
|
+ pinctrl_lookup_state(pctldev->p, PINCTRL_STATE_DEFAULT);
|
|
|
+ if (IS_ERR(pctldev->hog_default)) {
|
|
|
+ dev_dbg(pctldev->dev,
|
|
|
+ "failed to lookup the default state\n");
|
|
|
+ } else {
|
|
|
+ if (pinctrl_select_state(pctldev->p,
|
|
|
+ pctldev->hog_default))
|
|
|
+ dev_err(pctldev->dev,
|
|
|
+ "failed to select default state\n");
|
|
|
+ }
|
|
|
+
|
|
|
+ pctldev->hog_sleep =
|
|
|
+ pinctrl_lookup_state(pctldev->p,
|
|
|
+ PINCTRL_STATE_SLEEP);
|
|
|
+ if (IS_ERR(pctldev->hog_sleep))
|
|
|
+ dev_dbg(pctldev->dev,
|
|
|
+ "failed to lookup the sleep state\n");
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+int pinctrl_enable(struct pinctrl_dev *pctldev)
|
|
|
+{
|
|
|
+ int error;
|
|
|
+
|
|
|
+ error = pinctrl_claim_hogs(pctldev);
|
|
|
+ if (error) {
|
|
|
+ dev_err(pctldev->dev, "could not claim hogs: %i\n",
|
|
|
+ error);
|
|
|
+ mutex_destroy(&pctldev->mutex);
|
|
|
+ kfree(pctldev);
|
|
|
+
|
|
|
+ return error;
|
|
|
}
|
|
|
|
|
|
mutex_lock(&pinctrldev_list_mutex);
|
|
@@ -2043,6 +2071,7 @@ static int pinctrl_create_and_start(struct pinctrl_dev *pctldev)
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
+EXPORT_SYMBOL_GPL(pinctrl_enable);
|
|
|
|
|
|
/**
|
|
|
* pinctrl_register() - register a pin controller device
|
|
@@ -2065,25 +2094,30 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
|
|
|
if (IS_ERR(pctldev))
|
|
|
return pctldev;
|
|
|
|
|
|
- error = pinctrl_create_and_start(pctldev);
|
|
|
- if (error) {
|
|
|
- mutex_destroy(&pctldev->mutex);
|
|
|
- kfree(pctldev);
|
|
|
-
|
|
|
+ error = pinctrl_enable(pctldev);
|
|
|
+ if (error)
|
|
|
return ERR_PTR(error);
|
|
|
- }
|
|
|
|
|
|
return pctldev;
|
|
|
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(pinctrl_register);
|
|
|
|
|
|
+/**
|
|
|
+ * pinctrl_register_and_init() - register and init pin controller device
|
|
|
+ * @pctldesc: descriptor for this pin controller
|
|
|
+ * @dev: parent device for this pin controller
|
|
|
+ * @driver_data: private pin controller data for this pin controller
|
|
|
+ * @pctldev: pin controller device
|
|
|
+ *
|
|
|
+ * Note that pinctrl_enable() still needs to be manually called after
|
|
|
+ * this once the driver is ready.
|
|
|
+ */
|
|
|
int pinctrl_register_and_init(struct pinctrl_desc *pctldesc,
|
|
|
struct device *dev, void *driver_data,
|
|
|
struct pinctrl_dev **pctldev)
|
|
|
{
|
|
|
struct pinctrl_dev *p;
|
|
|
- int error;
|
|
|
|
|
|
p = pinctrl_init_controller(pctldesc, dev, driver_data);
|
|
|
if (IS_ERR(p))
|
|
@@ -2097,15 +2131,6 @@ int pinctrl_register_and_init(struct pinctrl_desc *pctldesc,
|
|
|
*/
|
|
|
*pctldev = p;
|
|
|
|
|
|
- error = pinctrl_create_and_start(p);
|
|
|
- if (error) {
|
|
|
- mutex_destroy(&p->mutex);
|
|
|
- kfree(p);
|
|
|
- *pctldev = NULL;
|
|
|
-
|
|
|
- return error;
|
|
|
- }
|
|
|
-
|
|
|
return 0;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(pinctrl_register_and_init);
|