@@ -94,6 +94,35 @@ static const struct irq_chip sg2042_msi_middle_irq_chip = {
9494 .irq_compose_msi_msg = sg2042_msi_irq_compose_msi_msg ,
9595};
9696
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+
97126static int sg204x_msi_parent_domain_alloc (struct irq_domain * domain , unsigned int virq , int hwirq )
98127{
99128 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
132161 irq_domain_set_hwirq_and_chip (domain , virq + i , hwirq + i ,
133162 data -> chip_info -> irqchip , data );
134163 }
135-
136164 return 0 ;
137165
138166err_hwirq :
139167 sg204x_msi_free_hwirq (data , hwirq , nr_irqs );
140168 irq_domain_free_irqs_parent (domain , virq , i );
141-
142169 return err ;
143170}
144171
@@ -172,6 +199,22 @@ static const struct msi_parent_ops sg2042_msi_parent_ops = {
172199 .init_dev_msi_info = msi_lib_init_dev_msi_info ,
173200};
174201
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+
175218static int sg204x_msi_init_domains (struct sg204x_msi_chipdata * data ,
176219 struct irq_domain * plic_domain , struct device * dev )
177220{
@@ -265,8 +308,14 @@ static const struct sg204x_msi_chip_info sg2042_chip_info = {
265308 .parent_ops = & sg2042_msi_parent_ops ,
266309};
267310
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+
268316static const struct of_device_id sg2042_msi_of_match [] = {
269317 { .compatible = "sophgo,sg2042-msi" , .data = & sg2042_chip_info },
318+ { .compatible = "sophgo,sg2044-msi" , .data = & sg2044_chip_info },
270319 { }
271320};
272321
0 commit comments