Commit 5d2eaf80 authored by Stephen Warren's avatar Stephen Warren Committed by Linus Walleij

pinctrl: Don't copy function name when requesting a pin

Instead, store a pointer to the currently assigned function.

This allows us to delete the mux_requested variable from pin_desc; a pin
is requested if its currently assigned function is non-NULL.

When a pin is requested as a GPIO rather than a regular function, the
assigned function name is dynamically constructed. In this case, we have
to kstrdup() the dynamically constructed name, so that mux_function doesn't
pointed at stack data. This requires pin_free to be told whether to free
the mux_function pointer or not.

This removes the hard-coded maximum function name length.
Signed-off-by: default avatarStephen Warren <swarren@nvidia.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 9af1e44f
...@@ -59,8 +59,7 @@ struct pin_desc { ...@@ -59,8 +59,7 @@ struct pin_desc {
spinlock_t lock; spinlock_t lock;
/* These fields only added when supporting pinmux drivers */ /* These fields only added when supporting pinmux drivers */
#ifdef CONFIG_PINMUX #ifdef CONFIG_PINMUX
bool mux_requested; const char *mux_function;
char mux_function[16];
#endif #endif
}; };
......
...@@ -130,14 +130,13 @@ static int pin_request(struct pinctrl_dev *pctldev, ...@@ -130,14 +130,13 @@ static int pin_request(struct pinctrl_dev *pctldev,
} }
spin_lock(&desc->lock); spin_lock(&desc->lock);
if (desc->mux_requested) { if (desc->mux_function) {
spin_unlock(&desc->lock); spin_unlock(&desc->lock);
dev_err(&pctldev->dev, dev_err(&pctldev->dev,
"pin already requested\n"); "pin already requested\n");
goto out; goto out;
} }
desc->mux_requested = true; desc->mux_function = function;
strncpy(desc->mux_function, function, sizeof(desc->mux_function));
spin_unlock(&desc->lock); spin_unlock(&desc->lock);
/* Let each pin increase references to this module */ /* Let each pin increase references to this module */
...@@ -168,8 +167,7 @@ static int pin_request(struct pinctrl_dev *pctldev, ...@@ -168,8 +167,7 @@ static int pin_request(struct pinctrl_dev *pctldev,
out_free_pin: out_free_pin:
if (status) { if (status) {
spin_lock(&desc->lock); spin_lock(&desc->lock);
desc->mux_requested = false; desc->mux_function = NULL;
desc->mux_function[0] = '\0';
spin_unlock(&desc->lock); spin_unlock(&desc->lock);
} }
out: out:
...@@ -184,8 +182,9 @@ static int pin_request(struct pinctrl_dev *pctldev, ...@@ -184,8 +182,9 @@ static int pin_request(struct pinctrl_dev *pctldev,
* pin_free() - release a single muxed in pin so something else can be muxed * pin_free() - release a single muxed in pin so something else can be muxed
* @pctldev: pin controller device handling this pin * @pctldev: pin controller device handling this pin
* @pin: the pin to free * @pin: the pin to free
* @free_func: whether to free the pin's assigned function name string
*/ */
static void pin_free(struct pinctrl_dev *pctldev, int pin) static void pin_free(struct pinctrl_dev *pctldev, int pin, int free_func)
{ {
const struct pinmux_ops *ops = pctldev->desc->pmxops; const struct pinmux_ops *ops = pctldev->desc->pmxops;
struct pin_desc *desc; struct pin_desc *desc;
...@@ -201,8 +200,9 @@ static void pin_free(struct pinctrl_dev *pctldev, int pin) ...@@ -201,8 +200,9 @@ static void pin_free(struct pinctrl_dev *pctldev, int pin)
ops->free(pctldev, pin); ops->free(pctldev, pin);
spin_lock(&desc->lock); spin_lock(&desc->lock);
desc->mux_requested = false; if (free_func)
desc->mux_function[0] = '\0'; kfree(desc->mux_function);
desc->mux_function = NULL;
spin_unlock(&desc->lock); spin_unlock(&desc->lock);
module_put(pctldev->owner); module_put(pctldev->owner);
} }
...@@ -214,6 +214,7 @@ static void pin_free(struct pinctrl_dev *pctldev, int pin) ...@@ -214,6 +214,7 @@ static void pin_free(struct pinctrl_dev *pctldev, int pin)
int pinmux_request_gpio(unsigned gpio) int pinmux_request_gpio(unsigned gpio)
{ {
char gpiostr[16]; char gpiostr[16];
const char *function;
struct pinctrl_dev *pctldev; struct pinctrl_dev *pctldev;
struct pinctrl_gpio_range *range; struct pinctrl_gpio_range *range;
int ret; int ret;
...@@ -229,7 +230,15 @@ int pinmux_request_gpio(unsigned gpio) ...@@ -229,7 +230,15 @@ int pinmux_request_gpio(unsigned gpio)
/* Conjure some name stating what chip and pin this is taken by */ /* Conjure some name stating what chip and pin this is taken by */
snprintf(gpiostr, 15, "%s:%d", range->name, gpio); snprintf(gpiostr, 15, "%s:%d", range->name, gpio);
return pin_request(pctldev, pin, gpiostr, true, range); function = kstrdup(gpiostr, GFP_KERNEL);
if (!function)
return -EINVAL;
ret = pin_request(pctldev, pin, function, true, range);
if (ret < 0)
kfree(function);
return ret;
} }
EXPORT_SYMBOL_GPL(pinmux_request_gpio); EXPORT_SYMBOL_GPL(pinmux_request_gpio);
...@@ -251,7 +260,7 @@ void pinmux_free_gpio(unsigned gpio) ...@@ -251,7 +260,7 @@ void pinmux_free_gpio(unsigned gpio)
/* Convert to the pin controllers number space */ /* Convert to the pin controllers number space */
pin = gpio - range->base; pin = gpio - range->base;
pin_free(pctldev, pin); pin_free(pctldev, pin, true);
} }
EXPORT_SYMBOL_GPL(pinmux_free_gpio); EXPORT_SYMBOL_GPL(pinmux_free_gpio);
...@@ -351,7 +360,7 @@ static int acquire_pins(struct pinctrl_dev *pctldev, ...@@ -351,7 +360,7 @@ static int acquire_pins(struct pinctrl_dev *pctldev,
/* On error release all taken pins */ /* On error release all taken pins */
i--; /* this pin just failed */ i--; /* this pin just failed */
for (; i >= 0; i--) for (; i >= 0; i--)
pin_free(pctldev, pins[i]); pin_free(pctldev, pins[i], false);
return -ENODEV; return -ENODEV;
} }
} }
...@@ -381,7 +390,7 @@ static void release_pins(struct pinctrl_dev *pctldev, ...@@ -381,7 +390,7 @@ static void release_pins(struct pinctrl_dev *pctldev,
return; return;
} }
for (i = 0; i < num_pins; i++) for (i = 0; i < num_pins; i++)
pin_free(pctldev, pins[i]); pin_free(pctldev, pins[i], false);
} }
/** /**
...@@ -1013,7 +1022,8 @@ static int pinmux_pins_show(struct seq_file *s, void *what) ...@@ -1013,7 +1022,8 @@ static int pinmux_pins_show(struct seq_file *s, void *what)
seq_printf(s, "pin %d (%s): %s\n", pin, seq_printf(s, "pin %d (%s): %s\n", pin,
desc->name ? desc->name : "unnamed", desc->name ? desc->name : "unnamed",
desc->mux_requested ? desc->mux_function : "UNCLAIMED"); desc->mux_function ? desc->mux_function
: "UNCLAIMED");
} }
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment