aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/arm64/iort.c238
1 files changed, 120 insertions, 118 deletions
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
index 9058cb084b91..b5390b4c9ade 100644
--- a/drivers/acpi/arm64/iort.c
+++ b/drivers/acpi/arm64/iort.c
@@ -753,31 +753,6 @@ static int __maybe_unused __get_pci_rid(struct pci_dev *pdev, u16 alias,
753 return 0; 753 return 0;
754} 754}
755 755
756static int arm_smmu_iort_xlate(struct device *dev, u32 streamid,
757 struct fwnode_handle *fwnode,
758 const struct iommu_ops *ops)
759{
760 int ret = iommu_fwspec_init(dev, fwnode, ops);
761
762 if (!ret)
763 ret = iommu_fwspec_add_ids(dev, &streamid, 1);
764
765 return ret;
766}
767
768static inline bool iort_iommu_driver_enabled(u8 type)
769{
770 switch (type) {
771 case ACPI_IORT_NODE_SMMU_V3:
772 return IS_BUILTIN(CONFIG_ARM_SMMU_V3);
773 case ACPI_IORT_NODE_SMMU:
774 return IS_BUILTIN(CONFIG_ARM_SMMU);
775 default:
776 pr_warn("IORT node type %u does not describe an SMMU\n", type);
777 return false;
778 }
779}
780
781#ifdef CONFIG_IOMMU_API 756#ifdef CONFIG_IOMMU_API
782static struct acpi_iort_node *iort_get_msi_resv_iommu(struct device *dev) 757static struct acpi_iort_node *iort_get_msi_resv_iommu(struct device *dev)
783{ 758{
@@ -878,15 +853,39 @@ int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head)
878 853
879 return (resv == its->its_count) ? resv : -ENODEV; 854 return (resv == its->its_count) ? resv : -ENODEV;
880} 855}
881#else 856
882static inline const struct iommu_ops *iort_fwspec_iommu_ops(struct device *dev) 857static inline bool iort_iommu_driver_enabled(u8 type)
883{ return NULL; } 858{
884static inline int iort_add_device_replay(const struct iommu_ops *ops, 859 switch (type) {
885 struct device *dev) 860 case ACPI_IORT_NODE_SMMU_V3:
886{ return 0; } 861 return IS_BUILTIN(CONFIG_ARM_SMMU_V3);
887int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head) 862 case ACPI_IORT_NODE_SMMU:
888{ return 0; } 863 return IS_BUILTIN(CONFIG_ARM_SMMU);
889#endif 864 default:
865 pr_warn("IORT node type %u does not describe an SMMU\n", type);
866 return false;
867 }
868}
869
870static int arm_smmu_iort_xlate(struct device *dev, u32 streamid,
871 struct fwnode_handle *fwnode,
872 const struct iommu_ops *ops)
873{
874 int ret = iommu_fwspec_init(dev, fwnode, ops);
875
876 if (!ret)
877 ret = iommu_fwspec_add_ids(dev, &streamid, 1);
878
879 return ret;
880}
881
882static bool iort_pci_rc_supports_ats(struct acpi_iort_node *node)
883{
884 struct acpi_iort_root_complex *pci_rc;
885
886 pci_rc = (struct acpi_iort_root_complex *)node->node_data;
887 return pci_rc->ats_attribute & ACPI_IORT_ATS_SUPPORTED;
888}
890 889
891static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node, 890static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
892 u32 streamid) 891 u32 streamid)
@@ -933,6 +932,93 @@ static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
933 return iort_iommu_xlate(info->dev, parent, streamid); 932 return iort_iommu_xlate(info->dev, parent, streamid);
934} 933}
935 934
935/**
936 * iort_iommu_configure - Set-up IOMMU configuration for a device.
937 *
938 * @dev: device to configure
939 *
940 * Returns: iommu_ops pointer on configuration success
941 * NULL on configuration failure
942 */
943const struct iommu_ops *iort_iommu_configure(struct device *dev)
944{
945 struct acpi_iort_node *node, *parent;
946 const struct iommu_ops *ops;
947 u32 streamid = 0;
948 int err = -ENODEV;
949
950 /*
951 * If we already translated the fwspec there
952 * is nothing left to do, return the iommu_ops.
953 */
954 ops = iort_fwspec_iommu_ops(dev);
955 if (ops)
956 return ops;
957
958 if (dev_is_pci(dev)) {
959 struct pci_bus *bus = to_pci_dev(dev)->bus;
960 struct iort_pci_alias_info info = { .dev = dev };
961
962 node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
963 iort_match_node_callback, &bus->dev);
964 if (!node)
965 return NULL;
966
967 info.node = node;
968 err = pci_for_each_dma_alias(to_pci_dev(dev),
969 iort_pci_iommu_init, &info);
970
971 if (!err && iort_pci_rc_supports_ats(node))
972 dev->iommu_fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS;
973 } else {
974 int i = 0;
975
976 node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
977 iort_match_node_callback, dev);
978 if (!node)
979 return NULL;
980
981 do {
982 parent = iort_node_map_platform_id(node, &streamid,
983 IORT_IOMMU_TYPE,
984 i++);
985
986 if (parent)
987 err = iort_iommu_xlate(dev, parent, streamid);
988 } while (parent && !err);
989 }
990
991 /*
992 * If we have reason to believe the IOMMU driver missed the initial
993 * add_device callback for dev, replay it to get things in order.
994 */
995 if (!err) {
996 ops = iort_fwspec_iommu_ops(dev);
997 err = iort_add_device_replay(ops, dev);
998 }
999
1000 /* Ignore all other errors apart from EPROBE_DEFER */
1001 if (err == -EPROBE_DEFER) {
1002 ops = ERR_PTR(err);
1003 } else if (err) {
1004 dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
1005 ops = NULL;
1006 }
1007
1008 return ops;
1009}
1010#else
1011static inline const struct iommu_ops *iort_fwspec_iommu_ops(struct device *dev)
1012{ return NULL; }
1013static inline int iort_add_device_replay(const struct iommu_ops *ops,
1014 struct device *dev)
1015{ return 0; }
1016int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head)
1017{ return 0; }
1018const struct iommu_ops *iort_iommu_configure(struct device *dev)
1019{ return NULL; }
1020#endif
1021
936static int nc_dma_get_range(struct device *dev, u64 *size) 1022static int nc_dma_get_range(struct device *dev, u64 *size)
937{ 1023{
938 struct acpi_iort_node *node; 1024 struct acpi_iort_node *node;
@@ -1031,90 +1117,6 @@ void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size)
1031 dev_dbg(dev, "dma_pfn_offset(%#08llx)\n", offset); 1117 dev_dbg(dev, "dma_pfn_offset(%#08llx)\n", offset);
1032} 1118}
1033 1119
1034static bool iort_pci_rc_supports_ats(struct acpi_iort_node *node)
1035{
1036 struct acpi_iort_root_complex *pci_rc;
1037
1038 pci_rc = (struct acpi_iort_root_complex *)node->node_data;
1039 return pci_rc->ats_attribute & ACPI_IORT_ATS_SUPPORTED;
1040}
1041
1042/**
1043 * iort_iommu_configure - Set-up IOMMU configuration for a device.
1044 *
1045 * @dev: device to configure
1046 *
1047 * Returns: iommu_ops pointer on configuration success
1048 * NULL on configuration failure
1049 */
1050const struct iommu_ops *iort_iommu_configure(struct device *dev)
1051{
1052 struct acpi_iort_node *node, *parent;
1053 const struct iommu_ops *ops;
1054 u32 streamid = 0;
1055 int err = -ENODEV;
1056
1057 /*
1058 * If we already translated the fwspec there
1059 * is nothing left to do, return the iommu_ops.
1060 */
1061 ops = iort_fwspec_iommu_ops(dev);
1062 if (ops)
1063 return ops;
1064
1065 if (dev_is_pci(dev)) {
1066 struct pci_bus *bus = to_pci_dev(dev)->bus;
1067 struct iort_pci_alias_info info = { .dev = dev };
1068
1069 node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
1070 iort_match_node_callback, &bus->dev);
1071 if (!node)
1072 return NULL;
1073
1074 info.node = node;
1075 err = pci_for_each_dma_alias(to_pci_dev(dev),
1076 iort_pci_iommu_init, &info);
1077
1078 if (!err && iort_pci_rc_supports_ats(node))
1079 dev->iommu_fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS;
1080 } else {
1081 int i = 0;
1082
1083 node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
1084 iort_match_node_callback, dev);
1085 if (!node)
1086 return NULL;
1087
1088 do {
1089 parent = iort_node_map_platform_id(node, &streamid,
1090 IORT_IOMMU_TYPE,
1091 i++);
1092
1093 if (parent)
1094 err = iort_iommu_xlate(dev, parent, streamid);
1095 } while (parent && !err);
1096 }
1097
1098 /*
1099 * If we have reason to believe the IOMMU driver missed the initial
1100 * add_device callback for dev, replay it to get things in order.
1101 */
1102 if (!err) {
1103 ops = iort_fwspec_iommu_ops(dev);
1104 err = iort_add_device_replay(ops, dev);
1105 }
1106
1107 /* Ignore all other errors apart from EPROBE_DEFER */
1108 if (err == -EPROBE_DEFER) {
1109 ops = ERR_PTR(err);
1110 } else if (err) {
1111 dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
1112 ops = NULL;
1113 }
1114
1115 return ops;
1116}
1117
1118static void __init acpi_iort_register_irq(int hwirq, const char *name, 1120static void __init acpi_iort_register_irq(int hwirq, const char *name,
1119 int trigger, 1121 int trigger,
1120 struct resource *res) 1122 struct resource *res)