Merge branch 'parisc-4.20-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller...
[sfrench/cifs-2.6.git] / drivers / mtd / maps / gpio-addr-flash.c
1 /*
2  * drivers/mtd/maps/gpio-addr-flash.c
3  *
4  * Handle the case where a flash device is mostly addressed using physical
5  * line and supplemented by GPIOs.  This way you can hook up say a 8MiB flash
6  * to a 2MiB memory range and use the GPIOs to select a particular range.
7  *
8  * Copyright © 2000 Nicolas Pitre <nico@cam.org>
9  * Copyright © 2005-2009 Analog Devices Inc.
10  *
11  * Enter bugs at http://blackfin.uclinux.org/
12  *
13  * Licensed under the GPL-2 or later.
14  */
15
16 #include <linux/gpio.h>
17 #include <linux/gpio/consumer.h>
18 #include <linux/io.h>
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21 #include <linux/mtd/mtd.h>
22 #include <linux/mtd/map.h>
23 #include <linux/mtd/partitions.h>
24 #include <linux/mtd/physmap.h>
25 #include <linux/platform_device.h>
26 #include <linux/slab.h>
27 #include <linux/types.h>
28
29 #define win_mask(x) ((BIT(x)) - 1)
30
31 #define DRIVER_NAME "gpio-addr-flash"
32
33 /**
34  * struct async_state - keep GPIO flash state
35  *      @mtd:         MTD state for this mapping
36  *      @map:         MTD map state for this flash
37  *      @gpios:       Struct containing the array of GPIO descriptors
38  *      @gpio_values: cached GPIO values
39  *      @win_order:   dedicated memory size (if no GPIOs)
40  */
41 struct async_state {
42         struct mtd_info *mtd;
43         struct map_info map;
44         struct gpio_descs *gpios;
45         unsigned int gpio_values;
46         unsigned int win_order;
47 };
48 #define gf_map_info_to_state(mi) ((struct async_state *)(mi)->map_priv_1)
49
50 /**
51  * gf_set_gpios() - set GPIO address lines to access specified flash offset
52  *      @state: GPIO flash state
53  *      @ofs:   desired offset to access
54  *
55  * Rather than call the GPIO framework every time, cache the last-programmed
56  * value.  This speeds up sequential accesses (which are by far the most common
57  * type).
58  */
59 static void gf_set_gpios(struct async_state *state, unsigned long ofs)
60 {
61         int i;
62
63         ofs >>= state->win_order;
64
65         if (ofs == state->gpio_values)
66                 return;
67
68         for (i = 0; i < state->gpios->ndescs; i++) {
69                 if ((ofs & BIT(i)) == (state->gpio_values & BIT(i)))
70                         continue;
71
72                 gpiod_set_value(state->gpios->desc[i], !!(ofs & BIT(i)));
73         }
74
75         state->gpio_values = ofs;
76 }
77
78 /**
79  * gf_read() - read a word at the specified offset
80  *      @map: MTD map state
81  *      @ofs: desired offset to read
82  */
83 static map_word gf_read(struct map_info *map, unsigned long ofs)
84 {
85         struct async_state *state = gf_map_info_to_state(map);
86         uint16_t word;
87         map_word test;
88
89         gf_set_gpios(state, ofs);
90
91         word = readw(map->virt + (ofs & win_mask(state->win_order)));
92         test.x[0] = word;
93         return test;
94 }
95
96 /**
97  * gf_copy_from() - copy a chunk of data from the flash
98  *      @map:  MTD map state
99  *      @to:   memory to copy to
100  *      @from: flash offset to copy from
101  *      @len:  how much to copy
102  *
103  * The "from" region may straddle more than one window, so toggle the GPIOs for
104  * each window region before reading its data.
105  */
106 static void gf_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
107 {
108         struct async_state *state = gf_map_info_to_state(map);
109
110         int this_len;
111
112         while (len) {
113                 this_len = from & win_mask(state->win_order);
114                 this_len = BIT(state->win_order) - this_len;
115                 this_len = min_t(int, len, this_len);
116
117                 gf_set_gpios(state, from);
118                 memcpy_fromio(to,
119                               map->virt + (from & win_mask(state->win_order)),
120                               this_len);
121                 len -= this_len;
122                 from += this_len;
123                 to += this_len;
124         }
125 }
126
127 /**
128  * gf_write() - write a word at the specified offset
129  *      @map: MTD map state
130  *      @ofs: desired offset to write
131  */
132 static void gf_write(struct map_info *map, map_word d1, unsigned long ofs)
133 {
134         struct async_state *state = gf_map_info_to_state(map);
135         uint16_t d;
136
137         gf_set_gpios(state, ofs);
138
139         d = d1.x[0];
140         writew(d, map->virt + (ofs & win_mask(state->win_order)));
141 }
142
143 /**
144  * gf_copy_to() - copy a chunk of data to the flash
145  *      @map:  MTD map state
146  *      @to:   flash offset to copy to
147  *      @from: memory to copy from
148  *      @len:  how much to copy
149  *
150  * See gf_copy_from() caveat.
151  */
152 static void gf_copy_to(struct map_info *map, unsigned long to,
153                        const void *from, ssize_t len)
154 {
155         struct async_state *state = gf_map_info_to_state(map);
156
157         int this_len;
158
159         while (len) {
160                 this_len = to & win_mask(state->win_order);
161                 this_len = BIT(state->win_order) - this_len;
162                 this_len = min_t(int, len, this_len);
163
164                 gf_set_gpios(state, to);
165                 memcpy_toio(map->virt + (to & win_mask(state->win_order)),
166                             from, len);
167
168                 len -= this_len;
169                 to += this_len;
170                 from += this_len;
171         }
172 }
173
174 static const char * const part_probe_types[] = {
175         "cmdlinepart", "RedBoot", NULL };
176
177 /**
178  * gpio_flash_probe() - setup a mapping for a GPIO assisted flash
179  *      @pdev: platform device
180  *
181  * The platform resource layout expected looks something like:
182  * struct mtd_partition partitions[] = { ... };
183  * struct physmap_flash_data flash_data = { ... };
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  *
193  * struct resource flash_resource[] = {
194  *      {
195  *              .name  = "cfi_probe",
196  *              .start = 0x20000000,
197  *              .end   = 0x201fffff,
198  *              .flags = IORESOURCE_MEM,
199  *      },
200  * };
201  * struct platform_device flash_device = {
202  *      .name          = "gpio-addr-flash",
203  *      .dev           = { .platform_data = &flash_data, },
204  *      .num_resources = ARRAY_SIZE(flash_resource),
205  *      .resource      = flash_resource,
206  *      ...
207  * };
208  */
209 static int gpio_flash_probe(struct platform_device *pdev)
210 {
211         struct physmap_flash_data *pdata;
212         struct resource *memory;
213         struct async_state *state;
214
215         pdata = dev_get_platdata(&pdev->dev);
216         memory = platform_get_resource(pdev, IORESOURCE_MEM, 0);
217
218         if (!memory)
219                 return -EINVAL;
220
221         state = devm_kzalloc(&pdev->dev, sizeof(*state), GFP_KERNEL);
222         if (!state)
223                 return -ENOMEM;
224
225         state->gpios = devm_gpiod_get_array(&pdev->dev, "addr", GPIOD_OUT_LOW);
226         if (IS_ERR(state->gpios))
227                 return PTR_ERR(state->gpios);
228
229         state->win_order      = get_bitmask_order(resource_size(memory)) - 1;
230
231         state->map.name       = DRIVER_NAME;
232         state->map.read       = gf_read;
233         state->map.copy_from  = gf_copy_from;
234         state->map.write      = gf_write;
235         state->map.copy_to    = gf_copy_to;
236         state->map.bankwidth  = pdata->width;
237         state->map.size       = BIT(state->win_order + state->gpios->ndescs);
238         state->map.virt       = devm_ioremap_resource(&pdev->dev, memory);
239         if (IS_ERR(state->map.virt))
240                 return PTR_ERR(state->map.virt);
241
242         state->map.phys       = NO_XIP;
243         state->map.map_priv_1 = (unsigned long)state;
244
245         platform_set_drvdata(pdev, state);
246
247         dev_notice(&pdev->dev, "probing %d-bit flash bus\n",
248                    state->map.bankwidth * 8);
249         state->mtd = do_map_probe(memory->name, &state->map);
250         if (!state->mtd)
251                 return -ENXIO;
252         state->mtd->dev.parent = &pdev->dev;
253
254         mtd_device_parse_register(state->mtd, part_probe_types, NULL,
255                                   pdata->parts, pdata->nr_parts);
256
257         return 0;
258 }
259
260 static int gpio_flash_remove(struct platform_device *pdev)
261 {
262         struct async_state *state = platform_get_drvdata(pdev);
263
264         mtd_device_unregister(state->mtd);
265         map_destroy(state->mtd);
266         return 0;
267 }
268
269 static struct platform_driver gpio_flash_driver = {
270         .probe          = gpio_flash_probe,
271         .remove         = gpio_flash_remove,
272         .driver         = {
273                 .name   = DRIVER_NAME,
274         },
275 };
276
277 module_platform_driver(gpio_flash_driver);
278
279 MODULE_AUTHOR("Mike Frysinger <vapier@gentoo.org>");
280 MODULE_DESCRIPTION("MTD map driver for flashes addressed physically and with gpios");
281 MODULE_LICENSE("GPL");