@@ -94,6 +94,35 @@ static const struct irq_chip sg2042_msi_middle_irq_chip = {
94
94
.irq_compose_msi_msg = sg2042_msi_irq_compose_msi_msg ,
95
95
};
96
96
97
+ static void sg2044_msi_irq_ack (struct irq_data * d )
98
+ {
99
+ struct sg204x_msi_chipdata * data = irq_data_get_irq_chip_data (d );
100
+
101
+ writel (0 , (u32 * )data -> reg_clr + d -> hwirq );
102
+ irq_chip_ack_parent (d );
103
+ }
104
+
105
+ static void sg2044_msi_irq_compose_msi_msg (struct irq_data * d , struct msi_msg * msg )
106
+ {
107
+ struct sg204x_msi_chipdata * data = irq_data_get_irq_chip_data (d );
108
+ phys_addr_t doorbell = data -> doorbell_addr + 4 * (d -> hwirq / 32 );
109
+
110
+ msg -> address_lo = lower_32_bits (doorbell );
111
+ msg -> address_hi = upper_32_bits (doorbell );
112
+ msg -> data = d -> hwirq % 32 ;
113
+ }
114
+
115
+ static struct irq_chip sg2044_msi_middle_irq_chip = {
116
+ .name = "SG2044 MSI" ,
117
+ .irq_ack = sg2044_msi_irq_ack ,
118
+ .irq_mask = irq_chip_mask_parent ,
119
+ .irq_unmask = irq_chip_unmask_parent ,
120
+ #ifdef CONFIG_SMP
121
+ .irq_set_affinity = irq_chip_set_affinity_parent ,
122
+ #endif
123
+ .irq_compose_msi_msg = sg2044_msi_irq_compose_msi_msg ,
124
+ };
125
+
97
126
static int sg204x_msi_parent_domain_alloc (struct irq_domain * domain , unsigned int virq , int hwirq )
98
127
{
99
128
struct sg204x_msi_chipdata * data = domain -> host_data ;
@@ -132,13 +161,11 @@ static int sg204x_msi_middle_domain_alloc(struct irq_domain *domain, unsigned in
132
161
irq_domain_set_hwirq_and_chip (domain , virq + i , hwirq + i ,
133
162
data -> chip_info -> irqchip , data );
134
163
}
135
-
136
164
return 0 ;
137
165
138
166
err_hwirq :
139
167
sg204x_msi_free_hwirq (data , hwirq , nr_irqs );
140
168
irq_domain_free_irqs_parent (domain , virq , i );
141
-
142
169
return err ;
143
170
}
144
171
@@ -172,6 +199,22 @@ static const struct msi_parent_ops sg2042_msi_parent_ops = {
172
199
.init_dev_msi_info = msi_lib_init_dev_msi_info ,
173
200
};
174
201
202
+ #define SG2044_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \
203
+ MSI_FLAG_USE_DEF_CHIP_OPS)
204
+
205
+ #define SG2044_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK | \
206
+ MSI_FLAG_PCI_MSIX)
207
+
208
+ static const struct msi_parent_ops sg2044_msi_parent_ops = {
209
+ .required_flags = SG2044_MSI_FLAGS_REQUIRED ,
210
+ .supported_flags = SG2044_MSI_FLAGS_SUPPORTED ,
211
+ .chip_flags = MSI_CHIP_FLAG_SET_EOI | MSI_CHIP_FLAG_SET_ACK ,
212
+ .bus_select_mask = MATCH_PCI_MSI ,
213
+ .bus_select_token = DOMAIN_BUS_NEXUS ,
214
+ .prefix = "SG2044-" ,
215
+ .init_dev_msi_info = msi_lib_init_dev_msi_info ,
216
+ };
217
+
175
218
static int sg204x_msi_init_domains (struct sg204x_msi_chipdata * data ,
176
219
struct irq_domain * plic_domain , struct device * dev )
177
220
{
@@ -265,8 +308,14 @@ static const struct sg204x_msi_chip_info sg2042_chip_info = {
265
308
.parent_ops = & sg2042_msi_parent_ops ,
266
309
};
267
310
311
+ static const struct sg204x_msi_chip_info sg2044_chip_info = {
312
+ .irqchip = & sg2044_msi_middle_irq_chip ,
313
+ .parent_ops = & sg2044_msi_parent_ops ,
314
+ };
315
+
268
316
static const struct of_device_id sg2042_msi_of_match [] = {
269
317
{ .compatible = "sophgo,sg2042-msi" , .data = & sg2042_chip_info },
318
+ { .compatible = "sophgo,sg2044-msi" , .data = & sg2044_chip_info },
270
319
{ }
271
320
};
272
321
0 commit comments