From: "Heiko Stübner" <heiko@sntech.de>
To: Tomasz Figa <tomasz.figa@gmail.com>
Cc: linus.walleij@linaro.org, linux-arm-kernel@lists.infradead.org,
linux-samsung-soc@vger.kernel.org, kgene.kim@samsung.com,
thomas.abraham@linaro.org
Subject: Re: [PATCH] pinctrl: Add pinctrl-s3c24xx driver
Date: Wed, 10 Apr 2013 15:45:48 +0200 [thread overview]
Message-ID: <201304101545.49264.heiko@sntech.de> (raw)
In-Reply-To: <136562781.D2dqZAGJoQ@flatron>
Am Mittwoch, 10. April 2013, 14:31:29 schrieb Tomasz Figa:
> On Wednesday 10 of April 2013 14:20:22 Heiko Stübner wrote:
> > Hi Tomasz,
> >
> > thanks for your comments, more inline.
> >
> > Am Mittwoch, 10. April 2013, 12:36:39 schrieb Tomasz Figa:
> > > Hi Heiko,
> > >
> > > Basically looks good to me, but please see my inline comments about
> > > handling of EINT0-3.
> > >
> > > On Wednesday 10 of April 2013 01:35:12 Heiko Stübner wrote:
> > > > The s3c24xx pins follow a similar pattern as the other Samsung SoCs
> > > > and
> > > > can therefore reuse the already introduced infrastructure.
> >
> > [...]
> >
> > > > +struct s3c24xx_eint_data {
> > > > + struct samsung_pinctrl_drv_data *drvdata;
> > > > + struct irq_domain *domains[NUM_EINT];
> > > > + int parents[NUM_EINT_IRQ];
> > > > +};
> > > > +
> > > > +struct s3c24xx_eint_domain_data {
> > > > + struct samsung_pin_bank *bank;
> > > > + struct s3c24xx_eint_data *eint_data;
> > >
> > > What about:
> > >
> > > + bool eint0_3_parent_only;
> > >
> > > (or whatever name would be more appropriate), which would store the
> > > information about the s3c24xx-specific quirk in 24xx-specific data
> > > structure, without the need to add another field to the generic
> > > samsung_pinctrl_drv_data structure?
> > >
> > > See my further comments on how I would see using this field in
> > > interrupt handling code.
> >
> > ok, sounds good, especially gathering the type from the wakeup-int
> > property
> >
> > > > +};
> >
> > [...]
> >
> > > Now I would split the following 3 functions into two sets of 3
> > > functions, one set for s3c2412 and other for remaining SoCs and make
> > > separate EINT0-3 IRQ chips for both cases.
> >
> > Not doing the decision every time, might bring some very slight speed
> > improvements, so is probably the right way to go.
> >
> > > > +
> > > > +static void s3c24xx_eint0_3_ack(struct irq_data *data)
> > > > +{
> > > > + struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
> > > > + struct samsung_pinctrl_drv_data *d = bank->drvdata;
> > > > + struct s3c24xx_eint_domain_data *ddata = bank->irq_domain-
> > > >
> > > >host_data;
> > > >
> > > > + struct s3c24xx_eint_data *eint_data = ddata->eint_data;
> > > > + int parent_irq = eint_data->parents[data->hwirq];
> > > > + struct irq_chip *parent_chip = irq_get_chip(parent_irq);
> > > > +
> > > > + if (d->ctrl->type == S3C2412) {
> > > > + unsigned long bitval = 1UL << data->hwirq;
> > > > + writel(bitval, d->virt_base + EINTPEND_REG);
> > > > + }
> > > > +
> > > > + if (parent_chip->irq_ack)
> > > > + parent_chip->irq_ack(irq_get_irq_data(parent_irq));
> > >
> > > Btw. Is this parent level acking really needed here?
> >
> > Depends. If using chained_irq_* of course not, but if the irq-handler
> > should stay in charge of when to ack it might be better this way.
> >
> > Generic s3c24xx SoCs need acking in the main controller only, while
> > s3c2412 needs acking in both the main controller and eintpend.
> >
> > > > +}
> >
> > [...]
> >
> > > > +static void s3c24xx_demux_eint0_3(unsigned int irq, struct irq_desc
> > > > *desc) +{
> > > > + struct irq_data *data = irq_desc_get_irq_data(desc);
> > > > + struct s3c24xx_eint_data *eint_data = irq_get_handler_data(irq);
> > > > + unsigned int virq;
> > > > +
> > >
> > > Instead of acking the interrupt at parent chip from ack callback of
> > > EINT0_3 chip, I would rather use chained_irq_enter() here...
> > >
> > > > + /* the first 4 eints have a simple 1 to 1 mapping */
> > > > + virq = irq_linear_revmap(eint_data->domains[data->hwirq],
> > > > data->hwirq); + /* Something must be really wrong if an unmapped
> > >
> > > EINT
> > >
> > > > + * was unmasked...
> > > > + */
> > > > + BUG_ON(!virq);
> > > > +
> > > > + generic_handle_irq(virq);
> > >
> > > ...and chained_irq_exit() here.
> >
> > If I understand it correctly, the way chained_irq_* works it would limit
> > the eints to a level style handling. With the way it's currently the
> > whole determination of when to ack,mask and unmask is completely for
> > the real handler (edge or level) to decide, as the original interrupt
> > gets completely forwarded into the irq-domain without further
> > constraints.
> >
> > So, after the change on regular s3c24xx SoCs when the real irq handler
> > wants to ack the irq, it would be a no-op, as it would already have
> > been acked by chained_irq_enter.
> >
> > Masking might be even more interesting. Currently control is transfered
> > completely to the pinctrl irq-domain, which then controls the masking of
> > the interrupt thru the parent-calls - on regular s3c24xx the masking of
> > these is also only done in the main controller.
> >
> > When using chained_irq_* it also wants to mask the interrupt which might
> > conflict with regular enable_irq/disable_irq calls being done for
> > example in driver code.
> >
> >
> > So in short I agree with the earlier split of the irqchip, but would
> > keep the irq operations themself centralized in the pinctrl driver,
> > instead of using chained_irq_* functions.
>
> Right, my solution wouldn't work properly in case of regular s3c24xx and
> edge triggered interrupts.
>
> However I'm still wondering if it's OK to manually call parent chip
> operations in case of s3c2416. This would imply the same operation calling
> order as imposed by flow handler of the chained EINT (which can be
> handle_edge_irq), while the parent chip is probably level triggered, isn't
> it?
I think imposing the same calling order is the right way to go :-) .
The eints can be set hardware-wise to either level or edge triggered, but
their flow handler is currently hard set to handle_edge_irq. I remember seeing
a patch from the Openmoko guys somewhere indicating that this does not work at
all with level irqs.
Only the main interrupts of the real demuxed eints (3_to_7 and 8_to...) are
always level triggered, and therefore already use chained_irq...
In the current pinctrl driver, the parent eints do not have a flow handler of
their own (as the chained handler replaces it). So all flow handling is done
by the flowhandler of the irq in the pinctrl domain.
handle_IRQ(main_eint)
-> demux_eint0_3
-> generic_handle_irq(pinctrl_eint)
-> handle_edge_irq (or handle_level_irq)
-> call ack, mask or unmask of the pinctrl eint
-> call ack, mask or unmask of the underlying main eint
Heiko
WARNING: multiple messages have this Message-ID (diff)
From: heiko@sntech.de (Heiko Stübner)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] pinctrl: Add pinctrl-s3c24xx driver
Date: Wed, 10 Apr 2013 15:45:48 +0200 [thread overview]
Message-ID: <201304101545.49264.heiko@sntech.de> (raw)
In-Reply-To: <136562781.D2dqZAGJoQ@flatron>
Am Mittwoch, 10. April 2013, 14:31:29 schrieb Tomasz Figa:
> On Wednesday 10 of April 2013 14:20:22 Heiko St?bner wrote:
> > Hi Tomasz,
> >
> > thanks for your comments, more inline.
> >
> > Am Mittwoch, 10. April 2013, 12:36:39 schrieb Tomasz Figa:
> > > Hi Heiko,
> > >
> > > Basically looks good to me, but please see my inline comments about
> > > handling of EINT0-3.
> > >
> > > On Wednesday 10 of April 2013 01:35:12 Heiko St?bner wrote:
> > > > The s3c24xx pins follow a similar pattern as the other Samsung SoCs
> > > > and
> > > > can therefore reuse the already introduced infrastructure.
> >
> > [...]
> >
> > > > +struct s3c24xx_eint_data {
> > > > + struct samsung_pinctrl_drv_data *drvdata;
> > > > + struct irq_domain *domains[NUM_EINT];
> > > > + int parents[NUM_EINT_IRQ];
> > > > +};
> > > > +
> > > > +struct s3c24xx_eint_domain_data {
> > > > + struct samsung_pin_bank *bank;
> > > > + struct s3c24xx_eint_data *eint_data;
> > >
> > > What about:
> > >
> > > + bool eint0_3_parent_only;
> > >
> > > (or whatever name would be more appropriate), which would store the
> > > information about the s3c24xx-specific quirk in 24xx-specific data
> > > structure, without the need to add another field to the generic
> > > samsung_pinctrl_drv_data structure?
> > >
> > > See my further comments on how I would see using this field in
> > > interrupt handling code.
> >
> > ok, sounds good, especially gathering the type from the wakeup-int
> > property
> >
> > > > +};
> >
> > [...]
> >
> > > Now I would split the following 3 functions into two sets of 3
> > > functions, one set for s3c2412 and other for remaining SoCs and make
> > > separate EINT0-3 IRQ chips for both cases.
> >
> > Not doing the decision every time, might bring some very slight speed
> > improvements, so is probably the right way to go.
> >
> > > > +
> > > > +static void s3c24xx_eint0_3_ack(struct irq_data *data)
> > > > +{
> > > > + struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
> > > > + struct samsung_pinctrl_drv_data *d = bank->drvdata;
> > > > + struct s3c24xx_eint_domain_data *ddata = bank->irq_domain-
> > > >
> > > >host_data;
> > > >
> > > > + struct s3c24xx_eint_data *eint_data = ddata->eint_data;
> > > > + int parent_irq = eint_data->parents[data->hwirq];
> > > > + struct irq_chip *parent_chip = irq_get_chip(parent_irq);
> > > > +
> > > > + if (d->ctrl->type == S3C2412) {
> > > > + unsigned long bitval = 1UL << data->hwirq;
> > > > + writel(bitval, d->virt_base + EINTPEND_REG);
> > > > + }
> > > > +
> > > > + if (parent_chip->irq_ack)
> > > > + parent_chip->irq_ack(irq_get_irq_data(parent_irq));
> > >
> > > Btw. Is this parent level acking really needed here?
> >
> > Depends. If using chained_irq_* of course not, but if the irq-handler
> > should stay in charge of when to ack it might be better this way.
> >
> > Generic s3c24xx SoCs need acking in the main controller only, while
> > s3c2412 needs acking in both the main controller and eintpend.
> >
> > > > +}
> >
> > [...]
> >
> > > > +static void s3c24xx_demux_eint0_3(unsigned int irq, struct irq_desc
> > > > *desc) +{
> > > > + struct irq_data *data = irq_desc_get_irq_data(desc);
> > > > + struct s3c24xx_eint_data *eint_data = irq_get_handler_data(irq);
> > > > + unsigned int virq;
> > > > +
> > >
> > > Instead of acking the interrupt at parent chip from ack callback of
> > > EINT0_3 chip, I would rather use chained_irq_enter() here...
> > >
> > > > + /* the first 4 eints have a simple 1 to 1 mapping */
> > > > + virq = irq_linear_revmap(eint_data->domains[data->hwirq],
> > > > data->hwirq); + /* Something must be really wrong if an unmapped
> > >
> > > EINT
> > >
> > > > + * was unmasked...
> > > > + */
> > > > + BUG_ON(!virq);
> > > > +
> > > > + generic_handle_irq(virq);
> > >
> > > ...and chained_irq_exit() here.
> >
> > If I understand it correctly, the way chained_irq_* works it would limit
> > the eints to a level style handling. With the way it's currently the
> > whole determination of when to ack,mask and unmask is completely for
> > the real handler (edge or level) to decide, as the original interrupt
> > gets completely forwarded into the irq-domain without further
> > constraints.
> >
> > So, after the change on regular s3c24xx SoCs when the real irq handler
> > wants to ack the irq, it would be a no-op, as it would already have
> > been acked by chained_irq_enter.
> >
> > Masking might be even more interesting. Currently control is transfered
> > completely to the pinctrl irq-domain, which then controls the masking of
> > the interrupt thru the parent-calls - on regular s3c24xx the masking of
> > these is also only done in the main controller.
> >
> > When using chained_irq_* it also wants to mask the interrupt which might
> > conflict with regular enable_irq/disable_irq calls being done for
> > example in driver code.
> >
> >
> > So in short I agree with the earlier split of the irqchip, but would
> > keep the irq operations themself centralized in the pinctrl driver,
> > instead of using chained_irq_* functions.
>
> Right, my solution wouldn't work properly in case of regular s3c24xx and
> edge triggered interrupts.
>
> However I'm still wondering if it's OK to manually call parent chip
> operations in case of s3c2416. This would imply the same operation calling
> order as imposed by flow handler of the chained EINT (which can be
> handle_edge_irq), while the parent chip is probably level triggered, isn't
> it?
I think imposing the same calling order is the right way to go :-) .
The eints can be set hardware-wise to either level or edge triggered, but
their flow handler is currently hard set to handle_edge_irq. I remember seeing
a patch from the Openmoko guys somewhere indicating that this does not work at
all with level irqs.
Only the main interrupts of the real demuxed eints (3_to_7 and 8_to...) are
always level triggered, and therefore already use chained_irq...
In the current pinctrl driver, the parent eints do not have a flow handler of
their own (as the chained handler replaces it). So all flow handling is done
by the flowhandler of the irq in the pinctrl domain.
handle_IRQ(main_eint)
-> demux_eint0_3
-> generic_handle_irq(pinctrl_eint)
-> handle_edge_irq (or handle_level_irq)
-> call ack, mask or unmask of the pinctrl eint
-> call ack, mask or unmask of the underlying main eint
Heiko
next prev parent reply other threads:[~2013-04-10 13:45 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-04-09 23:35 [PATCH] pinctrl: Add pinctrl-s3c24xx driver Heiko Stübner
2013-04-09 23:35 ` Heiko Stübner
2013-04-10 10:10 ` Kukjin Kim
2013-04-10 10:10 ` Kukjin Kim
2013-04-10 10:36 ` Tomasz Figa
2013-04-10 10:36 ` Tomasz Figa
2013-04-10 12:20 ` Heiko Stübner
2013-04-10 12:20 ` Heiko Stübner
2013-04-10 12:31 ` Tomasz Figa
2013-04-10 12:31 ` Tomasz Figa
2013-04-10 13:45 ` Heiko Stübner [this message]
2013-04-10 13:45 ` Heiko Stübner
2013-04-10 19:51 ` Tomasz Figa
2013-04-10 19:51 ` Tomasz Figa
2013-04-10 20:11 ` Heiko Stübner
2013-04-10 20:11 ` Heiko Stübner
2013-04-10 20:17 ` Tomasz Figa
2013-04-10 20:17 ` Tomasz Figa
2013-04-10 20:42 ` Heiko Stübner
2013-04-10 20:42 ` Heiko Stübner
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=201304101545.49264.heiko@sntech.de \
--to=heiko@sntech.de \
--cc=kgene.kim@samsung.com \
--cc=linus.walleij@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-samsung-soc@vger.kernel.org \
--cc=thomas.abraham@linaro.org \
--cc=tomasz.figa@gmail.com \
/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.