Commit 023a6007a08d342b64895a7342e426d12d9627dd
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
Merge tag 'gpio-v4.0-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio
Pull GPIO fixes from Linus Walleij: "Two GPIO fixes: - Fix a translation problem in of_get_named_gpiod_flags() - Fix a long standing container_of() mistake in the TPS65912 driver" * tag 'gpio-v4.0-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio: gpio: tps65912: fix wrong container_of arguments gpiolib: of: allow of_gpiochip_find_and_xlate to find more than one chip per node
Showing 2 changed files Inline Diff
drivers/gpio/gpio-tps65912.c
1 | /* | 1 | /* |
2 | * Copyright 2011 Texas Instruments Inc. | 2 | * Copyright 2011 Texas Instruments Inc. |
3 | * | 3 | * |
4 | * Author: Margarita Olaya <magi@slimlogic.co.uk> | 4 | * Author: Margarita Olaya <magi@slimlogic.co.uk> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms of the GNU General Public License as published by the | 7 | * under the terms of the GNU General Public License as published by the |
8 | * Free Software Foundation; either version 2 of the License, or (at your | 8 | * Free Software Foundation; either version 2 of the License, or (at your |
9 | * option) any later version. | 9 | * option) any later version. |
10 | * | 10 | * |
11 | * This driver is based on wm8350 implementation. | 11 | * This driver is based on wm8350 implementation. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
17 | #include <linux/gpio.h> | 17 | #include <linux/gpio.h> |
18 | #include <linux/mfd/core.h> | 18 | #include <linux/mfd/core.h> |
19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
20 | #include <linux/seq_file.h> | 20 | #include <linux/seq_file.h> |
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <linux/mfd/tps65912.h> | 22 | #include <linux/mfd/tps65912.h> |
23 | 23 | ||
24 | struct tps65912_gpio_data { | 24 | struct tps65912_gpio_data { |
25 | struct tps65912 *tps65912; | 25 | struct tps65912 *tps65912; |
26 | struct gpio_chip gpio_chip; | 26 | struct gpio_chip gpio_chip; |
27 | }; | 27 | }; |
28 | 28 | ||
29 | #define to_tgd(gc) container_of(gc, struct tps65912_gpio_data, gpio_chip) | ||
30 | |||
29 | static int tps65912_gpio_get(struct gpio_chip *gc, unsigned offset) | 31 | static int tps65912_gpio_get(struct gpio_chip *gc, unsigned offset) |
30 | { | 32 | { |
31 | struct tps65912 *tps65912 = container_of(gc, struct tps65912, gpio); | 33 | struct tps65912_gpio_data *tps65912_gpio = to_tgd(gc); |
34 | struct tps65912 *tps65912 = tps65912_gpio->tps65912; | ||
32 | int val; | 35 | int val; |
33 | 36 | ||
34 | val = tps65912_reg_read(tps65912, TPS65912_GPIO1 + offset); | 37 | val = tps65912_reg_read(tps65912, TPS65912_GPIO1 + offset); |
35 | 38 | ||
36 | if (val & GPIO_STS_MASK) | 39 | if (val & GPIO_STS_MASK) |
37 | return 1; | 40 | return 1; |
38 | 41 | ||
39 | return 0; | 42 | return 0; |
40 | } | 43 | } |
41 | 44 | ||
42 | static void tps65912_gpio_set(struct gpio_chip *gc, unsigned offset, | 45 | static void tps65912_gpio_set(struct gpio_chip *gc, unsigned offset, |
43 | int value) | 46 | int value) |
44 | { | 47 | { |
45 | struct tps65912 *tps65912 = container_of(gc, struct tps65912, gpio); | 48 | struct tps65912_gpio_data *tps65912_gpio = to_tgd(gc); |
49 | struct tps65912 *tps65912 = tps65912_gpio->tps65912; | ||
46 | 50 | ||
47 | if (value) | 51 | if (value) |
48 | tps65912_set_bits(tps65912, TPS65912_GPIO1 + offset, | 52 | tps65912_set_bits(tps65912, TPS65912_GPIO1 + offset, |
49 | GPIO_SET_MASK); | 53 | GPIO_SET_MASK); |
50 | else | 54 | else |
51 | tps65912_clear_bits(tps65912, TPS65912_GPIO1 + offset, | 55 | tps65912_clear_bits(tps65912, TPS65912_GPIO1 + offset, |
52 | GPIO_SET_MASK); | 56 | GPIO_SET_MASK); |
53 | } | 57 | } |
54 | 58 | ||
55 | static int tps65912_gpio_output(struct gpio_chip *gc, unsigned offset, | 59 | static int tps65912_gpio_output(struct gpio_chip *gc, unsigned offset, |
56 | int value) | 60 | int value) |
57 | { | 61 | { |
58 | struct tps65912 *tps65912 = container_of(gc, struct tps65912, gpio); | 62 | struct tps65912_gpio_data *tps65912_gpio = to_tgd(gc); |
63 | struct tps65912 *tps65912 = tps65912_gpio->tps65912; | ||
59 | 64 | ||
60 | /* Set the initial value */ | 65 | /* Set the initial value */ |
61 | tps65912_gpio_set(gc, offset, value); | 66 | tps65912_gpio_set(gc, offset, value); |
62 | 67 | ||
63 | return tps65912_set_bits(tps65912, TPS65912_GPIO1 + offset, | 68 | return tps65912_set_bits(tps65912, TPS65912_GPIO1 + offset, |
64 | GPIO_CFG_MASK); | 69 | GPIO_CFG_MASK); |
65 | } | 70 | } |
66 | 71 | ||
67 | static int tps65912_gpio_input(struct gpio_chip *gc, unsigned offset) | 72 | static int tps65912_gpio_input(struct gpio_chip *gc, unsigned offset) |
68 | { | 73 | { |
69 | struct tps65912 *tps65912 = container_of(gc, struct tps65912, gpio); | 74 | struct tps65912_gpio_data *tps65912_gpio = to_tgd(gc); |
75 | struct tps65912 *tps65912 = tps65912_gpio->tps65912; | ||
70 | 76 | ||
71 | return tps65912_clear_bits(tps65912, TPS65912_GPIO1 + offset, | 77 | return tps65912_clear_bits(tps65912, TPS65912_GPIO1 + offset, |
72 | GPIO_CFG_MASK); | 78 | GPIO_CFG_MASK); |
73 | } | 79 | } |
74 | 80 | ||
75 | static struct gpio_chip template_chip = { | 81 | static struct gpio_chip template_chip = { |
76 | .label = "tps65912", | 82 | .label = "tps65912", |
77 | .owner = THIS_MODULE, | 83 | .owner = THIS_MODULE, |
78 | .direction_input = tps65912_gpio_input, | 84 | .direction_input = tps65912_gpio_input, |
79 | .direction_output = tps65912_gpio_output, | 85 | .direction_output = tps65912_gpio_output, |
80 | .get = tps65912_gpio_get, | 86 | .get = tps65912_gpio_get, |
81 | .set = tps65912_gpio_set, | 87 | .set = tps65912_gpio_set, |
82 | .can_sleep = true, | 88 | .can_sleep = true, |
83 | .ngpio = 5, | 89 | .ngpio = 5, |
84 | .base = -1, | 90 | .base = -1, |
85 | }; | 91 | }; |
86 | 92 | ||
87 | static int tps65912_gpio_probe(struct platform_device *pdev) | 93 | static int tps65912_gpio_probe(struct platform_device *pdev) |
88 | { | 94 | { |
89 | struct tps65912 *tps65912 = dev_get_drvdata(pdev->dev.parent); | 95 | struct tps65912 *tps65912 = dev_get_drvdata(pdev->dev.parent); |
90 | struct tps65912_board *pdata = dev_get_platdata(tps65912->dev); | 96 | struct tps65912_board *pdata = dev_get_platdata(tps65912->dev); |
91 | struct tps65912_gpio_data *tps65912_gpio; | 97 | struct tps65912_gpio_data *tps65912_gpio; |
92 | int ret; | 98 | int ret; |
93 | 99 | ||
94 | tps65912_gpio = devm_kzalloc(&pdev->dev, sizeof(*tps65912_gpio), | 100 | tps65912_gpio = devm_kzalloc(&pdev->dev, sizeof(*tps65912_gpio), |
95 | GFP_KERNEL); | 101 | GFP_KERNEL); |
96 | if (tps65912_gpio == NULL) | 102 | if (tps65912_gpio == NULL) |
97 | return -ENOMEM; | 103 | return -ENOMEM; |
98 | 104 | ||
99 | tps65912_gpio->tps65912 = tps65912; | 105 | tps65912_gpio->tps65912 = tps65912; |
100 | tps65912_gpio->gpio_chip = template_chip; | 106 | tps65912_gpio->gpio_chip = template_chip; |
101 | tps65912_gpio->gpio_chip.dev = &pdev->dev; | 107 | tps65912_gpio->gpio_chip.dev = &pdev->dev; |
102 | if (pdata && pdata->gpio_base) | 108 | if (pdata && pdata->gpio_base) |
103 | tps65912_gpio->gpio_chip.base = pdata->gpio_base; | 109 | tps65912_gpio->gpio_chip.base = pdata->gpio_base; |
104 | 110 | ||
105 | ret = gpiochip_add(&tps65912_gpio->gpio_chip); | 111 | ret = gpiochip_add(&tps65912_gpio->gpio_chip); |
106 | if (ret < 0) { | 112 | if (ret < 0) { |
107 | dev_err(&pdev->dev, "Failed to register gpiochip, %d\n", ret); | 113 | dev_err(&pdev->dev, "Failed to register gpiochip, %d\n", ret); |
108 | return ret; | 114 | return ret; |
109 | } | 115 | } |
110 | 116 | ||
111 | platform_set_drvdata(pdev, tps65912_gpio); | 117 | platform_set_drvdata(pdev, tps65912_gpio); |
112 | 118 | ||
113 | return ret; | 119 | return ret; |
114 | } | 120 | } |
115 | 121 | ||
116 | static int tps65912_gpio_remove(struct platform_device *pdev) | 122 | static int tps65912_gpio_remove(struct platform_device *pdev) |
117 | { | 123 | { |
118 | struct tps65912_gpio_data *tps65912_gpio = platform_get_drvdata(pdev); | 124 | struct tps65912_gpio_data *tps65912_gpio = platform_get_drvdata(pdev); |
119 | 125 | ||
120 | gpiochip_remove(&tps65912_gpio->gpio_chip); | 126 | gpiochip_remove(&tps65912_gpio->gpio_chip); |
121 | return 0; | 127 | return 0; |
122 | } | 128 | } |
123 | 129 | ||
124 | static struct platform_driver tps65912_gpio_driver = { | 130 | static struct platform_driver tps65912_gpio_driver = { |
125 | .driver = { | 131 | .driver = { |
126 | .name = "tps65912-gpio", | 132 | .name = "tps65912-gpio", |
127 | }, | 133 | }, |
128 | .probe = tps65912_gpio_probe, | 134 | .probe = tps65912_gpio_probe, |
129 | .remove = tps65912_gpio_remove, | 135 | .remove = tps65912_gpio_remove, |
130 | }; | 136 | }; |
131 | 137 | ||
132 | static int __init tps65912_gpio_init(void) | 138 | static int __init tps65912_gpio_init(void) |
133 | { | 139 | { |
134 | return platform_driver_register(&tps65912_gpio_driver); | 140 | return platform_driver_register(&tps65912_gpio_driver); |
135 | } | 141 | } |
136 | subsys_initcall(tps65912_gpio_init); | 142 | subsys_initcall(tps65912_gpio_init); |
137 | 143 | ||
138 | static void __exit tps65912_gpio_exit(void) | 144 | static void __exit tps65912_gpio_exit(void) |
139 | { | 145 | { |
140 | platform_driver_unregister(&tps65912_gpio_driver); | 146 | platform_driver_unregister(&tps65912_gpio_driver); |
141 | } | 147 | } |
142 | module_exit(tps65912_gpio_exit); | 148 | module_exit(tps65912_gpio_exit); |
143 | 149 | ||
144 | MODULE_AUTHOR("Margarita Olaya Cabrera <magi@slimlogic.co.uk>"); | 150 | MODULE_AUTHOR("Margarita Olaya Cabrera <magi@slimlogic.co.uk>"); |
145 | MODULE_DESCRIPTION("GPIO interface for TPS65912 PMICs"); | 151 | MODULE_DESCRIPTION("GPIO interface for TPS65912 PMICs"); |
146 | MODULE_LICENSE("GPL v2"); | 152 | MODULE_LICENSE("GPL v2"); |
147 | MODULE_ALIAS("platform:tps65912-gpio"); | 153 | MODULE_ALIAS("platform:tps65912-gpio"); |
148 | 154 |
drivers/gpio/gpiolib-of.c
1 | /* | 1 | /* |
2 | * OF helpers for the GPIO API | 2 | * OF helpers for the GPIO API |
3 | * | 3 | * |
4 | * Copyright (c) 2007-2008 MontaVista Software, Inc. | 4 | * Copyright (c) 2007-2008 MontaVista Software, Inc. |
5 | * | 5 | * |
6 | * Author: Anton Vorontsov <avorontsov@ru.mvista.com> | 6 | * Author: Anton Vorontsov <avorontsov@ru.mvista.com> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
10 | * the Free Software Foundation; either version 2 of the License, or | 10 | * the Free Software Foundation; either version 2 of the License, or |
11 | * (at your option) any later version. | 11 | * (at your option) any later version. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/device.h> | 14 | #include <linux/device.h> |
15 | #include <linux/err.h> | 15 | #include <linux/err.h> |
16 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/io.h> | 18 | #include <linux/io.h> |
19 | #include <linux/gpio/consumer.h> | 19 | #include <linux/gpio/consumer.h> |
20 | #include <linux/of.h> | 20 | #include <linux/of.h> |
21 | #include <linux/of_address.h> | 21 | #include <linux/of_address.h> |
22 | #include <linux/of_gpio.h> | 22 | #include <linux/of_gpio.h> |
23 | #include <linux/pinctrl/pinctrl.h> | 23 | #include <linux/pinctrl/pinctrl.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | 25 | ||
26 | #include "gpiolib.h" | 26 | #include "gpiolib.h" |
27 | 27 | ||
28 | /* Private data structure for of_gpiochip_find_and_xlate */ | 28 | /* Private data structure for of_gpiochip_find_and_xlate */ |
29 | struct gg_data { | 29 | struct gg_data { |
30 | enum of_gpio_flags *flags; | 30 | enum of_gpio_flags *flags; |
31 | struct of_phandle_args gpiospec; | 31 | struct of_phandle_args gpiospec; |
32 | 32 | ||
33 | struct gpio_desc *out_gpio; | 33 | struct gpio_desc *out_gpio; |
34 | }; | 34 | }; |
35 | 35 | ||
36 | /* Private function for resolving node pointer to gpio_chip */ | 36 | /* Private function for resolving node pointer to gpio_chip */ |
37 | static int of_gpiochip_find_and_xlate(struct gpio_chip *gc, void *data) | 37 | static int of_gpiochip_find_and_xlate(struct gpio_chip *gc, void *data) |
38 | { | 38 | { |
39 | struct gg_data *gg_data = data; | 39 | struct gg_data *gg_data = data; |
40 | int ret; | 40 | int ret; |
41 | 41 | ||
42 | if ((gc->of_node != gg_data->gpiospec.np) || | 42 | if ((gc->of_node != gg_data->gpiospec.np) || |
43 | (gc->of_gpio_n_cells != gg_data->gpiospec.args_count) || | 43 | (gc->of_gpio_n_cells != gg_data->gpiospec.args_count) || |
44 | (!gc->of_xlate)) | 44 | (!gc->of_xlate)) |
45 | return false; | 45 | return false; |
46 | 46 | ||
47 | ret = gc->of_xlate(gc, &gg_data->gpiospec, gg_data->flags); | 47 | ret = gc->of_xlate(gc, &gg_data->gpiospec, gg_data->flags); |
48 | if (ret < 0) { | 48 | if (ret < 0) { |
49 | /* We've found the gpio chip, but the translation failed. | 49 | /* We've found a gpio chip, but the translation failed. |
50 | * Return true to stop looking and return the translation | 50 | * Store translation error in out_gpio. |
51 | * error via out_gpio | 51 | * Return false to keep looking, as more than one gpio chip |
52 | * could be registered per of-node. | ||
52 | */ | 53 | */ |
53 | gg_data->out_gpio = ERR_PTR(ret); | 54 | gg_data->out_gpio = ERR_PTR(ret); |
54 | return true; | 55 | return false; |
55 | } | 56 | } |
56 | 57 | ||
57 | gg_data->out_gpio = gpiochip_get_desc(gc, ret); | 58 | gg_data->out_gpio = gpiochip_get_desc(gc, ret); |
58 | return true; | 59 | return true; |
59 | } | 60 | } |
60 | 61 | ||
61 | /** | 62 | /** |
62 | * of_get_named_gpiod_flags() - Get a GPIO descriptor and flags for GPIO API | 63 | * of_get_named_gpiod_flags() - Get a GPIO descriptor and flags for GPIO API |
63 | * @np: device node to get GPIO from | 64 | * @np: device node to get GPIO from |
64 | * @propname: property name containing gpio specifier(s) | 65 | * @propname: property name containing gpio specifier(s) |
65 | * @index: index of the GPIO | 66 | * @index: index of the GPIO |
66 | * @flags: a flags pointer to fill in | 67 | * @flags: a flags pointer to fill in |
67 | * | 68 | * |
68 | * Returns GPIO descriptor to use with Linux GPIO API, or one of the errno | 69 | * Returns GPIO descriptor to use with Linux GPIO API, or one of the errno |
69 | * value on the error condition. If @flags is not NULL the function also fills | 70 | * value on the error condition. If @flags is not NULL the function also fills |
70 | * in flags for the GPIO. | 71 | * in flags for the GPIO. |
71 | */ | 72 | */ |
72 | struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np, | 73 | struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np, |
73 | const char *propname, int index, enum of_gpio_flags *flags) | 74 | const char *propname, int index, enum of_gpio_flags *flags) |
74 | { | 75 | { |
75 | /* Return -EPROBE_DEFER to support probe() functions to be called | 76 | /* Return -EPROBE_DEFER to support probe() functions to be called |
76 | * later when the GPIO actually becomes available | 77 | * later when the GPIO actually becomes available |
77 | */ | 78 | */ |
78 | struct gg_data gg_data = { | 79 | struct gg_data gg_data = { |
79 | .flags = flags, | 80 | .flags = flags, |
80 | .out_gpio = ERR_PTR(-EPROBE_DEFER) | 81 | .out_gpio = ERR_PTR(-EPROBE_DEFER) |
81 | }; | 82 | }; |
82 | int ret; | 83 | int ret; |
83 | 84 | ||
84 | /* .of_xlate might decide to not fill in the flags, so clear it. */ | 85 | /* .of_xlate might decide to not fill in the flags, so clear it. */ |
85 | if (flags) | 86 | if (flags) |
86 | *flags = 0; | 87 | *flags = 0; |
87 | 88 | ||
88 | ret = of_parse_phandle_with_args(np, propname, "#gpio-cells", index, | 89 | ret = of_parse_phandle_with_args(np, propname, "#gpio-cells", index, |
89 | &gg_data.gpiospec); | 90 | &gg_data.gpiospec); |
90 | if (ret) { | 91 | if (ret) { |
91 | pr_debug("%s: can't parse '%s' property of node '%s[%d]'\n", | 92 | pr_debug("%s: can't parse '%s' property of node '%s[%d]'\n", |
92 | __func__, propname, np->full_name, index); | 93 | __func__, propname, np->full_name, index); |
93 | return ERR_PTR(ret); | 94 | return ERR_PTR(ret); |
94 | } | 95 | } |
95 | 96 | ||
96 | gpiochip_find(&gg_data, of_gpiochip_find_and_xlate); | 97 | gpiochip_find(&gg_data, of_gpiochip_find_and_xlate); |
97 | 98 | ||
98 | of_node_put(gg_data.gpiospec.np); | 99 | of_node_put(gg_data.gpiospec.np); |
99 | pr_debug("%s: parsed '%s' property of node '%s[%d]' - status (%d)\n", | 100 | pr_debug("%s: parsed '%s' property of node '%s[%d]' - status (%d)\n", |
100 | __func__, propname, np->full_name, index, | 101 | __func__, propname, np->full_name, index, |
101 | PTR_ERR_OR_ZERO(gg_data.out_gpio)); | 102 | PTR_ERR_OR_ZERO(gg_data.out_gpio)); |
102 | return gg_data.out_gpio; | 103 | return gg_data.out_gpio; |
103 | } | 104 | } |
104 | 105 | ||
105 | int of_get_named_gpio_flags(struct device_node *np, const char *list_name, | 106 | int of_get_named_gpio_flags(struct device_node *np, const char *list_name, |
106 | int index, enum of_gpio_flags *flags) | 107 | int index, enum of_gpio_flags *flags) |
107 | { | 108 | { |
108 | struct gpio_desc *desc; | 109 | struct gpio_desc *desc; |
109 | 110 | ||
110 | desc = of_get_named_gpiod_flags(np, list_name, index, flags); | 111 | desc = of_get_named_gpiod_flags(np, list_name, index, flags); |
111 | 112 | ||
112 | if (IS_ERR(desc)) | 113 | if (IS_ERR(desc)) |
113 | return PTR_ERR(desc); | 114 | return PTR_ERR(desc); |
114 | else | 115 | else |
115 | return desc_to_gpio(desc); | 116 | return desc_to_gpio(desc); |
116 | } | 117 | } |
117 | EXPORT_SYMBOL(of_get_named_gpio_flags); | 118 | EXPORT_SYMBOL(of_get_named_gpio_flags); |
118 | 119 | ||
119 | /** | 120 | /** |
120 | * of_gpio_simple_xlate - translate gpio_spec to the GPIO number and flags | 121 | * of_gpio_simple_xlate - translate gpio_spec to the GPIO number and flags |
121 | * @gc: pointer to the gpio_chip structure | 122 | * @gc: pointer to the gpio_chip structure |
122 | * @np: device node of the GPIO chip | 123 | * @np: device node of the GPIO chip |
123 | * @gpio_spec: gpio specifier as found in the device tree | 124 | * @gpio_spec: gpio specifier as found in the device tree |
124 | * @flags: a flags pointer to fill in | 125 | * @flags: a flags pointer to fill in |
125 | * | 126 | * |
126 | * This is simple translation function, suitable for the most 1:1 mapped | 127 | * This is simple translation function, suitable for the most 1:1 mapped |
127 | * gpio chips. This function performs only one sanity check: whether gpio | 128 | * gpio chips. This function performs only one sanity check: whether gpio |
128 | * is less than ngpios (that is specified in the gpio_chip). | 129 | * is less than ngpios (that is specified in the gpio_chip). |
129 | */ | 130 | */ |
130 | int of_gpio_simple_xlate(struct gpio_chip *gc, | 131 | int of_gpio_simple_xlate(struct gpio_chip *gc, |
131 | const struct of_phandle_args *gpiospec, u32 *flags) | 132 | const struct of_phandle_args *gpiospec, u32 *flags) |
132 | { | 133 | { |
133 | /* | 134 | /* |
134 | * We're discouraging gpio_cells < 2, since that way you'll have to | 135 | * We're discouraging gpio_cells < 2, since that way you'll have to |
135 | * write your own xlate function (that will have to retrive the GPIO | 136 | * write your own xlate function (that will have to retrive the GPIO |
136 | * number and the flags from a single gpio cell -- this is possible, | 137 | * number and the flags from a single gpio cell -- this is possible, |
137 | * but not recommended). | 138 | * but not recommended). |
138 | */ | 139 | */ |
139 | if (gc->of_gpio_n_cells < 2) { | 140 | if (gc->of_gpio_n_cells < 2) { |
140 | WARN_ON(1); | 141 | WARN_ON(1); |
141 | return -EINVAL; | 142 | return -EINVAL; |
142 | } | 143 | } |
143 | 144 | ||
144 | if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells)) | 145 | if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells)) |
145 | return -EINVAL; | 146 | return -EINVAL; |
146 | 147 | ||
147 | if (gpiospec->args[0] >= gc->ngpio) | 148 | if (gpiospec->args[0] >= gc->ngpio) |
148 | return -EINVAL; | 149 | return -EINVAL; |
149 | 150 | ||
150 | if (flags) | 151 | if (flags) |
151 | *flags = gpiospec->args[1]; | 152 | *flags = gpiospec->args[1]; |
152 | 153 | ||
153 | return gpiospec->args[0]; | 154 | return gpiospec->args[0]; |
154 | } | 155 | } |
155 | EXPORT_SYMBOL(of_gpio_simple_xlate); | 156 | EXPORT_SYMBOL(of_gpio_simple_xlate); |
156 | 157 | ||
157 | /** | 158 | /** |
158 | * of_mm_gpiochip_add - Add memory mapped GPIO chip (bank) | 159 | * of_mm_gpiochip_add - Add memory mapped GPIO chip (bank) |
159 | * @np: device node of the GPIO chip | 160 | * @np: device node of the GPIO chip |
160 | * @mm_gc: pointer to the of_mm_gpio_chip allocated structure | 161 | * @mm_gc: pointer to the of_mm_gpio_chip allocated structure |
161 | * | 162 | * |
162 | * To use this function you should allocate and fill mm_gc with: | 163 | * To use this function you should allocate and fill mm_gc with: |
163 | * | 164 | * |
164 | * 1) In the gpio_chip structure: | 165 | * 1) In the gpio_chip structure: |
165 | * - all the callbacks | 166 | * - all the callbacks |
166 | * - of_gpio_n_cells | 167 | * - of_gpio_n_cells |
167 | * - of_xlate callback (optional) | 168 | * - of_xlate callback (optional) |
168 | * | 169 | * |
169 | * 3) In the of_mm_gpio_chip structure: | 170 | * 3) In the of_mm_gpio_chip structure: |
170 | * - save_regs callback (optional) | 171 | * - save_regs callback (optional) |
171 | * | 172 | * |
172 | * If succeeded, this function will map bank's memory and will | 173 | * If succeeded, this function will map bank's memory and will |
173 | * do all necessary work for you. Then you'll able to use .regs | 174 | * do all necessary work for you. Then you'll able to use .regs |
174 | * to manage GPIOs from the callbacks. | 175 | * to manage GPIOs from the callbacks. |
175 | */ | 176 | */ |
176 | int of_mm_gpiochip_add(struct device_node *np, | 177 | int of_mm_gpiochip_add(struct device_node *np, |
177 | struct of_mm_gpio_chip *mm_gc) | 178 | struct of_mm_gpio_chip *mm_gc) |
178 | { | 179 | { |
179 | int ret = -ENOMEM; | 180 | int ret = -ENOMEM; |
180 | struct gpio_chip *gc = &mm_gc->gc; | 181 | struct gpio_chip *gc = &mm_gc->gc; |
181 | 182 | ||
182 | gc->label = kstrdup(np->full_name, GFP_KERNEL); | 183 | gc->label = kstrdup(np->full_name, GFP_KERNEL); |
183 | if (!gc->label) | 184 | if (!gc->label) |
184 | goto err0; | 185 | goto err0; |
185 | 186 | ||
186 | mm_gc->regs = of_iomap(np, 0); | 187 | mm_gc->regs = of_iomap(np, 0); |
187 | if (!mm_gc->regs) | 188 | if (!mm_gc->regs) |
188 | goto err1; | 189 | goto err1; |
189 | 190 | ||
190 | gc->base = -1; | 191 | gc->base = -1; |
191 | 192 | ||
192 | if (mm_gc->save_regs) | 193 | if (mm_gc->save_regs) |
193 | mm_gc->save_regs(mm_gc); | 194 | mm_gc->save_regs(mm_gc); |
194 | 195 | ||
195 | mm_gc->gc.of_node = np; | 196 | mm_gc->gc.of_node = np; |
196 | 197 | ||
197 | ret = gpiochip_add(gc); | 198 | ret = gpiochip_add(gc); |
198 | if (ret) | 199 | if (ret) |
199 | goto err2; | 200 | goto err2; |
200 | 201 | ||
201 | return 0; | 202 | return 0; |
202 | err2: | 203 | err2: |
203 | iounmap(mm_gc->regs); | 204 | iounmap(mm_gc->regs); |
204 | err1: | 205 | err1: |
205 | kfree(gc->label); | 206 | kfree(gc->label); |
206 | err0: | 207 | err0: |
207 | pr_err("%s: GPIO chip registration failed with status %d\n", | 208 | pr_err("%s: GPIO chip registration failed with status %d\n", |
208 | np->full_name, ret); | 209 | np->full_name, ret); |
209 | return ret; | 210 | return ret; |
210 | } | 211 | } |
211 | EXPORT_SYMBOL(of_mm_gpiochip_add); | 212 | EXPORT_SYMBOL(of_mm_gpiochip_add); |
212 | 213 | ||
213 | /** | 214 | /** |
214 | * of_mm_gpiochip_remove - Remove memory mapped GPIO chip (bank) | 215 | * of_mm_gpiochip_remove - Remove memory mapped GPIO chip (bank) |
215 | * @mm_gc: pointer to the of_mm_gpio_chip allocated structure | 216 | * @mm_gc: pointer to the of_mm_gpio_chip allocated structure |
216 | */ | 217 | */ |
217 | void of_mm_gpiochip_remove(struct of_mm_gpio_chip *mm_gc) | 218 | void of_mm_gpiochip_remove(struct of_mm_gpio_chip *mm_gc) |
218 | { | 219 | { |
219 | struct gpio_chip *gc = &mm_gc->gc; | 220 | struct gpio_chip *gc = &mm_gc->gc; |
220 | 221 | ||
221 | if (!mm_gc) | 222 | if (!mm_gc) |
222 | return; | 223 | return; |
223 | 224 | ||
224 | gpiochip_remove(gc); | 225 | gpiochip_remove(gc); |
225 | iounmap(mm_gc->regs); | 226 | iounmap(mm_gc->regs); |
226 | kfree(gc->label); | 227 | kfree(gc->label); |
227 | } | 228 | } |
228 | EXPORT_SYMBOL(of_mm_gpiochip_remove); | 229 | EXPORT_SYMBOL(of_mm_gpiochip_remove); |
229 | 230 | ||
230 | #ifdef CONFIG_PINCTRL | 231 | #ifdef CONFIG_PINCTRL |
231 | static void of_gpiochip_add_pin_range(struct gpio_chip *chip) | 232 | static void of_gpiochip_add_pin_range(struct gpio_chip *chip) |
232 | { | 233 | { |
233 | struct device_node *np = chip->of_node; | 234 | struct device_node *np = chip->of_node; |
234 | struct of_phandle_args pinspec; | 235 | struct of_phandle_args pinspec; |
235 | struct pinctrl_dev *pctldev; | 236 | struct pinctrl_dev *pctldev; |
236 | int index = 0, ret; | 237 | int index = 0, ret; |
237 | const char *name; | 238 | const char *name; |
238 | static const char group_names_propname[] = "gpio-ranges-group-names"; | 239 | static const char group_names_propname[] = "gpio-ranges-group-names"; |
239 | struct property *group_names; | 240 | struct property *group_names; |
240 | 241 | ||
241 | if (!np) | 242 | if (!np) |
242 | return; | 243 | return; |
243 | 244 | ||
244 | group_names = of_find_property(np, group_names_propname, NULL); | 245 | group_names = of_find_property(np, group_names_propname, NULL); |
245 | 246 | ||
246 | for (;; index++) { | 247 | for (;; index++) { |
247 | ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, | 248 | ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, |
248 | index, &pinspec); | 249 | index, &pinspec); |
249 | if (ret) | 250 | if (ret) |
250 | break; | 251 | break; |
251 | 252 | ||
252 | pctldev = of_pinctrl_get(pinspec.np); | 253 | pctldev = of_pinctrl_get(pinspec.np); |
253 | if (!pctldev) | 254 | if (!pctldev) |
254 | break; | 255 | break; |
255 | 256 | ||
256 | if (pinspec.args[2]) { | 257 | if (pinspec.args[2]) { |
257 | if (group_names) { | 258 | if (group_names) { |
258 | ret = of_property_read_string_index(np, | 259 | ret = of_property_read_string_index(np, |
259 | group_names_propname, | 260 | group_names_propname, |
260 | index, &name); | 261 | index, &name); |
261 | if (strlen(name)) { | 262 | if (strlen(name)) { |
262 | pr_err("%s: Group name of numeric GPIO ranges must be the empty string.\n", | 263 | pr_err("%s: Group name of numeric GPIO ranges must be the empty string.\n", |
263 | np->full_name); | 264 | np->full_name); |
264 | break; | 265 | break; |
265 | } | 266 | } |
266 | } | 267 | } |
267 | /* npins != 0: linear range */ | 268 | /* npins != 0: linear range */ |
268 | ret = gpiochip_add_pin_range(chip, | 269 | ret = gpiochip_add_pin_range(chip, |
269 | pinctrl_dev_get_devname(pctldev), | 270 | pinctrl_dev_get_devname(pctldev), |
270 | pinspec.args[0], | 271 | pinspec.args[0], |
271 | pinspec.args[1], | 272 | pinspec.args[1], |
272 | pinspec.args[2]); | 273 | pinspec.args[2]); |
273 | if (ret) | 274 | if (ret) |
274 | break; | 275 | break; |
275 | } else { | 276 | } else { |
276 | /* npins == 0: special range */ | 277 | /* npins == 0: special range */ |
277 | if (pinspec.args[1]) { | 278 | if (pinspec.args[1]) { |
278 | pr_err("%s: Illegal gpio-range format.\n", | 279 | pr_err("%s: Illegal gpio-range format.\n", |
279 | np->full_name); | 280 | np->full_name); |
280 | break; | 281 | break; |
281 | } | 282 | } |
282 | 283 | ||
283 | if (!group_names) { | 284 | if (!group_names) { |
284 | pr_err("%s: GPIO group range requested but no %s property.\n", | 285 | pr_err("%s: GPIO group range requested but no %s property.\n", |
285 | np->full_name, group_names_propname); | 286 | np->full_name, group_names_propname); |
286 | break; | 287 | break; |
287 | } | 288 | } |
288 | 289 | ||
289 | ret = of_property_read_string_index(np, | 290 | ret = of_property_read_string_index(np, |
290 | group_names_propname, | 291 | group_names_propname, |
291 | index, &name); | 292 | index, &name); |
292 | if (ret) | 293 | if (ret) |
293 | break; | 294 | break; |
294 | 295 | ||
295 | if (!strlen(name)) { | 296 | if (!strlen(name)) { |
296 | pr_err("%s: Group name of GPIO group range cannot be the empty string.\n", | 297 | pr_err("%s: Group name of GPIO group range cannot be the empty string.\n", |
297 | np->full_name); | 298 | np->full_name); |
298 | break; | 299 | break; |
299 | } | 300 | } |
300 | 301 | ||
301 | ret = gpiochip_add_pingroup_range(chip, pctldev, | 302 | ret = gpiochip_add_pingroup_range(chip, pctldev, |
302 | pinspec.args[0], name); | 303 | pinspec.args[0], name); |
303 | if (ret) | 304 | if (ret) |
304 | break; | 305 | break; |
305 | } | 306 | } |
306 | } | 307 | } |
307 | } | 308 | } |
308 | 309 | ||
309 | #else | 310 | #else |
310 | static void of_gpiochip_add_pin_range(struct gpio_chip *chip) {} | 311 | static void of_gpiochip_add_pin_range(struct gpio_chip *chip) {} |
311 | #endif | 312 | #endif |
312 | 313 | ||
313 | void of_gpiochip_add(struct gpio_chip *chip) | 314 | void of_gpiochip_add(struct gpio_chip *chip) |
314 | { | 315 | { |
315 | if ((!chip->of_node) && (chip->dev)) | 316 | if ((!chip->of_node) && (chip->dev)) |
316 | chip->of_node = chip->dev->of_node; | 317 | chip->of_node = chip->dev->of_node; |
317 | 318 | ||
318 | if (!chip->of_node) | 319 | if (!chip->of_node) |
319 | return; | 320 | return; |
320 | 321 | ||
321 | if (!chip->of_xlate) { | 322 | if (!chip->of_xlate) { |
322 | chip->of_gpio_n_cells = 2; | 323 | chip->of_gpio_n_cells = 2; |
323 | chip->of_xlate = of_gpio_simple_xlate; | 324 | chip->of_xlate = of_gpio_simple_xlate; |
324 | } | 325 | } |
325 | 326 | ||
326 | of_gpiochip_add_pin_range(chip); | 327 | of_gpiochip_add_pin_range(chip); |
327 | of_node_get(chip->of_node); | 328 | of_node_get(chip->of_node); |
328 | } | 329 | } |
329 | 330 | ||
330 | void of_gpiochip_remove(struct gpio_chip *chip) | 331 | void of_gpiochip_remove(struct gpio_chip *chip) |
331 | { | 332 | { |
332 | gpiochip_remove_pin_ranges(chip); | 333 | gpiochip_remove_pin_ranges(chip); |
333 | of_node_put(chip->of_node); | 334 | of_node_put(chip->of_node); |
334 | } | 335 | } |
335 | 336 |