These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / misc / sram.c
1 /*
2  * Generic on-chip SRAM allocation driver
3  *
4  * Copyright (C) 2012 Philipp Zabel, Pengutronix
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18  * MA 02110-1301, USA.
19  */
20
21 #include <linux/clk.h>
22 #include <linux/genalloc.h>
23 #include <linux/io.h>
24 #include <linux/list_sort.h>
25 #include <linux/of_address.h>
26 #include <linux/platform_device.h>
27 #include <linux/slab.h>
28
29 #define SRAM_GRANULARITY        32
30
31 struct sram_partition {
32         void __iomem *base;
33
34         struct gen_pool *pool;
35         struct bin_attribute battr;
36         struct mutex lock;
37 };
38
39 struct sram_dev {
40         struct device *dev;
41         void __iomem *virt_base;
42
43         struct gen_pool *pool;
44         struct clk *clk;
45
46         struct sram_partition *partition;
47         u32 partitions;
48 };
49
50 struct sram_reserve {
51         struct list_head list;
52         u32 start;
53         u32 size;
54         bool export;
55         bool pool;
56         const char *label;
57 };
58
59 static ssize_t sram_read(struct file *filp, struct kobject *kobj,
60                          struct bin_attribute *attr,
61                          char *buf, loff_t pos, size_t count)
62 {
63         struct sram_partition *part;
64
65         part = container_of(attr, struct sram_partition, battr);
66
67         mutex_lock(&part->lock);
68         memcpy_fromio(buf, part->base + pos, count);
69         mutex_unlock(&part->lock);
70
71         return count;
72 }
73
74 static ssize_t sram_write(struct file *filp, struct kobject *kobj,
75                           struct bin_attribute *attr,
76                           char *buf, loff_t pos, size_t count)
77 {
78         struct sram_partition *part;
79
80         part = container_of(attr, struct sram_partition, battr);
81
82         mutex_lock(&part->lock);
83         memcpy_toio(part->base + pos, buf, count);
84         mutex_unlock(&part->lock);
85
86         return count;
87 }
88
89 static int sram_add_pool(struct sram_dev *sram, struct sram_reserve *block,
90                          phys_addr_t start, struct sram_partition *part)
91 {
92         int ret;
93
94         part->pool = devm_gen_pool_create(sram->dev, ilog2(SRAM_GRANULARITY),
95                                           NUMA_NO_NODE, block->label);
96         if (IS_ERR(part->pool))
97                 return PTR_ERR(part->pool);
98
99         ret = gen_pool_add_virt(part->pool, (unsigned long)part->base, start,
100                                 block->size, NUMA_NO_NODE);
101         if (ret < 0) {
102                 dev_err(sram->dev, "failed to register subpool: %d\n", ret);
103                 return ret;
104         }
105
106         return 0;
107 }
108
109 static int sram_add_export(struct sram_dev *sram, struct sram_reserve *block,
110                            phys_addr_t start, struct sram_partition *part)
111 {
112         sysfs_bin_attr_init(&part->battr);
113         part->battr.attr.name = devm_kasprintf(sram->dev, GFP_KERNEL,
114                                                "%llx.sram",
115                                                (unsigned long long)start);
116         if (!part->battr.attr.name)
117                 return -ENOMEM;
118
119         part->battr.attr.mode = S_IRUSR | S_IWUSR;
120         part->battr.read = sram_read;
121         part->battr.write = sram_write;
122         part->battr.size = block->size;
123
124         return device_create_bin_file(sram->dev, &part->battr);
125 }
126
127 static int sram_add_partition(struct sram_dev *sram, struct sram_reserve *block,
128                               phys_addr_t start)
129 {
130         int ret;
131         struct sram_partition *part = &sram->partition[sram->partitions];
132
133         mutex_init(&part->lock);
134         part->base = sram->virt_base + block->start;
135
136         if (block->pool) {
137                 ret = sram_add_pool(sram, block, start, part);
138                 if (ret)
139                         return ret;
140         }
141         if (block->export) {
142                 ret = sram_add_export(sram, block, start, part);
143                 if (ret)
144                         return ret;
145         }
146         sram->partitions++;
147
148         return 0;
149 }
150
151 static void sram_free_partitions(struct sram_dev *sram)
152 {
153         struct sram_partition *part;
154
155         if (!sram->partitions)
156                 return;
157
158         part = &sram->partition[sram->partitions - 1];
159         for (; sram->partitions; sram->partitions--, part--) {
160                 if (part->battr.size)
161                         device_remove_bin_file(sram->dev, &part->battr);
162
163                 if (part->pool &&
164                     gen_pool_avail(part->pool) < gen_pool_size(part->pool))
165                         dev_err(sram->dev, "removed pool while SRAM allocated\n");
166         }
167 }
168
169 static int sram_reserve_cmp(void *priv, struct list_head *a,
170                                         struct list_head *b)
171 {
172         struct sram_reserve *ra = list_entry(a, struct sram_reserve, list);
173         struct sram_reserve *rb = list_entry(b, struct sram_reserve, list);
174
175         return ra->start - rb->start;
176 }
177
178 static int sram_reserve_regions(struct sram_dev *sram, struct resource *res)
179 {
180         struct device_node *np = sram->dev->of_node, *child;
181         unsigned long size, cur_start, cur_size;
182         struct sram_reserve *rblocks, *block;
183         struct list_head reserve_list;
184         unsigned int nblocks, exports = 0;
185         const char *label;
186         int ret = 0;
187
188         INIT_LIST_HEAD(&reserve_list);
189
190         size = resource_size(res);
191
192         /*
193          * We need an additional block to mark the end of the memory region
194          * after the reserved blocks from the dt are processed.
195          */
196         nblocks = (np) ? of_get_available_child_count(np) + 1 : 1;
197         rblocks = kzalloc((nblocks) * sizeof(*rblocks), GFP_KERNEL);
198         if (!rblocks)
199                 return -ENOMEM;
200
201         block = &rblocks[0];
202         for_each_available_child_of_node(np, child) {
203                 struct resource child_res;
204
205                 ret = of_address_to_resource(child, 0, &child_res);
206                 if (ret < 0) {
207                         dev_err(sram->dev,
208                                 "could not get address for node %s\n",
209                                 child->full_name);
210                         goto err_chunks;
211                 }
212
213                 if (child_res.start < res->start || child_res.end > res->end) {
214                         dev_err(sram->dev,
215                                 "reserved block %s outside the sram area\n",
216                                 child->full_name);
217                         ret = -EINVAL;
218                         goto err_chunks;
219                 }
220
221                 block->start = child_res.start - res->start;
222                 block->size = resource_size(&child_res);
223                 list_add_tail(&block->list, &reserve_list);
224
225                 if (of_find_property(child, "export", NULL))
226                         block->export = true;
227
228                 if (of_find_property(child, "pool", NULL))
229                         block->pool = true;
230
231                 if ((block->export || block->pool) && block->size) {
232                         exports++;
233
234                         label = NULL;
235                         ret = of_property_read_string(child, "label", &label);
236                         if (ret && ret != -EINVAL) {
237                                 dev_err(sram->dev,
238                                         "%s has invalid label name\n",
239                                         child->full_name);
240                                 goto err_chunks;
241                         }
242                         if (!label)
243                                 label = child->name;
244
245                         block->label = devm_kstrdup(sram->dev,
246                                                     label, GFP_KERNEL);
247                         if (!block->label)
248                                 goto err_chunks;
249
250                         dev_dbg(sram->dev, "found %sblock '%s' 0x%x-0x%x\n",
251                                 block->export ? "exported " : "", block->label,
252                                 block->start, block->start + block->size);
253                 } else {
254                         dev_dbg(sram->dev, "found reserved block 0x%x-0x%x\n",
255                                 block->start, block->start + block->size);
256                 }
257
258                 block++;
259         }
260         child = NULL;
261
262         /* the last chunk marks the end of the region */
263         rblocks[nblocks - 1].start = size;
264         rblocks[nblocks - 1].size = 0;
265         list_add_tail(&rblocks[nblocks - 1].list, &reserve_list);
266
267         list_sort(NULL, &reserve_list, sram_reserve_cmp);
268
269         if (exports) {
270                 sram->partition = devm_kzalloc(sram->dev,
271                                        exports * sizeof(*sram->partition),
272                                        GFP_KERNEL);
273                 if (!sram->partition) {
274                         ret = -ENOMEM;
275                         goto err_chunks;
276                 }
277         }
278
279         cur_start = 0;
280         list_for_each_entry(block, &reserve_list, list) {
281                 /* can only happen if sections overlap */
282                 if (block->start < cur_start) {
283                         dev_err(sram->dev,
284                                 "block at 0x%x starts after current offset 0x%lx\n",
285                                 block->start, cur_start);
286                         ret = -EINVAL;
287                         sram_free_partitions(sram);
288                         goto err_chunks;
289                 }
290
291                 if ((block->export || block->pool) && block->size) {
292                         ret = sram_add_partition(sram, block,
293                                                  res->start + block->start);
294                         if (ret) {
295                                 sram_free_partitions(sram);
296                                 goto err_chunks;
297                         }
298                 }
299
300                 /* current start is in a reserved block, so continue after it */
301                 if (block->start == cur_start) {
302                         cur_start = block->start + block->size;
303                         continue;
304                 }
305
306                 /*
307                  * allocate the space between the current starting
308                  * address and the following reserved block, or the
309                  * end of the region.
310                  */
311                 cur_size = block->start - cur_start;
312
313                 dev_dbg(sram->dev, "adding chunk 0x%lx-0x%lx\n",
314                         cur_start, cur_start + cur_size);
315
316                 ret = gen_pool_add_virt(sram->pool,
317                                 (unsigned long)sram->virt_base + cur_start,
318                                 res->start + cur_start, cur_size, -1);
319                 if (ret < 0) {
320                         sram_free_partitions(sram);
321                         goto err_chunks;
322                 }
323
324                 /* next allocation after this reserved block */
325                 cur_start = block->start + block->size;
326         }
327
328  err_chunks:
329         if (child)
330                 of_node_put(child);
331
332         kfree(rblocks);
333
334         return ret;
335 }
336
337 static int sram_probe(struct platform_device *pdev)
338 {
339         struct sram_dev *sram;
340         struct resource *res;
341         size_t size;
342         int ret;
343
344         sram = devm_kzalloc(&pdev->dev, sizeof(*sram), GFP_KERNEL);
345         if (!sram)
346                 return -ENOMEM;
347
348         sram->dev = &pdev->dev;
349
350         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
351         if (!res) {
352                 dev_err(sram->dev, "found no memory resource\n");
353                 return -EINVAL;
354         }
355
356         size = resource_size(res);
357
358         if (!devm_request_mem_region(sram->dev, res->start, size, pdev->name)) {
359                 dev_err(sram->dev, "could not request region for resource\n");
360                 return -EBUSY;
361         }
362
363         sram->virt_base = devm_ioremap_wc(sram->dev, res->start, size);
364         if (IS_ERR(sram->virt_base))
365                 return PTR_ERR(sram->virt_base);
366
367         sram->pool = devm_gen_pool_create(sram->dev, ilog2(SRAM_GRANULARITY),
368                                           NUMA_NO_NODE, NULL);
369         if (IS_ERR(sram->pool))
370                 return PTR_ERR(sram->pool);
371
372         ret = sram_reserve_regions(sram, res);
373         if (ret)
374                 return ret;
375
376         sram->clk = devm_clk_get(sram->dev, NULL);
377         if (IS_ERR(sram->clk))
378                 sram->clk = NULL;
379         else
380                 clk_prepare_enable(sram->clk);
381
382         platform_set_drvdata(pdev, sram);
383
384         dev_dbg(sram->dev, "SRAM pool: %zu KiB @ 0x%p\n",
385                 gen_pool_size(sram->pool) / 1024, sram->virt_base);
386
387         return 0;
388 }
389
390 static int sram_remove(struct platform_device *pdev)
391 {
392         struct sram_dev *sram = platform_get_drvdata(pdev);
393
394         sram_free_partitions(sram);
395
396         if (gen_pool_avail(sram->pool) < gen_pool_size(sram->pool))
397                 dev_err(sram->dev, "removed while SRAM allocated\n");
398
399         if (sram->clk)
400                 clk_disable_unprepare(sram->clk);
401
402         return 0;
403 }
404
405 #ifdef CONFIG_OF
406 static const struct of_device_id sram_dt_ids[] = {
407         { .compatible = "mmio-sram" },
408         {}
409 };
410 #endif
411
412 static struct platform_driver sram_driver = {
413         .driver = {
414                 .name = "sram",
415                 .of_match_table = of_match_ptr(sram_dt_ids),
416         },
417         .probe = sram_probe,
418         .remove = sram_remove,
419 };
420
421 static int __init sram_init(void)
422 {
423         return platform_driver_register(&sram_driver);
424 }
425
426 postcore_initcall(sram_init);