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