pinctrl: add some error checking for user interfaces
This patch can avoid kernel oops in case the mux or config function is not supported by driver. Acked-by: Stephen Warren <swarren@wwwdotorg.org> Signed-off-by: Dong Aisheng <dong.aisheng@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
committed by
Linus Walleij
parent
a1d31f71e6
commit
ad8bb720c2
@@ -448,8 +448,12 @@ static void pinconf_dump_pin(struct pinctrl_dev *pctldev,
|
|||||||
static int pinconf_pins_show(struct seq_file *s, void *what)
|
static int pinconf_pins_show(struct seq_file *s, void *what)
|
||||||
{
|
{
|
||||||
struct pinctrl_dev *pctldev = s->private;
|
struct pinctrl_dev *pctldev = s->private;
|
||||||
|
const struct pinconf_ops *ops = pctldev->desc->confops;
|
||||||
unsigned i, pin;
|
unsigned i, pin;
|
||||||
|
|
||||||
|
if (!ops || !ops->pin_config_get)
|
||||||
|
return 0;
|
||||||
|
|
||||||
seq_puts(s, "Pin config settings per pin\n");
|
seq_puts(s, "Pin config settings per pin\n");
|
||||||
seq_puts(s, "Format: pin (name): pinmux setting array\n");
|
seq_puts(s, "Format: pin (name): pinmux setting array\n");
|
||||||
|
|
||||||
|
@@ -323,6 +323,11 @@ int pinmux_map_to_setting(struct pinctrl_map const *map,
|
|||||||
const unsigned *pins;
|
const unsigned *pins;
|
||||||
unsigned num_pins;
|
unsigned num_pins;
|
||||||
|
|
||||||
|
if (!pmxops) {
|
||||||
|
dev_err(pctldev->dev, "does not support mux function\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
setting->data.mux.func =
|
setting->data.mux.func =
|
||||||
pinmux_func_name_to_selector(pctldev, map->data.mux.function);
|
pinmux_func_name_to_selector(pctldev, map->data.mux.function);
|
||||||
if (setting->data.mux.func < 0)
|
if (setting->data.mux.func < 0)
|
||||||
@@ -481,11 +486,14 @@ static int pinmux_functions_show(struct seq_file *s, void *what)
|
|||||||
{
|
{
|
||||||
struct pinctrl_dev *pctldev = s->private;
|
struct pinctrl_dev *pctldev = s->private;
|
||||||
const struct pinmux_ops *pmxops = pctldev->desc->pmxops;
|
const struct pinmux_ops *pmxops = pctldev->desc->pmxops;
|
||||||
unsigned nfuncs = pmxops->get_functions_count(pctldev);
|
unsigned nfuncs;
|
||||||
unsigned func_selector = 0;
|
unsigned func_selector = 0;
|
||||||
|
|
||||||
mutex_lock(&pinctrl_mutex);
|
if (!pmxops)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
mutex_lock(&pinctrl_mutex);
|
||||||
|
nfuncs = pmxops->get_functions_count(pctldev);
|
||||||
while (func_selector < nfuncs) {
|
while (func_selector < nfuncs) {
|
||||||
const char *func = pmxops->get_function_name(pctldev,
|
const char *func = pmxops->get_function_name(pctldev,
|
||||||
func_selector);
|
func_selector);
|
||||||
@@ -520,6 +528,9 @@ static int pinmux_pins_show(struct seq_file *s, void *what)
|
|||||||
const struct pinmux_ops *pmxops = pctldev->desc->pmxops;
|
const struct pinmux_ops *pmxops = pctldev->desc->pmxops;
|
||||||
unsigned i, pin;
|
unsigned i, pin;
|
||||||
|
|
||||||
|
if (!pmxops)
|
||||||
|
return 0;
|
||||||
|
|
||||||
seq_puts(s, "Pinmux settings per pin\n");
|
seq_puts(s, "Pinmux settings per pin\n");
|
||||||
seq_puts(s, "Format: pin (name): mux_owner gpio_owner hog?\n");
|
seq_puts(s, "Format: pin (name): mux_owner gpio_owner hog?\n");
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user