From 9dfac4fd7f8cdcdf734dff2ccc7ca467f53f1cfd Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 1 Feb 2012 18:02:47 +0100 Subject: pinctrl: delete raw device pointers in pinmux maps After discussion with Mark Brown in an unrelated thread about ADC lookups, it came to my knowledge that the ability to pass a struct device * in the regulator consumers is just a historical artifact, and not really recommended. Since there are no in-kernel users of these pointers, we just kill them right now, before someone starts to use them. Reviewed-by: Mark Brown Signed-off-by: Linus Walleij --- include/linux/pinctrl/machine.h | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h index d0aecb7f6fb9..f8593fdc6466 100644 --- a/include/linux/pinctrl/machine.h +++ b/include/linux/pinctrl/machine.h @@ -17,22 +17,16 @@ * @name: the name of this specific map entry for the particular machine. * This is the second parameter passed to pinmux_get() when you want * to have several mappings to the same device - * @ctrl_dev: the pin control device to be used by this mapping, may be NULL - * if you provide .ctrl_dev_name instead (this is more common) * @ctrl_dev_name: the name of the device controlling this specific mapping, - * the name must be the same as in your struct device*, may be NULL if - * you provide .ctrl_dev instead + * the name must be the same as in your struct device* * @function: a function in the driver to use for this mapping, the driver * will lookup the function referenced by this ID on the specified * pin control device * @group: sometimes a function can map to different pin groups, so this * selects a certain specific pin group to activate for the function, if * left as NULL, the first applicable group will be used - * @dev: the device using this specific mapping, may be NULL if you provide - * .dev_name instead (this is more common) * @dev_name: the name of the device using this specific mapping, the name - * must be the same as in your struct device*, may be NULL if you - * provide .dev instead + * must be the same as in your struct device* * @hog_on_boot: if this is set to true, the pin control subsystem will itself * hog the mappings as the pinmux device drivers are attached, so this is * typically used with system maps (mux mappings without an assigned @@ -42,11 +36,9 @@ */ struct pinmux_map { const char *name; - struct device *ctrl_dev; const char *ctrl_dev_name; const char *function; const char *group; - struct device *dev; const char *dev_name; bool hog_on_boot; }; -- cgit v1.2.3 From 28a8d14cc74a0180323d9150c3d3dbf9dd60d55a Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 9 Feb 2012 01:52:22 +0100 Subject: pinctrl: break out a pinctrl consumer header This breaks out a header to be used by all pinmux and pinconfig alike, so drivers needing services from pinctrl does not need to include different headers. This is similar to the approach taken by the regulator API. Acked-by: Stephen Warren Signed-off-by: Linus Walleij --- include/linux/pinctrl/consumer.h | 118 +++++++++++++++++++++++++++++++++++++++ include/linux/pinctrl/pinconf.h | 39 ------------- include/linux/pinctrl/pinmux.h | 52 ----------------- 3 files changed, 118 insertions(+), 91 deletions(-) create mode 100644 include/linux/pinctrl/consumer.h (limited to 'include/linux') diff --git a/include/linux/pinctrl/consumer.h b/include/linux/pinctrl/consumer.h new file mode 100644 index 000000000000..9c8513d5d0fb --- /dev/null +++ b/include/linux/pinctrl/consumer.h @@ -0,0 +1,118 @@ +/* + * Consumer interface the pin control subsystem + * + * Copyright (C) 2012 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 + * + * License terms: GNU General Public License (GPL) version 2 + */ +#ifndef __LINUX_PINCTRL_CONSUMER_H +#define __LINUX_PINCTRL_CONSUMER_H + +#include +#include +#include "pinctrl.h" + +/* This struct is private to the core and should be regarded as a cookie */ +struct pinmux; + +#ifdef CONFIG_PINMUX + +/* External interface to pinmux */ +extern int pinmux_request_gpio(unsigned gpio); +extern void pinmux_free_gpio(unsigned gpio); +extern int pinmux_gpio_direction_input(unsigned gpio); +extern int pinmux_gpio_direction_output(unsigned gpio); +extern struct pinmux * __must_check pinmux_get(struct device *dev, const char *name); +extern void pinmux_put(struct pinmux *pmx); +extern int pinmux_enable(struct pinmux *pmx); +extern void pinmux_disable(struct pinmux *pmx); + +#else /* !CONFIG_PINMUX */ + +static inline int pinmux_request_gpio(unsigned gpio) +{ + return 0; +} + +static inline void pinmux_free_gpio(unsigned gpio) +{ +} + +static inline int pinmux_gpio_direction_input(unsigned gpio) +{ + return 0; +} + +static inline int pinmux_gpio_direction_output(unsigned gpio) +{ + return 0; +} + +static inline struct pinmux * __must_check pinmux_get(struct device *dev, const char *name) +{ + return NULL; +} + +static inline void pinmux_put(struct pinmux *pmx) +{ +} + +static inline int pinmux_enable(struct pinmux *pmx) +{ + return 0; +} + +static inline void pinmux_disable(struct pinmux *pmx) +{ +} + +#endif /* CONFIG_PINMUX */ + +#ifdef CONFIG_PINCONF + +extern int pin_config_get(const char *dev_name, const char *name, + unsigned long *config); +extern int pin_config_set(const char *dev_name, const char *name, + unsigned long config); +extern int pin_config_group_get(const char *dev_name, + const char *pin_group, + unsigned long *config); +extern int pin_config_group_set(const char *dev_name, + const char *pin_group, + unsigned long config); + +#else + +static inline int pin_config_get(const char *dev_name, const char *name, + unsigned long *config) +{ + return 0; +} + +static inline int pin_config_set(const char *dev_name, const char *name, + unsigned long config) +{ + return 0; +} + +static inline int pin_config_group_get(const char *dev_name, + const char *pin_group, + unsigned long *config) +{ + return 0; +} + +static inline int pin_config_group_set(const char *dev_name, + const char *pin_group, + unsigned long config) +{ + return 0; +} + +#endif + +#endif /* __LINUX_PINCTRL_CONSUMER_H */ diff --git a/include/linux/pinctrl/pinconf.h b/include/linux/pinctrl/pinconf.h index 477922cf043a..f8cf156873d7 100644 --- a/include/linux/pinctrl/pinconf.h +++ b/include/linux/pinctrl/pinconf.h @@ -53,45 +53,6 @@ struct pinconf_ops { unsigned selector); }; -extern int pin_config_get(const char *dev_name, const char *name, - unsigned long *config); -extern int pin_config_set(const char *dev_name, const char *name, - unsigned long config); -extern int pin_config_group_get(const char *dev_name, - const char *pin_group, - unsigned long *config); -extern int pin_config_group_set(const char *dev_name, - const char *pin_group, - unsigned long config); - -#else - -static inline int pin_config_get(const char *dev_name, const char *name, - unsigned long *config) -{ - return 0; -} - -static inline int pin_config_set(const char *dev_name, const char *name, - unsigned long config) -{ - return 0; -} - -static inline int pin_config_group_get(const char *dev_name, - const char *pin_group, - unsigned long *config) -{ - return 0; -} - -static inline int pin_config_group_set(const char *dev_name, - const char *pin_group, - unsigned long config) -{ - return 0; -} - #endif #endif /* __LINUX_PINCTRL_PINCONF_H */ diff --git a/include/linux/pinctrl/pinmux.h b/include/linux/pinctrl/pinmux.h index 937b3e2fa36f..47e9237edd47 100644 --- a/include/linux/pinctrl/pinmux.h +++ b/include/linux/pinctrl/pinmux.h @@ -16,9 +16,6 @@ #include #include "pinctrl.h" -/* This struct is private to the core and should be regarded as a cookie */ -struct pinmux; - #ifdef CONFIG_PINMUX struct pinctrl_dev; @@ -88,55 +85,6 @@ struct pinmux_ops { bool input); }; -/* External interface to pinmux */ -extern int pinmux_request_gpio(unsigned gpio); -extern void pinmux_free_gpio(unsigned gpio); -extern int pinmux_gpio_direction_input(unsigned gpio); -extern int pinmux_gpio_direction_output(unsigned gpio); -extern struct pinmux * __must_check pinmux_get(struct device *dev, const char *name); -extern void pinmux_put(struct pinmux *pmx); -extern int pinmux_enable(struct pinmux *pmx); -extern void pinmux_disable(struct pinmux *pmx); - -#else /* !CONFIG_PINMUX */ - -static inline int pinmux_request_gpio(unsigned gpio) -{ - return 0; -} - -static inline void pinmux_free_gpio(unsigned gpio) -{ -} - -static inline int pinmux_gpio_direction_input(unsigned gpio) -{ - return 0; -} - -static inline int pinmux_gpio_direction_output(unsigned gpio) -{ - return 0; -} - -static inline struct pinmux * __must_check pinmux_get(struct device *dev, const char *name) -{ - return NULL; -} - -static inline void pinmux_put(struct pinmux *pmx) -{ -} - -static inline int pinmux_enable(struct pinmux *pmx) -{ - return 0; -} - -static inline void pinmux_disable(struct pinmux *pmx) -{ -} - #endif /* CONFIG_PINMUX */ #endif /* __LINUX_PINCTRL_PINMUX_H */ -- cgit v1.2.3 From e93bcee00c43e2bd4037291262111016f4c05793 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 9 Feb 2012 07:23:28 +0100 Subject: pinctrl: move generic functions to the pinctrl_ namespace Since we want to use the former pinmux handles and mapping tables for generic control involving both muxing and configuration we begin refactoring by renaming them from pinmux_* to pinctrl_*. ChangeLog v1->v2: - Also rename the PINMUX_* macros in machine.h to PIN_ as indicated in the documentation so as to reflect the generic nature of these mapping entries from now on. Acked-by: Stephen Warren Signed-off-by: Linus Walleij --- include/linux/pinctrl/consumer.h | 34 +++++++++++++++++----------------- include/linux/pinctrl/machine.h | 26 +++++++++++++------------- 2 files changed, 30 insertions(+), 30 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pinctrl/consumer.h b/include/linux/pinctrl/consumer.h index 9c8513d5d0fb..c7d061776293 100644 --- a/include/linux/pinctrl/consumer.h +++ b/include/linux/pinctrl/consumer.h @@ -17,56 +17,56 @@ #include "pinctrl.h" /* This struct is private to the core and should be regarded as a cookie */ -struct pinmux; +struct pinctrl; #ifdef CONFIG_PINMUX /* External interface to pinmux */ -extern int pinmux_request_gpio(unsigned gpio); -extern void pinmux_free_gpio(unsigned gpio); -extern int pinmux_gpio_direction_input(unsigned gpio); -extern int pinmux_gpio_direction_output(unsigned gpio); -extern struct pinmux * __must_check pinmux_get(struct device *dev, const char *name); -extern void pinmux_put(struct pinmux *pmx); -extern int pinmux_enable(struct pinmux *pmx); -extern void pinmux_disable(struct pinmux *pmx); +extern int pinctrl_request_gpio(unsigned gpio); +extern void pinctrl_free_gpio(unsigned gpio); +extern int pinctrl_gpio_direction_input(unsigned gpio); +extern int pinctrl_gpio_direction_output(unsigned gpio); +extern struct pinctrl * __must_check pinctrl_get(struct device *dev, const char *name); +extern void pinctrl_put(struct pinctrl *p); +extern int pinctrl_enable(struct pinctrl *p); +extern void pinctrl_disable(struct pinctrl *p); #else /* !CONFIG_PINMUX */ -static inline int pinmux_request_gpio(unsigned gpio) +static inline int pinctrl_request_gpio(unsigned gpio) { return 0; } -static inline void pinmux_free_gpio(unsigned gpio) +static inline void pinctrl_free_gpio(unsigned gpio) { } -static inline int pinmux_gpio_direction_input(unsigned gpio) +static inline int pinctrl_gpio_direction_input(unsigned gpio) { return 0; } -static inline int pinmux_gpio_direction_output(unsigned gpio) +static inline int pinctrl_gpio_direction_output(unsigned gpio) { return 0; } -static inline struct pinmux * __must_check pinmux_get(struct device *dev, const char *name) +static inline struct pinctrl * __must_check pinctrl_get(struct device *dev, const char *name) { return NULL; } -static inline void pinmux_put(struct pinmux *pmx) +static inline void pinctrl_put(struct pinctrl *p) { } -static inline int pinmux_enable(struct pinmux *pmx) +static inline int pinctrl_enable(struct pinctrl *p) { return 0; } -static inline void pinmux_disable(struct pinmux *pmx) +static inline void pinctrl_disable(struct pinctrl *p) { } diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h index f8593fdc6466..a2ab524a0106 100644 --- a/include/linux/pinctrl/machine.h +++ b/include/linux/pinctrl/machine.h @@ -9,11 +9,11 @@ * * License terms: GNU General Public License (GPL) version 2 */ -#ifndef __LINUX_PINMUX_MACHINE_H -#define __LINUX_PINMUX_MACHINE_H +#ifndef __LINUX_PINCTRL_MACHINE_H +#define __LINUX_PINCTRL_MACHINE_H /** - * struct pinmux_map - boards/machines shall provide this map for devices + * struct pinctrl_map - boards/machines shall provide this map for devices * @name: the name of this specific map entry for the particular machine. * This is the second parameter passed to pinmux_get() when you want * to have several mappings to the same device @@ -34,7 +34,7 @@ * a pinmux device supporting it is registered. These maps will not be * disabled and put until the system shuts down. */ -struct pinmux_map { +struct pinctrl_map { const char *name; const char *ctrl_dev_name; const char *function; @@ -47,41 +47,41 @@ struct pinmux_map { * Convenience macro to set a simple map from a certain pin controller and a * certain function to a named device */ -#define PINMUX_MAP(a, b, c, d) \ +#define PIN_MAP(a, b, c, d) \ { .name = a, .ctrl_dev_name = b, .function = c, .dev_name = d } /* * Convenience macro to map a system function onto a certain pinctrl device. * System functions are not assigned to a particular device. */ -#define PINMUX_MAP_SYS(a, b, c) \ +#define PIN_MAP_SYS(a, b, c) \ { .name = a, .ctrl_dev_name = b, .function = c } /* * Convenience macro to map a system function onto a certain pinctrl device, - * to be hogged by the pinmux core until the system shuts down. + * to be hogged by the pin control core until the system shuts down. */ -#define PINMUX_MAP_SYS_HOG(a, b, c) \ +#define PIN_MAP_SYS_HOG(a, b, c) \ { .name = a, .ctrl_dev_name = b, .function = c, \ .hog_on_boot = true } /* * Convenience macro to map a system function onto a certain pinctrl device - * using a specified group, to be hogged by the pinmux core until the system - * shuts down. + * using a specified group, to be hogged by the pin control core until the + * system shuts down. */ -#define PINMUX_MAP_SYS_HOG_GROUP(a, b, c, d) \ +#define PIN_MAP_SYS_HOG_GROUP(a, b, c, d) \ { .name = a, .ctrl_dev_name = b, .function = c, .group = d, \ .hog_on_boot = true } #ifdef CONFIG_PINMUX -extern int pinmux_register_mappings(struct pinmux_map const *map, +extern int pinctrl_register_mappings(struct pinctrl_map const *map, unsigned num_maps); #else -static inline int pinmux_register_mappings(struct pinmux_map const *map, +static inline int pinctrl_register_mappings(struct pinctrl_map const *map, unsigned num_maps) { return 0; -- cgit v1.2.3 From befe5bdfbb698b3bc57c58d0bd7ca3391c9275ed Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 9 Feb 2012 19:47:48 +0100 Subject: pinctrl: factor pin control handles over to the core This moves the per-devices struct pinctrl handles and device map over from the pinmux part of the subsystem to the core pinctrl part. This makes the device handles core infrastructure with the goal of using these handles also for pin configuration, so that device drivers (or boards etc) will need one and only one handle to the pin control core. Acked-by: Stephen Warren Signed-off-by: Linus Walleij --- include/linux/pinctrl/consumer.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pinctrl/consumer.h b/include/linux/pinctrl/consumer.h index c7d061776293..30865947f2d9 100644 --- a/include/linux/pinctrl/consumer.h +++ b/include/linux/pinctrl/consumer.h @@ -19,9 +19,9 @@ /* This struct is private to the core and should be regarded as a cookie */ struct pinctrl; -#ifdef CONFIG_PINMUX +#ifdef CONFIG_PINCTRL -/* External interface to pinmux */ +/* External interface to pin control */ extern int pinctrl_request_gpio(unsigned gpio); extern void pinctrl_free_gpio(unsigned gpio); extern int pinctrl_gpio_direction_input(unsigned gpio); @@ -31,7 +31,7 @@ extern void pinctrl_put(struct pinctrl *p); extern int pinctrl_enable(struct pinctrl *p); extern void pinctrl_disable(struct pinctrl *p); -#else /* !CONFIG_PINMUX */ +#else /* !CONFIG_PINCTRL */ static inline int pinctrl_request_gpio(unsigned gpio) { @@ -70,7 +70,7 @@ static inline void pinctrl_disable(struct pinctrl *p) { } -#endif /* CONFIG_PINMUX */ +#endif /* CONFIG_PINCTRL */ #ifdef CONFIG_PINCONF -- cgit v1.2.3 From 77a5988355f993840928d195f790a939200a4ff0 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 10 Feb 2012 01:34:12 +0100 Subject: pinctrl: changes hog mechanism to be self-referential Instead of a specific boolean field to indicate if a map entry shall be hogged, treat self-reference as an indication of desired hogging. This drops one field off the map struct and has a nice Douglas R. Hofstadter-feel to it. Acked-by: Dong Aisheng Acked-by: Stephen Warren Signed-off-by: Linus Walleij --- include/linux/pinctrl/machine.h | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h index a2ab524a0106..af145d571970 100644 --- a/include/linux/pinctrl/machine.h +++ b/include/linux/pinctrl/machine.h @@ -26,13 +26,9 @@ * selects a certain specific pin group to activate for the function, if * left as NULL, the first applicable group will be used * @dev_name: the name of the device using this specific mapping, the name - * must be the same as in your struct device* - * @hog_on_boot: if this is set to true, the pin control subsystem will itself - * hog the mappings as the pinmux device drivers are attached, so this is - * typically used with system maps (mux mappings without an assigned - * device) that you want to get hogged and enabled by default as soon as - * a pinmux device supporting it is registered. These maps will not be - * disabled and put until the system shuts down. + * must be the same as in your struct device*. If this name is set to the + * same name as the pin controllers own dev_name(), the map entry will be + * hogged by the driver itself upon registration */ struct pinctrl_map { const char *name; @@ -40,7 +36,6 @@ struct pinctrl_map { const char *function; const char *group; const char *dev_name; - bool hog_on_boot; }; /* @@ -62,8 +57,7 @@ struct pinctrl_map { * to be hogged by the pin control core until the system shuts down. */ #define PIN_MAP_SYS_HOG(a, b, c) \ - { .name = a, .ctrl_dev_name = b, .function = c, \ - .hog_on_boot = true } + { .name = a, .ctrl_dev_name = b, .dev_name = b, .function = c, } /* * Convenience macro to map a system function onto a certain pinctrl device @@ -71,8 +65,8 @@ struct pinctrl_map { * system shuts down. */ #define PIN_MAP_SYS_HOG_GROUP(a, b, c, d) \ - { .name = a, .ctrl_dev_name = b, .function = c, .group = d, \ - .hog_on_boot = true } + { .name = a, .ctrl_dev_name = b, .dev_name = b, .function = c, \ + .group = d, } #ifdef CONFIG_PINMUX -- cgit v1.2.3 From 1681f5ae4ca25bddb6f7b6d4f463cc83e3d1ad01 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 22 Feb 2012 14:25:58 -0700 Subject: pinctrl: disallow map table entries with NULL dev_name field Hog entries are mapping table entries with .ctrl_dev_name == .dev_name. All other mapping table entries need .dev_name set so that they will match some pinctrl_get() call. All extant PIN_MAP*() macros set .dev_name. So, there is no reason to allow mapping table entries without .dev_name set. Update the code and documentation to disallow this. Signed-off-by: Stephen Warren Acked-by: Dong Aisheng Signed-off-by: Linus Walleij --- include/linux/pinctrl/machine.h | 7 ------- 1 file changed, 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h index af145d571970..400f1926b234 100644 --- a/include/linux/pinctrl/machine.h +++ b/include/linux/pinctrl/machine.h @@ -45,13 +45,6 @@ struct pinctrl_map { #define PIN_MAP(a, b, c, d) \ { .name = a, .ctrl_dev_name = b, .function = c, .dev_name = d } -/* - * Convenience macro to map a system function onto a certain pinctrl device. - * System functions are not assigned to a particular device. - */ -#define PIN_MAP_SYS(a, b, c) \ - { .name = a, .ctrl_dev_name = b, .function = c } - /* * Convenience macro to map a system function onto a certain pinctrl device, * to be hogged by the pin control core until the system shuts down. -- cgit v1.2.3 From 806d314325812fb8ffe7059bd84a23d334350c21 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Thu, 23 Feb 2012 17:04:39 -0700 Subject: pinctrl: re-order struct pinctrl_map The lookup key in struct pinctrl_map is (.dev_name, .name). Re-order the struct definition to put the lookup key fields first, and the result values afterwards. To me at least, this slightly better reflects the lookup process. Update the documentation in a similar fashion. Note: PIN_MAP*() macros aren't updated; I plan to update this once later when enhancing the mapping table format to support pin config to reduce churn. Signed-off-by: Stephen Warren Acked-by: Dong Aisheng [Rebased for cherry-picking] Signed-off-by: Linus Walleij --- include/linux/pinctrl/machine.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h index 400f1926b234..73fbb2745301 100644 --- a/include/linux/pinctrl/machine.h +++ b/include/linux/pinctrl/machine.h @@ -14,6 +14,10 @@ /** * struct pinctrl_map - boards/machines shall provide this map for devices + * @dev_name: the name of the device using this specific mapping, the name + * must be the same as in your struct device*. If this name is set to the + * same name as the pin controllers own dev_name(), the map entry will be + * hogged by the driver itself upon registration * @name: the name of this specific map entry for the particular machine. * This is the second parameter passed to pinmux_get() when you want * to have several mappings to the same device @@ -25,17 +29,13 @@ * @group: sometimes a function can map to different pin groups, so this * selects a certain specific pin group to activate for the function, if * left as NULL, the first applicable group will be used - * @dev_name: the name of the device using this specific mapping, the name - * must be the same as in your struct device*. If this name is set to the - * same name as the pin controllers own dev_name(), the map entry will be - * hogged by the driver itself upon registration */ struct pinctrl_map { + const char *dev_name; const char *name; const char *ctrl_dev_name; const char *function; const char *group; - const char *dev_name; }; /* -- cgit v1.2.3 From 46919ae63d4820e76724beb655274ce143f0da0b Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Thu, 1 Mar 2012 18:48:32 -0700 Subject: pinctrl: introduce PINCTRL_STATE_DEFAULT, define hogs as that state This provides a single centralized name for the default state. Update PIN_MAP_* macros to use this state name, instead of requiring the user to pass a state name in. With this change, hog entries in the mapping table are defined as those with state name PINCTRL_STATE_DEFAULT, i.e. all entries have the same name. This interacts badly with the nested iteration over mapping table entries in pinctrl_hog_maps() and pinctrl_hog_map() which would now attempt to claim each hog mapping table entry multiple times. Replacing the custom hog code with a simple pinctrl_get()/pinctrl_enable(). Update documentation and mapping tables to use this. Signed-off-by: Stephen Warren Acked-by: Dong Aisheng Signed-off-by: Linus Walleij --- include/linux/pinctrl/machine.h | 13 ++++++++----- include/linux/pinctrl/pinctrl.h | 2 ++ 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h index 73fbb2745301..20e97353d5f9 100644 --- a/include/linux/pinctrl/machine.h +++ b/include/linux/pinctrl/machine.h @@ -12,6 +12,8 @@ #ifndef __LINUX_PINCTRL_MACHINE_H #define __LINUX_PINCTRL_MACHINE_H +#include "pinctrl.h" + /** * struct pinctrl_map - boards/machines shall provide this map for devices * @dev_name: the name of the device using this specific mapping, the name @@ -49,17 +51,18 @@ struct pinctrl_map { * Convenience macro to map a system function onto a certain pinctrl device, * to be hogged by the pin control core until the system shuts down. */ -#define PIN_MAP_SYS_HOG(a, b, c) \ - { .name = a, .ctrl_dev_name = b, .dev_name = b, .function = c, } +#define PIN_MAP_SYS_HOG(a, b) \ + { .name = PINCTRL_STATE_DEFAULT, .ctrl_dev_name = a, .dev_name = a, \ + .function = b, } /* * Convenience macro to map a system function onto a certain pinctrl device * using a specified group, to be hogged by the pin control core until the * system shuts down. */ -#define PIN_MAP_SYS_HOG_GROUP(a, b, c, d) \ - { .name = a, .ctrl_dev_name = b, .dev_name = b, .function = c, \ - .group = d, } +#define PIN_MAP_SYS_HOG_GROUP(a, b, c) \ + { .name = PINCTRL_STATE_DEFAULT, .ctrl_dev_name = a, .dev_name = a, \ + .function = b, .group = c, } #ifdef CONFIG_PINMUX diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h index 8bd22ee7aa09..411fe232adf1 100644 --- a/include/linux/pinctrl/pinctrl.h +++ b/include/linux/pinctrl/pinctrl.h @@ -19,6 +19,8 @@ #include #include +#define PINCTRL_STATE_DEFAULT "default" + struct pinctrl_dev; struct pinmux_ops; struct pinconf_ops; -- cgit v1.2.3 From 57b676f9c1b7cd84397fe5a86c9bd2788ac4bd32 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 2 Mar 2012 13:05:44 -0700 Subject: pinctrl: fix and simplify locking There are many problems with the current pinctrl locking: struct pinctrl_dev's gpio_ranges_lock isn't effective; pinctrl_match_gpio_range() only holds this lock while searching for a gpio range, but the found range is return and manipulated after releading the lock. This could allow pinctrl_remove_gpio_range() for that range while it is in use, and the caller may very well delete the range after removing it, causing pinctrl code to touch the now-free range object. Solving this requires the introduction of a higher-level lock, at least a lock per pin controller, which both gpio range registration and pinctrl_get()/put() will acquire. There is missing locking on HW programming; pin controllers may pack the configuration for different pins/groups/config options/... into one register, and hence have to read-modify-write the register. This needs to be protected, but currently isn't. Related, a future change will add a "complete" op to the pin controller drivers, the idea being that each state's programming will be programmed into the pinctrl driver followed by the "complete" call, which may e.g. flush a register cache to HW. For this to work, it must not be possible to interleave the pinctrl driver calls for different devices. As above, solving this requires the introduction of a higher-level lock, at least a lock per pin controller, which will be held for the duration of any pinctrl_enable()/disable() call. However, each pinctrl mapping table entry may affect a different pin controller if necessary. Hence, with a per-pin-controller lock, almost any pinctrl API may need to acquire multiple locks, one per controller. To avoid deadlock, these would need to be acquired in the same order in all cases. This is extremely difficult to implement in the case of pinctrl_get(), which doesn't know which pin controllers to lock until it has parsed the entire mapping table, since it contains somewhat arbitrary data. The simplest solution here is to introduce a single lock that covers all pin controllers at once. This will be acquired by all pinctrl APIs. This then makes struct pinctrl's mutex irrelevant, since that single lock will always be held whenever this mutex is currently held. Signed-off-by: Stephen Warren Signed-off-by: Linus Walleij --- include/linux/pinctrl/pinctrl.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h index 411fe232adf1..bbdd7e16bada 100644 --- a/include/linux/pinctrl/pinctrl.h +++ b/include/linux/pinctrl/pinctrl.h @@ -15,7 +15,6 @@ #ifdef CONFIG_PINCTRL #include -#include #include #include -- cgit v1.2.3 From 6e5e959dde0d92d177f035652aeaa77f9330c9c6 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 2 Mar 2012 13:05:47 -0700 Subject: pinctrl: API changes to support multiple states per device The API model is changed from: p = pinctrl_get(dev, "state1"); pinctrl_enable(p); ... pinctrl_disable(p); pinctrl_put(p); p = pinctrl_get(dev, "state2"); pinctrl_enable(p); ... pinctrl_disable(p); pinctrl_put(p); to this: p = pinctrl_get(dev); s1 = pinctrl_lookup_state(p, "state1"); s2 = pinctrl_lookup_state(p, "state2"); pinctrl_select_state(p, s1); ... pinctrl_select_state(p, s2); ... pinctrl_put(p); This allows devices to directly transition between states without disabling the pin controller programming and put()/get()ing the configuration data each time. This model will also better suit pinconf programming, which doesn't have a concept of "disable". The special-case hogging feature of pin controllers is re-written to use the regular APIs instead of special-case code. Hence, the pinmux-hogs debugfs file is removed; see the top-level pinctrl-handles files for equivalent data. Signed-off-by: Stephen Warren Acked-by: Dong Aisheng Signed-off-by: Linus Walleij --- include/linux/pinctrl/consumer.h | 55 +++++++++++++++++++++++++++++++++++----- include/linux/pinctrl/machine.h | 11 ++++---- 2 files changed, 53 insertions(+), 13 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pinctrl/consumer.h b/include/linux/pinctrl/consumer.h index 30865947f2d9..9ad5896cfa0e 100644 --- a/include/linux/pinctrl/consumer.h +++ b/include/linux/pinctrl/consumer.h @@ -12,12 +12,14 @@ #ifndef __LINUX_PINCTRL_CONSUMER_H #define __LINUX_PINCTRL_CONSUMER_H +#include #include #include #include "pinctrl.h" /* This struct is private to the core and should be regarded as a cookie */ struct pinctrl; +struct pinctrl_state; #ifdef CONFIG_PINCTRL @@ -26,10 +28,13 @@ extern int pinctrl_request_gpio(unsigned gpio); extern void pinctrl_free_gpio(unsigned gpio); extern int pinctrl_gpio_direction_input(unsigned gpio); extern int pinctrl_gpio_direction_output(unsigned gpio); -extern struct pinctrl * __must_check pinctrl_get(struct device *dev, const char *name); + +extern struct pinctrl * __must_check pinctrl_get(struct device *dev); extern void pinctrl_put(struct pinctrl *p); -extern int pinctrl_enable(struct pinctrl *p); -extern void pinctrl_disable(struct pinctrl *p); +extern struct pinctrl_state * __must_check pinctrl_lookup_state( + struct pinctrl *p, + const char *name); +extern int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *s); #else /* !CONFIG_PINCTRL */ @@ -52,7 +57,7 @@ static inline int pinctrl_gpio_direction_output(unsigned gpio) return 0; } -static inline struct pinctrl * __must_check pinctrl_get(struct device *dev, const char *name) +static inline struct pinctrl * __must_check pinctrl_get(struct device *dev) { return NULL; } @@ -61,17 +66,53 @@ static inline void pinctrl_put(struct pinctrl *p) { } -static inline int pinctrl_enable(struct pinctrl *p) +static inline struct pinctrl_state * __must_check pinctrl_lookup_state( + struct pinctrl *p, + const char *name) { - return 0; + return NULL; } -static inline void pinctrl_disable(struct pinctrl *p) +static inline int pinctrl_select_state(struct pinctrl *p, + struct pinctrl_state *s) { + return 0; } #endif /* CONFIG_PINCTRL */ +static inline struct pinctrl * __must_check pinctrl_get_select( + struct device *dev, const char *name) +{ + struct pinctrl *p; + struct pinctrl_state *s; + int ret; + + p = pinctrl_get(dev); + if (IS_ERR(p)) + return p; + + s = pinctrl_lookup_state(p, name); + if (IS_ERR(s)) { + pinctrl_put(p); + return ERR_PTR(PTR_ERR(s)); + } + + ret = pinctrl_select_state(p, s); + if (ret < 0) { + pinctrl_put(p); + return ERR_PTR(ret); + } + + return p; +} + +static inline struct pinctrl * __must_check pinctrl_get_select_default( + struct device *dev) +{ + return pinctrl_get_select(dev, PINCTRL_STATE_DEFAULT); +} + #ifdef CONFIG_PINCONF extern int pin_config_get(const char *dev_name, const char *name, diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h index 20e97353d5f9..05d25c8adbaf 100644 --- a/include/linux/pinctrl/machine.h +++ b/include/linux/pinctrl/machine.h @@ -21,23 +21,22 @@ * same name as the pin controllers own dev_name(), the map entry will be * hogged by the driver itself upon registration * @name: the name of this specific map entry for the particular machine. - * This is the second parameter passed to pinmux_get() when you want - * to have several mappings to the same device + * This is the parameter passed to pinmux_lookup_state() * @ctrl_dev_name: the name of the device controlling this specific mapping, * the name must be the same as in your struct device* - * @function: a function in the driver to use for this mapping, the driver - * will lookup the function referenced by this ID on the specified - * pin control device * @group: sometimes a function can map to different pin groups, so this * selects a certain specific pin group to activate for the function, if * left as NULL, the first applicable group will be used + * @function: a function in the driver to use for this mapping, the driver + * will lookup the function referenced by this ID on the specified + * pin control device */ struct pinctrl_map { const char *dev_name; const char *name; const char *ctrl_dev_name; - const char *function; const char *group; + const char *function; }; /* -- cgit v1.2.3 From 1e2082b520721734c358f776d34a069867214c8e Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 2 Mar 2012 13:05:48 -0700 Subject: pinctrl: enhance mapping table to support pin config operations The pinctrl mapping table can now contain entries to: * Set the mux function of a pin group * Apply a set of pin config options to a pin or a group This allows pinctrl_select_state() to apply pin configs settings as well as mux settings. v3: Fix find_pinctrl() to iterate over the correct list. s/_MUX_CONFIGS_/_CONFIGS_/ in mapping table macros. Fix documentation to use correct mapping table macro. v2: Added numerous extra PIN_MAP_*() special-case macros. Fixed kerneldoc typo. Delete pinctrl_get_pin_id() and replace it with pin_get_from_name(). Various minor fixes. Updates due to rebase. Signed-off-by: Stephen Warren Acked-by: Dong Aisheng Signed-off-by: Linus Walleij --- include/linux/pinctrl/machine.h | 145 +++++++++++++++++++++++++++++++--------- 1 file changed, 115 insertions(+), 30 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h index 05d25c8adbaf..3fd2f9dfc645 100644 --- a/include/linux/pinctrl/machine.h +++ b/include/linux/pinctrl/machine.h @@ -14,6 +14,41 @@ #include "pinctrl.h" +enum pinctrl_map_type { + PIN_MAP_TYPE_INVALID, + PIN_MAP_TYPE_DUMMY_STATE, + PIN_MAP_TYPE_MUX_GROUP, + PIN_MAP_TYPE_CONFIGS_PIN, + PIN_MAP_TYPE_CONFIGS_GROUP, +}; + +/** + * struct pinctrl_map_mux - mapping table content for MAP_TYPE_MUX_GROUP + * @group: the name of the group whose mux function is to be configured. This + * field may be left NULL, and the first applicable group for the function + * will be used. + * @function: the mux function to select for the group + */ +struct pinctrl_map_mux { + const char *group; + const char *function; +}; + +/** + * struct pinctrl_map_configs - mapping table content for MAP_TYPE_CONFIGS_* + * @group_or_pin: the name of the pin or group whose configuration parameters + * are to be configured. + * @configs: a pointer to an array of config parameters/values to program into + * hardware. Each individual pin controller defines the format and meaning + * of config parameters. + * @num_configs: the number of entries in array @configs + */ +struct pinctrl_map_configs { + const char *group_or_pin; + unsigned long *configs; + unsigned num_configs; +}; + /** * struct pinctrl_map - boards/machines shall provide this map for devices * @dev_name: the name of the device using this specific mapping, the name @@ -22,46 +57,96 @@ * hogged by the driver itself upon registration * @name: the name of this specific map entry for the particular machine. * This is the parameter passed to pinmux_lookup_state() + * @type: the type of mapping table entry * @ctrl_dev_name: the name of the device controlling this specific mapping, - * the name must be the same as in your struct device* - * @group: sometimes a function can map to different pin groups, so this - * selects a certain specific pin group to activate for the function, if - * left as NULL, the first applicable group will be used - * @function: a function in the driver to use for this mapping, the driver - * will lookup the function referenced by this ID on the specified - * pin control device + * the name must be the same as in your struct device*. This field is not + * used for PIN_MAP_TYPE_DUMMY_STATE + * @data: Data specific to the mapping type */ struct pinctrl_map { const char *dev_name; const char *name; + enum pinctrl_map_type type; const char *ctrl_dev_name; - const char *group; - const char *function; + union { + struct pinctrl_map_mux mux; + struct pinctrl_map_configs configs; + } data; }; -/* - * Convenience macro to set a simple map from a certain pin controller and a - * certain function to a named device - */ -#define PIN_MAP(a, b, c, d) \ - { .name = a, .ctrl_dev_name = b, .function = c, .dev_name = d } +/* Convenience macros to create mapping table entries */ -/* - * Convenience macro to map a system function onto a certain pinctrl device, - * to be hogged by the pin control core until the system shuts down. - */ -#define PIN_MAP_SYS_HOG(a, b) \ - { .name = PINCTRL_STATE_DEFAULT, .ctrl_dev_name = a, .dev_name = a, \ - .function = b, } +#define PIN_MAP_DUMMY_STATE(dev, state) \ + { \ + .dev_name = dev, \ + .name = state, \ + .type = PIN_MAP_TYPE_DUMMY_STATE, \ + } -/* - * Convenience macro to map a system function onto a certain pinctrl device - * using a specified group, to be hogged by the pin control core until the - * system shuts down. - */ -#define PIN_MAP_SYS_HOG_GROUP(a, b, c) \ - { .name = PINCTRL_STATE_DEFAULT, .ctrl_dev_name = a, .dev_name = a, \ - .function = b, .group = c, } +#define PIN_MAP_MUX_GROUP(dev, state, pinctrl, grp, func) \ + { \ + .dev_name = dev, \ + .name = state, \ + .type = PIN_MAP_TYPE_MUX_GROUP, \ + .ctrl_dev_name = pinctrl, \ + .data.mux = { \ + .group = grp, \ + .function = func, \ + }, \ + } + +#define PIN_MAP_MUX_GROUP_DEFAULT(dev, pinctrl, grp, func) \ + PIN_MAP_MUX_GROUP(dev, PINCTRL_STATE_DEFAULT, pinctrl, grp, func) + +#define PIN_MAP_MUX_GROUP_HOG(dev, state, grp, func) \ + PIN_MAP_MUX_GROUP(dev, state, dev, grp, func) + +#define PIN_MAP_MUX_GROUP_HOG_DEFAULT(dev, grp, func) \ + PIN_MAP_MUX_GROUP(dev, PINCTRL_STATE_DEFAULT, dev, grp, func) + +#define PIN_MAP_CONFIGS_PIN(dev, state, pinctrl, pin, cfgs) \ + { \ + .dev_name = dev, \ + .name = state, \ + .type = PIN_MAP_TYPE_CONFIGS_PIN, \ + .ctrl_dev_name = pinctrl, \ + .data.configs = { \ + .group_or_pin = pin, \ + .configs = cfgs, \ + .num_configs = ARRAY_SIZE(cfgs), \ + }, \ + } + +#define PIN_MAP_CONFIGS_PIN_DEFAULT(dev, pinctrl, pin, cfgs) \ + PIN_MAP_CONFIGS_PIN(dev, PINCTRL_STATE_DEFAULT, pinctrl, pin, cfgs) + +#define PIN_MAP_CONFIGS_PIN_HOG(dev, state, pin, cfgs) \ + PIN_MAP_CONFIGS_PIN(dev, state, dev, pin, cfgs) + +#define PIN_MAP_CONFIGS_PIN_HOG_DEFAULT(dev, pin, cfgs) \ + PIN_MAP_CONFIGS_PIN(dev, PINCTRL_STATE_DEFAULT, dev, pin, cfgs) + +#define PIN_MAP_CONFIGS_GROUP(dev, state, pinctrl, grp, cfgs) \ + { \ + .dev_name = dev, \ + .name = state, \ + .type = PIN_MAP_TYPE_CONFIGS_GROUP, \ + .ctrl_dev_name = pinctrl, \ + .data.configs = { \ + .group_or_pin = grp, \ + .configs = cfgs, \ + .num_configs = ARRAY_SIZE(cfgs), \ + }, \ + } + +#define PIN_MAP_CONFIGS_GROUP_DEFAULT(dev, pinctrl, grp, cfgs) \ + PIN_MAP_CONFIGS_GROUP(dev, PINCTRL_STATE_DEFAULT, pinctrl, grp, cfgs) + +#define PIN_MAP_CONFIGS_GROUP_HOG(dev, state, grp, cfgs) \ + PIN_MAP_CONFIGS_GROUP(dev, state, dev, grp, cfgs) + +#define PIN_MAP_CONFIGS_GROUP_HOG_DEFAULT(dev, grp, cfgs) \ + PIN_MAP_CONFIGS_GROUP(dev, PINCTRL_STATE_DEFAULT, dev, grp, cfgs) #ifdef CONFIG_PINMUX -- cgit v1.2.3 From 9a01be1715b6a027765701ca09ba0401ff066fc5 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 6 Mar 2012 21:15:51 +0100 Subject: pinctrl: split pincontrol states into its own header Move the pin control state defines into its own header file, since it is used both by machine.h which is facing the platform and by consumer.h which is facing the drivers, and pinctrl.h which is pinctrl-driver internal, let's not have each and every .h file include all others, then isolation is moot. Acked-by: Stephen Warren Signed-off-by: Linus Walleij --- include/linux/pinctrl/consumer.h | 2 +- include/linux/pinctrl/machine.h | 2 +- include/linux/pinctrl/pinctrl-state.h | 6 ++++++ include/linux/pinctrl/pinctrl.h | 3 +-- 4 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 include/linux/pinctrl/pinctrl-state.h (limited to 'include/linux') diff --git a/include/linux/pinctrl/consumer.h b/include/linux/pinctrl/consumer.h index 9ad5896cfa0e..191e72688481 100644 --- a/include/linux/pinctrl/consumer.h +++ b/include/linux/pinctrl/consumer.h @@ -15,7 +15,7 @@ #include #include #include -#include "pinctrl.h" +#include "pinctrl-state.h" /* This struct is private to the core and should be regarded as a cookie */ struct pinctrl; diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h index 3fd2f9dfc645..fee4349364f7 100644 --- a/include/linux/pinctrl/machine.h +++ b/include/linux/pinctrl/machine.h @@ -12,7 +12,7 @@ #ifndef __LINUX_PINCTRL_MACHINE_H #define __LINUX_PINCTRL_MACHINE_H -#include "pinctrl.h" +#include "pinctrl-state.h" enum pinctrl_map_type { PIN_MAP_TYPE_INVALID, diff --git a/include/linux/pinctrl/pinctrl-state.h b/include/linux/pinctrl/pinctrl-state.h new file mode 100644 index 000000000000..3920e28b4da7 --- /dev/null +++ b/include/linux/pinctrl/pinctrl-state.h @@ -0,0 +1,6 @@ +/* + * Standard pin control state definitions + */ + +#define PINCTRL_STATE_DEFAULT "default" +#define PINCTRL_STATE_IDLE "idle" diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h index bbdd7e16bada..e9e94eb52d79 100644 --- a/include/linux/pinctrl/pinctrl.h +++ b/include/linux/pinctrl/pinctrl.h @@ -17,8 +17,7 @@ #include #include #include - -#define PINCTRL_STATE_DEFAULT "default" +#include "pinctrl-state.h" struct pinctrl_dev; struct pinmux_ops; -- cgit v1.2.3 From 0acfb076f7987bd4bb5cd5de879ba3e3e71724e9 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 6 Mar 2012 12:12:12 -0700 Subject: pinctrl: forward-declare struct device Add a dummy declaration of struct device to avoid the following warning: In file included from include/linux/pinctrl/machine.h:15:0, from arch/arm/mach-tegra/board-pinmux.h:18, from arch/arm/mach-tegra/board-trimslice-pinmux.c:20: include/linux/pinctrl/pinctrl.h:115:12: warning: 'struct device' declared inside parameter list [enabled by default] include/linux/pinctrl/pinctrl.h:115:12: warning: its scope is only this definition or declaration, which is probably not what you want [enabled by default] Signed-off-by: Stephen Warren Signed-off-by: Linus Walleij --- include/linux/pinctrl/pinctrl.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h index e9e94eb52d79..4e9f0788c221 100644 --- a/include/linux/pinctrl/pinctrl.h +++ b/include/linux/pinctrl/pinctrl.h @@ -19,6 +19,7 @@ #include #include "pinctrl-state.h" +struct device; struct pinctrl_dev; struct pinmux_ops; struct pinconf_ops; -- cgit v1.2.3 From 394349f7789fdfcdc74b61afcac84046535c40b7 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 24 Nov 2011 18:27:15 +0100 Subject: pinctrl: introduce generic pin config This is a split-off from the earlier patch set which adds generic pin configuration for the pin controllers that want it. Since we may have a system with mixed generic and custom pin controllers, we pass a boolean in the pin controller ops vtable to indicate if it is generic. ChangeLog v1->v5: - Follow parent patch versioning number system. - Document the semantic meaning of return values from pin config get functions, so we can iterate over pins and check their properties from debugfs as part of the generic config code. - Use proper cast functions in the generic debugfs pin config file. - Expand generic config to optionally cover groups too. ChangeLog v5->v6: - Update to match underlying changes. ChangeLog v6->v7: - Drop DRIVE_OFF parameter, use bias high impedance for this - Delete argument for drive modes push-pull, od and os. These are now just state transitions. - Delete slew rate rising/falling due to discussions on on proper semantics - Drop config wakeup, struct irq_chip does this for now, add back if need be. - Set PIN_CONFIG_END to 0x7fff making room for custom config parameters from 0x8000 and up. - Prefix accessor functions with pinconf_ --- include/linux/pinctrl/pinconf-generic.h | 114 ++++++++++++++++++++++++++++++++ include/linux/pinctrl/pinconf.h | 5 ++ 2 files changed, 119 insertions(+) create mode 100644 include/linux/pinctrl/pinconf-generic.h (limited to 'include/linux') diff --git a/include/linux/pinctrl/pinconf-generic.h b/include/linux/pinctrl/pinconf-generic.h new file mode 100644 index 000000000000..4f0abb9f1c09 --- /dev/null +++ b/include/linux/pinctrl/pinconf-generic.h @@ -0,0 +1,114 @@ +/* + * Interface the generic pinconfig portions of the pinctrl subsystem + * + * Copyright (C) 2011 ST-Ericsson SA + * Written on behalf of Linaro for ST-Ericsson + * This interface is used in the core to keep track of pins. + * + * Author: Linus Walleij + * + * License terms: GNU General Public License (GPL) version 2 + */ +#ifndef __LINUX_PINCTRL_PINCONF_GENERIC_H +#define __LINUX_PINCTRL_PINCONF_GENERIC_H + +/* + * You shouldn't even be able to compile with these enums etc unless you're + * using generic pin config. That is why this is defined out. + */ +#ifdef CONFIG_GENERIC_PINCONF + +/** + * enum pin_config_param - possible pin configuration parameters + * @PIN_CONFIG_BIAS_DISABLE: disable any pin bias on the pin, a + * transition from say pull-up to pull-down implies that you disable + * pull-up in the process, this setting disables all biasing. + * @PIN_CONFIG_BIAS_HIGH_IMPEDANCE: the pin will be set to a high impedance + * mode, also know as "third-state" (tristate) or "high-Z" or "floating". + * On output pins this effectively disconnects the pin, which is useful + * if for example some other pin is going to drive the signal connected + * to it for a while. Pins used for input are usually always high + * impedance. + * @PIN_CONFIG_BIAS_PULL_UP: the pin will be pulled up (usually with high + * impedance to VDD). If the argument is != 0 pull-up is enabled, + * if it is 0, pull-up is disabled. + * @PIN_CONFIG_BIAS_PULL_DOWN: the pin will be pulled down (usually with high + * impedance to GROUND). If the argument is != 0 pull-down is enabled, + * if it is 0, pull-down is disabled. + * @PIN_CONFIG_DRIVE_PUSH_PULL: the pin will be driven actively high and + * low, this is the most typical case and is typically achieved with two + * active transistors on the output. Sending this config will enabale + * push-pull mode, the argument is ignored. + * @PIN_CONFIG_DRIVE_OPEN_DRAIN: the pin will be driven with open drain (open + * collector) which means it is usually wired with other output ports + * which are then pulled up with an external resistor. Sending this + * config will enabale open drain mode, the argument is ignored. + * @PIN_CONFIG_DRIVE_OPEN_SOURCE: the pin will be driven with open source + * (open emitter). Sending this config will enabale open drain mode, the + * argument is ignored. + * @PIN_CONFIG_INPUT_SCHMITT: this will configure an input pin to run in + * schmitt-trigger mode. If the schmitt-trigger has adjustable hysteresis, + * the threshold value is given on a custom format as argument when + * setting pins to this mode. The argument zero turns the schmitt trigger + * off. + * @PIN_CONFIG_INPUT_DEBOUNCE: this will configure the pin to debounce mode, + * which means it will wait for signals to settle when reading inputs. The + * argument gives the debounce time on a custom format. Setting the + * argument to zero turns debouncing off. + * @PIN_CONFIG_POWER_SOURCE: if the pin can select between different power + * supplies, the argument to this parameter (on a custom format) tells + * the driver which alternative power source to use. + * @PIN_CONFIG_LOW_POWER_MODE: this will configure the pin for low power + * operation, if several modes of operation are supported these can be + * passed in the argument on a custom form, else just use argument 1 + * to indicate low power mode, argument 0 turns low power mode off. + * @PIN_CONFIG_END: this is the last enumerator for pin configurations, if + * you need to pass in custom configurations to the pin controller, use + * PIN_CONFIG_END+1 as the base offset. + */ +enum pin_config_param { + PIN_CONFIG_BIAS_DISABLE, + PIN_CONFIG_BIAS_HIGH_IMPEDANCE, + PIN_CONFIG_BIAS_PULL_UP, + PIN_CONFIG_BIAS_PULL_DOWN, + PIN_CONFIG_DRIVE_PUSH_PULL, + PIN_CONFIG_DRIVE_OPEN_DRAIN, + PIN_CONFIG_DRIVE_OPEN_SOURCE, + PIN_CONFIG_INPUT_SCHMITT, + PIN_CONFIG_INPUT_DEBOUNCE, + PIN_CONFIG_POWER_SOURCE, + PIN_CONFIG_LOW_POWER_MODE, + PIN_CONFIG_END = 0x7FFF, +}; + +/* + * Helpful configuration macro to be used in tables etc. + */ +#define PIN_CONF_PACKED(p, a) ((a << 16) | ((unsigned long) p & 0xffffUL)) + +/* + * The following inlines stuffs a configuration parameter and data value + * into and out of an unsigned long argument, as used by the generic pin config + * system. We put the parameter in the lower 16 bits and the argument in the + * upper 16 bits. + */ + +static inline enum pin_config_param pinconf_to_config_param(unsigned long config) +{ + return (enum pin_config_param) (config & 0xffffUL); +} + +static inline u16 pinconf_to_config_argument(unsigned long config) +{ + return (enum pin_config_param) ((config >> 16) & 0xffffUL); +} + +static inline unsigned long pinconf_to_config_packed(enum pin_config_param param, + u16 argument) +{ + return PIN_CONF_PACKED(param, argument); +} + +#endif /* CONFIG_GENERIC_PINCONF */ + +#endif /* __LINUX_PINCTRL_PINCONF_GENERIC_H */ diff --git a/include/linux/pinctrl/pinconf.h b/include/linux/pinctrl/pinconf.h index f8cf156873d7..ec431f03362d 100644 --- a/include/linux/pinctrl/pinconf.h +++ b/include/linux/pinctrl/pinconf.h @@ -20,6 +20,8 @@ struct seq_file; /** * struct pinconf_ops - pin config operations, to be implemented by * pin configuration capable drivers. + * @is_generic: for pin controllers that want to use the generic interface, + * this flag tells the framework that it's generic. * @pin_config_get: get the config of a certain pin, if the requested config * is not available on this controller this should return -ENOTSUPP * and if it is available but disabled it should return -EINVAL @@ -33,6 +35,9 @@ struct seq_file; * per-device info for a certain group in debugfs */ struct pinconf_ops { +#ifdef CONFIG_GENERIC_PINCONF + bool is_generic; +#endif int (*pin_config_get) (struct pinctrl_dev *pctldev, unsigned pin, unsigned long *config); -- cgit v1.2.3