| .. | .. |
|---|
| 28 | 28 | #define catu_dbg(x, ...) do {} while (0) |
|---|
| 29 | 29 | #endif |
|---|
| 30 | 30 | |
|---|
| 31 | +DEFINE_CORESIGHT_DEVLIST(catu_devs, "catu"); |
|---|
| 32 | + |
|---|
| 31 | 33 | struct catu_etr_buf { |
|---|
| 32 | 34 | struct tmc_sg_table *catu_table; |
|---|
| 33 | 35 | dma_addr_t sladdr; |
|---|
| .. | .. |
|---|
| 328 | 330 | struct etr_buf *etr_buf, int node, void **pages) |
|---|
| 329 | 331 | { |
|---|
| 330 | 332 | struct coresight_device *csdev; |
|---|
| 331 | | - struct device *catu_dev; |
|---|
| 332 | 333 | struct tmc_sg_table *catu_table; |
|---|
| 333 | 334 | struct catu_etr_buf *catu_buf; |
|---|
| 334 | 335 | |
|---|
| 335 | 336 | csdev = tmc_etr_get_catu_device(tmc_drvdata); |
|---|
| 336 | 337 | if (!csdev) |
|---|
| 337 | 338 | return -ENODEV; |
|---|
| 338 | | - catu_dev = csdev->dev.parent; |
|---|
| 339 | 339 | catu_buf = kzalloc(sizeof(*catu_buf), GFP_KERNEL); |
|---|
| 340 | 340 | if (!catu_buf) |
|---|
| 341 | 341 | return -ENOMEM; |
|---|
| 342 | 342 | |
|---|
| 343 | | - catu_table = catu_init_sg_table(catu_dev, node, etr_buf->size, pages); |
|---|
| 343 | + catu_table = catu_init_sg_table(&csdev->dev, node, |
|---|
| 344 | + etr_buf->size, pages); |
|---|
| 344 | 345 | if (IS_ERR(catu_table)) { |
|---|
| 345 | 346 | kfree(catu_buf); |
|---|
| 346 | 347 | return PTR_ERR(catu_table); |
|---|
| .. | .. |
|---|
| 357 | 358 | return 0; |
|---|
| 358 | 359 | } |
|---|
| 359 | 360 | |
|---|
| 360 | | -const struct etr_buf_operations etr_catu_buf_ops = { |
|---|
| 361 | +static const struct etr_buf_operations etr_catu_buf_ops = { |
|---|
| 361 | 362 | .alloc = catu_alloc_etr_buf, |
|---|
| 362 | 363 | .free = catu_free_etr_buf, |
|---|
| 363 | 364 | .sync = catu_sync_etr_buf, |
|---|
| .. | .. |
|---|
| 400 | 401 | |
|---|
| 401 | 402 | static inline int catu_wait_for_ready(struct catu_drvdata *drvdata) |
|---|
| 402 | 403 | { |
|---|
| 403 | | - return coresight_timeout(drvdata->base, |
|---|
| 404 | | - CATU_STATUS, CATU_STATUS_READY, 1); |
|---|
| 404 | + struct csdev_access *csa = &drvdata->csdev->access; |
|---|
| 405 | + |
|---|
| 406 | + return coresight_timeout(csa, CATU_STATUS, CATU_STATUS_READY, 1); |
|---|
| 405 | 407 | } |
|---|
| 406 | 408 | |
|---|
| 407 | 409 | static int catu_enable_hw(struct catu_drvdata *drvdata, void *data) |
|---|
| 408 | 410 | { |
|---|
| 411 | + int rc; |
|---|
| 409 | 412 | u32 control, mode; |
|---|
| 410 | 413 | struct etr_buf *etr_buf = data; |
|---|
| 414 | + struct device *dev = &drvdata->csdev->dev; |
|---|
| 415 | + struct coresight_device *csdev = drvdata->csdev; |
|---|
| 411 | 416 | |
|---|
| 412 | 417 | if (catu_wait_for_ready(drvdata)) |
|---|
| 413 | | - dev_warn(drvdata->dev, "Timeout while waiting for READY\n"); |
|---|
| 418 | + dev_warn(dev, "Timeout while waiting for READY\n"); |
|---|
| 414 | 419 | |
|---|
| 415 | 420 | control = catu_read_control(drvdata); |
|---|
| 416 | 421 | if (control & BIT(CATU_CONTROL_ENABLE)) { |
|---|
| 417 | | - dev_warn(drvdata->dev, "CATU is already enabled\n"); |
|---|
| 422 | + dev_warn(dev, "CATU is already enabled\n"); |
|---|
| 418 | 423 | return -EBUSY; |
|---|
| 419 | 424 | } |
|---|
| 425 | + |
|---|
| 426 | + rc = coresight_claim_device_unlocked(csdev); |
|---|
| 427 | + if (rc) |
|---|
| 428 | + return rc; |
|---|
| 420 | 429 | |
|---|
| 421 | 430 | control |= BIT(CATU_CONTROL_ENABLE); |
|---|
| 422 | 431 | |
|---|
| .. | .. |
|---|
| 436 | 445 | catu_write_irqen(drvdata, 0); |
|---|
| 437 | 446 | catu_write_mode(drvdata, mode); |
|---|
| 438 | 447 | catu_write_control(drvdata, control); |
|---|
| 439 | | - dev_dbg(drvdata->dev, "Enabled in %s mode\n", |
|---|
| 448 | + dev_dbg(dev, "Enabled in %s mode\n", |
|---|
| 440 | 449 | (mode == CATU_MODE_PASS_THROUGH) ? |
|---|
| 441 | 450 | "Pass through" : |
|---|
| 442 | 451 | "Translate"); |
|---|
| .. | .. |
|---|
| 457 | 466 | static int catu_disable_hw(struct catu_drvdata *drvdata) |
|---|
| 458 | 467 | { |
|---|
| 459 | 468 | int rc = 0; |
|---|
| 469 | + struct device *dev = &drvdata->csdev->dev; |
|---|
| 470 | + struct coresight_device *csdev = drvdata->csdev; |
|---|
| 460 | 471 | |
|---|
| 461 | 472 | catu_write_control(drvdata, 0); |
|---|
| 473 | + coresight_disclaim_device_unlocked(csdev); |
|---|
| 462 | 474 | if (catu_wait_for_ready(drvdata)) { |
|---|
| 463 | | - dev_info(drvdata->dev, "Timeout while waiting for READY\n"); |
|---|
| 475 | + dev_info(dev, "Timeout while waiting for READY\n"); |
|---|
| 464 | 476 | rc = -EAGAIN; |
|---|
| 465 | 477 | } |
|---|
| 466 | 478 | |
|---|
| 467 | | - dev_dbg(drvdata->dev, "Disabled\n"); |
|---|
| 479 | + dev_dbg(dev, "Disabled\n"); |
|---|
| 468 | 480 | return rc; |
|---|
| 469 | 481 | } |
|---|
| 470 | 482 | |
|---|
| .. | .. |
|---|
| 479 | 491 | return rc; |
|---|
| 480 | 492 | } |
|---|
| 481 | 493 | |
|---|
| 482 | | -const struct coresight_ops_helper catu_helper_ops = { |
|---|
| 494 | +static const struct coresight_ops_helper catu_helper_ops = { |
|---|
| 483 | 495 | .enable = catu_enable, |
|---|
| 484 | 496 | .disable = catu_disable, |
|---|
| 485 | 497 | }; |
|---|
| 486 | 498 | |
|---|
| 487 | | -const struct coresight_ops catu_ops = { |
|---|
| 499 | +static const struct coresight_ops catu_ops = { |
|---|
| 488 | 500 | .helper_ops = &catu_helper_ops, |
|---|
| 489 | 501 | }; |
|---|
| 490 | 502 | |
|---|
| .. | .. |
|---|
| 496 | 508 | struct coresight_desc catu_desc; |
|---|
| 497 | 509 | struct coresight_platform_data *pdata = NULL; |
|---|
| 498 | 510 | struct device *dev = &adev->dev; |
|---|
| 499 | | - struct device_node *np = dev->of_node; |
|---|
| 500 | 511 | void __iomem *base; |
|---|
| 501 | 512 | |
|---|
| 502 | | - if (np) { |
|---|
| 503 | | - pdata = of_get_coresight_platform_data(dev, np); |
|---|
| 504 | | - if (IS_ERR(pdata)) { |
|---|
| 505 | | - ret = PTR_ERR(pdata); |
|---|
| 506 | | - goto out; |
|---|
| 507 | | - } |
|---|
| 508 | | - dev->platform_data = pdata; |
|---|
| 509 | | - } |
|---|
| 513 | + catu_desc.name = coresight_alloc_device_name(&catu_devs, dev); |
|---|
| 514 | + if (!catu_desc.name) |
|---|
| 515 | + return -ENOMEM; |
|---|
| 510 | 516 | |
|---|
| 511 | 517 | drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); |
|---|
| 512 | 518 | if (!drvdata) { |
|---|
| .. | .. |
|---|
| 514 | 520 | goto out; |
|---|
| 515 | 521 | } |
|---|
| 516 | 522 | |
|---|
| 517 | | - drvdata->dev = dev; |
|---|
| 518 | 523 | dev_set_drvdata(dev, drvdata); |
|---|
| 519 | 524 | base = devm_ioremap_resource(dev, &adev->res); |
|---|
| 520 | 525 | if (IS_ERR(base)) { |
|---|
| .. | .. |
|---|
| 541 | 546 | if (ret) |
|---|
| 542 | 547 | goto out; |
|---|
| 543 | 548 | |
|---|
| 549 | + pdata = coresight_get_platform_data(dev); |
|---|
| 550 | + if (IS_ERR(pdata)) { |
|---|
| 551 | + ret = PTR_ERR(pdata); |
|---|
| 552 | + goto out; |
|---|
| 553 | + } |
|---|
| 554 | + dev->platform_data = pdata; |
|---|
| 555 | + |
|---|
| 544 | 556 | drvdata->base = base; |
|---|
| 557 | + catu_desc.access = CSDEV_ACCESS_IOMEM(base); |
|---|
| 545 | 558 | catu_desc.pdata = pdata; |
|---|
| 546 | 559 | catu_desc.dev = dev; |
|---|
| 547 | 560 | catu_desc.groups = catu_groups; |
|---|
| 548 | 561 | catu_desc.type = CORESIGHT_DEV_TYPE_HELPER; |
|---|
| 549 | 562 | catu_desc.subtype.helper_subtype = CORESIGHT_DEV_SUBTYPE_HELPER_CATU; |
|---|
| 550 | 563 | catu_desc.ops = &catu_ops; |
|---|
| 564 | + |
|---|
| 551 | 565 | drvdata->csdev = coresight_register(&catu_desc); |
|---|
| 552 | 566 | if (IS_ERR(drvdata->csdev)) |
|---|
| 553 | 567 | ret = PTR_ERR(drvdata->csdev); |
|---|
| 568 | + else |
|---|
| 569 | + pm_runtime_put(&adev->dev); |
|---|
| 554 | 570 | out: |
|---|
| 555 | | - pm_runtime_put(&adev->dev); |
|---|
| 556 | 571 | return ret; |
|---|
| 557 | 572 | } |
|---|
| 558 | 573 | |
|---|
| 574 | +static void catu_remove(struct amba_device *adev) |
|---|
| 575 | +{ |
|---|
| 576 | + struct catu_drvdata *drvdata = dev_get_drvdata(&adev->dev); |
|---|
| 577 | + |
|---|
| 578 | + coresight_unregister(drvdata->csdev); |
|---|
| 579 | +} |
|---|
| 580 | + |
|---|
| 559 | 581 | static struct amba_id catu_ids[] = { |
|---|
| 560 | | - { |
|---|
| 561 | | - .id = 0x000bb9ee, |
|---|
| 562 | | - .mask = 0x000fffff, |
|---|
| 563 | | - }, |
|---|
| 582 | + CS_AMBA_ID(0x000bb9ee), |
|---|
| 564 | 583 | {}, |
|---|
| 565 | 584 | }; |
|---|
| 585 | + |
|---|
| 586 | +MODULE_DEVICE_TABLE(amba, catu_ids); |
|---|
| 566 | 587 | |
|---|
| 567 | 588 | static struct amba_driver catu_driver = { |
|---|
| 568 | 589 | .drv = { |
|---|
| .. | .. |
|---|
| 571 | 592 | .suppress_bind_attrs = true, |
|---|
| 572 | 593 | }, |
|---|
| 573 | 594 | .probe = catu_probe, |
|---|
| 595 | + .remove = catu_remove, |
|---|
| 574 | 596 | .id_table = catu_ids, |
|---|
| 575 | 597 | }; |
|---|
| 576 | 598 | |
|---|
| 577 | | -builtin_amba_driver(catu_driver); |
|---|
| 599 | +static int __init catu_init(void) |
|---|
| 600 | +{ |
|---|
| 601 | + int ret; |
|---|
| 602 | + |
|---|
| 603 | + ret = amba_driver_register(&catu_driver); |
|---|
| 604 | + if (ret) |
|---|
| 605 | + pr_info("Error registering catu driver\n"); |
|---|
| 606 | + tmc_etr_set_catu_ops(&etr_catu_buf_ops); |
|---|
| 607 | + return ret; |
|---|
| 608 | +} |
|---|
| 609 | + |
|---|
| 610 | +static void __exit catu_exit(void) |
|---|
| 611 | +{ |
|---|
| 612 | + tmc_etr_remove_catu_ops(); |
|---|
| 613 | + amba_driver_unregister(&catu_driver); |
|---|
| 614 | +} |
|---|
| 615 | + |
|---|
| 616 | +module_init(catu_init); |
|---|
| 617 | +module_exit(catu_exit); |
|---|
| 618 | + |
|---|
| 619 | +MODULE_AUTHOR("Suzuki K Poulose <suzuki.poulose@arm.com>"); |
|---|
| 620 | +MODULE_DESCRIPTION("Arm CoreSight Address Translation Unit (CATU) Driver"); |
|---|
| 621 | +MODULE_LICENSE("GPL v2"); |
|---|