Skip to content

Commit fbfe7e1

Browse files
committed
irqchip/mbigen: Prepare for real per device MSI
The core infrastructure has everything in place to switch MBIGEN to per device MSI domains and avoid the convoluted construct of the existing platform-MSI layering violation. The new infrastructure provides a wired interrupt specific interface in the MSI core which converts the 'hardware interrupt number + trigger type' allocation which is required for wired interrupts in the regular irqdomain code to a normal MSI allocation. The hardware interrupt number and the trigger type are stored in the MSI descriptor device cookie by the core code so the MBIGEN specific code can retrieve them. The new per device domain is only instantiated when the irqdomain which is associated to the MBIGEN device provides MSI parent functionality. Up to that point it invokes the existing code. Once the parent is converted the code for the current platform-MSI mechanism is removed. The new domain shares the interrupt chip callbacks and the translation function. The only new functionality aside of filling out the msi_domain_template is a domain specific set_desc() callback, which will go away once all platform-MSI code has been converted. Signed-off-by: Thomas Gleixner <[email protected]> Signed-off-by: Anna-Maria Behnsen <[email protected]> Signed-off-by: Shivamurthy Shastri <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 496436f commit fbfe7e1

File tree

1 file changed

+70
-28
lines changed

1 file changed

+70
-28
lines changed

drivers/irqchip/irq-mbigen.c

Lines changed: 70 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -135,24 +135,14 @@ static int mbigen_set_type(struct irq_data *data, unsigned int type)
135135
return 0;
136136
}
137137

138-
static struct irq_chip mbigen_irq_chip = {
139-
.name = "mbigen-v2",
140-
.irq_mask = irq_chip_mask_parent,
141-
.irq_unmask = irq_chip_unmask_parent,
142-
.irq_eoi = mbigen_eoi_irq,
143-
.irq_set_type = mbigen_set_type,
144-
.irq_set_affinity = irq_chip_set_affinity_parent,
145-
};
146-
147-
static void mbigen_write_msg(struct msi_desc *desc, struct msi_msg *msg)
138+
static void mbigen_write_msi_msg(struct irq_data *d, struct msi_msg *msg)
148139
{
149-
struct irq_data *d = irq_get_irq_data(desc->irq);
150140
void __iomem *base = d->chip_data;
151141
u32 val;
152142

153143
if (!msg->address_lo && !msg->address_hi)
154144
return;
155-
145+
156146
base += get_mbigen_vec_reg(d->hwirq);
157147
val = readl_relaxed(base);
158148

@@ -165,10 +155,8 @@ static void mbigen_write_msg(struct msi_desc *desc, struct msi_msg *msg)
165155
writel_relaxed(val, base);
166156
}
167157

168-
static int mbigen_domain_translate(struct irq_domain *d,
169-
struct irq_fwspec *fwspec,
170-
unsigned long *hwirq,
171-
unsigned int *type)
158+
static int mbigen_domain_translate(struct irq_domain *d, struct irq_fwspec *fwspec,
159+
unsigned long *hwirq, unsigned int *type)
172160
{
173161
if (is_of_node(fwspec->fwnode) || is_acpi_device_node(fwspec->fwnode)) {
174162
if (fwspec->param_count != 2)
@@ -192,6 +180,17 @@ static int mbigen_domain_translate(struct irq_domain *d,
192180
return -EINVAL;
193181
}
194182

183+
/* The following section will go away once ITS provides a MSI parent */
184+
185+
static struct irq_chip mbigen_irq_chip = {
186+
.name = "mbigen-v2",
187+
.irq_mask = irq_chip_mask_parent,
188+
.irq_unmask = irq_chip_unmask_parent,
189+
.irq_eoi = mbigen_eoi_irq,
190+
.irq_set_type = mbigen_set_type,
191+
.irq_set_affinity = irq_chip_set_affinity_parent,
192+
};
193+
195194
static int mbigen_irq_domain_alloc(struct irq_domain *domain,
196195
unsigned int virq,
197196
unsigned int nr_irqs,
@@ -232,11 +231,63 @@ static const struct irq_domain_ops mbigen_domain_ops = {
232231
.free = mbigen_irq_domain_free,
233232
};
234233

234+
static void mbigen_write_msg(struct msi_desc *desc, struct msi_msg *msg)
235+
{
236+
mbigen_write_msi_msg(irq_get_irq_data(desc->irq), msg);
237+
}
238+
239+
/* End of to be removed section */
240+
241+
static void mbigen_domain_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
242+
{
243+
arg->desc = desc;
244+
arg->hwirq = (u32)desc->data.icookie.value;
245+
}
246+
247+
static const struct msi_domain_template mbigen_msi_template = {
248+
.chip = {
249+
.name = "mbigen-v2",
250+
.irq_mask = irq_chip_mask_parent,
251+
.irq_unmask = irq_chip_unmask_parent,
252+
.irq_eoi = mbigen_eoi_irq,
253+
.irq_set_type = mbigen_set_type,
254+
.irq_write_msi_msg = mbigen_write_msi_msg,
255+
},
256+
257+
.ops = {
258+
.set_desc = mbigen_domain_set_desc,
259+
.msi_translate = mbigen_domain_translate,
260+
},
261+
262+
.info = {
263+
.bus_token = DOMAIN_BUS_WIRED_TO_MSI,
264+
.flags = MSI_FLAG_USE_DEV_FWNODE,
265+
},
266+
};
267+
268+
static bool mbigen_create_device_domain(struct device *dev, unsigned int size,
269+
struct mbigen_device *mgn_chip)
270+
{
271+
struct irq_domain *domain = dev->msi.domain;
272+
273+
if (WARN_ON_ONCE(!domain))
274+
return false;
275+
276+
if (irq_domain_is_msi_parent(domain)) {
277+
return msi_create_device_irq_domain(dev, MSI_DEFAULT_DOMAIN,
278+
&mbigen_msi_template, size,
279+
NULL, mgn_chip->base);
280+
}
281+
282+
/* Remove once ITS provides MSI parent */
283+
return !!platform_msi_create_device_domain(dev, size, mbigen_write_msg,
284+
&mbigen_domain_ops, mgn_chip);
285+
}
286+
235287
static int mbigen_of_create_domain(struct platform_device *pdev,
236288
struct mbigen_device *mgn_chip)
237289
{
238290
struct platform_device *child;
239-
struct irq_domain *domain;
240291
struct device_node *np;
241292
u32 num_pins;
242293
int ret = 0;
@@ -258,11 +309,7 @@ static int mbigen_of_create_domain(struct platform_device *pdev,
258309
break;
259310
}
260311

261-
domain = platform_msi_create_device_domain(&child->dev, num_pins,
262-
mbigen_write_msg,
263-
&mbigen_domain_ops,
264-
mgn_chip);
265-
if (!domain) {
312+
if (!mbigen_create_device_domain(&child->dev, num_pins, mgn_chip)) {
266313
ret = -ENOMEM;
267314
break;
268315
}
@@ -284,7 +331,6 @@ MODULE_DEVICE_TABLE(acpi, mbigen_acpi_match);
284331
static int mbigen_acpi_create_domain(struct platform_device *pdev,
285332
struct mbigen_device *mgn_chip)
286333
{
287-
struct irq_domain *domain;
288334
u32 num_pins = 0;
289335
int ret;
290336

@@ -315,11 +361,7 @@ static int mbigen_acpi_create_domain(struct platform_device *pdev,
315361
if (ret || num_pins == 0)
316362
return -EINVAL;
317363

318-
domain = platform_msi_create_device_domain(&pdev->dev, num_pins,
319-
mbigen_write_msg,
320-
&mbigen_domain_ops,
321-
mgn_chip);
322-
if (!domain)
364+
if (!mbigen_create_device_domain(&pdev->dev, num_pins, mgn_chip))
323365
return -ENOMEM;
324366

325367
return 0;

0 commit comments

Comments
 (0)