All of lore.kernel.org
 help / color / mirror / Atom feed
From: Julien Grall <julien.grall@citrix.com>
To: Ian Campbell <ian.campbell@citrix.com>, xen-devel@lists.xen.org
Cc: julien.grall@linaro.org, tim@xen.org, stefano.stabellini@eu.citrix.com
Subject: Re: [PATCH v4 1/6] xen: dt: add dt_for_each_irq_map helper
Date: Fri, 26 Jun 2015 19:47:44 +0200	[thread overview]
Message-ID: <558D9040.7070503@citrix.com> (raw)
In-Reply-To: <1431084420-14372-1-git-send-email-ian.campbell@citrix.com>

Hi Ian,

On 08/05/2015 13:26, Ian Campbell wrote:
> This function iterates over a nodes interrupt-map property and calls a
> callback for each interrupt. For now it only supplies the translated
> IRQ since my use case has no need of e.g. child unit address. These
> can be added as needed by any future users.
>
> This follows much the same logic as dt_irq_map_raw when parsing the
> interrupt-map, but doesn't walk up the tree doing the actual
> translation and it iterates over all entries instead of just looking
> for the first match.
>
> I looked into refactoring dt_irq_map_raw but I couldn't find a way
> which I was confident in, plus I was reluctant to diverge from the
> Linux roots of this function any further.
>
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>

Reviewed-by: Julien Grall <julien.grall@citrix.com>
> ---
> v4: Pass a dt_irq not a dt_irq_raw to the callback.
> ---
>   xen/common/device_tree.c      |  148 +++++++++++++++++++++++++++++++++++++++++
>   xen/include/xen/device_tree.h |   12 ++++
>   2 files changed, 160 insertions(+)
>
> diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c
> index 02cae91..a2aeecd 100644
> --- a/xen/common/device_tree.c
> +++ b/xen/common/device_tree.c
> @@ -811,6 +811,154 @@ unsigned int dt_number_of_address(const struct dt_device_node *dev)
>       return (psize / onesize);
>   }
>
> +int dt_for_each_irq_map(const struct dt_device_node *dev,
> +                        int (*cb)(const struct dt_device_node *,
> +                                  const struct dt_irq *,
> +                                  void *),
> +                        void *data)
> +{
> +    const struct dt_device_node *ipar, *tnode, *old = NULL;
> +    const __be32 *tmp, *imap;
> +    u32 intsize = 1, addrsize, pintsize = 0, paddrsize = 0;
> +    u32 imaplen;
> +    int i, ret;
> +
> +    struct dt_raw_irq dt_raw_irq;
> +    struct dt_irq dt_irq;
> +
> +    dt_dprintk("%s: par=%s cb=%p data=%p\n", __func__,
> +               dev->full_name, cb, data);
> +
> +    ipar = dev;
> +
> +    /* First get the #interrupt-cells property of the current cursor
> +     * that tells us how to interpret the passed-in intspec. If there
> +     * is none, we are nice and just walk up the tree
> +     */
> +    do {
> +        tmp = dt_get_property(ipar, "#interrupt-cells", NULL);
> +        if ( tmp != NULL )
> +        {
> +            intsize = be32_to_cpu(*tmp);
> +            break;
> +        }
> +        tnode = ipar;
> +        ipar = dt_irq_find_parent(ipar);
> +    } while ( ipar );

This loop doesn't seem useful. AFAIU the spec, the PCI node (i.e your 
variable dev) will always have property #interrupt-cells. We will break 
directly.

[..]

> +    if ( intsize > DT_MAX_IRQ_SPEC )
> +    {
> +        dt_dprintk(" -> too many irq specifier cells\n");
> +        goto fail;
> +    }

[..]

> +    /* Parse interrupt-map */
> +    while ( imaplen > (addrsize + intsize + 1) )
> +    {
> +        /* skip child unit address and child interrupt specifier */
> +        imap += addrsize + intsize;
> +        imaplen -= addrsize + intsize;
> +
> +        /* Get the interrupt parent */
> +        ipar = dt_find_node_by_phandle(be32_to_cpup(imap));

[..]

> +        /* Get #interrupt-cells and #address-cells of new
> +         * parent
> +         */
> +        tmp = dt_get_property(ipar, "#interrupt-cells", NULL);
> +        if ( tmp == NULL )
> +        {
> +            dt_dprintk(" -> parent lacks #interrupt-cells!\n");
> +            goto fail;
> +        }
> +        pintsize = be32_to_cpu(*tmp);

[..]

> +        dt_raw_irq.controller = ipar;
> +        dt_raw_irq.size = pintsize;

Don't you need to check that pintsize is < DT_MAX_IRQ_SPEC?
The previous "if ( ... > DT_MAX_IRQ_SPEC )" will likely be done on a 
different parent.

For instance with the following incomplete DT (based on the 
apm-storm.dsi in Linux):

pcie0 {
    #interrupt-cells = <1>;
    ...
    #interrupt-map = < 0x0 0x0 0x0 0x1 &gic ... >
}

The first ipar will point to pcie0 because it has a property 
"#interrupt-cells", while the second time ipar will point to the gic node.

> +        for ( i = 0; i < pintsize; i++ )
> +            dt_raw_irq.specifier[i] = dt_read_number(imap + i, 1);
> +
> +        ret = dt_irq_translate(&dt_raw_irq, &dt_irq);
> +        if ( ret < 0 )

The other caller of dt_irq_translate returns an error when ret is not 0. 
I would do the same here.

Regards,

-- 
Julien Grall

  reply	other threads:[~2015-06-26 17:47 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-08 11:26 [PATCH v3 0/6] xen: arm: Parse PCI DT nodes' ranges and interrupt-map Ian Campbell
2015-05-08 11:26 ` [PATCH v4 1/6] xen: dt: add dt_for_each_irq_map helper Ian Campbell
2015-06-26 17:47   ` Julien Grall [this message]
2015-07-03 14:16     ` Ian Campbell
2015-07-03 15:15       ` Julien Grall
2015-07-03 15:28         ` Ian Campbell
2015-05-08 11:26 ` [PATCH v4 2/6] xen: dt: add dt_for_each_range helper Ian Campbell
2015-05-08 11:26 ` [PATCH v4 3/6] xen: arm: slightly refactor gic DT node creation for domain 0 Ian Campbell
2015-05-08 16:21   ` Ian Campbell
2015-05-08 11:26 ` [PATCH v4 4/6] xen: arm: drop redundant extra call to vgic_reserve_virq Ian Campbell
2015-06-26 17:49   ` Julien Grall
2015-05-08 11:26 ` [PATCH v4 5/6] xen: arm: map child MMIO and IRQs to dom0 for PCI bus DT nodes Ian Campbell
2015-06-26 17:56   ` Julien Grall
2015-07-03 10:59     ` Ian Campbell
2015-07-03 11:26       ` Julien Grall
2015-05-08 11:27 ` [PATCH v4 6/6] xen: arm: Import of_bus PCI entry from Linux (as a dt_bus entry) Ian Campbell
2015-06-26 18:08   ` Julien Grall
2015-07-03 10:47     ` Ian Campbell
2015-07-03 10:56       ` Ian Campbell
2015-07-03 11:24         ` Julien Grall
2015-07-03 11:30           ` Ian Campbell
2015-05-08 11:41 ` [PATCH v3 0/6] xen: arm: Parse PCI DT nodes' ranges and interrupt-map Ian Campbell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=558D9040.7070503@citrix.com \
    --to=julien.grall@citrix.com \
    --cc=ian.campbell@citrix.com \
    --cc=julien.grall@linaro.org \
    --cc=stefano.stabellini@eu.citrix.com \
    --cc=tim@xen.org \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.