hc
2024-10-12 a5969cabbb4660eab42b6ef0412cbbd1200cf14d
kernel/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
....@@ -7,6 +7,8 @@
77 *
88 */
99
10
+#include <linux/acpi.h>
11
+#include <linux/acpi_iort.h>
1012 #include <linux/of_device.h>
1113 #include <linux/of_address.h>
1214 #include <linux/irq.h>
....@@ -22,6 +24,19 @@
2224 .irq_eoi = irq_chip_eoi_parent,
2325 .irq_set_affinity = msi_domain_set_affinity
2426 };
27
+
28
+static u32 fsl_mc_msi_domain_get_msi_id(struct irq_domain *domain,
29
+ struct fsl_mc_device *mc_dev)
30
+{
31
+ struct device_node *of_node;
32
+ u32 out_id;
33
+
34
+ of_node = irq_domain_get_of_node(domain);
35
+ out_id = of_node ? of_msi_map_id(&mc_dev->dev, of_node, mc_dev->icid) :
36
+ iort_msi_map_id(&mc_dev->dev, mc_dev->icid);
37
+
38
+ return out_id;
39
+}
2540
2641 static int its_fsl_mc_msi_prepare(struct irq_domain *msi_domain,
2742 struct device *dev,
....@@ -43,7 +58,8 @@
4358 * NOTE: This device id corresponds to the IOMMU stream ID
4459 * associated with the DPRC object (ICID).
4560 */
46
- info->scratchpad[0].ul = mc_bus_dev->icid;
61
+ info->scratchpad[0].ul = fsl_mc_msi_domain_get_msi_id(msi_domain,
62
+ mc_bus_dev);
4763 msi_info = msi_get_domain_info(msi_domain->parent);
4864
4965 /* Allocate at least 32 MSIs, and always as a power of 2 */
....@@ -66,11 +82,70 @@
6682 {},
6783 };
6884
69
-static int __init its_fsl_mc_msi_init(void)
85
+static void __init its_fsl_mc_msi_init_one(struct fwnode_handle *handle,
86
+ const char *name)
7087 {
71
- struct device_node *np;
7288 struct irq_domain *parent;
7389 struct irq_domain *mc_msi_domain;
90
+
91
+ parent = irq_find_matching_fwnode(handle, DOMAIN_BUS_NEXUS);
92
+ if (!parent || !msi_get_domain_info(parent)) {
93
+ pr_err("%s: unable to locate ITS domain\n", name);
94
+ return;
95
+ }
96
+
97
+ mc_msi_domain = fsl_mc_msi_create_irq_domain(handle,
98
+ &its_fsl_mc_msi_domain_info,
99
+ parent);
100
+ if (!mc_msi_domain) {
101
+ pr_err("%s: unable to create fsl-mc domain\n", name);
102
+ return;
103
+ }
104
+
105
+ pr_info("fsl-mc MSI: %s domain created\n", name);
106
+}
107
+
108
+#ifdef CONFIG_ACPI
109
+static int __init
110
+its_fsl_mc_msi_parse_madt(union acpi_subtable_headers *header,
111
+ const unsigned long end)
112
+{
113
+ struct acpi_madt_generic_translator *its_entry;
114
+ struct fwnode_handle *dom_handle;
115
+ const char *node_name;
116
+ int err = 0;
117
+
118
+ its_entry = (struct acpi_madt_generic_translator *)header;
119
+ node_name = kasprintf(GFP_KERNEL, "ITS@0x%lx",
120
+ (long)its_entry->base_address);
121
+
122
+ dom_handle = iort_find_domain_token(its_entry->translation_id);
123
+ if (!dom_handle) {
124
+ pr_err("%s: Unable to locate ITS domain handle\n", node_name);
125
+ err = -ENXIO;
126
+ goto out;
127
+ }
128
+
129
+ its_fsl_mc_msi_init_one(dom_handle, node_name);
130
+
131
+out:
132
+ kfree(node_name);
133
+ return err;
134
+}
135
+
136
+
137
+static void __init its_fsl_mc_acpi_msi_init(void)
138
+{
139
+ acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR,
140
+ its_fsl_mc_msi_parse_madt, 0);
141
+}
142
+#else
143
+static inline void its_fsl_mc_acpi_msi_init(void) { }
144
+#endif
145
+
146
+static void __init its_fsl_mc_of_msi_init(void)
147
+{
148
+ struct device_node *np;
74149
75150 for (np = of_find_matching_node(NULL, its_device_id); np;
76151 np = of_find_matching_node(np, its_device_id)) {
....@@ -79,23 +154,15 @@
79154 if (!of_property_read_bool(np, "msi-controller"))
80155 continue;
81156
82
- parent = irq_find_matching_host(np, DOMAIN_BUS_NEXUS);
83
- if (!parent || !msi_get_domain_info(parent)) {
84
- pr_err("%pOF: unable to locate ITS domain\n", np);
85
- continue;
86
- }
87
-
88
- mc_msi_domain = fsl_mc_msi_create_irq_domain(
89
- of_node_to_fwnode(np),
90
- &its_fsl_mc_msi_domain_info,
91
- parent);
92
- if (!mc_msi_domain) {
93
- pr_err("%pOF: unable to create fsl-mc domain\n", np);
94
- continue;
95
- }
96
-
97
- pr_info("fsl-mc MSI: %pOF domain created\n", np);
157
+ its_fsl_mc_msi_init_one(of_node_to_fwnode(np),
158
+ np->full_name);
98159 }
160
+}
161
+
162
+static int __init its_fsl_mc_msi_init(void)
163
+{
164
+ its_fsl_mc_of_msi_init();
165
+ its_fsl_mc_acpi_msi_init();
99166
100167 return 0;
101168 }