|
14 | 14 | #include <linux/of_irq.h>
|
15 | 15 | #include <linux/of_platform.h>
|
16 | 16 |
|
| 17 | +#include "irq-msi-lib.h" |
| 18 | + |
17 | 19 | /* Cause register */
|
18 | 20 | #define GICP_SECR(idx) (0x0 + ((idx) * 0x4))
|
19 | 21 | /* Mask register */
|
@@ -190,6 +192,7 @@ static void mvebu_sei_domain_free(struct irq_domain *domain, unsigned int virq,
|
190 | 192 | }
|
191 | 193 |
|
192 | 194 | static const struct irq_domain_ops mvebu_sei_domain_ops = {
|
| 195 | + .select = msi_lib_irq_domain_select, |
193 | 196 | .alloc = mvebu_sei_domain_alloc,
|
194 | 197 | .free = mvebu_sei_domain_free,
|
195 | 198 | };
|
@@ -307,21 +310,6 @@ static const struct irq_domain_ops mvebu_sei_cp_domain_ops = {
|
307 | 310 | .free = mvebu_sei_cp_domain_free,
|
308 | 311 | };
|
309 | 312 |
|
310 |
| -static struct irq_chip mvebu_sei_msi_irq_chip = { |
311 |
| - .name = "SEI pMSI", |
312 |
| - .irq_ack = irq_chip_ack_parent, |
313 |
| - .irq_set_type = irq_chip_set_type_parent, |
314 |
| -}; |
315 |
| - |
316 |
| -static struct msi_domain_ops mvebu_sei_msi_ops = { |
317 |
| -}; |
318 |
| - |
319 |
| -static struct msi_domain_info mvebu_sei_msi_domain_info = { |
320 |
| - .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS, |
321 |
| - .ops = &mvebu_sei_msi_ops, |
322 |
| - .chip = &mvebu_sei_msi_irq_chip, |
323 |
| -}; |
324 |
| - |
325 | 313 | static void mvebu_sei_handle_cascade_irq(struct irq_desc *desc)
|
326 | 314 | {
|
327 | 315 | struct mvebu_sei *sei = irq_desc_get_handler_data(desc);
|
@@ -360,10 +348,23 @@ static void mvebu_sei_reset(struct mvebu_sei *sei)
|
360 | 348 | }
|
361 | 349 | }
|
362 | 350 |
|
| 351 | +#define SEI_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \ |
| 352 | + MSI_FLAG_USE_DEF_CHIP_OPS) |
| 353 | + |
| 354 | +#define SEI_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK) |
| 355 | + |
| 356 | +static const struct msi_parent_ops sei_msi_parent_ops = { |
| 357 | + .supported_flags = SEI_MSI_FLAGS_SUPPORTED, |
| 358 | + .required_flags = SEI_MSI_FLAGS_REQUIRED, |
| 359 | + .bus_select_mask = MATCH_PLATFORM_MSI, |
| 360 | + .bus_select_token = DOMAIN_BUS_GENERIC_MSI, |
| 361 | + .prefix = "SEI-", |
| 362 | + .init_dev_msi_info = msi_lib_init_dev_msi_info, |
| 363 | +}; |
| 364 | + |
363 | 365 | static int mvebu_sei_probe(struct platform_device *pdev)
|
364 | 366 | {
|
365 | 367 | struct device_node *node = pdev->dev.of_node;
|
366 |
| - struct irq_domain *plat_domain; |
367 | 368 | struct mvebu_sei *sei;
|
368 | 369 | u32 parent_irq;
|
369 | 370 | int ret;
|
@@ -440,33 +441,20 @@ static int mvebu_sei_probe(struct platform_device *pdev)
|
440 | 441 | }
|
441 | 442 |
|
442 | 443 | irq_domain_update_bus_token(sei->cp_domain, DOMAIN_BUS_GENERIC_MSI);
|
443 |
| - |
444 |
| - plat_domain = platform_msi_create_irq_domain(of_node_to_fwnode(node), |
445 |
| - &mvebu_sei_msi_domain_info, |
446 |
| - sei->cp_domain); |
447 |
| - if (!plat_domain) { |
448 |
| - pr_err("Failed to create CPs MSI domain\n"); |
449 |
| - ret = -ENOMEM; |
450 |
| - goto remove_cp_domain; |
451 |
| - } |
| 444 | + sei->cp_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT; |
| 445 | + sei->cp_domain->msi_parent_ops = &sei_msi_parent_ops; |
452 | 446 |
|
453 | 447 | mvebu_sei_reset(sei);
|
454 | 448 |
|
455 |
| - irq_set_chained_handler_and_data(parent_irq, |
456 |
| - mvebu_sei_handle_cascade_irq, |
457 |
| - sei); |
458 |
| - |
| 449 | + irq_set_chained_handler_and_data(parent_irq, mvebu_sei_handle_cascade_irq, sei); |
459 | 450 | return 0;
|
460 | 451 |
|
461 |
| -remove_cp_domain: |
462 |
| - irq_domain_remove(sei->cp_domain); |
463 | 452 | remove_ap_domain:
|
464 | 453 | irq_domain_remove(sei->ap_domain);
|
465 | 454 | remove_sei_domain:
|
466 | 455 | irq_domain_remove(sei->sei_domain);
|
467 | 456 | dispose_irq:
|
468 | 457 | irq_dispose_mapping(parent_irq);
|
469 |
| - |
470 | 458 | return ret;
|
471 | 459 | }
|
472 | 460 |
|
|
0 commit comments