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