Merge branch 'for-torvalds' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl

Here are some fixes to the pin control system that has accumulated since
-rc1.  Mainly Tony Lindgren fixed the module load/unload logic and the
rest are minor fixes and documentation.

* 'for-torvalds' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl:
  pinctrl: add checks for empty function names
  pinctrl: fix pinmux_hog_maps when ctrl_dev_name is not set
  pinctrl: fix some pinmux typos
  pinctrl: free debugfs entries when unloading a pinmux driver
  pinctrl: unbreak error messages
  Documentation/pinctrl: fix a few syntax errors in code examples
  pinctrl: fix pinconf_pins_show iteration
This commit is contained in:
Linus Torvalds 2012-01-30 17:06:26 -08:00
commit 8e2a2880a5
7 changed files with 95 additions and 74 deletions

View File

@ -857,42 +857,41 @@ case), we define a mapping like this:
...
{
.name "2bit"
.name = "2bit"
.ctrl_dev_name = "pinctrl-foo",
.function = "mmc0",
.group = "mmc0_1_grp",
.dev_name = "foo-mmc.0",
},
{
.name "4bit"
.name = "4bit"
.ctrl_dev_name = "pinctrl-foo",
.function = "mmc0",
.group = "mmc0_1_grp",
.dev_name = "foo-mmc.0",
},
{
.name "4bit"
.name = "4bit"
.ctrl_dev_name = "pinctrl-foo",
.function = "mmc0",
.group = "mmc0_2_grp",
.dev_name = "foo-mmc.0",
},
{
.name "8bit"
.name = "8bit"
.ctrl_dev_name = "pinctrl-foo",
.function = "mmc0",
.group = "mmc0_1_grp",
.dev_name = "foo-mmc.0",
},
{
.name "8bit"
.name = "8bit"
.ctrl_dev_name = "pinctrl-foo",
.function = "mmc0",
.group = "mmc0_2_grp",
.dev_name = "foo-mmc.0",
},
{
.name "8bit"
.name = "8bit"
.ctrl_dev_name = "pinctrl-foo",
.function = "mmc0",
.group = "mmc0_3_grp",
@ -995,7 +994,7 @@ This is enabled by simply setting the .hog_on_boot field in the map to true,
like this:
{
.name "POWERMAP"
.name = "POWERMAP"
.ctrl_dev_name = "pinctrl-foo",
.function = "power_func",
.hog_on_boot = true,
@ -1025,7 +1024,7 @@ it, disables and releases it, and muxes it in on the pins defined by group B:
foo_switch()
{
struct pinmux pmx;
struct pinmux *pmx;
/* Enable on position A */
pmx = pinmux_get(&device, "spi0-pos-A");

View File

@ -510,10 +510,12 @@ static struct dentry *debugfs_root;
static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev)
{
static struct dentry *device_root;
struct dentry *device_root;
device_root = debugfs_create_dir(dev_name(pctldev->dev),
debugfs_root);
pctldev->device_root = device_root;
if (IS_ERR(device_root) || !device_root) {
pr_warn("failed to create debugfs directory for %s\n",
dev_name(pctldev->dev));
@ -529,6 +531,11 @@ static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev)
pinconf_init_device_debugfs(device_root, pctldev);
}
static void pinctrl_remove_device_debugfs(struct pinctrl_dev *pctldev)
{
debugfs_remove_recursive(pctldev->device_root);
}
static void pinctrl_init_debugfs(void)
{
debugfs_root = debugfs_create_dir("pinctrl", NULL);
@ -553,6 +560,10 @@ static void pinctrl_init_debugfs(void)
{
}
static void pinctrl_remove_device_debugfs(struct pinctrl_dev *pctldev)
{
}
#endif
/**
@ -572,26 +583,6 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
if (pctldesc->name == NULL)
return NULL;
/* If we're implementing pinmuxing, check the ops for sanity */
if (pctldesc->pmxops) {
ret = pinmux_check_ops(pctldesc->pmxops);
if (ret) {
pr_err("%s pinmux ops lacks necessary functions\n",
pctldesc->name);
return NULL;
}
}
/* If we're implementing pinconfig, check the ops for sanity */
if (pctldesc->confops) {
ret = pinconf_check_ops(pctldesc->confops);
if (ret) {
pr_err("%s pin config ops lacks necessary functions\n",
pctldesc->name);
return NULL;
}
}
pctldev = kzalloc(sizeof(struct pinctrl_dev), GFP_KERNEL);
if (pctldev == NULL)
return NULL;
@ -606,6 +597,26 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
mutex_init(&pctldev->gpio_ranges_lock);
pctldev->dev = dev;
/* If we're implementing pinmuxing, check the ops for sanity */
if (pctldesc->pmxops) {
ret = pinmux_check_ops(pctldev);
if (ret) {
pr_err("%s pinmux ops lacks necessary functions\n",
pctldesc->name);
goto out_err;
}
}
/* If we're implementing pinconfig, check the ops for sanity */
if (pctldesc->confops) {
ret = pinconf_check_ops(pctldev);
if (ret) {
pr_err("%s pin config ops lacks necessary functions\n",
pctldesc->name);
goto out_err;
}
}
/* Register all the pins */
pr_debug("try to register %d pins on %s...\n",
pctldesc->npins, pctldesc->name);
@ -641,6 +652,7 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev)
if (pctldev == NULL)
return;
pinctrl_remove_device_debugfs(pctldev);
pinmux_unhog_maps(pctldev);
/* TODO: check that no pinmuxes are still active? */
mutex_lock(&pinctrldev_list_mutex);

View File

@ -41,6 +41,9 @@ struct pinctrl_dev {
struct device *dev;
struct module *owner;
void *driver_data;
#ifdef CONFIG_DEBUG_FS
struct dentry *device_root;
#endif
#ifdef CONFIG_PINMUX
struct mutex pinmux_hogs_lock;
struct list_head pinmux_hogs;

View File

@ -205,8 +205,10 @@ int pin_config_group_set(const char *dev_name, const char *pin_group,
}
EXPORT_SYMBOL(pin_config_group_set);
int pinconf_check_ops(const struct pinconf_ops *ops)
int pinconf_check_ops(struct pinctrl_dev *pctldev)
{
const struct pinconf_ops *ops = pctldev->desc->confops;
/* We must be able to read out pin status */
if (!ops->pin_config_get && !ops->pin_config_group_get)
return -EINVAL;
@ -236,7 +238,7 @@ static int pinconf_pins_show(struct seq_file *s, void *what)
seq_puts(s, "Format: pin (name): pinmux setting array\n");
/* The pin number can be retrived from the pin controller descriptor */
for (i = 0; pin < pctldev->desc->npins; i++) {
for (i = 0; i < pctldev->desc->npins; i++) {
struct pin_desc *desc;
pin = pctldev->desc->pins[i].number;

View File

@ -13,7 +13,7 @@
#ifdef CONFIG_PINCONF
int pinconf_check_ops(const struct pinconf_ops *ops);
int pinconf_check_ops(struct pinctrl_dev *pctldev);
void pinconf_init_device_debugfs(struct dentry *devroot,
struct pinctrl_dev *pctldev);
int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
@ -23,7 +23,7 @@ int pin_config_set_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
#else
static inline int pinconf_check_ops(const struct pinconf_ops *ops)
static inline int pinconf_check_ops(struct pinctrl_dev *pctldev)
{
return 0;
}

View File

@ -53,11 +53,6 @@ struct pinmux_group {
* @dev: the device using this pinmux
* @usecount: the number of active users of this mux setting, used to keep
* track of nested use cases
* @pins: an array of discrete physical pins used in this mapping, taken
* from the global pin enumeration space (copied from pinmux map)
* @num_pins: the number of pins in this mapping array, i.e. the number of
* elements in .pins so we can iterate over that array (copied from
* pinmux map)
* @pctldev: pin control device handling this pinmux
* @func_selector: the function selector for the pinmux device handling
* this pinmux
@ -152,8 +147,7 @@ static int pin_request(struct pinctrl_dev *pctldev,
status = 0;
if (status)
dev_err(pctldev->dev, "->request on device %s failed "
"for pin %d\n",
dev_err(pctldev->dev, "->request on device %s failed for pin %d\n",
pctldev->desc->name, pin);
out_free_pin:
if (status) {
@ -355,21 +349,20 @@ int __init pinmux_register_mappings(struct pinmux_map const *maps,
/* First sanity check the new mapping */
for (i = 0; i < num_maps; i++) {
if (!maps[i].name) {
pr_err("failed to register map %d: "
"no map name given\n", i);
pr_err("failed to register map %d: no map name given\n",
i);
return -EINVAL;
}
if (!maps[i].ctrl_dev && !maps[i].ctrl_dev_name) {
pr_err("failed to register map %s (%d): "
"no pin control device given\n",
pr_err("failed to register map %s (%d): no pin control device given\n",
maps[i].name, i);
return -EINVAL;
}
if (!maps[i].function) {
pr_err("failed to register map %s (%d): "
"no function ID given\n", maps[i].name, i);
pr_err("failed to register map %s (%d): no function ID given\n",
maps[i].name, i);
return -EINVAL;
}
@ -411,7 +404,7 @@ int __init pinmux_register_mappings(struct pinmux_map const *maps,
}
/**
* acquire_pins() - acquire all the pins for a certain funcion on a pinmux
* acquire_pins() - acquire all the pins for a certain function on a pinmux
* @pctldev: the device to take the pins on
* @func_selector: the function selector to acquire the pins for
* @group_selector: the group selector containing the pins to acquire
@ -442,8 +435,7 @@ static int acquire_pins(struct pinctrl_dev *pctldev,
ret = pin_request(pctldev, pins[i], func, NULL);
if (ret) {
dev_err(pctldev->dev,
"could not get pin %d for function %s "
"on device %s - conflicting mux mappings?\n",
"could not get pin %d for function %s on device %s - conflicting mux mappings?\n",
pins[i], func ? : "(undefined)",
pinctrl_dev_get_name(pctldev));
/* On error release all taken pins */
@ -458,7 +450,7 @@ static int acquire_pins(struct pinctrl_dev *pctldev,
/**
* release_pins() - release pins taken by earlier acquirement
* @pctldev: the device to free the pinx on
* @pctldev: the device to free the pins on
* @group_selector: the group selector containing the pins to free
*/
static void release_pins(struct pinctrl_dev *pctldev,
@ -473,8 +465,7 @@ static void release_pins(struct pinctrl_dev *pctldev,
ret = pctlops->get_group_pins(pctldev, group_selector,
&pins, &num_pins);
if (ret) {
dev_err(pctldev->dev, "could not get pins to release for "
"group selector %d\n",
dev_err(pctldev->dev, "could not get pins to release for group selector %d\n",
group_selector);
return;
}
@ -526,8 +517,7 @@ static int pinmux_check_pin_group(struct pinctrl_dev *pctldev,
ret = pinctrl_get_group_selector(pctldev, groups[0]);
if (ret < 0) {
dev_err(pctldev->dev,
"function %s wants group %s but the pin "
"controller does not seem to have that group\n",
"function %s wants group %s but the pin controller does not seem to have that group\n",
pmxops->get_function_name(pctldev, func_selector),
groups[0]);
return ret;
@ -535,8 +525,7 @@ static int pinmux_check_pin_group(struct pinctrl_dev *pctldev,
if (num_groups > 1)
dev_dbg(pctldev->dev,
"function %s support more than one group, "
"default-selecting first group %s (%d)\n",
"function %s support more than one group, default-selecting first group %s (%d)\n",
pmxops->get_function_name(pctldev, func_selector),
groups[0],
ret);
@ -628,10 +617,8 @@ static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev,
if (pmx->pctldev && pmx->pctldev != pctldev) {
dev_err(pctldev->dev,
"different pin control devices given for device %s, "
"function %s\n",
devname,
map->function);
"different pin control devices given for device %s, function %s\n",
devname, map->function);
return -EINVAL;
}
pmx->dev = dev;
@ -695,7 +682,6 @@ static void pinmux_free_groups(struct pinmux *pmx)
*/
struct pinmux *pinmux_get(struct device *dev, const char *name)
{
struct pinmux_map const *map = NULL;
struct pinctrl_dev *pctldev = NULL;
const char *devname = NULL;
@ -745,8 +731,7 @@ struct pinmux *pinmux_get(struct device *dev, const char *name)
else if (map->ctrl_dev_name)
devname = map->ctrl_dev_name;
pr_warning("could not find a pinctrl device for pinmux "
"function %s, fishy, they shall all have one\n",
pr_warning("could not find a pinctrl device for pinmux function %s, fishy, they shall all have one\n",
map->function);
pr_warning("given pinctrl device name: %s",
devname ? devname : "UNDEFINED");
@ -904,8 +889,11 @@ void pinmux_disable(struct pinmux *pmx)
}
EXPORT_SYMBOL_GPL(pinmux_disable);
int pinmux_check_ops(const struct pinmux_ops *ops)
int pinmux_check_ops(struct pinctrl_dev *pctldev)
{
const struct pinmux_ops *ops = pctldev->desc->pmxops;
unsigned selector = 0;
/* Check that we implement required operations */
if (!ops->list_functions ||
!ops->get_function_name ||
@ -914,6 +902,18 @@ int pinmux_check_ops(const struct pinmux_ops *ops)
!ops->disable)
return -EINVAL;
/* Check that all functions registered have names */
while (ops->list_functions(pctldev, selector) >= 0) {
const char *fname = ops->get_function_name(pctldev,
selector);
if (!fname) {
pr_err("pinmux ops has no name for function%u\n",
selector);
return -EINVAL;
}
selector++;
}
return 0;
}
@ -932,8 +932,8 @@ static int pinmux_hog_map(struct pinctrl_dev *pctldev,
* without any problems, so then we can hog pinmuxes for
* all devices that just want a static pin mux at this point.
*/
dev_err(pctldev->dev, "map %s wants to hog a non-system "
"pinmux, this is not going to work\n", map->name);
dev_err(pctldev->dev, "map %s wants to hog a non-system pinmux, this is not going to work\n",
map->name);
return -EINVAL;
}
@ -993,9 +993,12 @@ int pinmux_hog_maps(struct pinctrl_dev *pctldev)
for (i = 0; i < pinmux_maps_num; i++) {
struct pinmux_map const *map = &pinmux_maps[i];
if (((map->ctrl_dev == dev) ||
!strcmp(map->ctrl_dev_name, devname)) &&
map->hog_on_boot) {
if (!map->hog_on_boot)
continue;
if ((map->ctrl_dev == dev) ||
(map->ctrl_dev_name &&
!strcmp(map->ctrl_dev_name, devname))) {
/* OK time to hog! */
ret = pinmux_hog_map(pctldev, map);
if (ret)
@ -1122,13 +1125,15 @@ static int pinmux_show(struct seq_file *s, void *what)
seq_printf(s, "device: %s function: %s (%u),",
pinctrl_dev_get_name(pmx->pctldev),
pmxops->get_function_name(pctldev, pmx->func_selector),
pmxops->get_function_name(pctldev,
pmx->func_selector),
pmx->func_selector);
seq_printf(s, " groups: [");
list_for_each_entry(grp, &pmx->groups, node) {
seq_printf(s, " %s (%u)",
pctlops->get_group_name(pctldev, grp->group_selector),
pctlops->get_group_name(pctldev,
grp->group_selector),
grp->group_selector);
}
seq_printf(s, " ]");

View File

@ -12,7 +12,7 @@
*/
#ifdef CONFIG_PINMUX
int pinmux_check_ops(const struct pinmux_ops *ops);
int pinmux_check_ops(struct pinctrl_dev *pctldev);
void pinmux_init_device_debugfs(struct dentry *devroot,
struct pinctrl_dev *pctldev);
void pinmux_init_debugfs(struct dentry *subsys_root);
@ -21,7 +21,7 @@ void pinmux_unhog_maps(struct pinctrl_dev *pctldev);
#else
static inline int pinmux_check_ops(const struct pinmux_ops *ops)
static inline int pinmux_check_ops(struct pinctrl_dev *pctldev)
{
return 0;
}