From: James Hogan <james.hogan@imgtec.com>
To: Grant Likely <grant.likely@linaro.org>
Cc: Linus Walleij <linus.walleij@linaro.org>,
linux-kernel@vger.kernel.org,
Rob Herring <rob.herring@calxeda.com>,
Rob Landley <rob@landley.net>,
linux-doc@vger.kernel.org, devicetree-discuss@lists.ozlabs.org
Subject: Re: [PATCH v3 2/4] gpio-tz1090: add TZ1090 gpio driver
Date: Mon, 24 Jun 2013 15:48:17 +0100 [thread overview]
Message-ID: <51C85C31.4070003@imgtec.com> (raw)
In-Reply-To: <20130624133453.8FC5D3E0A89@localhost>
On 24/06/13 14:34, Grant Likely wrote:
> On Thu, 20 Jun 2013 10:26:28 +0100, James Hogan <james.hogan@imgtec.com> wrote:
>> diff --git a/Documentation/devicetree/bindings/gpio/gpio-tz1090.txt b/Documentation/devicetree/bindings/gpio/gpio-tz1090.txt
>> new file mode 100644
>> index 0000000..e017d4b
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/gpio/gpio-tz1090.txt
>> @@ -0,0 +1,87 @@
>> +ImgTec TZ1090 GPIO Controller
>> +
>> +Required properties:
>> +- compatible: Compatible property value should be "img,tz1090-gpio>".
>
> typo at end of line
Yes, I'll fix in gpio-tz1090-pdc driver bindings too
>> + Bank subnode optional properties:
>> + - gpio-ranges: Mapping to pin controller pins
>
> This is specific to this binding. To avoid namespace colisions, add a
> "img," prefix to the property name.
This property is described in
Documentation/devicetree/bindings/gpio/gpio.txt... (and my examples are
out of date from when the gpio offset cell was added in v3.10). I'll add
a reference to that Document.
>> +/* GPIO chip callbacks */
>> +
>> +static int tz1090_gpio_direction_input(struct gpio_chip *chip,
>> + unsigned int offset)
>> +{
>> + struct tz1090_gpio_bank *bank = to_bank(chip);
>> + tz1090_gpio_set_bit(bank, REG_GPIO_DIR, offset);
>> +
>> + return 0;
>> +}
>> +
>> +static int tz1090_gpio_direction_output(struct gpio_chip *chip,
>> + unsigned int offset, int output_value)
>> +{
>> + struct tz1090_gpio_bank *bank = to_bank(chip);
>> + int lstat;
>> +
>> + __global_lock2(lstat);
>> + _tz1090_gpio_mod_bit(bank, REG_GPIO_DOUT, offset, output_value);
>> + _tz1090_gpio_clear_bit(bank, REG_GPIO_DIR, offset);
>> + __global_unlock2(lstat);
>> +
>> + return 0;
>> +}
>> +
>> +/*
>> + * Return GPIO level
>> + */
>> +static int tz1090_gpio_get(struct gpio_chip *chip, unsigned int offset)
>> +{
>> + struct tz1090_gpio_bank *bank = to_bank(chip);
>> +
>> + return tz1090_gpio_read_bit(bank, REG_GPIO_DIN, offset);
>> +}
>> +
>> +/*
>> + * Set output GPIO level
>> + */
>> +static void tz1090_gpio_set(struct gpio_chip *chip, unsigned int offset,
>> + int output_value)
>> +{
>> + struct tz1090_gpio_bank *bank = to_bank(chip);
>> +
>> + tz1090_gpio_mod_bit(bank, REG_GPIO_DOUT, offset, output_value);
>> +}
>> +
>> +static int tz1090_gpio_request(struct gpio_chip *chip, unsigned int offset)
>> +{
>> + struct tz1090_gpio_bank *bank = to_bank(chip);
>> + int ret;
>> +
>> + ret = pinctrl_request_gpio(chip->base + offset);
>> + if (ret)
>> + return ret;
>> +
>> + tz1090_gpio_set_bit(bank, REG_GPIO_DIR, offset);
>> + tz1090_gpio_set_bit(bank, REG_GPIO_BIT_EN, offset);
>> +
>> + return 0;
>> +}
>
> Is it possible to use the gpio-generic.c hooks for manipulating the
> gpio bits?
Due to the unfortunate necessity to use the __global_lock2 functions
(for atomic accesses between different non-linux threads/cores) I don't
think this is possible.
>> +/* IRQ chip handlers */
>> +
>> +/* Get TZ1090 GPIO chip from irq data provided to generic IRQ callbacks */
>> +static inline struct tz1090_gpio_bank *irqd_to_gpio_bank(struct irq_data *data)
>> +{
>> + return (struct tz1090_gpio_bank *)data->domain->host_data;
>> +}
>> +
>> +static void tz1090_gpio_irq_clear(struct tz1090_gpio_bank *bank,
>> + unsigned int offset)
>> +{
>> + tz1090_gpio_clear_bit(bank, REG_GPIO_IRQ_STS, offset);
>> +}
>> +
>> +static void tz1090_gpio_irq_enable(struct tz1090_gpio_bank *bank,
>> + unsigned int offset, bool enable)
>> +{
>> + tz1090_gpio_mod_bit(bank, REG_GPIO_IRQ_EN, offset, enable);
>> +}
>> +
>> +static void tz1090_gpio_irq_polarity(struct tz1090_gpio_bank *bank,
>> + unsigned int offset, unsigned int polarity)
>> +{
>> + tz1090_gpio_mod_bit(bank, REG_GPIO_IRQ_PLRT, offset, polarity);
>> +}
>> +
>> +static int tz1090_gpio_valid_handler(struct irq_desc *desc)
>> +{
>> + return desc->handle_irq == handle_level_irq ||
>> + desc->handle_irq == handle_edge_irq;
>> +}
>> +
>> +static void tz1090_gpio_irq_type(struct tz1090_gpio_bank *bank,
>> + unsigned int offset, unsigned int type)
>> +{
>> + tz1090_gpio_mod_bit(bank, REG_GPIO_IRQ_TYPE, offset, type);
>> +}
>> +
>> +/* set polarity to trigger on next edge, whether rising or falling */
>> +static void tz1090_gpio_irq_next_edge(struct tz1090_gpio_bank *bank,
>> + unsigned int offset)
>> +{
>> + unsigned int value_p, value_i;
>> + int lstat;
>> +
>> + /*
>> + * Set the GPIO's interrupt polarity to the opposite of the current
>> + * input value so that the next edge triggers an interrupt.
>> + */
>> + __global_lock2(lstat);
>> + value_i = ~tz1090_gpio_read(bank, REG_GPIO_DIN);
>> + value_p = tz1090_gpio_read(bank, REG_GPIO_IRQ_PLRT);
>> + value_p &= ~BIT(offset);
>> + value_p |= value_i & BIT(offset);
>> + tz1090_gpio_write(bank, REG_GPIO_IRQ_PLRT, value_p);
>> + __global_unlock2(lstat);
>> +}
>> +
>> +static void gpio_ack_irq(struct irq_data *data)
>> +{
>> + struct tz1090_gpio_bank *bank = irqd_to_gpio_bank(data);
>> +
>> + tz1090_gpio_irq_clear(bank, data->hwirq);
>> +}
>> +
>> +static void gpio_mask_irq(struct irq_data *data)
>> +{
>> + struct tz1090_gpio_bank *bank = irqd_to_gpio_bank(data);
>> +
>> + tz1090_gpio_irq_enable(bank, data->hwirq, false);
>> +}
>> +
>> +static void gpio_unmask_irq(struct irq_data *data)
>> +{
>> + struct tz1090_gpio_bank *bank = irqd_to_gpio_bank(data);
>> +
>> + tz1090_gpio_irq_enable(bank, data->hwirq, true);
>> +}
>
> Similarly, can this driver use the generic irq chip to eliminate the
> above hooks?
hmm, I could probably get away with it for irq callbacks since a bank's
IRQ cannot be shared with non-Linux threads/cores.
>
> [...]
>> +
>> +static void tz1090_gpio_register_banks(struct tz1090_gpio *priv)
>> +{
>> + struct device_node *np = priv->dev->of_node;
>> + struct device_node *node;
>> +
>> + for_each_available_child_of_node(np, node) {
>> + struct tz1090_gpio_bank_info info;
>> + const __be32 *addr;
>> + int len, ret;
>> +
>> + addr = of_get_property(node, "reg", &len);
>> + if (!addr || (len < sizeof(int))) {
>> + dev_err(priv->dev, "invalid reg on %s\n",
>> + node->full_name);
>> + continue;
>> + }
>
> Use of_property_read_u32(). It's safer and does the be32 conversion for you.
will do.
Thanks for the review.
Cheers
James
WARNING: multiple messages have this Message-ID (diff)
From: James Hogan <james.hogan@imgtec.com>
To: Grant Likely <grant.likely@linaro.org>
Cc: Linus Walleij <linus.walleij@linaro.org>,
<linux-kernel@vger.kernel.org>,
Rob Herring <rob.herring@calxeda.com>,
Rob Landley <rob@landley.net>, <linux-doc@vger.kernel.org>,
<devicetree-discuss@lists.ozlabs.org>
Subject: Re: [PATCH v3 2/4] gpio-tz1090: add TZ1090 gpio driver
Date: Mon, 24 Jun 2013 15:48:17 +0100 [thread overview]
Message-ID: <51C85C31.4070003@imgtec.com> (raw)
In-Reply-To: <20130624133453.8FC5D3E0A89@localhost>
On 24/06/13 14:34, Grant Likely wrote:
> On Thu, 20 Jun 2013 10:26:28 +0100, James Hogan <james.hogan@imgtec.com> wrote:
>> diff --git a/Documentation/devicetree/bindings/gpio/gpio-tz1090.txt b/Documentation/devicetree/bindings/gpio/gpio-tz1090.txt
>> new file mode 100644
>> index 0000000..e017d4b
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/gpio/gpio-tz1090.txt
>> @@ -0,0 +1,87 @@
>> +ImgTec TZ1090 GPIO Controller
>> +
>> +Required properties:
>> +- compatible: Compatible property value should be "img,tz1090-gpio>".
>
> typo at end of line
Yes, I'll fix in gpio-tz1090-pdc driver bindings too
>> + Bank subnode optional properties:
>> + - gpio-ranges: Mapping to pin controller pins
>
> This is specific to this binding. To avoid namespace colisions, add a
> "img," prefix to the property name.
This property is described in
Documentation/devicetree/bindings/gpio/gpio.txt... (and my examples are
out of date from when the gpio offset cell was added in v3.10). I'll add
a reference to that Document.
>> +/* GPIO chip callbacks */
>> +
>> +static int tz1090_gpio_direction_input(struct gpio_chip *chip,
>> + unsigned int offset)
>> +{
>> + struct tz1090_gpio_bank *bank = to_bank(chip);
>> + tz1090_gpio_set_bit(bank, REG_GPIO_DIR, offset);
>> +
>> + return 0;
>> +}
>> +
>> +static int tz1090_gpio_direction_output(struct gpio_chip *chip,
>> + unsigned int offset, int output_value)
>> +{
>> + struct tz1090_gpio_bank *bank = to_bank(chip);
>> + int lstat;
>> +
>> + __global_lock2(lstat);
>> + _tz1090_gpio_mod_bit(bank, REG_GPIO_DOUT, offset, output_value);
>> + _tz1090_gpio_clear_bit(bank, REG_GPIO_DIR, offset);
>> + __global_unlock2(lstat);
>> +
>> + return 0;
>> +}
>> +
>> +/*
>> + * Return GPIO level
>> + */
>> +static int tz1090_gpio_get(struct gpio_chip *chip, unsigned int offset)
>> +{
>> + struct tz1090_gpio_bank *bank = to_bank(chip);
>> +
>> + return tz1090_gpio_read_bit(bank, REG_GPIO_DIN, offset);
>> +}
>> +
>> +/*
>> + * Set output GPIO level
>> + */
>> +static void tz1090_gpio_set(struct gpio_chip *chip, unsigned int offset,
>> + int output_value)
>> +{
>> + struct tz1090_gpio_bank *bank = to_bank(chip);
>> +
>> + tz1090_gpio_mod_bit(bank, REG_GPIO_DOUT, offset, output_value);
>> +}
>> +
>> +static int tz1090_gpio_request(struct gpio_chip *chip, unsigned int offset)
>> +{
>> + struct tz1090_gpio_bank *bank = to_bank(chip);
>> + int ret;
>> +
>> + ret = pinctrl_request_gpio(chip->base + offset);
>> + if (ret)
>> + return ret;
>> +
>> + tz1090_gpio_set_bit(bank, REG_GPIO_DIR, offset);
>> + tz1090_gpio_set_bit(bank, REG_GPIO_BIT_EN, offset);
>> +
>> + return 0;
>> +}
>
> Is it possible to use the gpio-generic.c hooks for manipulating the
> gpio bits?
Due to the unfortunate necessity to use the __global_lock2 functions
(for atomic accesses between different non-linux threads/cores) I don't
think this is possible.
>> +/* IRQ chip handlers */
>> +
>> +/* Get TZ1090 GPIO chip from irq data provided to generic IRQ callbacks */
>> +static inline struct tz1090_gpio_bank *irqd_to_gpio_bank(struct irq_data *data)
>> +{
>> + return (struct tz1090_gpio_bank *)data->domain->host_data;
>> +}
>> +
>> +static void tz1090_gpio_irq_clear(struct tz1090_gpio_bank *bank,
>> + unsigned int offset)
>> +{
>> + tz1090_gpio_clear_bit(bank, REG_GPIO_IRQ_STS, offset);
>> +}
>> +
>> +static void tz1090_gpio_irq_enable(struct tz1090_gpio_bank *bank,
>> + unsigned int offset, bool enable)
>> +{
>> + tz1090_gpio_mod_bit(bank, REG_GPIO_IRQ_EN, offset, enable);
>> +}
>> +
>> +static void tz1090_gpio_irq_polarity(struct tz1090_gpio_bank *bank,
>> + unsigned int offset, unsigned int polarity)
>> +{
>> + tz1090_gpio_mod_bit(bank, REG_GPIO_IRQ_PLRT, offset, polarity);
>> +}
>> +
>> +static int tz1090_gpio_valid_handler(struct irq_desc *desc)
>> +{
>> + return desc->handle_irq == handle_level_irq ||
>> + desc->handle_irq == handle_edge_irq;
>> +}
>> +
>> +static void tz1090_gpio_irq_type(struct tz1090_gpio_bank *bank,
>> + unsigned int offset, unsigned int type)
>> +{
>> + tz1090_gpio_mod_bit(bank, REG_GPIO_IRQ_TYPE, offset, type);
>> +}
>> +
>> +/* set polarity to trigger on next edge, whether rising or falling */
>> +static void tz1090_gpio_irq_next_edge(struct tz1090_gpio_bank *bank,
>> + unsigned int offset)
>> +{
>> + unsigned int value_p, value_i;
>> + int lstat;
>> +
>> + /*
>> + * Set the GPIO's interrupt polarity to the opposite of the current
>> + * input value so that the next edge triggers an interrupt.
>> + */
>> + __global_lock2(lstat);
>> + value_i = ~tz1090_gpio_read(bank, REG_GPIO_DIN);
>> + value_p = tz1090_gpio_read(bank, REG_GPIO_IRQ_PLRT);
>> + value_p &= ~BIT(offset);
>> + value_p |= value_i & BIT(offset);
>> + tz1090_gpio_write(bank, REG_GPIO_IRQ_PLRT, value_p);
>> + __global_unlock2(lstat);
>> +}
>> +
>> +static void gpio_ack_irq(struct irq_data *data)
>> +{
>> + struct tz1090_gpio_bank *bank = irqd_to_gpio_bank(data);
>> +
>> + tz1090_gpio_irq_clear(bank, data->hwirq);
>> +}
>> +
>> +static void gpio_mask_irq(struct irq_data *data)
>> +{
>> + struct tz1090_gpio_bank *bank = irqd_to_gpio_bank(data);
>> +
>> + tz1090_gpio_irq_enable(bank, data->hwirq, false);
>> +}
>> +
>> +static void gpio_unmask_irq(struct irq_data *data)
>> +{
>> + struct tz1090_gpio_bank *bank = irqd_to_gpio_bank(data);
>> +
>> + tz1090_gpio_irq_enable(bank, data->hwirq, true);
>> +}
>
> Similarly, can this driver use the generic irq chip to eliminate the
> above hooks?
hmm, I could probably get away with it for irq callbacks since a bank's
IRQ cannot be shared with non-Linux threads/cores.
>
> [...]
>> +
>> +static void tz1090_gpio_register_banks(struct tz1090_gpio *priv)
>> +{
>> + struct device_node *np = priv->dev->of_node;
>> + struct device_node *node;
>> +
>> + for_each_available_child_of_node(np, node) {
>> + struct tz1090_gpio_bank_info info;
>> + const __be32 *addr;
>> + int len, ret;
>> +
>> + addr = of_get_property(node, "reg", &len);
>> + if (!addr || (len < sizeof(int))) {
>> + dev_err(priv->dev, "invalid reg on %s\n",
>> + node->full_name);
>> + continue;
>> + }
>
> Use of_property_read_u32(). It's safer and does the be32 conversion for you.
will do.
Thanks for the review.
Cheers
James
next prev parent reply other threads:[~2013-06-24 14:48 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-06-20 9:26 [PATCH v3 0/4] Add TZ1090 pinctrl/gpio drivers James Hogan
2013-06-20 9:26 ` James Hogan
[not found] ` <1371720391-21825-1-git-send-email-james.hogan-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>
2013-06-20 9:26 ` [PATCH v3 1/4] pinctrl-tz1090: add TZ1090 pinctrl driver James Hogan
2013-06-20 9:26 ` James Hogan
2013-06-24 15:04 ` Linus Walleij
2013-06-24 15:38 ` James Hogan
2013-06-20 9:26 ` [PATCH v3 2/4] gpio-tz1090: add TZ1090 gpio driver James Hogan
2013-06-20 9:26 ` James Hogan
2013-06-24 13:34 ` Grant Likely
2013-06-24 13:34 ` Grant Likely
2013-06-24 14:48 ` James Hogan [this message]
2013-06-24 14:48 ` James Hogan
2013-06-24 15:36 ` James Hogan
2013-06-24 15:36 ` James Hogan
2013-06-20 9:26 ` [PATCH v3 3/4] pinctrl-tz1090-pdc: add TZ1090 PDC pinctrl driver James Hogan
2013-06-20 9:26 ` James Hogan
2013-06-24 15:08 ` Linus Walleij
2013-06-20 9:26 ` [PATCH v3 4/4] gpio-tz1090-pdc: add TZ1090 PDC gpio driver James Hogan
2013-06-20 9:26 ` James Hogan
2013-06-24 15:11 ` Linus Walleij
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=51C85C31.4070003@imgtec.com \
--to=james.hogan@imgtec.com \
--cc=devicetree-discuss@lists.ozlabs.org \
--cc=grant.likely@linaro.org \
--cc=linus.walleij@linaro.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=rob.herring@calxeda.com \
--cc=rob@landley.net \
/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.