lkml.org 
[lkml]   [2022]   [Nov]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[patch V2 24/40] irqchip/mbigen: Prepare for real per device MSI
    Date
    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 <tglx@linutronix.de>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: Marc Zyngier <maz@kernel.org>
    Cc: Shameerali Kolothum Thodi <shameerali.kolothum.thodi@huawei.com>
    Cc: Zenghui Yu <yuzenghui@huawei.com>
    ---
    drivers/irqchip/irq-mbigen.c | 100 ++++++++++++++++++++++++++++++-------------
    1 file changed, 71 insertions(+), 29 deletions(-)

    --- a/drivers/irqchip/irq-mbigen.c
    +++ b/drivers/irqchip/irq-mbigen.c
    @@ -135,24 +135,14 @@ static int mbigen_set_type(struct irq_da
    return 0;
    }

    -static struct irq_chip mbigen_irq_chip = {
    - .name = "mbigen-v2",
    - .irq_mask = irq_chip_mask_parent,
    - .irq_unmask = irq_chip_unmask_parent,
    - .irq_eoi = mbigen_eoi_irq,
    - .irq_set_type = mbigen_set_type,
    - .irq_set_affinity = irq_chip_set_affinity_parent,
    -};
    -
    -static void mbigen_write_msg(struct msi_desc *desc, struct msi_msg *msg)
    +static void mbigen_write_msi_msg(struct irq_data *d, struct msi_msg *msg)
    {
    - struct irq_data *d = irq_get_irq_data(desc->irq);
    void __iomem *base = d->chip_data;
    u32 val;

    if (!msg->address_lo && !msg->address_hi)
    return;
    -
    +
    base += get_mbigen_vec_reg(d->hwirq);
    val = readl_relaxed(base);

    @@ -165,10 +155,8 @@ static void mbigen_write_msg(struct msi_
    writel_relaxed(val, base);
    }

    -static int mbigen_domain_translate(struct irq_domain *d,
    - struct irq_fwspec *fwspec,
    - unsigned long *hwirq,
    - unsigned int *type)
    +static int mbigen_domain_translate(struct irq_domain *d, struct irq_fwspec *fwspec,
    + unsigned long *hwirq, unsigned int *type)
    {
    if (is_of_node(fwspec->fwnode) || is_acpi_device_node(fwspec->fwnode)) {
    if (fwspec->param_count != 2)
    @@ -192,6 +180,17 @@ static int mbigen_domain_translate(struc
    return -EINVAL;
    }

    +/* The following section will go away once ITS provides a MSI parent */
    +
    +static struct irq_chip mbigen_irq_chip = {
    + .name = "mbigen-v2",
    + .irq_mask = irq_chip_mask_parent,
    + .irq_unmask = irq_chip_unmask_parent,
    + .irq_eoi = mbigen_eoi_irq,
    + .irq_set_type = mbigen_set_type,
    + .irq_set_affinity = irq_chip_set_affinity_parent,
    +};
    +
    static int mbigen_irq_domain_alloc(struct irq_domain *domain,
    unsigned int virq,
    unsigned int nr_irqs,
    @@ -232,13 +231,65 @@ static const struct irq_domain_ops mbige
    .free = mbigen_irq_domain_free,
    };

    +static void mbigen_write_msg(struct msi_desc *desc, struct msi_msg *msg)
    +{
    + mbigen_write_msi_msg(irq_get_irq_data(desc->irq), msg);
    +}
    +
    +/* End of to be removed section */
    +
    +static void mbigen_domain_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
    +{
    + arg->desc = desc;
    + arg->hwirq = (u32)desc->data.icookie.value;
    +}
    +
    +static const struct msi_domain_template mbigen_msi_template = {
    + .chip = {
    + .name = "mbigen-v2",
    + .irq_mask = irq_chip_mask_parent,
    + .irq_unmask = irq_chip_unmask_parent,
    + .irq_eoi = mbigen_eoi_irq,
    + .irq_set_type = mbigen_set_type,
    + .irq_write_msi_msg = mbigen_write_msi_msg,
    + },
    +
    + .ops = {
    + .set_desc = mbigen_domain_set_desc,
    + .msi_translate = mbigen_domain_translate,
    + },
    +
    + .info = {
    + .bus_token = DOMAIN_BUS_WIRED_TO_MSI,
    + .flags = MSI_FLAG_USE_DEV_FWNODE,
    + },
    +};
    +
    +static bool mbigen_create_device_domain(struct device *dev, unsigned int size,
    + struct mbigen_device *mgn_chip)
    +{
    + struct irq_domain *domain = dev->msi.domain;
    +
    + if (WARN_ON_ONCE(!domain))
    + return false;
    +
    + if (irq_domain_is_msi_parent(domain)) {
    + return msi_create_device_irq_domain(dev, MSI_DEFAULT_DOMAIN,
    + &mbigen_msi_template, size,
    + NULL, mgn_chip->base);
    + }
    +
    + /* Remove once ITS provides MSI parent */
    + return !!platform_msi_create_device_domain(dev, size, mbigen_write_msg,
    + &mbigen_domain_ops, mgn_chip);
    +}
    +
    static int mbigen_of_create_domain(struct platform_device *pdev,
    struct mbigen_device *mgn_chip)
    {
    - struct device *parent;
    struct platform_device *child;
    - struct irq_domain *domain;
    struct device_node *np;
    + struct device *parent;
    u32 num_pins;

    for_each_child_of_node(pdev->dev.of_node, np) {
    @@ -259,11 +310,7 @@ static int mbigen_of_create_domain(struc
    return -EINVAL;
    }

    - domain = platform_msi_create_device_domain(&child->dev, num_pins,
    - mbigen_write_msg,
    - &mbigen_domain_ops,
    - mgn_chip);
    - if (!domain) {
    + if (!mbigen_create_device_domain(&child->dev, num_pins, mgn_chip)) {
    of_node_put(np);
    return -ENOMEM;
    }
    @@ -282,7 +329,6 @@ MODULE_DEVICE_TABLE(acpi, mbigen_acpi_ma
    static int mbigen_acpi_create_domain(struct platform_device *pdev,
    struct mbigen_device *mgn_chip)
    {
    - struct irq_domain *domain;
    u32 num_pins = 0;
    int ret;

    @@ -313,11 +359,7 @@ static int mbigen_acpi_create_domain(str
    if (ret || num_pins == 0)
    return -EINVAL;

    - domain = platform_msi_create_device_domain(&pdev->dev, num_pins,
    - mbigen_write_msg,
    - &mbigen_domain_ops,
    - mgn_chip);
    - if (!domain)
    + if (!mbigen_create_device_domain(&pdev->dev, num_pins, mgn_chip))
    return -ENOMEM;

    return 0;
    \
     
     \ /
      Last update: 2022-11-21 15:51    [W:5.211 / U:0.156 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site