diff options
| -rw-r--r-- | Documentation/devicetree/bindings/iommu/arm,smmu.txt | 6 | ||||
| -rw-r--r-- | drivers/iommu/arm-smmu.c | 493 |
2 files changed, 240 insertions, 259 deletions
diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt b/Documentation/devicetree/bindings/iommu/arm,smmu.txt index f284b99402bc..2d0f7cd867ea 100644 --- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt | |||
| @@ -42,12 +42,6 @@ conditions. | |||
| 42 | 42 | ||
| 43 | ** System MMU optional properties: | 43 | ** System MMU optional properties: |
| 44 | 44 | ||
| 45 | - smmu-parent : When multiple SMMUs are chained together, this | ||
| 46 | property can be used to provide a phandle to the | ||
| 47 | parent SMMU (that is the next SMMU on the path going | ||
| 48 | from the mmu-masters towards memory) node for this | ||
| 49 | SMMU. | ||
| 50 | |||
| 51 | - calxeda,smmu-secure-config-access : Enable proper handling of buggy | 45 | - calxeda,smmu-secure-config-access : Enable proper handling of buggy |
| 52 | implementations that always use secure access to | 46 | implementations that always use secure access to |
| 53 | SMMU configuration registers. In this case non-secure | 47 | SMMU configuration registers. In this case non-secure |
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 1599354e974d..f3f66416e252 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | #include <linux/mm.h> | 39 | #include <linux/mm.h> |
| 40 | #include <linux/module.h> | 40 | #include <linux/module.h> |
| 41 | #include <linux/of.h> | 41 | #include <linux/of.h> |
| 42 | #include <linux/pci.h> | ||
| 42 | #include <linux/platform_device.h> | 43 | #include <linux/platform_device.h> |
| 43 | #include <linux/slab.h> | 44 | #include <linux/slab.h> |
| 44 | #include <linux/spinlock.h> | 45 | #include <linux/spinlock.h> |
| @@ -316,9 +317,9 @@ | |||
| 316 | #define FSR_AFF (1 << 2) | 317 | #define FSR_AFF (1 << 2) |
| 317 | #define FSR_TF (1 << 1) | 318 | #define FSR_TF (1 << 1) |
| 318 | 319 | ||
| 319 | #define FSR_IGN (FSR_AFF | FSR_ASF | FSR_TLBMCF | \ | 320 | #define FSR_IGN (FSR_AFF | FSR_ASF | \ |
| 320 | FSR_TLBLKF) | 321 | FSR_TLBMCF | FSR_TLBLKF) |
| 321 | #define FSR_FAULT (FSR_MULTI | FSR_SS | FSR_UUT | \ | 322 | #define FSR_FAULT (FSR_MULTI | FSR_SS | FSR_UUT | \ |
| 322 | FSR_EF | FSR_PF | FSR_TF | FSR_IGN) | 323 | FSR_EF | FSR_PF | FSR_TF | FSR_IGN) |
| 323 | 324 | ||
| 324 | #define FSYNR0_WNR (1 << 4) | 325 | #define FSYNR0_WNR (1 << 4) |
| @@ -329,27 +330,20 @@ struct arm_smmu_smr { | |||
| 329 | u16 id; | 330 | u16 id; |
| 330 | }; | 331 | }; |
| 331 | 332 | ||
| 332 | struct arm_smmu_master { | 333 | struct arm_smmu_master_cfg { |
| 333 | struct device_node *of_node; | ||
| 334 | |||
| 335 | /* | ||
| 336 | * The following is specific to the master's position in the | ||
| 337 | * SMMU chain. | ||
| 338 | */ | ||
| 339 | struct rb_node node; | ||
| 340 | int num_streamids; | 334 | int num_streamids; |
| 341 | u16 streamids[MAX_MASTER_STREAMIDS]; | 335 | u16 streamids[MAX_MASTER_STREAMIDS]; |
| 342 | |||
| 343 | /* | ||
| 344 | * We only need to allocate these on the root SMMU, as we | ||
| 345 | * configure unmatched streams to bypass translation. | ||
| 346 | */ | ||
| 347 | struct arm_smmu_smr *smrs; | 336 | struct arm_smmu_smr *smrs; |
| 348 | }; | 337 | }; |
| 349 | 338 | ||
| 339 | struct arm_smmu_master { | ||
| 340 | struct device_node *of_node; | ||
| 341 | struct rb_node node; | ||
| 342 | struct arm_smmu_master_cfg cfg; | ||
| 343 | }; | ||
| 344 | |||
| 350 | struct arm_smmu_device { | 345 | struct arm_smmu_device { |
| 351 | struct device *dev; | 346 | struct device *dev; |
| 352 | struct device_node *parent_of_node; | ||
| 353 | 347 | ||
| 354 | void __iomem *base; | 348 | void __iomem *base; |
| 355 | unsigned long size; | 349 | unsigned long size; |
| @@ -387,7 +381,6 @@ struct arm_smmu_device { | |||
| 387 | }; | 381 | }; |
| 388 | 382 | ||
| 389 | struct arm_smmu_cfg { | 383 | struct arm_smmu_cfg { |
| 390 | struct arm_smmu_device *smmu; | ||
| 391 | u8 cbndx; | 384 | u8 cbndx; |
| 392 | u8 irptndx; | 385 | u8 irptndx; |
| 393 | u32 cbar; | 386 | u32 cbar; |
| @@ -399,15 +392,8 @@ struct arm_smmu_cfg { | |||
| 399 | #define ARM_SMMU_CB_VMID(cfg) ((cfg)->cbndx + 1) | 392 | #define ARM_SMMU_CB_VMID(cfg) ((cfg)->cbndx + 1) |
| 400 | 393 | ||
| 401 | struct arm_smmu_domain { | 394 | struct arm_smmu_domain { |
| 402 | /* | 395 | struct arm_smmu_device *smmu; |
| 403 | * A domain can span across multiple, chained SMMUs and requires | 396 | struct arm_smmu_cfg cfg; |
| 404 | * all devices within the domain to follow the same translation | ||
| 405 | * path. | ||
| 406 | */ | ||
| 407 | struct arm_smmu_device *leaf_smmu; | ||
| 408 | struct arm_smmu_cfg root_cfg; | ||
| 409 | phys_addr_t output_mask; | ||
| 410 | |||
| 411 | spinlock_t lock; | 397 | spinlock_t lock; |
| 412 | }; | 398 | }; |
| 413 | 399 | ||
| @@ -419,7 +405,7 @@ struct arm_smmu_option_prop { | |||
| 419 | const char *prop; | 405 | const char *prop; |
| 420 | }; | 406 | }; |
| 421 | 407 | ||
| 422 | static struct arm_smmu_option_prop arm_smmu_options [] = { | 408 | static struct arm_smmu_option_prop arm_smmu_options[] = { |
| 423 | { ARM_SMMU_OPT_SECURE_CFG_ACCESS, "calxeda,smmu-secure-config-access" }, | 409 | { ARM_SMMU_OPT_SECURE_CFG_ACCESS, "calxeda,smmu-secure-config-access" }, |
| 424 | { 0, NULL}, | 410 | { 0, NULL}, |
| 425 | }; | 411 | }; |
| @@ -427,6 +413,7 @@ static struct arm_smmu_option_prop arm_smmu_options [] = { | |||
| 427 | static void parse_driver_options(struct arm_smmu_device *smmu) | 413 | static void parse_driver_options(struct arm_smmu_device *smmu) |
| 428 | { | 414 | { |
| 429 | int i = 0; | 415 | int i = 0; |
| 416 | |||
| 430 | do { | 417 | do { |
| 431 | if (of_property_read_bool(smmu->dev->of_node, | 418 | if (of_property_read_bool(smmu->dev->of_node, |
| 432 | arm_smmu_options[i].prop)) { | 419 | arm_smmu_options[i].prop)) { |
| @@ -437,6 +424,19 @@ static void parse_driver_options(struct arm_smmu_device *smmu) | |||
| 437 | } while (arm_smmu_options[++i].opt); | 424 | } while (arm_smmu_options[++i].opt); |
| 438 | } | 425 | } |
| 439 | 426 | ||
| 427 | static struct device *dev_get_master_dev(struct device *dev) | ||
| 428 | { | ||
| 429 | if (dev_is_pci(dev)) { | ||
| 430 | struct pci_bus *bus = to_pci_dev(dev)->bus; | ||
| 431 | |||
| 432 | while (!pci_is_root_bus(bus)) | ||
| 433 | bus = bus->parent; | ||
| 434 | return bus->bridge->parent; | ||
| 435 | } | ||
| 436 | |||
| 437 | return dev; | ||
| 438 | } | ||
| 439 | |||
| 440 | static struct arm_smmu_master *find_smmu_master(struct arm_smmu_device *smmu, | 440 | static struct arm_smmu_master *find_smmu_master(struct arm_smmu_device *smmu, |
| 441 | struct device_node *dev_node) | 441 | struct device_node *dev_node) |
| 442 | { | 442 | { |
| @@ -444,6 +444,7 @@ static struct arm_smmu_master *find_smmu_master(struct arm_smmu_device *smmu, | |||
| 444 | 444 | ||
| 445 | while (node) { | 445 | while (node) { |
| 446 | struct arm_smmu_master *master; | 446 | struct arm_smmu_master *master; |
| 447 | |||
| 447 | master = container_of(node, struct arm_smmu_master, node); | 448 | master = container_of(node, struct arm_smmu_master, node); |
| 448 | 449 | ||
| 449 | if (dev_node < master->of_node) | 450 | if (dev_node < master->of_node) |
| @@ -457,6 +458,18 @@ static struct arm_smmu_master *find_smmu_master(struct arm_smmu_device *smmu, | |||
| 457 | return NULL; | 458 | return NULL; |
| 458 | } | 459 | } |
| 459 | 460 | ||
| 461 | static struct arm_smmu_master_cfg * | ||
| 462 | find_smmu_master_cfg(struct arm_smmu_device *smmu, struct device *dev) | ||
| 463 | { | ||
| 464 | struct arm_smmu_master *master; | ||
| 465 | |||
| 466 | if (dev_is_pci(dev)) | ||
| 467 | return dev->archdata.iommu; | ||
| 468 | |||
| 469 | master = find_smmu_master(smmu, dev->of_node); | ||
| 470 | return master ? &master->cfg : NULL; | ||
| 471 | } | ||
| 472 | |||
| 460 | static int insert_smmu_master(struct arm_smmu_device *smmu, | 473 | static int insert_smmu_master(struct arm_smmu_device *smmu, |
| 461 | struct arm_smmu_master *master) | 474 | struct arm_smmu_master *master) |
| 462 | { | 475 | { |
| @@ -465,8 +478,8 @@ static int insert_smmu_master(struct arm_smmu_device *smmu, | |||
| 465 | new = &smmu->masters.rb_node; | 478 | new = &smmu->masters.rb_node; |
| 466 | parent = NULL; | 479 | parent = NULL; |
| 467 | while (*new) { | 480 | while (*new) { |
| 468 | struct arm_smmu_master *this; | 481 | struct arm_smmu_master *this |
| 469 | this = container_of(*new, struct arm_smmu_master, node); | 482 | = container_of(*new, struct arm_smmu_master, node); |
| 470 | 483 | ||
| 471 | parent = *new; | 484 | parent = *new; |
| 472 | if (master->of_node < this->of_node) | 485 | if (master->of_node < this->of_node) |
| @@ -508,33 +521,30 @@ static int register_smmu_master(struct arm_smmu_device *smmu, | |||
| 508 | if (!master) | 521 | if (!master) |
| 509 | return -ENOMEM; | 522 | return -ENOMEM; |
| 510 | 523 | ||
| 511 | master->of_node = masterspec->np; | 524 | master->of_node = masterspec->np; |
| 512 | master->num_streamids = masterspec->args_count; | 525 | master->cfg.num_streamids = masterspec->args_count; |
| 513 | 526 | ||
| 514 | for (i = 0; i < master->num_streamids; ++i) | 527 | for (i = 0; i < master->cfg.num_streamids; ++i) |
| 515 | master->streamids[i] = masterspec->args[i]; | 528 | master->cfg.streamids[i] = masterspec->args[i]; |
| 516 | 529 | ||
| 517 | return insert_smmu_master(smmu, master); | 530 | return insert_smmu_master(smmu, master); |
| 518 | } | 531 | } |
| 519 | 532 | ||
| 520 | static struct arm_smmu_device *find_parent_smmu(struct arm_smmu_device *smmu) | 533 | static struct arm_smmu_device *find_smmu_for_device(struct device *dev) |
| 521 | { | 534 | { |
| 522 | struct arm_smmu_device *parent; | 535 | struct arm_smmu_device *smmu; |
| 523 | 536 | struct arm_smmu_master *master = NULL; | |
| 524 | if (!smmu->parent_of_node) | 537 | struct device_node *dev_node = dev_get_master_dev(dev)->of_node; |
| 525 | return NULL; | ||
| 526 | 538 | ||
| 527 | spin_lock(&arm_smmu_devices_lock); | 539 | spin_lock(&arm_smmu_devices_lock); |
| 528 | list_for_each_entry(parent, &arm_smmu_devices, list) | 540 | list_for_each_entry(smmu, &arm_smmu_devices, list) { |
| 529 | if (parent->dev->of_node == smmu->parent_of_node) | 541 | master = find_smmu_master(smmu, dev_node); |
| 530 | goto out_unlock; | 542 | if (master) |
| 531 | 543 | break; | |
| 532 | parent = NULL; | 544 | } |
| 533 | dev_warn(smmu->dev, | ||
| 534 | "Failed to find SMMU parent despite parent in DT\n"); | ||
| 535 | out_unlock: | ||
| 536 | spin_unlock(&arm_smmu_devices_lock); | 545 | spin_unlock(&arm_smmu_devices_lock); |
| 537 | return parent; | 546 | |
| 547 | return master ? smmu : NULL; | ||
| 538 | } | 548 | } |
| 539 | 549 | ||
| 540 | static int __arm_smmu_alloc_bitmap(unsigned long *map, int start, int end) | 550 | static int __arm_smmu_alloc_bitmap(unsigned long *map, int start, int end) |
| @@ -574,9 +584,10 @@ static void arm_smmu_tlb_sync(struct arm_smmu_device *smmu) | |||
| 574 | } | 584 | } |
| 575 | } | 585 | } |
| 576 | 586 | ||
| 577 | static void arm_smmu_tlb_inv_context(struct arm_smmu_cfg *cfg) | 587 | static void arm_smmu_tlb_inv_context(struct arm_smmu_domain *smmu_domain) |
| 578 | { | 588 | { |
| 579 | struct arm_smmu_device *smmu = cfg->smmu; | 589 | struct arm_smmu_cfg *cfg = &smmu_domain->cfg; |
| 590 | struct arm_smmu_device *smmu = smmu_domain->smmu; | ||
| 580 | void __iomem *base = ARM_SMMU_GR0(smmu); | 591 | void __iomem *base = ARM_SMMU_GR0(smmu); |
| 581 | bool stage1 = cfg->cbar != CBAR_TYPE_S2_TRANS; | 592 | bool stage1 = cfg->cbar != CBAR_TYPE_S2_TRANS; |
| 582 | 593 | ||
| @@ -600,11 +611,11 @@ static irqreturn_t arm_smmu_context_fault(int irq, void *dev) | |||
| 600 | unsigned long iova; | 611 | unsigned long iova; |
| 601 | struct iommu_domain *domain = dev; | 612 | struct iommu_domain *domain = dev; |
| 602 | struct arm_smmu_domain *smmu_domain = domain->priv; | 613 | struct arm_smmu_domain *smmu_domain = domain->priv; |
| 603 | struct arm_smmu_cfg *root_cfg = &smmu_domain->root_cfg; | 614 | struct arm_smmu_cfg *cfg = &smmu_domain->cfg; |
| 604 | struct arm_smmu_device *smmu = root_cfg->smmu; | 615 | struct arm_smmu_device *smmu = smmu_domain->smmu; |
| 605 | void __iomem *cb_base; | 616 | void __iomem *cb_base; |
| 606 | 617 | ||
| 607 | cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, root_cfg->cbndx); | 618 | cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx); |
| 608 | fsr = readl_relaxed(cb_base + ARM_SMMU_CB_FSR); | 619 | fsr = readl_relaxed(cb_base + ARM_SMMU_CB_FSR); |
| 609 | 620 | ||
| 610 | if (!(fsr & FSR_FAULT)) | 621 | if (!(fsr & FSR_FAULT)) |
| @@ -631,7 +642,7 @@ static irqreturn_t arm_smmu_context_fault(int irq, void *dev) | |||
| 631 | } else { | 642 | } else { |
| 632 | dev_err_ratelimited(smmu->dev, | 643 | dev_err_ratelimited(smmu->dev, |
| 633 | "Unhandled context fault: iova=0x%08lx, fsynr=0x%x, cb=%d\n", | 644 | "Unhandled context fault: iova=0x%08lx, fsynr=0x%x, cb=%d\n", |
| 634 | iova, fsynr, root_cfg->cbndx); | 645 | iova, fsynr, cfg->cbndx); |
| 635 | ret = IRQ_NONE; | 646 | ret = IRQ_NONE; |
| 636 | resume = RESUME_TERMINATE; | 647 | resume = RESUME_TERMINATE; |
| 637 | } | 648 | } |
| @@ -696,19 +707,19 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain) | |||
| 696 | { | 707 | { |
| 697 | u32 reg; | 708 | u32 reg; |
| 698 | bool stage1; | 709 | bool stage1; |
| 699 | struct arm_smmu_cfg *root_cfg = &smmu_domain->root_cfg; | 710 | struct arm_smmu_cfg *cfg = &smmu_domain->cfg; |
| 700 | struct arm_smmu_device *smmu = root_cfg->smmu; | 711 | struct arm_smmu_device *smmu = smmu_domain->smmu; |
| 701 | void __iomem *cb_base, *gr0_base, *gr1_base; | 712 | void __iomem *cb_base, *gr0_base, *gr1_base; |
| 702 | 713 | ||
| 703 | gr0_base = ARM_SMMU_GR0(smmu); | 714 | gr0_base = ARM_SMMU_GR0(smmu); |
| 704 | gr1_base = ARM_SMMU_GR1(smmu); | 715 | gr1_base = ARM_SMMU_GR1(smmu); |
| 705 | stage1 = root_cfg->cbar != CBAR_TYPE_S2_TRANS; | 716 | stage1 = cfg->cbar != CBAR_TYPE_S2_TRANS; |
| 706 | cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, root_cfg->cbndx); | 717 | cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx); |
| 707 | 718 | ||
| 708 | /* CBAR */ | 719 | /* CBAR */ |
| 709 | reg = root_cfg->cbar; | 720 | reg = cfg->cbar; |
| 710 | if (smmu->version == 1) | 721 | if (smmu->version == 1) |
| 711 | reg |= root_cfg->irptndx << CBAR_IRPTNDX_SHIFT; | 722 | reg |= cfg->irptndx << CBAR_IRPTNDX_SHIFT; |
| 712 | 723 | ||
| 713 | /* | 724 | /* |
| 714 | * Use the weakest shareability/memory types, so they are | 725 | * Use the weakest shareability/memory types, so they are |
| @@ -718,9 +729,9 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain) | |||
| 718 | reg |= (CBAR_S1_BPSHCFG_NSH << CBAR_S1_BPSHCFG_SHIFT) | | 729 | reg |= (CBAR_S1_BPSHCFG_NSH << CBAR_S1_BPSHCFG_SHIFT) | |
| 719 | (CBAR_S1_MEMATTR_WB << CBAR_S1_MEMATTR_SHIFT); | 730 | (CBAR_S1_MEMATTR_WB << CBAR_S1_MEMATTR_SHIFT); |
| 720 | } else { | 731 | } else { |
| 721 | reg |= ARM_SMMU_CB_VMID(root_cfg) << CBAR_VMID_SHIFT; | 732 | reg |= ARM_SMMU_CB_VMID(cfg) << CBAR_VMID_SHIFT; |
| 722 | } | 733 | } |
| 723 | writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBAR(root_cfg->cbndx)); | 734 | writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBAR(cfg->cbndx)); |
| 724 | 735 | ||
| 725 | if (smmu->version > 1) { | 736 | if (smmu->version > 1) { |
| 726 | /* CBA2R */ | 737 | /* CBA2R */ |
| @@ -730,7 +741,7 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain) | |||
| 730 | reg = CBA2R_RW64_32BIT; | 741 | reg = CBA2R_RW64_32BIT; |
| 731 | #endif | 742 | #endif |
| 732 | writel_relaxed(reg, | 743 | writel_relaxed(reg, |
| 733 | gr1_base + ARM_SMMU_GR1_CBA2R(root_cfg->cbndx)); | 744 | gr1_base + ARM_SMMU_GR1_CBA2R(cfg->cbndx)); |
| 734 | 745 | ||
| 735 | /* TTBCR2 */ | 746 | /* TTBCR2 */ |
| 736 | switch (smmu->input_size) { | 747 | switch (smmu->input_size) { |
| @@ -780,13 +791,13 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain) | |||
| 780 | } | 791 | } |
| 781 | 792 | ||
| 782 | /* TTBR0 */ | 793 | /* TTBR0 */ |
| 783 | arm_smmu_flush_pgtable(smmu, root_cfg->pgd, | 794 | arm_smmu_flush_pgtable(smmu, cfg->pgd, |
| 784 | PTRS_PER_PGD * sizeof(pgd_t)); | 795 | PTRS_PER_PGD * sizeof(pgd_t)); |
| 785 | reg = __pa(root_cfg->pgd); | 796 | reg = __pa(cfg->pgd); |
| 786 | writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO); | 797 | writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO); |
| 787 | reg = (phys_addr_t)__pa(root_cfg->pgd) >> 32; | 798 | reg = (phys_addr_t)__pa(cfg->pgd) >> 32; |
| 788 | if (stage1) | 799 | if (stage1) |
| 789 | reg |= ARM_SMMU_CB_ASID(root_cfg) << TTBRn_HI_ASID_SHIFT; | 800 | reg |= ARM_SMMU_CB_ASID(cfg) << TTBRn_HI_ASID_SHIFT; |
| 790 | writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_HI); | 801 | writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_HI); |
| 791 | 802 | ||
| 792 | /* | 803 | /* |
| @@ -800,6 +811,8 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain) | |||
| 800 | reg = TTBCR_TG0_64K; | 811 | reg = TTBCR_TG0_64K; |
| 801 | 812 | ||
| 802 | if (!stage1) { | 813 | if (!stage1) { |
| 814 | reg |= (64 - smmu->s1_output_size) << TTBCR_T0SZ_SHIFT; | ||
| 815 | |||
| 803 | switch (smmu->s2_output_size) { | 816 | switch (smmu->s2_output_size) { |
| 804 | case 32: | 817 | case 32: |
| 805 | reg |= (TTBCR2_ADDR_32 << TTBCR_PASIZE_SHIFT); | 818 | reg |= (TTBCR2_ADDR_32 << TTBCR_PASIZE_SHIFT); |
| @@ -821,7 +834,7 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain) | |||
| 821 | break; | 834 | break; |
| 822 | } | 835 | } |
| 823 | } else { | 836 | } else { |
| 824 | reg |= (64 - smmu->s1_output_size) << TTBCR_T0SZ_SHIFT; | 837 | reg |= (64 - smmu->input_size) << TTBCR_T0SZ_SHIFT; |
| 825 | } | 838 | } |
| 826 | } else { | 839 | } else { |
| 827 | reg = 0; | 840 | reg = 0; |
| @@ -853,44 +866,25 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain) | |||
| 853 | } | 866 | } |
| 854 | 867 | ||
| 855 | static int arm_smmu_init_domain_context(struct iommu_domain *domain, | 868 | static int arm_smmu_init_domain_context(struct iommu_domain *domain, |
| 856 | struct device *dev) | 869 | struct arm_smmu_device *smmu) |
| 857 | { | 870 | { |
| 858 | int irq, ret, start; | 871 | int irq, ret, start; |
| 859 | struct arm_smmu_domain *smmu_domain = domain->priv; | 872 | struct arm_smmu_domain *smmu_domain = domain->priv; |
| 860 | struct arm_smmu_cfg *root_cfg = &smmu_domain->root_cfg; | 873 | struct arm_smmu_cfg *cfg = &smmu_domain->cfg; |
| 861 | struct arm_smmu_device *smmu, *parent; | ||
| 862 | |||
| 863 | /* | ||
| 864 | * Walk the SMMU chain to find the root device for this chain. | ||
| 865 | * We assume that no masters have translations which terminate | ||
| 866 | * early, and therefore check that the root SMMU does indeed have | ||
| 867 | * a StreamID for the master in question. | ||
| 868 | */ | ||
| 869 | parent = dev->archdata.iommu; | ||
| 870 | smmu_domain->output_mask = -1; | ||
| 871 | do { | ||
| 872 | smmu = parent; | ||
| 873 | smmu_domain->output_mask &= (1ULL << smmu->s2_output_size) - 1; | ||
| 874 | } while ((parent = find_parent_smmu(smmu))); | ||
| 875 | |||
| 876 | if (!find_smmu_master(smmu, dev->of_node)) { | ||
| 877 | dev_err(dev, "unable to find root SMMU for device\n"); | ||
| 878 | return -ENODEV; | ||
| 879 | } | ||
| 880 | 874 | ||
| 881 | if (smmu->features & ARM_SMMU_FEAT_TRANS_NESTED) { | 875 | if (smmu->features & ARM_SMMU_FEAT_TRANS_NESTED) { |
| 882 | /* | 876 | /* |
| 883 | * We will likely want to change this if/when KVM gets | 877 | * We will likely want to change this if/when KVM gets |
| 884 | * involved. | 878 | * involved. |
| 885 | */ | 879 | */ |
| 886 | root_cfg->cbar = CBAR_TYPE_S1_TRANS_S2_BYPASS; | 880 | cfg->cbar = CBAR_TYPE_S1_TRANS_S2_BYPASS; |
| 887 | start = smmu->num_s2_context_banks; | 881 | start = smmu->num_s2_context_banks; |
| 888 | } else if (smmu->features & ARM_SMMU_FEAT_TRANS_S2) { | 882 | } else if (smmu->features & ARM_SMMU_FEAT_TRANS_S1) { |
| 889 | root_cfg->cbar = CBAR_TYPE_S2_TRANS; | 883 | cfg->cbar = CBAR_TYPE_S1_TRANS_S2_BYPASS; |
| 890 | start = 0; | ||
| 891 | } else { | ||
| 892 | root_cfg->cbar = CBAR_TYPE_S1_TRANS_S2_BYPASS; | ||
| 893 | start = smmu->num_s2_context_banks; | 884 | start = smmu->num_s2_context_banks; |
| 885 | } else { | ||
| 886 | cfg->cbar = CBAR_TYPE_S2_TRANS; | ||
| 887 | start = 0; | ||
| 894 | } | 888 | } |
| 895 | 889 | ||
| 896 | ret = __arm_smmu_alloc_bitmap(smmu->context_map, start, | 890 | ret = __arm_smmu_alloc_bitmap(smmu->context_map, start, |
| @@ -898,38 +892,38 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, | |||
| 898 | if (IS_ERR_VALUE(ret)) | 892 | if (IS_ERR_VALUE(ret)) |
| 899 | return ret; | 893 | return ret; |
| 900 | 894 | ||
| 901 | root_cfg->cbndx = ret; | 895 | cfg->cbndx = ret; |
| 902 | if (smmu->version == 1) { | 896 | if (smmu->version == 1) { |
| 903 | root_cfg->irptndx = atomic_inc_return(&smmu->irptndx); | 897 | cfg->irptndx = atomic_inc_return(&smmu->irptndx); |
| 904 | root_cfg->irptndx %= smmu->num_context_irqs; | 898 | cfg->irptndx %= smmu->num_context_irqs; |
| 905 | } else { | 899 | } else { |
| 906 | root_cfg->irptndx = root_cfg->cbndx; | 900 | cfg->irptndx = cfg->cbndx; |
| 907 | } | 901 | } |
| 908 | 902 | ||
| 909 | irq = smmu->irqs[smmu->num_global_irqs + root_cfg->irptndx]; | 903 | irq = smmu->irqs[smmu->num_global_irqs + cfg->irptndx]; |
| 910 | ret = request_irq(irq, arm_smmu_context_fault, IRQF_SHARED, | 904 | ret = request_irq(irq, arm_smmu_context_fault, IRQF_SHARED, |
| 911 | "arm-smmu-context-fault", domain); | 905 | "arm-smmu-context-fault", domain); |
| 912 | if (IS_ERR_VALUE(ret)) { | 906 | if (IS_ERR_VALUE(ret)) { |
| 913 | dev_err(smmu->dev, "failed to request context IRQ %d (%u)\n", | 907 | dev_err(smmu->dev, "failed to request context IRQ %d (%u)\n", |
| 914 | root_cfg->irptndx, irq); | 908 | cfg->irptndx, irq); |
| 915 | root_cfg->irptndx = INVALID_IRPTNDX; | 909 | cfg->irptndx = INVALID_IRPTNDX; |
| 916 | goto out_free_context; | 910 | goto out_free_context; |
| 917 | } | 911 | } |
| 918 | 912 | ||
| 919 | root_cfg->smmu = smmu; | 913 | smmu_domain->smmu = smmu; |
| 920 | arm_smmu_init_context_bank(smmu_domain); | 914 | arm_smmu_init_context_bank(smmu_domain); |
| 921 | return ret; | 915 | return 0; |
| 922 | 916 | ||
| 923 | out_free_context: | 917 | out_free_context: |
| 924 | __arm_smmu_free_bitmap(smmu->context_map, root_cfg->cbndx); | 918 | __arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx); |
| 925 | return ret; | 919 | return ret; |
| 926 | } | 920 | } |
| 927 | 921 | ||
| 928 | static void arm_smmu_destroy_domain_context(struct iommu_domain *domain) | 922 | static void arm_smmu_destroy_domain_context(struct iommu_domain *domain) |
| 929 | { | 923 | { |
| 930 | struct arm_smmu_domain *smmu_domain = domain->priv; | 924 | struct arm_smmu_domain *smmu_domain = domain->priv; |
| 931 | struct arm_smmu_cfg *root_cfg = &smmu_domain->root_cfg; | 925 | struct arm_smmu_device *smmu = smmu_domain->smmu; |
| 932 | struct arm_smmu_device *smmu = root_cfg->smmu; | 926 | struct arm_smmu_cfg *cfg = &smmu_domain->cfg; |
| 933 | void __iomem *cb_base; | 927 | void __iomem *cb_base; |
| 934 | int irq; | 928 | int irq; |
| 935 | 929 | ||
| @@ -937,16 +931,16 @@ static void arm_smmu_destroy_domain_context(struct iommu_domain *domain) | |||
| 937 | return; | 931 | return; |
| 938 | 932 | ||
| 939 | /* Disable the context bank and nuke the TLB before freeing it. */ | 933 | /* Disable the context bank and nuke the TLB before freeing it. */ |
| 940 | cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, root_cfg->cbndx); | 934 | cb_base = ARM_SMMU_CB_BASE(smmu) + ARM_SMMU_CB(smmu, cfg->cbndx); |
| 941 | writel_relaxed(0, cb_base + ARM_SMMU_CB_SCTLR); | 935 | writel_relaxed(0, cb_base + ARM_SMMU_CB_SCTLR); |
| 942 | arm_smmu_tlb_inv_context(root_cfg); | 936 | arm_smmu_tlb_inv_context(smmu_domain); |
| 943 | 937 | ||
| 944 | if (root_cfg->irptndx != INVALID_IRPTNDX) { | 938 | if (cfg->irptndx != INVALID_IRPTNDX) { |
| 945 | irq = smmu->irqs[smmu->num_global_irqs + root_cfg->irptndx]; | 939 | irq = smmu->irqs[smmu->num_global_irqs + cfg->irptndx]; |
| 946 | free_irq(irq, domain); | 940 | free_irq(irq, domain); |
| 947 | } | 941 | } |
| 948 | 942 | ||
| 949 | __arm_smmu_free_bitmap(smmu->context_map, root_cfg->cbndx); | 943 | __arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx); |
| 950 | } | 944 | } |
| 951 | 945 | ||
| 952 | static int arm_smmu_domain_init(struct iommu_domain *domain) | 946 | static int arm_smmu_domain_init(struct iommu_domain *domain) |
| @@ -963,10 +957,10 @@ static int arm_smmu_domain_init(struct iommu_domain *domain) | |||
| 963 | if (!smmu_domain) | 957 | if (!smmu_domain) |
| 964 | return -ENOMEM; | 958 | return -ENOMEM; |
| 965 | 959 | ||
| 966 | pgd = kzalloc(PTRS_PER_PGD * sizeof(pgd_t), GFP_KERNEL); | 960 | pgd = kcalloc(PTRS_PER_PGD, sizeof(pgd_t), GFP_KERNEL); |
| 967 | if (!pgd) | 961 | if (!pgd) |
| 968 | goto out_free_domain; | 962 | goto out_free_domain; |
| 969 | smmu_domain->root_cfg.pgd = pgd; | 963 | smmu_domain->cfg.pgd = pgd; |
| 970 | 964 | ||
| 971 | spin_lock_init(&smmu_domain->lock); | 965 | spin_lock_init(&smmu_domain->lock); |
| 972 | domain->priv = smmu_domain; | 966 | domain->priv = smmu_domain; |
| @@ -980,6 +974,7 @@ out_free_domain: | |||
| 980 | static void arm_smmu_free_ptes(pmd_t *pmd) | 974 | static void arm_smmu_free_ptes(pmd_t *pmd) |
| 981 | { | 975 | { |
| 982 | pgtable_t table = pmd_pgtable(*pmd); | 976 | pgtable_t table = pmd_pgtable(*pmd); |
| 977 | |||
| 983 | pgtable_page_dtor(table); | 978 | pgtable_page_dtor(table); |
| 984 | __free_page(table); | 979 | __free_page(table); |
| 985 | } | 980 | } |
| @@ -1021,8 +1016,8 @@ static void arm_smmu_free_puds(pgd_t *pgd) | |||
| 1021 | static void arm_smmu_free_pgtables(struct arm_smmu_domain *smmu_domain) | 1016 | static void arm_smmu_free_pgtables(struct arm_smmu_domain *smmu_domain) |
| 1022 | { | 1017 | { |
| 1023 | int i; | 1018 | int i; |
| 1024 | struct arm_smmu_cfg *root_cfg = &smmu_domain->root_cfg; | 1019 | struct arm_smmu_cfg *cfg = &smmu_domain->cfg; |
| 1025 | pgd_t *pgd, *pgd_base = root_cfg->pgd; | 1020 | pgd_t *pgd, *pgd_base = cfg->pgd; |
| 1026 | 1021 | ||
| 1027 | /* | 1022 | /* |
| 1028 | * Recursively free the page tables for this domain. We don't | 1023 | * Recursively free the page tables for this domain. We don't |
| @@ -1054,7 +1049,7 @@ static void arm_smmu_domain_destroy(struct iommu_domain *domain) | |||
| 1054 | } | 1049 | } |
| 1055 | 1050 | ||
| 1056 | static int arm_smmu_master_configure_smrs(struct arm_smmu_device *smmu, | 1051 | static int arm_smmu_master_configure_smrs(struct arm_smmu_device *smmu, |
| 1057 | struct arm_smmu_master *master) | 1052 | struct arm_smmu_master_cfg *cfg) |
| 1058 | { | 1053 | { |
| 1059 | int i; | 1054 | int i; |
| 1060 | struct arm_smmu_smr *smrs; | 1055 | struct arm_smmu_smr *smrs; |
| @@ -1063,18 +1058,18 @@ static int arm_smmu_master_configure_smrs(struct arm_smmu_device *smmu, | |||
| 1063 | if (!(smmu->features & ARM_SMMU_FEAT_STREAM_MATCH)) | 1058 | if (!(smmu->features & ARM_SMMU_FEAT_STREAM_MATCH)) |
| 1064 | return 0; | 1059 | return 0; |
| 1065 | 1060 | ||
| 1066 | if (master->smrs) | 1061 | if (cfg->smrs) |
| 1067 | return -EEXIST; | 1062 | return -EEXIST; |
| 1068 | 1063 | ||
| 1069 | smrs = kmalloc(sizeof(*smrs) * master->num_streamids, GFP_KERNEL); | 1064 | smrs = kmalloc_array(cfg->num_streamids, sizeof(*smrs), GFP_KERNEL); |
| 1070 | if (!smrs) { | 1065 | if (!smrs) { |
| 1071 | dev_err(smmu->dev, "failed to allocate %d SMRs for master %s\n", | 1066 | dev_err(smmu->dev, "failed to allocate %d SMRs\n", |
| 1072 | master->num_streamids, master->of_node->name); | 1067 | cfg->num_streamids); |
| 1073 | return -ENOMEM; | 1068 | return -ENOMEM; |
| 1074 | } | 1069 | } |
| 1075 | 1070 | ||
| 1076 | /* Allocate the SMRs on the root SMMU */ | 1071 | /* Allocate the SMRs on the SMMU */ |
| 1077 | for (i = 0; i < master->num_streamids; ++i) { | 1072 | for (i = 0; i < cfg->num_streamids; ++i) { |
| 1078 | int idx = __arm_smmu_alloc_bitmap(smmu->smr_map, 0, | 1073 | int idx = __arm_smmu_alloc_bitmap(smmu->smr_map, 0, |
| 1079 | smmu->num_mapping_groups); | 1074 | smmu->num_mapping_groups); |
| 1080 | if (IS_ERR_VALUE(idx)) { | 1075 | if (IS_ERR_VALUE(idx)) { |
| @@ -1085,18 +1080,18 @@ static int arm_smmu_master_configure_smrs(struct arm_smmu_device *smmu, | |||
| 1085 | smrs[i] = (struct arm_smmu_smr) { | 1080 | smrs[i] = (struct arm_smmu_smr) { |
| 1086 | .idx = idx, | 1081 | .idx = idx, |
| 1087 | .mask = 0, /* We don't currently share SMRs */ | 1082 | .mask = 0, /* We don't currently share SMRs */ |
| 1088 | .id = master->streamids[i], | 1083 | .id = cfg->streamids[i], |
| 1089 | }; | 1084 | }; |
| 1090 | } | 1085 | } |
| 1091 | 1086 | ||
| 1092 | /* It worked! Now, poke the actual hardware */ | 1087 | /* It worked! Now, poke the actual hardware */ |
| 1093 | for (i = 0; i < master->num_streamids; ++i) { | 1088 | for (i = 0; i < cfg->num_streamids; ++i) { |
| 1094 | u32 reg = SMR_VALID | smrs[i].id << SMR_ID_SHIFT | | 1089 | u32 reg = SMR_VALID | smrs[i].id << SMR_ID_SHIFT | |
| 1095 | smrs[i].mask << SMR_MASK_SHIFT; | 1090 | smrs[i].mask << SMR_MASK_SHIFT; |
| 1096 | writel_relaxed(reg, gr0_base + ARM_SMMU_GR0_SMR(smrs[i].idx)); | 1091 | writel_relaxed(reg, gr0_base + ARM_SMMU_GR0_SMR(smrs[i].idx)); |
| 1097 | } | 1092 | } |
| 1098 | 1093 | ||
| 1099 | master->smrs = smrs; | 1094 | cfg->smrs = smrs; |
| 1100 | return 0; | 1095 | return 0; |
| 1101 | 1096 | ||
| 1102 | err_free_smrs: | 1097 | err_free_smrs: |
| @@ -1107,68 +1102,55 @@ err_free_smrs: | |||
| 1107 | } | 1102 | } |
| 1108 | 1103 | ||
| 1109 | static void arm_smmu_master_free_smrs(struct arm_smmu_device *smmu, | 1104 | static void arm_smmu_master_free_smrs(struct arm_smmu_device *smmu, |
| 1110 | struct arm_smmu_master *master) | 1105 | struct arm_smmu_master_cfg *cfg) |
| 1111 | { | 1106 | { |
| 1112 | int i; | 1107 | int i; |
| 1113 | void __iomem *gr0_base = ARM_SMMU_GR0(smmu); | 1108 | void __iomem *gr0_base = ARM_SMMU_GR0(smmu); |
| 1114 | struct arm_smmu_smr *smrs = master->smrs; | 1109 | struct arm_smmu_smr *smrs = cfg->smrs; |
| 1115 | 1110 | ||
| 1116 | /* Invalidate the SMRs before freeing back to the allocator */ | 1111 | /* Invalidate the SMRs before freeing back to the allocator */ |
| 1117 | for (i = 0; i < master->num_streamids; ++i) { | 1112 | for (i = 0; i < cfg->num_streamids; ++i) { |
| 1118 | u8 idx = smrs[i].idx; | 1113 | u8 idx = smrs[i].idx; |
| 1114 | |||
| 1119 | writel_relaxed(~SMR_VALID, gr0_base + ARM_SMMU_GR0_SMR(idx)); | 1115 | writel_relaxed(~SMR_VALID, gr0_base + ARM_SMMU_GR0_SMR(idx)); |
| 1120 | __arm_smmu_free_bitmap(smmu->smr_map, idx); | 1116 | __arm_smmu_free_bitmap(smmu->smr_map, idx); |
| 1121 | } | 1117 | } |
| 1122 | 1118 | ||
| 1123 | master->smrs = NULL; | 1119 | cfg->smrs = NULL; |
| 1124 | kfree(smrs); | 1120 | kfree(smrs); |
| 1125 | } | 1121 | } |
| 1126 | 1122 | ||
| 1127 | static void arm_smmu_bypass_stream_mapping(struct arm_smmu_device *smmu, | 1123 | static void arm_smmu_bypass_stream_mapping(struct arm_smmu_device *smmu, |
| 1128 | struct arm_smmu_master *master) | 1124 | struct arm_smmu_master_cfg *cfg) |
| 1129 | { | 1125 | { |
| 1130 | int i; | 1126 | int i; |
| 1131 | void __iomem *gr0_base = ARM_SMMU_GR0(smmu); | 1127 | void __iomem *gr0_base = ARM_SMMU_GR0(smmu); |
| 1132 | 1128 | ||
| 1133 | for (i = 0; i < master->num_streamids; ++i) { | 1129 | for (i = 0; i < cfg->num_streamids; ++i) { |
| 1134 | u16 sid = master->streamids[i]; | 1130 | u16 sid = cfg->streamids[i]; |
| 1131 | |||
| 1135 | writel_relaxed(S2CR_TYPE_BYPASS, | 1132 | writel_relaxed(S2CR_TYPE_BYPASS, |
| 1136 | gr0_base + ARM_SMMU_GR0_S2CR(sid)); | 1133 | gr0_base + ARM_SMMU_GR0_S2CR(sid)); |
| 1137 | } | 1134 | } |
| 1138 | } | 1135 | } |
| 1139 | 1136 | ||
| 1140 | static int arm_smmu_domain_add_master(struct arm_smmu_domain *smmu_domain, | 1137 | static int arm_smmu_domain_add_master(struct arm_smmu_domain *smmu_domain, |
| 1141 | struct arm_smmu_master *master) | 1138 | struct arm_smmu_master_cfg *cfg) |
| 1142 | { | 1139 | { |
| 1143 | int i, ret; | 1140 | int i, ret; |
| 1144 | struct arm_smmu_device *parent, *smmu = smmu_domain->root_cfg.smmu; | 1141 | struct arm_smmu_device *smmu = smmu_domain->smmu; |
| 1145 | void __iomem *gr0_base = ARM_SMMU_GR0(smmu); | 1142 | void __iomem *gr0_base = ARM_SMMU_GR0(smmu); |
| 1146 | 1143 | ||
| 1147 | ret = arm_smmu_master_configure_smrs(smmu, master); | 1144 | ret = arm_smmu_master_configure_smrs(smmu, cfg); |
| 1148 | if (ret) | 1145 | if (ret) |
| 1149 | return ret; | 1146 | return ret; |
| 1150 | 1147 | ||
| 1151 | /* Bypass the leaves */ | 1148 | for (i = 0; i < cfg->num_streamids; ++i) { |
| 1152 | smmu = smmu_domain->leaf_smmu; | ||
| 1153 | while ((parent = find_parent_smmu(smmu))) { | ||
| 1154 | /* | ||
| 1155 | * We won't have a StreamID match for anything but the root | ||
| 1156 | * smmu, so we only need to worry about StreamID indexing, | ||
| 1157 | * where we must install bypass entries in the S2CRs. | ||
| 1158 | */ | ||
| 1159 | if (smmu->features & ARM_SMMU_FEAT_STREAM_MATCH) | ||
| 1160 | continue; | ||
| 1161 | |||
| 1162 | arm_smmu_bypass_stream_mapping(smmu, master); | ||
| 1163 | smmu = parent; | ||
| 1164 | } | ||
| 1165 | |||
| 1166 | /* Now we're at the root, time to point at our context bank */ | ||
| 1167 | for (i = 0; i < master->num_streamids; ++i) { | ||
| 1168 | u32 idx, s2cr; | 1149 | u32 idx, s2cr; |
| 1169 | idx = master->smrs ? master->smrs[i].idx : master->streamids[i]; | 1150 | |
| 1151 | idx = cfg->smrs ? cfg->smrs[i].idx : cfg->streamids[i]; | ||
| 1170 | s2cr = S2CR_TYPE_TRANS | | 1152 | s2cr = S2CR_TYPE_TRANS | |
| 1171 | (smmu_domain->root_cfg.cbndx << S2CR_CBNDX_SHIFT); | 1153 | (smmu_domain->cfg.cbndx << S2CR_CBNDX_SHIFT); |
| 1172 | writel_relaxed(s2cr, gr0_base + ARM_SMMU_GR0_S2CR(idx)); | 1154 | writel_relaxed(s2cr, gr0_base + ARM_SMMU_GR0_S2CR(idx)); |
| 1173 | } | 1155 | } |
| 1174 | 1156 | ||
| @@ -1176,58 +1158,57 @@ static int arm_smmu_domain_add_master(struct arm_smmu_domain *smmu_domain, | |||
| 1176 | } | 1158 | } |
| 1177 | 1159 | ||
| 1178 | static void arm_smmu_domain_remove_master(struct arm_smmu_domain *smmu_domain, | 1160 | static void arm_smmu_domain_remove_master(struct arm_smmu_domain *smmu_domain, |
| 1179 | struct arm_smmu_master *master) | 1161 | struct arm_smmu_master_cfg *cfg) |
| 1180 | { | 1162 | { |
| 1181 | struct arm_smmu_device *smmu = smmu_domain->root_cfg.smmu; | 1163 | struct arm_smmu_device *smmu = smmu_domain->smmu; |
| 1182 | 1164 | ||
| 1183 | /* | 1165 | /* |
| 1184 | * We *must* clear the S2CR first, because freeing the SMR means | 1166 | * We *must* clear the S2CR first, because freeing the SMR means |
| 1185 | * that it can be re-allocated immediately. | 1167 | * that it can be re-allocated immediately. |
| 1186 | */ | 1168 | */ |
| 1187 | arm_smmu_bypass_stream_mapping(smmu, master); | 1169 | arm_smmu_bypass_stream_mapping(smmu, cfg); |
| 1188 | arm_smmu_master_free_smrs(smmu, master); | 1170 | arm_smmu_master_free_smrs(smmu, cfg); |
| 1189 | } | 1171 | } |
| 1190 | 1172 | ||
| 1191 | static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) | 1173 | static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) |
| 1192 | { | 1174 | { |
| 1193 | int ret = -EINVAL; | 1175 | int ret = -EINVAL; |
| 1194 | struct arm_smmu_domain *smmu_domain = domain->priv; | 1176 | struct arm_smmu_domain *smmu_domain = domain->priv; |
| 1195 | struct arm_smmu_device *device_smmu = dev->archdata.iommu; | 1177 | struct arm_smmu_device *smmu; |
| 1196 | struct arm_smmu_master *master; | 1178 | struct arm_smmu_master_cfg *cfg; |
| 1197 | unsigned long flags; | 1179 | unsigned long flags; |
| 1198 | 1180 | ||
| 1199 | if (!device_smmu) { | 1181 | smmu = dev_get_master_dev(dev)->archdata.iommu; |
| 1182 | if (!smmu) { | ||
| 1200 | dev_err(dev, "cannot attach to SMMU, is it on the same bus?\n"); | 1183 | dev_err(dev, "cannot attach to SMMU, is it on the same bus?\n"); |
| 1201 | return -ENXIO; | 1184 | return -ENXIO; |
| 1202 | } | 1185 | } |
| 1203 | 1186 | ||
| 1204 | /* | 1187 | /* |
| 1205 | * Sanity check the domain. We don't currently support domains | 1188 | * Sanity check the domain. We don't support domains across |
| 1206 | * that cross between different SMMU chains. | 1189 | * different SMMUs. |
| 1207 | */ | 1190 | */ |
| 1208 | spin_lock_irqsave(&smmu_domain->lock, flags); | 1191 | spin_lock_irqsave(&smmu_domain->lock, flags); |
| 1209 | if (!smmu_domain->leaf_smmu) { | 1192 | if (!smmu_domain->smmu) { |
| 1210 | /* Now that we have a master, we can finalise the domain */ | 1193 | /* Now that we have a master, we can finalise the domain */ |
| 1211 | ret = arm_smmu_init_domain_context(domain, dev); | 1194 | ret = arm_smmu_init_domain_context(domain, smmu); |
| 1212 | if (IS_ERR_VALUE(ret)) | 1195 | if (IS_ERR_VALUE(ret)) |
| 1213 | goto err_unlock; | 1196 | goto err_unlock; |
| 1214 | 1197 | } else if (smmu_domain->smmu != smmu) { | |
| 1215 | smmu_domain->leaf_smmu = device_smmu; | ||
| 1216 | } else if (smmu_domain->leaf_smmu != device_smmu) { | ||
| 1217 | dev_err(dev, | 1198 | dev_err(dev, |
| 1218 | "cannot attach to SMMU %s whilst already attached to domain on SMMU %s\n", | 1199 | "cannot attach to SMMU %s whilst already attached to domain on SMMU %s\n", |
| 1219 | dev_name(smmu_domain->leaf_smmu->dev), | 1200 | dev_name(smmu_domain->smmu->dev), |
| 1220 | dev_name(device_smmu->dev)); | 1201 | dev_name(smmu->dev)); |
| 1221 | goto err_unlock; | 1202 | goto err_unlock; |
| 1222 | } | 1203 | } |
| 1223 | spin_unlock_irqrestore(&smmu_domain->lock, flags); | 1204 | spin_unlock_irqrestore(&smmu_domain->lock, flags); |
| 1224 | 1205 | ||
| 1225 | /* Looks ok, so add the device to the domain */ | 1206 | /* Looks ok, so add the device to the domain */ |
| 1226 | master = find_smmu_master(smmu_domain->leaf_smmu, dev->of_node); | 1207 | cfg = find_smmu_master_cfg(smmu_domain->smmu, dev); |
| 1227 | if (!master) | 1208 | if (!cfg) |
| 1228 | return -ENODEV; | 1209 | return -ENODEV; |
| 1229 | 1210 | ||
| 1230 | return arm_smmu_domain_add_master(smmu_domain, master); | 1211 | return arm_smmu_domain_add_master(smmu_domain, cfg); |
| 1231 | 1212 | ||
| 1232 | err_unlock: | 1213 | err_unlock: |
| 1233 | spin_unlock_irqrestore(&smmu_domain->lock, flags); | 1214 | spin_unlock_irqrestore(&smmu_domain->lock, flags); |
| @@ -1237,11 +1218,11 @@ err_unlock: | |||
| 1237 | static void arm_smmu_detach_dev(struct iommu_domain *domain, struct device *dev) | 1218 | static void arm_smmu_detach_dev(struct iommu_domain *domain, struct device *dev) |
| 1238 | { | 1219 | { |
| 1239 | struct arm_smmu_domain *smmu_domain = domain->priv; | 1220 | struct arm_smmu_domain *smmu_domain = domain->priv; |
| 1240 | struct arm_smmu_master *master; | 1221 | struct arm_smmu_master_cfg *cfg; |
| 1241 | 1222 | ||
| 1242 | master = find_smmu_master(smmu_domain->leaf_smmu, dev->of_node); | 1223 | cfg = find_smmu_master_cfg(smmu_domain->smmu, dev); |
| 1243 | if (master) | 1224 | if (cfg) |
| 1244 | arm_smmu_domain_remove_master(smmu_domain, master); | 1225 | arm_smmu_domain_remove_master(smmu_domain, cfg); |
| 1245 | } | 1226 | } |
| 1246 | 1227 | ||
| 1247 | static bool arm_smmu_pte_is_contiguous_range(unsigned long addr, | 1228 | static bool arm_smmu_pte_is_contiguous_range(unsigned long addr, |
| @@ -1261,6 +1242,7 @@ static int arm_smmu_alloc_init_pte(struct arm_smmu_device *smmu, pmd_t *pmd, | |||
| 1261 | if (pmd_none(*pmd)) { | 1242 | if (pmd_none(*pmd)) { |
| 1262 | /* Allocate a new set of tables */ | 1243 | /* Allocate a new set of tables */ |
| 1263 | pgtable_t table = alloc_page(GFP_ATOMIC|__GFP_ZERO); | 1244 | pgtable_t table = alloc_page(GFP_ATOMIC|__GFP_ZERO); |
| 1245 | |||
| 1264 | if (!table) | 1246 | if (!table) |
| 1265 | return -ENOMEM; | 1247 | return -ENOMEM; |
| 1266 | 1248 | ||
| @@ -1326,6 +1308,7 @@ static int arm_smmu_alloc_init_pte(struct arm_smmu_device *smmu, pmd_t *pmd, | |||
| 1326 | */ | 1308 | */ |
| 1327 | do { | 1309 | do { |
| 1328 | int i = 1; | 1310 | int i = 1; |
| 1311 | |||
| 1329 | pteval &= ~ARM_SMMU_PTE_CONT; | 1312 | pteval &= ~ARM_SMMU_PTE_CONT; |
| 1330 | 1313 | ||
| 1331 | if (arm_smmu_pte_is_contiguous_range(addr, end)) { | 1314 | if (arm_smmu_pte_is_contiguous_range(addr, end)) { |
| @@ -1340,7 +1323,8 @@ static int arm_smmu_alloc_init_pte(struct arm_smmu_device *smmu, pmd_t *pmd, | |||
| 1340 | idx &= ~(ARM_SMMU_PTE_CONT_ENTRIES - 1); | 1323 | idx &= ~(ARM_SMMU_PTE_CONT_ENTRIES - 1); |
| 1341 | cont_start = pmd_page_vaddr(*pmd) + idx; | 1324 | cont_start = pmd_page_vaddr(*pmd) + idx; |
| 1342 | for (j = 0; j < ARM_SMMU_PTE_CONT_ENTRIES; ++j) | 1325 | for (j = 0; j < ARM_SMMU_PTE_CONT_ENTRIES; ++j) |
| 1343 | pte_val(*(cont_start + j)) &= ~ARM_SMMU_PTE_CONT; | 1326 | pte_val(*(cont_start + j)) &= |
| 1327 | ~ARM_SMMU_PTE_CONT; | ||
| 1344 | 1328 | ||
| 1345 | arm_smmu_flush_pgtable(smmu, cont_start, | 1329 | arm_smmu_flush_pgtable(smmu, cont_start, |
| 1346 | sizeof(*pte) * | 1330 | sizeof(*pte) * |
| @@ -1429,12 +1413,12 @@ static int arm_smmu_handle_mapping(struct arm_smmu_domain *smmu_domain, | |||
| 1429 | int ret, stage; | 1413 | int ret, stage; |
| 1430 | unsigned long end; | 1414 | unsigned long end; |
| 1431 | phys_addr_t input_mask, output_mask; | 1415 | phys_addr_t input_mask, output_mask; |
| 1432 | struct arm_smmu_cfg *root_cfg = &smmu_domain->root_cfg; | 1416 | struct arm_smmu_device *smmu = smmu_domain->smmu; |
| 1433 | pgd_t *pgd = root_cfg->pgd; | 1417 | struct arm_smmu_cfg *cfg = &smmu_domain->cfg; |
| 1434 | struct arm_smmu_device *smmu = root_cfg->smmu; | 1418 | pgd_t *pgd = cfg->pgd; |
| 1435 | unsigned long flags; | 1419 | unsigned long flags; |
| 1436 | 1420 | ||
| 1437 | if (root_cfg->cbar == CBAR_TYPE_S2_TRANS) { | 1421 | if (cfg->cbar == CBAR_TYPE_S2_TRANS) { |
| 1438 | stage = 2; | 1422 | stage = 2; |
| 1439 | output_mask = (1ULL << smmu->s2_output_size) - 1; | 1423 | output_mask = (1ULL << smmu->s2_output_size) - 1; |
| 1440 | } else { | 1424 | } else { |
| @@ -1484,10 +1468,6 @@ static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova, | |||
| 1484 | if (!smmu_domain) | 1468 | if (!smmu_domain) |
| 1485 | return -ENODEV; | 1469 | return -ENODEV; |
| 1486 | 1470 | ||
| 1487 | /* Check for silent address truncation up the SMMU chain. */ | ||
| 1488 | if ((phys_addr_t)iova & ~smmu_domain->output_mask) | ||
| 1489 | return -ERANGE; | ||
| 1490 | |||
| 1491 | return arm_smmu_handle_mapping(smmu_domain, iova, paddr, size, prot); | 1471 | return arm_smmu_handle_mapping(smmu_domain, iova, paddr, size, prot); |
| 1492 | } | 1472 | } |
| 1493 | 1473 | ||
| @@ -1498,7 +1478,7 @@ static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova, | |||
| 1498 | struct arm_smmu_domain *smmu_domain = domain->priv; | 1478 | struct arm_smmu_domain *smmu_domain = domain->priv; |
| 1499 | 1479 | ||
| 1500 | ret = arm_smmu_handle_mapping(smmu_domain, iova, 0, size, 0); | 1480 | ret = arm_smmu_handle_mapping(smmu_domain, iova, 0, size, 0); |
| 1501 | arm_smmu_tlb_inv_context(&smmu_domain->root_cfg); | 1481 | arm_smmu_tlb_inv_context(smmu_domain); |
| 1502 | return ret ? 0 : size; | 1482 | return ret ? 0 : size; |
| 1503 | } | 1483 | } |
| 1504 | 1484 | ||
| @@ -1510,9 +1490,9 @@ static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain, | |||
| 1510 | pmd_t pmd; | 1490 | pmd_t pmd; |
| 1511 | pte_t pte; | 1491 | pte_t pte; |
| 1512 | struct arm_smmu_domain *smmu_domain = domain->priv; | 1492 | struct arm_smmu_domain *smmu_domain = domain->priv; |
| 1513 | struct arm_smmu_cfg *root_cfg = &smmu_domain->root_cfg; | 1493 | struct arm_smmu_cfg *cfg = &smmu_domain->cfg; |
| 1514 | 1494 | ||
| 1515 | pgdp = root_cfg->pgd; | 1495 | pgdp = cfg->pgd; |
| 1516 | if (!pgdp) | 1496 | if (!pgdp) |
| 1517 | return 0; | 1497 | return 0; |
| 1518 | 1498 | ||
| @@ -1538,19 +1518,29 @@ static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain, | |||
| 1538 | static int arm_smmu_domain_has_cap(struct iommu_domain *domain, | 1518 | static int arm_smmu_domain_has_cap(struct iommu_domain *domain, |
| 1539 | unsigned long cap) | 1519 | unsigned long cap) |
| 1540 | { | 1520 | { |
| 1541 | unsigned long caps = 0; | ||
| 1542 | struct arm_smmu_domain *smmu_domain = domain->priv; | 1521 | struct arm_smmu_domain *smmu_domain = domain->priv; |
| 1522 | struct arm_smmu_device *smmu = smmu_domain->smmu; | ||
| 1523 | u32 features = smmu ? smmu->features : 0; | ||
| 1524 | |||
| 1525 | switch (cap) { | ||
| 1526 | case IOMMU_CAP_CACHE_COHERENCY: | ||
| 1527 | return features & ARM_SMMU_FEAT_COHERENT_WALK; | ||
| 1528 | case IOMMU_CAP_INTR_REMAP: | ||
| 1529 | return 1; /* MSIs are just memory writes */ | ||
| 1530 | default: | ||
| 1531 | return 0; | ||
| 1532 | } | ||
| 1533 | } | ||
| 1543 | 1534 | ||
| 1544 | if (smmu_domain->root_cfg.smmu->features & ARM_SMMU_FEAT_COHERENT_WALK) | 1535 | static int __arm_smmu_get_pci_sid(struct pci_dev *pdev, u16 alias, void *data) |
| 1545 | caps |= IOMMU_CAP_CACHE_COHERENCY; | 1536 | { |
| 1546 | 1537 | *((u16 *)data) = alias; | |
| 1547 | return !!(cap & caps); | 1538 | return 0; /* Continue walking */ |
| 1548 | } | 1539 | } |
| 1549 | 1540 | ||
| 1550 | static int arm_smmu_add_device(struct device *dev) | 1541 | static int arm_smmu_add_device(struct device *dev) |
| 1551 | { | 1542 | { |
| 1552 | struct arm_smmu_device *child, *parent, *smmu; | 1543 | struct arm_smmu_device *smmu; |
| 1553 | struct arm_smmu_master *master = NULL; | ||
| 1554 | struct iommu_group *group; | 1544 | struct iommu_group *group; |
| 1555 | int ret; | 1545 | int ret; |
| 1556 | 1546 | ||
| @@ -1559,35 +1549,8 @@ static int arm_smmu_add_device(struct device *dev) | |||
| 1559 | return -EINVAL; | 1549 | return -EINVAL; |
| 1560 | } | 1550 | } |
| 1561 | 1551 | ||
| 1562 | spin_lock(&arm_smmu_devices_lock); | 1552 | smmu = find_smmu_for_device(dev); |
| 1563 | list_for_each_entry(parent, &arm_smmu_devices, list) { | 1553 | if (!smmu) |
| 1564 | smmu = parent; | ||
| 1565 | |||
| 1566 | /* Try to find a child of the current SMMU. */ | ||
| 1567 | list_for_each_entry(child, &arm_smmu_devices, list) { | ||
| 1568 | if (child->parent_of_node == parent->dev->of_node) { | ||
| 1569 | /* Does the child sit above our master? */ | ||
| 1570 | master = find_smmu_master(child, dev->of_node); | ||
| 1571 | if (master) { | ||
| 1572 | smmu = NULL; | ||
| 1573 | break; | ||
| 1574 | } | ||
| 1575 | } | ||
| 1576 | } | ||
| 1577 | |||
| 1578 | /* We found some children, so keep searching. */ | ||
| 1579 | if (!smmu) { | ||
| 1580 | master = NULL; | ||
| 1581 | continue; | ||
| 1582 | } | ||
| 1583 | |||
| 1584 | master = find_smmu_master(smmu, dev->of_node); | ||
| 1585 | if (master) | ||
| 1586 | break; | ||
| 1587 | } | ||
| 1588 | spin_unlock(&arm_smmu_devices_lock); | ||
| 1589 | |||
| 1590 | if (!master) | ||
| 1591 | return -ENODEV; | 1554 | return -ENODEV; |
| 1592 | 1555 | ||
| 1593 | group = iommu_group_alloc(); | 1556 | group = iommu_group_alloc(); |
| @@ -1596,15 +1559,40 @@ static int arm_smmu_add_device(struct device *dev) | |||
| 1596 | return PTR_ERR(group); | 1559 | return PTR_ERR(group); |
| 1597 | } | 1560 | } |
| 1598 | 1561 | ||
| 1562 | if (dev_is_pci(dev)) { | ||
| 1563 | struct arm_smmu_master_cfg *cfg; | ||
| 1564 | struct pci_dev *pdev = to_pci_dev(dev); | ||
| 1565 | |||
| 1566 | cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); | ||
| 1567 | if (!cfg) { | ||
| 1568 | ret = -ENOMEM; | ||
| 1569 | goto out_put_group; | ||
| 1570 | } | ||
| 1571 | |||
| 1572 | cfg->num_streamids = 1; | ||
| 1573 | /* | ||
| 1574 | * Assume Stream ID == Requester ID for now. | ||
| 1575 | * We need a way to describe the ID mappings in FDT. | ||
| 1576 | */ | ||
| 1577 | pci_for_each_dma_alias(pdev, __arm_smmu_get_pci_sid, | ||
| 1578 | &cfg->streamids[0]); | ||
| 1579 | dev->archdata.iommu = cfg; | ||
| 1580 | } else { | ||
| 1581 | dev->archdata.iommu = smmu; | ||
| 1582 | } | ||
| 1583 | |||
| 1599 | ret = iommu_group_add_device(group, dev); | 1584 | ret = iommu_group_add_device(group, dev); |
| 1600 | iommu_group_put(group); | ||
| 1601 | dev->archdata.iommu = smmu; | ||
| 1602 | 1585 | ||
| 1586 | out_put_group: | ||
| 1587 | iommu_group_put(group); | ||
| 1603 | return ret; | 1588 | return ret; |
| 1604 | } | 1589 | } |
| 1605 | 1590 | ||
| 1606 | static void arm_smmu_remove_device(struct device *dev) | 1591 | static void arm_smmu_remove_device(struct device *dev) |
| 1607 | { | 1592 | { |
| 1593 | if (dev_is_pci(dev)) | ||
| 1594 | kfree(dev->archdata.iommu); | ||
| 1595 | |||
| 1608 | dev->archdata.iommu = NULL; | 1596 | dev->archdata.iommu = NULL; |
| 1609 | iommu_group_remove_device(dev); | 1597 | iommu_group_remove_device(dev); |
| 1610 | } | 1598 | } |
| @@ -1639,7 +1627,8 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu) | |||
| 1639 | /* Mark all SMRn as invalid and all S2CRn as bypass */ | 1627 | /* Mark all SMRn as invalid and all S2CRn as bypass */ |
| 1640 | for (i = 0; i < smmu->num_mapping_groups; ++i) { | 1628 | for (i = 0; i < smmu->num_mapping_groups; ++i) { |
| 1641 | writel_relaxed(~SMR_VALID, gr0_base + ARM_SMMU_GR0_SMR(i)); | 1629 | writel_relaxed(~SMR_VALID, gr0_base + ARM_SMMU_GR0_SMR(i)); |
| 1642 | writel_relaxed(S2CR_TYPE_BYPASS, gr0_base + ARM_SMMU_GR0_S2CR(i)); | 1630 | writel_relaxed(S2CR_TYPE_BYPASS, |
| 1631 | gr0_base + ARM_SMMU_GR0_S2CR(i)); | ||
| 1643 | } | 1632 | } |
| 1644 | 1633 | ||
| 1645 | /* Make sure all context banks are disabled and clear CB_FSR */ | 1634 | /* Make sure all context banks are disabled and clear CB_FSR */ |
| @@ -1779,11 +1768,13 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu) | |||
| 1779 | smmu->pagesize = (id & ID1_PAGESIZE) ? SZ_64K : SZ_4K; | 1768 | smmu->pagesize = (id & ID1_PAGESIZE) ? SZ_64K : SZ_4K; |
| 1780 | 1769 | ||
| 1781 | /* Check for size mismatch of SMMU address space from mapped region */ | 1770 | /* Check for size mismatch of SMMU address space from mapped region */ |
| 1782 | size = 1 << (((id >> ID1_NUMPAGENDXB_SHIFT) & ID1_NUMPAGENDXB_MASK) + 1); | 1771 | size = 1 << |
| 1772 | (((id >> ID1_NUMPAGENDXB_SHIFT) & ID1_NUMPAGENDXB_MASK) + 1); | ||
| 1783 | size *= (smmu->pagesize << 1); | 1773 | size *= (smmu->pagesize << 1); |
| 1784 | if (smmu->size != size) | 1774 | if (smmu->size != size) |
| 1785 | dev_warn(smmu->dev, "SMMU address space size (0x%lx) differs " | 1775 | dev_warn(smmu->dev, |
| 1786 | "from mapped region size (0x%lx)!\n", size, smmu->size); | 1776 | "SMMU address space size (0x%lx) differs from mapped region size (0x%lx)!\n", |
| 1777 | size, smmu->size); | ||
| 1787 | 1778 | ||
| 1788 | smmu->num_s2_context_banks = (id >> ID1_NUMS2CB_SHIFT) & | 1779 | smmu->num_s2_context_banks = (id >> ID1_NUMS2CB_SHIFT) & |
| 1789 | ID1_NUMS2CB_MASK; | 1780 | ID1_NUMS2CB_MASK; |
| @@ -1804,14 +1795,14 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu) | |||
| 1804 | * allocation (PTRS_PER_PGD). | 1795 | * allocation (PTRS_PER_PGD). |
| 1805 | */ | 1796 | */ |
| 1806 | #ifdef CONFIG_64BIT | 1797 | #ifdef CONFIG_64BIT |
| 1807 | smmu->s1_output_size = min((unsigned long)VA_BITS, size); | 1798 | smmu->s1_output_size = min_t(unsigned long, VA_BITS, size); |
| 1808 | #else | 1799 | #else |
| 1809 | smmu->s1_output_size = min(32UL, size); | 1800 | smmu->s1_output_size = min(32UL, size); |
| 1810 | #endif | 1801 | #endif |
| 1811 | 1802 | ||
| 1812 | /* The stage-2 output mask is also applied for bypass */ | 1803 | /* The stage-2 output mask is also applied for bypass */ |
| 1813 | size = arm_smmu_id_size_to_bits((id >> ID2_OAS_SHIFT) & ID2_OAS_MASK); | 1804 | size = arm_smmu_id_size_to_bits((id >> ID2_OAS_SHIFT) & ID2_OAS_MASK); |
| 1814 | smmu->s2_output_size = min((unsigned long)PHYS_MASK_SHIFT, size); | 1805 | smmu->s2_output_size = min_t(unsigned long, PHYS_MASK_SHIFT, size); |
| 1815 | 1806 | ||
| 1816 | if (smmu->version == 1) { | 1807 | if (smmu->version == 1) { |
| 1817 | smmu->input_size = 32; | 1808 | smmu->input_size = 32; |
| @@ -1835,7 +1826,8 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu) | |||
| 1835 | 1826 | ||
| 1836 | dev_notice(smmu->dev, | 1827 | dev_notice(smmu->dev, |
| 1837 | "\t%lu-bit VA, %lu-bit IPA, %lu-bit PA\n", | 1828 | "\t%lu-bit VA, %lu-bit IPA, %lu-bit PA\n", |
| 1838 | smmu->input_size, smmu->s1_output_size, smmu->s2_output_size); | 1829 | smmu->input_size, smmu->s1_output_size, |
| 1830 | smmu->s2_output_size); | ||
| 1839 | return 0; | 1831 | return 0; |
| 1840 | } | 1832 | } |
| 1841 | 1833 | ||
| @@ -1843,7 +1835,6 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev) | |||
| 1843 | { | 1835 | { |
| 1844 | struct resource *res; | 1836 | struct resource *res; |
| 1845 | struct arm_smmu_device *smmu; | 1837 | struct arm_smmu_device *smmu; |
| 1846 | struct device_node *dev_node; | ||
| 1847 | struct device *dev = &pdev->dev; | 1838 | struct device *dev = &pdev->dev; |
| 1848 | struct rb_node *node; | 1839 | struct rb_node *node; |
| 1849 | struct of_phandle_args masterspec; | 1840 | struct of_phandle_args masterspec; |
| @@ -1890,6 +1881,7 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev) | |||
| 1890 | 1881 | ||
| 1891 | for (i = 0; i < num_irqs; ++i) { | 1882 | for (i = 0; i < num_irqs; ++i) { |
| 1892 | int irq = platform_get_irq(pdev, i); | 1883 | int irq = platform_get_irq(pdev, i); |
| 1884 | |||
| 1893 | if (irq < 0) { | 1885 | if (irq < 0) { |
| 1894 | dev_err(dev, "failed to get irq index %d\n", i); | 1886 | dev_err(dev, "failed to get irq index %d\n", i); |
| 1895 | return -ENODEV; | 1887 | return -ENODEV; |
| @@ -1913,12 +1905,9 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev) | |||
| 1913 | } | 1905 | } |
| 1914 | dev_notice(dev, "registered %d master devices\n", i); | 1906 | dev_notice(dev, "registered %d master devices\n", i); |
| 1915 | 1907 | ||
| 1916 | if ((dev_node = of_parse_phandle(dev->of_node, "smmu-parent", 0))) | ||
| 1917 | smmu->parent_of_node = dev_node; | ||
| 1918 | |||
| 1919 | err = arm_smmu_device_cfg_probe(smmu); | 1908 | err = arm_smmu_device_cfg_probe(smmu); |
| 1920 | if (err) | 1909 | if (err) |
| 1921 | goto out_put_parent; | 1910 | goto out_put_masters; |
| 1922 | 1911 | ||
| 1923 | parse_driver_options(smmu); | 1912 | parse_driver_options(smmu); |
| 1924 | 1913 | ||
| @@ -1928,7 +1917,7 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev) | |||
| 1928 | "found only %d context interrupt(s) but %d required\n", | 1917 | "found only %d context interrupt(s) but %d required\n", |
| 1929 | smmu->num_context_irqs, smmu->num_context_banks); | 1918 | smmu->num_context_irqs, smmu->num_context_banks); |
| 1930 | err = -ENODEV; | 1919 | err = -ENODEV; |
| 1931 | goto out_put_parent; | 1920 | goto out_put_masters; |
| 1932 | } | 1921 | } |
| 1933 | 1922 | ||
| 1934 | for (i = 0; i < smmu->num_global_irqs; ++i) { | 1923 | for (i = 0; i < smmu->num_global_irqs; ++i) { |
| @@ -1956,14 +1945,10 @@ out_free_irqs: | |||
| 1956 | while (i--) | 1945 | while (i--) |
| 1957 | free_irq(smmu->irqs[i], smmu); | 1946 | free_irq(smmu->irqs[i], smmu); |
| 1958 | 1947 | ||
| 1959 | out_put_parent: | ||
| 1960 | if (smmu->parent_of_node) | ||
| 1961 | of_node_put(smmu->parent_of_node); | ||
| 1962 | |||
| 1963 | out_put_masters: | 1948 | out_put_masters: |
| 1964 | for (node = rb_first(&smmu->masters); node; node = rb_next(node)) { | 1949 | for (node = rb_first(&smmu->masters); node; node = rb_next(node)) { |
| 1965 | struct arm_smmu_master *master; | 1950 | struct arm_smmu_master *master |
| 1966 | master = container_of(node, struct arm_smmu_master, node); | 1951 | = container_of(node, struct arm_smmu_master, node); |
| 1967 | of_node_put(master->of_node); | 1952 | of_node_put(master->of_node); |
| 1968 | } | 1953 | } |
| 1969 | 1954 | ||
| @@ -1990,12 +1975,9 @@ static int arm_smmu_device_remove(struct platform_device *pdev) | |||
| 1990 | if (!smmu) | 1975 | if (!smmu) |
| 1991 | return -ENODEV; | 1976 | return -ENODEV; |
| 1992 | 1977 | ||
| 1993 | if (smmu->parent_of_node) | ||
| 1994 | of_node_put(smmu->parent_of_node); | ||
| 1995 | |||
| 1996 | for (node = rb_first(&smmu->masters); node; node = rb_next(node)) { | 1978 | for (node = rb_first(&smmu->masters); node; node = rb_next(node)) { |
| 1997 | struct arm_smmu_master *master; | 1979 | struct arm_smmu_master *master |
| 1998 | master = container_of(node, struct arm_smmu_master, node); | 1980 | = container_of(node, struct arm_smmu_master, node); |
| 1999 | of_node_put(master->of_node); | 1981 | of_node_put(master->of_node); |
| 2000 | } | 1982 | } |
| 2001 | 1983 | ||
| @@ -2006,7 +1988,7 @@ static int arm_smmu_device_remove(struct platform_device *pdev) | |||
| 2006 | free_irq(smmu->irqs[i], smmu); | 1988 | free_irq(smmu->irqs[i], smmu); |
| 2007 | 1989 | ||
| 2008 | /* Turn the thing off */ | 1990 | /* Turn the thing off */ |
| 2009 | writel(sCR0_CLIENTPD,ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0); | 1991 | writel(sCR0_CLIENTPD, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0); |
| 2010 | return 0; | 1992 | return 0; |
| 2011 | } | 1993 | } |
| 2012 | 1994 | ||
| @@ -2048,6 +2030,11 @@ static int __init arm_smmu_init(void) | |||
| 2048 | bus_set_iommu(&amba_bustype, &arm_smmu_ops); | 2030 | bus_set_iommu(&amba_bustype, &arm_smmu_ops); |
| 2049 | #endif | 2031 | #endif |
| 2050 | 2032 | ||
| 2033 | #ifdef CONFIG_PCI | ||
| 2034 | if (!iommu_present(&pci_bus_type)) | ||
| 2035 | bus_set_iommu(&pci_bus_type, &arm_smmu_ops); | ||
| 2036 | #endif | ||
| 2037 | |||
| 2051 | return 0; | 2038 | return 0; |
| 2052 | } | 2039 | } |
| 2053 | 2040 | ||
