From: Tony Lindgren <tony@atomide.com>
To: Gary Bisson <gary.bisson@boundarydevices.com>
Cc: "Mika Penttilä" <mika.penttila@nextfour.com>,
LKML <linux-kernel@vger.kernel.org>,
linus.walleij@linaro.org
Subject: Re: [REGRESSION] pinctrl, of, unable to find hogs
Date: Mon, 27 Feb 2017 10:45:35 -0800 [thread overview]
Message-ID: <20170227184535.GP21809@atomide.com> (raw)
In-Reply-To: <20170227173718.GO21809@atomide.com>
* Tony Lindgren <tony@atomide.com> [170227 09:37]:
> * Gary Bisson <gary.bisson@boundarydevices.com> [170227 08:42]:
> > > Not sure how to fix it though since we can't move the dt probing before
> > > radix tree init.
>
> Yup looks like we still have an issue with pinctrl driver functions
> getting called before driver probe has completed.
>
> How about we introduce something like:
>
> int pinctrl_claim_hogs(struct pinctrl_dev *pctldev);
>
> Then the drivers can call that at the end of the probe after
> the pins have been parsed?
>
> This should be safe as no other driver can claim the pins either
> before the pins have been parsed :)
Below is an initial take on this solution. I've only briefly tested
it so far but maybe give it a try and see if it helps.
I'll take a look if we can make the error handling better for
pinctrl_register_and_init().
Regards,
Tony
8< ---------------------------
>From tony Mon Sep 17 00:00:00 2001
From: Tony Lindgren <tony@atomide.com>
Date: Mon, 27 Feb 2017 10:15:22 -0800
Subject: [PATCH] Fix imx hogs
---
drivers/pinctrl/core.c | 90 ++++++++++++++++++++++++---------
drivers/pinctrl/freescale/pinctrl-imx.c | 6 +++
drivers/pinctrl/pinctrl-single.c | 6 +++
drivers/pinctrl/sh-pfc/pinctrl.c | 12 ++++-
drivers/pinctrl/ti/pinctrl-ti-iodelay.c | 4 +-
include/linux/pinctrl/pinctrl.h | 1 +
6 files changed, 93 insertions(+), 26 deletions(-)
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -2010,30 +2010,14 @@ struct pinctrl_dev *pinctrl_init_controller(struct pinctrl_desc *pctldesc,
return ERR_PTR(ret);
}
-static int pinctrl_create_and_start(struct pinctrl_dev *pctldev)
+static int pinctrl_create(struct pinctrl_dev *pctldev)
{
+ /* REVISIT: Can we bail out on errors here? */
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");
- }
-
- 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");
- }
+ if (IS_ERR(pctldev->p))
+ dev_warn(pctldev->dev,
+ "creating incomplete pin controller: %li\n",
+ PTR_ERR(pctldev->p));
mutex_lock(&pinctrldev_list_mutex);
list_add_tail(&pctldev->node, &pinctrldev_list);
@@ -2044,6 +2028,66 @@ static int pinctrl_create_and_start(struct pinctrl_dev *pctldev)
return 0;
}
+int pinctrl_claim_hogs(struct pinctrl_dev *pctldev)
+{
+ if (IS_ERR(pctldev->p)) {
+ dev_err(pctldev->dev,
+ "claim hogs for incomplete pin controller?: %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;
+}
+EXPORT_SYMBOL_GPL(pinctrl_claim_hogs);
+
+/* REVISIT: Can we bail out on errors here? */
+static int pinctrl_create_and_start(struct pinctrl_dev *pctldev)
+{
+ int error;
+
+ error = pinctrl_create(pctldev);
+ if (error) {
+ dev_warn(pctldev->dev,
+ "pin controller not claiming hogs: %i\n",
+ error);
+
+ goto out_warn_only;
+ }
+
+ error = pinctrl_claim_hogs(pctldev);
+ if (!error)
+ return 0;
+
+out_warn_only:
+ dev_warn(pctldev->dev,
+ "pin controller incomplete, hogs not claimed: %i\n",
+ error);
+
+ return 0;
+}
+
/**
* pinctrl_register() - register a pin controller device
* @pctldesc: descriptor for this pin controller
@@ -2097,7 +2141,7 @@ int pinctrl_register_and_init(struct pinctrl_desc *pctldesc,
*/
*pctldev = p;
- error = pinctrl_create_and_start(p);
+ error = pinctrl_create(p);
if (error) {
mutex_destroy(&p->mutex);
kfree(p);
diff --git a/drivers/pinctrl/freescale/pinctrl-imx.c b/drivers/pinctrl/freescale/pinctrl-imx.c
--- a/drivers/pinctrl/freescale/pinctrl-imx.c
+++ b/drivers/pinctrl/freescale/pinctrl-imx.c
@@ -788,6 +788,12 @@ int imx_pinctrl_probe(struct platform_device *pdev,
goto free;
}
+ ret = pinctrl_claim_hogs(ipctl->pctl);
+ if (ret) {
+ dev_err(&pdev->dev, "could not claim hogs: %i\n", ret);
+ goto free;
+ }
+
dev_info(&pdev->dev, "initialized IMX pinctrl driver\n");
return 0;
diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -1765,6 +1765,12 @@ static int pcs_probe(struct platform_device *pdev)
goto free;
}
+ ret = pinctrl_claim_hogs(pcs->pctl);
+ if (ret) {
+ dev_err(pcs->dev, "could not claim hogs\n");
+ goto free;
+ }
+
ret = pcs_add_gpio_func(np, pcs);
if (ret < 0)
goto free;
diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c
--- a/drivers/pinctrl/sh-pfc/pinctrl.c
+++ b/drivers/pinctrl/sh-pfc/pinctrl.c
@@ -816,6 +816,14 @@ int sh_pfc_register_pinctrl(struct sh_pfc *pfc)
pmx->pctl_desc.pins = pmx->pins;
pmx->pctl_desc.npins = pfc->info->nr_pins;
- return devm_pinctrl_register_and_init(pfc->dev, &pmx->pctl_desc, pmx,
- &pmx->pctl);
+ ret = devm_pinctrl_register_and_init(pfc->dev, &pmx->pctl_desc, pmx,
+ &pmx->pctl);
+ if (ret) {
+ dev_error(pcf->dev, "could not claim hogs: %i\n", ret);
+
+ return ret;
+
+ }
+
+ return pinctrl_claim_hogs(pmx->pctl);
}
diff --git a/drivers/pinctrl/ti/pinctrl-ti-iodelay.c b/drivers/pinctrl/ti/pinctrl-ti-iodelay.c
--- a/drivers/pinctrl/ti/pinctrl-ti-iodelay.c
+++ b/drivers/pinctrl/ti/pinctrl-ti-iodelay.c
@@ -885,13 +885,15 @@ static int ti_iodelay_probe(struct platform_device *pdev)
iod->desc.name = dev_name(dev);
iod->desc.owner = THIS_MODULE;
+ platform_set_drvdata(pdev, iod);
+
ret = pinctrl_register_and_init(&iod->desc, dev, iod, &iod->pctl);
if (ret) {
dev_err(dev, "Failed to register pinctrl\n");
goto exit_out;
}
- platform_set_drvdata(pdev, iod);
+ return pinctrl_claim_hogs(iod->pctl);
exit_out:
of_node_put(np);
diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h
--- a/include/linux/pinctrl/pinctrl.h
+++ b/include/linux/pinctrl/pinctrl.h
@@ -145,6 +145,7 @@ struct pinctrl_desc {
extern int pinctrl_register_and_init(struct pinctrl_desc *pctldesc,
struct device *dev, void *driver_data,
struct pinctrl_dev **pctldev);
+extern int pinctrl_claim_hogs(struct pinctrl_dev *pctldev);
/* Please use pinctrl_register_and_init() instead */
extern struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
--
2.11.1
next prev parent reply other threads:[~2017-02-27 22:35 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-02-27 5:44 [REGRESSION] pinctrl, of, unable to find hogs Mika Penttilä
2017-02-27 15:53 ` Tony Lindgren
2017-02-27 16:27 ` Gary Bisson
2017-02-27 16:40 ` Gary Bisson
2017-02-27 17:37 ` Tony Lindgren
2017-02-27 18:45 ` Tony Lindgren [this message]
2017-02-27 21:06 ` Gary Bisson
2017-02-27 23:05 ` Tony Lindgren
2017-02-28 9:25 ` Gary Bisson
2017-02-28 17:24 ` Tony Lindgren
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170227184535.GP21809@atomide.com \
--to=tony@atomide.com \
--cc=gary.bisson@boundarydevices.com \
--cc=linus.walleij@linaro.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mika.penttila@nextfour.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.