aboutsummaryrefslogtreecommitdiff
path: root/drivers/pinctrl/pinmux.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pinctrl/pinmux.c')
-rw-r--r--drivers/pinctrl/pinmux.c80
1 files changed, 55 insertions, 25 deletions
diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
index bd83c8b01cd..051e8592990 100644
--- a/drivers/pinctrl/pinmux.c
+++ b/drivers/pinctrl/pinmux.c
@@ -391,19 +391,25 @@ int pinmux_enable_setting(struct pinctrl_setting const *setting)
struct pinctrl_dev *pctldev = setting->pctldev;
const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
const struct pinmux_ops *ops = pctldev->desc->pmxops;
- int ret;
- const unsigned *pins;
- unsigned num_pins;
+ int ret = 0;
+ const unsigned *pins = NULL;
+ unsigned num_pins = 0;
int i;
struct pin_desc *desc;
- ret = pctlops->get_group_pins(pctldev, setting->data.mux.group,
- &pins, &num_pins);
+ if (pctlops->get_group_pins)
+ ret = pctlops->get_group_pins(pctldev, setting->data.mux.group,
+ &pins, &num_pins);
+
if (ret) {
+ const char *gname;
+
/* errors only affect debug data, so just warn */
+ gname = pctlops->get_group_name(pctldev,
+ setting->data.mux.group);
dev_warn(pctldev->dev,
- "could not get pins for group selector %d\n",
- setting->data.mux.group);
+ "could not get pins for group %s\n",
+ gname);
num_pins = 0;
}
@@ -411,9 +417,18 @@ int pinmux_enable_setting(struct pinctrl_setting const *setting)
for (i = 0; i < num_pins; i++) {
ret = pin_request(pctldev, pins[i], setting->dev_name, NULL);
if (ret) {
+ const char *gname;
+ const char *pname;
+
+ desc = pin_desc_get(pctldev, pins[i]);
+ pname = desc ? desc->name : "non-existing";
+ gname = pctlops->get_group_name(pctldev,
+ setting->data.mux.group);
dev_err(pctldev->dev,
- "could not request pin %d on device %s\n",
- pins[i], pinctrl_dev_get_name(pctldev));
+ "could not request pin %d (%s) from group %s "
+ " on device %s\n",
+ pins[i], pname, gname,
+ pinctrl_dev_get_name(pctldev));
goto err_pin_request;
}
}
@@ -457,19 +472,24 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting)
struct pinctrl_dev *pctldev = setting->pctldev;
const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
const struct pinmux_ops *ops = pctldev->desc->pmxops;
- int ret;
- const unsigned *pins;
- unsigned num_pins;
+ int ret = 0;
+ const unsigned *pins = NULL;
+ unsigned num_pins = 0;
int i;
struct pin_desc *desc;
- ret = pctlops->get_group_pins(pctldev, setting->data.mux.group,
- &pins, &num_pins);
+ if (pctlops->get_group_pins)
+ ret = pctlops->get_group_pins(pctldev, setting->data.mux.group,
+ &pins, &num_pins);
if (ret) {
+ const char *gname;
+
/* errors only affect debug data, so just warn */
+ gname = pctlops->get_group_name(pctldev,
+ setting->data.mux.group);
dev_warn(pctldev->dev,
- "could not get pins for group selector %d\n",
- setting->data.mux.group);
+ "could not get pins for group %s\n",
+ gname);
num_pins = 0;
}
@@ -482,12 +502,22 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting)
pins[i]);
continue;
}
- desc->mux_setting = NULL;
- }
+ if (desc->mux_setting == &(setting->data.mux)) {
+ desc->mux_setting = NULL;
+ /* And release the pin */
+ pin_free(pctldev, pins[i], NULL);
+ } else {
+ const char *gname;
- /* And release the pins */
- for (i = 0; i < num_pins; i++)
- pin_free(pctldev, pins[i], NULL);
+ gname = pctlops->get_group_name(pctldev,
+ setting->data.mux.group);
+ dev_warn(pctldev->dev,
+ "not freeing pin %d (%s) as part of "
+ "deactivating group %s - it is already "
+ "used for some other setting",
+ pins[i], desc->name, gname);
+ }
+ }
if (ops->disable)
ops->disable(pctldev, setting->data.mux.func, setting->data.mux.group);
@@ -506,7 +536,7 @@ static int pinmux_functions_show(struct seq_file *s, void *what)
if (!pmxops)
return 0;
- mutex_lock(&pinctrl_mutex);
+ mutex_lock(&pctldev->mutex);
nfuncs = pmxops->get_functions_count(pctldev);
while (func_selector < nfuncs) {
const char *func = pmxops->get_function_name(pctldev,
@@ -530,7 +560,7 @@ static int pinmux_functions_show(struct seq_file *s, void *what)
func_selector++;
}
- mutex_unlock(&pinctrl_mutex);
+ mutex_unlock(&pctldev->mutex);
return 0;
}
@@ -548,7 +578,7 @@ static int pinmux_pins_show(struct seq_file *s, void *what)
seq_puts(s, "Pinmux settings per pin\n");
seq_puts(s, "Format: pin (name): mux_owner gpio_owner hog?\n");
- mutex_lock(&pinctrl_mutex);
+ mutex_lock(&pctldev->mutex);
/* The pin number can be retrived from the pin controller descriptor */
for (i = 0; i < pctldev->desc->npins; i++) {
@@ -583,7 +613,7 @@ static int pinmux_pins_show(struct seq_file *s, void *what)
seq_printf(s, "\n");
}
- mutex_unlock(&pinctrl_mutex);
+ mutex_unlock(&pctldev->mutex);
return 0;
}