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"); 667