hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/drivers/iommu/fsl_pamu_domain.c
....@@ -1,20 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
2
- * This program is free software; you can redistribute it and/or modify
3
- * it under the terms of the GNU General Public License, version 2, as
4
- * published by the Free Software Foundation.
5
- *
6
- * This program is distributed in the hope that it will be useful,
7
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
8
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9
- * GNU General Public License for more details.
10
- *
11
- * You should have received a copy of the GNU General Public License
12
- * along with this program; if not, write to the Free Software
13
- * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
143 *
154 * Copyright (C) 2013 Freescale Semiconductor, Inc.
165 * Author: Varun Sethi <varun.sethi@freescale.com>
17
- *
186 */
197
208 #define pr_fmt(fmt) "fsl-pamu-domain: %s: " fmt, __func__
....@@ -335,7 +323,7 @@
335323 pamu_disable_liodn(info->liodn);
336324 spin_unlock_irqrestore(&iommu_lock, flags);
337325 spin_lock_irqsave(&device_domain_lock, flags);
338
- info->dev->archdata.iommu_domain = NULL;
326
+ dev_iommu_priv_set(info->dev, NULL);
339327 kmem_cache_free(iommu_devinfo_cache, info);
340328 spin_unlock_irqrestore(&device_domain_lock, flags);
341329 }
....@@ -364,7 +352,7 @@
364352 * Check here if the device is already attached to domain or not.
365353 * If the device is already attached to a domain detach it.
366354 */
367
- old_domain_info = dev->archdata.iommu_domain;
355
+ old_domain_info = dev_iommu_priv_get(dev);
368356 if (old_domain_info && old_domain_info->domain != dma_domain) {
369357 spin_unlock_irqrestore(&device_domain_lock, flags);
370358 detach_device(dev, old_domain_info->domain);
....@@ -383,8 +371,8 @@
383371 * the info for the first LIODN as all
384372 * LIODNs share the same domain
385373 */
386
- if (!dev->archdata.iommu_domain)
387
- dev->archdata.iommu_domain = info;
374
+ if (!dev_iommu_priv_get(dev))
375
+ dev_iommu_priv_set(dev, info);
388376 spin_unlock_irqrestore(&device_domain_lock, flags);
389377 }
390378
....@@ -814,6 +802,55 @@
814802 return 0;
815803 }
816804
805
+static int fsl_pamu_set_windows(struct iommu_domain *domain, u32 w_count)
806
+{
807
+ struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain);
808
+ unsigned long flags;
809
+ int ret;
810
+
811
+ spin_lock_irqsave(&dma_domain->domain_lock, flags);
812
+ /* Ensure domain is inactive i.e. DMA should be disabled for the domain */
813
+ if (dma_domain->enabled) {
814
+ pr_debug("Can't set geometry attributes as domain is active\n");
815
+ spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
816
+ return -EBUSY;
817
+ }
818
+
819
+ /* Ensure that the geometry has been set for the domain */
820
+ if (!dma_domain->geom_size) {
821
+ pr_debug("Please configure geometry before setting the number of windows\n");
822
+ spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
823
+ return -EINVAL;
824
+ }
825
+
826
+ /*
827
+ * Ensure we have valid window count i.e. it should be less than
828
+ * maximum permissible limit and should be a power of two.
829
+ */
830
+ if (w_count > pamu_get_max_subwin_cnt() || !is_power_of_2(w_count)) {
831
+ pr_debug("Invalid window count\n");
832
+ spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
833
+ return -EINVAL;
834
+ }
835
+
836
+ ret = pamu_set_domain_geometry(dma_domain, &domain->geometry,
837
+ w_count > 1 ? w_count : 0);
838
+ if (!ret) {
839
+ kfree(dma_domain->win_arr);
840
+ dma_domain->win_arr = kcalloc(w_count,
841
+ sizeof(*dma_domain->win_arr),
842
+ GFP_ATOMIC);
843
+ if (!dma_domain->win_arr) {
844
+ spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
845
+ return -ENOMEM;
846
+ }
847
+ dma_domain->win_cnt = w_count;
848
+ }
849
+ spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
850
+
851
+ return ret;
852
+}
853
+
817854 static int fsl_pamu_set_domain_attr(struct iommu_domain *domain,
818855 enum iommu_attr attr_type, void *data)
819856 {
....@@ -829,6 +866,9 @@
829866 break;
830867 case DOMAIN_ATTR_FSL_PAMU_ENABLE:
831868 ret = configure_domain_dma_state(dma_domain, *(int *)data);
869
+ break;
870
+ case DOMAIN_ATTR_WINDOWS:
871
+ ret = fsl_pamu_set_windows(domain, *(u32 *)data);
832872 break;
833873 default:
834874 pr_debug("Unsupported attribute type\n");
....@@ -855,6 +895,9 @@
855895 break;
856896 case DOMAIN_ATTR_FSL_PAMUV1:
857897 *(int *)data = DOMAIN_ATTR_FSL_PAMUV1;
898
+ break;
899
+ case DOMAIN_ATTR_WINDOWS:
900
+ *(u32 *)data = dma_domain->win_cnt;
858901 break;
859902 default:
860903 pr_debug("Unsupported attribute type\n");
....@@ -916,13 +959,13 @@
916959 static struct iommu_group *get_pci_device_group(struct pci_dev *pdev)
917960 {
918961 struct pci_controller *pci_ctl;
919
- bool pci_endpt_partioning;
962
+ bool pci_endpt_partitioning;
920963 struct iommu_group *group = NULL;
921964
922965 pci_ctl = pci_bus_to_host(pdev->bus);
923
- pci_endpt_partioning = check_pci_ctl_endpt_part(pci_ctl);
966
+ pci_endpt_partitioning = check_pci_ctl_endpt_part(pci_ctl);
924967 /* We can partition PCIe devices so assign device group to the device */
925
- if (pci_endpt_partioning) {
968
+ if (pci_endpt_partitioning) {
926969 group = pci_device_group(&pdev->dev);
927970
928971 /*
....@@ -973,81 +1016,13 @@
9731016 return group;
9741017 }
9751018
976
-static int fsl_pamu_add_device(struct device *dev)
1019
+static struct iommu_device *fsl_pamu_probe_device(struct device *dev)
9771020 {
978
- struct iommu_group *group;
979
-
980
- group = iommu_group_get_for_dev(dev);
981
- if (IS_ERR(group))
982
- return PTR_ERR(group);
983
-
984
- iommu_group_put(group);
985
-
986
- iommu_device_link(&pamu_iommu, dev);
987
-
988
- return 0;
1021
+ return &pamu_iommu;
9891022 }
9901023
991
-static void fsl_pamu_remove_device(struct device *dev)
1024
+static void fsl_pamu_release_device(struct device *dev)
9921025 {
993
- iommu_device_unlink(&pamu_iommu, dev);
994
- iommu_group_remove_device(dev);
995
-}
996
-
997
-static int fsl_pamu_set_windows(struct iommu_domain *domain, u32 w_count)
998
-{
999
- struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain);
1000
- unsigned long flags;
1001
- int ret;
1002
-
1003
- spin_lock_irqsave(&dma_domain->domain_lock, flags);
1004
- /* Ensure domain is inactive i.e. DMA should be disabled for the domain */
1005
- if (dma_domain->enabled) {
1006
- pr_debug("Can't set geometry attributes as domain is active\n");
1007
- spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
1008
- return -EBUSY;
1009
- }
1010
-
1011
- /* Ensure that the geometry has been set for the domain */
1012
- if (!dma_domain->geom_size) {
1013
- pr_debug("Please configure geometry before setting the number of windows\n");
1014
- spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
1015
- return -EINVAL;
1016
- }
1017
-
1018
- /*
1019
- * Ensure we have valid window count i.e. it should be less than
1020
- * maximum permissible limit and should be a power of two.
1021
- */
1022
- if (w_count > pamu_get_max_subwin_cnt() || !is_power_of_2(w_count)) {
1023
- pr_debug("Invalid window count\n");
1024
- spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
1025
- return -EINVAL;
1026
- }
1027
-
1028
- ret = pamu_set_domain_geometry(dma_domain, &domain->geometry,
1029
- w_count > 1 ? w_count : 0);
1030
- if (!ret) {
1031
- kfree(dma_domain->win_arr);
1032
- dma_domain->win_arr = kcalloc(w_count,
1033
- sizeof(*dma_domain->win_arr),
1034
- GFP_ATOMIC);
1035
- if (!dma_domain->win_arr) {
1036
- spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
1037
- return -ENOMEM;
1038
- }
1039
- dma_domain->win_cnt = w_count;
1040
- }
1041
- spin_unlock_irqrestore(&dma_domain->domain_lock, flags);
1042
-
1043
- return ret;
1044
-}
1045
-
1046
-static u32 fsl_pamu_get_windows(struct iommu_domain *domain)
1047
-{
1048
- struct fsl_dma_domain *dma_domain = to_fsl_dma_domain(domain);
1049
-
1050
- return dma_domain->win_cnt;
10511026 }
10521027
10531028 static const struct iommu_ops fsl_pamu_ops = {
....@@ -1058,13 +1033,11 @@
10581033 .detach_dev = fsl_pamu_detach_device,
10591034 .domain_window_enable = fsl_pamu_window_enable,
10601035 .domain_window_disable = fsl_pamu_window_disable,
1061
- .domain_get_windows = fsl_pamu_get_windows,
1062
- .domain_set_windows = fsl_pamu_set_windows,
10631036 .iova_to_phys = fsl_pamu_iova_to_phys,
10641037 .domain_set_attr = fsl_pamu_set_domain_attr,
10651038 .domain_get_attr = fsl_pamu_get_domain_attr,
1066
- .add_device = fsl_pamu_add_device,
1067
- .remove_device = fsl_pamu_remove_device,
1039
+ .probe_device = fsl_pamu_probe_device,
1040
+ .release_device = fsl_pamu_release_device,
10681041 .device_group = fsl_pamu_device_group,
10691042 };
10701043