Merge tag 'selinux-pr-20190726' of git://git.kernel.org/pub/scm/linux/kernel/git...
[sfrench/cifs-2.6.git] / drivers / fsi / fsi-scom.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * SCOM FSI Client device driver
4  *
5  * Copyright (C) IBM Corporation 2016
6  */
7
8 #include <linux/fsi.h>
9 #include <linux/module.h>
10 #include <linux/cdev.h>
11 #include <linux/delay.h>
12 #include <linux/fs.h>
13 #include <linux/uaccess.h>
14 #include <linux/slab.h>
15 #include <linux/list.h>
16
17 #include <uapi/linux/fsi.h>
18
19 #define FSI_ENGID_SCOM          0x5
20
21 /* SCOM engine register set */
22 #define SCOM_DATA0_REG          0x00
23 #define SCOM_DATA1_REG          0x04
24 #define SCOM_CMD_REG            0x08
25 #define SCOM_FSI2PIB_RESET_REG  0x18
26 #define SCOM_STATUS_REG         0x1C /* Read */
27 #define SCOM_PIB_RESET_REG      0x1C /* Write */
28
29 /* Command register */
30 #define SCOM_WRITE_CMD          0x80000000
31 #define SCOM_READ_CMD           0x00000000
32
33 /* Status register bits */
34 #define SCOM_STATUS_ERR_SUMMARY         0x80000000
35 #define SCOM_STATUS_PROTECTION          0x01000000
36 #define SCOM_STATUS_PARITY              0x04000000
37 #define SCOM_STATUS_PIB_ABORT           0x00100000
38 #define SCOM_STATUS_PIB_RESP_MASK       0x00007000
39 #define SCOM_STATUS_PIB_RESP_SHIFT      12
40
41 #define SCOM_STATUS_ANY_ERR             (SCOM_STATUS_ERR_SUMMARY | \
42                                          SCOM_STATUS_PROTECTION | \
43                                          SCOM_STATUS_PARITY |     \
44                                          SCOM_STATUS_PIB_ABORT | \
45                                          SCOM_STATUS_PIB_RESP_MASK)
46 /* SCOM address encodings */
47 #define XSCOM_ADDR_IND_FLAG             BIT_ULL(63)
48 #define XSCOM_ADDR_INF_FORM1            BIT_ULL(60)
49
50 /* SCOM indirect stuff */
51 #define XSCOM_ADDR_DIRECT_PART          0x7fffffffull
52 #define XSCOM_ADDR_INDIRECT_PART        0x000fffff00000000ull
53 #define XSCOM_DATA_IND_READ             BIT_ULL(63)
54 #define XSCOM_DATA_IND_COMPLETE         BIT_ULL(31)
55 #define XSCOM_DATA_IND_ERR_MASK         0x70000000ull
56 #define XSCOM_DATA_IND_ERR_SHIFT        28
57 #define XSCOM_DATA_IND_DATA             0x0000ffffull
58 #define XSCOM_DATA_IND_FORM1_DATA       0x000fffffffffffffull
59 #define XSCOM_ADDR_FORM1_LOW            0x000ffffffffull
60 #define XSCOM_ADDR_FORM1_HI             0xfff00000000ull
61 #define XSCOM_ADDR_FORM1_HI_SHIFT       20
62
63 /* Retries */
64 #define SCOM_MAX_RETRIES                100     /* Retries on busy */
65 #define SCOM_MAX_IND_RETRIES            10      /* Retries indirect not ready */
66
67 struct scom_device {
68         struct list_head link;
69         struct fsi_device *fsi_dev;
70         struct device dev;
71         struct cdev cdev;
72         struct mutex lock;
73         bool dead;
74 };
75
76 static int __put_scom(struct scom_device *scom_dev, uint64_t value,
77                       uint32_t addr, uint32_t *status)
78 {
79         __be32 data, raw_status;
80         int rc;
81
82         data = cpu_to_be32((value >> 32) & 0xffffffff);
83         rc = fsi_device_write(scom_dev->fsi_dev, SCOM_DATA0_REG, &data,
84                                 sizeof(uint32_t));
85         if (rc)
86                 return rc;
87
88         data = cpu_to_be32(value & 0xffffffff);
89         rc = fsi_device_write(scom_dev->fsi_dev, SCOM_DATA1_REG, &data,
90                                 sizeof(uint32_t));
91         if (rc)
92                 return rc;
93
94         data = cpu_to_be32(SCOM_WRITE_CMD | addr);
95         rc = fsi_device_write(scom_dev->fsi_dev, SCOM_CMD_REG, &data,
96                                 sizeof(uint32_t));
97         if (rc)
98                 return rc;
99         rc = fsi_device_read(scom_dev->fsi_dev, SCOM_STATUS_REG, &raw_status,
100                              sizeof(uint32_t));
101         if (rc)
102                 return rc;
103         *status = be32_to_cpu(raw_status);
104
105         return 0;
106 }
107
108 static int __get_scom(struct scom_device *scom_dev, uint64_t *value,
109                       uint32_t addr, uint32_t *status)
110 {
111         __be32 data, raw_status;
112         int rc;
113
114
115         *value = 0ULL;
116         data = cpu_to_be32(SCOM_READ_CMD | addr);
117         rc = fsi_device_write(scom_dev->fsi_dev, SCOM_CMD_REG, &data,
118                                 sizeof(uint32_t));
119         if (rc)
120                 return rc;
121         rc = fsi_device_read(scom_dev->fsi_dev, SCOM_STATUS_REG, &raw_status,
122                              sizeof(uint32_t));
123         if (rc)
124                 return rc;
125
126         /*
127          * Read the data registers even on error, so we don't have
128          * to interpret the status register here.
129          */
130         rc = fsi_device_read(scom_dev->fsi_dev, SCOM_DATA0_REG, &data,
131                                 sizeof(uint32_t));
132         if (rc)
133                 return rc;
134         *value |= (uint64_t)be32_to_cpu(data) << 32;
135         rc = fsi_device_read(scom_dev->fsi_dev, SCOM_DATA1_REG, &data,
136                                 sizeof(uint32_t));
137         if (rc)
138                 return rc;
139         *value |= be32_to_cpu(data);
140         *status = be32_to_cpu(raw_status);
141
142         return rc;
143 }
144
145 static int put_indirect_scom_form0(struct scom_device *scom, uint64_t value,
146                                    uint64_t addr, uint32_t *status)
147 {
148         uint64_t ind_data, ind_addr;
149         int rc, retries, err = 0;
150
151         if (value & ~XSCOM_DATA_IND_DATA)
152                 return -EINVAL;
153
154         ind_addr = addr & XSCOM_ADDR_DIRECT_PART;
155         ind_data = (addr & XSCOM_ADDR_INDIRECT_PART) | value;
156         rc = __put_scom(scom, ind_data, ind_addr, status);
157         if (rc || (*status & SCOM_STATUS_ANY_ERR))
158                 return rc;
159
160         for (retries = 0; retries < SCOM_MAX_IND_RETRIES; retries++) {
161                 rc = __get_scom(scom, &ind_data, addr, status);
162                 if (rc || (*status & SCOM_STATUS_ANY_ERR))
163                         return rc;
164
165                 err = (ind_data & XSCOM_DATA_IND_ERR_MASK) >> XSCOM_DATA_IND_ERR_SHIFT;
166                 *status = err << SCOM_STATUS_PIB_RESP_SHIFT;
167                 if ((ind_data & XSCOM_DATA_IND_COMPLETE) || (err != SCOM_PIB_BLOCKED))
168                         return 0;
169
170                 msleep(1);
171         }
172         return rc;
173 }
174
175 static int put_indirect_scom_form1(struct scom_device *scom, uint64_t value,
176                                    uint64_t addr, uint32_t *status)
177 {
178         uint64_t ind_data, ind_addr;
179
180         if (value & ~XSCOM_DATA_IND_FORM1_DATA)
181                 return -EINVAL;
182
183         ind_addr = addr & XSCOM_ADDR_FORM1_LOW;
184         ind_data = value | (addr & XSCOM_ADDR_FORM1_HI) << XSCOM_ADDR_FORM1_HI_SHIFT;
185         return __put_scom(scom, ind_data, ind_addr, status);
186 }
187
188 static int get_indirect_scom_form0(struct scom_device *scom, uint64_t *value,
189                                    uint64_t addr, uint32_t *status)
190 {
191         uint64_t ind_data, ind_addr;
192         int rc, retries, err = 0;
193
194         ind_addr = addr & XSCOM_ADDR_DIRECT_PART;
195         ind_data = (addr & XSCOM_ADDR_INDIRECT_PART) | XSCOM_DATA_IND_READ;
196         rc = __put_scom(scom, ind_data, ind_addr, status);
197         if (rc || (*status & SCOM_STATUS_ANY_ERR))
198                 return rc;
199
200         for (retries = 0; retries < SCOM_MAX_IND_RETRIES; retries++) {
201                 rc = __get_scom(scom, &ind_data, addr, status);
202                 if (rc || (*status & SCOM_STATUS_ANY_ERR))
203                         return rc;
204
205                 err = (ind_data & XSCOM_DATA_IND_ERR_MASK) >> XSCOM_DATA_IND_ERR_SHIFT;
206                 *status = err << SCOM_STATUS_PIB_RESP_SHIFT;
207                 *value = ind_data & XSCOM_DATA_IND_DATA;
208
209                 if ((ind_data & XSCOM_DATA_IND_COMPLETE) || (err != SCOM_PIB_BLOCKED))
210                         return 0;
211
212                 msleep(1);
213         }
214         return rc;
215 }
216
217 static int raw_put_scom(struct scom_device *scom, uint64_t value,
218                         uint64_t addr, uint32_t *status)
219 {
220         if (addr & XSCOM_ADDR_IND_FLAG) {
221                 if (addr & XSCOM_ADDR_INF_FORM1)
222                         return put_indirect_scom_form1(scom, value, addr, status);
223                 else
224                         return put_indirect_scom_form0(scom, value, addr, status);
225         } else
226                 return __put_scom(scom, value, addr, status);
227 }
228
229 static int raw_get_scom(struct scom_device *scom, uint64_t *value,
230                         uint64_t addr, uint32_t *status)
231 {
232         if (addr & XSCOM_ADDR_IND_FLAG) {
233                 if (addr & XSCOM_ADDR_INF_FORM1)
234                         return -ENXIO;
235                 return get_indirect_scom_form0(scom, value, addr, status);
236         } else
237                 return __get_scom(scom, value, addr, status);
238 }
239
240 static int handle_fsi2pib_status(struct scom_device *scom, uint32_t status)
241 {
242         uint32_t dummy = -1;
243
244         if (status & SCOM_STATUS_PROTECTION)
245                 return -EPERM;
246         if (status & SCOM_STATUS_PARITY) {
247                 fsi_device_write(scom->fsi_dev, SCOM_FSI2PIB_RESET_REG, &dummy,
248                                  sizeof(uint32_t));
249                 return -EIO;
250         }
251         /* Return -EBUSY on PIB abort to force a retry */
252         if (status & SCOM_STATUS_PIB_ABORT)
253                 return -EBUSY;
254         if (status & SCOM_STATUS_ERR_SUMMARY) {
255                 fsi_device_write(scom->fsi_dev, SCOM_FSI2PIB_RESET_REG, &dummy,
256                                  sizeof(uint32_t));
257                 return -EIO;
258         }
259         return 0;
260 }
261
262 static int handle_pib_status(struct scom_device *scom, uint8_t status)
263 {
264         uint32_t dummy = -1;
265
266         if (status == SCOM_PIB_SUCCESS)
267                 return 0;
268         if (status == SCOM_PIB_BLOCKED)
269                 return -EBUSY;
270
271         /* Reset the bridge */
272         fsi_device_write(scom->fsi_dev, SCOM_FSI2PIB_RESET_REG, &dummy,
273                          sizeof(uint32_t));
274
275         switch(status) {
276         case SCOM_PIB_OFFLINE:
277                 return -ENODEV;
278         case SCOM_PIB_BAD_ADDR:
279                 return -ENXIO;
280         case SCOM_PIB_TIMEOUT:
281                 return -ETIMEDOUT;
282         case SCOM_PIB_PARTIAL:
283         case SCOM_PIB_CLK_ERR:
284         case SCOM_PIB_PARITY_ERR:
285         default:
286                 return -EIO;
287         }
288 }
289
290 static int put_scom(struct scom_device *scom, uint64_t value,
291                     uint64_t addr)
292 {
293         uint32_t status, dummy = -1;
294         int rc, retries;
295
296         for (retries = 0; retries < SCOM_MAX_RETRIES; retries++) {
297                 rc = raw_put_scom(scom, value, addr, &status);
298                 if (rc) {
299                         /* Try resetting the bridge if FSI fails */
300                         if (rc != -ENODEV && retries == 0) {
301                                 fsi_device_write(scom->fsi_dev, SCOM_FSI2PIB_RESET_REG,
302                                                  &dummy, sizeof(uint32_t));
303                                 rc = -EBUSY;
304                         } else
305                                 return rc;
306                 } else
307                         rc = handle_fsi2pib_status(scom, status);
308                 if (rc && rc != -EBUSY)
309                         break;
310                 if (rc == 0) {
311                         rc = handle_pib_status(scom,
312                                                (status & SCOM_STATUS_PIB_RESP_MASK)
313                                                >> SCOM_STATUS_PIB_RESP_SHIFT);
314                         if (rc && rc != -EBUSY)
315                                 break;
316                 }
317                 if (rc == 0)
318                         break;
319                 msleep(1);
320         }
321         return rc;
322 }
323
324 static int get_scom(struct scom_device *scom, uint64_t *value,
325                     uint64_t addr)
326 {
327         uint32_t status, dummy = -1;
328         int rc, retries;
329
330         for (retries = 0; retries < SCOM_MAX_RETRIES; retries++) {
331                 rc = raw_get_scom(scom, value, addr, &status);
332                 if (rc) {
333                         /* Try resetting the bridge if FSI fails */
334                         if (rc != -ENODEV && retries == 0) {
335                                 fsi_device_write(scom->fsi_dev, SCOM_FSI2PIB_RESET_REG,
336                                                  &dummy, sizeof(uint32_t));
337                                 rc = -EBUSY;
338                         } else
339                                 return rc;
340                 } else
341                         rc = handle_fsi2pib_status(scom, status);
342                 if (rc && rc != -EBUSY)
343                         break;
344                 if (rc == 0) {
345                         rc = handle_pib_status(scom,
346                                                (status & SCOM_STATUS_PIB_RESP_MASK)
347                                                >> SCOM_STATUS_PIB_RESP_SHIFT);
348                         if (rc && rc != -EBUSY)
349                                 break;
350                 }
351                 if (rc == 0)
352                         break;
353                 msleep(1);
354         }
355         return rc;
356 }
357
358 static ssize_t scom_read(struct file *filep, char __user *buf, size_t len,
359                          loff_t *offset)
360 {
361         struct scom_device *scom = filep->private_data;
362         struct device *dev = &scom->fsi_dev->dev;
363         uint64_t val;
364         int rc;
365
366         if (len != sizeof(uint64_t))
367                 return -EINVAL;
368
369         mutex_lock(&scom->lock);
370         if (scom->dead)
371                 rc = -ENODEV;
372         else
373                 rc = get_scom(scom, &val, *offset);
374         mutex_unlock(&scom->lock);
375         if (rc) {
376                 dev_dbg(dev, "get_scom fail:%d\n", rc);
377                 return rc;
378         }
379
380         rc = copy_to_user(buf, &val, len);
381         if (rc)
382                 dev_dbg(dev, "copy to user failed:%d\n", rc);
383
384         return rc ? rc : len;
385 }
386
387 static ssize_t scom_write(struct file *filep, const char __user *buf,
388                           size_t len, loff_t *offset)
389 {
390         int rc;
391         struct scom_device *scom = filep->private_data;
392         struct device *dev = &scom->fsi_dev->dev;
393         uint64_t val;
394
395         if (len != sizeof(uint64_t))
396                 return -EINVAL;
397
398         rc = copy_from_user(&val, buf, len);
399         if (rc) {
400                 dev_dbg(dev, "copy from user failed:%d\n", rc);
401                 return -EINVAL;
402         }
403
404         mutex_lock(&scom->lock);
405         if (scom->dead)
406                 rc = -ENODEV;
407         else
408                 rc = put_scom(scom, val, *offset);
409         mutex_unlock(&scom->lock);
410         if (rc) {
411                 dev_dbg(dev, "put_scom failed with:%d\n", rc);
412                 return rc;
413         }
414
415         return len;
416 }
417
418 static loff_t scom_llseek(struct file *file, loff_t offset, int whence)
419 {
420         switch (whence) {
421         case SEEK_CUR:
422                 break;
423         case SEEK_SET:
424                 file->f_pos = offset;
425                 break;
426         default:
427                 return -EINVAL;
428         }
429
430         return offset;
431 }
432
433 static void raw_convert_status(struct scom_access *acc, uint32_t status)
434 {
435         acc->pib_status = (status & SCOM_STATUS_PIB_RESP_MASK) >>
436                 SCOM_STATUS_PIB_RESP_SHIFT;
437         acc->intf_errors = 0;
438
439         if (status & SCOM_STATUS_PROTECTION)
440                 acc->intf_errors |= SCOM_INTF_ERR_PROTECTION;
441         else if (status & SCOM_STATUS_PARITY)
442                 acc->intf_errors |= SCOM_INTF_ERR_PARITY;
443         else if (status & SCOM_STATUS_PIB_ABORT)
444                 acc->intf_errors |= SCOM_INTF_ERR_ABORT;
445         else if (status & SCOM_STATUS_ERR_SUMMARY)
446                 acc->intf_errors |= SCOM_INTF_ERR_UNKNOWN;
447 }
448
449 static int scom_raw_read(struct scom_device *scom, void __user *argp)
450 {
451         struct scom_access acc;
452         uint32_t status;
453         int rc;
454
455         if (copy_from_user(&acc, argp, sizeof(struct scom_access)))
456                 return -EFAULT;
457
458         rc = raw_get_scom(scom, &acc.data, acc.addr, &status);
459         if (rc)
460                 return rc;
461         raw_convert_status(&acc, status);
462         if (copy_to_user(argp, &acc, sizeof(struct scom_access)))
463                 return -EFAULT;
464         return 0;
465 }
466
467 static int scom_raw_write(struct scom_device *scom, void __user *argp)
468 {
469         u64 prev_data, mask, data;
470         struct scom_access acc;
471         uint32_t status;
472         int rc;
473
474         if (copy_from_user(&acc, argp, sizeof(struct scom_access)))
475                 return -EFAULT;
476
477         if (acc.mask) {
478                 rc = raw_get_scom(scom, &prev_data, acc.addr, &status);
479                 if (rc)
480                         return rc;
481                 if (status & SCOM_STATUS_ANY_ERR)
482                         goto fail;
483                 mask = acc.mask;
484         } else {
485                 prev_data = mask = -1ull;
486         }
487         data = (prev_data & ~mask) | (acc.data & mask);
488         rc = raw_put_scom(scom, data, acc.addr, &status);
489         if (rc)
490                 return rc;
491  fail:
492         raw_convert_status(&acc, status);
493         if (copy_to_user(argp, &acc, sizeof(struct scom_access)))
494                 return -EFAULT;
495         return 0;
496 }
497
498 static int scom_reset(struct scom_device *scom, void __user *argp)
499 {
500         uint32_t flags, dummy = -1;
501         int rc = 0;
502
503         if (get_user(flags, (__u32 __user *)argp))
504                 return -EFAULT;
505         if (flags & SCOM_RESET_PIB)
506                 rc = fsi_device_write(scom->fsi_dev, SCOM_PIB_RESET_REG, &dummy,
507                                       sizeof(uint32_t));
508         if (!rc && (flags & (SCOM_RESET_PIB | SCOM_RESET_INTF)))
509                 rc = fsi_device_write(scom->fsi_dev, SCOM_FSI2PIB_RESET_REG, &dummy,
510                                       sizeof(uint32_t));
511         return rc;
512 }
513
514 static int scom_check(struct scom_device *scom, void __user *argp)
515 {
516         /* Still need to find out how to get "protected" */
517         return put_user(SCOM_CHECK_SUPPORTED, (__u32 __user *)argp);
518 }
519
520 static long scom_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
521 {
522         struct scom_device *scom = file->private_data;
523         void __user *argp = (void __user *)arg;
524         int rc = -ENOTTY;
525
526         mutex_lock(&scom->lock);
527         if (scom->dead) {
528                 mutex_unlock(&scom->lock);
529                 return -ENODEV;
530         }
531         switch(cmd) {
532         case FSI_SCOM_CHECK:
533                 rc = scom_check(scom, argp);
534                 break;
535         case FSI_SCOM_READ:
536                 rc = scom_raw_read(scom, argp);
537                 break;
538         case FSI_SCOM_WRITE:
539                 rc = scom_raw_write(scom, argp);
540                 break;
541         case FSI_SCOM_RESET:
542                 rc = scom_reset(scom, argp);
543                 break;
544         }
545         mutex_unlock(&scom->lock);
546         return rc;
547 }
548
549 static int scom_open(struct inode *inode, struct file *file)
550 {
551         struct scom_device *scom = container_of(inode->i_cdev, struct scom_device, cdev);
552
553         file->private_data = scom;
554
555         return 0;
556 }
557
558 static const struct file_operations scom_fops = {
559         .owner          = THIS_MODULE,
560         .open           = scom_open,
561         .llseek         = scom_llseek,
562         .read           = scom_read,
563         .write          = scom_write,
564         .unlocked_ioctl = scom_ioctl,
565 };
566
567 static void scom_free(struct device *dev)
568 {
569         struct scom_device *scom = container_of(dev, struct scom_device, dev);
570
571         put_device(&scom->fsi_dev->dev);
572         kfree(scom);
573 }
574
575 static int scom_probe(struct device *dev)
576 {
577         struct fsi_device *fsi_dev = to_fsi_dev(dev);
578         struct scom_device *scom;
579         int rc, didx;
580
581         scom = kzalloc(sizeof(*scom), GFP_KERNEL);
582         if (!scom)
583                 return -ENOMEM;
584         dev_set_drvdata(dev, scom);
585         mutex_init(&scom->lock);
586
587         /* Grab a reference to the device (parent of our cdev), we'll drop it later */
588         if (!get_device(dev)) {
589                 kfree(scom);
590                 return -ENODEV;
591         }
592         scom->fsi_dev = fsi_dev;
593
594         /* Create chardev for userspace access */
595         scom->dev.type = &fsi_cdev_type;
596         scom->dev.parent = dev;
597         scom->dev.release = scom_free;
598         device_initialize(&scom->dev);
599
600         /* Allocate a minor in the FSI space */
601         rc = fsi_get_new_minor(fsi_dev, fsi_dev_scom, &scom->dev.devt, &didx);
602         if (rc)
603                 goto err;
604
605         dev_set_name(&scom->dev, "scom%d", didx);
606         cdev_init(&scom->cdev, &scom_fops);
607         rc = cdev_device_add(&scom->cdev, &scom->dev);
608         if (rc) {
609                 dev_err(dev, "Error %d creating char device %s\n",
610                         rc, dev_name(&scom->dev));
611                 goto err_free_minor;
612         }
613
614         return 0;
615  err_free_minor:
616         fsi_free_minor(scom->dev.devt);
617  err:
618         put_device(&scom->dev);
619         return rc;
620 }
621
622 static int scom_remove(struct device *dev)
623 {
624         struct scom_device *scom = dev_get_drvdata(dev);
625
626         mutex_lock(&scom->lock);
627         scom->dead = true;
628         mutex_unlock(&scom->lock);
629         cdev_device_del(&scom->cdev, &scom->dev);
630         fsi_free_minor(scom->dev.devt);
631         put_device(&scom->dev);
632
633         return 0;
634 }
635
636 static struct fsi_device_id scom_ids[] = {
637         {
638                 .engine_type = FSI_ENGID_SCOM,
639                 .version = FSI_VERSION_ANY,
640         },
641         { 0 }
642 };
643
644 static struct fsi_driver scom_drv = {
645         .id_table = scom_ids,
646         .drv = {
647                 .name = "scom",
648                 .bus = &fsi_bus_type,
649                 .probe = scom_probe,
650                 .remove = scom_remove,
651         }
652 };
653
654 static int scom_init(void)
655 {
656         return fsi_driver_register(&scom_drv);
657 }
658
659 static void scom_exit(void)
660 {
661         fsi_driver_unregister(&scom_drv);
662 }
663
664 module_init(scom_init);
665 module_exit(scom_exit);
666 MODULE_LICENSE("GPL");