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: 24+ 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]
[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-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
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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).