From: u.kleine-koenig@pengutronix.de (Uwe Kleine-König)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v5 07/15] ARM: mxs: Add gpio support
Date: Fri, 10 Dec 2010 11:24:16 +0100 [thread overview]
Message-ID: <20101210102416.GH17441@pengutronix.de> (raw)
In-Reply-To: <1291968402-19393-2-git-send-email-shawn.guo@freescale.com>
Hello Shawn,
On Fri, Dec 10, 2010 at 04:06:40PM +0800, Shawn Guo wrote:
> + /* set level or edge */
> + if (edge & GPIO_INT_LEV_MASK)
> + __raw_writel(1 << (gpio & 31),
> + port->base + PINCTRL_IRQLEV(port->id) + MXS_SET_ADDR);
> + else
> + __raw_writel(1 << (gpio & 31),
> + port->base + PINCTRL_IRQLEV(port->id) + MXS_CLR_ADDR);
Is this preferable?:
__raw_writel(1 << (gpio & 31), port->base + PINCTRL_IRQLEV(port->id) +
(edge & GPIO_INT_LEV_MASK ? MXS_SET_ADDR : MXS_CLR_ADDR))
. I'm not sure. And if you like my __raw_setl/__raw_clearl (or
__raw_clrl?) suggestion this won't work though. If you don't, I'd
prefer to be easily able to see that the two commands only differ by
MXS_SET_ADDR vs. MXS_CLR_ADDR.
e.g.
u32 nicename = 1 << (gpio & 31);
correcttype addr = port->base + PINCTRL_IRQLEV(port->id);
if (edge & GPIO_INT_LEV_MASK)
__raw_writel(nicename, addr + MXS_SET_ADDR);
else
__raw_writel(nicename, addr + MXS_CLR_ADDR);
> + /* set polarity */
> + if (edge & GPIO_INT_POL_MASK)
> + __raw_writel(1 << (gpio & 31),
> + port->base + PINCTRL_IRQPOL(port->id) + MXS_SET_ADDR);
> + else
> + __raw_writel(1 << (gpio & 31),
> + port->base + PINCTRL_IRQPOL(port->id) + MXS_CLR_ADDR);
ditto. You can even reuse nicename here.
> +
> + _clear_gpio_irqstatus(port, gpio & 0x1f);
> +
> + return 0;
> +}
> +
> +/* MXS has one interrupt *per* gpio port */
> +static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
> +{
> + u32 irq_stat;
> + struct mxs_gpio_port *port = (struct mxs_gpio_port *)get_irq_data(irq);
> + u32 gpio_irq_no_base = port->virtual_irq_start;
> +
> + irq_stat = __raw_readl(port->base + PINCTRL_IRQSTAT(port->id)) &
> + __raw_readl(port->base + PINCTRL_IRQEN(port->id)) &
> + __raw_readl(port->base + PINCTRL_PIN2IRQ(port->id));
I think now a bit set in PINCTRL_IRQEN implies the same bit set in
PINCTRL_PIN2IRQ, doesn't it? If so, & PINCTRL_PIN2IRQ doesn't add any
value.
> +static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,
> + int dir)
mxs_gpio_direction_set would better match the naming scheme of
mxs_gpio_direction_input and mxs_gpio_direction_output. (If you ask me,
don't use leading underscores in .c files, static is enough to signal
the function to be private.)
> +{
> + struct mxs_gpio_port *port =
> + container_of(chip, struct mxs_gpio_port, chip);
> +
> + if (dir)
> + __raw_writel(1 << offset,
> + port->base + PINCTRL_DOE(port->id) + MXS_SET_ADDR);
> + else
> + __raw_writel(1 << offset,
> + port->base + PINCTRL_DOE(port->id) + MXS_CLR_ADDR);
as above, at least give a name for port->base + PINCTRL_DOE(port->id).
> +int __init mxs_gpio_init(struct mxs_gpio_port *port, int cnt)
> +{
> + int i, j;
> +
> + /* save for local usage */
> + mxs_gpio_ports = port;
> + gpio_table_size = cnt;
> +
> + pr_info("MXS GPIO hardware\n");
> +
> + for (i = 0; i < cnt; i++) {
> + /* disable the interrupt and clear the status */
> + __raw_writel(0, port[i].base +
> + PINCTRL_PIN2IRQ(i));
> + __raw_writel(0, port[i].base +
> + PINCTRL_IRQEN(i));
> + __raw_writel(~0, port[i].base +
> + PINCTRL_IRQSTAT(i) + MXS_CLR_ADDR);
Why not __raw_writel(0, port[i].base + PINCTRL_IRQSTAT(i)) ?
(And note that applying ~ on a signed integer isn't portable in
general. For all sane archs this is the same as ~0U though and ARM is
sane (here), still I think it's good to be aware of such things and
avoid them if easily possible.)
> + /* its a serious configuration bug when it fails */
> + BUG_ON( gpiochip_add(&port[i].chip) < 0 );
> +
> + /* setup one handler for each entry */
> + set_irq_chained_handler(port[i].irq, mxs_gpio_irq_handler);
> + set_irq_data(port[i].irq, &port[i]);
I think it's saver to first setup the irq stuff and only then register
the gpiochip.
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
next prev parent reply other threads:[~2010-12-10 10:24 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-12-10 8:06 [PATCH v5 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
2010-12-10 8:06 ` [PATCH v5 07/15] ARM: mxs: Add gpio support Shawn Guo
2010-12-10 10:24 ` Uwe Kleine-König [this message]
2010-12-10 15:42 ` Shawn Guo
2010-12-13 7:28 ` Shawn Guo
2010-12-13 7:54 ` Lothar Waßmann
2010-12-13 7:57 ` Uwe Kleine-König
2010-12-13 8:10 ` Shawn Guo
2010-12-13 8:19 ` Shawn Guo
2010-12-13 8:24 ` Uwe Kleine-König
2010-12-10 8:06 ` [PATCH v5 08/15] ARM: mxs: Add iomux support Shawn Guo
2010-12-10 8:06 ` [PATCH v5 09/15] ARM: mxs: Add clock support 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=20101210102416.GH17441@pengutronix.de \
--to=u.kleine-koenig@pengutronix.de \
--cc=linux-arm-kernel@lists.infradead.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 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).