summaryrefslogtreecommitdiff
path: root/drivers/irqchip/irq-imx-mu-msi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/irqchip/irq-imx-mu-msi.c')
-rw-r--r--drivers/irqchip/irq-imx-mu-msi.c54
1 files changed, 23 insertions, 31 deletions
diff --git a/drivers/irqchip/irq-imx-mu-msi.c b/drivers/irqchip/irq-imx-mu-msi.c
index 90d41c1407ac..4342a21de1eb 100644
--- a/drivers/irqchip/irq-imx-mu-msi.c
+++ b/drivers/irqchip/irq-imx-mu-msi.c
@@ -24,6 +24,8 @@
#include <linux/pm_domain.h>
#include <linux/spinlock.h>
+#include "irq-msi-lib.h"
+
#define IMX_MU_CHANS 4
enum imx_mu_xcr {
@@ -114,20 +116,6 @@ static void imx_mu_msi_parent_ack_irq(struct irq_data *data)
imx_mu_read(msi_data, msi_data->cfg->xRR + data->hwirq * 4);
}
-static struct irq_chip imx_mu_msi_irq_chip = {
- .name = "MU-MSI",
- .irq_ack = irq_chip_ack_parent,
-};
-
-static struct msi_domain_ops imx_mu_msi_irq_ops = {
-};
-
-static struct msi_domain_info imx_mu_msi_domain_info = {
- .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS),
- .ops = &imx_mu_msi_irq_ops,
- .chip = &imx_mu_msi_irq_chip,
-};
-
static void imx_mu_msi_parent_compose_msg(struct irq_data *data,
struct msi_msg *msg)
{
@@ -195,6 +183,7 @@ static void imx_mu_msi_domain_irq_free(struct irq_domain *domain,
}
static const struct irq_domain_ops imx_mu_msi_domain_ops = {
+ .select = msi_lib_irq_domain_select,
.alloc = imx_mu_msi_domain_irq_alloc,
.free = imx_mu_msi_domain_irq_free,
};
@@ -216,35 +205,38 @@ static void imx_mu_msi_irq_handler(struct irq_desc *desc)
chained_irq_exit(chip, desc);
}
+#define IMX_MU_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \
+ MSI_FLAG_USE_DEF_CHIP_OPS | \
+ MSI_FLAG_PARENT_PM_DEV)
+
+#define IMX_MU_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK)
+
+static const struct msi_parent_ops imx_mu_msi_parent_ops = {
+ .supported_flags = IMX_MU_MSI_FLAGS_SUPPORTED,
+ .required_flags = IMX_MU_MSI_FLAGS_REQUIRED,
+ .bus_select_token = DOMAIN_BUS_NEXUS,
+ .bus_select_mask = MATCH_PLATFORM_MSI,
+ .prefix = "MU-MSI-",
+ .init_dev_msi_info = msi_lib_init_dev_msi_info,
+};
+
static int imx_mu_msi_domains_init(struct imx_mu_msi *msi_data, struct device *dev)
{
struct fwnode_handle *fwnodes = dev_fwnode(dev);
struct irq_domain *parent;
/* Initialize MSI domain parent */
- parent = irq_domain_create_linear(fwnodes,
- IMX_MU_CHANS,
- &imx_mu_msi_domain_ops,
- msi_data);
+ parent = irq_domain_create_linear(fwnodes, IMX_MU_CHANS,
+ &imx_mu_msi_domain_ops, msi_data);
if (!parent) {
dev_err(dev, "failed to create IRQ domain\n");
return -ENOMEM;
}
irq_domain_update_bus_token(parent, DOMAIN_BUS_NEXUS);
-
- msi_data->msi_domain = platform_msi_create_irq_domain(fwnodes,
- &imx_mu_msi_domain_info,
- parent);
-
- if (!msi_data->msi_domain) {
- dev_err(dev, "failed to create MSI domain\n");
- irq_domain_remove(parent);
- return -ENOMEM;
- }
-
- irq_domain_set_pm_device(msi_data->msi_domain, dev);
-
+ parent->dev = parent->pm_dev = dev;
+ parent->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT;
+ parent->msi_parent_ops = &imx_mu_msi_parent_ops;
return 0;
}