Some work to implement of_gpio_count()
cover Some work to implement of_gpio_count()
Hi all,
Few patches are needed to implement of_gpio_count() helper function.
So far there are two potential users for the new helper:
- PPC4xx SPI driver
http://www.mail-archive.com/[email protected]/msg26847.html
^^ The driver implements of_num_gpios() by itself. Though its implementation has some minor issues with regard to the empty cells. We'll convert it to the generic function later (the driver is a half way to the mainline, so I don't want to interfere. And it's another reason for the "of_gpio_count" name).
- Some MPC83xx SPI work I'm about to send.
Thanks,
Signature · 3 lines
Anton Vorontsov email: [email protected] irc://irc.freenode.net/bd2
PATCH 1/3 of: Minor simplification for the of_parse_phandles_with_args()
By using 'list++' in the beginning we can simplify the code a little bit.
--- drivers/of/base.c | 11 ++++------- 1 files changed, 4 insertions(+), 7 deletions(-)
drivers/of/base.c +4 -7
@@ -547,14 +547,12 @@ int of_parse_phandles_with_args(struct device_node *np, const char *list_name,const u32 *cells;const phandle *phandle; - phandle = list; - args = list +1 ; + phandle = list++; + args = list;/* one cell hole in the list = <>; */ -if (!*phandle) { - list++; +if (!*phandle) goto next; - } node =of_find_node_by_phandle (*phandle);if (!node) {
@@ -570,8 +568,7 @@ int of_parse_phandles_with_args(struct device_node *np, const char *list_name, goto err1; } -/* Next phandle is at offset of one phandle cell + #cells */ - list +=1 + *cells; + list += *cells;if (list > list_end) {pr_debug ("%s: insufficient arguments length\n" , np->full_name);
Signature · 1 line
1.5.6.5
PATCH 2/3 of: of_parse_phandles_with_args() learns to differentiate 'hole' cells
In reply to Anton VorontsovGiven this list (contains three gpio specifiers, one of which is a hole):
gpios = <&phandle1 1 2 3
0 /* a hole */
&phandle2 4 5 6>;of_parse_phandles_with_args() would report -ENOENT for the `hole' specifier item, the same error value is used to report the end of the list, for example.
Sometimes we want to differentiate holes from real errors -- for example when we want to count all the [syntax correct] specifiers.
With this patch of_parse_phandles_with_args() will report -EEXITS when somebody requested to parse a hole.
Also, make the out_{node,args} arguments optional, when counting we don't really need the out values.
--- drivers/of/base.c | 22 ++++++++++++++++------ 1 files changed, 16 insertions(+), 6 deletions(-)
drivers/of/base.c +16 -6
@@ -499,8 +499,8 @@ EXPORT_SYMBOL_GPL(of_modalias_node);* @list_name: property name that contains a list * @cells_name: property name that specifies phandles' arguments count * @index: index of a phandle to parse out -* @out_node: pointer to device_node struct pointer (will be filled) -* @out_args: pointer to arguments pointer (will be filled) +* @out_node: optional pointer to device_node struct pointer (will be filled) +* @out_args: optional pointer to arguments pointer (will be filled) * * This function is useful to parse lists of phandles and their arguments. * Returns 0 on success and fills out_node and out_args, on error returns
@@ -534,7 +534,7 @@ int of_parse_phandles_with_args(struct device_node *np, const char *list_name,int size;int cur_index =0 ;struct device_node *node =NULL ; -const void *args; +const void *args =NULL ; list =of_get_property (np, list_name, &size);if (!list) {
@@ -580,16 +580,26 @@ next:of_node_put (node); node =NULL ; + args =NULL ; cur_index++; }if (!node) { - ret = -ENOENT ; +/* +* args w/o node indicates that the loop above has stopped at +* the 'hole' cell. Report this differently. +*/ +if (args) + ret = -EEXIST ; +else + ret = -ENOENT ; goto err0; } - *out_node = node; - *out_args = args; +if (out_node) + *out_node = node; +if (out_args) + *out_args = args;return 0 ; err1:
Signature · 1 line
1.5.6.5
PATCH 3/3 of/gpio: Implement of_gpio_count()
In reply to Anton VorontsovThis function is used to count how many GPIOs are specified for a device node.
--- drivers/of/gpio.c | 34 ++++++++++++++++++++++++++++++++++ include/linux/of_gpio.h | 6 ++++++ 2 files changed, 40 insertions(+), 0 deletions(-)
drivers/of/gpio.c +34 -0
@@ -80,6 +80,40 @@ err0:EXPORT_SYMBOL (of_get_gpio_flags);/** +* of_gpio_count - Count GPIOs for a device +* @np: device node to count GPIOs for +* +* The function returns the count of GPIOs specified for a node. +* +* Note that the empty GPIO specifiers counts too. For example, +* +* gpios = <0 +* &pio1 1 2 +* 0 +* &pio2 3 4>; +* +* defines four GPIOs (so this function will return 4), two of which +* are not specified. +*/ +unsigned int of_gpio_count (struct device_node *np) +{ +unsigned int cnt =0 ; + +do { +int ret; + + ret =of_parse_phandles_with_args (np,"gpios" ,"#gpio-cells" , + cnt,NULL ,NULL ); +/* A hole in the gpios = <> counts anyway. */ +if (ret <0 && ret != -EEXIST ) +break ; + }while (++cnt); + +return cnt; +} +EXPORT_SYMBOL (of_gpio_count); + +/** * of_gpio_simple_xlate - translate gpio_spec to the GPIO number and flags * @of_gc: pointer to the of_gpio_chip structure * @np: device node of the GPIO chip
include/linux/of_gpio.h +6 -0
@@ -65,6 +65,7 @@ static inline struct of_mm_gpio_chip *to_of_mm_gpio_chip(struct gpio_chip *gc)extern int of_get_gpio_flags (struct device_node *np,int index,enum of_gpio_flags *flags); +extern unsigned int of_gpio_count (struct device_node *np);extern int of_mm_gpiochip_add (struct device_node *np,struct of_mm_gpio_chip *mm_gc);
@@ -81,6 +82,11 @@ static inline int of_get_gpio_flags(struct device_node *np, int index, return -ENOSYS; } +static inline unsigned int of_gpio_count (struct device_node *np) +{ +return 0 ; +} +#endif /* CONFIG_OF_GPIO */ /**
Signature · 1 line
1.5.6.5