diff options
author | Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com> | 2018-10-04 09:01:08 -0400 |
---|---|---|
committer | Boris Brezillon <boris.brezillon@bootlin.com> | 2018-10-08 15:32:58 -0400 |
commit | 299b43535d3895bcde93cc7310b95b92b4fd8129 (patch) | |
tree | 603b46b071e9bd8dcd35b1e5548581433f9894f8 | |
parent | 0304f8eaa3aebc0480787139a26c7a19ac9936bd (diff) |
mtd: maps: gpio-addr-flash: Convert to gpiod
Convert from legacy gpio API to gpiod.
Board files will have to use gpiod_lookup_tables.
Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
Suggested-by: Boris Brezillon <boris.brezillon@bootlin.com>
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
-rw-r--r-- | drivers/mtd/maps/gpio-addr-flash.c | 55 |
1 files changed, 21 insertions, 34 deletions
diff --git a/drivers/mtd/maps/gpio-addr-flash.c b/drivers/mtd/maps/gpio-addr-flash.c index 47b12a6fead4..a20e85aa770e 100644 --- a/drivers/mtd/maps/gpio-addr-flash.c +++ b/drivers/mtd/maps/gpio-addr-flash.c | |||
@@ -14,6 +14,7 @@ | |||
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/gpio.h> | 16 | #include <linux/gpio.h> |
17 | #include <linux/gpio/consumer.h> | ||
17 | #include <linux/io.h> | 18 | #include <linux/io.h> |
18 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
19 | #include <linux/module.h> | 20 | #include <linux/module.h> |
@@ -33,16 +34,14 @@ | |||
33 | * struct async_state - keep GPIO flash state | 34 | * struct async_state - keep GPIO flash state |
34 | * @mtd: MTD state for this mapping | 35 | * @mtd: MTD state for this mapping |
35 | * @map: MTD map state for this flash | 36 | * @map: MTD map state for this flash |
36 | * @gpio_count: number of GPIOs used to address | 37 | * @gpios: Struct containing the array of GPIO descriptors |
37 | * @gpio_addrs: array of GPIOs to twiddle | ||
38 | * @gpio_values: cached GPIO values | 38 | * @gpio_values: cached GPIO values |
39 | * @win_order: dedicated memory size (if no GPIOs) | 39 | * @win_order: dedicated memory size (if no GPIOs) |
40 | */ | 40 | */ |
41 | struct async_state { | 41 | struct async_state { |
42 | struct mtd_info *mtd; | 42 | struct mtd_info *mtd; |
43 | struct map_info map; | 43 | struct map_info map; |
44 | size_t gpio_count; | 44 | struct gpio_descs *gpios; |
45 | unsigned *gpio_addrs; | ||
46 | unsigned int gpio_values; | 45 | unsigned int gpio_values; |
47 | unsigned int win_order; | 46 | unsigned int win_order; |
48 | }; | 47 | }; |
@@ -66,11 +65,11 @@ static void gf_set_gpios(struct async_state *state, unsigned long ofs) | |||
66 | if (ofs == state->gpio_values) | 65 | if (ofs == state->gpio_values) |
67 | return; | 66 | return; |
68 | 67 | ||
69 | for (i = 0; i < state->gpio_count; i++) { | 68 | for (i = 0; i < state->gpios->ndescs; i++) { |
70 | if ((ofs & BIT(i)) == (state->gpio_values & BIT(i))) | 69 | if ((ofs & BIT(i)) == (state->gpio_values & BIT(i))) |
71 | continue; | 70 | continue; |
72 | 71 | ||
73 | gpio_set_value(state->gpio_addrs[i], !!(ofs & BIT(i))); | 72 | gpiod_set_value(state->gpios->desc[i], !!(ofs & BIT(i))); |
74 | } | 73 | } |
75 | 74 | ||
76 | state->gpio_values = ofs; | 75 | state->gpio_values = ofs; |
@@ -182,18 +181,22 @@ static const char * const part_probe_types[] = { | |||
182 | * The platform resource layout expected looks something like: | 181 | * The platform resource layout expected looks something like: |
183 | * struct mtd_partition partitions[] = { ... }; | 182 | * struct mtd_partition partitions[] = { ... }; |
184 | * struct physmap_flash_data flash_data = { ... }; | 183 | * struct physmap_flash_data flash_data = { ... }; |
185 | * unsigned flash_gpios[] = { GPIO_XX, GPIO_XX, ... }; | 184 | * static struct gpiod_lookup_table addr_flash_gpios = { |
185 | * .dev_id = "gpio-addr-flash.0", | ||
186 | * .table = { | ||
187 | * GPIO_LOOKUP_IDX("gpio.0", 15, "addr", 0, GPIO_ACTIVE_HIGH), | ||
188 | * GPIO_LOOKUP_IDX("gpio.0", 16, "addr", 1, GPIO_ACTIVE_HIGH), | ||
189 | * ); | ||
190 | * }; | ||
191 | * gpiod_add_lookup_table(&addr_flash_gpios); | ||
192 | * | ||
186 | * struct resource flash_resource[] = { | 193 | * struct resource flash_resource[] = { |
187 | * { | 194 | * { |
188 | * .name = "cfi_probe", | 195 | * .name = "cfi_probe", |
189 | * .start = 0x20000000, | 196 | * .start = 0x20000000, |
190 | * .end = 0x201fffff, | 197 | * .end = 0x201fffff, |
191 | * .flags = IORESOURCE_MEM, | 198 | * .flags = IORESOURCE_MEM, |
192 | * }, { | 199 | * }, |
193 | * .start = (unsigned long)flash_gpios, | ||
194 | * .end = ARRAY_SIZE(flash_gpios), | ||
195 | * .flags = IORESOURCE_IRQ, | ||
196 | * } | ||
197 | * }; | 200 | * }; |
198 | * struct platform_device flash_device = { | 201 | * struct platform_device flash_device = { |
199 | * .name = "gpio-addr-flash", | 202 | * .name = "gpio-addr-flash", |
@@ -205,29 +208,24 @@ static const char * const part_probe_types[] = { | |||
205 | */ | 208 | */ |
206 | static int gpio_flash_probe(struct platform_device *pdev) | 209 | static int gpio_flash_probe(struct platform_device *pdev) |
207 | { | 210 | { |
208 | size_t i; | ||
209 | struct physmap_flash_data *pdata; | 211 | struct physmap_flash_data *pdata; |
210 | struct resource *memory; | 212 | struct resource *memory; |
211 | struct resource *gpios; | ||
212 | struct async_state *state; | 213 | struct async_state *state; |
213 | 214 | ||
214 | pdata = dev_get_platdata(&pdev->dev); | 215 | pdata = dev_get_platdata(&pdev->dev); |
215 | memory = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 216 | memory = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
216 | gpios = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
217 | 217 | ||
218 | if (!memory || !gpios || !gpios->end) | 218 | if (!memory) |
219 | return -EINVAL; | 219 | return -EINVAL; |
220 | 220 | ||
221 | state = devm_kzalloc(&pdev->dev, sizeof(*state), GFP_KERNEL); | 221 | state = devm_kzalloc(&pdev->dev, sizeof(*state), GFP_KERNEL); |
222 | if (!state) | 222 | if (!state) |
223 | return -ENOMEM; | 223 | return -ENOMEM; |
224 | 224 | ||
225 | /* | 225 | state->gpios = devm_gpiod_get_array(&pdev->dev, "addr", GPIOD_OUT_LOW); |
226 | * We cast start/end to known types in the boards file, so cast | 226 | if (IS_ERR(state->gpios)) |
227 | * away their pointer types here to the known types (gpios->xxx). | 227 | return PTR_ERR(state->gpios); |
228 | */ | 228 | |
229 | state->gpio_count = gpios->end; | ||
230 | state->gpio_addrs = (void *)(unsigned long)gpios->start; | ||
231 | state->win_order = get_bitmask_order(resource_size(memory)) - 1; | 229 | state->win_order = get_bitmask_order(resource_size(memory)) - 1; |
232 | 230 | ||
233 | state->map.name = DRIVER_NAME; | 231 | state->map.name = DRIVER_NAME; |
@@ -236,7 +234,7 @@ static int gpio_flash_probe(struct platform_device *pdev) | |||
236 | state->map.write = gf_write; | 234 | state->map.write = gf_write; |
237 | state->map.copy_to = gf_copy_to; | 235 | state->map.copy_to = gf_copy_to; |
238 | state->map.bankwidth = pdata->width; | 236 | state->map.bankwidth = pdata->width; |
239 | state->map.size = BIT(state->win_order + state->gpio_count); | 237 | state->map.size = BIT(state->win_order + state->gpios->ndescs); |
240 | state->map.virt = devm_ioremap_resource(&pdev->dev, memory); | 238 | state->map.virt = devm_ioremap_resource(&pdev->dev, memory); |
241 | if (IS_ERR(state->map.virt)) | 239 | if (IS_ERR(state->map.virt)) |
242 | return PTR_ERR(state->map.virt); | 240 | return PTR_ERR(state->map.virt); |
@@ -246,17 +244,6 @@ static int gpio_flash_probe(struct platform_device *pdev) | |||
246 | 244 | ||
247 | platform_set_drvdata(pdev, state); | 245 | platform_set_drvdata(pdev, state); |
248 | 246 | ||
249 | i = 0; | ||
250 | do { | ||
251 | if (devm_gpio_request(&pdev->dev, state->gpio_addrs[i], | ||
252 | DRIVER_NAME)) { | ||
253 | dev_err(&pdev->dev, "failed to request gpio %d\n", | ||
254 | state->gpio_addrs[i]); | ||
255 | return -EBUSY; | ||
256 | } | ||
257 | gpio_direction_output(state->gpio_addrs[i], 0); | ||
258 | } while (++i < state->gpio_count); | ||
259 | |||
260 | dev_notice(&pdev->dev, "probing %d-bit flash bus\n", | 247 | dev_notice(&pdev->dev, "probing %d-bit flash bus\n", |
261 | state->map.bankwidth * 8); | 248 | state->map.bankwidth * 8); |
262 | state->mtd = do_map_probe(memory->name, &state->map); | 249 | state->mtd = do_map_probe(memory->name, &state->map); |