Skip to content

Commit 3de7dee

Browse files
Light Hsiehlinusw
authored andcommitted
pinctrl: mediatek: Check gpio pin number and use binary search in mtk_hw_pin_field_lookup()
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. Improve mtk_hw_pin_field_lookup() 2.1 Modify mtk_hw_pin_field_lookup() to use binary search for accelerating search. 2.2 Correct message after the following check fail: if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) { rc = &hw->soc->reg_cal[field]; The original message is: "Not support field %d for pin %d (%s)\n" However, the check is on soc chip level, not on pin level yet. So the message is corrected as: "Not support field %d for this soc\n" Signed-off-by: Light Hsieh <[email protected]> Link: https://lore.kernel.org/r/[email protected] Acked-by: Sean Wang <[email protected]> Signed-off-by: Linus Walleij <[email protected]>
1 parent ef1ea54 commit 3de7dee

File tree

2 files changed

+46
-6
lines changed

2 files changed

+46
-6
lines changed

drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,32 +68,44 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
6868
{
6969
const struct mtk_pin_field_calc *c, *e;
7070
const struct mtk_pin_reg_calc *rc;
71+
int start = 0, end, check;
72+
bool found = false;
7173
u32 bits;
7274

7375
if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) {
7476
rc = &hw->soc->reg_cal[field];
7577
} else {
7678
dev_dbg(hw->dev,
77-
"Not support field %d for pin %d (%s)\n",
78-
field, desc->number, desc->name);
79+
"Not support field %d for this soc\n", field);
7980
return -ENOTSUPP;
8081
}
8182

83+
end = rc->nranges - 1;
8284
c = rc->range;
8385
e = c + rc->nranges;
8486

85-
while (c < e) {
86-
if (desc->number >= c->s_pin && desc->number <= c->e_pin)
87+
while (start <= end) {
88+
check = (start + end) >> 1;
89+
if (desc->number >= rc->range[check].s_pin
90+
&& desc->number <= rc->range[check].e_pin) {
91+
found = true;
92+
break;
93+
} else if (start == end)
8794
break;
88-
c++;
95+
else if (desc->number < rc->range[check].s_pin)
96+
end = check - 1;
97+
else
98+
start = check + 1;
8999
}
90100

91-
if (c >= e) {
101+
if (!found) {
92102
dev_dbg(hw->dev, "Not support field %d for pin = %d (%s)\n",
93103
field, desc->number, desc->name);
94104
return -ENOTSUPP;
95105
}
96106

107+
c = rc->range + check;
108+
97109
if (c->i_base > hw->nbase - 1) {
98110
dev_err(hw->dev,
99111
"Invalid base for field %d for pin = %d (%s)\n",
@@ -182,6 +194,9 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
182194
if (err)
183195
return err;
184196

197+
if (value < 0 || value > pf.mask)
198+
return -EINVAL;
199+
185200
if (!pf.next)
186201
mtk_rmw(hw, pf.index, pf.offset, pf.mask << pf.bitpos,
187202
(value & pf.mask) << pf.bitpos);

drivers/pinctrl/mediatek/pinctrl-paris.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
8181
int val, val2, err, reg, ret = 1;
8282
const struct mtk_pin_desc *desc;
8383

84+
if (pin >= hw->soc->npins)
85+
return -EINVAL;
8486
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
8587

8688
switch (param) {
@@ -206,6 +208,10 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
206208
int err = 0;
207209
u32 reg;
208210

211+
if (pin >= hw->soc->npins) {
212+
err = -EINVAL;
213+
goto err;
214+
}
209215
desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin];
210216

211217
switch ((u32)param) {
@@ -693,6 +699,9 @@ static int mtk_gpio_get_direction(struct gpio_chip *chip, unsigned int gpio)
693699
const struct mtk_pin_desc *desc;
694700
int value, err;
695701

702+
if (gpio > hw->soc->npins)
703+
return -EINVAL;
704+
696705
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
697706

698707
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &value);
@@ -708,6 +717,9 @@ static int mtk_gpio_get(struct gpio_chip *chip, unsigned int gpio)
708717
const struct mtk_pin_desc *desc;
709718
int value, err;
710719

720+
if (gpio > hw->soc->npins)
721+
return -EINVAL;
722+
711723
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
712724

713725
err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value);
@@ -722,19 +734,32 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value)
722734
struct mtk_pinctrl *hw = gpiochip_get_data(chip);
723735
const struct mtk_pin_desc *desc;
724736

737+
if (gpio > hw->soc->npins)
738+
return;
739+
725740
desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
726741

727742
mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, !!value);
728743
}
729744

730745
static int mtk_gpio_direction_input(struct gpio_chip *chip, unsigned int gpio)
731746
{
747+
struct mtk_pinctrl *hw = gpiochip_get_data(chip);
748+
749+
if (gpio > hw->soc->npins)
750+
return -EINVAL;
751+
732752
return pinctrl_gpio_direction_input(chip->base + gpio);
733753
}
734754

735755
static int mtk_gpio_direction_output(struct gpio_chip *chip, unsigned int gpio,
736756
int value)
737757
{
758+
struct mtk_pinctrl *hw = gpiochip_get_data(chip);
759+
760+
if (gpio > hw->soc->npins)
761+
return -EINVAL;
762+
738763
mtk_gpio_set(chip, gpio, value);
739764

740765
return pinctrl_gpio_direction_output(chip->base + gpio);

0 commit comments

Comments
 (0)