.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) 2011-2014 NVIDIA CORPORATION. All rights reserved. |
---|
3 | | - * |
---|
4 | | - * This program is free software; you can redistribute it and/or modify |
---|
5 | | - * it under the terms of the GNU General Public License version 2 as |
---|
6 | | - * published by the Free Software Foundation. |
---|
7 | 4 | */ |
---|
8 | 5 | |
---|
9 | 6 | #include <linux/bitops.h> |
---|
.. | .. |
---|
15 | 12 | #include <linux/of_device.h> |
---|
16 | 13 | #include <linux/platform_device.h> |
---|
17 | 14 | #include <linux/slab.h> |
---|
| 15 | +#include <linux/spinlock.h> |
---|
18 | 16 | #include <linux/dma-mapping.h> |
---|
19 | 17 | |
---|
20 | 18 | #include <soc/tegra/ahb.h> |
---|
.. | .. |
---|
22 | 20 | |
---|
23 | 21 | struct tegra_smmu_group { |
---|
24 | 22 | struct list_head list; |
---|
| 23 | + struct tegra_smmu *smmu; |
---|
25 | 24 | const struct tegra_smmu_group_soc *soc; |
---|
26 | 25 | struct iommu_group *group; |
---|
| 26 | + unsigned int swgroup; |
---|
27 | 27 | }; |
---|
28 | 28 | |
---|
29 | 29 | struct tegra_smmu { |
---|
.. | .. |
---|
52 | 52 | struct iommu_domain domain; |
---|
53 | 53 | struct tegra_smmu *smmu; |
---|
54 | 54 | unsigned int use_count; |
---|
| 55 | + spinlock_t lock; |
---|
55 | 56 | u32 *count; |
---|
56 | 57 | struct page **pts; |
---|
57 | 58 | struct page *pd; |
---|
.. | .. |
---|
130 | 131 | #define SMMU_PDE_SHIFT 22 |
---|
131 | 132 | #define SMMU_PTE_SHIFT 12 |
---|
132 | 133 | |
---|
| 134 | +#define SMMU_PAGE_MASK (~(SMMU_SIZE_PT-1)) |
---|
| 135 | +#define SMMU_OFFSET_IN_PAGE(x) ((unsigned long)(x) & ~SMMU_PAGE_MASK) |
---|
| 136 | +#define SMMU_PFN_PHYS(x) ((phys_addr_t)(x) << SMMU_PTE_SHIFT) |
---|
| 137 | +#define SMMU_PHYS_PFN(x) ((unsigned long)((x) >> SMMU_PTE_SHIFT)) |
---|
| 138 | + |
---|
133 | 139 | #define SMMU_PD_READABLE (1 << 31) |
---|
134 | 140 | #define SMMU_PD_WRITABLE (1 << 30) |
---|
135 | 141 | #define SMMU_PD_NONSECURE (1 << 29) |
---|
.. | .. |
---|
145 | 151 | |
---|
146 | 152 | #define SMMU_PDE_ATTR (SMMU_PDE_READABLE | SMMU_PDE_WRITABLE | \ |
---|
147 | 153 | SMMU_PDE_NONSECURE) |
---|
148 | | -#define SMMU_PTE_ATTR (SMMU_PTE_READABLE | SMMU_PTE_WRITABLE | \ |
---|
149 | | - SMMU_PTE_NONSECURE) |
---|
150 | 154 | |
---|
151 | 155 | static unsigned int iova_pd_index(unsigned long iova) |
---|
152 | 156 | { |
---|
.. | .. |
---|
245 | 249 | |
---|
246 | 250 | static inline void smmu_flush(struct tegra_smmu *smmu) |
---|
247 | 251 | { |
---|
248 | | - smmu_readl(smmu, SMMU_CONFIG); |
---|
| 252 | + smmu_readl(smmu, SMMU_PTB_ASID); |
---|
249 | 253 | } |
---|
250 | 254 | |
---|
251 | 255 | static int tegra_smmu_alloc_asid(struct tegra_smmu *smmu, unsigned int *idp) |
---|
.. | .. |
---|
313 | 317 | return NULL; |
---|
314 | 318 | } |
---|
315 | 319 | |
---|
| 320 | + spin_lock_init(&as->lock); |
---|
| 321 | + |
---|
316 | 322 | /* setup aperture */ |
---|
317 | 323 | as->domain.geometry.aperture_start = 0; |
---|
318 | 324 | as->domain.geometry.aperture_end = 0xffffffff; |
---|
.. | .. |
---|
327 | 333 | |
---|
328 | 334 | /* TODO: free page directory and page tables */ |
---|
329 | 335 | |
---|
| 336 | + WARN_ON_ONCE(as->use_count); |
---|
| 337 | + kfree(as->count); |
---|
| 338 | + kfree(as->pts); |
---|
330 | 339 | kfree(as); |
---|
331 | 340 | } |
---|
332 | 341 | |
---|
.. | .. |
---|
353 | 362 | unsigned int i; |
---|
354 | 363 | u32 value; |
---|
355 | 364 | |
---|
| 365 | + group = tegra_smmu_find_swgroup(smmu, swgroup); |
---|
| 366 | + if (group) { |
---|
| 367 | + value = smmu_readl(smmu, group->reg); |
---|
| 368 | + value &= ~SMMU_ASID_MASK; |
---|
| 369 | + value |= SMMU_ASID_VALUE(asid); |
---|
| 370 | + value |= SMMU_ASID_ENABLE; |
---|
| 371 | + smmu_writel(smmu, value, group->reg); |
---|
| 372 | + } else { |
---|
| 373 | + pr_warn("%s group from swgroup %u not found\n", __func__, |
---|
| 374 | + swgroup); |
---|
| 375 | + /* No point moving ahead if group was not found */ |
---|
| 376 | + return; |
---|
| 377 | + } |
---|
| 378 | + |
---|
356 | 379 | for (i = 0; i < smmu->soc->num_clients; i++) { |
---|
357 | 380 | const struct tegra_mc_client *client = &smmu->soc->clients[i]; |
---|
358 | 381 | |
---|
.. | .. |
---|
362 | 385 | value = smmu_readl(smmu, client->smmu.reg); |
---|
363 | 386 | value |= BIT(client->smmu.bit); |
---|
364 | 387 | smmu_writel(smmu, value, client->smmu.reg); |
---|
365 | | - } |
---|
366 | | - |
---|
367 | | - group = tegra_smmu_find_swgroup(smmu, swgroup); |
---|
368 | | - if (group) { |
---|
369 | | - value = smmu_readl(smmu, group->reg); |
---|
370 | | - value &= ~SMMU_ASID_MASK; |
---|
371 | | - value |= SMMU_ASID_VALUE(asid); |
---|
372 | | - value |= SMMU_ASID_ENABLE; |
---|
373 | | - smmu_writel(smmu, value, group->reg); |
---|
374 | 388 | } |
---|
375 | 389 | } |
---|
376 | 390 | |
---|
.. | .. |
---|
462 | 476 | static int tegra_smmu_attach_dev(struct iommu_domain *domain, |
---|
463 | 477 | struct device *dev) |
---|
464 | 478 | { |
---|
465 | | - struct tegra_smmu *smmu = dev->archdata.iommu; |
---|
| 479 | + struct tegra_smmu *smmu = dev_iommu_priv_get(dev); |
---|
466 | 480 | struct tegra_smmu_as *as = to_smmu_as(domain); |
---|
467 | 481 | struct device_node *np = dev->of_node; |
---|
468 | 482 | struct of_phandle_args args; |
---|
.. | .. |
---|
566 | 580 | } |
---|
567 | 581 | |
---|
568 | 582 | static u32 *as_get_pte(struct tegra_smmu_as *as, dma_addr_t iova, |
---|
569 | | - dma_addr_t *dmap) |
---|
| 583 | + dma_addr_t *dmap, struct page *page) |
---|
570 | 584 | { |
---|
571 | 585 | unsigned int pde = iova_pd_index(iova); |
---|
572 | 586 | struct tegra_smmu *smmu = as->smmu; |
---|
573 | 587 | |
---|
574 | 588 | if (!as->pts[pde]) { |
---|
575 | | - struct page *page; |
---|
576 | 589 | dma_addr_t dma; |
---|
577 | | - |
---|
578 | | - page = alloc_page(GFP_KERNEL | __GFP_DMA | __GFP_ZERO); |
---|
579 | | - if (!page) |
---|
580 | | - return NULL; |
---|
581 | 590 | |
---|
582 | 591 | dma = dma_map_page(smmu->dev, page, 0, SMMU_SIZE_PT, |
---|
583 | 592 | DMA_TO_DEVICE); |
---|
.. | .. |
---|
641 | 650 | u32 *pte, dma_addr_t pte_dma, u32 val) |
---|
642 | 651 | { |
---|
643 | 652 | struct tegra_smmu *smmu = as->smmu; |
---|
644 | | - unsigned long offset = offset_in_page(pte); |
---|
| 653 | + unsigned long offset = SMMU_OFFSET_IN_PAGE(pte); |
---|
645 | 654 | |
---|
646 | 655 | *pte = val; |
---|
647 | 656 | |
---|
.. | .. |
---|
652 | 661 | smmu_flush(smmu); |
---|
653 | 662 | } |
---|
654 | 663 | |
---|
655 | | -static int tegra_smmu_map(struct iommu_domain *domain, unsigned long iova, |
---|
656 | | - phys_addr_t paddr, size_t size, int prot) |
---|
| 664 | +static struct page *as_get_pde_page(struct tegra_smmu_as *as, |
---|
| 665 | + unsigned long iova, gfp_t gfp, |
---|
| 666 | + unsigned long *flags) |
---|
| 667 | +{ |
---|
| 668 | + unsigned int pde = iova_pd_index(iova); |
---|
| 669 | + struct page *page = as->pts[pde]; |
---|
| 670 | + |
---|
| 671 | + /* at first check whether allocation needs to be done at all */ |
---|
| 672 | + if (page) |
---|
| 673 | + return page; |
---|
| 674 | + |
---|
| 675 | + /* |
---|
| 676 | + * In order to prevent exhaustion of the atomic memory pool, we |
---|
| 677 | + * allocate page in a sleeping context if GFP flags permit. Hence |
---|
| 678 | + * spinlock needs to be unlocked and re-locked after allocation. |
---|
| 679 | + */ |
---|
| 680 | + if (!(gfp & __GFP_ATOMIC)) |
---|
| 681 | + spin_unlock_irqrestore(&as->lock, *flags); |
---|
| 682 | + |
---|
| 683 | + page = alloc_page(gfp | __GFP_DMA | __GFP_ZERO); |
---|
| 684 | + |
---|
| 685 | + if (!(gfp & __GFP_ATOMIC)) |
---|
| 686 | + spin_lock_irqsave(&as->lock, *flags); |
---|
| 687 | + |
---|
| 688 | + /* |
---|
| 689 | + * In a case of blocking allocation, a concurrent mapping may win |
---|
| 690 | + * the PDE allocation. In this case the allocated page isn't needed |
---|
| 691 | + * if allocation succeeded and the allocation failure isn't fatal. |
---|
| 692 | + */ |
---|
| 693 | + if (as->pts[pde]) { |
---|
| 694 | + if (page) |
---|
| 695 | + __free_page(page); |
---|
| 696 | + |
---|
| 697 | + page = as->pts[pde]; |
---|
| 698 | + } |
---|
| 699 | + |
---|
| 700 | + return page; |
---|
| 701 | +} |
---|
| 702 | + |
---|
| 703 | +static int |
---|
| 704 | +__tegra_smmu_map(struct iommu_domain *domain, unsigned long iova, |
---|
| 705 | + phys_addr_t paddr, size_t size, int prot, gfp_t gfp, |
---|
| 706 | + unsigned long *flags) |
---|
657 | 707 | { |
---|
658 | 708 | struct tegra_smmu_as *as = to_smmu_as(domain); |
---|
659 | 709 | dma_addr_t pte_dma; |
---|
| 710 | + struct page *page; |
---|
| 711 | + u32 pte_attrs; |
---|
660 | 712 | u32 *pte; |
---|
661 | 713 | |
---|
662 | | - pte = as_get_pte(as, iova, &pte_dma); |
---|
| 714 | + page = as_get_pde_page(as, iova, gfp, flags); |
---|
| 715 | + if (!page) |
---|
| 716 | + return -ENOMEM; |
---|
| 717 | + |
---|
| 718 | + pte = as_get_pte(as, iova, &pte_dma, page); |
---|
663 | 719 | if (!pte) |
---|
664 | 720 | return -ENOMEM; |
---|
665 | 721 | |
---|
.. | .. |
---|
667 | 723 | if (*pte == 0) |
---|
668 | 724 | tegra_smmu_pte_get_use(as, iova); |
---|
669 | 725 | |
---|
| 726 | + pte_attrs = SMMU_PTE_NONSECURE; |
---|
| 727 | + |
---|
| 728 | + if (prot & IOMMU_READ) |
---|
| 729 | + pte_attrs |= SMMU_PTE_READABLE; |
---|
| 730 | + |
---|
| 731 | + if (prot & IOMMU_WRITE) |
---|
| 732 | + pte_attrs |= SMMU_PTE_WRITABLE; |
---|
| 733 | + |
---|
670 | 734 | tegra_smmu_set_pte(as, iova, pte, pte_dma, |
---|
671 | | - __phys_to_pfn(paddr) | SMMU_PTE_ATTR); |
---|
| 735 | + SMMU_PHYS_PFN(paddr) | pte_attrs); |
---|
672 | 736 | |
---|
673 | 737 | return 0; |
---|
674 | 738 | } |
---|
675 | 739 | |
---|
676 | | -static size_t tegra_smmu_unmap(struct iommu_domain *domain, unsigned long iova, |
---|
677 | | - size_t size) |
---|
| 740 | +static size_t |
---|
| 741 | +__tegra_smmu_unmap(struct iommu_domain *domain, unsigned long iova, |
---|
| 742 | + size_t size, struct iommu_iotlb_gather *gather) |
---|
678 | 743 | { |
---|
679 | 744 | struct tegra_smmu_as *as = to_smmu_as(domain); |
---|
680 | 745 | dma_addr_t pte_dma; |
---|
.. | .. |
---|
686 | 751 | |
---|
687 | 752 | tegra_smmu_set_pte(as, iova, pte, pte_dma, 0); |
---|
688 | 753 | tegra_smmu_pte_put_use(as, iova); |
---|
| 754 | + |
---|
| 755 | + return size; |
---|
| 756 | +} |
---|
| 757 | + |
---|
| 758 | +static int tegra_smmu_map(struct iommu_domain *domain, unsigned long iova, |
---|
| 759 | + phys_addr_t paddr, size_t size, int prot, gfp_t gfp) |
---|
| 760 | +{ |
---|
| 761 | + struct tegra_smmu_as *as = to_smmu_as(domain); |
---|
| 762 | + unsigned long flags; |
---|
| 763 | + int ret; |
---|
| 764 | + |
---|
| 765 | + spin_lock_irqsave(&as->lock, flags); |
---|
| 766 | + ret = __tegra_smmu_map(domain, iova, paddr, size, prot, gfp, &flags); |
---|
| 767 | + spin_unlock_irqrestore(&as->lock, flags); |
---|
| 768 | + |
---|
| 769 | + return ret; |
---|
| 770 | +} |
---|
| 771 | + |
---|
| 772 | +static size_t tegra_smmu_unmap(struct iommu_domain *domain, unsigned long iova, |
---|
| 773 | + size_t size, struct iommu_iotlb_gather *gather) |
---|
| 774 | +{ |
---|
| 775 | + struct tegra_smmu_as *as = to_smmu_as(domain); |
---|
| 776 | + unsigned long flags; |
---|
| 777 | + |
---|
| 778 | + spin_lock_irqsave(&as->lock, flags); |
---|
| 779 | + size = __tegra_smmu_unmap(domain, iova, size, gather); |
---|
| 780 | + spin_unlock_irqrestore(&as->lock, flags); |
---|
689 | 781 | |
---|
690 | 782 | return size; |
---|
691 | 783 | } |
---|
.. | .. |
---|
704 | 796 | |
---|
705 | 797 | pfn = *pte & as->smmu->pfn_mask; |
---|
706 | 798 | |
---|
707 | | - return PFN_PHYS(pfn); |
---|
| 799 | + return SMMU_PFN_PHYS(pfn) + SMMU_OFFSET_IN_PAGE(iova); |
---|
708 | 800 | } |
---|
709 | 801 | |
---|
710 | 802 | static struct tegra_smmu *tegra_smmu_find(struct device_node *np) |
---|
.. | .. |
---|
745 | 837 | return 0; |
---|
746 | 838 | } |
---|
747 | 839 | |
---|
748 | | -static int tegra_smmu_add_device(struct device *dev) |
---|
| 840 | +static struct iommu_device *tegra_smmu_probe_device(struct device *dev) |
---|
749 | 841 | { |
---|
750 | 842 | struct device_node *np = dev->of_node; |
---|
751 | 843 | struct tegra_smmu *smmu = NULL; |
---|
752 | | - struct iommu_group *group; |
---|
753 | 844 | struct of_phandle_args args; |
---|
754 | 845 | unsigned int index = 0; |
---|
755 | 846 | int err; |
---|
.. | .. |
---|
762 | 853 | of_node_put(args.np); |
---|
763 | 854 | |
---|
764 | 855 | if (err < 0) |
---|
765 | | - return err; |
---|
| 856 | + return ERR_PTR(err); |
---|
766 | 857 | |
---|
767 | 858 | /* |
---|
768 | 859 | * Only a single IOMMU master interface is currently |
---|
769 | 860 | * supported by the Linux kernel, so abort after the |
---|
770 | 861 | * first match. |
---|
771 | 862 | */ |
---|
772 | | - dev->archdata.iommu = smmu; |
---|
773 | | - |
---|
774 | | - iommu_device_link(&smmu->iommu, dev); |
---|
| 863 | + dev_iommu_priv_set(dev, smmu); |
---|
775 | 864 | |
---|
776 | 865 | break; |
---|
777 | 866 | } |
---|
.. | .. |
---|
781 | 870 | } |
---|
782 | 871 | |
---|
783 | 872 | if (!smmu) |
---|
784 | | - return -ENODEV; |
---|
| 873 | + return ERR_PTR(-ENODEV); |
---|
785 | 874 | |
---|
786 | | - group = iommu_group_get_for_dev(dev); |
---|
787 | | - if (IS_ERR(group)) |
---|
788 | | - return PTR_ERR(group); |
---|
789 | | - |
---|
790 | | - iommu_group_put(group); |
---|
791 | | - |
---|
792 | | - return 0; |
---|
| 875 | + return &smmu->iommu; |
---|
793 | 876 | } |
---|
794 | 877 | |
---|
795 | | -static void tegra_smmu_remove_device(struct device *dev) |
---|
| 878 | +static void tegra_smmu_release_device(struct device *dev) |
---|
796 | 879 | { |
---|
797 | | - struct tegra_smmu *smmu = dev->archdata.iommu; |
---|
798 | | - |
---|
799 | | - if (smmu) |
---|
800 | | - iommu_device_unlink(&smmu->iommu, dev); |
---|
801 | | - |
---|
802 | | - dev->archdata.iommu = NULL; |
---|
803 | | - iommu_group_remove_device(dev); |
---|
| 880 | + dev_iommu_priv_set(dev, NULL); |
---|
804 | 881 | } |
---|
805 | 882 | |
---|
806 | 883 | static const struct tegra_smmu_group_soc * |
---|
.. | .. |
---|
816 | 893 | return NULL; |
---|
817 | 894 | } |
---|
818 | 895 | |
---|
| 896 | +static void tegra_smmu_group_release(void *iommu_data) |
---|
| 897 | +{ |
---|
| 898 | + struct tegra_smmu_group *group = iommu_data; |
---|
| 899 | + struct tegra_smmu *smmu = group->smmu; |
---|
| 900 | + |
---|
| 901 | + mutex_lock(&smmu->lock); |
---|
| 902 | + list_del(&group->list); |
---|
| 903 | + mutex_unlock(&smmu->lock); |
---|
| 904 | +} |
---|
| 905 | + |
---|
819 | 906 | static struct iommu_group *tegra_smmu_group_get(struct tegra_smmu *smmu, |
---|
820 | 907 | unsigned int swgroup) |
---|
821 | 908 | { |
---|
822 | 909 | const struct tegra_smmu_group_soc *soc; |
---|
823 | 910 | struct tegra_smmu_group *group; |
---|
| 911 | + struct iommu_group *grp; |
---|
824 | 912 | |
---|
| 913 | + /* Find group_soc associating with swgroup */ |
---|
825 | 914 | soc = tegra_smmu_find_group(smmu, swgroup); |
---|
826 | | - if (!soc) |
---|
827 | | - return NULL; |
---|
828 | 915 | |
---|
829 | 916 | mutex_lock(&smmu->lock); |
---|
830 | 917 | |
---|
| 918 | + /* Find existing iommu_group associating with swgroup or group_soc */ |
---|
831 | 919 | list_for_each_entry(group, &smmu->groups, list) |
---|
832 | | - if (group->soc == soc) { |
---|
| 920 | + if ((group->swgroup == swgroup) || (soc && group->soc == soc)) { |
---|
| 921 | + grp = iommu_group_ref_get(group->group); |
---|
833 | 922 | mutex_unlock(&smmu->lock); |
---|
834 | | - return group->group; |
---|
| 923 | + return grp; |
---|
835 | 924 | } |
---|
836 | 925 | |
---|
837 | 926 | group = devm_kzalloc(smmu->dev, sizeof(*group), GFP_KERNEL); |
---|
.. | .. |
---|
841 | 930 | } |
---|
842 | 931 | |
---|
843 | 932 | INIT_LIST_HEAD(&group->list); |
---|
| 933 | + group->swgroup = swgroup; |
---|
| 934 | + group->smmu = smmu; |
---|
844 | 935 | group->soc = soc; |
---|
845 | 936 | |
---|
846 | 937 | group->group = iommu_group_alloc(); |
---|
.. | .. |
---|
850 | 941 | return NULL; |
---|
851 | 942 | } |
---|
852 | 943 | |
---|
| 944 | + iommu_group_set_iommudata(group->group, group, tegra_smmu_group_release); |
---|
| 945 | + if (soc) |
---|
| 946 | + iommu_group_set_name(group->group, soc->name); |
---|
853 | 947 | list_add_tail(&group->list, &smmu->groups); |
---|
854 | 948 | mutex_unlock(&smmu->lock); |
---|
855 | 949 | |
---|
.. | .. |
---|
858 | 952 | |
---|
859 | 953 | static struct iommu_group *tegra_smmu_device_group(struct device *dev) |
---|
860 | 954 | { |
---|
861 | | - struct iommu_fwspec *fwspec = dev->iommu_fwspec; |
---|
862 | | - struct tegra_smmu *smmu = dev->archdata.iommu; |
---|
| 955 | + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); |
---|
| 956 | + struct tegra_smmu *smmu = dev_iommu_priv_get(dev); |
---|
863 | 957 | struct iommu_group *group; |
---|
864 | 958 | |
---|
865 | 959 | group = tegra_smmu_group_get(smmu, fwspec->ids[0]); |
---|
.. | .. |
---|
883 | 977 | .domain_free = tegra_smmu_domain_free, |
---|
884 | 978 | .attach_dev = tegra_smmu_attach_dev, |
---|
885 | 979 | .detach_dev = tegra_smmu_detach_dev, |
---|
886 | | - .add_device = tegra_smmu_add_device, |
---|
887 | | - .remove_device = tegra_smmu_remove_device, |
---|
| 980 | + .probe_device = tegra_smmu_probe_device, |
---|
| 981 | + .release_device = tegra_smmu_release_device, |
---|
888 | 982 | .device_group = tegra_smmu_device_group, |
---|
889 | 983 | .map = tegra_smmu_map, |
---|
890 | 984 | .unmap = tegra_smmu_unmap, |
---|
.. | .. |
---|
938 | 1032 | return 0; |
---|
939 | 1033 | } |
---|
940 | 1034 | |
---|
941 | | -static int tegra_smmu_swgroups_open(struct inode *inode, struct file *file) |
---|
942 | | -{ |
---|
943 | | - return single_open(file, tegra_smmu_swgroups_show, inode->i_private); |
---|
944 | | -} |
---|
945 | | - |
---|
946 | | -static const struct file_operations tegra_smmu_swgroups_fops = { |
---|
947 | | - .open = tegra_smmu_swgroups_open, |
---|
948 | | - .read = seq_read, |
---|
949 | | - .llseek = seq_lseek, |
---|
950 | | - .release = single_release, |
---|
951 | | -}; |
---|
| 1035 | +DEFINE_SHOW_ATTRIBUTE(tegra_smmu_swgroups); |
---|
952 | 1036 | |
---|
953 | 1037 | static int tegra_smmu_clients_show(struct seq_file *s, void *data) |
---|
954 | 1038 | { |
---|
.. | .. |
---|
976 | 1060 | return 0; |
---|
977 | 1061 | } |
---|
978 | 1062 | |
---|
979 | | -static int tegra_smmu_clients_open(struct inode *inode, struct file *file) |
---|
980 | | -{ |
---|
981 | | - return single_open(file, tegra_smmu_clients_show, inode->i_private); |
---|
982 | | -} |
---|
983 | | - |
---|
984 | | -static const struct file_operations tegra_smmu_clients_fops = { |
---|
985 | | - .open = tegra_smmu_clients_open, |
---|
986 | | - .read = seq_read, |
---|
987 | | - .llseek = seq_lseek, |
---|
988 | | - .release = single_release, |
---|
989 | | -}; |
---|
| 1063 | +DEFINE_SHOW_ATTRIBUTE(tegra_smmu_clients); |
---|
990 | 1064 | |
---|
991 | 1065 | static void tegra_smmu_debugfs_init(struct tegra_smmu *smmu) |
---|
992 | 1066 | { |
---|
.. | .. |
---|
1014 | 1088 | u32 value; |
---|
1015 | 1089 | int err; |
---|
1016 | 1090 | |
---|
1017 | | - /* This can happen on Tegra20 which doesn't have an SMMU */ |
---|
1018 | | - if (!soc) |
---|
1019 | | - return NULL; |
---|
1020 | | - |
---|
1021 | 1091 | smmu = devm_kzalloc(dev, sizeof(*smmu), GFP_KERNEL); |
---|
1022 | 1092 | if (!smmu) |
---|
1023 | 1093 | return ERR_PTR(-ENOMEM); |
---|
.. | .. |
---|
1027 | 1097 | * value. However the IOMMU registration process will attempt to add |
---|
1028 | 1098 | * all devices to the IOMMU when bus_set_iommu() is called. In order |
---|
1029 | 1099 | * not to rely on global variables to track the IOMMU instance, we |
---|
1030 | | - * set it here so that it can be looked up from the .add_device() |
---|
| 1100 | + * set it here so that it can be looked up from the .probe_device() |
---|
1031 | 1101 | * callback via the IOMMU device's .drvdata field. |
---|
1032 | 1102 | */ |
---|
1033 | 1103 | mc->smmu = smmu; |
---|
.. | .. |
---|
1046 | 1116 | smmu->dev = dev; |
---|
1047 | 1117 | smmu->mc = mc; |
---|
1048 | 1118 | |
---|
1049 | | - smmu->pfn_mask = BIT_MASK(mc->soc->num_address_bits - PAGE_SHIFT) - 1; |
---|
| 1119 | + smmu->pfn_mask = |
---|
| 1120 | + BIT_MASK(mc->soc->num_address_bits - SMMU_PTE_SHIFT) - 1; |
---|
1050 | 1121 | dev_dbg(dev, "address bits: %u, PFN mask: %#lx\n", |
---|
1051 | 1122 | mc->soc->num_address_bits, smmu->pfn_mask); |
---|
1052 | | - smmu->tlb_mask = (smmu->soc->num_tlb_lines << 1) - 1; |
---|
| 1123 | + smmu->tlb_mask = (1 << fls(smmu->soc->num_tlb_lines)) - 1; |
---|
1053 | 1124 | dev_dbg(dev, "TLB lines: %u, mask: %#lx\n", smmu->soc->num_tlb_lines, |
---|
1054 | 1125 | smmu->tlb_mask); |
---|
1055 | 1126 | |
---|