From: Anton Vorontsov <avorontsov@ru.mvista.com>
To: Kumar Gala <galak@kernel.crashing.org>
Cc: linuxppc-dev@ozlabs.org
Subject: [PATCH 4/5] [POWERPC] QE: implement support for the GPIO LIB API
Date: Thu, 17 Apr 2008 23:29:04 +0400 [thread overview]
Message-ID: <20080417192904.GD28286@polina.dev.rtsoft.ru> (raw)
In-Reply-To: <20080417192656.GA19107@polina.dev.rtsoft.ru>
This is needed to access QE GPIOs via Linux GPIO API.
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
Documentation/powerpc/booting-without-of.txt | 34 ++++---
arch/powerpc/platforms/Kconfig | 2 +
arch/powerpc/sysdev/qe_lib/qe_io.c | 137 +++++++++++++++++++++++++-
3 files changed, 159 insertions(+), 14 deletions(-)
diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
index 827b630..5c9cfab 100644
--- a/Documentation/powerpc/booting-without-of.txt
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -1721,24 +1721,32 @@ platforms are moved over to use the flattened-device-tree model.
information.
Required properties:
- - device_type : should be "par_io".
+ - #gpio-cells : should be "2".
+ - compatible : should be "fsl,qe-pario-bank-<bank>", "fsl,qe-pario-bank"
- reg : offset to the register set and its length.
- - num-ports : number of Parallel I/O ports
+ - gpio-controller : node to identify gpio controllers.
- Example:
- par_io@1400 {
- reg = <1400 100>;
- #address-cells = <1>;
- #size-cells = <0>;
- device_type = "par_io";
- num-ports = <7>;
- ucc_pin@01 {
- ......
- };
+ For example, two QE Par I/O banks:
+ qe_pio_a: gpio-controller@1400 {
+ #gpio-cells = <2>;
+ compatible = "fsl,qe-pario-bank-a", "fsl,qe-pario-bank";
+ reg = <0x1400 0x18>;
+ gpio-controller;
+ };
+ qe_pio_e: gpio-controller@1460 {
+ #gpio-cells = <2>;
+ compatible = "fsl,qe-pario-bank-e", "fsl,qe-pario-bank";
+ reg = <0x1460 0x18>;
+ gpio-controller;
+ };
vi) Pin configuration nodes
+ NOTE: pin configuration nodes are obsolete. Usually, their existance
+ is an evidence of the firmware shortcomings. Such fixups are
+ better handled by the Linux board file, not the device tree.
+
Required properties:
- linux,phandle : phandle of this node; likely referenced by a QE
device.
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index f38c50b..f6eecd1 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -270,6 +270,8 @@ config QUICC_ENGINE
bool
select PPC_LIB_RHEAP
select CRC32
+ select GENERIC_GPIO
+ select HAVE_GPIO_LIB
help
The QUICC Engine (QE) is a new generation of communications
coprocessors on Freescale embedded CPUs (akin to CPM in older chips).
diff --git a/arch/powerpc/sysdev/qe_lib/qe_io.c b/arch/powerpc/sysdev/qe_lib/qe_io.c
index a3f9c3f..a4a195a 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_io.c
+++ b/arch/powerpc/sysdev/qe_lib/qe_io.c
@@ -20,7 +20,8 @@
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/ioport.h>
-
+#include <linux/spinlock.h>
+#include <linux/of_gpio.h>
#include <asm/io.h>
#include <asm/qe.h>
#include <asm/prom.h>
@@ -214,6 +215,140 @@ int par_io_of_config(struct device_node *np)
}
EXPORT_SYMBOL(par_io_of_config);
+/*
+ * GPIO LIB API implementation
+ */
+
+struct qe_gpio_chip {
+ struct of_mm_gpio_chip mm_gc;
+ spinlock_t lock;
+
+ /* shadowed data register to clear/set bits safely */
+ u32 cpdata;
+};
+
+static inline struct qe_gpio_chip *
+to_qe_gpio_chip(struct of_mm_gpio_chip *mm_gc)
+{
+ return container_of(mm_gc, struct qe_gpio_chip, mm_gc);
+}
+
+static void qe_gpio_save_regs(struct of_mm_gpio_chip *mm_gc)
+{
+ struct qe_gpio_chip *qe_gc = to_qe_gpio_chip(mm_gc);
+ struct port_regs __iomem *regs = mm_gc->regs;
+
+ qe_gc->cpdata = in_be32(®s->cpdata);
+}
+
+static int qe_gpio_get(struct gpio_chip *gc, unsigned int gpio)
+{
+ struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+ struct port_regs __iomem *regs = mm_gc->regs;
+ u32 pin_mask;
+
+ /* calculate pin location */
+ pin_mask = (u32) (1 << (NUM_OF_PINS - 1 - gpio));
+
+ return !!(in_be32(®s->cpdata) & pin_mask);
+}
+
+static void qe_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+ struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+ struct qe_gpio_chip *qe_gc = to_qe_gpio_chip(mm_gc);
+ struct port_regs __iomem *regs = mm_gc->regs;
+ unsigned long flags;
+ u32 pin_mask = 1 << (NUM_OF_PINS - 1 - gpio);
+
+ spin_lock_irqsave(&qe_gc->lock, flags);
+
+ if (val)
+ qe_gc->cpdata |= pin_mask;
+ else
+ qe_gc->cpdata &= ~pin_mask;
+
+ out_be32(®s->cpdata, qe_gc->cpdata);
+
+ spin_unlock_irqrestore(&qe_gc->lock, flags);
+}
+
+static int qe_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
+{
+ struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+ struct qe_gpio_chip *qe_gc = to_qe_gpio_chip(mm_gc);
+ unsigned long flags;
+
+ spin_lock_irqsave(&qe_gc->lock, flags);
+
+ __par_io_config_pin(mm_gc->regs, gpio, 2, 0, 0, 0);
+
+ spin_unlock_irqrestore(&qe_gc->lock, flags);
+
+ return 0;
+}
+
+static int qe_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+ struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+ struct qe_gpio_chip *qe_gc = to_qe_gpio_chip(mm_gc);
+ unsigned long flags;
+
+ spin_lock_irqsave(&qe_gc->lock, flags);
+
+ __par_io_config_pin(mm_gc->regs, gpio, 1, 0, 0, 0);
+
+ spin_unlock_irqrestore(&qe_gc->lock, flags);
+
+ qe_gpio_set(gc, gpio, val);
+
+ return 0;
+}
+
+static int __init qe_add_gpiochips(void)
+{
+ int ret;
+ struct device_node *np;
+
+ for_each_compatible_node(np, NULL, "fsl,qe-pario-bank") {
+ struct qe_gpio_chip *qe_gc;
+ struct of_mm_gpio_chip *mm_gc;
+ struct of_gpio_chip *of_gc;
+ struct gpio_chip *gc;
+
+ qe_gc = kzalloc(sizeof(*qe_gc), GFP_KERNEL);
+ if (!qe_gc) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ spin_lock_init(&qe_gc->lock);
+
+ mm_gc = &qe_gc->mm_gc;
+ of_gc = &mm_gc->of_gc;
+ gc = &of_gc->gc;
+
+ mm_gc->save_regs = qe_gpio_save_regs;
+ of_gc->gpio_cells = 2;
+ gc->ngpio = NUM_OF_PINS;
+ gc->direction_input = qe_gpio_dir_in;
+ gc->direction_output = qe_gpio_dir_out;
+ gc->get = qe_gpio_get;
+ gc->set = qe_gpio_set;
+
+ ret = of_mm_gpiochip_add(np, mm_gc);
+ if (ret)
+ goto err;
+ }
+
+ return 0;
+err:
+ pr_err("%s: registration failed with status %d\n", np->full_name, ret);
+ of_node_put(np);
+ return ret;
+}
+arch_initcall(qe_add_gpiochips);
+
#ifdef DEBUG
static void dump_par_io(void)
{
--
1.5.5
next prev parent reply other threads:[~2008-04-17 19:29 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-04-17 19:26 [PATCH 0/5] Few more patches for Kumar's powerpc.git Anton Vorontsov
2008-04-17 19:28 ` [PATCH 1/5] [POWERPC] sysdev: implement FSL GTM support Anton Vorontsov
2008-04-17 22:47 ` Anton Vorontsov
2008-04-18 4:19 ` Kumar Gala
2008-04-18 9:54 ` Anton Vorontsov
2008-04-17 19:28 ` [PATCH 2/5] [POWERPC] QE: add support for QE USB clocks routing Anton Vorontsov
2008-04-17 19:56 ` Timur Tabi
2008-04-17 19:59 ` Scott Wood
2008-04-17 20:04 ` Timur Tabi
2008-04-17 20:14 ` Scott Wood
2008-04-17 20:17 ` Timur Tabi
2008-04-17 20:26 ` Scott Wood
2008-04-17 20:47 ` Dale Farnsworth
2008-04-17 20:49 ` Timur Tabi
2008-04-17 20:54 ` Dale Farnsworth
2008-04-17 21:48 ` Anton Vorontsov
2008-04-17 22:00 ` Timur Tabi
2008-04-17 19:28 ` [PATCH 3/5] [POWERPC] QE: split par_io_config_pin() Anton Vorontsov
2008-04-17 21:53 ` Kumar Gala
2008-04-17 22:35 ` Anton Vorontsov
2008-04-17 19:29 ` Anton Vorontsov [this message]
2008-04-17 22:35 ` [PATCH 4/5] [POWERPC] QE: implement support for the GPIO LIB API Kumar Gala
2008-04-17 22:41 ` Anton Vorontsov
2008-04-18 2:21 ` Kumar Gala
2008-04-17 19:29 ` [PATCH 5/5] [POWERPC] 83xx: new board support: MPC8360E-RDK Anton Vorontsov
-- strict thread matches above, loose matches on Subject: below --
2008-04-18 19:06 [PATCH 0/5 v2] Few more patches for Kumar's powerpc.git Anton Vorontsov
2008-04-18 19:09 ` [PATCH 4/5] [POWERPC] QE: implement support for the GPIO LIB API Anton Vorontsov
2008-04-19 5:49 ` David Brownell
2008-04-21 14:19 ` Grant Likely
2008-04-21 14:33 ` Anton Vorontsov
2008-04-21 14:49 ` Anton Vorontsov
2008-04-21 14:58 ` Grant Likely
2008-04-21 16:41 ` Anton Vorontsov
2008-04-21 20:01 ` David Brownell
2008-04-21 21:33 ` Anton Vorontsov
2008-04-21 22:19 ` David Brownell
2008-04-21 21:15 ` Grant Likely
2008-04-21 16:30 ` Segher Boessenkool
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=20080417192904.GD28286@polina.dev.rtsoft.ru \
--to=avorontsov@ru.mvista.com \
--cc=galak@kernel.crashing.org \
--cc=linuxppc-dev@ozlabs.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).