0654f0e6b320965cc458be99ea504b4698a34a47
[platform/kernel/linux-starfive.git] / drivers / char / bsr.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* IBM POWER Barrier Synchronization Register Driver
3  *
4  * Copyright IBM Corporation 2008
5  *
6  * Author: Sonny Rao <sonnyrao@us.ibm.com>
7  */
8
9 #include <linux/kernel.h>
10 #include <linux/of.h>
11 #include <linux/of_address.h>
12 #include <linux/of_device.h>
13 #include <linux/of_platform.h>
14 #include <linux/fs.h>
15 #include <linux/module.h>
16 #include <linux/cdev.h>
17 #include <linux/list.h>
18 #include <linux/mm.h>
19 #include <linux/slab.h>
20 #include <asm/io.h>
21
22 /*
23  This driver exposes a special register which can be used for fast
24  synchronization across a large SMP machine.  The hardware is exposed
25  as an array of bytes where each process will write to one of the bytes to
26  indicate it has finished the current stage and this update is broadcast to
27  all processors without having to bounce a cacheline between them. In
28  POWER5 and POWER6 there is one of these registers per SMP,  but it is
29  presented in two forms; first, it is given as a whole and then as a number
30  of smaller registers which alias to parts of the single whole register.
31  This can potentially allow multiple groups of processes to each have their
32  own private synchronization device.
33
34  Note that this hardware *must* be written to using *only* single byte writes.
35  It may be read using 1, 2, 4, or 8 byte loads which must be aligned since
36  this region is treated as cache-inhibited  processes should also use a
37  full sync before and after writing to the BSR to ensure all stores and
38  the BSR update have made it to all chips in the system
39 */
40
41 /* This is arbitrary number, up to Power6 it's been 17 or fewer  */
42 #define BSR_MAX_DEVS (32)
43
44 struct bsr_dev {
45         u64      bsr_addr;     /* Real address */
46         u64      bsr_len;      /* length of mem region we can map */
47         unsigned bsr_bytes;    /* size of the BSR reg itself */
48         unsigned bsr_stride;   /* interval at which BSR repeats in the page */
49         unsigned bsr_type;     /* maps to enum below */
50         unsigned bsr_num;      /* bsr id number for its type */
51         int      bsr_minor;
52
53         struct list_head bsr_list;
54
55         dev_t    bsr_dev;
56         struct cdev bsr_cdev;
57         struct device *bsr_device;
58         char     bsr_name[32];
59
60 };
61
62 static unsigned total_bsr_devs;
63 static LIST_HEAD(bsr_devs);
64 static int bsr_major;
65
66 enum {
67         BSR_8    = 0,
68         BSR_16   = 1,
69         BSR_64   = 2,
70         BSR_128  = 3,
71         BSR_4096 = 4,
72         BSR_UNKNOWN = 5,
73         BSR_MAX  = 6,
74 };
75
76 static unsigned bsr_types[BSR_MAX];
77
78 static ssize_t
79 bsr_size_show(struct device *dev, struct device_attribute *attr, char *buf)
80 {
81         struct bsr_dev *bsr_dev = dev_get_drvdata(dev);
82         return sprintf(buf, "%u\n", bsr_dev->bsr_bytes);
83 }
84 static DEVICE_ATTR_RO(bsr_size);
85
86 static ssize_t
87 bsr_stride_show(struct device *dev, struct device_attribute *attr, char *buf)
88 {
89         struct bsr_dev *bsr_dev = dev_get_drvdata(dev);
90         return sprintf(buf, "%u\n", bsr_dev->bsr_stride);
91 }
92 static DEVICE_ATTR_RO(bsr_stride);
93
94 static ssize_t
95 bsr_length_show(struct device *dev, struct device_attribute *attr, char *buf)
96 {
97         struct bsr_dev *bsr_dev = dev_get_drvdata(dev);
98         return sprintf(buf, "%llu\n", bsr_dev->bsr_len);
99 }
100 static DEVICE_ATTR_RO(bsr_length);
101
102 static struct attribute *bsr_dev_attrs[] = {
103         &dev_attr_bsr_size.attr,
104         &dev_attr_bsr_stride.attr,
105         &dev_attr_bsr_length.attr,
106         NULL,
107 };
108 ATTRIBUTE_GROUPS(bsr_dev);
109
110 static const struct class bsr_class = {
111         .name           = "bsr",
112         .dev_groups     = bsr_dev_groups,
113 };
114
115 static int bsr_mmap(struct file *filp, struct vm_area_struct *vma)
116 {
117         unsigned long size   = vma->vm_end - vma->vm_start;
118         struct bsr_dev *dev = filp->private_data;
119         int ret;
120
121         vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
122
123         /* check for the case of a small BSR device and map one 4k page for it*/
124         if (dev->bsr_len < PAGE_SIZE && size == PAGE_SIZE)
125                 ret = remap_4k_pfn(vma, vma->vm_start, dev->bsr_addr >> 12,
126                                    vma->vm_page_prot);
127         else if (size <= dev->bsr_len)
128                 ret = io_remap_pfn_range(vma, vma->vm_start,
129                                          dev->bsr_addr >> PAGE_SHIFT,
130                                          size, vma->vm_page_prot);
131         else
132                 return -EINVAL;
133
134         if (ret)
135                 return -EAGAIN;
136
137         return 0;
138 }
139
140 static int bsr_open(struct inode *inode, struct file *filp)
141 {
142         struct cdev *cdev = inode->i_cdev;
143         struct bsr_dev *dev = container_of(cdev, struct bsr_dev, bsr_cdev);
144
145         filp->private_data = dev;
146         return 0;
147 }
148
149 static const struct file_operations bsr_fops = {
150         .owner = THIS_MODULE,
151         .mmap  = bsr_mmap,
152         .open  = bsr_open,
153         .llseek = noop_llseek,
154 };
155
156 static void bsr_cleanup_devs(void)
157 {
158         struct bsr_dev *cur, *n;
159
160         list_for_each_entry_safe(cur, n, &bsr_devs, bsr_list) {
161                 if (cur->bsr_device) {
162                         cdev_del(&cur->bsr_cdev);
163                         device_del(cur->bsr_device);
164                 }
165                 list_del(&cur->bsr_list);
166                 kfree(cur);
167         }
168 }
169
170 static int bsr_add_node(struct device_node *bn)
171 {
172         int bsr_stride_len, bsr_bytes_len, num_bsr_devs;
173         const u32 *bsr_stride;
174         const u32 *bsr_bytes;
175         unsigned i;
176         int ret = -ENODEV;
177
178         bsr_stride = of_get_property(bn, "ibm,lock-stride", &bsr_stride_len);
179         bsr_bytes  = of_get_property(bn, "ibm,#lock-bytes", &bsr_bytes_len);
180
181         if (!bsr_stride || !bsr_bytes ||
182             (bsr_stride_len != bsr_bytes_len)) {
183                 printk(KERN_ERR "bsr of-node has missing/incorrect property\n");
184                 return ret;
185         }
186
187         num_bsr_devs = bsr_bytes_len / sizeof(u32);
188
189         for (i = 0 ; i < num_bsr_devs; i++) {
190                 struct bsr_dev *cur = kzalloc(sizeof(struct bsr_dev),
191                                               GFP_KERNEL);
192                 struct resource res;
193                 int result;
194
195                 if (!cur) {
196                         printk(KERN_ERR "Unable to alloc bsr dev\n");
197                         ret = -ENOMEM;
198                         goto out_err;
199                 }
200
201                 result = of_address_to_resource(bn, i, &res);
202                 if (result < 0) {
203                         printk(KERN_ERR "bsr of-node has invalid reg property, skipping\n");
204                         kfree(cur);
205                         continue;
206                 }
207
208                 cur->bsr_minor  = i + total_bsr_devs;
209                 cur->bsr_addr   = res.start;
210                 cur->bsr_len    = resource_size(&res);
211                 cur->bsr_bytes  = bsr_bytes[i];
212                 cur->bsr_stride = bsr_stride[i];
213                 cur->bsr_dev    = MKDEV(bsr_major, i + total_bsr_devs);
214
215                 /* if we have a bsr_len of > 4k and less then PAGE_SIZE (64k pages) */
216                 /* we can only map 4k of it, so only advertise the 4k in sysfs */
217                 if (cur->bsr_len > 4096 && cur->bsr_len < PAGE_SIZE)
218                         cur->bsr_len = 4096;
219
220                 switch(cur->bsr_bytes) {
221                 case 8:
222                         cur->bsr_type = BSR_8;
223                         break;
224                 case 16:
225                         cur->bsr_type = BSR_16;
226                         break;
227                 case 64:
228                         cur->bsr_type = BSR_64;
229                         break;
230                 case 128:
231                         cur->bsr_type = BSR_128;
232                         break;
233                 case 4096:
234                         cur->bsr_type = BSR_4096;
235                         break;
236                 default:
237                         cur->bsr_type = BSR_UNKNOWN;
238                 }
239
240                 cur->bsr_num = bsr_types[cur->bsr_type];
241                 snprintf(cur->bsr_name, 32, "bsr%d_%d",
242                          cur->bsr_bytes, cur->bsr_num);
243
244                 cdev_init(&cur->bsr_cdev, &bsr_fops);
245                 result = cdev_add(&cur->bsr_cdev, cur->bsr_dev, 1);
246                 if (result) {
247                         kfree(cur);
248                         goto out_err;
249                 }
250
251                 cur->bsr_device = device_create(&bsr_class, NULL, cur->bsr_dev,
252                                                 cur, "%s", cur->bsr_name);
253                 if (IS_ERR(cur->bsr_device)) {
254                         printk(KERN_ERR "device_create failed for %s\n",
255                                cur->bsr_name);
256                         cdev_del(&cur->bsr_cdev);
257                         kfree(cur);
258                         goto out_err;
259                 }
260
261                 bsr_types[cur->bsr_type] = cur->bsr_num + 1;
262                 list_add_tail(&cur->bsr_list, &bsr_devs);
263         }
264
265         total_bsr_devs += num_bsr_devs;
266
267         return 0;
268
269  out_err:
270
271         bsr_cleanup_devs();
272         return ret;
273 }
274
275 static int bsr_create_devs(struct device_node *bn)
276 {
277         int ret;
278
279         while (bn) {
280                 ret = bsr_add_node(bn);
281                 if (ret) {
282                         of_node_put(bn);
283                         return ret;
284                 }
285                 bn = of_find_compatible_node(bn, NULL, "ibm,bsr");
286         }
287         return 0;
288 }
289
290 static int __init bsr_init(void)
291 {
292         struct device_node *np;
293         dev_t bsr_dev;
294         int ret = -ENODEV;
295
296         np = of_find_compatible_node(NULL, NULL, "ibm,bsr");
297         if (!np)
298                 goto out_err;
299
300         ret = class_register(&bsr_class);
301         if (err)
302                 goto out_err_1;
303
304         ret = alloc_chrdev_region(&bsr_dev, 0, BSR_MAX_DEVS, "bsr");
305         bsr_major = MAJOR(bsr_dev);
306         if (ret < 0) {
307                 printk(KERN_ERR "alloc_chrdev_region() failed for bsr\n");
308                 goto out_err_2;
309         }
310
311         ret = bsr_create_devs(np);
312         if (ret < 0) {
313                 np = NULL;
314                 goto out_err_3;
315         }
316
317         return 0;
318
319  out_err_3:
320         unregister_chrdev_region(bsr_dev, BSR_MAX_DEVS);
321
322  out_err_2:
323         class_unregister(&bsr_class);
324
325  out_err_1:
326         of_node_put(np);
327
328  out_err:
329
330         return ret;
331 }
332
333 static void __exit  bsr_exit(void)
334 {
335
336         bsr_cleanup_devs();
337
338         class_unregister(&bsr_class);
339
340         if (bsr_major)
341                 unregister_chrdev_region(MKDEV(bsr_major, 0), BSR_MAX_DEVS);
342 }
343
344 module_init(bsr_init);
345 module_exit(bsr_exit);
346 MODULE_LICENSE("GPL");
347 MODULE_AUTHOR("Sonny Rao <sonnyrao@us.ibm.com>");