All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jamie Iles <jamie@jamieiles.com>
To: Linus Walleij <linus.walleij@stericsson.com>
Cc: linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	Grant Likely <grant.likely@secretlab.ca>,
	Stephen Warren <swarren@nvidia.com>,
	Russell King <linux@arm.linux.org.uk>,
	Sascha Hauer <s.hauer@pengutronix.de>,
	Barry Song <21cnbao@gmail.com>, Joe Perches <joe@perches.com>,
	Linaro Dev <linaro-dev@lists.linaro.org>,
	David Brown <davidb@codeaurora.org>,
	Lee Jones <lee.jones@linaro.org>,
	Linus Walleij <linus.walleij@linaro.org>
Subject: Re: [PATCH 1/4 v5] drivers: create a pin control subsystem v5
Date: Tue, 30 Aug 2011 11:02:45 +0100	[thread overview]
Message-ID: <20110830100245.GD5414@pulham.picochip.com> (raw)
In-Reply-To: <1314609001-28052-1-git-send-email-linus.walleij@stericsson.com>

Hi Linus,

This is looking really great!  A couple of pedantic nits inline, but 
with the gpio ranges support I think this covers all of the bases that 
we need from pin control, so thanks!

Jamie

On Mon, Aug 29, 2011 at 11:10:01AM +0200, Linus Walleij wrote:
[...]
> diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
> new file mode 100644
> index 0000000..596ce9f
> --- /dev/null
> +++ b/drivers/pinctrl/Makefile
> @@ -0,0 +1,6 @@
> +# generic pinmux support
> +
> +ccflags-$(CONFIG_DEBUG_PINMUX)	+= -DDEBUG
> +
> +obj-$(CONFIG_PINCTRL)		+= core.o
> +obj-$(CONFIG_PINMUX)		+= pinmux.o
> diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
> new file mode 100644
> index 0000000..762e9e8
> --- /dev/null
> +++ b/drivers/pinctrl/core.c
> @@ -0,0 +1,539 @@
> +/*
> + * Core driver for the pin control subsystem
> + *
> + * Copyright (C) 2011 ST-Ericsson SA
> + * Written on behalf of Linaro for ST-Ericsson
> + * Based on bits of regulator core, gpio core and clk core
> + *
> + * Author: Linus Walleij <linus.walleij@linaro.org>
> + *
> + * License terms: GNU General Public License (GPL) version 2
> + */
> +#define pr_fmt(fmt) "pinctrl core: " fmt
> +
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/device.h>
> +#include <linux/slab.h>
> +#include <linux/radix-tree.h>
> +#include <linux/err.h>
> +#include <linux/list.h>
> +#include <linux/mutex.h>
> +#include <linux/spinlock.h>
> +#include <linux/sysfs.h>
> +#include <linux/debugfs.h>
> +#include <linux/seq_file.h>
> +#include <linux/pinctrl/pinctrl.h>
> +#include <linux/pinctrl/machine.h>
> +#include "core.h"
> +#include "pinmux.h"
> +
> +/* Global list of pin control devices */
> +static DEFINE_MUTEX(pinctrldev_list_mutex);
> +static LIST_HEAD(pinctrldev_list);
> +
> +/* sysfs interaction */
> +static ssize_t pinctrl_name_show(struct device *dev,
> +				struct device_attribute *attr, char *buf)
> +{
> +	struct pinctrl_dev *pctldev = dev_get_drvdata(dev);

As you have a struct device in pctldev, you should be able to do:

#define to_pinctrl_dev(__dev) \
	container_of(__dev, struct pinctrl_dev, dev)

struct pinctrl_dev *pctldev = to_pinctrl_dev(dev);

then you don't need to use the driver data.

[...]
> +static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev)
> +{
> +	static struct dentry *device_root;

Does device_root need to be static?

> +
> +	device_root = debugfs_create_dir(dev_name(&pctldev->dev),
> +					 debugfs_root);
> +	if (IS_ERR(device_root) || !device_root) {
> +		pr_warn("failed to create debugfs directory for %s\n",
> +			dev_name(&pctldev->dev));
> +		return;
> +	}
> +	debugfs_create_file("pins", S_IFREG | S_IRUGO,
> +			    device_root, pctldev, &pinctrl_pins_ops);
> +	debugfs_create_file("gpio-ranges", S_IFREG | S_IRUGO,
> +			    device_root, pctldev, &pinctrl_gpioranges_ops);
> +	pinmux_init_device_debugfs(device_root, pctldev);
> +}
> +
> +static void pinctrl_init_debugfs(void)
> +{
> +	debugfs_root = debugfs_create_dir("pinctrl", NULL);
> +	if (IS_ERR(debugfs_root) || !debugfs_root) {

IS_ERR_OR_NULL()?

> +		pr_warn("failed to create debugfs directory\n");
> +		debugfs_root = NULL;
> +		return;
> +	}
> +
> +	debugfs_create_file("pinctrl-devices", S_IFREG | S_IRUGO,
> +			    debugfs_root, NULL, &pinctrl_devices_ops);
> +	pinmux_init_debugfs(debugfs_root);
> +}
> +
> +#else /* CONFIG_DEBUG_FS */
> +
> +static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev)
> +{
> +}
> +
> +static void pinctrl_init_debugfs(void)
> +{
> +}
> +
> +#endif
> +
> +/**
> + * pinctrl_register() - register a pin controller device
> + * @pctldesc: descriptor for this pin controller
> + * @dev: parent device for this pin controller
> + * @driver_data: private pin controller data for this pin controller
> + */
> +struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
> +				    struct device *dev, void *driver_data)
> +{
> +	static atomic_t pinmux_no = ATOMIC_INIT(0);
> +	struct pinctrl_dev *pctldev;
> +	int ret;
> +
> +	if (pctldesc == NULL)
> +		return ERR_PTR(-EINVAL);
> +	if (pctldesc->name == NULL)
> +		return ERR_PTR(-EINVAL);
> +
> +	/* If we're implementing pinmuxing, check the ops for sanity */
> +	if (pctldesc->pmxops) {
> +		ret = pinmux_check_ops(pctldesc->pmxops);
> +		if (ret)
> +			return ERR_PTR(ret);
> +	}
> +
> +	pctldev = kzalloc(sizeof(struct pinctrl_dev), GFP_KERNEL);
> +	if (pctldev == NULL)
> +		return ERR_PTR(-ENOMEM);
> +
> +	/* Initialize pin control device struct */
> +	pctldev->owner = pctldesc->owner;
> +	pctldev->desc = pctldesc;
> +	pctldev->driver_data = driver_data;
> +	INIT_RADIX_TREE(&pctldev->pin_desc_tree, GFP_KERNEL);
> +	spin_lock_init(&pctldev->pin_desc_tree_lock);
> +	INIT_LIST_HEAD(&pctldev->gpio_ranges);
> +	spin_lock_init(&pctldev->gpio_ranges_lock);
> +
> +	/* Register device with sysfs */
> +	pctldev->dev.parent = dev;
> +	pctldev->dev.bus = &pinctrl_bus;
> +	pctldev->dev.type = &pinctrl_type;
> +	dev_set_name(&pctldev->dev, "pinctrl.%d",
> +		     atomic_inc_return(&pinmux_no) - 1);
> +	ret = device_register(&pctldev->dev);
> +	if (ret != 0) {
> +		pr_err("error in device registration\n");
> +		put_device(&pctldev->dev);
> +		kfree(pctldev);

I don't think you need the kfree() here as it should get called in the 
devices release method.

> +		goto out_err;
> +	}
> +	dev_set_drvdata(&pctldev->dev, pctldev);
> +
> +	/* Register all the pins */
> +	pr_debug("try to register %d pins on %s...\n",
> +		 pctldesc->npins, pctldesc->name);
> +	ret = pinctrl_register_pins(pctldev, pctldesc->pins, pctldesc->npins);
> +	if (ret) {
> +		pr_err("error during pin registration\n");
> +		pinctrl_free_pindescs(pctldev, pctldesc->pins,
> +				      pctldesc->npins);
> +		goto out_err;
> +	}
> +
> +	pinctrl_init_device_debugfs(pctldev);
> +	mutex_lock(&pinctrldev_list_mutex);
> +	list_add(&pctldev->node, &pinctrldev_list);
> +	mutex_unlock(&pinctrldev_list_mutex);
> +	return pctldev;
> +
> +out_err:
> +	put_device(&pctldev->dev);
> +	kfree(pctldev);

I think this needs to be a device_unregister() rather than put device, 
and the kfree() can be dropped.

Possibly also do a dev_set_drvdata(&pctldev->dev, NULL) here too?

> diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
> new file mode 100644
> index 0000000..310d344
> --- /dev/null
> +++ b/drivers/pinctrl/pinmux.c
> @@ -0,0 +1,811 @@
> +/*
> + * Core driver for the pin muxing portions of the pin control subsystem
> + *
> + * Copyright (C) 2011 ST-Ericsson SA
> + * Written on behalf of Linaro for ST-Ericsson
> + * Based on bits of regulator core, gpio core and clk core
> + *
> + * Author: Linus Walleij <linus.walleij@linaro.org>
> + *
> + * License terms: GNU General Public License (GPL) version 2
> + */
> +#define pr_fmt(fmt) "pinmux core: " fmt
> +
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/device.h>
> +#include <linux/slab.h>
> +#include <linux/radix-tree.h>
> +#include <linux/err.h>
> +#include <linux/list.h>
> +#include <linux/mutex.h>
> +#include <linux/spinlock.h>
> +#include <linux/sysfs.h>
> +#include <linux/debugfs.h>
> +#include <linux/seq_file.h>
> +#include <linux/pinctrl/machine.h>
> +#include <linux/pinctrl/pinmux.h>
> +#include "core.h"
> +
> +/* Global list of pinmuxes */
> +static DEFINE_MUTEX(pinmux_list_mutex);
> +static LIST_HEAD(pinmux_list);
> +
> +/**
> + * struct pinmux - per-device pinmux state holder
> + * @node: global list node - only for internal use
> + * @dev: the device using this pinmux
> + * @map: corresponding pinmux map active for this pinmux setting
> + * @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
> + * @pmxdev_selector: the function selector for the pinmux device handling
> + *	this pinmux
> + * @pmxdev_position: the function position for the pinmux device and
> + *	selector handling this pinmux
> + * @mutex: a lock for the pinmux state holder
> + */
> +struct pinmux {
> +	struct list_head node;
> +	struct device *dev;
> +	struct pinmux_map const *map;
> +	unsigned usecount;
> +	struct pinctrl_dev *pctldev;
> +	unsigned pmxdev_selector;
> +	unsigned pmxdev_position;
> +	struct mutex mutex;
> +};
> +
> +/**
> + * pin_request() - request a single pin to be muxed in, typically for GPIO
> + * @pin: the pin number in the global pin space
> + * @function: a functional name to give to this pin, passed to the driver
> + *	so it knows what function to mux in, e.g. the string "gpioNN"
> + *	means that you want to mux in the pin for use as GPIO number NN
> + * @gpio: if this request concerns a single GPIO pin
> + * @gpio_range: the range matching the GPIO pin if this is a request for a
> + *	single GPIO pin
> + */
> +static int pin_request(struct pinctrl_dev *pctldev,
> +		       int pin, const char *function, bool gpio,
> +		       struct pinctrl_gpio_range *gpio_range)

@gpio_range is only valid if @gpio == true, so we could drop @gpio and 
only do gpio_request_enable if gpio_range != NULL?  At least that way we 
can't call gpio_request_enable with a NULL gpio_range (which I don't 
think is valid?).

[...]
> +/**
> + * pinmux_config() - configure a certain pinmux setting
> + * @pmx: the pinmux setting to configure
> + * @param: the parameter to configure
> + * @data: extra data to be passed to the configuration, also works as a
> + *	pointer to data returned from the function on success
> + */
> +int pinmux_config(struct pinmux *pmx, u16 param, unsigned long *data)
> +{
> +	struct pinctrl_dev *pctldev;
> +	const struct pinmux_ops *ops;
> +	int ret = 0;
> +
> +	if (pmx == NULL)
> +		return -ENODEV;
> +
> +	pctldev = pmx->pctldev;
> +	ops = pctldev->desc->pmxops;
> +
> +	/* This operation is not mandatory to implement */
> +	if (ops->config) {
> +		mutex_lock(&pmx->mutex);
> +		ret = ops->config(pctldev, pmx->pmxdev_selector, param, data);
> +		mutex_unlock(&pmx->mutex);
> +	}
> +
> +	return 0;

Shouldn't this return ret from ops->config()?

WARNING: multiple messages have this Message-ID (diff)
From: jamie@jamieiles.com (Jamie Iles)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 1/4 v5] drivers: create a pin control subsystem v5
Date: Tue, 30 Aug 2011 11:02:45 +0100	[thread overview]
Message-ID: <20110830100245.GD5414@pulham.picochip.com> (raw)
In-Reply-To: <1314609001-28052-1-git-send-email-linus.walleij@stericsson.com>

Hi Linus,

This is looking really great!  A couple of pedantic nits inline, but 
with the gpio ranges support I think this covers all of the bases that 
we need from pin control, so thanks!

Jamie

On Mon, Aug 29, 2011 at 11:10:01AM +0200, Linus Walleij wrote:
[...]
> diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
> new file mode 100644
> index 0000000..596ce9f
> --- /dev/null
> +++ b/drivers/pinctrl/Makefile
> @@ -0,0 +1,6 @@
> +# generic pinmux support
> +
> +ccflags-$(CONFIG_DEBUG_PINMUX)	+= -DDEBUG
> +
> +obj-$(CONFIG_PINCTRL)		+= core.o
> +obj-$(CONFIG_PINMUX)		+= pinmux.o
> diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
> new file mode 100644
> index 0000000..762e9e8
> --- /dev/null
> +++ b/drivers/pinctrl/core.c
> @@ -0,0 +1,539 @@
> +/*
> + * Core driver for the pin control subsystem
> + *
> + * Copyright (C) 2011 ST-Ericsson SA
> + * Written on behalf of Linaro for ST-Ericsson
> + * Based on bits of regulator core, gpio core and clk core
> + *
> + * Author: Linus Walleij <linus.walleij@linaro.org>
> + *
> + * License terms: GNU General Public License (GPL) version 2
> + */
> +#define pr_fmt(fmt) "pinctrl core: " fmt
> +
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/device.h>
> +#include <linux/slab.h>
> +#include <linux/radix-tree.h>
> +#include <linux/err.h>
> +#include <linux/list.h>
> +#include <linux/mutex.h>
> +#include <linux/spinlock.h>
> +#include <linux/sysfs.h>
> +#include <linux/debugfs.h>
> +#include <linux/seq_file.h>
> +#include <linux/pinctrl/pinctrl.h>
> +#include <linux/pinctrl/machine.h>
> +#include "core.h"
> +#include "pinmux.h"
> +
> +/* Global list of pin control devices */
> +static DEFINE_MUTEX(pinctrldev_list_mutex);
> +static LIST_HEAD(pinctrldev_list);
> +
> +/* sysfs interaction */
> +static ssize_t pinctrl_name_show(struct device *dev,
> +				struct device_attribute *attr, char *buf)
> +{
> +	struct pinctrl_dev *pctldev = dev_get_drvdata(dev);

As you have a struct device in pctldev, you should be able to do:

#define to_pinctrl_dev(__dev) \
	container_of(__dev, struct pinctrl_dev, dev)

struct pinctrl_dev *pctldev = to_pinctrl_dev(dev);

then you don't need to use the driver data.

[...]
> +static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev)
> +{
> +	static struct dentry *device_root;

Does device_root need to be static?

> +
> +	device_root = debugfs_create_dir(dev_name(&pctldev->dev),
> +					 debugfs_root);
> +	if (IS_ERR(device_root) || !device_root) {
> +		pr_warn("failed to create debugfs directory for %s\n",
> +			dev_name(&pctldev->dev));
> +		return;
> +	}
> +	debugfs_create_file("pins", S_IFREG | S_IRUGO,
> +			    device_root, pctldev, &pinctrl_pins_ops);
> +	debugfs_create_file("gpio-ranges", S_IFREG | S_IRUGO,
> +			    device_root, pctldev, &pinctrl_gpioranges_ops);
> +	pinmux_init_device_debugfs(device_root, pctldev);
> +}
> +
> +static void pinctrl_init_debugfs(void)
> +{
> +	debugfs_root = debugfs_create_dir("pinctrl", NULL);
> +	if (IS_ERR(debugfs_root) || !debugfs_root) {

IS_ERR_OR_NULL()?

> +		pr_warn("failed to create debugfs directory\n");
> +		debugfs_root = NULL;
> +		return;
> +	}
> +
> +	debugfs_create_file("pinctrl-devices", S_IFREG | S_IRUGO,
> +			    debugfs_root, NULL, &pinctrl_devices_ops);
> +	pinmux_init_debugfs(debugfs_root);
> +}
> +
> +#else /* CONFIG_DEBUG_FS */
> +
> +static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev)
> +{
> +}
> +
> +static void pinctrl_init_debugfs(void)
> +{
> +}
> +
> +#endif
> +
> +/**
> + * pinctrl_register() - register a pin controller device
> + * @pctldesc: descriptor for this pin controller
> + * @dev: parent device for this pin controller
> + * @driver_data: private pin controller data for this pin controller
> + */
> +struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
> +				    struct device *dev, void *driver_data)
> +{
> +	static atomic_t pinmux_no = ATOMIC_INIT(0);
> +	struct pinctrl_dev *pctldev;
> +	int ret;
> +
> +	if (pctldesc == NULL)
> +		return ERR_PTR(-EINVAL);
> +	if (pctldesc->name == NULL)
> +		return ERR_PTR(-EINVAL);
> +
> +	/* If we're implementing pinmuxing, check the ops for sanity */
> +	if (pctldesc->pmxops) {
> +		ret = pinmux_check_ops(pctldesc->pmxops);
> +		if (ret)
> +			return ERR_PTR(ret);
> +	}
> +
> +	pctldev = kzalloc(sizeof(struct pinctrl_dev), GFP_KERNEL);
> +	if (pctldev == NULL)
> +		return ERR_PTR(-ENOMEM);
> +
> +	/* Initialize pin control device struct */
> +	pctldev->owner = pctldesc->owner;
> +	pctldev->desc = pctldesc;
> +	pctldev->driver_data = driver_data;
> +	INIT_RADIX_TREE(&pctldev->pin_desc_tree, GFP_KERNEL);
> +	spin_lock_init(&pctldev->pin_desc_tree_lock);
> +	INIT_LIST_HEAD(&pctldev->gpio_ranges);
> +	spin_lock_init(&pctldev->gpio_ranges_lock);
> +
> +	/* Register device with sysfs */
> +	pctldev->dev.parent = dev;
> +	pctldev->dev.bus = &pinctrl_bus;
> +	pctldev->dev.type = &pinctrl_type;
> +	dev_set_name(&pctldev->dev, "pinctrl.%d",
> +		     atomic_inc_return(&pinmux_no) - 1);
> +	ret = device_register(&pctldev->dev);
> +	if (ret != 0) {
> +		pr_err("error in device registration\n");
> +		put_device(&pctldev->dev);
> +		kfree(pctldev);

I don't think you need the kfree() here as it should get called in the 
devices release method.

> +		goto out_err;
> +	}
> +	dev_set_drvdata(&pctldev->dev, pctldev);
> +
> +	/* Register all the pins */
> +	pr_debug("try to register %d pins on %s...\n",
> +		 pctldesc->npins, pctldesc->name);
> +	ret = pinctrl_register_pins(pctldev, pctldesc->pins, pctldesc->npins);
> +	if (ret) {
> +		pr_err("error during pin registration\n");
> +		pinctrl_free_pindescs(pctldev, pctldesc->pins,
> +				      pctldesc->npins);
> +		goto out_err;
> +	}
> +
> +	pinctrl_init_device_debugfs(pctldev);
> +	mutex_lock(&pinctrldev_list_mutex);
> +	list_add(&pctldev->node, &pinctrldev_list);
> +	mutex_unlock(&pinctrldev_list_mutex);
> +	return pctldev;
> +
> +out_err:
> +	put_device(&pctldev->dev);
> +	kfree(pctldev);

I think this needs to be a device_unregister() rather than put device, 
and the kfree() can be dropped.

Possibly also do a dev_set_drvdata(&pctldev->dev, NULL) here too?

> diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
> new file mode 100644
> index 0000000..310d344
> --- /dev/null
> +++ b/drivers/pinctrl/pinmux.c
> @@ -0,0 +1,811 @@
> +/*
> + * Core driver for the pin muxing portions of the pin control subsystem
> + *
> + * Copyright (C) 2011 ST-Ericsson SA
> + * Written on behalf of Linaro for ST-Ericsson
> + * Based on bits of regulator core, gpio core and clk core
> + *
> + * Author: Linus Walleij <linus.walleij@linaro.org>
> + *
> + * License terms: GNU General Public License (GPL) version 2
> + */
> +#define pr_fmt(fmt) "pinmux core: " fmt
> +
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/device.h>
> +#include <linux/slab.h>
> +#include <linux/radix-tree.h>
> +#include <linux/err.h>
> +#include <linux/list.h>
> +#include <linux/mutex.h>
> +#include <linux/spinlock.h>
> +#include <linux/sysfs.h>
> +#include <linux/debugfs.h>
> +#include <linux/seq_file.h>
> +#include <linux/pinctrl/machine.h>
> +#include <linux/pinctrl/pinmux.h>
> +#include "core.h"
> +
> +/* Global list of pinmuxes */
> +static DEFINE_MUTEX(pinmux_list_mutex);
> +static LIST_HEAD(pinmux_list);
> +
> +/**
> + * struct pinmux - per-device pinmux state holder
> + * @node: global list node - only for internal use
> + * @dev: the device using this pinmux
> + * @map: corresponding pinmux map active for this pinmux setting
> + * @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
> + * @pmxdev_selector: the function selector for the pinmux device handling
> + *	this pinmux
> + * @pmxdev_position: the function position for the pinmux device and
> + *	selector handling this pinmux
> + * @mutex: a lock for the pinmux state holder
> + */
> +struct pinmux {
> +	struct list_head node;
> +	struct device *dev;
> +	struct pinmux_map const *map;
> +	unsigned usecount;
> +	struct pinctrl_dev *pctldev;
> +	unsigned pmxdev_selector;
> +	unsigned pmxdev_position;
> +	struct mutex mutex;
> +};
> +
> +/**
> + * pin_request() - request a single pin to be muxed in, typically for GPIO
> + * @pin: the pin number in the global pin space
> + * @function: a functional name to give to this pin, passed to the driver
> + *	so it knows what function to mux in, e.g. the string "gpioNN"
> + *	means that you want to mux in the pin for use as GPIO number NN
> + * @gpio: if this request concerns a single GPIO pin
> + * @gpio_range: the range matching the GPIO pin if this is a request for a
> + *	single GPIO pin
> + */
> +static int pin_request(struct pinctrl_dev *pctldev,
> +		       int pin, const char *function, bool gpio,
> +		       struct pinctrl_gpio_range *gpio_range)

@gpio_range is only valid if @gpio == true, so we could drop @gpio and 
only do gpio_request_enable if gpio_range != NULL?  At least that way we 
can't call gpio_request_enable with a NULL gpio_range (which I don't 
think is valid?).

[...]
> +/**
> + * pinmux_config() - configure a certain pinmux setting
> + * @pmx: the pinmux setting to configure
> + * @param: the parameter to configure
> + * @data: extra data to be passed to the configuration, also works as a
> + *	pointer to data returned from the function on success
> + */
> +int pinmux_config(struct pinmux *pmx, u16 param, unsigned long *data)
> +{
> +	struct pinctrl_dev *pctldev;
> +	const struct pinmux_ops *ops;
> +	int ret = 0;
> +
> +	if (pmx == NULL)
> +		return -ENODEV;
> +
> +	pctldev = pmx->pctldev;
> +	ops = pctldev->desc->pmxops;
> +
> +	/* This operation is not mandatory to implement */
> +	if (ops->config) {
> +		mutex_lock(&pmx->mutex);
> +		ret = ops->config(pctldev, pmx->pmxdev_selector, param, data);
> +		mutex_unlock(&pmx->mutex);
> +	}
> +
> +	return 0;

Shouldn't this return ret from ops->config()?

  parent reply	other threads:[~2011-08-30 10:03 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-08-29  9:10 [PATCH 1/4 v5] drivers: create a pin control subsystem v5 Linus Walleij
2011-08-29  9:10 ` Linus Walleij
2011-08-29 21:32 ` Stephen Warren
2011-08-29 21:32   ` Stephen Warren
2011-09-01  8:59   ` Linus Walleij
2011-09-01  8:59     ` Linus Walleij
2011-09-01  9:13     ` Linus Walleij
2011-09-01  9:13       ` Linus Walleij
2011-09-01 19:43       ` Stephen Warren
2011-09-01 19:43         ` Stephen Warren
2011-09-02  8:07         ` Linus Walleij
2011-09-02  8:07           ` Linus Walleij
2011-08-30 10:02 ` Jamie Iles [this message]
2011-08-30 10:02   ` Jamie Iles
2011-08-31  9:45 ` Barry Song
2011-08-31  9:45   ` Barry Song

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110830100245.GD5414@pulham.picochip.com \
    --to=jamie@jamieiles.com \
    --cc=21cnbao@gmail.com \
    --cc=davidb@codeaurora.org \
    --cc=grant.likely@secretlab.ca \
    --cc=joe@perches.com \
    --cc=lee.jones@linaro.org \
    --cc=linaro-dev@lists.linaro.org \
    --cc=linus.walleij@linaro.org \
    --cc=linus.walleij@stericsson.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@arm.linux.org.uk \
    --cc=s.hauer@pengutronix.de \
    --cc=swarren@nvidia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.