* [PATCH] pinctrl: sh-pfc: Include the right header
From: Linus Walleij @ 2019-08-14 7:20 UTC (permalink / raw)
To: linux-gpio; +Cc: Linus Walleij, Geert Uytterhoeven
This is a GPIO driver, use the appropriate header
<linux/gpio/driver.h> rather than the legacy <linux/gpio.h>
header.
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
Geert tell me how you want me to handle this, you can send
it with your pull requests or I can apply it directly
if you're not queueing stuff right now.
---
drivers/pinctrl/sh-pfc/gpio.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c
index 64c09aa374ae..5a55b8da7919 100644
--- a/drivers/pinctrl/sh-pfc/gpio.c
+++ b/drivers/pinctrl/sh-pfc/gpio.c
@@ -7,7 +7,7 @@
*/
#include <linux/device.h>
-#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pinctrl/consumer.h>
--
2.21.0
^ permalink raw reply related
* [PATCH] pinctrl: st: Include the right header
From: Linus Walleij @ 2019-08-14 7:14 UTC (permalink / raw)
To: linux-gpio; +Cc: Linus Walleij, Patrice Chotard, Maxime Coquelin
The ST pinctrl driver wants to provode a gpio_chip but is using
the wrong header for this, fix the inclusion to use the right
header.
Cc: Patrice Chotard <patrice.chotard@st.com>
Cc: Maxime Coquelin <maxime.coquelin@st.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
drivers/pinctrl/pinctrl-st.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pinctrl/pinctrl-st.c b/drivers/pinctrl/pinctrl-st.c
index b9688ea548da..422bc8ec72ea 100644
--- a/drivers/pinctrl/pinctrl-st.c
+++ b/drivers/pinctrl/pinctrl-st.c
@@ -12,8 +12,8 @@
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_irq.h>
-#include <linux/of_gpio.h>
#include <linux/of_address.h>
+#include <linux/gpio/driver.h>
#include <linux/regmap.h>
#include <linux/mfd/syscon.h>
#include <linux/pinctrl/pinctrl.h>
--
2.21.0
^ permalink raw reply related
* Re: [PATCH v1 2/5] pinctrl: mediatek: Supporting driving setting without mapping current to register value
From: Sean Wang @ 2019-08-14 0:08 UTC (permalink / raw)
To: Light Hsieh
Cc: Linus Walleij, moderated list:ARM/Mediatek SoC support,
open list:GPIO SUBSYSTEM, lkml
In-Reply-To: <1565686400-5711-3-git-send-email-light.hsieh@mediatek.com>
Hi, Light
a few nitpicks, but the overall changes look good to me
On Tue, Aug 13, 2019 at 1:53 AM Light Hsieh <light.hsieh@mediatek.com> wrote:
>
> From: Light Hsieh <light.hsieh@mediatek.com>
>
> Mediatek's smarphone project actual usage does need to know current value
> (in mA) in procedure of finding the best driving setting.
> The steps in the procedure is like as follow:
>
> 1. set driving setting field in setting register as 0, measure waveform,
> perform test, and etc.
> 2. set driving setting field in setting register as 1, measure waveform,
> perform test, and etc.
> ...
> n. set driving setting field in setting register as n-1, measure
> waveform, perform test, and etc.
> Check the results of steps 1~n and adopt the setting that get best result.
>
> This procedure does need to know the mapping between current to register
> value.
> Therefore, setting driving without mapping current is more pratical for
> Mediatek's smartphone usage.
>
> Change-Id: Iacdabf0cada230fc5acad96673810c12a6c4556d
remove change-id
> ---
> drivers/pinctrl/mediatek/pinctrl-mt6765.c | 4 ++--
> drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 21 +++++++++++++++++++++
> drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h | 5 +++++
> drivers/pinctrl/mediatek/pinctrl-paris.c | 1 +
> 4 files changed, 29 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
> index 32451e8..e024ebc 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
> @@ -1077,8 +1077,8 @@
> .bias_disable_get = mtk_pinconf_bias_disable_get,
> .bias_set = mtk_pinconf_bias_set,
> .bias_get = mtk_pinconf_bias_get,
> - .drive_set = mtk_pinconf_drive_set_rev1,
> - .drive_get = mtk_pinconf_drive_get_rev1,
> + .drive_set = mtk_pinconf_drive_set_direct_val,
> + .drive_get = mtk_pinconf_drive_get_direct_val,
I prefer to mtk_pinconf_drive_[get,set]_raw_val that would be better
to understand.
> .adv_pull_get = mtk_pinconf_adv_pull_get,
> .adv_pull_set = mtk_pinconf_adv_pull_set,
> };
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> index 4687f63..23a9529 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> @@ -607,6 +607,27 @@ int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
> return 0;
> }
>
> +/* Revision direct value */
> +int mtk_pinconf_drive_set_direct_val(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc, u32 arg)
> +{
> + int err;
> +
> + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV, arg);
> +
> + return err;
> +}
> +
> +int mtk_pinconf_drive_get_direct_val(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc, int *val)
> +{
> + int err;
> +
> + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, val);
> +
> + return err;
> +}
> +
> int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
> const struct mtk_pin_desc *desc, bool pullup,
> u32 arg)
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
> index 1b7da42..b3bada0 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
> @@ -288,6 +288,11 @@ int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl *hw,
> int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
> const struct mtk_pin_desc *desc, int *val);
>
> +int mtk_pinconf_drive_set_direct_val(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc, u32 arg);
> +int mtk_pinconf_drive_get_direct_val(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc, int *val);
> +
> int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
> const struct mtk_pin_desc *desc, bool pullup,
> u32 arg);
> diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
> index 28b4951..71c94b2 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-paris.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
> @@ -964,3 +964,4 @@ static int mtk_paris_pinctrl_resume(struct device *device)
> .suspend_noirq = mtk_paris_pinctrl_suspend,
> .resume_noirq = mtk_paris_pinctrl_resume,
> };
> +
remove unnecessary the empty line
> --
> 1.8.1.1.dirty
>
^ permalink raw reply
* Hallo Schatz
From: Grace Garcia @ 2019-08-13 23:22 UTC (permalink / raw)
To: linux-gpio
Mein Liebling,
Es ist verständlich, dass Sie etwas besorgt sind, weil Sie mich nicht kennen. Ich schreibe Ihnen diese Mail mit ernsthaften Tränen in den Augen und großem Kummer in meinem Herzen. Ich habe mich entschlossen, Sie wegen der Dringlichkeit meiner Situation zu kontaktieren. Ich möchte dir das sagen, weil ich keine andere Wahl habe, als es dir zu sagen, als ich berührt wurde, um mich dir zu öffnen.
Ich bin Witwe, weil ich vor 9 Jahren meinen Mann verloren habe. Wir waren elf Jahre lang ohne Kind verheiratet. Er starb nach einer kurzen Krankheit, die einige Wochen dauerte. Als mein verstorbener Ehemann noch lebte, hinterlegte er bei einer der Banken hier in Benin die Summe von vier Millionen, achthundertfünfzigtausend Dollar (4.850.000 US-Dollar), weil wir früher Pläne hatten, eine Wohltätigkeitsfirma zu gründen.
In der Zwischenzeit sagte mir mein Arzt kürzlich, dass ich aufgrund eines Gehirntumor- / Krebs-Problems einige Wochen zu leben habe. Das, was mich am meisten stört, ist meine Schlaganfallkrankheit. Nachdem ich meinen Zustand gekannt habe, habe ich mich entschlossen, Ihnen diese Mission zu übergeben, um die weniger privilegierten Menschen zu betreuen. Sie werden dieses Geld so einsetzen, wie ich es hier anweisen werde. Ich möchte, dass Sie 35% des Gesamtgeldes für Ihren persönlichen und familiären Gebrauch verwenden, während 65% des Geldes für wohltätige Zwecke verwendet werden, um Menschen auf der Straße zu helfen.
Weil ich als Waise aufgewachsen bin und niemanden als Familienmitglied habe. Sobald ich Ihre Antwort erhalten habe, werde ich Sie mit der Bank verbinden.
Bitte kontaktieren Sie mich mit den folgenden Informationen: Ihr Nachname und Vorname, Ihre genaue Adresse und Ihr Handy- / Haus- / Bürotelefonkontakt sowie ein Ausweis wie Führerschein oder internationale Passdatenseite, damit ich sie an meine weiterleiten kann Bank und haben Sie bei der Bank als nächste Person für diesen Fonds anwesend, so dass, wenn ich jederzeit sterbe, die Situation nicht kompliziert sein wird.
Ich zähle auf Ihren guten Willen und insbesondere auf die ordnungsgemäße Verwendung dieser Mittel.
Dein
Grace Garcia
^ permalink raw reply
* Re: [PATCH v1 4/5] pinctrl: mediatek: Backward compatible to previous Mediatek's bias-pull usage
From: Sean Wang @ 2019-08-13 23:24 UTC (permalink / raw)
To: Light Hsieh
Cc: Linus Walleij, moderated list:ARM/Mediatek SoC support,
open list:GPIO SUBSYSTEM, lkml
In-Reply-To: <1565686400-5711-5-git-send-email-light.hsieh@mediatek.com>
Hi, Light
On Tue, Aug 13, 2019 at 1:53 AM Light Hsieh <light.hsieh@mediatek.com> wrote:
>
> From: Light Hsieh <light.hsieh@mediatek.com>
>
> Refine mtk_pinconf_set()/mtk_pinconf_get() for backward compatibility to
> previous Mediatek's bias-pull usage.
> In PINCTRL_MTK that use pinctrl-mtk-common.c, bias-pull setting for pins
> with 2 pull resistors can be specified as value for bias-pull-up and
> bias-pull-down. For example:
> bias-pull-up = <MTK_PUPD_SET_R1R0_00>;
> bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
> bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
> bias-pull-up = <MTK_PUPD_SET_R1R0_11>;
> bias-pull-down = <MTK_PUPD_SET_R1R0_00>;
> bias-pull-down = <MTK_PUPD_SET_R1R0_01>;
> bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
> bias-pull-down = <MTK_PUPD_SET_R1R0_11>;
>
> On the other hand, PINCTRL_MTK_PARIS use customized properties
> "mediatek,pull-up-adv" and "mediatek,pull-down-adv" to specify bias-pull
> setting for pins with 2 pull resistors.
> This introduce in-compatibility in device tree and increatse porting
> effort to Mediatek's customer that had already used PINCTRL_MTK version.
> Besides, if customers are not awared of this change and still write devicetree
> for PINCTRL_MTK version, they may encounter runtime failure with pinctrl and
> spent time to debug.
>
> This patch add backward compatible to previous Mediatek's bias-pull usage
> so that Mediatek's customer need not use a new devicetree property name.
> The rationale is that: changing driver implemenation had better leave
> interface unchanged.
>
> Change-Id: I8ea8f09278acc492ba04771826eaadb70224cd51
remove Change-Id
> ---
> drivers/pinctrl/mediatek/pinctrl-mt6765.c | 4 +-
> drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 285 +++++++++++++++++++++++
> drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h | 11 +
> drivers/pinctrl/mediatek/pinctrl-paris.c | 49 ++--
> 4 files changed, 327 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
> index bada37f..315aebd 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
> @@ -1074,8 +1074,8 @@
> .nbase_names = ARRAY_SIZE(mt6765_pinctrl_register_base_names),
> .bias_disable_set = mtk_pinconf_bias_disable_set,
> .bias_disable_get = mtk_pinconf_bias_disable_get,
> - .bias_set = mtk_pinconf_bias_set,
> - .bias_get = mtk_pinconf_bias_get,
> + .bias_set = mtk_pinconf_bias_set_combo,
> + .bias_get = mtk_pinconf_bias_get_combo,
base on the below context, I guess you should mean .bias_set_combo =
mtk_pinconf_bias_set_combo and .bias_get_combo =
mtk_pinconf_bias_get_combo.
> .drive_set = mtk_pinconf_drive_set_direct_val,
> .drive_get = mtk_pinconf_drive_get_direct_val,
> .adv_pull_get = mtk_pinconf_adv_pull_get,
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> index 23a9529..dab8418 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> @@ -13,6 +13,8 @@
> #include <linux/io.h>
> #include <linux/of_irq.h>
>
> +#include <dt-bindings/pinctrl/mt65xx.h>
include #include <dt-bindings/pinctrl/mt65xx.h> in pinctrl-paris.c,
common-v2.c is supposed dt-binding and chip independence.
> +
> #include "mtk-eint.h"
> #include "pinctrl-mtk-common-v2.h"
>
> @@ -205,6 +207,20 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
> return 0;
> }
>
> +void mtk_hw_set_value_no_lookup(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc,
> + int value, struct mtk_pin_field *pf)
> +{
> + if (value < 0 || value > pf->mask)
> + return;
> +
> + if (!pf->next)
> + mtk_rmw(hw, pf->index, pf->offset, pf->mask << pf->bitpos,
> + (value & pf->mask) << pf->bitpos);
> + else
> + mtk_hw_write_cross_field(hw, pf, value);
> +}
> +
> int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
> int field, int *value)
> {
> @@ -224,6 +240,17 @@ int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
> return 0;
> }
>
> +void mtk_hw_get_value_no_lookup(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc,
> + int *value, struct mtk_pin_field *pf)
> +{
> + if (!pf->next)
> + *value = (mtk_r32(hw, pf->index, pf->offset)
> + >> pf->bitpos) & pf->mask;
> + else
> + mtk_hw_read_cross_field(hw, pf, value);
> +}
> +
> static int mtk_xt_find_eint_num(struct mtk_pinctrl *hw, unsigned long eint_n)
> {
> const struct mtk_pin_desc *desc;
> @@ -516,6 +543,264 @@ int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
> return 0;
> }
>
> +/* Combo for the following pull register type:
> + * 1. PU + PD
> + * 2. PULLSEL + PULLEN
> + * 3. PUPD + R0 + R1
> + */
> +int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc,
> + u32 pullup, u32 arg)
> +{
> + struct mtk_pin_field pf;
> + int err = -EINVAL;
Initialization of err is not needed because mtk_hw_pin_field_lookup would do it.
> + int pu, pd;
> +
> + err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PU, &pf);
> + if (err)
> + goto out;
> +
> + if (arg == MTK_DISABLE) {
> + pu = 0;
> + pd = 0;
> + } else if ((arg == MTK_ENABLE) && pullup) {
> + pu = 1;
> + pd = 0;
> + } else if ((arg == MTK_ENABLE) && !pullup) {
> + pu = 0;
> + pd = 1;
> + } else {
> + goto out;
> + }
> +
> + mtk_hw_set_value_no_lookup(hw, desc, pu, &pf);
> +
> + err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PD, &pf);
> + if (err)
> + goto out;
> +
> + mtk_hw_set_value_no_lookup(hw, desc, pd, &pf);
> +
I think we always can merge merge both mtk_hw_pin_field_lookup and
mtk_hw_set_value_no_lookup into mtk_hw_set_value, or is there
something I am missing out?
> +out:
> + return err;
> +}
> +
> +int mtk_pinconf_bias_set_pullsel_pullen(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc,
> + u32 pullup, u32 arg)
> +{
> + struct mtk_pin_field pf;
> + int err = -EINVAL, enable;
ditto
> +
> + err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PULLEN, &pf);
> + if (err)
> + goto out;
> +
> + if (arg == MTK_DISABLE)
> + enable = 0;
> + else if (arg == MTK_ENABLE)
> + enable = 1;
> + else
> + goto out;
> +
> + mtk_hw_set_value_no_lookup(hw, desc, enable, &pf);
> +
> + err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PULLSEL, &pf);
> + if (err)
> + goto out;
> + mtk_hw_set_value_no_lookup(hw, desc, pullup, &pf);
> +
> +out:
> + return err;
> +}
> +
> +int mtk_pinconf_bias_set_pupd_r1_r0(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc,
> + u32 pullup, u32 arg)
> +{
> + struct mtk_pin_field pf;
> + int err = -EINVAL;
ditto
> + int r0, r1;
> +
> + err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PUPD, &pf);
> + if (err)
> + goto out;
> +
> + if ((arg == MTK_DISABLE) || (arg == MTK_PUPD_SET_R1R0_00)) {
> + pullup = 0;
> + r0 = 0;
> + r1 = 0;
> + } else if (arg == MTK_PUPD_SET_R1R0_01) {
> + r0 = 1;
> + r1 = 0;
> + } else if (arg == MTK_PUPD_SET_R1R0_10) {
> + r0 = 0;
> + r1 = 1;
> + } else if (arg == MTK_PUPD_SET_R1R0_11) {
> + r0 = 1;
> + r1 = 1;
> + } else
> + goto out;
> +
> + /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
> + mtk_hw_set_value_no_lookup(hw, desc, !pullup, &pf);
> +
> + err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_R0, &pf);
> + if (err)
> + goto out;
> + mtk_hw_set_value_no_lookup(hw, desc, r0, &pf);
> +
> + err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_R1, &pf);
> + if (err)
> + goto out;
> + mtk_hw_set_value_no_lookup(hw, desc, r1, &pf);
> +
> +out:
> + return err;
> +}
> +
> +int mtk_pinconf_bias_get_pu_pd(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc,
> + u32 *pullup, u32 *enable)
> +{
> + struct mtk_pin_field pf;
> + int err = -EINVAL;
ditto
> + int pu, pd;
> +
> + err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PU, &pf);
> + if (err)
> + goto out;
> +
> + mtk_hw_get_value_no_lookup(hw, desc, &pu, &pf);
> +
> + err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PD, &pf);
> + if (err)
> + goto out;
> +
> + mtk_hw_get_value_no_lookup(hw, desc, &pd, &pf);
> +
> + if (pu == 0 && pd == 0) {
> + *pullup = 0;
> + *enable = MTK_DISABLE;
> + } else if (pu == 1 && pd == 0) {
> + *pullup = 1;
> + *enable = MTK_ENABLE;
> + } else if (pu == 0 && pd == 1) {
> + *pullup = 0;
> + *enable = MTK_ENABLE;
> + } else {
> + err = -EINVAL;
> + goto out;
> + }
> +
> +out:
> + return err;
> +}
> +
> +int mtk_pinconf_bias_get_pullsel_pullen(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc,
> + u32 *pullup, u32 *enable)
> +{
> + struct mtk_pin_field pf;
> + int err = -EINVAL;
ditto
> +
> + err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PULLSEL, &pf);
> + if (err)
> + goto out;
> +
> + mtk_hw_get_value_no_lookup(hw, desc, pullup, &pf);
> +
> + err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PULLEN, &pf);
> + if (err)
> + goto out;
> +
> + mtk_hw_get_value_no_lookup(hw, desc, enable, &pf);
> +
> +out:
> + return err;
> +}
> +
> +int mtk_pinconf_bias_get_pupd_r1_r0(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc,
> + u32 *pullup, u32 *enable)
> +{
> + struct mtk_pin_field pf;
> + int err = -EINVAL;
ditto
> + int r0, r1;
> +
> + err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PUPD, &pf);
> + if (err)
> + goto out;
> +
> + /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
> + mtk_hw_get_value_no_lookup(hw, desc, pullup, &pf);
> + *pullup = !(*pullup);
> +
> + err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_R0, &pf);
> + if (err)
> + goto out;
> + mtk_hw_get_value_no_lookup(hw, desc, &r0, &pf);
> +
> + err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_R1, &pf);
> + if (err)
> + goto out;
> + mtk_hw_get_value_no_lookup(hw, desc, &r1, &pf);
> +
> + if ((r1 == 0) && (r0 == 0))
> + *enable = MTK_PUPD_SET_R1R0_00;
> + else if ((r1 == 0) && (r0 == 1))
> + *enable = MTK_PUPD_SET_R1R0_01;
> + else if ((r1 == 1) && (r0 == 0))
> + *enable = MTK_PUPD_SET_R1R0_10;
> + else if ((r1 == 1) && (r0 == 1))
> + *enable = MTK_PUPD_SET_R1R0_11;
> + else
> + goto out;
> +
> +out:
> + return err;
> +}
> +
> +int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc,
> + u32 pullup, u32 arg)
> +{
> + int err;
> +
> + err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg);
> + if (!err)
> + goto out;
> +
> + err = mtk_pinconf_bias_set_pullsel_pullen(hw, desc, pullup, arg);
> + if (!err)
> + goto out;
> +
> + err = mtk_pinconf_bias_set_pupd_r1_r0(hw, desc, pullup, arg);
> +
> +out:
> + return err;
> +}
> +
> +int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc,
> + u32 *pullup, u32 *enable)
> +{
> + int err;
> +
> + err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable);
> + if (!err)
> + goto out;
> +
> + err = mtk_pinconf_bias_get_pullsel_pullen(hw, desc, pullup, enable);
> + if (!err)
> + goto out;
> +
> + err = mtk_pinconf_bias_get_pupd_r1_r0(hw, desc, pullup, enable);
> +
> +out:
> + return err;
> +}
> +
> /* Revision 0 */
> int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
> const struct mtk_pin_desc *desc, u32 arg)
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
> index b3bada0..a13dcae 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
> @@ -216,6 +216,11 @@ struct mtk_pin_soc {
> int (*bias_get)(struct mtk_pinctrl *hw,
> const struct mtk_pin_desc *desc, bool pullup, int *res);
>
> + int (*bias_set_combo)(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc, u32 pullup, u32 arg);
> + int (*bias_get_combo)(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc, u32 *pullup, u32 *arg);
> +
> int (*drive_set)(struct mtk_pinctrl *hw,
> const struct mtk_pin_desc *desc, u32 arg);
> int (*drive_get)(struct mtk_pinctrl *hw,
> @@ -277,6 +282,12 @@ int mtk_pinconf_bias_set_rev1(struct mtk_pinctrl *hw,
> int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
> const struct mtk_pin_desc *desc, bool pullup,
> int *res);
> +int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc,
> + u32 pullup, u32 enable);
> +int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
> + const struct mtk_pin_desc *desc,
> + u32 *pullup, u32 *enable);
>
> int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
> const struct mtk_pin_desc *desc, u32 arg);
> diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
> index bbe3f8a..0a9440a 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-paris.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
> @@ -79,28 +79,38 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
> struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
> u32 param = pinconf_to_config_param(*config);
> int err, reg, ret = 1;
> + int pullup;
> const struct mtk_pin_desc *desc;
>
> desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
>
> switch (param) {
> case PIN_CONFIG_BIAS_DISABLE:
> - if (hw->soc->bias_disable_get)
> - err = hw->soc->bias_disable_get(hw, desc, &ret);
> - else
> - err = -ENOTSUPP;
> - break;
> case PIN_CONFIG_BIAS_PULL_UP:
> - if (hw->soc->bias_get)
> - err = hw->soc->bias_get(hw, desc, 1, &ret);
> - else
> - err = -ENOTSUPP;
> - break;
> case PIN_CONFIG_BIAS_PULL_DOWN:
> - if (hw->soc->bias_get)
> - err = hw->soc->bias_get(hw, desc, 0, &ret);
> - else
The above changes would break MT8183 driver, so we need to consider
them along with MT8183 pinctrl and then move the patchset forward.
> + if (hw->soc->bias_get_combo) {
> + err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret);
> + if (err)
> + goto out;
> + if (param == PIN_CONFIG_BIAS_DISABLE) {
> + if (ret == MTK_PUPD_SET_R1R0_00)
> + ret = MTK_DISABLE;
> + } else if (param == PIN_CONFIG_BIAS_PULL_UP) {
> + /* When desire to get pull-up value,
> + * return error if current setting is pull-down
> + */
> + if (!pullup)
> + err = -EINVAL;
> + } else if (param == PIN_CONFIG_BIAS_PULL_DOWN) {
> + /* When desire to get pull-down value,
> + * return error if current setting is pull-up
> + */
> + if (pullup)
> + err = -EINVAL;
> + }
> + } else {
> err = -ENOTSUPP;
> + }
> break;
> case PIN_CONFIG_SLEW_RATE:
> err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &ret);
> @@ -188,20 +198,20 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
>
> switch ((u32)param) {
> case PIN_CONFIG_BIAS_DISABLE:
> - if (hw->soc->bias_disable_set)
> - err = hw->soc->bias_disable_set(hw, desc);
> + if (hw->soc->bias_set_combo)
> + err = hw->soc->bias_set_combo(hw, desc, 0, MTK_DISABLE);
> else
> err = -ENOTSUPP;
> break;
> case PIN_CONFIG_BIAS_PULL_UP:
> - if (hw->soc->bias_set)
> - err = hw->soc->bias_set(hw, desc, 1);
> + if (hw->soc->bias_set_combo)
> + err = hw->soc->bias_set_combo(hw, desc, 1, arg);
> else
> err = -ENOTSUPP;
> break;
> case PIN_CONFIG_BIAS_PULL_DOWN:
> - if (hw->soc->bias_set)
> - err = hw->soc->bias_set(hw, desc, 0);
> + if (hw->soc->bias_set_combo)
> + err = hw->soc->bias_set_combo(hw, desc, 0, arg);
> else
> err = -ENOTSUPP;
> break;
> @@ -892,7 +902,6 @@ int mtk_paris_pinctrl_probe(struct platform_device *pdev,
> return 0;
> }
>
> -
remove the nunessary empty line
> static int mtk_paris_pinctrl_suspend(struct device *device)
> {
> struct mtk_pinctrl *pctl = dev_get_drvdata(device);
> --
> 1.8.1.1.dirty
>
^ permalink raw reply
* Re: [PATCH v1 1/5] pinctrl: mediatek: Check gpio pin number and use binary search in mtk_hw_pin_field_lookup()
From: Sean Wang @ 2019-08-13 22:54 UTC (permalink / raw)
To: Light Hsieh
Cc: Linus Walleij, moderated list:ARM/Mediatek SoC support,
open list:GPIO SUBSYSTEM, lkml
In-Reply-To: <1565686400-5711-2-git-send-email-light.hsieh@mediatek.com>
On Tue, Aug 13, 2019 at 1:53 AM Light Hsieh <light.hsieh@mediatek.com> wrote:
>
> From: Light Hsieh <light.hsieh@mediatek.com>
>
> 1. Check if gpio pin number is in valid range to prevent from get invalid
> pointer 'desc' in the following code:
> desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
>
> 2. Use binary search in mtk_hw_pin_field_lookup()
> Modify mtk_hw_pin_field_lookup() to use binary search for accelerating
> search.
>
> Change-Id: I22b4644ec216b90dd9dd5e223cc41d43761701b0
remove all of Change-Id in all the patches in the series
> ---
> drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 24 +++++++++++++++++++-----
> drivers/pinctrl/mediatek/pinctrl-paris.c | 19 +++++++++++++++++++
> 2 files changed, 38 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> index 20e1c89..4687f63 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> @@ -68,7 +68,7 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
> {
> const struct mtk_pin_field_calc *c, *e;
> const struct mtk_pin_reg_calc *rc;
> - u32 bits;
> + u32 bits, start = 0, end, found = 0, check;
variable found should be bool type, and the declaration should be
listed in reverse Xmas tree order
>
> if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) {
> rc = &hw->soc->reg_cal[field];
> @@ -79,21 +79,32 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
> return -ENOTSUPP;
> }
>
> + end = rc->nranges - 1;
> c = rc->range;
> e = c + rc->nranges;
>
> - while (c < e) {
> - if (desc->number >= c->s_pin && desc->number <= c->e_pin)
> + while (start <= end) {
> + check = (start + end) >> 1;
> + if (desc->number >= rc->range[check].s_pin
> + && desc->number <= rc->range[check].e_pin) {
> + found = 1;
found = true;
> break;
> - c++;
> + } else if (start == end)
> + break;
> + else if (desc->number < rc->range[check].s_pin)
> + end = check - 1;
> + else
> + start = check + 1;
> }
>
> - if (c >= e) {
> + if (!found) {
> dev_dbg(hw->dev, "Not support field %d for pin = %d (%s)\n",
> field, desc->number, desc->name);
> return -ENOTSUPP;
> }
>
> + c = rc->range + check;
> +
> if (c->i_base > hw->nbase - 1) {
> dev_err(hw->dev,
> "Invalid base for field %d for pin = %d (%s)\n",
> @@ -182,6 +193,9 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
> if (err)
> return err;
>
> + if (value < 0 || value > pf.mask)
> + return -EINVAL;
> +
> if (!pf.next)
> mtk_rmw(hw, pf.index, pf.offset, pf.mask << pf.bitpos,
> (value & pf.mask) << pf.bitpos);
> diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
> index 923264d..28b4951 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-paris.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
> @@ -693,6 +693,9 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, unsigned int gpio)
> const struct mtk_pin_desc *desc;
> int value, err;
>
> + if (gpio > hw->soc->npins)
> + return -EINVAL;
> +
> desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
>
> err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &value);
> @@ -708,6 +711,9 @@ static int mtk_gpio_get(struct gpio_chip *chip, unsigned int gpio)
> const struct mtk_pin_desc *desc;
> int value, err;
>
> + if (gpio > hw->soc->npins)
> + return -EINVAL;
> +
> desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
>
> err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value);
> @@ -722,6 +728,9 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value)
> struct mtk_pinctrl *hw = gpiochip_get_data(chip);
> const struct mtk_pin_desc *desc;
>
> + if (gpio > hw->soc->npins)
> + return;
> +
> desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
>
> mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, !!value);
> @@ -729,12 +738,22 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value)
>
> static int mtk_gpio_direction_input(struct gpio_chip *chip, unsigned int gpio)
> {
> + struct mtk_pinctrl *hw = gpiochip_get_data(chip);
> +
> + if (gpio > hw->soc->npins)
> + return -EINVAL;
> +
> return pinctrl_gpio_direction_input(chip->base + gpio);
> }
>
> static int mtk_gpio_direction_output(struct gpio_chip *chip, unsigned int gpio,
> int value)
> {
> + struct mtk_pinctrl *hw = gpiochip_get_data(chip);
> +
> + if (gpio > hw->soc->npins)
> + return -EINVAL;
> +
> mtk_gpio_set(chip, gpio, value);
>
> return pinctrl_gpio_direction_output(chip->base + gpio);
> --
> 1.8.1.1.dirty
>
^ permalink raw reply
* [PATCH] dt-bindings: pinctrl: stm32: Fix 'st,syscfg' schema
From: Rob Herring @ 2019-08-13 20:55 UTC (permalink / raw)
To: devicetree
Cc: Linus Walleij, Mark Rutland, Maxime Coquelin, Alexandre Torgue,
linux-gpio, linux-stm32, linux-arm-kernel
The proper way to add additional contraints to an existing json-schema
is using 'allOf' to reference the base schema. Using just '$ref' doesn't
work. Fix this for the 'st,syscfg' property.
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: Alexandre Torgue <alexandre.torgue@st.com>
Cc: linux-gpio@vger.kernel.org
Cc: linux-stm32@st-md-mailman.stormreply.com
Cc: linux-arm-kernel@lists.infradead.org
Signed-off-by: Rob Herring <robh@kernel.org>
---
I've got some other fixes queued up and can take this via the DT tree.
Rob
.../devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml
index 91d3e78b3395..400df2da018a 100644
--- a/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml
@@ -37,7 +37,8 @@ properties:
hwlocks: true
st,syscfg:
- $ref: "/schemas/types.yaml#/definitions/phandle-array"
+ allOf:
+ - $ref: "/schemas/types.yaml#/definitions/phandle-array"
description: Should be phandle/offset/mask
items:
- description: Phandle to the syscon node which includes IRQ mux selection.
--
2.20.1
^ permalink raw reply related
* Re: [PATCH v2] gpiolib: Take MUX usage into account
From: Stefan Wahren @ 2019-08-13 16:32 UTC (permalink / raw)
To: Fried, Ramon, linus.walleij, bgolaszewski; +Cc: linux-gpio, linux-kernel
In-Reply-To: <88cbb5b2-fd95-afb3-3645-e5b799844941@linux.intel.com>
Am 13.08.19 um 08:10 schrieb Fried, Ramon:
>
> On 8/13/2019 08:38, Stefan Wahren wrote:
>> Hi Ramon,
>>
>> On 13.08.19 03:42, Ramon Fried wrote:
>>> From: Stefan Wahren <stefan.wahren@i2se.com>
>>>
>>> The user space like gpioinfo only see the GPIO usage but not the
>>> MUX usage (e.g. I2C or SPI usage) of a pin. As a user we want to
>>> know which
>>> pin is free/safe to use. So take the MUX usage of strict pinmux
>>> controllers
>>> into account to get a more realistic view for ioctl
>>> GPIO_GET_LINEINFO_IOCTL.
>>>
>>> Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
>>> Tested-by: Ramon Fried <rfried.dev@gmail.com>
>>> Signed-off-by: Ramon Fried <rfried.dev@gmail.com>
>>> ---
>>> v2: Address review from linus:
>>> * ** Please notive logic was reversed **
>>> * renamed pinctrl_gpio_is_in_use() to pinctrl_gpio_can_use_line()
>>> * renamed pinmux_is_in_use() to pinmux_can_be_used_for_gpio()
>>> * changed dev_err to dev_dbg (Linus suggested removing it altogether, I
>>> find it better to keep it for debug).
>> thanks for taking care of this.
>>> drivers/gpio/gpiolib.c | 3 ++-
>>> drivers/pinctrl/core.c | 28 ++++++++++++++++++++++++++++
>>> drivers/pinctrl/pinmux.c | 27 +++++++++++++++++++++++++++
>>> drivers/pinctrl/pinmux.h | 8 ++++++++
>>> include/linux/pinctrl/consumer.h | 6 ++++++
>>> 5 files changed, 71 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
>>> index f497003f119c..52937bf8e514 100644
>>> --- a/drivers/gpio/gpiolib.c
>>> +++ b/drivers/gpio/gpiolib.c
>>> @@ -1084,7 +1084,8 @@ static long gpio_ioctl(struct file *filp,
>>> unsigned int cmd, unsigned long arg)
>>> test_bit(FLAG_IS_HOGGED, &desc->flags) ||
>>> test_bit(FLAG_USED_AS_IRQ, &desc->flags) ||
>>> test_bit(FLAG_EXPORT, &desc->flags) ||
>>> - test_bit(FLAG_SYSFS, &desc->flags))
>>> + test_bit(FLAG_SYSFS, &desc->flags) ||
>>> + !pinctrl_gpio_can_use_line(chip->base +
>>> lineinfo.line_offset))
>>> lineinfo.flags |= GPIOLINE_FLAG_KERNEL;
>>> if (test_bit(FLAG_IS_OUT, &desc->flags))
>>> lineinfo.flags |= GPIOLINE_FLAG_IS_OUT;
>>> diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
>>> index b70df27874d1..2bbd8ee93507 100644
>>> --- a/drivers/pinctrl/core.c
>>> +++ b/drivers/pinctrl/core.c
>>> @@ -736,6 +736,34 @@ int pinctrl_get_group_selector(struct
>>> pinctrl_dev *pctldev,
>>> return -EINVAL;
>>> }
>>> +bool pinctrl_gpio_can_use_line(unsigned gpio)
>>> +{
>>> + struct pinctrl_dev *pctldev;
>>> + struct pinctrl_gpio_range *range;
>>> + bool result;
>>> + int pin;
>>> +
>>> + /*
>>> + * Try to obtain GPIO range, if it fails
>>> + * we're probably dealing with GPIO driver
>>> + * without a backing pin controller - bail out.
>>> + */
>>> + if (pinctrl_get_device_gpio_range(gpio, &pctldev, &range))
>>> + return true;
>>> +
>>> + mutex_lock(&pctldev->mutex);
>>> +
>>> + /* Convert to the pin controllers number space */
>>> + pin = gpio_to_pin(range, gpio);
>>> +
>>> + result = pinmux_can_be_used_for_gpio(pctldev, pin);
>>> +
>>> + mutex_unlock(&pctldev->mutex);
>>> +
>>> + return result;
>>> +}
>>> +EXPORT_SYMBOL_GPL(pinctrl_gpio_can_use_line);
>>> +
>>> /**
>>> * pinctrl_gpio_request() - request a single pin to be used as GPIO
>>> * @gpio: the GPIO pin number from the GPIO subsystem number space
>>> diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
>>> index 020e54f843f9..7e42a5738d82 100644
>>> --- a/drivers/pinctrl/pinmux.c
>>> +++ b/drivers/pinctrl/pinmux.c
>>> @@ -70,6 +70,33 @@ int pinmux_validate_map(const struct pinctrl_map
>>> *map, int i)
>>> return 0;
>>> }
>>> +/**
>>> + * pinmux_can_be_used_for_gpio() - check if a specific pin
>>> + * is either muxed to a different function or used as gpio.
>>> + *
>>> + * @pin: the pin number in the global pin space
>>> + *
>>> + * Controllers not defined as strict will always return true,
>>> + * menaning that the gpio can be used.
>>> + */
>>> +bool pinmux_can_be_used_for_gpio(struct pinctrl_dev *pctldev,
>>> unsigned pin)
>>> +{
>>> + struct pin_desc *desc = pin_desc_get(pctldev, pin);
>>> + const struct pinmux_ops *ops = pctldev->desc->pmxops;
>>> +
>>> + if (!desc) {
>>> + dev_dbg(pctldev->dev,
>>> + "pin %u is not registered so it cannot be requested\n",
>>> + pin);
>>> + return true;
>> This return value looks strange to me.
>
> Basically, it's just the reversed return value you returned in the
> original patch,
> It means in this context that if the pin is not owned by a
> pin-controller it can be used for GPIO.
As long as the provided pin is valid. Btw shouldn't we change the logic
in the debug message?
>
> Thanks,
> Ramon.
>
>>
>> Stefan
>>
^ permalink raw reply
* Re: Intel GPIO / pin control repositories for next
From: Stephen Rothwell @ 2019-08-13 14:20 UTC (permalink / raw)
To: Andy Shevchenko; +Cc: linux-gpio, Linus Walleij, Mika Westerberg
In-Reply-To: <20190813140403.GB30120@smile.fi.intel.com>
[-- Attachment #1: Type: text/plain, Size: 1501 bytes --]
Hi Andy,
On Tue, 13 Aug 2019 17:04:03 +0300 Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote:
>
> Can you, please, include the following repositories for your linux-next bunch
> for getting better coverage?
>
> gpio-intel-fixes git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-gpio-intel.git#fixes
> gpio-intel git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-gpio-intel.git#for-next
>
> pinctrl-intel-fixes git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel.git#fixes
> pinctrl-intel git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel.git#for-next
Added from (later) today.
Thanks for adding your subsystem tree as a participant of linux-next. As
you may know, this is not a judgement of your code. The purpose of
linux-next is for integration testing and to lower the impact of
conflicts between subsystems in the next merge window.
You will need to ensure that the patches/commits in your tree/series have
been:
* submitted under GPL v2 (or later) and include the Contributor's
Signed-off-by,
* posted to the relevant mailing list,
* reviewed by you (or another maintainer of your subsystem tree),
* successfully unit tested, and
* destined for the current or next Linux merge window.
Basically, this should be just what you would send to Linus (or ask him
to fetch). It is allowed to be rebased if you deem it necessary.
--
Cheers,
Stephen Rothwell
sfr@canb.auug.org.au
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Intel GPIO / pin control repositories for next
From: Andy Shevchenko @ 2019-08-13 14:04 UTC (permalink / raw)
To: linux-gpio, Stephen Rothwell; +Cc: Linus Walleij, Mika Westerberg
Hi, Stephen!
Can you, please, include the following repositories for your linux-next bunch
for getting better coverage?
gpio-intel-fixes git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-gpio-intel.git#fixes
gpio-intel git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-gpio-intel.git#for-next
pinctrl-intel-fixes git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel.git#fixes
pinctrl-intel git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel.git#for-next
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Intel GPIO / pin control repositories for next
From: Andy Shevchenko @ 2019-08-13 13:50 UTC (permalink / raw)
To: linux-gpio; +Cc: Linus Walleij, Mika Westerberg
Hi, Stephen!
Can you, please, include the following repositories for your linux-next bunch
for getting better coverage?
gpio-intel-fixes git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-gpio-intel.git#fixes
gpio-intel git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-gpio-intel.git#for-next
pinctrl-intel-fixes git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel.git#fixes
pinctrl-intel git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel.git#for-next
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH 2/2] serial: mctrl_gpio: Support all GPIO suffixes (gpios vs gpio)
From: Andy Shevchenko @ 2019-08-13 12:15 UTC (permalink / raw)
To: Pavel Machek
Cc: Stefan Roese, linux-serial, linux-gpio, Geert Uytterhoeven,
Linus Walleij, Greg Kroah-Hartman
In-Reply-To: <20190813114258.GA11559@amd>
On Tue, Aug 13, 2019 at 01:42:58PM +0200, Pavel Machek wrote:
> On Mon 2019-08-12 13:53:07, Andy Shevchenko wrote:
> > On Thu, Aug 08, 2019 at 03:59:36PM +0200, Stefan Roese wrote:
> > > On 08.08.19 15:48, Andy Shevchenko wrote:
> > > > On Thu, Aug 08, 2019 at 03:25:43PM +0200, Stefan Roese wrote:
> > I tried hard to find an evidence of this in Linux kernel, I assume that comes
> > from DT compiler or something, but fail. Linux kernel OF properties handling is
> > written in the assumption of arbitrary length of the property name.
> >
> > It might be that my hard was not hard at all and I missed something.
> >
> > > > Or maybe we can still continue using kasprintf() approach?
> > >
> > > Frankly, I was feeling a bit uncomfortable with this memory allocation
> > > in a loop. And Pavel also commented on this:
> > >
> > > https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg2066286.html
> >
> > If memory allocator fails, it's a big issue, and what will happen next probably
> > much less important.
>
> Not... really. With "too big" allocations, it will fail.
Yeah, or with relatively small if memory is too much fragmented.
But we are talking about really small allocations here in most cases, right?
> Anyway, my point is that allocating in a loop for this is slow and
> ugly. If we don't have a maximum property length, we should probably
> invent some. I mean, we can agree that 64KB property name is not okay,
> right?
My point that is should be declared on the level of property API.
Restricting it on the level of one, 'client' to that API, framework is not
a solution.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH 2/2] serial: mctrl_gpio: Support all GPIO suffixes (gpios vs gpio)
From: Pavel Machek @ 2019-08-13 11:42 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Stefan Roese, linux-serial, linux-gpio, Geert Uytterhoeven,
Pavel Machek, Linus Walleij, Greg Kroah-Hartman
In-Reply-To: <20190812105307.GA30120@smile.fi.intel.com>
[-- Attachment #1: Type: text/plain, Size: 2546 bytes --]
On Mon 2019-08-12 13:53:07, Andy Shevchenko wrote:
> On Thu, Aug 08, 2019 at 03:59:36PM +0200, Stefan Roese wrote:
> > On 08.08.19 15:48, Andy Shevchenko wrote:
> > > On Thu, Aug 08, 2019 at 03:25:43PM +0200, Stefan Roese wrote:
> > > > This patch fixes a backward compatibility issue, when boards use the
> > > > old style GPIO suffix "-gpio" instead of the new "-gpios". This
> > > > potential problem has been introduced by commit d99482673f95 ("serial:
> > > > mctrl_gpio: Check if GPIO property exisits before requesting it").
> > > >
> > > > This patch now fixes this issue by iterating over all supported GPIO
> > > > suffixes by using the newly introduced for_each_gpio_suffix() helper.
> > > >
> > > > Also, the string buffer is now allocated on the stack to avoid the
> > > > problem of allocation in a loop and its potential failure.
> > >
> > > > for (i = 0; i < UART_GPIO_MAX; i++) {
> > > > enum gpiod_flags flags;
> > > > - char *gpio_str;
> > > > + const char *suffix;
> > > > + char gpio_str[32]; /* 32 is max size of property name */
> > >
> > > Hmm... don't we have some define for the maximum length of property?
> >
> > I've come up with this assumption from this code (identical comment):
> >
> > https://elixir.bootlin.com/linux/latest/source/drivers/gpio/gpiolib-of.c#L293
> >
> > (and other places in drivers/gpio/*)
>
> I tried hard to find an evidence of this in Linux kernel, I assume that comes
> from DT compiler or something, but fail. Linux kernel OF properties handling is
> written in the assumption of arbitrary length of the property name.
>
> It might be that my hard was not hard at all and I missed something.
>
> > > Or maybe we can still continue using kasprintf() approach?
> >
> > Frankly, I was feeling a bit uncomfortable with this memory allocation
> > in a loop. And Pavel also commented on this:
> >
> > https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg2066286.html
>
> If memory allocator fails, it's a big issue, and what will happen next probably
> much less important.
Not... really. With "too big" allocations, it will fail.
Anyway, my point is that allocating in a loop for this is slow and
ugly. If we don't have a maximum property length, we should probably
invent some. I mean, we can agree that 64KB property name is not okay,
right?
Pavel
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]
^ permalink raw reply
* Re: [PATCH v4] spi: bcm2835: Convert to use CS GPIO descriptors
From: Stefan Wahren @ 2019-08-13 9:36 UTC (permalink / raw)
To: Linus Walleij, Mark Brown, linux-spi
Cc: linux-gpio, Bartosz Golaszewski, Lukas Wunner, Martin Sperl,
Chris Boot
In-Reply-To: <20190804003852.1312-1-linus.walleij@linaro.org>
Hi Linus,
On 04.08.19 02:38, Linus Walleij wrote:
> This converts the BCM2835 SPI master driver to use GPIO
> descriptors for chip select handling.
>
> The BCM2835 driver was relying on the core to drive the
> CS high/low so very small changes were needed for this
> part. If it managed to request the CS from the device tree
> node, all is pretty straight forward.
>
> However for native GPIOs this driver has a quite unorthodox
> loopback to request some GPIOs from the SoC GPIO chip by
> looking it up from the device tree using gpiochip_find()
> and then offseting hard into its numberspace. This has
> been augmented a bit by using gpiochip_request_own_desc()
> but this code really needs to be verified. If "native CS"
> is actually an SoC GPIO, why is it even done this way?
> Should this GPIO not just be defined in the device tree
> like any other CS GPIO? I'm confused.
>
> Cc: Lukas Wunner <lukas@wunner.de>
> Cc: Stefan Wahren <stefan.wahren@i2se.com>
> Cc: Martin Sperl <kernel@martin.sperl.org>
> Cc: Chris Boot <bootc@bootc.net>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> ChangeLog v3->v4:
> - Fix the offset of the chipselect line to be 8 - CS
> as in the original code.
> - Use the modified gpiochip_request_own_desc() to set up
> line inversion semantics if need be. Look at the OF
> node of the SPI device for flags.
> ChangeLog v2->v3:
> - Fix unused variable "err" compile-time message.
> ChangeLog RFT->v2:
> - Rebased on v5.1-rc1
>
> I would very much appreciate if someone took this for
> a ride on top of linux-next (there are some fixes in
> the -rcs you need) and see if all still works as expected.
sorry for my late reply, but i was on vacation.
Thanks for your efforts on this, but currently i don't have a setup to
test this :-(
^ permalink raw reply
* [PATCH v1 2/5] pinctrl: mediatek: Supporting driving setting without mapping current to register value
From: Light Hsieh @ 2019-08-13 8:53 UTC (permalink / raw)
To: linus.walleij
Cc: linux-mediatek, linux-gpio, linux-kernel, sean.wang, Light Hsieh
In-Reply-To: <1565686400-5711-1-git-send-email-light.hsieh@mediatek.com>
From: Light Hsieh <light.hsieh@mediatek.com>
Mediatek's smarphone project actual usage does need to know current value
(in mA) in procedure of finding the best driving setting.
The steps in the procedure is like as follow:
1. set driving setting field in setting register as 0, measure waveform,
perform test, and etc.
2. set driving setting field in setting register as 1, measure waveform,
perform test, and etc.
...
n. set driving setting field in setting register as n-1, measure
waveform, perform test, and etc.
Check the results of steps 1~n and adopt the setting that get best result.
This procedure does need to know the mapping between current to register
value.
Therefore, setting driving without mapping current is more pratical for
Mediatek's smartphone usage.
Change-Id: Iacdabf0cada230fc5acad96673810c12a6c4556d
---
drivers/pinctrl/mediatek/pinctrl-mt6765.c | 4 ++--
drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 21 +++++++++++++++++++++
drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h | 5 +++++
drivers/pinctrl/mediatek/pinctrl-paris.c | 1 +
4 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
index 32451e8..e024ebc 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
@@ -1077,8 +1077,8 @@
.bias_disable_get = mtk_pinconf_bias_disable_get,
.bias_set = mtk_pinconf_bias_set,
.bias_get = mtk_pinconf_bias_get,
- .drive_set = mtk_pinconf_drive_set_rev1,
- .drive_get = mtk_pinconf_drive_get_rev1,
+ .drive_set = mtk_pinconf_drive_set_direct_val,
+ .drive_get = mtk_pinconf_drive_get_direct_val,
.adv_pull_get = mtk_pinconf_adv_pull_get,
.adv_pull_set = mtk_pinconf_adv_pull_set,
};
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index 4687f63..23a9529 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -607,6 +607,27 @@ int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
return 0;
}
+/* Revision direct value */
+int mtk_pinconf_drive_set_direct_val(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc, u32 arg)
+{
+ int err;
+
+ err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV, arg);
+
+ return err;
+}
+
+int mtk_pinconf_drive_get_direct_val(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc, int *val)
+{
+ int err;
+
+ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, val);
+
+ return err;
+}
+
int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, bool pullup,
u32 arg)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
index 1b7da42..b3bada0 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
@@ -288,6 +288,11 @@ int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl *hw,
int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, int *val);
+int mtk_pinconf_drive_set_direct_val(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc, u32 arg);
+int mtk_pinconf_drive_get_direct_val(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc, int *val);
+
int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, bool pullup,
u32 arg);
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 28b4951..71c94b2 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -964,3 +964,4 @@ static int mtk_paris_pinctrl_resume(struct device *device)
.suspend_noirq = mtk_paris_pinctrl_suspend,
.resume_noirq = mtk_paris_pinctrl_resume,
};
+
--
1.8.1.1.dirty
^ permalink raw reply related
* [PATCH v1 5/5] pinctrl: mediatek: Add support for pin configuration dump via sysfs.
From: Light Hsieh @ 2019-08-13 8:53 UTC (permalink / raw)
To: linus.walleij
Cc: linux-mediatek, linux-gpio, linux-kernel, sean.wang, Light Hsieh
In-Reply-To: <1565686400-5711-1-git-send-email-light.hsieh@mediatek.com>
From: Light Hsieh <light.hsieh@mediatek.com>
Add support for pin configuration dump via catting
/sys/kernel/debug/pinctrl/$platform_dependent_path/pinconf-pins.
pinctrl framework had already support such dump. This patch implement the
operation function pointer to fullfill this dump.
Change-Id: Ib59212eb47febcd84140cbf84e1bd7286769beb0
---
drivers/pinctrl/mediatek/pinctrl-paris.c | 88 ++++++++++++++++++++++++++++++++
drivers/pinctrl/mediatek/pinctrl-paris.h | 30 +++++++++++
2 files changed, 118 insertions(+)
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 0a9440a..91d6e72 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -531,12 +531,99 @@ static int mtk_pctrl_get_group_pins(struct pinctrl_dev *pctldev,
return 0;
}
+int mtk_hw_get_value_wrap(struct mtk_pinctrl *hw, unsigned int gpio, int field)
+{
+ const struct mtk_pin_desc *desc;
+ int value, err;
+
+ if (gpio > hw->soc->npins)
+ return -EINVAL;
+
+ desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
+
+ err = mtk_hw_get_value(hw, desc, field, &value);
+ if (err)
+ return err;
+
+ return value;
+}
+
+ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw,
+ unsigned int gpio, char *buf, unsigned int bufLen)
+{
+ const struct mtk_pin_desc *desc;
+ int pinmux, pullup, pullen, r1 = -1, r0 = -1, len = 0;
+
+ if (gpio > hw->soc->npins)
+ return -EINVAL;
+
+ desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
+ pinmux = mtk_pctrl_get_pinmux(hw, gpio);
+ if (pinmux >= hw->soc->nfuncs)
+ pinmux -= hw->soc->nfuncs;
+
+ mtk_pinconf_bias_get_combo(hw, desc, &pullup, &pullen);
+ if (pullen == MTK_PUPD_SET_R1R0_00) {
+ pullen = 0;
+ r1 = 0;
+ r0 = 0;
+ } else if (pullen == MTK_PUPD_SET_R1R0_01) {
+ pullen = 1;
+ r1 = 0;
+ r0 = 1;
+ } else if (pullen == MTK_PUPD_SET_R1R0_10) {
+ pullen = 1;
+ r1 = 1;
+ r0 = 0;
+ } else if (pullen == MTK_PUPD_SET_R1R0_11) {
+ pullen = 1;
+ r1 = 1;
+ r0 = 1;
+ } else if (pullen != MTK_DISABLE && pullen != MTK_ENABLE) {
+ pullen = 0;
+ }
+ len += snprintf(buf + len, bufLen - len,
+ "%03d: %1d%1d%1d%1d%02d%1d%1d%1d%1d",
+ gpio,
+ pinmux,
+ mtk_pctrl_get_direction(hw, gpio),
+ mtk_pctrl_get_out(hw, gpio),
+ mtk_pctrl_get_in(hw, gpio),
+ mtk_pctrl_get_driving(hw, gpio),
+ mtk_pctrl_get_smt(hw, gpio),
+ mtk_pctrl_get_ies(hw, gpio),
+ pullen,
+ pullup);
+
+ if (r1 != -1) {
+ len += snprintf(buf + len, bufLen - len, " (%1d %1d)\n",
+ r1, r0);
+ } else {
+ len += snprintf(buf + len, bufLen - len, "\n");
+ }
+
+ return len;
+}
+
+#define PIN_DBG_BUF_SZ 96
+static void mtk_pctrl_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
+ unsigned int gpio)
+{
+ struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
+ char buf[PIN_DBG_BUF_SZ];
+
+ (void)mtk_pctrl_show_one_pin(hw, gpio, buf, PIN_DBG_BUF_SZ);
+
+ seq_printf(s, "%s", buf);
+}
+
static const struct pinctrl_ops mtk_pctlops = {
.dt_node_to_map = mtk_pctrl_dt_node_to_map,
.dt_free_map = pinctrl_utils_free_map,
.get_groups_count = mtk_pctrl_get_groups_count,
.get_group_name = mtk_pctrl_get_group_name,
.get_group_pins = mtk_pctrl_get_group_pins,
+ .pin_dbg_show = mtk_pctrl_dbg_show,
};
static int mtk_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev)
@@ -633,6 +720,7 @@ static int mtk_pconf_group_set(struct pinctrl_dev *pctldev, unsigned group,
.pin_config_get = mtk_pinconf_get,
.pin_config_group_get = mtk_pconf_group_get,
.pin_config_group_set = mtk_pconf_group_set,
+ .is_generic = true,
};
static struct pinctrl_desc mtk_desc = {
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.h b/drivers/pinctrl/mediatek/pinctrl-paris.h
index 3d43771..d73f4b6 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.h
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.h
@@ -60,6 +60,36 @@
int mtk_paris_pinctrl_probe(struct platform_device *pdev,
const struct mtk_pin_soc *soc);
+int mtk_hw_get_value_wrap(struct mtk_pinctrl *hw, unsigned int gpio, int field);
+
+#define mtk_pctrl_get_pinmux(hw, gpio) \
+ mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_MODE)
+
+/* MTK HW use 0 as input, 1 for output
+ * This interface is for get direct register value,
+ * so don't reverse
+ */
+#define mtk_pctrl_get_direction(hw, gpio) \
+ mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_DIR)
+
+#define mtk_pctrl_get_out(hw, gpio) \
+ mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_DO)
+
+#define mtk_pctrl_get_in(hw, gpio) \
+ mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_DI)
+
+#define mtk_pctrl_get_smt(hw, gpio) \
+ mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_SMT)
+
+#define mtk_pctrl_get_ies(hw, gpio) \
+ mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_IES)
+
+#define mtk_pctrl_get_driving(hw, gpio) \
+ mtk_hw_get_value_wrap(hw, gpio, PINCTRL_PIN_REG_DRV)
+
+ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw,
+ unsigned int gpio, char *buf, unsigned int bufLen);
+
extern const struct dev_pm_ops mtk_paris_pinctrl_pm_ops;
#endif /* __PINCTRL_PARIS_H */
--
1.8.1.1.dirty
^ permalink raw reply related
* [PATCH v1 4/5] pinctrl: mediatek: Backward compatible to previous Mediatek's bias-pull usage
From: Light Hsieh @ 2019-08-13 8:53 UTC (permalink / raw)
To: linus.walleij
Cc: linux-mediatek, linux-gpio, linux-kernel, sean.wang, Light Hsieh
In-Reply-To: <1565686400-5711-1-git-send-email-light.hsieh@mediatek.com>
From: Light Hsieh <light.hsieh@mediatek.com>
Refine mtk_pinconf_set()/mtk_pinconf_get() for backward compatibility to
previous Mediatek's bias-pull usage.
In PINCTRL_MTK that use pinctrl-mtk-common.c, bias-pull setting for pins
with 2 pull resistors can be specified as value for bias-pull-up and
bias-pull-down. For example:
bias-pull-up = <MTK_PUPD_SET_R1R0_00>;
bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
bias-pull-up = <MTK_PUPD_SET_R1R0_11>;
bias-pull-down = <MTK_PUPD_SET_R1R0_00>;
bias-pull-down = <MTK_PUPD_SET_R1R0_01>;
bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
bias-pull-down = <MTK_PUPD_SET_R1R0_11>;
On the other hand, PINCTRL_MTK_PARIS use customized properties
"mediatek,pull-up-adv" and "mediatek,pull-down-adv" to specify bias-pull
setting for pins with 2 pull resistors.
This introduce in-compatibility in device tree and increatse porting
effort to Mediatek's customer that had already used PINCTRL_MTK version.
Besides, if customers are not awared of this change and still write devicetree
for PINCTRL_MTK version, they may encounter runtime failure with pinctrl and
spent time to debug.
This patch add backward compatible to previous Mediatek's bias-pull usage
so that Mediatek's customer need not use a new devicetree property name.
The rationale is that: changing driver implemenation had better leave
interface unchanged.
Change-Id: I8ea8f09278acc492ba04771826eaadb70224cd51
---
drivers/pinctrl/mediatek/pinctrl-mt6765.c | 4 +-
drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 285 +++++++++++++++++++++++
drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h | 11 +
drivers/pinctrl/mediatek/pinctrl-paris.c | 49 ++--
4 files changed, 327 insertions(+), 22 deletions(-)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
index bada37f..315aebd 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
@@ -1074,8 +1074,8 @@
.nbase_names = ARRAY_SIZE(mt6765_pinctrl_register_base_names),
.bias_disable_set = mtk_pinconf_bias_disable_set,
.bias_disable_get = mtk_pinconf_bias_disable_get,
- .bias_set = mtk_pinconf_bias_set,
- .bias_get = mtk_pinconf_bias_get,
+ .bias_set = mtk_pinconf_bias_set_combo,
+ .bias_get = mtk_pinconf_bias_get_combo,
.drive_set = mtk_pinconf_drive_set_direct_val,
.drive_get = mtk_pinconf_drive_get_direct_val,
.adv_pull_get = mtk_pinconf_adv_pull_get,
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index 23a9529..dab8418 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -13,6 +13,8 @@
#include <linux/io.h>
#include <linux/of_irq.h>
+#include <dt-bindings/pinctrl/mt65xx.h>
+
#include "mtk-eint.h"
#include "pinctrl-mtk-common-v2.h"
@@ -205,6 +207,20 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
return 0;
}
+void mtk_hw_set_value_no_lookup(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc,
+ int value, struct mtk_pin_field *pf)
+{
+ if (value < 0 || value > pf->mask)
+ return;
+
+ if (!pf->next)
+ mtk_rmw(hw, pf->index, pf->offset, pf->mask << pf->bitpos,
+ (value & pf->mask) << pf->bitpos);
+ else
+ mtk_hw_write_cross_field(hw, pf, value);
+}
+
int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
int field, int *value)
{
@@ -224,6 +240,17 @@ int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
return 0;
}
+void mtk_hw_get_value_no_lookup(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc,
+ int *value, struct mtk_pin_field *pf)
+{
+ if (!pf->next)
+ *value = (mtk_r32(hw, pf->index, pf->offset)
+ >> pf->bitpos) & pf->mask;
+ else
+ mtk_hw_read_cross_field(hw, pf, value);
+}
+
static int mtk_xt_find_eint_num(struct mtk_pinctrl *hw, unsigned long eint_n)
{
const struct mtk_pin_desc *desc;
@@ -516,6 +543,264 @@ int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
return 0;
}
+/* Combo for the following pull register type:
+ * 1. PU + PD
+ * 2. PULLSEL + PULLEN
+ * 3. PUPD + R0 + R1
+ */
+int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc,
+ u32 pullup, u32 arg)
+{
+ struct mtk_pin_field pf;
+ int err = -EINVAL;
+ int pu, pd;
+
+ err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PU, &pf);
+ if (err)
+ goto out;
+
+ if (arg == MTK_DISABLE) {
+ pu = 0;
+ pd = 0;
+ } else if ((arg == MTK_ENABLE) && pullup) {
+ pu = 1;
+ pd = 0;
+ } else if ((arg == MTK_ENABLE) && !pullup) {
+ pu = 0;
+ pd = 1;
+ } else {
+ goto out;
+ }
+
+ mtk_hw_set_value_no_lookup(hw, desc, pu, &pf);
+
+ err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PD, &pf);
+ if (err)
+ goto out;
+
+ mtk_hw_set_value_no_lookup(hw, desc, pd, &pf);
+
+out:
+ return err;
+}
+
+int mtk_pinconf_bias_set_pullsel_pullen(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc,
+ u32 pullup, u32 arg)
+{
+ struct mtk_pin_field pf;
+ int err = -EINVAL, enable;
+
+ err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PULLEN, &pf);
+ if (err)
+ goto out;
+
+ if (arg == MTK_DISABLE)
+ enable = 0;
+ else if (arg == MTK_ENABLE)
+ enable = 1;
+ else
+ goto out;
+
+ mtk_hw_set_value_no_lookup(hw, desc, enable, &pf);
+
+ err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PULLSEL, &pf);
+ if (err)
+ goto out;
+ mtk_hw_set_value_no_lookup(hw, desc, pullup, &pf);
+
+out:
+ return err;
+}
+
+int mtk_pinconf_bias_set_pupd_r1_r0(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc,
+ u32 pullup, u32 arg)
+{
+ struct mtk_pin_field pf;
+ int err = -EINVAL;
+ int r0, r1;
+
+ err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PUPD, &pf);
+ if (err)
+ goto out;
+
+ if ((arg == MTK_DISABLE) || (arg == MTK_PUPD_SET_R1R0_00)) {
+ pullup = 0;
+ r0 = 0;
+ r1 = 0;
+ } else if (arg == MTK_PUPD_SET_R1R0_01) {
+ r0 = 1;
+ r1 = 0;
+ } else if (arg == MTK_PUPD_SET_R1R0_10) {
+ r0 = 0;
+ r1 = 1;
+ } else if (arg == MTK_PUPD_SET_R1R0_11) {
+ r0 = 1;
+ r1 = 1;
+ } else
+ goto out;
+
+ /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
+ mtk_hw_set_value_no_lookup(hw, desc, !pullup, &pf);
+
+ err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_R0, &pf);
+ if (err)
+ goto out;
+ mtk_hw_set_value_no_lookup(hw, desc, r0, &pf);
+
+ err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_R1, &pf);
+ if (err)
+ goto out;
+ mtk_hw_set_value_no_lookup(hw, desc, r1, &pf);
+
+out:
+ return err;
+}
+
+int mtk_pinconf_bias_get_pu_pd(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc,
+ u32 *pullup, u32 *enable)
+{
+ struct mtk_pin_field pf;
+ int err = -EINVAL;
+ int pu, pd;
+
+ err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PU, &pf);
+ if (err)
+ goto out;
+
+ mtk_hw_get_value_no_lookup(hw, desc, &pu, &pf);
+
+ err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PD, &pf);
+ if (err)
+ goto out;
+
+ mtk_hw_get_value_no_lookup(hw, desc, &pd, &pf);
+
+ if (pu == 0 && pd == 0) {
+ *pullup = 0;
+ *enable = MTK_DISABLE;
+ } else if (pu == 1 && pd == 0) {
+ *pullup = 1;
+ *enable = MTK_ENABLE;
+ } else if (pu == 0 && pd == 1) {
+ *pullup = 0;
+ *enable = MTK_ENABLE;
+ } else {
+ err = -EINVAL;
+ goto out;
+ }
+
+out:
+ return err;
+}
+
+int mtk_pinconf_bias_get_pullsel_pullen(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc,
+ u32 *pullup, u32 *enable)
+{
+ struct mtk_pin_field pf;
+ int err = -EINVAL;
+
+ err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PULLSEL, &pf);
+ if (err)
+ goto out;
+
+ mtk_hw_get_value_no_lookup(hw, desc, pullup, &pf);
+
+ err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PULLEN, &pf);
+ if (err)
+ goto out;
+
+ mtk_hw_get_value_no_lookup(hw, desc, enable, &pf);
+
+out:
+ return err;
+}
+
+int mtk_pinconf_bias_get_pupd_r1_r0(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc,
+ u32 *pullup, u32 *enable)
+{
+ struct mtk_pin_field pf;
+ int err = -EINVAL;
+ int r0, r1;
+
+ err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_PUPD, &pf);
+ if (err)
+ goto out;
+
+ /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */
+ mtk_hw_get_value_no_lookup(hw, desc, pullup, &pf);
+ *pullup = !(*pullup);
+
+ err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_R0, &pf);
+ if (err)
+ goto out;
+ mtk_hw_get_value_no_lookup(hw, desc, &r0, &pf);
+
+ err = mtk_hw_pin_field_lookup(hw, desc, PINCTRL_PIN_REG_R1, &pf);
+ if (err)
+ goto out;
+ mtk_hw_get_value_no_lookup(hw, desc, &r1, &pf);
+
+ if ((r1 == 0) && (r0 == 0))
+ *enable = MTK_PUPD_SET_R1R0_00;
+ else if ((r1 == 0) && (r0 == 1))
+ *enable = MTK_PUPD_SET_R1R0_01;
+ else if ((r1 == 1) && (r0 == 0))
+ *enable = MTK_PUPD_SET_R1R0_10;
+ else if ((r1 == 1) && (r0 == 1))
+ *enable = MTK_PUPD_SET_R1R0_11;
+ else
+ goto out;
+
+out:
+ return err;
+}
+
+int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc,
+ u32 pullup, u32 arg)
+{
+ int err;
+
+ err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg);
+ if (!err)
+ goto out;
+
+ err = mtk_pinconf_bias_set_pullsel_pullen(hw, desc, pullup, arg);
+ if (!err)
+ goto out;
+
+ err = mtk_pinconf_bias_set_pupd_r1_r0(hw, desc, pullup, arg);
+
+out:
+ return err;
+}
+
+int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc,
+ u32 *pullup, u32 *enable)
+{
+ int err;
+
+ err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable);
+ if (!err)
+ goto out;
+
+ err = mtk_pinconf_bias_get_pullsel_pullen(hw, desc, pullup, enable);
+ if (!err)
+ goto out;
+
+ err = mtk_pinconf_bias_get_pupd_r1_r0(hw, desc, pullup, enable);
+
+out:
+ return err;
+}
+
/* Revision 0 */
int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, u32 arg)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
index b3bada0..a13dcae 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
@@ -216,6 +216,11 @@ struct mtk_pin_soc {
int (*bias_get)(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, bool pullup, int *res);
+ int (*bias_set_combo)(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc, u32 pullup, u32 arg);
+ int (*bias_get_combo)(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc, u32 *pullup, u32 *arg);
+
int (*drive_set)(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, u32 arg);
int (*drive_get)(struct mtk_pinctrl *hw,
@@ -277,6 +282,12 @@ int mtk_pinconf_bias_set_rev1(struct mtk_pinctrl *hw,
int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, bool pullup,
int *res);
+int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc,
+ u32 pullup, u32 enable);
+int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw,
+ const struct mtk_pin_desc *desc,
+ u32 *pullup, u32 *enable);
int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
const struct mtk_pin_desc *desc, u32 arg);
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
index bbe3f8a..0a9440a 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -79,28 +79,38 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
u32 param = pinconf_to_config_param(*config);
int err, reg, ret = 1;
+ int pullup;
const struct mtk_pin_desc *desc;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
- if (hw->soc->bias_disable_get)
- err = hw->soc->bias_disable_get(hw, desc, &ret);
- else
- err = -ENOTSUPP;
- break;
case PIN_CONFIG_BIAS_PULL_UP:
- if (hw->soc->bias_get)
- err = hw->soc->bias_get(hw, desc, 1, &ret);
- else
- err = -ENOTSUPP;
- break;
case PIN_CONFIG_BIAS_PULL_DOWN:
- if (hw->soc->bias_get)
- err = hw->soc->bias_get(hw, desc, 0, &ret);
- else
+ if (hw->soc->bias_get_combo) {
+ err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret);
+ if (err)
+ goto out;
+ if (param == PIN_CONFIG_BIAS_DISABLE) {
+ if (ret == MTK_PUPD_SET_R1R0_00)
+ ret = MTK_DISABLE;
+ } else if (param == PIN_CONFIG_BIAS_PULL_UP) {
+ /* When desire to get pull-up value,
+ * return error if current setting is pull-down
+ */
+ if (!pullup)
+ err = -EINVAL;
+ } else if (param == PIN_CONFIG_BIAS_PULL_DOWN) {
+ /* When desire to get pull-down value,
+ * return error if current setting is pull-up
+ */
+ if (pullup)
+ err = -EINVAL;
+ }
+ } else {
err = -ENOTSUPP;
+ }
break;
case PIN_CONFIG_SLEW_RATE:
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &ret);
@@ -188,20 +198,20 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
switch ((u32)param) {
case PIN_CONFIG_BIAS_DISABLE:
- if (hw->soc->bias_disable_set)
- err = hw->soc->bias_disable_set(hw, desc);
+ if (hw->soc->bias_set_combo)
+ err = hw->soc->bias_set_combo(hw, desc, 0, MTK_DISABLE);
else
err = -ENOTSUPP;
break;
case PIN_CONFIG_BIAS_PULL_UP:
- if (hw->soc->bias_set)
- err = hw->soc->bias_set(hw, desc, 1);
+ if (hw->soc->bias_set_combo)
+ err = hw->soc->bias_set_combo(hw, desc, 1, arg);
else
err = -ENOTSUPP;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
- if (hw->soc->bias_set)
- err = hw->soc->bias_set(hw, desc, 0);
+ if (hw->soc->bias_set_combo)
+ err = hw->soc->bias_set_combo(hw, desc, 0, arg);
else
err = -ENOTSUPP;
break;
@@ -892,7 +902,6 @@ int mtk_paris_pinctrl_probe(struct platform_device *pdev,
return 0;
}
-
static int mtk_paris_pinctrl_suspend(struct device *device)
{
struct mtk_pinctrl *pctl = dev_get_drvdata(device);
--
1.8.1.1.dirty
^ permalink raw reply related
* [PATCH v1 1/5] pinctrl: mediatek: Check gpio pin number and use binary search in mtk_hw_pin_field_lookup()
From: Light Hsieh @ 2019-08-13 8:53 UTC (permalink / raw)
To: linus.walleij
Cc: linux-mediatek, linux-gpio, linux-kernel, sean.wang, Light Hsieh
In-Reply-To: <1565686400-5711-1-git-send-email-light.hsieh@mediatek.com>
From: Light Hsieh <light.hsieh@mediatek.com>
1. Check if gpio pin number is in valid range to prevent from get invalid
pointer 'desc' in the following code:
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
2. Use binary search in mtk_hw_pin_field_lookup()
Modify mtk_hw_pin_field_lookup() to use binary search for accelerating
search.
Change-Id: I22b4644ec216b90dd9dd5e223cc41d43761701b0
---
drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 24 +++++++++++++++++++-----
drivers/pinctrl/mediatek/pinctrl-paris.c | 19 +++++++++++++++++++
2 files changed, 38 insertions(+), 5 deletions(-)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index 20e1c89..4687f63 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -68,7 +68,7 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
{
const struct mtk_pin_field_calc *c, *e;
const struct mtk_pin_reg_calc *rc;
- u32 bits;
+ u32 bits, start = 0, end, found = 0, check;
if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) {
rc = &hw->soc->reg_cal[field];
@@ -79,21 +79,32 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
return -ENOTSUPP;
}
+ end = rc->nranges - 1;
c = rc->range;
e = c + rc->nranges;
- while (c < e) {
- if (desc->number >= c->s_pin && desc->number <= c->e_pin)
+ while (start <= end) {
+ check = (start + end) >> 1;
+ if (desc->number >= rc->range[check].s_pin
+ && desc->number <= rc->range[check].e_pin) {
+ found = 1;
break;
- c++;
+ } else if (start == end)
+ break;
+ else if (desc->number < rc->range[check].s_pin)
+ end = check - 1;
+ else
+ start = check + 1;
}
- if (c >= e) {
+ if (!found) {
dev_dbg(hw->dev, "Not support field %d for pin = %d (%s)\n",
field, desc->number, desc->name);
return -ENOTSUPP;
}
+ c = rc->range + check;
+
if (c->i_base > hw->nbase - 1) {
dev_err(hw->dev,
"Invalid base for field %d for pin = %d (%s)\n",
@@ -182,6 +193,9 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
if (err)
return err;
+ if (value < 0 || value > pf.mask)
+ return -EINVAL;
+
if (!pf.next)
mtk_rmw(hw, pf.index, pf.offset, pf.mask << pf.bitpos,
(value & pf.mask) << pf.bitpos);
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 923264d..28b4951 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -693,6 +693,9 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, unsigned int gpio)
const struct mtk_pin_desc *desc;
int value, err;
+ if (gpio > hw->soc->npins)
+ return -EINVAL;
+
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &value);
@@ -708,6 +711,9 @@ static int mtk_gpio_get(struct gpio_chip *chip, unsigned int gpio)
const struct mtk_pin_desc *desc;
int value, err;
+ if (gpio > hw->soc->npins)
+ return -EINVAL;
+
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value);
@@ -722,6 +728,9 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value)
struct mtk_pinctrl *hw = gpiochip_get_data(chip);
const struct mtk_pin_desc *desc;
+ if (gpio > hw->soc->npins)
+ return;
+
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, !!value);
@@ -729,12 +738,22 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value)
static int mtk_gpio_direction_input(struct gpio_chip *chip, unsigned int gpio)
{
+ struct mtk_pinctrl *hw = gpiochip_get_data(chip);
+
+ if (gpio > hw->soc->npins)
+ return -EINVAL;
+
return pinctrl_gpio_direction_input(chip->base + gpio);
}
static int mtk_gpio_direction_output(struct gpio_chip *chip, unsigned int gpio,
int value)
{
+ struct mtk_pinctrl *hw = gpiochip_get_data(chip);
+
+ if (gpio > hw->soc->npins)
+ return -EINVAL;
+
mtk_gpio_set(chip, gpio, value);
return pinctrl_gpio_direction_output(chip->base + gpio);
--
1.8.1.1.dirty
^ permalink raw reply related
* [PATCH v1 3/5] pinctrl: mediatek: Refine mtk_pinconf_get() and mtk_pinconf_set()
From: Light Hsieh @ 2019-08-13 8:53 UTC (permalink / raw)
To: linus.walleij
Cc: linux-mediatek, linux-gpio, linux-kernel, sean.wang, Light Hsieh
In-Reply-To: <1565686400-5711-1-git-send-email-light.hsieh@mediatek.com>
From: Light Hsieh <light.hsieh@mediatek.com>
1.Refine mtk_pinconf_get():
1.1 Use only one occurrence of return at end of this function.
1.2 Correct cases for PIN_CONFIG_SLEW_RATE, PIN_CONFIG_INPUT_SCHMITT_ENABLE,
and PIN_CONFIG_OUTPUT_ENABLE -
Use variable ret to receive value in mtk_hw_get_value() (instead of
variable val) since pinconf_to_config_packed() at end of this function
use variable ret to pack config value.
2.Refine mtk_pinconf_set():
2.1 Use only one occurrence of return at end of this function.
2.2 Modify case of PIN_CONFIG_INPUT_ENABLE -
Remove check of ies_present flag and always invoke mtk_hw_set_value()
since mtk_hw_pin_field_lookup() invoked inside mtk_hw_set_value() has
the same effect of checking if ies control is supported.
[The rationale is that: available of a control is always checked
in mtk_hw_pin_field_lookup() and no need to add ies_present flag
specially for ies control.]
2.3 Simply code logic for case of PIN_CONFIG_INPUT_SCHMITT.
2.4 Add case for PIN_CONFIG_INPUT_SCHMITT_ENABLE and process it with the
same code for case of PIN_CONFIG_INPUT_SCHMITT.
Change-Id: Ia82ca7e2516839554feaad6f1aabd9f1bd3b5222
---
drivers/pinctrl/mediatek/pinctrl-mt6765.c | 1 -
drivers/pinctrl/mediatek/pinctrl-paris.c | 204 +++++++++++-------------------
2 files changed, 75 insertions(+), 130 deletions(-)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6765.c b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
index e024ebc..bada37f 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt6765.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt6765.c
@@ -1070,7 +1070,6 @@
.ngrps = ARRAY_SIZE(mtk_pins_mt6765),
.eint_hw = &mt6765_eint_hw,
.gpio_m = 0,
- .ies_present = true,
.base_names = mt6765_pinctrl_register_base_names,
.nbase_names = ARRAY_SIZE(mt6765_pinctrl_register_base_names),
.bias_disable_set = mtk_pinconf_bias_disable_set,
diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 71c94b2..bbe3f8a 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -78,93 +78,75 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
{
struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
u32 param = pinconf_to_config_param(*config);
- int val, val2, err, reg, ret = 1;
+ int err, reg, ret = 1;
const struct mtk_pin_desc *desc;
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
switch (param) {
case PIN_CONFIG_BIAS_DISABLE:
- if (hw->soc->bias_disable_get) {
+ if (hw->soc->bias_disable_get)
err = hw->soc->bias_disable_get(hw, desc, &ret);
- if (err)
- return err;
- } else {
- return -ENOTSUPP;
- }
+ else
+ err = -ENOTSUPP;
break;
case PIN_CONFIG_BIAS_PULL_UP:
- if (hw->soc->bias_get) {
+ if (hw->soc->bias_get)
err = hw->soc->bias_get(hw, desc, 1, &ret);
- if (err)
- return err;
- } else {
- return -ENOTSUPP;
- }
+ else
+ err = -ENOTSUPP;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
- if (hw->soc->bias_get) {
+ if (hw->soc->bias_get)
err = hw->soc->bias_get(hw, desc, 0, &ret);
- if (err)
- return err;
- } else {
- return -ENOTSUPP;
- }
+ else
+ err = -ENOTSUPP;
break;
case PIN_CONFIG_SLEW_RATE:
- err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &val);
- if (err)
- return err;
-
- if (!val)
- return -EINVAL;
-
+ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &ret);
break;
case PIN_CONFIG_INPUT_ENABLE:
case PIN_CONFIG_OUTPUT_ENABLE:
- err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val);
+ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret);
if (err)
- return err;
-
- /* HW takes input mode as zero; output mode as non-zero */
- if ((val && param == PIN_CONFIG_INPUT_ENABLE) ||
- (!val && param == PIN_CONFIG_OUTPUT_ENABLE))
- return -EINVAL;
+ goto out;
+ /* CONFIG Current direction return value
+ * ------------- ----------------- ----------------------
+ * OUTPUT_ENABLE output 1 (= HW value)
+ * input 0 (= HW value)
+ * INPUT_ENABLE output 0 (= reverse HW value)
+ * input 1 (= reverse HW value)
+ */
+ if (param == PIN_CONFIG_INPUT_ENABLE)
+ ret = !ret;
break;
case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
- err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val);
- if (err)
- return err;
-
- err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &val2);
+ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret);
if (err)
- return err;
+ goto out;
+ /* return error when in output mode
+ * because schmitt trigger only work in input mode
+ */
+ if (ret) {
+ err = -EINVAL;
+ goto out;
+ }
- if (val || !val2)
- return -EINVAL;
+ err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &ret);
break;
case PIN_CONFIG_DRIVE_STRENGTH:
- if (hw->soc->drive_get) {
+ if (hw->soc->drive_get)
err = hw->soc->drive_get(hw, desc, &ret);
- if (err)
- return err;
- } else {
+ else
err = -ENOTSUPP;
- }
break;
case MTK_PIN_CONFIG_TDSEL:
case MTK_PIN_CONFIG_RDSEL:
reg = (param == MTK_PIN_CONFIG_TDSEL) ?
PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL;
-
err = mtk_hw_get_value(hw, desc, reg, &val);
- if (err)
- return err;
-
- ret = val;
-
break;
case MTK_PIN_CONFIG_PU_ADV:
case MTK_PIN_CONFIG_PD_ADV:
@@ -173,28 +155,24 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
pullup = param == MTK_PIN_CONFIG_PU_ADV;
err = hw->soc->adv_pull_get(hw, desc, pullup, &ret);
- if (err)
- return err;
- } else {
- return -ENOTSUPP;
- }
+ } else
+ err = -ENOTSUPP;
break;
case MTK_PIN_CONFIG_DRV_ADV:
- if (hw->soc->adv_drive_get) {
+ if (hw->soc->adv_drive_get)
err = hw->soc->adv_drive_get(hw, desc, &ret);
- if (err)
- return err;
- } else {
- return -ENOTSUPP;
- }
+ else
+ err = -ENOTSUPP;
break;
default:
- return -ENOTSUPP;
+ err = -ENOTSUPP;
}
- *config = pinconf_to_config_packed(param, ret);
+out:
+ if (!err)
+ *config = pinconf_to_config_packed(param, ret);
- return 0;
+ return err;
}
static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
@@ -210,60 +188,46 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
switch ((u32)param) {
case PIN_CONFIG_BIAS_DISABLE:
- if (hw->soc->bias_disable_set) {
+ if (hw->soc->bias_disable_set)
err = hw->soc->bias_disable_set(hw, desc);
- if (err)
- return err;
- } else {
- return -ENOTSUPP;
- }
+ else
+ err = -ENOTSUPP;
break;
case PIN_CONFIG_BIAS_PULL_UP:
- if (hw->soc->bias_set) {
+ if (hw->soc->bias_set)
err = hw->soc->bias_set(hw, desc, 1);
- if (err)
- return err;
- } else {
- return -ENOTSUPP;
- }
+ else
+ err = -ENOTSUPP;
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
- if (hw->soc->bias_set) {
+ if (hw->soc->bias_set)
err = hw->soc->bias_set(hw, desc, 0);
- if (err)
- return err;
- } else {
- return -ENOTSUPP;
- }
+ else
+ err = -ENOTSUPP;
break;
case PIN_CONFIG_OUTPUT_ENABLE:
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT,
MTK_DISABLE);
- if (err)
+ /* keep set direction to if SMT is not supported on this pin */
+ if (err != -ENOTSUPP)
goto err;
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
MTK_OUTPUT);
- if (err)
- goto err;
break;
case PIN_CONFIG_INPUT_ENABLE:
- if (hw->soc->ies_present) {
- mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES,
- MTK_ENABLE);
- }
+ /* regard all non-zero value as enable */
+ mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES, !!arg);
- err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
- MTK_INPUT);
if (err)
goto err;
+
+ err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
+ MTK_INPUT);
break;
case PIN_CONFIG_SLEW_RATE:
- err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SR,
- arg);
- if (err)
- goto err;
-
+ /* regard all non-zero value as enable */
+ err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SR, !!arg);
break;
case PIN_CONFIG_OUTPUT:
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
@@ -273,41 +237,29 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO,
arg);
- if (err)
- goto err;
break;
+ case PIN_CONFIG_INPUT_SCHMITT:
case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
- /* arg = 1: Input mode & SMT enable ;
+ /* arg = 1: Input mode & SMT enable
* arg = 0: Output mode & SMT disable
*/
- arg = arg ? 2 : 1;
- err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR,
- arg & 1);
+ err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, !arg);
if (err)
goto err;
- err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT,
- !!(arg & 2));
- if (err)
- goto err;
+ err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, !!arg);
break;
case PIN_CONFIG_DRIVE_STRENGTH:
- if (hw->soc->drive_set) {
+ if (hw->soc->drive_set)
err = hw->soc->drive_set(hw, desc, arg);
- if (err)
- return err;
- } else {
- return -ENOTSUPP;
- }
+ else
+ err = -ENOTSUPP;
break;
case MTK_PIN_CONFIG_TDSEL:
case MTK_PIN_CONFIG_RDSEL:
reg = (param == MTK_PIN_CONFIG_TDSEL) ?
PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL;
-
err = mtk_hw_set_value(hw, desc, reg, arg);
- if (err)
- goto err;
break;
case MTK_PIN_CONFIG_PU_ADV:
case MTK_PIN_CONFIG_PD_ADV:
@@ -317,20 +269,14 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
pullup = param == MTK_PIN_CONFIG_PU_ADV;
err = hw->soc->adv_pull_set(hw, desc, pullup,
arg);
- if (err)
- return err;
- } else {
- return -ENOTSUPP;
- }
+ } else
+ err = -ENOTSUPP;
break;
case MTK_PIN_CONFIG_DRV_ADV:
- if (hw->soc->adv_drive_set) {
+ if (hw->soc->adv_drive_set)
err = hw->soc->adv_drive_set(hw, desc, arg);
- if (err)
- return err;
- } else {
- return -ENOTSUPP;
- }
+ else
+ err = -ENOTSUPP;
break;
default:
err = -ENOTSUPP;
@@ -946,6 +892,7 @@ int mtk_paris_pinctrl_probe(struct platform_device *pdev,
return 0;
}
+
static int mtk_paris_pinctrl_suspend(struct device *device)
{
struct mtk_pinctrl *pctl = dev_get_drvdata(device);
@@ -964,4 +911,3 @@ static int mtk_paris_pinctrl_resume(struct device *device)
.suspend_noirq = mtk_paris_pinctrl_suspend,
.resume_noirq = mtk_paris_pinctrl_resume,
};
-
--
1.8.1.1.dirty
^ permalink raw reply related
* [PATCH v1 0/5] Improve MediaTek pinctrl v2 and make backward compatible to smartphone mass production usage
From: Light Hsieh @ 2019-08-13 8:53 UTC (permalink / raw)
To: linus.walleij; +Cc: linux-mediatek, linux-gpio, linux-kernel, sean.wang
This patch improves MediaTek pinctrl v2 and makes backward compatible to
current smartphone mass production usage by:
1.Check gpio pin number and use binary search in control address lookup
2.Supporting driving setting without mapping current to register value
3.Correct usage of PIN_CONFIG get/set implementation
4.Backward compatible to previous Mediatek's bias-pull usage
5.Add support for pin configuration dump via sysfs
^ permalink raw reply
* [PATCH] RFC: pinctrl: cherryview: Pass irqchip when adding gpiochip
From: Linus Walleij @ 2019-08-13 7:01 UTC (permalink / raw)
To: linux-gpio
Cc: Linus Walleij, Thomas Gleixner, Jason Cooper, Marc Zyngier,
Andy Shevchenko, Mika Westerberg, Thierry Reding
We need to convert all old gpio irqchips to pass the irqchip
setup along when adding the gpio_chip. For more info see
drivers/gpio/TODO.
This driver is something of a special case, so we need to
discuss it.
It picks a number of IRQ descriptors before setting up
the gpio_irq_chip using devm_irq_alloc_descs() giving a
fixed irq base in the IRQ numberspace. It then games the
irqchip API by associating IRQs from that base and upward
with as many pins there are in the "community" which is a
set of pins. Then after each gpio_chip is registered, it
fills in the pin to IRQ map for each GPIO range inside
that "community" with irq_domain_associate_many() which
works fine since the descriptors were allocated
previously.
This is actually a hierarchical irq_chip as far as I can
tell. The problem is that very likely the Intel root IRQ
chip is not hierarchical so it does not support using the
facilities for hierarchical irqdomains.
I will soon merge the patch providing hierarchical irqchip
support in gpiolib:
https://lore.kernel.org/linux-gpio/20190808123242.5359-1-linus.walleij@linaro.org/
Will we need to bite the bullet and convert the root
irqchip for the intels to support hierarcical irqdomain?
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
Cc: Thierry Reding <treding@nvidia.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
drivers/pinctrl/intel/pinctrl-cherryview.c | 37 +++++++++++++++-------
1 file changed, 26 insertions(+), 11 deletions(-)
diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c
index 03ec7a5d9d0b..932da7071356 100644
--- a/drivers/pinctrl/intel/pinctrl-cherryview.c
+++ b/drivers/pinctrl/intel/pinctrl-cherryview.c
@@ -1547,6 +1547,7 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq)
{
const struct chv_gpio_pinrange *range;
struct gpio_chip *chip = &pctrl->chip;
+ struct gpio_irq_chip *girq;
bool need_valid_mask = !dmi_check_system(chv_no_valid_mask);
const struct chv_community *community = pctrl->community;
int ret, i, irq_base;
@@ -1559,12 +1560,6 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq)
chip->base = -1;
chip->irq.need_valid_mask = need_valid_mask;
- ret = devm_gpiochip_add_data(pctrl->dev, chip, pctrl);
- if (ret) {
- dev_err(pctrl->dev, "Failed to register gpiochip\n");
- return ret;
- }
-
for (i = 0; i < community->ngpio_ranges; i++) {
range = &community->gpio_ranges[i];
ret = gpiochip_add_pin_range(chip, dev_name(pctrl->dev),
@@ -1610,6 +1605,11 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq)
/* Clear all interrupts */
chv_writel(0xffff, pctrl->regs + CHV_INTSTAT);
+ /*
+ * FIXME: this picks as many IRQs as there are lines in the
+ * "community", which is then later associated per-range below
+ * registering the gpio_chip. This is actually hierarchical IRQ.
+ */
if (!need_valid_mask) {
irq_base = devm_irq_alloc_descs(pctrl->dev, -1, 0,
community->npins, NUMA_NO_NODE);
@@ -1619,13 +1619,30 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq)
}
}
- ret = gpiochip_irqchip_add(chip, &chv_gpio_irqchip, 0,
- handle_bad_irq, IRQ_TYPE_NONE);
+ girq = &chip->irq;
+ girq->chip = &chv_gpio_irqchip;
+ girq->parent_handler = chv_gpio_irq_handler;
+ girq->num_parents = 1;
+ girq->parents = devm_kcalloc(pctrl->dev, 1,
+ sizeof(*girq->parents),
+ GFP_KERNEL);
+ if (!girq->parents)
+ return -ENOMEM;
+ girq->parents[0] = irq;
+ girq->default_handler = IRQ_TYPE_NONE;
+ girq->handler = handle_bad_irq;
+
+ ret = devm_gpiochip_add_data(pctrl->dev, chip, pctrl);
if (ret) {
- dev_err(pctrl->dev, "failed to add IRQ chip\n");
+ dev_err(pctrl->dev, "Failed to register gpiochip\n");
return ret;
}
+ /*
+ * FIXME: this associates a different IRQ with each discrete range
+ * inside the community. If we use the hierarchical irq support,
+ * the .translate() function can do this translation for each IRQ.
+ */
if (!need_valid_mask) {
for (i = 0; i < community->ngpio_ranges; i++) {
range = &community->gpio_ranges[i];
@@ -1636,8 +1653,6 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq)
}
}
- gpiochip_set_chained_irqchip(chip, &chv_gpio_irqchip, irq,
- chv_gpio_irq_handler);
return 0;
}
--
2.21.0
^ permalink raw reply related
* Re: [PATCH v2] gpiolib: Take MUX usage into account
From: Fried, Ramon @ 2019-08-13 6:10 UTC (permalink / raw)
To: Stefan Wahren, linus.walleij, bgolaszewski; +Cc: linux-gpio, linux-kernel
In-Reply-To: <1650c967-5176-70db-ff9a-b2af432ba1e7@i2se.com>
On 8/13/2019 08:38, Stefan Wahren wrote:
> Hi Ramon,
>
> On 13.08.19 03:42, Ramon Fried wrote:
>> From: Stefan Wahren <stefan.wahren@i2se.com>
>>
>> The user space like gpioinfo only see the GPIO usage but not the
>> MUX usage (e.g. I2C or SPI usage) of a pin. As a user we want to know which
>> pin is free/safe to use. So take the MUX usage of strict pinmux controllers
>> into account to get a more realistic view for ioctl GPIO_GET_LINEINFO_IOCTL.
>>
>> Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
>> Tested-by: Ramon Fried <rfried.dev@gmail.com>
>> Signed-off-by: Ramon Fried <rfried.dev@gmail.com>
>> ---
>> v2: Address review from linus:
>> * ** Please notive logic was reversed **
>> * renamed pinctrl_gpio_is_in_use() to pinctrl_gpio_can_use_line()
>> * renamed pinmux_is_in_use() to pinmux_can_be_used_for_gpio()
>> * changed dev_err to dev_dbg (Linus suggested removing it altogether, I
>> find it better to keep it for debug).
> thanks for taking care of this.
>> drivers/gpio/gpiolib.c | 3 ++-
>> drivers/pinctrl/core.c | 28 ++++++++++++++++++++++++++++
>> drivers/pinctrl/pinmux.c | 27 +++++++++++++++++++++++++++
>> drivers/pinctrl/pinmux.h | 8 ++++++++
>> include/linux/pinctrl/consumer.h | 6 ++++++
>> 5 files changed, 71 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
>> index f497003f119c..52937bf8e514 100644
>> --- a/drivers/gpio/gpiolib.c
>> +++ b/drivers/gpio/gpiolib.c
>> @@ -1084,7 +1084,8 @@ static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
>> test_bit(FLAG_IS_HOGGED, &desc->flags) ||
>> test_bit(FLAG_USED_AS_IRQ, &desc->flags) ||
>> test_bit(FLAG_EXPORT, &desc->flags) ||
>> - test_bit(FLAG_SYSFS, &desc->flags))
>> + test_bit(FLAG_SYSFS, &desc->flags) ||
>> + !pinctrl_gpio_can_use_line(chip->base + lineinfo.line_offset))
>> lineinfo.flags |= GPIOLINE_FLAG_KERNEL;
>> if (test_bit(FLAG_IS_OUT, &desc->flags))
>> lineinfo.flags |= GPIOLINE_FLAG_IS_OUT;
>> diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
>> index b70df27874d1..2bbd8ee93507 100644
>> --- a/drivers/pinctrl/core.c
>> +++ b/drivers/pinctrl/core.c
>> @@ -736,6 +736,34 @@ int pinctrl_get_group_selector(struct pinctrl_dev *pctldev,
>> return -EINVAL;
>> }
>>
>> +bool pinctrl_gpio_can_use_line(unsigned gpio)
>> +{
>> + struct pinctrl_dev *pctldev;
>> + struct pinctrl_gpio_range *range;
>> + bool result;
>> + int pin;
>> +
>> + /*
>> + * Try to obtain GPIO range, if it fails
>> + * we're probably dealing with GPIO driver
>> + * without a backing pin controller - bail out.
>> + */
>> + if (pinctrl_get_device_gpio_range(gpio, &pctldev, &range))
>> + return true;
>> +
>> + mutex_lock(&pctldev->mutex);
>> +
>> + /* Convert to the pin controllers number space */
>> + pin = gpio_to_pin(range, gpio);
>> +
>> + result = pinmux_can_be_used_for_gpio(pctldev, pin);
>> +
>> + mutex_unlock(&pctldev->mutex);
>> +
>> + return result;
>> +}
>> +EXPORT_SYMBOL_GPL(pinctrl_gpio_can_use_line);
>> +
>> /**
>> * pinctrl_gpio_request() - request a single pin to be used as GPIO
>> * @gpio: the GPIO pin number from the GPIO subsystem number space
>> diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
>> index 020e54f843f9..7e42a5738d82 100644
>> --- a/drivers/pinctrl/pinmux.c
>> +++ b/drivers/pinctrl/pinmux.c
>> @@ -70,6 +70,33 @@ int pinmux_validate_map(const struct pinctrl_map *map, int i)
>> return 0;
>> }
>>
>> +/**
>> + * pinmux_can_be_used_for_gpio() - check if a specific pin
>> + * is either muxed to a different function or used as gpio.
>> + *
>> + * @pin: the pin number in the global pin space
>> + *
>> + * Controllers not defined as strict will always return true,
>> + * menaning that the gpio can be used.
>> + */
>> +bool pinmux_can_be_used_for_gpio(struct pinctrl_dev *pctldev, unsigned pin)
>> +{
>> + struct pin_desc *desc = pin_desc_get(pctldev, pin);
>> + const struct pinmux_ops *ops = pctldev->desc->pmxops;
>> +
>> + if (!desc) {
>> + dev_dbg(pctldev->dev,
>> + "pin %u is not registered so it cannot be requested\n",
>> + pin);
>> + return true;
> This return value looks strange to me.
Basically, it's just the reversed return value you returned in the
original patch,
It means in this context that if the pin is not owned by a
pin-controller it can be used for GPIO.
Thanks,
Ramon.
>
> Stefan
>
^ permalink raw reply
* Re: [PATCH v2] gpiolib: Take MUX usage into account
From: Stefan Wahren @ 2019-08-13 5:38 UTC (permalink / raw)
To: Ramon Fried, linus.walleij, bgolaszewski; +Cc: linux-gpio, linux-kernel
In-Reply-To: <20190813014210.15519-1-ramon.fried@linux.intel.com>
Hi Ramon,
On 13.08.19 03:42, Ramon Fried wrote:
> From: Stefan Wahren <stefan.wahren@i2se.com>
>
> The user space like gpioinfo only see the GPIO usage but not the
> MUX usage (e.g. I2C or SPI usage) of a pin. As a user we want to know which
> pin is free/safe to use. So take the MUX usage of strict pinmux controllers
> into account to get a more realistic view for ioctl GPIO_GET_LINEINFO_IOCTL.
>
> Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
> Tested-by: Ramon Fried <rfried.dev@gmail.com>
> Signed-off-by: Ramon Fried <rfried.dev@gmail.com>
> ---
> v2: Address review from linus:
> * ** Please notive logic was reversed **
> * renamed pinctrl_gpio_is_in_use() to pinctrl_gpio_can_use_line()
> * renamed pinmux_is_in_use() to pinmux_can_be_used_for_gpio()
> * changed dev_err to dev_dbg (Linus suggested removing it altogether, I
> find it better to keep it for debug).
thanks for taking care of this.
>
> drivers/gpio/gpiolib.c | 3 ++-
> drivers/pinctrl/core.c | 28 ++++++++++++++++++++++++++++
> drivers/pinctrl/pinmux.c | 27 +++++++++++++++++++++++++++
> drivers/pinctrl/pinmux.h | 8 ++++++++
> include/linux/pinctrl/consumer.h | 6 ++++++
> 5 files changed, 71 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
> index f497003f119c..52937bf8e514 100644
> --- a/drivers/gpio/gpiolib.c
> +++ b/drivers/gpio/gpiolib.c
> @@ -1084,7 +1084,8 @@ static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
> test_bit(FLAG_IS_HOGGED, &desc->flags) ||
> test_bit(FLAG_USED_AS_IRQ, &desc->flags) ||
> test_bit(FLAG_EXPORT, &desc->flags) ||
> - test_bit(FLAG_SYSFS, &desc->flags))
> + test_bit(FLAG_SYSFS, &desc->flags) ||
> + !pinctrl_gpio_can_use_line(chip->base + lineinfo.line_offset))
> lineinfo.flags |= GPIOLINE_FLAG_KERNEL;
> if (test_bit(FLAG_IS_OUT, &desc->flags))
> lineinfo.flags |= GPIOLINE_FLAG_IS_OUT;
> diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
> index b70df27874d1..2bbd8ee93507 100644
> --- a/drivers/pinctrl/core.c
> +++ b/drivers/pinctrl/core.c
> @@ -736,6 +736,34 @@ int pinctrl_get_group_selector(struct pinctrl_dev *pctldev,
> return -EINVAL;
> }
>
> +bool pinctrl_gpio_can_use_line(unsigned gpio)
> +{
> + struct pinctrl_dev *pctldev;
> + struct pinctrl_gpio_range *range;
> + bool result;
> + int pin;
> +
> + /*
> + * Try to obtain GPIO range, if it fails
> + * we're probably dealing with GPIO driver
> + * without a backing pin controller - bail out.
> + */
> + if (pinctrl_get_device_gpio_range(gpio, &pctldev, &range))
> + return true;
> +
> + mutex_lock(&pctldev->mutex);
> +
> + /* Convert to the pin controllers number space */
> + pin = gpio_to_pin(range, gpio);
> +
> + result = pinmux_can_be_used_for_gpio(pctldev, pin);
> +
> + mutex_unlock(&pctldev->mutex);
> +
> + return result;
> +}
> +EXPORT_SYMBOL_GPL(pinctrl_gpio_can_use_line);
> +
> /**
> * pinctrl_gpio_request() - request a single pin to be used as GPIO
> * @gpio: the GPIO pin number from the GPIO subsystem number space
> diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
> index 020e54f843f9..7e42a5738d82 100644
> --- a/drivers/pinctrl/pinmux.c
> +++ b/drivers/pinctrl/pinmux.c
> @@ -70,6 +70,33 @@ int pinmux_validate_map(const struct pinctrl_map *map, int i)
> return 0;
> }
>
> +/**
> + * pinmux_can_be_used_for_gpio() - check if a specific pin
> + * is either muxed to a different function or used as gpio.
> + *
> + * @pin: the pin number in the global pin space
> + *
> + * Controllers not defined as strict will always return true,
> + * menaning that the gpio can be used.
> + */
> +bool pinmux_can_be_used_for_gpio(struct pinctrl_dev *pctldev, unsigned pin)
> +{
> + struct pin_desc *desc = pin_desc_get(pctldev, pin);
> + const struct pinmux_ops *ops = pctldev->desc->pmxops;
> +
> + if (!desc) {
> + dev_dbg(pctldev->dev,
> + "pin %u is not registered so it cannot be requested\n",
> + pin);
> + return true;
This return value looks strange to me.
Stefan
^ permalink raw reply
* Re: [PATCH] gpio: aspeed: Pass irqchip when adding gpiochip
From: Joel Stanley @ 2019-08-13 4:44 UTC (permalink / raw)
To: Linus Walleij
Cc: open list:GPIO SUBSYSTEM, Bartosz Golaszewski, Andrew Jeffery,
Benjamin Herrenschmidt, Thierry Reding
In-Reply-To: <20190809125515.19094-1-linus.walleij@linaro.org>
On Fri, 9 Aug 2019 at 12:55, Linus Walleij <linus.walleij@linaro.org> wrote:
>
> We need to convert all old gpio irqchips to pass the irqchip
> setup along when adding the gpio_chip. For more info see
> drivers/gpio/TODO.
>
> For chained irqchips this is a pretty straight-forward
> conversion.
>
> Cc: Joel Stanley <joel@jms.id.au>
> Cc: Andrew Jeffery <andrew@aj.id.au>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Thierry Reding <treding@nvidia.com>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> Hi Aspeed folks, it'd be great if you could test/review this
> patch.
> ---
> drivers/gpio/gpio-aspeed.c | 60 ++++++++++++++++++--------------------
> 1 file changed, 29 insertions(+), 31 deletions(-)
>
> diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c
> index 13d80bfbc3b6..9defe25d4721 100644
> --- a/drivers/gpio/gpio-aspeed.c
> +++ b/drivers/gpio/gpio-aspeed.c
> @@ -711,32 +711,6 @@ static void set_irq_valid_mask(struct aspeed_gpio *gpio)
> }
> }
>
> -static int aspeed_gpio_setup_irqs(struct aspeed_gpio *gpio,
> - struct platform_device *pdev)
> -{
> - int rc;
> -
> - rc = platform_get_irq(pdev, 0);
> - if (rc < 0)
> - return rc;
> -
> - gpio->irq = rc;
> -
> - set_irq_valid_mask(gpio);
> -
> - rc = gpiochip_irqchip_add(&gpio->chip, &aspeed_gpio_irqchip,
> - 0, handle_bad_irq, IRQ_TYPE_NONE);
> - if (rc) {
> - dev_info(&pdev->dev, "Could not add irqchip\n");
> - return rc;
> - }
> -
> - gpiochip_set_chained_irqchip(&gpio->chip, &aspeed_gpio_irqchip,
> - gpio->irq, aspeed_gpio_irq_handler);
> -
> - return 0;
> -}
> -
> static int aspeed_gpio_reset_tolerance(struct gpio_chip *chip,
> unsigned int offset, bool enable)
> {
> @@ -1189,7 +1163,6 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev)
> gpio->chip.set_config = aspeed_gpio_set_config;
> gpio->chip.label = dev_name(&pdev->dev);
> gpio->chip.base = -1;
> - gpio->chip.irq.need_valid_mask = true;
>
> /* Allocate a cache of the output registers */
> banks = gpio->config->nr_gpios >> 5;
> @@ -1212,16 +1185,41 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev)
> aspeed_gpio_change_cmd_source(gpio, bank, 3, GPIO_CMDSRC_ARM);
> }
>
> - rc = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio);
> - if (rc < 0)
> - return rc;
> + /* Optionally set up an irqchip if there is an IRQ */
> + rc = platform_get_irq(pdev, 0);
> + if (rc > 0) {
> + struct gpio_irq_chip *girq;
> +
> + gpio->irq = rc;
> + girq = &gpio->chip.irq;
> + girq->chip = &aspeed_gpio_irqchip;
> + girq->parent_handler = aspeed_gpio_irq_handler;
> + girq->num_parents = 1;
> + girq->parents = devm_kcalloc(&pdev->dev, 1,
> + sizeof(*girq->parents),
> + GFP_KERNEL);
Is there a reason this is kcalloc and not kzalloc?
Other than that,
Acked-by: Joel Stanley <joel@jms.id.au>
Cheers,
Joel
> + if (!girq->parents)
> + return -ENOMEM;
> + girq->parents[0] = gpio->irq;
> + girq->default_type = IRQ_TYPE_NONE;
> + girq->handler = handle_bad_irq;
> + girq->need_valid_mask = true;
> + }
>
> gpio->offset_timer =
> devm_kzalloc(&pdev->dev, gpio->chip.ngpio, GFP_KERNEL);
> if (!gpio->offset_timer)
> return -ENOMEM;
>
> - return aspeed_gpio_setup_irqs(gpio, pdev);
> + rc = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio);
> + if (rc < 0)
> + return rc;
> +
> + /* Now the valid mask is allocated */
> + if (gpio->irq)
> + set_irq_valid_mask(gpio);
> +
> + return 0;
> }
>
> static struct platform_driver aspeed_gpio_driver = {
> --
> 2.21.0
>
^ permalink raw reply
* Re: [PATCH] gpio: aspeed: Pass irqchip when adding gpiochip
From: Andrew Jeffery @ 2019-08-13 4:36 UTC (permalink / raw)
To: Linus Walleij, linux-gpio
Cc: Bartosz Golaszewski, Joel Stanley, Benjamin Herrenschmidt,
Thierry Reding
In-Reply-To: <20190809125515.19094-1-linus.walleij@linaro.org>
On Fri, 9 Aug 2019, at 22:25, Linus Walleij wrote:
> We need to convert all old gpio irqchips to pass the irqchip
> setup along when adding the gpio_chip. For more info see
> drivers/gpio/TODO.
>
> For chained irqchips this is a pretty straight-forward
> conversion.
>
> Cc: Joel Stanley <joel@jms.id.au>
> Cc: Andrew Jeffery <andrew@aj.id.au>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Thierry Reding <treding@nvidia.com>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> Hi Aspeed folks, it'd be great if you could test/review this
> patch.
Used it to exercise our WIP GPIO model for qemu. After fixing the qemu bugs it
worked fine there. Booted it on a Witherspoon and things worked as expected
there too. From a brief inspection it looks fine to me.
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
Tested-by: Andrew Jeffery <andrew@aj.id.au>
> ---
> drivers/gpio/gpio-aspeed.c | 60 ++++++++++++++++++--------------------
> 1 file changed, 29 insertions(+), 31 deletions(-)
>
> diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c
> index 13d80bfbc3b6..9defe25d4721 100644
> --- a/drivers/gpio/gpio-aspeed.c
> +++ b/drivers/gpio/gpio-aspeed.c
> @@ -711,32 +711,6 @@ static void set_irq_valid_mask(struct aspeed_gpio *gpio)
> }
> }
>
> -static int aspeed_gpio_setup_irqs(struct aspeed_gpio *gpio,
> - struct platform_device *pdev)
> -{
> - int rc;
> -
> - rc = platform_get_irq(pdev, 0);
> - if (rc < 0)
> - return rc;
> -
> - gpio->irq = rc;
> -
> - set_irq_valid_mask(gpio);
> -
> - rc = gpiochip_irqchip_add(&gpio->chip, &aspeed_gpio_irqchip,
> - 0, handle_bad_irq, IRQ_TYPE_NONE);
> - if (rc) {
> - dev_info(&pdev->dev, "Could not add irqchip\n");
> - return rc;
> - }
> -
> - gpiochip_set_chained_irqchip(&gpio->chip, &aspeed_gpio_irqchip,
> - gpio->irq, aspeed_gpio_irq_handler);
> -
> - return 0;
> -}
> -
> static int aspeed_gpio_reset_tolerance(struct gpio_chip *chip,
> unsigned int offset, bool enable)
> {
> @@ -1189,7 +1163,6 @@ static int __init aspeed_gpio_probe(struct
> platform_device *pdev)
> gpio->chip.set_config = aspeed_gpio_set_config;
> gpio->chip.label = dev_name(&pdev->dev);
> gpio->chip.base = -1;
> - gpio->chip.irq.need_valid_mask = true;
>
> /* Allocate a cache of the output registers */
> banks = gpio->config->nr_gpios >> 5;
> @@ -1212,16 +1185,41 @@ static int __init aspeed_gpio_probe(struct
> platform_device *pdev)
> aspeed_gpio_change_cmd_source(gpio, bank, 3, GPIO_CMDSRC_ARM);
> }
>
> - rc = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio);
> - if (rc < 0)
> - return rc;
> + /* Optionally set up an irqchip if there is an IRQ */
> + rc = platform_get_irq(pdev, 0);
> + if (rc > 0) {
> + struct gpio_irq_chip *girq;
> +
> + gpio->irq = rc;
> + girq = &gpio->chip.irq;
> + girq->chip = &aspeed_gpio_irqchip;
> + girq->parent_handler = aspeed_gpio_irq_handler;
> + girq->num_parents = 1;
> + girq->parents = devm_kcalloc(&pdev->dev, 1,
> + sizeof(*girq->parents),
> + GFP_KERNEL);
> + if (!girq->parents)
> + return -ENOMEM;
> + girq->parents[0] = gpio->irq;
> + girq->default_type = IRQ_TYPE_NONE;
> + girq->handler = handle_bad_irq;
> + girq->need_valid_mask = true;
> + }
>
> gpio->offset_timer =
> devm_kzalloc(&pdev->dev, gpio->chip.ngpio, GFP_KERNEL);
> if (!gpio->offset_timer)
> return -ENOMEM;
>
> - return aspeed_gpio_setup_irqs(gpio, pdev);
> + rc = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio);
> + if (rc < 0)
> + return rc;
> +
> + /* Now the valid mask is allocated */
> + if (gpio->irq)
> + set_irq_valid_mask(gpio);
> +
> + return 0;
> }
>
> static struct platform_driver aspeed_gpio_driver = {
> --
> 2.21.0
>
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox