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