From: Shawn Guo <shawn.guo@linaro.org>
To: Marc Zyngier <maz@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>,
Maulik Shah <quic_mkshah@quicinc.com>,
Bjorn Andersson <bjorn.andersson@linaro.org>,
Rob Herring <robh+dt@kernel.org>,
Loic Poulain <loic.poulain@linaro.org>,
devicetree@vger.kernel.org, linux-arm-msm@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2 2/2] irqchip: Add Qualcomm MPM controller driver
Date: Tue, 30 Nov 2021 10:31:52 +0800 [thread overview]
Message-ID: <20211130023151.GD10105@dragon> (raw)
In-Reply-To: <87pmqjm1c8.wl-maz@kernel.org>
+ Maulik
On Mon, Nov 29, 2021 at 03:24:39PM +0000, Marc Zyngier wrote:
[...]
> > > > @@ -430,6 +430,14 @@ config QCOM_PDC
> > > > Power Domain Controller driver to manage and configure wakeup
> > > > IRQs for Qualcomm Technologies Inc (QTI) mobile chips.
> > > >
> > > > +config QCOM_MPM
> > > > + bool "QCOM MPM"
> > >
> > > Can't be built as a module?
> >
> > The driver is implemented as a builtin_platform_driver().
>
> This, on its own, shouldn't preclude the driver from being built as a
> module. However, the config option only allows it to be built in. Why?
I just tried to build it as a module, and it seems that "irq_to_desc" is
only available for built-in build.
>
> [...]
>
> > > > +static inline void
> > > > +qcom_mpm_write(struct qcom_mpm_priv *priv, unsigned int reg,
> > > > + unsigned int index, u32 val)
> > > > +{
> > > > + unsigned int offset = (reg * priv->reg_stride + index + 2) * 4;
> > > > + u32 r_val;
> > > > +
> > > > + writel(val, priv->base + offset);
> > > > +
> > > > + do {
> > > > + r_val = readl(priv->base + offset);
> > > > + udelay(5);
> > > > + } while (r_val != val);
> > >
> > > What? Is this waiting for a bit to clear? Why isn't this one of the
> > > read*_poll_timeout*() function instead? Surely you can't wait forever
> > > here.
> >
> > This is taken from downstream, and it seems to double check the written
> > value by reading it back. But to be honest, I'm not really this is
> > necessary. I will do some testing with the read-back check dropped.
>
> How about asking for specs instead? There are QC people on Cc, and
> many more reading the list. Hopefully they can explain what this is
> all about.
Maulik,
If you have some information about this, that would be great.
>
> > >
> > > > +}
> > > > +
> > > > +static inline void qcom_mpm_enable_irq(struct irq_data *d, bool en)
> > > > +{
> > > > + struct qcom_mpm_priv *priv = d->domain->host_data;
> > >
> > > This really should be stored in d->chip_data.
> >
> > OK.
> >
> > >
> > > > + int pin = d->hwirq;
> > > > + unsigned int index = pin / 32;
> > > > + unsigned int shift = pin % 32;
> > > > + unsigned long flags;
> > > > + u32 val;
> > > > +
> > > > + priv->pin_to_irq[pin] = d->irq;
> > >
> > > This makes no sense. This is only reinventing the very notion of an
> > > irq domain, which is to lookup the Linux interrupt based on a context
> > > and a signal number.
> >
> > The uniqueness of this driver is that it has two irq domains. This
> > little lookup table is created to avoid resolving mapping on each of
> > these domains, which is less efficient. But you think this is really
> > nonsense, I can change.
>
> "efficient"? You are taking an interrupt to... err... reinject some
> other interrupts. I'm sorry, but the efficiency argument sailed once
> someone built this wonderful piece of HW. The first mistake was to
> involve SW here, so let's not optimise for something that really
> doesn't need it.
OK.
>
> Furthermore, why would you look up anywhere other than the wake-up
> domain? My impression was that only these interrupts would require
> being re-triggered.
Both domains have MPM pins that could wake up system.
>
> [...]
>
> > > > +static inline void
> > > > +mpm_set_type(struct qcom_mpm_priv *priv, bool set, unsigned int reg,
> > > > + unsigned int index, unsigned int shift)
> > > > +{
> > > > + u32 val;
> > > > +
> > > > + val = qcom_mpm_read(priv, reg, index);
> > > > + if (set)
> > > > + val |= 1 << shift;
> > > > + else
> > > > + val &= ~(1 << shift);
> > > > + qcom_mpm_write(priv, reg, index, val);
> > > > +}
> > > > +
> > > > +static int qcom_mpm_set_type(struct irq_data *d, unsigned int type)
> > > > +{
> > > > + struct qcom_mpm_priv *priv = d->domain->host_data;
> > > > + int pin = d->hwirq;
> > > > + unsigned int index = pin / 32;
> > > > + unsigned int shift = pin % 32;
> > > > + unsigned long flags;
> > > > +
> > > > + spin_lock_irqsave(&priv->lock, flags);
> > > > +
> > > > + mpm_set_type(priv, (type & IRQ_TYPE_EDGE_RISING) ? 1 : 0,
> > >
> > > You have a bool type as the second parameter. Why the convoluted ?:
> > > operator?
> >
> > Will change to !!(type & IRQ_TYPE_EDGE_RISING).
> >
> > >
> > > > + MPM_REG_RISING_EDGE, index, shift);
> > > > + mpm_set_type(priv, (type & IRQ_TYPE_EDGE_FALLING) ? 1 : 0,
> > > > + MPM_REG_FALLING_EDGE, index, shift);
> > > > + mpm_set_type(priv, (type & IRQ_TYPE_LEVEL_HIGH) ? 1 : 0,
> > > > + MPM_REG_POLARITY, index, shift);
> > >
> > > Why does this mean for an edge interrupt?
> >
> > Edge polarity is configured above on MPM_REG_RISING_EDGE and
> > MPM_REG_FALLING_EDGE. So I guess MPM_REG_POLARITY doesn't have an
> > impact on edge interrupt. I do not have any document or information
> > other than downstream code to be sure though.
>
> A well formed 'type' will have that bit clear when any of the EDGE
> flags is set. So this will always be 0. It would also be much better
> if you expressed the whole thing as a switch/case.
OK.
>
> [...]
>
> > > > +static int qcom_mpm_probe(struct platform_device *pdev)
> > > > +{
> > > > + struct irq_domain *parent_domain, *mpm_gic_domain, *mpm_gpio_domain;
> > > > + struct device *dev = &pdev->dev;
> > > > + struct device_node *np = dev->of_node;
> > > > + struct device_node *parent = of_irq_find_parent(np);
> > > > + struct qcom_mpm_priv *priv;
> > > > + unsigned int pin_num;
> > > > + int irq;
> > > > + int ret;
> > > > +
> > > > + /* See comments in platform_irqchip_probe() */
> > > > + if (parent && !irq_find_matching_host(parent, DOMAIN_BUS_ANY))
> > > > + return -EPROBE_DEFER;
> > >
> > > So why aren't you using that infrastructure?
> >
> > Because I need to populate .pm of platform_driver and use match data to
> > pass mpm_data.
>
> Then I'd rather you improve the existing infrastructure to pass the
> bit of extra data you need, instead than reinventing your own.
OK. I will see what I can do here.
>
> [...]
>
> > > > + priv->mbox_client.dev = dev;
> > > > + priv->mbox_chan = mbox_request_channel(&priv->mbox_client, 0);
> > > > + if (IS_ERR(priv->mbox_chan)) {
> > > > + ret = PTR_ERR(priv->mbox_chan);
> > > > + dev_err(dev, "failed to acquire IPC channel: %d\n", ret);
> > > > + goto remove_gpio_domain;
> > >
> > > Why don't you request this first, before all the allocations?
> >
> > Then I will need to call mbox_free_channel() for any allocation failures
> > afterward.
>
> Which would be fine. Checking for dependencies before allocating
> resources is good practice, specially when this can result in a probe
> deferral.
Good point, thanks!
Shawn
next prev parent reply other threads:[~2021-11-30 2:32 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-11-26 9:35 [PATCH v2 0/2] Add Qualcomm MPM irqchip driver support Shawn Guo
2021-11-26 9:35 ` [PATCH v2 1/2] dt-bindings: interrupt-controller: Add Qualcomm MPM support Shawn Guo
2021-12-01 23:02 ` Rob Herring
2021-11-26 9:35 ` [PATCH v2 2/2] irqchip: Add Qualcomm MPM controller driver Shawn Guo
2021-11-26 15:13 ` Marc Zyngier
2021-11-26 19:19 ` Marc Zyngier
2021-11-29 13:33 ` Shawn Guo
2021-11-29 15:24 ` Marc Zyngier
2021-11-30 2:31 ` Shawn Guo [this message]
2021-11-30 8:42 ` Marc Zyngier
2021-11-30 9:17 ` Shawn Guo
2021-11-30 10:44 ` Marc Zyngier
2021-12-01 7:36 ` Shawn Guo
[not found] ` <2e821841-a921-3fda-9ee6-3d5127653033@quicinc.com>
2021-11-30 8:31 ` Shawn Guo
2021-11-30 8:52 ` Marc Zyngier
2021-11-30 8:54 ` Maulik Shah
2021-11-30 8:47 ` Marc Zyngier
2021-11-27 7:49 ` kernel test robot
2021-11-27 7:49 ` kernel test robot
2021-11-29 7:23 ` Maulik Shah
2021-11-29 13:45 ` Shawn Guo
2021-11-30 8:26 ` Maulik Shah
2021-11-30 8:44 ` Shawn Guo
2021-11-30 9:04 ` Maulik Shah
2021-11-30 9:26 ` Shawn Guo
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=20211130023151.GD10105@dragon \
--to=shawn.guo@linaro.org \
--cc=bjorn.andersson@linaro.org \
--cc=devicetree@vger.kernel.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=loic.poulain@linaro.org \
--cc=maz@kernel.org \
--cc=quic_mkshah@quicinc.com \
--cc=robh+dt@kernel.org \
--cc=tglx@linutronix.de \
/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.