* [1/6] usb: chipidea: Add dynamic pinctrl selection
@ 2018-08-23 14:53 Bjorn Andersson
0 siblings, 0 replies; 5+ messages in thread
From: Bjorn Andersson @ 2018-08-23 14:53 UTC (permalink / raw)
To: Loic Poulain
Cc: Peter.Chen, linux-usb, linux-arm-msm, david.brown, robh+dt,
andy.gross
On Tue 21 Aug 06:55 PDT 2018, Loic Poulain wrote:
> Some hardware implementations require to configure pins differently
> according to the USB role (host/device), this can be an update of the
> pins routing or a simple GPIO value change.
>
> This patch introduces new optional "host" and "device" pinctrls.
> If these pinctrls are defined by the device, they are respectively
> selected on host/device role start.
>
> If a default pinctrl exist, it is restored on host/device role stop.
>
The implementation looks reasonable, but we're actually just toggling a
gpio using pinctrl states. Do you see any reason not to control this mux
through the gpio api?
Regards,
Bjorn
> Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
> ---
> drivers/usb/chipidea/core.c | 19 +++++++++++++++++++
> drivers/usb/chipidea/host.c | 9 +++++++++
> drivers/usb/chipidea/udc.c | 9 +++++++++
> include/linux/usb/chipidea.h | 6 ++++++
> 4 files changed, 43 insertions(+)
>
> diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
> index 85fc6db..03e52fc 100644
> --- a/drivers/usb/chipidea/core.c
> +++ b/drivers/usb/chipidea/core.c
> @@ -46,6 +46,7 @@
> #include <linux/extcon.h>
> #include <linux/phy/phy.h>
> #include <linux/platform_device.h>
> +#include <linux/pinctrl/consumer.h>
> #include <linux/module.h>
> #include <linux/idr.h>
> #include <linux/interrupt.h>
> @@ -723,6 +724,24 @@ static int ci_get_platdata(struct device *dev,
> else
> cable->connected = false;
> }
> +
> + platdata->pctl = devm_pinctrl_get(dev);
> + if (!IS_ERR(platdata->pctl)) {
> + struct pinctrl_state *p;
> +
> + p = pinctrl_lookup_state(platdata->pctl, "default");
> + if (!IS_ERR(p))
> + platdata->pins_default = p;
> +
> + p = pinctrl_lookup_state(platdata->pctl, "host");
> + if (!IS_ERR(p))
> + platdata->pins_host = p;
> +
> + p = pinctrl_lookup_state(platdata->pctl, "device");
> + if (!IS_ERR(p))
> + platdata->pins_device = p;
> + }
> +
> return 0;
> }
>
> diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
> index af45aa32..55dbd49 100644
> --- a/drivers/usb/chipidea/host.c
> +++ b/drivers/usb/chipidea/host.c
> @@ -13,6 +13,7 @@
> #include <linux/usb/hcd.h>
> #include <linux/usb/chipidea.h>
> #include <linux/regulator/consumer.h>
> +#include <linux/pinctrl/consumer.h>
>
> #include "../host/ehci.h"
>
> @@ -150,6 +151,10 @@ static int host_start(struct ci_hdrc *ci)
> }
> }
>
> + if (ci->platdata->pins_host)
> + pinctrl_select_state(ci->platdata->pctl,
> + ci->platdata->pins_host);
> +
> ret = usb_add_hcd(hcd, 0, 0);
> if (ret) {
> goto disable_reg;
> @@ -194,6 +199,10 @@ static void host_stop(struct ci_hdrc *ci)
> }
> ci->hcd = NULL;
> ci->otg.host = NULL;
> +
> + if (ci->platdata->pins_host && ci->platdata->pins_default)
> + pinctrl_select_state(ci->platdata->pctl,
> + ci->platdata->pins_default);
> }
>
>
> diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
> index 9852ec5..c04384e 100644
> --- a/drivers/usb/chipidea/udc.c
> +++ b/drivers/usb/chipidea/udc.c
> @@ -19,6 +19,7 @@
> #include <linux/usb/gadget.h>
> #include <linux/usb/otg-fsm.h>
> #include <linux/usb/chipidea.h>
> +#include <linux/pinctrl/consumer.h>
>
> #include "ci.h"
> #include "udc.h"
> @@ -1965,6 +1966,10 @@ void ci_hdrc_gadget_destroy(struct ci_hdrc *ci)
>
> static int udc_id_switch_for_device(struct ci_hdrc *ci)
> {
> + if (ci->platdata->pins_device)
> + pinctrl_select_state(ci->platdata->pctl,
> + ci->platdata->pins_device);
> +
> if (ci->is_otg)
> /* Clear and enable BSV irq */
> hw_write_otgsc(ci, OTGSC_BSVIS | OTGSC_BSVIE,
> @@ -1983,6 +1988,10 @@ static void udc_id_switch_for_host(struct ci_hdrc *ci)
> hw_write_otgsc(ci, OTGSC_BSVIE | OTGSC_BSVIS, OTGSC_BSVIS);
>
> ci->vbus_active = 0;
> +
> + if (ci->platdata->pins_device && ci->platdata->pins_default)
> + pinctrl_select_state(ci->platdata->pctl,
> + ci->platdata->pins_default);
> }
>
> /**
> diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
> index 07f9936..63758c3 100644
> --- a/include/linux/usb/chipidea.h
> +++ b/include/linux/usb/chipidea.h
> @@ -77,6 +77,12 @@ struct ci_hdrc_platform_data {
> struct ci_hdrc_cable vbus_extcon;
> struct ci_hdrc_cable id_extcon;
> u32 phy_clkgate_delay_us;
> +
> + /* pins */
> + struct pinctrl *pctl;
> + struct pinctrl_state *pins_default;
> + struct pinctrl_state *pins_host;
> + struct pinctrl_state *pins_device;
> };
>
> /* Default offset of capability registers */
> --
> 2.7.4
>
^ permalink raw reply [flat|nested] 5+ messages in thread* [1/6] usb: chipidea: Add dynamic pinctrl selection
@ 2018-08-24 9:40 Loic Poulain
0 siblings, 0 replies; 5+ messages in thread
From: Loic Poulain @ 2018-08-24 9:40 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Peter Chen, USB, linux-arm-msm, David Brown, Rob Herring,
Bjorn Andersson, Andy Gross
On 23 August 2018 at 12:11, Andy Shevchenko <andy.shevchenko@gmail.com> wrote:
> On Tue, Aug 21, 2018 at 4:57 PM Loic Poulain <loic.poulain@linaro.org> wrote:
>>
>> Some hardware implementations require to configure pins differently
>> according to the USB role (host/device), this can be an update of the
>> pins routing or a simple GPIO value change.
>>
>> This patch introduces new optional "host" and "device" pinctrls.
>> If these pinctrls are defined by the device, they are respectively
>> selected on host/device role start.
>>
>> If a default pinctrl exist, it is restored on host/device role stop.
>
>> #include <linux/extcon.h>
>> #include <linux/phy/phy.h>
>> #include <linux/platform_device.h>
>> +#include <linux/pinctrl/consumer.h>
>
> A nit: Even in this context it would be nice to keep *some* order.
>
Ok.
>> #include <linux/module.h>
>> #include <linux/idr.h>
>> #include <linux/interrupt.h>
>
>> + p = pinctrl_lookup_state(platdata->pctl, "default");
>> + p = pinctrl_lookup_state(platdata->pctl, "host");
>> + p = pinctrl_lookup_state(platdata->pctl, "device");
>
> I'm wondering if we have any rules applied to these names.
I suppose i have document this in the chipidea DT binding doc.
>
>> #include <linux/usb/hcd.h>
>> #include <linux/usb/chipidea.h>
>> #include <linux/regulator/consumer.h>
>> +#include <linux/pinctrl/consumer.h>
>
> Ditto about ordering.
>
>> + if (ci->platdata->pins_host)
>> + pinctrl_select_state(ci->platdata->pctl,
>> + ci->platdata->pins_host);
>
> Hmm... Do we need to have a condition above?
>
Yes, since these pinctrls are optional and can be null.
>> + if (ci->platdata->pins_host && ci->platdata->pins_default)
>> + pinctrl_select_state(ci->platdata->pctl,
>> + ci->platdata->pins_default);
>
> Ditto about conditional.
>
>> #include <linux/usb/gadget.h>
>> #include <linux/usb/otg-fsm.h>
>> #include <linux/usb/chipidea.h>
>> +#include <linux/pinctrl/consumer.h>
>
> Ditto about ordering.
>
>> + if (ci->platdata->pins_device)
>> + pinctrl_select_state(ci->platdata->pctl,
>> + ci->platdata->pins_device);
>
>
>> + if (ci->platdata->pins_device && ci->platdata->pins_default)
>> + pinctrl_select_state(ci->platdata->pctl,
>> + ci->platdata->pins_default);
>
> Ditto about conditional.
>
> --
> With Best Regards,
> Andy Shevchenko
Regards,
Loic
^ permalink raw reply [flat|nested] 5+ messages in thread
* [1/6] usb: chipidea: Add dynamic pinctrl selection
@ 2018-08-23 15:44 Loic Poulain
0 siblings, 0 replies; 5+ messages in thread
From: Loic Poulain @ 2018-08-23 15:44 UTC (permalink / raw)
To: Bjorn Andersson
Cc: Peter Chen, USB, linux-arm-msm, David Brown, Rob Herring,
Andy Gross
Hi Bjorn,
On 23 August 2018 at 16:53, Bjorn Andersson <bjorn.andersson@linaro.org> wrote:
> On Tue 21 Aug 06:55 PDT 2018, Loic Poulain wrote:
>
>> Some hardware implementations require to configure pins differently
>> according to the USB role (host/device), this can be an update of the
>> pins routing or a simple GPIO value change.
>>
>> This patch introduces new optional "host" and "device" pinctrls.
>> If these pinctrls are defined by the device, they are respectively
>> selected on host/device role start.
>>
>> If a default pinctrl exist, it is restored on host/device role stop.
>>
>
> The implementation looks reasonable, but we're actually just toggling a
> gpio using pinctrl states. Do you see any reason not to control this mux
> through the gpio api?
>
Actually, two gpios (including hub reset one), but you're right.
Point is that these gpios are very specific to the Dragonboard layout and
not related to USB controller itself (external mux), so I'm not sure it makes
sense to control a 'mux' GPIO from the chipidea driver. That's why I used
pinctrl which is more generic and hides the underlying operations (a simple
GPIO toggling in our case).
But let me know if there is a better way.
Regards,
Loic
^ permalink raw reply [flat|nested] 5+ messages in thread
* [1/6] usb: chipidea: Add dynamic pinctrl selection
@ 2018-08-23 10:11 Andy Shevchenko
0 siblings, 0 replies; 5+ messages in thread
From: Andy Shevchenko @ 2018-08-23 10:11 UTC (permalink / raw)
To: Loic Poulain
Cc: Peter.Chen, USB, linux-arm-msm, David Brown, Rob Herring,
Bjorn Andersson, Andy Gross
On Tue, Aug 21, 2018 at 4:57 PM Loic Poulain <loic.poulain@linaro.org> wrote:
>
> Some hardware implementations require to configure pins differently
> according to the USB role (host/device), this can be an update of the
> pins routing or a simple GPIO value change.
>
> This patch introduces new optional "host" and "device" pinctrls.
> If these pinctrls are defined by the device, they are respectively
> selected on host/device role start.
>
> If a default pinctrl exist, it is restored on host/device role stop.
> #include <linux/extcon.h>
> #include <linux/phy/phy.h>
> #include <linux/platform_device.h>
> +#include <linux/pinctrl/consumer.h>
A nit: Even in this context it would be nice to keep *some* order.
> #include <linux/module.h>
> #include <linux/idr.h>
> #include <linux/interrupt.h>
> + p = pinctrl_lookup_state(platdata->pctl, "default");
> + p = pinctrl_lookup_state(platdata->pctl, "host");
> + p = pinctrl_lookup_state(platdata->pctl, "device");
I'm wondering if we have any rules applied to these names.
> #include <linux/usb/hcd.h>
> #include <linux/usb/chipidea.h>
> #include <linux/regulator/consumer.h>
> +#include <linux/pinctrl/consumer.h>
Ditto about ordering.
> + if (ci->platdata->pins_host)
> + pinctrl_select_state(ci->platdata->pctl,
> + ci->platdata->pins_host);
Hmm... Do we need to have a condition above?
> + if (ci->platdata->pins_host && ci->platdata->pins_default)
> + pinctrl_select_state(ci->platdata->pctl,
> + ci->platdata->pins_default);
Ditto about conditional.
> #include <linux/usb/gadget.h>
> #include <linux/usb/otg-fsm.h>
> #include <linux/usb/chipidea.h>
> +#include <linux/pinctrl/consumer.h>
Ditto about ordering.
> + if (ci->platdata->pins_device)
> + pinctrl_select_state(ci->platdata->pctl,
> + ci->platdata->pins_device);
> + if (ci->platdata->pins_device && ci->platdata->pins_default)
> + pinctrl_select_state(ci->platdata->pctl,
> + ci->platdata->pins_default);
Ditto about conditional.
^ permalink raw reply [flat|nested] 5+ messages in thread
* [1/6] usb: chipidea: Add dynamic pinctrl selection
@ 2018-08-21 13:55 Loic Poulain
0 siblings, 0 replies; 5+ messages in thread
From: Loic Poulain @ 2018-08-21 13:55 UTC (permalink / raw)
To: Peter.Chen
Cc: linux-usb, linux-arm-msm, david.brown, robh+dt, bjorn.andersson,
andy.gross, Loic Poulain
Some hardware implementations require to configure pins differently
according to the USB role (host/device), this can be an update of the
pins routing or a simple GPIO value change.
This patch introduces new optional "host" and "device" pinctrls.
If these pinctrls are defined by the device, they are respectively
selected on host/device role start.
If a default pinctrl exist, it is restored on host/device role stop.
Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
---
drivers/usb/chipidea/core.c | 19 +++++++++++++++++++
drivers/usb/chipidea/host.c | 9 +++++++++
drivers/usb/chipidea/udc.c | 9 +++++++++
include/linux/usb/chipidea.h | 6 ++++++
4 files changed, 43 insertions(+)
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 85fc6db..03e52fc 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -46,6 +46,7 @@
#include <linux/extcon.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
+#include <linux/pinctrl/consumer.h>
#include <linux/module.h>
#include <linux/idr.h>
#include <linux/interrupt.h>
@@ -723,6 +724,24 @@ static int ci_get_platdata(struct device *dev,
else
cable->connected = false;
}
+
+ platdata->pctl = devm_pinctrl_get(dev);
+ if (!IS_ERR(platdata->pctl)) {
+ struct pinctrl_state *p;
+
+ p = pinctrl_lookup_state(platdata->pctl, "default");
+ if (!IS_ERR(p))
+ platdata->pins_default = p;
+
+ p = pinctrl_lookup_state(platdata->pctl, "host");
+ if (!IS_ERR(p))
+ platdata->pins_host = p;
+
+ p = pinctrl_lookup_state(platdata->pctl, "device");
+ if (!IS_ERR(p))
+ platdata->pins_device = p;
+ }
+
return 0;
}
diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
index af45aa32..55dbd49 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -13,6 +13,7 @@
#include <linux/usb/hcd.h>
#include <linux/usb/chipidea.h>
#include <linux/regulator/consumer.h>
+#include <linux/pinctrl/consumer.h>
#include "../host/ehci.h"
@@ -150,6 +151,10 @@ static int host_start(struct ci_hdrc *ci)
}
}
+ if (ci->platdata->pins_host)
+ pinctrl_select_state(ci->platdata->pctl,
+ ci->platdata->pins_host);
+
ret = usb_add_hcd(hcd, 0, 0);
if (ret) {
goto disable_reg;
@@ -194,6 +199,10 @@ static void host_stop(struct ci_hdrc *ci)
}
ci->hcd = NULL;
ci->otg.host = NULL;
+
+ if (ci->platdata->pins_host && ci->platdata->pins_default)
+ pinctrl_select_state(ci->platdata->pctl,
+ ci->platdata->pins_default);
}
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 9852ec5..c04384e 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -19,6 +19,7 @@
#include <linux/usb/gadget.h>
#include <linux/usb/otg-fsm.h>
#include <linux/usb/chipidea.h>
+#include <linux/pinctrl/consumer.h>
#include "ci.h"
#include "udc.h"
@@ -1965,6 +1966,10 @@ void ci_hdrc_gadget_destroy(struct ci_hdrc *ci)
static int udc_id_switch_for_device(struct ci_hdrc *ci)
{
+ if (ci->platdata->pins_device)
+ pinctrl_select_state(ci->platdata->pctl,
+ ci->platdata->pins_device);
+
if (ci->is_otg)
/* Clear and enable BSV irq */
hw_write_otgsc(ci, OTGSC_BSVIS | OTGSC_BSVIE,
@@ -1983,6 +1988,10 @@ static void udc_id_switch_for_host(struct ci_hdrc *ci)
hw_write_otgsc(ci, OTGSC_BSVIE | OTGSC_BSVIS, OTGSC_BSVIS);
ci->vbus_active = 0;
+
+ if (ci->platdata->pins_device && ci->platdata->pins_default)
+ pinctrl_select_state(ci->platdata->pctl,
+ ci->platdata->pins_default);
}
/**
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index 07f9936..63758c3 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -77,6 +77,12 @@ struct ci_hdrc_platform_data {
struct ci_hdrc_cable vbus_extcon;
struct ci_hdrc_cable id_extcon;
u32 phy_clkgate_delay_us;
+
+ /* pins */
+ struct pinctrl *pctl;
+ struct pinctrl_state *pins_default;
+ struct pinctrl_state *pins_host;
+ struct pinctrl_state *pins_device;
};
/* Default offset of capability registers */
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2018-08-24 9:40 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-08-23 14:53 [1/6] usb: chipidea: Add dynamic pinctrl selection Bjorn Andersson
-- strict thread matches above, loose matches on Subject: below --
2018-08-24 9:40 Loic Poulain
2018-08-23 15:44 Loic Poulain
2018-08-23 10:11 Andy Shevchenko
2018-08-21 13:55 Loic Poulain
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox