diff options
Diffstat (limited to 'drivers/irqchip/irq-mvebu-gicp.c')
-rw-r--r-- | drivers/irqchip/irq-mvebu-gicp.c | 61 |
1 files changed, 26 insertions, 35 deletions
diff --git a/drivers/irqchip/irq-mvebu-gicp.c b/drivers/irqchip/irq-mvebu-gicp.c index c43a345061d5..d3232d6d8dce 100644 --- a/drivers/irqchip/irq-mvebu-gicp.c +++ b/drivers/irqchip/irq-mvebu-gicp.c @@ -17,6 +17,8 @@ #include <linux/of_platform.h> #include <linux/platform_device.h> +#include <linux/irqchip/irq-msi-lib.h> + #include <dt-bindings/interrupt-controller/arm-gic.h> #define GICP_SETSPI_NSR_OFFSET 0x0 @@ -145,32 +147,36 @@ static void gicp_irq_domain_free(struct irq_domain *domain, } static const struct irq_domain_ops gicp_domain_ops = { + .select = msi_lib_irq_domain_select, .alloc = gicp_irq_domain_alloc, .free = gicp_irq_domain_free, }; -static struct irq_chip gicp_msi_irq_chip = { - .name = "GICP", - .irq_set_type = irq_chip_set_type_parent, - .flags = IRQCHIP_SUPPORTS_LEVEL_MSI, -}; +#define GICP_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \ + MSI_FLAG_USE_DEF_CHIP_OPS) -static struct msi_domain_ops gicp_msi_ops = { -}; +#define GICP_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK | \ + MSI_FLAG_LEVEL_CAPABLE) -static struct msi_domain_info gicp_msi_domain_info = { - .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | - MSI_FLAG_LEVEL_CAPABLE), - .ops = &gicp_msi_ops, - .chip = &gicp_msi_irq_chip, +static const struct msi_parent_ops gicp_msi_parent_ops = { + .supported_flags = GICP_MSI_FLAGS_SUPPORTED, + .required_flags = GICP_MSI_FLAGS_REQUIRED, + .chip_flags = MSI_CHIP_FLAG_SET_EOI, + .bus_select_token = DOMAIN_BUS_GENERIC_MSI, + .bus_select_mask = MATCH_PLATFORM_MSI, + .prefix = "GICP-", + .init_dev_msi_info = msi_lib_init_dev_msi_info, }; static int mvebu_gicp_probe(struct platform_device *pdev) { - struct mvebu_gicp *gicp; - struct irq_domain *inner_domain, *plat_domain, *parent_domain; struct device_node *node = pdev->dev.of_node; struct device_node *irq_parent_dn; + struct irq_domain_info info = { + .fwnode = of_fwnode_handle(node), + .ops = &gicp_domain_ops, + }; + struct mvebu_gicp *gicp; int ret, i; gicp = devm_kzalloc(&pdev->dev, sizeof(*gicp), GFP_KERNEL); @@ -214,38 +220,23 @@ static int mvebu_gicp_probe(struct platform_device *pdev) if (!gicp->spi_bitmap) return -ENOMEM; + info.size = gicp->spi_cnt; + info.host_data = gicp; + irq_parent_dn = of_irq_find_parent(node); if (!irq_parent_dn) { dev_err(&pdev->dev, "failed to find parent IRQ node\n"); return -ENODEV; } - parent_domain = irq_find_host(irq_parent_dn); + info.parent = irq_find_host(irq_parent_dn); of_node_put(irq_parent_dn); - if (!parent_domain) { + if (!info.parent) { dev_err(&pdev->dev, "failed to find parent IRQ domain\n"); return -ENODEV; } - inner_domain = irq_domain_create_hierarchy(parent_domain, 0, - gicp->spi_cnt, - of_node_to_fwnode(node), - &gicp_domain_ops, gicp); - if (!inner_domain) - return -ENOMEM; - - - plat_domain = platform_msi_create_irq_domain(of_node_to_fwnode(node), - &gicp_msi_domain_info, - inner_domain); - if (!plat_domain) { - irq_domain_remove(inner_domain); - return -ENOMEM; - } - - platform_set_drvdata(pdev, gicp); - - return 0; + return msi_create_parent_irq_domain(&info, &gicp_msi_parent_ops) ? 0 : -ENOMEM; } static const struct of_device_id mvebu_gicp_of_match[] = { |