Fix pinctrl-single pcs_pin_dbg_show()
Subsystems (3)
v2 cover Fix pinctrl-single pcs_pin_dbg_show()
These patches fix the pcs_pin_dbg_show() function for the scenario where a single register controls multiple pins (i.e. bits_per_mux is not zero) Additionally, the common formula is moved to a separate function to allow reuse.
Changes since v2:
-----------------
- move read() register to be outside of if condition (as it common read()).
- Remove extra parentheses
- replace offset variable by direct return statements
Changes since v1:
-----------------
- remove unused variable in In function 'pcs_allocate_pin_table' (Reported-by: kernel test robot <[email protected]>)
Hanna Hawa (3):
pinctrl: pinctrl-single: remove unused variable
pinctrl: pinctrl-single: remove unused parameter
pinctrl: pinctrl-single: fix pcs_pin_dbg_show() when bits_per_mux is
not zero
drivers/pinctrl/pinctrl-single.c | 67 +++++++++++++++++++------------- 1 file changed, 39 insertions(+), 28 deletions(-)
Signature · 1 line
2.17.1
PATCH v3 1/3 pinctrl: pinctrl-single: remove unused variable
Remove unused parameter 'num_pins_in_register' from pcs_allocate_pin_table().
--- drivers/pinctrl/pinctrl-single.c | 2 -- 1 file changed, 2 deletions(-)
drivers/pinctrl/pinctrl-single.c +0 -2
@@ -703,14 +703,12 @@ static int pcs_add_pin(struct pcs_device *pcs, unsigned offset,static int pcs_allocate_pin_table (struct pcs_device *pcs) {int mux_bytes, nr_pins, i; -int num_pins_in_register =0 ; mux_bytes = pcs->width /BITS_PER_BYTE ;if (pcs->bits_per_mux) { pcs->bits_per_pin =fls (pcs->fmask); nr_pins = (pcs->size *BITS_PER_BYTE ) / pcs->bits_per_pin; - num_pins_in_register = pcs->width / pcs->bits_per_pin; }else { nr_pins = pcs->size / mux_bytes; }
Signature · 1 line
2.17.1
PATCH v3 2/3 pinctrl: pinctrl-single: remove unused parameter
In reply to Hanna HawaRemove unused parameter 'pin_pos' from pcs_add_pin().
--- drivers/pinctrl/pinctrl-single.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
drivers/pinctrl/pinctrl-single.c +2 -6
@@ -656,10 +656,8 @@ static const struct pinconf_ops pcs_pinconf_ops = {* pcs_add_pin() - add a pin to the static per controller pin array * @pcs: pcs driver instance * @offset: register offset from base -* @pin_pos: unused */ -static int pcs_add_pin (struct pcs_device *pcs,unsigned offset, -unsigned pin_pos) +static int pcs_add_pin (struct pcs_device *pcs,unsigned int offset) {struct pcs_soc_data *pcs_soc = &pcs->socdata;struct pinctrl_pin_desc *pin;
@@ -727,16 +725,14 @@ static int pcs_allocate_pin_table(struct pcs_device *pcs)unsigned offset;int res;int byte_num; -int pin_pos =0 ;if (pcs->bits_per_mux) { byte_num = (pcs->bits_per_pin * i) /BITS_PER_BYTE ; offset = (byte_num / mux_bytes) * mux_bytes; - pin_pos = i % num_pins_in_register; }else { offset = i * mux_bytes; } - res =pcs_add_pin (pcs, offset, pin_pos); + res =pcs_add_pin (pcs, offset);if (res <0 ) {dev_err (pcs->dev,"error adding pins: %i\n" , res);return res;
Signature · 1 line
2.17.1
PATCH v3 3/3 pinctrl: pinctrl-single: fix pcs_pin_dbg_show() when bits_per_mux is not zero
In reply to Hanna HawaAn SError was detected when trying to print the supported pins in a pinctrl device which supports multiple pins per register. This change fixes the pcs_pin_dbg_show() in pinctrl-single driver when bits_per_mux is not zero. In addition move offset calculation and pin offset in register to common function.
--- drivers/pinctrl/pinctrl-single.c | 57 +++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 20 deletions(-)
drivers/pinctrl/pinctrl-single.c +37 -20
@@ -270,20 +270,46 @@ static void __maybe_unused pcs_writel(unsigned val, void __iomem *reg)writel (val, reg); } +static unsigned int pcs_pin_reg_offset_get (struct pcs_device *pcs, +unsigned int pin) +{ +unsigned int mux_bytes; + + mux_bytes = pcs->width /BITS_PER_BYTE ; + +if (pcs->bits_per_mux) { +unsigned int pin_offset_bytes; + + pin_offset_bytes = (pcs->bits_per_pin * pin) /BITS_PER_BYTE ; +return (pin_offset_bytes / mux_bytes) * mux_bytes; + } + +return pin * mux_bytes; +} + +static unsigned int pcs_pin_shift_reg_get (struct pcs_device *pcs, +unsigned int pin) +{ +return (pin % (pcs->width / pcs->bits_per_pin)) * pcs->bits_per_pin; +} +static void pcs_pin_dbg_show (struct pinctrl_dev *pctldev,struct seq_file *s,unsigned pin) {struct pcs_device *pcs; -unsigned val, mux_bytes; +unsigned int val;unsigned long offset;size_t pa; pcs =pinctrl_dev_get_drvdata (pctldev); - mux_bytes = pcs->width /BITS_PER_BYTE ; - offset = pin * mux_bytes; + offset =pcs_pin_reg_offset_get (pcs, pin); val = pcs->read (pcs->base + offset); + +if (pcs->bits_per_mux) + val &= pcs->fmask <<pcs_pin_shift_reg_get (pcs, pin); + pa = pcs->res->start + offset;seq_printf (s,"%zx %08x %s " , pa, val,DRIVER_NAME );
@@ -384,7 +410,6 @@ static int pcs_request_gpio(struct pinctrl_dev *pctldev,struct pcs_device *pcs =pinctrl_dev_get_drvdata (pctldev);struct pcs_gpiofunc_range *frange =NULL ;struct list_head *pos, *tmp; -int mux_bytes =0 ;unsigned data;/* If function mask is null, return directly. */
@@ -392,29 +417,27 @@ static int pcs_request_gpio(struct pinctrl_dev *pctldev,return -ENOTSUPP ;list_for_each_safe (pos, tmp, &pcs->gpiofuncs) { +u32 offset; + frange = list_entry(pos, struct pcs_gpiofunc_range, node);if (pin >= frange->offset + frange->npins || pin < frange->offset)continue ; - mux_bytes = pcs->width /BITS_PER_BYTE ; -if (pcs->bits_per_mux) { -int byte_num, offset, pin_shift; + offset =pcs_pin_reg_offset_get (pcs, pin); - byte_num = (pcs->bits_per_pin * pin) /BITS_PER_BYTE ; - offset = (byte_num / mux_bytes) * mux_bytes; - pin_shift = pin % (pcs->width / pcs->bits_per_pin) * - pcs->bits_per_pin; +if (pcs->bits_per_mux) { +int pin_shift =pcs_pin_shift_reg_get (pcs, pin); data = pcs->read (pcs->base + offset); data &= ~(pcs->fmask << pin_shift); data |= frange->gpiofunc << pin_shift; pcs->write (data, pcs->base + offset); }else { - data = pcs->read (pcs->base + pin * mux_bytes); + data = pcs->read (pcs->base + offset); data &= ~pcs->fmask; data |= frange->gpiofunc; - pcs->write (data, pcs->base + pin * mux_bytes); + pcs->write (data, pcs->base + offset); }break ; }
@@ -724,14 +747,8 @@ static int pcs_allocate_pin_table(struct pcs_device *pcs)for (i =0 ; i < pcs->desc.npins; i++) {unsigned offset;int res; -int byte_num; -if (pcs->bits_per_mux) { - byte_num = (pcs->bits_per_pin * i) /BITS_PER_BYTE ; - offset = (byte_num / mux_bytes) * mux_bytes; - }else { - offset = i * mux_bytes; - } + offset =pcs_pin_reg_offset_get (pcs, i); res =pcs_add_pin (pcs, offset);if (res <0 ) {dev_err (pcs->dev,"error adding pins: %i\n" , res);
Signature · 1 line
2.17.1
Re: [PATCH v3 3/3] pinctrl: pinctrl-single: fix pcs_pin_dbg_show() when bits_per_mux is not zero
Quoted 3 lines · Hanna Hawa
An SError was detected when trying to print the supported pins in a
What is SError? Yes, I have read a discussion, but here is the hint:
if a person sees this as a first text due to, for example, bisecting an issue, what she/he can get from this cryptic name?
Quoted 4 lines
pinctrl device which supports multiple pins per register. This change fixes the
pcs_pin_dbg_show()in pinctrl-single driver whenbits_per_muxis not zero. In addition move offset calculation and pin offset in register to common function.
Quoted 11 lines
Fixes 4e7e8017a80e ("pinctrl: pinctrl-single: enhance to configure multiple pins of different modules")Signed-off-by Hanna Hawa <[email protected]>--- drivers/pinctrl/pinctrl-single.c | 57 +++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 20 deletions(-)drivers/pinctrl/pinctrl-single.c +0
-0
drivers/pinctrl/pinctrl-single.c static void __maybe_unused pcs_writel(unsigned val, void __iomem *reg) · line 279
Quoted 10 lines
drivers/pinctrl/pinctrl-single.c +6
-0@@ -270,20 +270,46 @@ static void __maybe_unused pcs_writel(unsigned val, void __iomem *reg)writel (val, reg); } +static unsigned int pcs_pin_reg_offset_get (struct pcs_device *pcs, +unsigned int pin) +{ +unsigned int mux_bytes; + + mux_bytes = pcs->width /BITS_PER_BYTE ;
Can be folded to one line.
drivers/pinctrl/pinctrl-single.c static void __maybe_unused pcs_writel(unsigned val, void __iomem *reg) · line 284
Quoted 5 lines
drivers/pinctrl/pinctrl-single.c +5
-0+if (pcs->bits_per_mux) { +unsigned int pin_offset_bytes; + + pin_offset_bytes = (pcs->bits_per_pin * pin) /BITS_PER_BYTE ; +return (pin_offset_bytes / mux_bytes) * mux_bytes;
Side note for the further improvements (in a separate change, because I see that you just copied an original code, and after all this is just a fix patch): this can be replaced by round down APIs (one which works for arbitrary divisors).
drivers/pinctrl/pinctrl-single.c static void __maybe_unused pcs_writel(unsigned val, void __iomem *reg) · line 293
Quoted 9 lines
drivers/pinctrl/pinctrl-single.c +9
-0+ } + +return pin * mux_bytes; +} + +static unsigned int pcs_pin_shift_reg_get (struct pcs_device *pcs, +unsigned int pin) +{ +return (pin % (pcs->width / pcs->bits_per_pin)) * pcs->bits_per_pin;
Also a side note: I'm wondering if this can be optimized to have less divisions.
Quoted 89 lines
drivers/pinctrl/pinctrl-single.c +16
-21+} +static void pcs_pin_dbg_show (struct pinctrl_dev *pctldev,struct seq_file *s,unsigned pin) {struct pcs_device *pcs; -unsigned val, mux_bytes; +unsigned int val;unsigned long offset;size_t pa; pcs =pinctrl_dev_get_drvdata (pctldev); - mux_bytes = pcs->width /BITS_PER_BYTE ; - offset = pin * mux_bytes; + offset =pcs_pin_reg_offset_get (pcs, pin); val = pcs->read (pcs->base + offset); + +if (pcs->bits_per_mux) + val &= pcs->fmask <<pcs_pin_shift_reg_get (pcs, pin); + pa = pcs->res->start + offset;seq_printf (s,"%zx %08x %s " , pa, val,DRIVER_NAME );@@ -384,7 +410,6 @@ static int pcs_request_gpio(struct pinctrl_dev *pctldev,struct pcs_device *pcs =pinctrl_dev_get_drvdata (pctldev);struct pcs_gpiofunc_range *frange =NULL ;struct list_head *pos, *tmp; -int mux_bytes =0 ;unsigned data;/* If function mask is null, return directly. */ @@ -392,29 +417,27 @@ static int pcs_request_gpio(struct pinctrl_dev *pctldev,return -ENOTSUPP ;list_for_each_safe (pos, tmp, &pcs->gpiofuncs) { +u32 offset; + frange = list_entry(pos, struct pcs_gpiofunc_range, node);if (pin >= frange->offset + frange->npins || pin < frange->offset)continue ; - mux_bytes = pcs->width /BITS_PER_BYTE ; -if (pcs->bits_per_mux) { -int byte_num, offset, pin_shift; + offset =pcs_pin_reg_offset_get (pcs, pin); - byte_num = (pcs->bits_per_pin * pin) /BITS_PER_BYTE ; - offset = (byte_num / mux_bytes) * mux_bytes; - pin_shift = pin % (pcs->width / pcs->bits_per_pin) * - pcs->bits_per_pin; +if (pcs->bits_per_mux) { +int pin_shift =pcs_pin_shift_reg_get (pcs, pin); data = pcs->read (pcs->base + offset); data &= ~(pcs->fmask << pin_shift); data |= frange->gpiofunc << pin_shift; pcs->write (data, pcs->base + offset); }else { - data = pcs->read (pcs->base + pin * mux_bytes); + data = pcs->read (pcs->base + offset); data &= ~pcs->fmask; data |= frange->gpiofunc; - pcs->write (data, pcs->base + pin * mux_bytes); + pcs->write (data, pcs->base + offset); }break ; }@@ -724,14 +747,8 @@ static int pcs_allocate_pin_table(struct pcs_device *pcs)for (i =0 ; i < pcs->desc.npins; i++) {unsigned offset;int res; -int byte_num; -if (pcs->bits_per_mux) { - byte_num = (pcs->bits_per_pin * i) /BITS_PER_BYTE ; - offset = (byte_num / mux_bytes) * mux_bytes; - }else { - offset = i * mux_bytes; - } + offset =pcs_pin_reg_offset_get (pcs, i); res =pcs_add_pin (pcs, offset);if (res <0 ) {dev_err (pcs->dev,"error adding pins: %i\n" , res); --2.17.1
Signature · 2 lines
With Best Regards, Andy Shevchenko
Re: [PATCH v3 3/3] pinctrl: pinctrl-single: fix pcs_pin_dbg_show() when bits_per_mux is not zero
Quoted 7 lines · Andy Shevchenko
Quoted 1 line · Hanna Hawa
An SError was detected when trying to print the supported pins in a
What is SError? Yes, I have read a discussion, but here is the hint:
if a person sees this as a first text due to, for example, bisecting an issue, what she/he can get from this cryptic name?
What you suggest?
s/An SError/A kernel-panic/?
Or remove the sentence and keep the below:
"
This change fixes the pcs_pin_dbg_show() in pinctrl-single driver when bits_per_mux is not zero. In addition move offset calculation and pin offset in register to common function. "
Quoted 6 lines
Quoted 5 lines
pinctrl device which supports multiple pins per register. This change fixes the
pcs_pin_dbg_show()in pinctrl-single driver whenbits_per_muxis not zero. In addition move offset calculation and pin offset in register to common function.Reviewed-by Andy Shevchenko<[email protected]>
Thanks
Quoted 15 lines
Quoted 15 lines
Fixes 4e7e8017a80e ("pinctrl: pinctrl-single: enhance to configure multiple pins of different modules")Signed-off-by Hanna Hawa<[email protected]>--- drivers/pinctrl/pinctrl-single.c | 57 +++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 20 deletions(-)drivers/pinctrl/pinctrl-single.c +0
-0@@ -270,20 +270,46 @@ static void __maybe_unused pcs_writel(unsigned val, void __iomem *reg)writel (val, reg); }
Quoted 7 lines
drivers/pinctrl/pinctrl-single.c static void __maybe_unused pcs_writel(unsigned val, void __iomem *reg) · line 278
Quoted 6 lines
drivers/pinctrl/pinctrl-single.c +6
-0+static unsigned int pcs_pin_reg_offset_get (struct pcs_device *pcs, +unsigned int pin) +{ +unsigned int mux_bytes; + + mux_bytes = pcs->width /BITS_PER_BYTE ;Can be folded to one line.
Ack
Quoted 10 lines
drivers/pinctrl/pinctrl-single.c static void __maybe_unused pcs_writel(unsigned val, void __iomem *reg) · line 284
Quoted 6 lines
drivers/pinctrl/pinctrl-single.c +5
-0+if (pcs->bits_per_mux) { +unsigned int pin_offset_bytes; + + pin_offset_bytes = (pcs->bits_per_pin * pin) /BITS_PER_BYTE ; +return (pin_offset_bytes / mux_bytes) * mux_bytes;Side note for the further improvements (in a separate change, because I see that you just copied an original code, and after all this is just a fix patch): this can be replaced by round down APIs (one which works for arbitrary divisors).
Agree, didn't want to change the formula as it's fix patch. (here and below), this can be taken for further improvements.
Quoted 12 lines
drivers/pinctrl/pinctrl-single.c static void __maybe_unused pcs_writel(unsigned val, void __iomem *reg) · line 293
Quoted 10 lines
drivers/pinctrl/pinctrl-single.c +9
-0+ } + +return pin * mux_bytes; +} + +static unsigned int pcs_pin_shift_reg_get (struct pcs_device *pcs, +unsigned int pin) +{ +return (pin % (pcs->width / pcs->bits_per_pin)) * pcs->bits_per_pin;Also a side note: I'm wondering if this can be optimized to have less divisions.
Quoted 6 lines
drivers/pinctrl/pinctrl-single.c static void __maybe_unused pcs_writel(unsigned val, void __iomem *reg) · line 299
Quoted 6 lines
drivers/pinctrl/pinctrl-single.c +2
-0+} +static void pcs_pin_dbg_show (struct pinctrl_dev *pctldev,struct seq_file *s,unsigned pin) {
Thanks,
Hanna
Re: [PATCH v3 3/3] pinctrl: pinctrl-single: fix pcs_pin_dbg_show() when bits_per_mux is not zero
Quoted 9 lines · Hanna
Quoted 5 lines · Andy Shevchenko
Quoted 1 line · Hanna Hawa
An SError was detected when trying to print the supported pins in a
What is SError? Yes, I have read a discussion, but here is the hint:
if a person sees this as a first text due to, for example, bisecting an issue, what she/he can get from this cryptic name?What you suggest?
s/An SError/A kernel-panic/?
Not below, but something which makes clear what SError is.
Like "A System Error (SError, followed by kernel panic) ..."
Quoted 6 lines
Or remove the sentence and keep the below:
"
This change fixes thepcs_pin_dbg_show()in pinctrl-single driver whenbits_per_muxis not zero. In addition move offset calculation and pin offset in register to common function.
"
Signature · 2 lines
With Best Regards, Andy Shevchenko