* [PATCH 1/2] gpio: move mpc8xxx/512x gpio driver to drivers/gpio
@ 2011-09-20 17:32 Wolfram Sang
2011-09-20 17:32 ` [PATCH 2/2] powerpc: update 512x-defconfig Wolfram Sang
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Wolfram Sang @ 2011-09-20 17:32 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Anatolij Gustschin
Move the driver to the place where it is expected to be nowadays. Also
rename its CONFIG-name to match the rest and adapt the defconfigs.
Finally, move selection of REQUIRE_GPIOLIB or WANTS_OPTIONAL_GPIOLIB to
the platforms, because this option is per-platform and not per-driver.
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Cc: Anatolij Gustschin <agust@denx.de>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
I'd think this should go via ppc, so it is in sync with the defconfig update of
patch 2/2.
arch/powerpc/configs/85xx/p1023rds_defconfig | 2 +-
arch/powerpc/configs/85xx/xes_mpc85xx_defconfig | 2 +-
arch/powerpc/configs/mpc85xx_defconfig | 2 +-
arch/powerpc/configs/mpc85xx_smp_defconfig | 2 +-
arch/powerpc/configs/ppc6xx_defconfig | 2 +-
arch/powerpc/platforms/512x/Kconfig | 1 +
arch/powerpc/platforms/83xx/Kconfig | 9 +-
arch/powerpc/platforms/85xx/Kconfig | 12 +-
arch/powerpc/platforms/86xx/Kconfig | 1 +
arch/powerpc/platforms/Kconfig | 10 -
arch/powerpc/sysdev/Makefile | 1 -
arch/powerpc/sysdev/mpc8xxx_gpio.c | 395 -----------------------
drivers/gpio/Kconfig | 8 +
drivers/gpio/Makefile | 1 +
drivers/gpio/gpio-mpc8xxx.c | 395 +++++++++++++++++++++++
15 files changed, 425 insertions(+), 418 deletions(-)
delete mode 100644 arch/powerpc/sysdev/mpc8xxx_gpio.c
create mode 100644 drivers/gpio/gpio-mpc8xxx.c
diff --git a/arch/powerpc/configs/85xx/p1023rds_defconfig b/arch/powerpc/configs/85xx/p1023rds_defconfig
index 3ff5a81..c091aaf 100644
--- a/arch/powerpc/configs/85xx/p1023rds_defconfig
+++ b/arch/powerpc/configs/85xx/p1023rds_defconfig
@@ -24,7 +24,7 @@ CONFIG_P1023_RDS=y
CONFIG_QUICC_ENGINE=y
CONFIG_QE_GPIO=y
CONFIG_CPM2=y
-CONFIG_MPC8xxx_GPIO=y
+CONFIG_GPIO_MPC8XXX=y
CONFIG_HIGHMEM=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
diff --git a/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig b/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig
index 5ea3124..1cd6fcb 100644
--- a/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig
+++ b/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig
@@ -20,7 +20,7 @@ CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_MODVERSIONS=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_XES_MPC85xx=y
-CONFIG_MPC8xxx_GPIO=y
+CONFIG_GPIO_MPC8XXX=y
CONFIG_HIGHMEM=y
CONFIG_MATH_EMULATION=y
CONFIG_SPARSE_IRQ=y
diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig
index a3467bf..2500912 100644
--- a/arch/powerpc/configs/mpc85xx_defconfig
+++ b/arch/powerpc/configs/mpc85xx_defconfig
@@ -41,7 +41,7 @@ CONFIG_TQM8560=y
CONFIG_SBC8548=y
CONFIG_QUICC_ENGINE=y
CONFIG_QE_GPIO=y
-CONFIG_MPC8xxx_GPIO=y
+CONFIG_GPIO_MPC8XXX=y
CONFIG_HIGHMEM=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
diff --git a/arch/powerpc/configs/mpc85xx_smp_defconfig b/arch/powerpc/configs/mpc85xx_smp_defconfig
index 9693f6e..a4ba13b 100644
--- a/arch/powerpc/configs/mpc85xx_smp_defconfig
+++ b/arch/powerpc/configs/mpc85xx_smp_defconfig
@@ -42,7 +42,7 @@ CONFIG_TQM8560=y
CONFIG_SBC8548=y
CONFIG_QUICC_ENGINE=y
CONFIG_QE_GPIO=y
-CONFIG_MPC8xxx_GPIO=y
+CONFIG_GPIO_MPC8XXX=y
CONFIG_HIGHMEM=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig
index 04360f9..c47f2be 100644
--- a/arch/powerpc/configs/ppc6xx_defconfig
+++ b/arch/powerpc/configs/ppc6xx_defconfig
@@ -70,7 +70,7 @@ CONFIG_TAU_AVERAGE=y
CONFIG_QUICC_ENGINE=y
CONFIG_QE_GPIO=y
CONFIG_PPC_BESTCOMM=y
-CONFIG_MPC8xxx_GPIO=y
+CONFIG_GPIO_MPC8XXX=y
CONFIG_MCU_MPC8349EMITX=m
CONFIG_HIGHMEM=y
CONFIG_NO_HZ=y
diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig
index 27b0651..b3ebce1 100644
--- a/arch/powerpc/platforms/512x/Kconfig
+++ b/arch/powerpc/platforms/512x/Kconfig
@@ -6,6 +6,7 @@ config PPC_MPC512x
select PPC_CLOCK
select PPC_PCI_CHOICE
select FSL_PCI if PCI
+ select ARCH_WANT_OPTIONAL_GPIOLIB
config MPC5121_ADS
bool "Freescale MPC5121E ADS"
diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig
index 73f4135..670a033 100644
--- a/arch/powerpc/platforms/83xx/Kconfig
+++ b/arch/powerpc/platforms/83xx/Kconfig
@@ -114,18 +114,21 @@ config KMETER1
endif
-# used for usb
+# used for usb & gpio
config PPC_MPC831x
bool
+ select ARCH_WANT_OPTIONAL_GPIOLIB
# used for math-emu
config PPC_MPC832x
bool
-# used for usb
+# used for usb & gpio
config PPC_MPC834x
bool
+ select ARCH_WANT_OPTIONAL_GPIOLIB
-# used for usb
+# used for usb & gpio
config PPC_MPC837x
bool
+ select ARCH_WANT_OPTIONAL_GPIOLIB
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index 498534c..1b393f4 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -177,7 +177,8 @@ config P2040_RDB
select PPC_E500MC
select PHYS_64BIT
select SWIOTLB
- select MPC8xxx_GPIO
+ select ARCH_REQUIRE_GPIOLIB
+ select GPIO_MPC8XXX
select HAS_RAPIDIO
select PPC_EPAPR_HV_PIC
help
@@ -189,7 +190,8 @@ config P3041_DS
select PPC_E500MC
select PHYS_64BIT
select SWIOTLB
- select MPC8xxx_GPIO
+ select ARCH_REQUIRE_GPIOLIB
+ select GPIO_MPC8XXX
select HAS_RAPIDIO
select PPC_EPAPR_HV_PIC
help
@@ -201,7 +203,8 @@ config P4080_DS
select PPC_E500MC
select PHYS_64BIT
select SWIOTLB
- select MPC8xxx_GPIO
+ select ARCH_REQUIRE_GPIOLIB
+ select GPIO_MPC8XXX
select HAS_RAPIDIO
select PPC_EPAPR_HV_PIC
help
@@ -216,7 +219,8 @@ config P5020_DS
select PPC_E500MC
select PHYS_64BIT
select SWIOTLB
- select MPC8xxx_GPIO
+ select ARCH_REQUIRE_GPIOLIB
+ select GPIO_MPC8XXX
select HAS_RAPIDIO
select PPC_EPAPR_HV_PIC
help
diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig
index a0b5638..8d6599d 100644
--- a/arch/powerpc/platforms/86xx/Kconfig
+++ b/arch/powerpc/platforms/86xx/Kconfig
@@ -4,6 +4,7 @@ menuconfig PPC_86xx
depends on 6xx
select FSL_SOC
select ALTIVEC
+ select ARCH_WANT_OPTIONAL_GPIOLIB
help
The Freescale E600 SoCs have 74xx cores.
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index b9ba861..c0cb1ea 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -333,16 +333,6 @@ config OF_RTC
source "arch/powerpc/sysdev/bestcomm/Kconfig"
-config MPC8xxx_GPIO
- bool "MPC512x/MPC8xxx GPIO support"
- depends on PPC_MPC512x || PPC_MPC831x || PPC_MPC834x || PPC_MPC837x || \
- FSL_SOC_BOOKE || PPC_86xx
- select GENERIC_GPIO
- select ARCH_REQUIRE_GPIOLIB
- help
- Say Y here if you're going to use hardware that connects to the
- MPC512x/831x/834x/837x/8572/8610 GPIOs.
-
config SIMPLE_GPIO
bool "Support for simple, memory-mapped GPIO controllers"
depends on PPC
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index cf736ca..84e1325 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -18,7 +18,6 @@ obj-$(CONFIG_FSL_PCI) += fsl_pci.o $(fsl-msi-obj-y)
obj-$(CONFIG_FSL_PMC) += fsl_pmc.o
obj-$(CONFIG_FSL_LBC) += fsl_lbc.o
obj-$(CONFIG_FSL_GTM) += fsl_gtm.o
-obj-$(CONFIG_MPC8xxx_GPIO) += mpc8xxx_gpio.o
obj-$(CONFIG_FSL_85XX_CACHE_SRAM) += fsl_85xx_l2ctlr.o fsl_85xx_cache_sram.o
obj-$(CONFIG_SIMPLE_GPIO) += simple_gpio.o
obj-$(CONFIG_FSL_RIO) += fsl_rio.o
diff --git a/arch/powerpc/sysdev/mpc8xxx_gpio.c b/arch/powerpc/sysdev/mpc8xxx_gpio.c
deleted file mode 100644
index fb4963a..0000000
--- a/arch/powerpc/sysdev/mpc8xxx_gpio.c
+++ /dev/null
@@ -1,395 +0,0 @@
-/*
- * GPIOs on MPC512x/8349/8572/8610 and compatible
- *
- * Copyright (C) 2008 Peter Korsgaard <jacmet@sunsite.dk>
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/of.h>
-#include <linux/of_gpio.h>
-#include <linux/gpio.h>
-#include <linux/slab.h>
-#include <linux/irq.h>
-
-#define MPC8XXX_GPIO_PINS 32
-
-#define GPIO_DIR 0x00
-#define GPIO_ODR 0x04
-#define GPIO_DAT 0x08
-#define GPIO_IER 0x0c
-#define GPIO_IMR 0x10
-#define GPIO_ICR 0x14
-#define GPIO_ICR2 0x18
-
-struct mpc8xxx_gpio_chip {
- struct of_mm_gpio_chip mm_gc;
- spinlock_t lock;
-
- /*
- * shadowed data register to be able to clear/set output pins in
- * open drain mode safely
- */
- u32 data;
- struct irq_host *irq;
- void *of_dev_id_data;
-};
-
-static inline u32 mpc8xxx_gpio2mask(unsigned int gpio)
-{
- return 1u << (MPC8XXX_GPIO_PINS - 1 - gpio);
-}
-
-static inline struct mpc8xxx_gpio_chip *
-to_mpc8xxx_gpio_chip(struct of_mm_gpio_chip *mm)
-{
- return container_of(mm, struct mpc8xxx_gpio_chip, mm_gc);
-}
-
-static void mpc8xxx_gpio_save_regs(struct of_mm_gpio_chip *mm)
-{
- struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
-
- mpc8xxx_gc->data = in_be32(mm->regs + GPIO_DAT);
-}
-
-/* Workaround GPIO 1 errata on MPC8572/MPC8536. The status of GPIOs
- * defined as output cannot be determined by reading GPDAT register,
- * so we use shadow data register instead. The status of input pins
- * is determined by reading GPDAT register.
- */
-static int mpc8572_gpio_get(struct gpio_chip *gc, unsigned int gpio)
-{
- u32 val;
- struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
- struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
-
- val = in_be32(mm->regs + GPIO_DAT) & ~in_be32(mm->regs + GPIO_DIR);
-
- return (val | mpc8xxx_gc->data) & mpc8xxx_gpio2mask(gpio);
-}
-
-static int mpc8xxx_gpio_get(struct gpio_chip *gc, unsigned int gpio)
-{
- struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
-
- return in_be32(mm->regs + GPIO_DAT) & mpc8xxx_gpio2mask(gpio);
-}
-
-static void mpc8xxx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
-{
- struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
- struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
- unsigned long flags;
-
- spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
-
- if (val)
- mpc8xxx_gc->data |= mpc8xxx_gpio2mask(gpio);
- else
- mpc8xxx_gc->data &= ~mpc8xxx_gpio2mask(gpio);
-
- out_be32(mm->regs + GPIO_DAT, mpc8xxx_gc->data);
-
- spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
-}
-
-static int mpc8xxx_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
-{
- struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
- struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
- unsigned long flags;
-
- spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
-
- clrbits32(mm->regs + GPIO_DIR, mpc8xxx_gpio2mask(gpio));
-
- spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
-
- return 0;
-}
-
-static int mpc8xxx_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
-{
- struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
- struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
- unsigned long flags;
-
- mpc8xxx_gpio_set(gc, gpio, val);
-
- spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
-
- setbits32(mm->regs + GPIO_DIR, mpc8xxx_gpio2mask(gpio));
-
- spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
-
- return 0;
-}
-
-static int mpc8xxx_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
-{
- struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
- struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
-
- if (mpc8xxx_gc->irq && offset < MPC8XXX_GPIO_PINS)
- return irq_create_mapping(mpc8xxx_gc->irq, offset);
- else
- return -ENXIO;
-}
-
-static void mpc8xxx_gpio_irq_cascade(unsigned int irq, struct irq_desc *desc)
-{
- struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_desc_get_handler_data(desc);
- struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
- unsigned int mask;
-
- mask = in_be32(mm->regs + GPIO_IER) & in_be32(mm->regs + GPIO_IMR);
- if (mask)
- generic_handle_irq(irq_linear_revmap(mpc8xxx_gc->irq,
- 32 - ffs(mask)));
-}
-
-static void mpc8xxx_irq_unmask(struct irq_data *d)
-{
- struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
- struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
- unsigned long flags;
-
- spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
-
- setbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
-
- spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
-}
-
-static void mpc8xxx_irq_mask(struct irq_data *d)
-{
- struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
- struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
- unsigned long flags;
-
- spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
-
- clrbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
-
- spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
-}
-
-static void mpc8xxx_irq_ack(struct irq_data *d)
-{
- struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
- struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
-
- out_be32(mm->regs + GPIO_IER, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
-}
-
-static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
-{
- struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
- struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
- unsigned long flags;
-
- switch (flow_type) {
- case IRQ_TYPE_EDGE_FALLING:
- spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
- setbits32(mm->regs + GPIO_ICR,
- mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
- spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
- break;
-
- case IRQ_TYPE_EDGE_BOTH:
- spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
- clrbits32(mm->regs + GPIO_ICR,
- mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
- spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int mpc512x_irq_set_type(struct irq_data *d, unsigned int flow_type)
-{
- struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
- struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
- unsigned long gpio = irqd_to_hwirq(d);
- void __iomem *reg;
- unsigned int shift;
- unsigned long flags;
-
- if (gpio < 16) {
- reg = mm->regs + GPIO_ICR;
- shift = (15 - gpio) * 2;
- } else {
- reg = mm->regs + GPIO_ICR2;
- shift = (15 - (gpio % 16)) * 2;
- }
-
- switch (flow_type) {
- case IRQ_TYPE_EDGE_FALLING:
- case IRQ_TYPE_LEVEL_LOW:
- spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
- clrsetbits_be32(reg, 3 << shift, 2 << shift);
- spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
- break;
-
- case IRQ_TYPE_EDGE_RISING:
- case IRQ_TYPE_LEVEL_HIGH:
- spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
- clrsetbits_be32(reg, 3 << shift, 1 << shift);
- spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
- break;
-
- case IRQ_TYPE_EDGE_BOTH:
- spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
- clrbits32(reg, 3 << shift);
- spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static struct irq_chip mpc8xxx_irq_chip = {
- .name = "mpc8xxx-gpio",
- .irq_unmask = mpc8xxx_irq_unmask,
- .irq_mask = mpc8xxx_irq_mask,
- .irq_ack = mpc8xxx_irq_ack,
- .irq_set_type = mpc8xxx_irq_set_type,
-};
-
-static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq,
- irq_hw_number_t hw)
-{
- struct mpc8xxx_gpio_chip *mpc8xxx_gc = h->host_data;
-
- if (mpc8xxx_gc->of_dev_id_data)
- mpc8xxx_irq_chip.irq_set_type = mpc8xxx_gc->of_dev_id_data;
-
- irq_set_chip_data(virq, h->host_data);
- irq_set_chip_and_handler(virq, &mpc8xxx_irq_chip, handle_level_irq);
- irq_set_irq_type(virq, IRQ_TYPE_NONE);
-
- return 0;
-}
-
-static int mpc8xxx_gpio_irq_xlate(struct irq_host *h, struct device_node *ct,
- const u32 *intspec, unsigned int intsize,
- irq_hw_number_t *out_hwirq,
- unsigned int *out_flags)
-
-{
- /* interrupt sense values coming from the device tree equal either
- * EDGE_FALLING or EDGE_BOTH
- */
- *out_hwirq = intspec[0];
- *out_flags = intspec[1];
-
- return 0;
-}
-
-static struct irq_host_ops mpc8xxx_gpio_irq_ops = {
- .map = mpc8xxx_gpio_irq_map,
- .xlate = mpc8xxx_gpio_irq_xlate,
-};
-
-static struct of_device_id mpc8xxx_gpio_ids[] __initdata = {
- { .compatible = "fsl,mpc8349-gpio", },
- { .compatible = "fsl,mpc8572-gpio", },
- { .compatible = "fsl,mpc8610-gpio", },
- { .compatible = "fsl,mpc5121-gpio", .data = mpc512x_irq_set_type, },
- { .compatible = "fsl,qoriq-gpio", },
- {}
-};
-
-static void __init mpc8xxx_add_controller(struct device_node *np)
-{
- struct mpc8xxx_gpio_chip *mpc8xxx_gc;
- struct of_mm_gpio_chip *mm_gc;
- struct gpio_chip *gc;
- const struct of_device_id *id;
- unsigned hwirq;
- int ret;
-
- mpc8xxx_gc = kzalloc(sizeof(*mpc8xxx_gc), GFP_KERNEL);
- if (!mpc8xxx_gc) {
- ret = -ENOMEM;
- goto err;
- }
-
- spin_lock_init(&mpc8xxx_gc->lock);
-
- mm_gc = &mpc8xxx_gc->mm_gc;
- gc = &mm_gc->gc;
-
- mm_gc->save_regs = mpc8xxx_gpio_save_regs;
- gc->ngpio = MPC8XXX_GPIO_PINS;
- gc->direction_input = mpc8xxx_gpio_dir_in;
- gc->direction_output = mpc8xxx_gpio_dir_out;
- if (of_device_is_compatible(np, "fsl,mpc8572-gpio"))
- gc->get = mpc8572_gpio_get;
- else
- gc->get = mpc8xxx_gpio_get;
- gc->set = mpc8xxx_gpio_set;
- gc->to_irq = mpc8xxx_gpio_to_irq;
-
- ret = of_mm_gpiochip_add(np, mm_gc);
- if (ret)
- goto err;
-
- hwirq = irq_of_parse_and_map(np, 0);
- if (hwirq == NO_IRQ)
- goto skip_irq;
-
- mpc8xxx_gc->irq =
- irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, MPC8XXX_GPIO_PINS,
- &mpc8xxx_gpio_irq_ops, MPC8XXX_GPIO_PINS);
- if (!mpc8xxx_gc->irq)
- goto skip_irq;
-
- id = of_match_node(mpc8xxx_gpio_ids, np);
- if (id)
- mpc8xxx_gc->of_dev_id_data = id->data;
-
- mpc8xxx_gc->irq->host_data = mpc8xxx_gc;
-
- /* ack and mask all irqs */
- out_be32(mm_gc->regs + GPIO_IER, 0xffffffff);
- out_be32(mm_gc->regs + GPIO_IMR, 0);
-
- irq_set_handler_data(hwirq, mpc8xxx_gc);
- irq_set_chained_handler(hwirq, mpc8xxx_gpio_irq_cascade);
-
-skip_irq:
- return;
-
-err:
- pr_err("%s: registration failed with status %d\n",
- np->full_name, ret);
- kfree(mpc8xxx_gc);
-
- return;
-}
-
-static int __init mpc8xxx_add_gpiochips(void)
-{
- struct device_node *np;
-
- for_each_matching_node(np, mpc8xxx_gpio_ids)
- mpc8xxx_add_controller(np);
-
- return 0;
-}
-arch_initcall(mpc8xxx_add_gpiochips);
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index d539efd..4744cf2 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -103,6 +103,14 @@ config GPIO_MPC5200
def_bool y
depends on PPC_MPC52xx
+config GPIO_MPC8XXX
+ bool "MPC512x/MPC8xxx GPIO support"
+ depends on PPC_MPC512x || PPC_MPC831x || PPC_MPC834x || PPC_MPC837x || \
+ FSL_SOC_BOOKE || PPC_86xx
+ help
+ Say Y here if you're going to use hardware that connects to the
+ MPC512x/831x/834x/837x/8572/8610 GPIOs.
+
config GPIO_MSM_V1
tristate "Qualcomm MSM GPIO v1"
depends on GPIOLIB && ARCH_MSM
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 9588948..828bba9 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o
obj-$(CONFIG_GPIO_MCP23S08) += gpio-mcp23s08.o
obj-$(CONFIG_GPIO_ML_IOH) += gpio-ml-ioh.o
obj-$(CONFIG_GPIO_MPC5200) += gpio-mpc5200.o
+obj-$(CONFIG_GPIO_MPC8XXX) += gpio-mpc8xxx.o
obj-$(CONFIG_GPIO_MSM_V1) += gpio-msm-v1.o
obj-$(CONFIG_GPIO_MSM_V2) += gpio-msm-v2.o
obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o
diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c
new file mode 100644
index 0000000..fb4963a
--- /dev/null
+++ b/drivers/gpio/gpio-mpc8xxx.c
@@ -0,0 +1,395 @@
+/*
+ * GPIOs on MPC512x/8349/8572/8610 and compatible
+ *
+ * Copyright (C) 2008 Peter Korsgaard <jacmet@sunsite.dk>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/gpio.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+
+#define MPC8XXX_GPIO_PINS 32
+
+#define GPIO_DIR 0x00
+#define GPIO_ODR 0x04
+#define GPIO_DAT 0x08
+#define GPIO_IER 0x0c
+#define GPIO_IMR 0x10
+#define GPIO_ICR 0x14
+#define GPIO_ICR2 0x18
+
+struct mpc8xxx_gpio_chip {
+ struct of_mm_gpio_chip mm_gc;
+ spinlock_t lock;
+
+ /*
+ * shadowed data register to be able to clear/set output pins in
+ * open drain mode safely
+ */
+ u32 data;
+ struct irq_host *irq;
+ void *of_dev_id_data;
+};
+
+static inline u32 mpc8xxx_gpio2mask(unsigned int gpio)
+{
+ return 1u << (MPC8XXX_GPIO_PINS - 1 - gpio);
+}
+
+static inline struct mpc8xxx_gpio_chip *
+to_mpc8xxx_gpio_chip(struct of_mm_gpio_chip *mm)
+{
+ return container_of(mm, struct mpc8xxx_gpio_chip, mm_gc);
+}
+
+static void mpc8xxx_gpio_save_regs(struct of_mm_gpio_chip *mm)
+{
+ struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
+
+ mpc8xxx_gc->data = in_be32(mm->regs + GPIO_DAT);
+}
+
+/* Workaround GPIO 1 errata on MPC8572/MPC8536. The status of GPIOs
+ * defined as output cannot be determined by reading GPDAT register,
+ * so we use shadow data register instead. The status of input pins
+ * is determined by reading GPDAT register.
+ */
+static int mpc8572_gpio_get(struct gpio_chip *gc, unsigned int gpio)
+{
+ u32 val;
+ struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
+ struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
+
+ val = in_be32(mm->regs + GPIO_DAT) & ~in_be32(mm->regs + GPIO_DIR);
+
+ return (val | mpc8xxx_gc->data) & mpc8xxx_gpio2mask(gpio);
+}
+
+static int mpc8xxx_gpio_get(struct gpio_chip *gc, unsigned int gpio)
+{
+ struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
+
+ return in_be32(mm->regs + GPIO_DAT) & mpc8xxx_gpio2mask(gpio);
+}
+
+static void mpc8xxx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+ struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
+ struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
+ unsigned long flags;
+
+ spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+
+ if (val)
+ mpc8xxx_gc->data |= mpc8xxx_gpio2mask(gpio);
+ else
+ mpc8xxx_gc->data &= ~mpc8xxx_gpio2mask(gpio);
+
+ out_be32(mm->regs + GPIO_DAT, mpc8xxx_gc->data);
+
+ spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+}
+
+static int mpc8xxx_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
+{
+ struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
+ struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
+ unsigned long flags;
+
+ spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+
+ clrbits32(mm->regs + GPIO_DIR, mpc8xxx_gpio2mask(gpio));
+
+ spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+
+ return 0;
+}
+
+static int mpc8xxx_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+ struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
+ struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
+ unsigned long flags;
+
+ mpc8xxx_gpio_set(gc, gpio, val);
+
+ spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+
+ setbits32(mm->regs + GPIO_DIR, mpc8xxx_gpio2mask(gpio));
+
+ spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+
+ return 0;
+}
+
+static int mpc8xxx_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
+{
+ struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
+ struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
+
+ if (mpc8xxx_gc->irq && offset < MPC8XXX_GPIO_PINS)
+ return irq_create_mapping(mpc8xxx_gc->irq, offset);
+ else
+ return -ENXIO;
+}
+
+static void mpc8xxx_gpio_irq_cascade(unsigned int irq, struct irq_desc *desc)
+{
+ struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_desc_get_handler_data(desc);
+ struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
+ unsigned int mask;
+
+ mask = in_be32(mm->regs + GPIO_IER) & in_be32(mm->regs + GPIO_IMR);
+ if (mask)
+ generic_handle_irq(irq_linear_revmap(mpc8xxx_gc->irq,
+ 32 - ffs(mask)));
+}
+
+static void mpc8xxx_irq_unmask(struct irq_data *d)
+{
+ struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
+ struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
+ unsigned long flags;
+
+ spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+
+ setbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
+
+ spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+}
+
+static void mpc8xxx_irq_mask(struct irq_data *d)
+{
+ struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
+ struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
+ unsigned long flags;
+
+ spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+
+ clrbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
+
+ spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+}
+
+static void mpc8xxx_irq_ack(struct irq_data *d)
+{
+ struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
+ struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
+
+ out_be32(mm->regs + GPIO_IER, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
+}
+
+static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
+{
+ struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
+ struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
+ unsigned long flags;
+
+ switch (flow_type) {
+ case IRQ_TYPE_EDGE_FALLING:
+ spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+ setbits32(mm->regs + GPIO_ICR,
+ mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
+ spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+ break;
+
+ case IRQ_TYPE_EDGE_BOTH:
+ spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+ clrbits32(mm->regs + GPIO_ICR,
+ mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
+ spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int mpc512x_irq_set_type(struct irq_data *d, unsigned int flow_type)
+{
+ struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
+ struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
+ unsigned long gpio = irqd_to_hwirq(d);
+ void __iomem *reg;
+ unsigned int shift;
+ unsigned long flags;
+
+ if (gpio < 16) {
+ reg = mm->regs + GPIO_ICR;
+ shift = (15 - gpio) * 2;
+ } else {
+ reg = mm->regs + GPIO_ICR2;
+ shift = (15 - (gpio % 16)) * 2;
+ }
+
+ switch (flow_type) {
+ case IRQ_TYPE_EDGE_FALLING:
+ case IRQ_TYPE_LEVEL_LOW:
+ spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+ clrsetbits_be32(reg, 3 << shift, 2 << shift);
+ spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+ break;
+
+ case IRQ_TYPE_EDGE_RISING:
+ case IRQ_TYPE_LEVEL_HIGH:
+ spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+ clrsetbits_be32(reg, 3 << shift, 1 << shift);
+ spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+ break;
+
+ case IRQ_TYPE_EDGE_BOTH:
+ spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+ clrbits32(reg, 3 << shift);
+ spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct irq_chip mpc8xxx_irq_chip = {
+ .name = "mpc8xxx-gpio",
+ .irq_unmask = mpc8xxx_irq_unmask,
+ .irq_mask = mpc8xxx_irq_mask,
+ .irq_ack = mpc8xxx_irq_ack,
+ .irq_set_type = mpc8xxx_irq_set_type,
+};
+
+static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq,
+ irq_hw_number_t hw)
+{
+ struct mpc8xxx_gpio_chip *mpc8xxx_gc = h->host_data;
+
+ if (mpc8xxx_gc->of_dev_id_data)
+ mpc8xxx_irq_chip.irq_set_type = mpc8xxx_gc->of_dev_id_data;
+
+ irq_set_chip_data(virq, h->host_data);
+ irq_set_chip_and_handler(virq, &mpc8xxx_irq_chip, handle_level_irq);
+ irq_set_irq_type(virq, IRQ_TYPE_NONE);
+
+ return 0;
+}
+
+static int mpc8xxx_gpio_irq_xlate(struct irq_host *h, struct device_node *ct,
+ const u32 *intspec, unsigned int intsize,
+ irq_hw_number_t *out_hwirq,
+ unsigned int *out_flags)
+
+{
+ /* interrupt sense values coming from the device tree equal either
+ * EDGE_FALLING or EDGE_BOTH
+ */
+ *out_hwirq = intspec[0];
+ *out_flags = intspec[1];
+
+ return 0;
+}
+
+static struct irq_host_ops mpc8xxx_gpio_irq_ops = {
+ .map = mpc8xxx_gpio_irq_map,
+ .xlate = mpc8xxx_gpio_irq_xlate,
+};
+
+static struct of_device_id mpc8xxx_gpio_ids[] __initdata = {
+ { .compatible = "fsl,mpc8349-gpio", },
+ { .compatible = "fsl,mpc8572-gpio", },
+ { .compatible = "fsl,mpc8610-gpio", },
+ { .compatible = "fsl,mpc5121-gpio", .data = mpc512x_irq_set_type, },
+ { .compatible = "fsl,qoriq-gpio", },
+ {}
+};
+
+static void __init mpc8xxx_add_controller(struct device_node *np)
+{
+ struct mpc8xxx_gpio_chip *mpc8xxx_gc;
+ struct of_mm_gpio_chip *mm_gc;
+ struct gpio_chip *gc;
+ const struct of_device_id *id;
+ unsigned hwirq;
+ int ret;
+
+ mpc8xxx_gc = kzalloc(sizeof(*mpc8xxx_gc), GFP_KERNEL);
+ if (!mpc8xxx_gc) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ spin_lock_init(&mpc8xxx_gc->lock);
+
+ mm_gc = &mpc8xxx_gc->mm_gc;
+ gc = &mm_gc->gc;
+
+ mm_gc->save_regs = mpc8xxx_gpio_save_regs;
+ gc->ngpio = MPC8XXX_GPIO_PINS;
+ gc->direction_input = mpc8xxx_gpio_dir_in;
+ gc->direction_output = mpc8xxx_gpio_dir_out;
+ if (of_device_is_compatible(np, "fsl,mpc8572-gpio"))
+ gc->get = mpc8572_gpio_get;
+ else
+ gc->get = mpc8xxx_gpio_get;
+ gc->set = mpc8xxx_gpio_set;
+ gc->to_irq = mpc8xxx_gpio_to_irq;
+
+ ret = of_mm_gpiochip_add(np, mm_gc);
+ if (ret)
+ goto err;
+
+ hwirq = irq_of_parse_and_map(np, 0);
+ if (hwirq == NO_IRQ)
+ goto skip_irq;
+
+ mpc8xxx_gc->irq =
+ irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, MPC8XXX_GPIO_PINS,
+ &mpc8xxx_gpio_irq_ops, MPC8XXX_GPIO_PINS);
+ if (!mpc8xxx_gc->irq)
+ goto skip_irq;
+
+ id = of_match_node(mpc8xxx_gpio_ids, np);
+ if (id)
+ mpc8xxx_gc->of_dev_id_data = id->data;
+
+ mpc8xxx_gc->irq->host_data = mpc8xxx_gc;
+
+ /* ack and mask all irqs */
+ out_be32(mm_gc->regs + GPIO_IER, 0xffffffff);
+ out_be32(mm_gc->regs + GPIO_IMR, 0);
+
+ irq_set_handler_data(hwirq, mpc8xxx_gc);
+ irq_set_chained_handler(hwirq, mpc8xxx_gpio_irq_cascade);
+
+skip_irq:
+ return;
+
+err:
+ pr_err("%s: registration failed with status %d\n",
+ np->full_name, ret);
+ kfree(mpc8xxx_gc);
+
+ return;
+}
+
+static int __init mpc8xxx_add_gpiochips(void)
+{
+ struct device_node *np;
+
+ for_each_matching_node(np, mpc8xxx_gpio_ids)
+ mpc8xxx_add_controller(np);
+
+ return 0;
+}
+arch_initcall(mpc8xxx_add_gpiochips);
--
1.7.5.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/2] powerpc: update 512x-defconfig
2011-09-20 17:32 [PATCH 1/2] gpio: move mpc8xxx/512x gpio driver to drivers/gpio Wolfram Sang
@ 2011-09-20 17:32 ` Wolfram Sang
2011-09-20 17:34 ` [PATCH 1/2] gpio: move mpc8xxx/512x gpio driver to drivers/gpio Wolfram Sang
2011-09-20 17:59 ` Grant Likely
2 siblings, 0 replies; 4+ messages in thread
From: Wolfram Sang @ 2011-09-20 17:32 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Anatolij Gustschin
Activate all MPC512x related boards. Also enable GPIO-driver, SPI driver
and at25 to test SPI. Enable DEVTMPFS. Bump to 3.1-rc6.
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Cc: Anatolij Gustschin <agust@denx.de>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/configs/mpc512x_defconfig | 19 +++++++++++--------
1 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/configs/mpc512x_defconfig b/arch/powerpc/configs/mpc512x_defconfig
index c02bbb2..211fcc9 100644
--- a/arch/powerpc/configs/mpc512x_defconfig
+++ b/arch/powerpc/configs/mpc512x_defconfig
@@ -1,9 +1,9 @@
CONFIG_EXPERIMENTAL=y
# CONFIG_SWAP is not set
CONFIG_SYSVIPC=y
+CONFIG_SPARSE_IRQ=y
CONFIG_LOG_BUF_SHIFT=16
CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
# CONFIG_COMPAT_BRK is not set
CONFIG_SLAB=y
CONFIG_MODULES=y
@@ -13,10 +13,11 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_PPC_CHRP is not set
CONFIG_PPC_MPC512x=y
CONFIG_MPC5121_ADS=y
+CONFIG_MPC5121_GENERIC=y
+CONFIG_PDM360NG=y
# CONFIG_PPC_PMAC is not set
CONFIG_NO_HZ=y
CONFIG_HZ_1000=y
-CONFIG_SPARSE_IRQ=y
# CONFIG_MIGRATION is not set
# CONFIG_SECCOMP is not set
# CONFIG_PCI is not set
@@ -35,18 +36,16 @@ CONFIG_CAN=y
CONFIG_CAN_RAW=y
CONFIG_CAN_BCM=y
CONFIG_CAN_VCAN=y
-CONFIG_CAN_DEV=y
CONFIG_CAN_MSCAN=y
CONFIG_CAN_DEBUG_DEVICES=y
# CONFIG_WIRELESS is not set
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
# CONFIG_FIRMWARE_IN_KERNEL is not set
CONFIG_MTD=y
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_OF_PARTS=y
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_CFI=y
@@ -63,6 +62,7 @@ CONFIG_BLK_DEV_RAM_SIZE=8192
CONFIG_BLK_DEV_XIP=y
CONFIG_MISC_DEVICES=y
CONFIG_EEPROM_AT24=y
+CONFIG_EEPROM_AT25=y
CONFIG_SCSI=y
# CONFIG_SCSI_PROC_FS is not set
CONFIG_BLK_DEV_SD=y
@@ -99,10 +99,14 @@ CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_MPC=y
+CONFIG_SPI=y
+CONFIG_SPI_MPC512x_PSC=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_MPC8XXX=y
# CONFIG_HWMON is not set
CONFIG_MEDIA_SUPPORT=y
CONFIG_VIDEO_DEV=y
-# CONFIG_VIDEO_ALLOW_V4L1 is not set
CONFIG_VIDEO_ADV_DEBUG=y
# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
CONFIG_VIDEO_SAA711X=y
@@ -132,6 +136,5 @@ CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
# CONFIG_ENABLE_WARN_DEPRECATED is not set
# CONFIG_ENABLE_MUST_CHECK is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRYPTO_HW is not set
--
1.7.5.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 1/2] gpio: move mpc8xxx/512x gpio driver to drivers/gpio
2011-09-20 17:32 [PATCH 1/2] gpio: move mpc8xxx/512x gpio driver to drivers/gpio Wolfram Sang
2011-09-20 17:32 ` [PATCH 2/2] powerpc: update 512x-defconfig Wolfram Sang
@ 2011-09-20 17:34 ` Wolfram Sang
2011-09-20 17:59 ` Grant Likely
2 siblings, 0 replies; 4+ messages in thread
From: Wolfram Sang @ 2011-09-20 17:34 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Anatolij Gustschin
[-- Attachment #1: Type: text/plain, Size: 970 bytes --]
On Tue, Sep 20, 2011 at 07:32:20PM +0200, Wolfram Sang wrote:
> Move the driver to the place where it is expected to be nowadays. Also
> rename its CONFIG-name to match the rest and adapt the defconfigs.
> Finally, move selection of REQUIRE_GPIOLIB or WANTS_OPTIONAL_GPIOLIB to
> the platforms, because this option is per-platform and not per-driver.
>
> Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
> Cc: Anatolij Gustschin <agust@denx.de>
> Cc: Grant Likely <grant.likely@secretlab.ca>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
>
> I'd think this should go via ppc, so it is in sync with the defconfig update of
> patch 2/2.
Forgot to mention: Both patches tested on a MPC5121-based board with
linux 3.1-rc6 (couldn't find an alternative location for ppc-next).
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 1/2] gpio: move mpc8xxx/512x gpio driver to drivers/gpio
2011-09-20 17:32 [PATCH 1/2] gpio: move mpc8xxx/512x gpio driver to drivers/gpio Wolfram Sang
2011-09-20 17:32 ` [PATCH 2/2] powerpc: update 512x-defconfig Wolfram Sang
2011-09-20 17:34 ` [PATCH 1/2] gpio: move mpc8xxx/512x gpio driver to drivers/gpio Wolfram Sang
@ 2011-09-20 17:59 ` Grant Likely
2 siblings, 0 replies; 4+ messages in thread
From: Grant Likely @ 2011-09-20 17:59 UTC (permalink / raw)
To: Wolfram Sang; +Cc: linuxppc-dev, Anatolij Gustschin
On Tue, Sep 20, 2011 at 07:32:20PM +0200, Wolfram Sang wrote:
> Move the driver to the place where it is expected to be nowadays. Also
> rename its CONFIG-name to match the rest and adapt the defconfigs.
> Finally, move selection of REQUIRE_GPIOLIB or WANTS_OPTIONAL_GPIOLIB to
> the platforms, because this option is per-platform and not per-driver.
>
> Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
> Cc: Anatolij Gustschin <agust@denx.de>
> Cc: Grant Likely <grant.likely@secretlab.ca>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
>
> I'd think this should go via ppc, so it is in sync with the defconfig update of
> patch 2/2.
>
> arch/powerpc/configs/85xx/p1023rds_defconfig | 2 +-
> arch/powerpc/configs/85xx/xes_mpc85xx_defconfig | 2 +-
> arch/powerpc/configs/mpc85xx_defconfig | 2 +-
> arch/powerpc/configs/mpc85xx_smp_defconfig | 2 +-
> arch/powerpc/configs/ppc6xx_defconfig | 2 +-
> arch/powerpc/platforms/512x/Kconfig | 1 +
> arch/powerpc/platforms/83xx/Kconfig | 9 +-
> arch/powerpc/platforms/85xx/Kconfig | 12 +-
> arch/powerpc/platforms/86xx/Kconfig | 1 +
> arch/powerpc/platforms/Kconfig | 10 -
> arch/powerpc/sysdev/Makefile | 1 -
> arch/powerpc/sysdev/mpc8xxx_gpio.c | 395 -----------------------
> drivers/gpio/Kconfig | 8 +
> drivers/gpio/Makefile | 1 +
> drivers/gpio/gpio-mpc8xxx.c | 395 +++++++++++++++++++++++
Please resubmit and use the --find-renames flag so to keep the diff
showing only the actual changes.
g.
> 15 files changed, 425 insertions(+), 418 deletions(-)
> delete mode 100644 arch/powerpc/sysdev/mpc8xxx_gpio.c
> create mode 100644 drivers/gpio/gpio-mpc8xxx.c
>
> diff --git a/arch/powerpc/configs/85xx/p1023rds_defconfig b/arch/powerpc/configs/85xx/p1023rds_defconfig
> index 3ff5a81..c091aaf 100644
> --- a/arch/powerpc/configs/85xx/p1023rds_defconfig
> +++ b/arch/powerpc/configs/85xx/p1023rds_defconfig
> @@ -24,7 +24,7 @@ CONFIG_P1023_RDS=y
> CONFIG_QUICC_ENGINE=y
> CONFIG_QE_GPIO=y
> CONFIG_CPM2=y
> -CONFIG_MPC8xxx_GPIO=y
> +CONFIG_GPIO_MPC8XXX=y
> CONFIG_HIGHMEM=y
> CONFIG_NO_HZ=y
> CONFIG_HIGH_RES_TIMERS=y
> diff --git a/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig b/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig
> index 5ea3124..1cd6fcb 100644
> --- a/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig
> +++ b/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig
> @@ -20,7 +20,7 @@ CONFIG_MODULE_FORCE_UNLOAD=y
> CONFIG_MODVERSIONS=y
> # CONFIG_BLK_DEV_BSG is not set
> CONFIG_XES_MPC85xx=y
> -CONFIG_MPC8xxx_GPIO=y
> +CONFIG_GPIO_MPC8XXX=y
> CONFIG_HIGHMEM=y
> CONFIG_MATH_EMULATION=y
> CONFIG_SPARSE_IRQ=y
> diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig
> index a3467bf..2500912 100644
> --- a/arch/powerpc/configs/mpc85xx_defconfig
> +++ b/arch/powerpc/configs/mpc85xx_defconfig
> @@ -41,7 +41,7 @@ CONFIG_TQM8560=y
> CONFIG_SBC8548=y
> CONFIG_QUICC_ENGINE=y
> CONFIG_QE_GPIO=y
> -CONFIG_MPC8xxx_GPIO=y
> +CONFIG_GPIO_MPC8XXX=y
> CONFIG_HIGHMEM=y
> CONFIG_NO_HZ=y
> CONFIG_HIGH_RES_TIMERS=y
> diff --git a/arch/powerpc/configs/mpc85xx_smp_defconfig b/arch/powerpc/configs/mpc85xx_smp_defconfig
> index 9693f6e..a4ba13b 100644
> --- a/arch/powerpc/configs/mpc85xx_smp_defconfig
> +++ b/arch/powerpc/configs/mpc85xx_smp_defconfig
> @@ -42,7 +42,7 @@ CONFIG_TQM8560=y
> CONFIG_SBC8548=y
> CONFIG_QUICC_ENGINE=y
> CONFIG_QE_GPIO=y
> -CONFIG_MPC8xxx_GPIO=y
> +CONFIG_GPIO_MPC8XXX=y
> CONFIG_HIGHMEM=y
> CONFIG_NO_HZ=y
> CONFIG_HIGH_RES_TIMERS=y
> diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig
> index 04360f9..c47f2be 100644
> --- a/arch/powerpc/configs/ppc6xx_defconfig
> +++ b/arch/powerpc/configs/ppc6xx_defconfig
> @@ -70,7 +70,7 @@ CONFIG_TAU_AVERAGE=y
> CONFIG_QUICC_ENGINE=y
> CONFIG_QE_GPIO=y
> CONFIG_PPC_BESTCOMM=y
> -CONFIG_MPC8xxx_GPIO=y
> +CONFIG_GPIO_MPC8XXX=y
> CONFIG_MCU_MPC8349EMITX=m
> CONFIG_HIGHMEM=y
> CONFIG_NO_HZ=y
> diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig
> index 27b0651..b3ebce1 100644
> --- a/arch/powerpc/platforms/512x/Kconfig
> +++ b/arch/powerpc/platforms/512x/Kconfig
> @@ -6,6 +6,7 @@ config PPC_MPC512x
> select PPC_CLOCK
> select PPC_PCI_CHOICE
> select FSL_PCI if PCI
> + select ARCH_WANT_OPTIONAL_GPIOLIB
>
> config MPC5121_ADS
> bool "Freescale MPC5121E ADS"
> diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig
> index 73f4135..670a033 100644
> --- a/arch/powerpc/platforms/83xx/Kconfig
> +++ b/arch/powerpc/platforms/83xx/Kconfig
> @@ -114,18 +114,21 @@ config KMETER1
>
> endif
>
> -# used for usb
> +# used for usb & gpio
> config PPC_MPC831x
> bool
> + select ARCH_WANT_OPTIONAL_GPIOLIB
>
> # used for math-emu
> config PPC_MPC832x
> bool
>
> -# used for usb
> +# used for usb & gpio
> config PPC_MPC834x
> bool
> + select ARCH_WANT_OPTIONAL_GPIOLIB
>
> -# used for usb
> +# used for usb & gpio
> config PPC_MPC837x
> bool
> + select ARCH_WANT_OPTIONAL_GPIOLIB
> diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
> index 498534c..1b393f4 100644
> --- a/arch/powerpc/platforms/85xx/Kconfig
> +++ b/arch/powerpc/platforms/85xx/Kconfig
> @@ -177,7 +177,8 @@ config P2040_RDB
> select PPC_E500MC
> select PHYS_64BIT
> select SWIOTLB
> - select MPC8xxx_GPIO
> + select ARCH_REQUIRE_GPIOLIB
> + select GPIO_MPC8XXX
> select HAS_RAPIDIO
> select PPC_EPAPR_HV_PIC
> help
> @@ -189,7 +190,8 @@ config P3041_DS
> select PPC_E500MC
> select PHYS_64BIT
> select SWIOTLB
> - select MPC8xxx_GPIO
> + select ARCH_REQUIRE_GPIOLIB
> + select GPIO_MPC8XXX
> select HAS_RAPIDIO
> select PPC_EPAPR_HV_PIC
> help
> @@ -201,7 +203,8 @@ config P4080_DS
> select PPC_E500MC
> select PHYS_64BIT
> select SWIOTLB
> - select MPC8xxx_GPIO
> + select ARCH_REQUIRE_GPIOLIB
> + select GPIO_MPC8XXX
> select HAS_RAPIDIO
> select PPC_EPAPR_HV_PIC
> help
> @@ -216,7 +219,8 @@ config P5020_DS
> select PPC_E500MC
> select PHYS_64BIT
> select SWIOTLB
> - select MPC8xxx_GPIO
> + select ARCH_REQUIRE_GPIOLIB
> + select GPIO_MPC8XXX
> select HAS_RAPIDIO
> select PPC_EPAPR_HV_PIC
> help
> diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig
> index a0b5638..8d6599d 100644
> --- a/arch/powerpc/platforms/86xx/Kconfig
> +++ b/arch/powerpc/platforms/86xx/Kconfig
> @@ -4,6 +4,7 @@ menuconfig PPC_86xx
> depends on 6xx
> select FSL_SOC
> select ALTIVEC
> + select ARCH_WANT_OPTIONAL_GPIOLIB
> help
> The Freescale E600 SoCs have 74xx cores.
>
> diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
> index b9ba861..c0cb1ea 100644
> --- a/arch/powerpc/platforms/Kconfig
> +++ b/arch/powerpc/platforms/Kconfig
> @@ -333,16 +333,6 @@ config OF_RTC
>
> source "arch/powerpc/sysdev/bestcomm/Kconfig"
>
> -config MPC8xxx_GPIO
> - bool "MPC512x/MPC8xxx GPIO support"
> - depends on PPC_MPC512x || PPC_MPC831x || PPC_MPC834x || PPC_MPC837x || \
> - FSL_SOC_BOOKE || PPC_86xx
> - select GENERIC_GPIO
> - select ARCH_REQUIRE_GPIOLIB
> - help
> - Say Y here if you're going to use hardware that connects to the
> - MPC512x/831x/834x/837x/8572/8610 GPIOs.
> -
> config SIMPLE_GPIO
> bool "Support for simple, memory-mapped GPIO controllers"
> depends on PPC
> diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
> index cf736ca..84e1325 100644
> --- a/arch/powerpc/sysdev/Makefile
> +++ b/arch/powerpc/sysdev/Makefile
> @@ -18,7 +18,6 @@ obj-$(CONFIG_FSL_PCI) += fsl_pci.o $(fsl-msi-obj-y)
> obj-$(CONFIG_FSL_PMC) += fsl_pmc.o
> obj-$(CONFIG_FSL_LBC) += fsl_lbc.o
> obj-$(CONFIG_FSL_GTM) += fsl_gtm.o
> -obj-$(CONFIG_MPC8xxx_GPIO) += mpc8xxx_gpio.o
> obj-$(CONFIG_FSL_85XX_CACHE_SRAM) += fsl_85xx_l2ctlr.o fsl_85xx_cache_sram.o
> obj-$(CONFIG_SIMPLE_GPIO) += simple_gpio.o
> obj-$(CONFIG_FSL_RIO) += fsl_rio.o
> diff --git a/arch/powerpc/sysdev/mpc8xxx_gpio.c b/arch/powerpc/sysdev/mpc8xxx_gpio.c
> deleted file mode 100644
> index fb4963a..0000000
> --- a/arch/powerpc/sysdev/mpc8xxx_gpio.c
> +++ /dev/null
> @@ -1,395 +0,0 @@
> -/*
> - * GPIOs on MPC512x/8349/8572/8610 and compatible
> - *
> - * Copyright (C) 2008 Peter Korsgaard <jacmet@sunsite.dk>
> - *
> - * This file is licensed under the terms of the GNU General Public License
> - * version 2. This program is licensed "as is" without any warranty of any
> - * kind, whether express or implied.
> - */
> -
> -#include <linux/kernel.h>
> -#include <linux/init.h>
> -#include <linux/spinlock.h>
> -#include <linux/io.h>
> -#include <linux/of.h>
> -#include <linux/of_gpio.h>
> -#include <linux/gpio.h>
> -#include <linux/slab.h>
> -#include <linux/irq.h>
> -
> -#define MPC8XXX_GPIO_PINS 32
> -
> -#define GPIO_DIR 0x00
> -#define GPIO_ODR 0x04
> -#define GPIO_DAT 0x08
> -#define GPIO_IER 0x0c
> -#define GPIO_IMR 0x10
> -#define GPIO_ICR 0x14
> -#define GPIO_ICR2 0x18
> -
> -struct mpc8xxx_gpio_chip {
> - struct of_mm_gpio_chip mm_gc;
> - spinlock_t lock;
> -
> - /*
> - * shadowed data register to be able to clear/set output pins in
> - * open drain mode safely
> - */
> - u32 data;
> - struct irq_host *irq;
> - void *of_dev_id_data;
> -};
> -
> -static inline u32 mpc8xxx_gpio2mask(unsigned int gpio)
> -{
> - return 1u << (MPC8XXX_GPIO_PINS - 1 - gpio);
> -}
> -
> -static inline struct mpc8xxx_gpio_chip *
> -to_mpc8xxx_gpio_chip(struct of_mm_gpio_chip *mm)
> -{
> - return container_of(mm, struct mpc8xxx_gpio_chip, mm_gc);
> -}
> -
> -static void mpc8xxx_gpio_save_regs(struct of_mm_gpio_chip *mm)
> -{
> - struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
> -
> - mpc8xxx_gc->data = in_be32(mm->regs + GPIO_DAT);
> -}
> -
> -/* Workaround GPIO 1 errata on MPC8572/MPC8536. The status of GPIOs
> - * defined as output cannot be determined by reading GPDAT register,
> - * so we use shadow data register instead. The status of input pins
> - * is determined by reading GPDAT register.
> - */
> -static int mpc8572_gpio_get(struct gpio_chip *gc, unsigned int gpio)
> -{
> - u32 val;
> - struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
> - struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
> -
> - val = in_be32(mm->regs + GPIO_DAT) & ~in_be32(mm->regs + GPIO_DIR);
> -
> - return (val | mpc8xxx_gc->data) & mpc8xxx_gpio2mask(gpio);
> -}
> -
> -static int mpc8xxx_gpio_get(struct gpio_chip *gc, unsigned int gpio)
> -{
> - struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
> -
> - return in_be32(mm->regs + GPIO_DAT) & mpc8xxx_gpio2mask(gpio);
> -}
> -
> -static void mpc8xxx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
> -{
> - struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
> - struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
> - unsigned long flags;
> -
> - spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
> -
> - if (val)
> - mpc8xxx_gc->data |= mpc8xxx_gpio2mask(gpio);
> - else
> - mpc8xxx_gc->data &= ~mpc8xxx_gpio2mask(gpio);
> -
> - out_be32(mm->regs + GPIO_DAT, mpc8xxx_gc->data);
> -
> - spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
> -}
> -
> -static int mpc8xxx_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
> -{
> - struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
> - struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
> - unsigned long flags;
> -
> - spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
> -
> - clrbits32(mm->regs + GPIO_DIR, mpc8xxx_gpio2mask(gpio));
> -
> - spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
> -
> - return 0;
> -}
> -
> -static int mpc8xxx_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
> -{
> - struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
> - struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
> - unsigned long flags;
> -
> - mpc8xxx_gpio_set(gc, gpio, val);
> -
> - spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
> -
> - setbits32(mm->regs + GPIO_DIR, mpc8xxx_gpio2mask(gpio));
> -
> - spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
> -
> - return 0;
> -}
> -
> -static int mpc8xxx_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
> -{
> - struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
> - struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
> -
> - if (mpc8xxx_gc->irq && offset < MPC8XXX_GPIO_PINS)
> - return irq_create_mapping(mpc8xxx_gc->irq, offset);
> - else
> - return -ENXIO;
> -}
> -
> -static void mpc8xxx_gpio_irq_cascade(unsigned int irq, struct irq_desc *desc)
> -{
> - struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_desc_get_handler_data(desc);
> - struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
> - unsigned int mask;
> -
> - mask = in_be32(mm->regs + GPIO_IER) & in_be32(mm->regs + GPIO_IMR);
> - if (mask)
> - generic_handle_irq(irq_linear_revmap(mpc8xxx_gc->irq,
> - 32 - ffs(mask)));
> -}
> -
> -static void mpc8xxx_irq_unmask(struct irq_data *d)
> -{
> - struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
> - struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
> - unsigned long flags;
> -
> - spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
> -
> - setbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
> -
> - spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
> -}
> -
> -static void mpc8xxx_irq_mask(struct irq_data *d)
> -{
> - struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
> - struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
> - unsigned long flags;
> -
> - spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
> -
> - clrbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
> -
> - spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
> -}
> -
> -static void mpc8xxx_irq_ack(struct irq_data *d)
> -{
> - struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
> - struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
> -
> - out_be32(mm->regs + GPIO_IER, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
> -}
> -
> -static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
> -{
> - struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
> - struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
> - unsigned long flags;
> -
> - switch (flow_type) {
> - case IRQ_TYPE_EDGE_FALLING:
> - spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
> - setbits32(mm->regs + GPIO_ICR,
> - mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
> - spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
> - break;
> -
> - case IRQ_TYPE_EDGE_BOTH:
> - spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
> - clrbits32(mm->regs + GPIO_ICR,
> - mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
> - spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
> - break;
> -
> - default:
> - return -EINVAL;
> - }
> -
> - return 0;
> -}
> -
> -static int mpc512x_irq_set_type(struct irq_data *d, unsigned int flow_type)
> -{
> - struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
> - struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
> - unsigned long gpio = irqd_to_hwirq(d);
> - void __iomem *reg;
> - unsigned int shift;
> - unsigned long flags;
> -
> - if (gpio < 16) {
> - reg = mm->regs + GPIO_ICR;
> - shift = (15 - gpio) * 2;
> - } else {
> - reg = mm->regs + GPIO_ICR2;
> - shift = (15 - (gpio % 16)) * 2;
> - }
> -
> - switch (flow_type) {
> - case IRQ_TYPE_EDGE_FALLING:
> - case IRQ_TYPE_LEVEL_LOW:
> - spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
> - clrsetbits_be32(reg, 3 << shift, 2 << shift);
> - spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
> - break;
> -
> - case IRQ_TYPE_EDGE_RISING:
> - case IRQ_TYPE_LEVEL_HIGH:
> - spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
> - clrsetbits_be32(reg, 3 << shift, 1 << shift);
> - spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
> - break;
> -
> - case IRQ_TYPE_EDGE_BOTH:
> - spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
> - clrbits32(reg, 3 << shift);
> - spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
> - break;
> -
> - default:
> - return -EINVAL;
> - }
> -
> - return 0;
> -}
> -
> -static struct irq_chip mpc8xxx_irq_chip = {
> - .name = "mpc8xxx-gpio",
> - .irq_unmask = mpc8xxx_irq_unmask,
> - .irq_mask = mpc8xxx_irq_mask,
> - .irq_ack = mpc8xxx_irq_ack,
> - .irq_set_type = mpc8xxx_irq_set_type,
> -};
> -
> -static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq,
> - irq_hw_number_t hw)
> -{
> - struct mpc8xxx_gpio_chip *mpc8xxx_gc = h->host_data;
> -
> - if (mpc8xxx_gc->of_dev_id_data)
> - mpc8xxx_irq_chip.irq_set_type = mpc8xxx_gc->of_dev_id_data;
> -
> - irq_set_chip_data(virq, h->host_data);
> - irq_set_chip_and_handler(virq, &mpc8xxx_irq_chip, handle_level_irq);
> - irq_set_irq_type(virq, IRQ_TYPE_NONE);
> -
> - return 0;
> -}
> -
> -static int mpc8xxx_gpio_irq_xlate(struct irq_host *h, struct device_node *ct,
> - const u32 *intspec, unsigned int intsize,
> - irq_hw_number_t *out_hwirq,
> - unsigned int *out_flags)
> -
> -{
> - /* interrupt sense values coming from the device tree equal either
> - * EDGE_FALLING or EDGE_BOTH
> - */
> - *out_hwirq = intspec[0];
> - *out_flags = intspec[1];
> -
> - return 0;
> -}
> -
> -static struct irq_host_ops mpc8xxx_gpio_irq_ops = {
> - .map = mpc8xxx_gpio_irq_map,
> - .xlate = mpc8xxx_gpio_irq_xlate,
> -};
> -
> -static struct of_device_id mpc8xxx_gpio_ids[] __initdata = {
> - { .compatible = "fsl,mpc8349-gpio", },
> - { .compatible = "fsl,mpc8572-gpio", },
> - { .compatible = "fsl,mpc8610-gpio", },
> - { .compatible = "fsl,mpc5121-gpio", .data = mpc512x_irq_set_type, },
> - { .compatible = "fsl,qoriq-gpio", },
> - {}
> -};
> -
> -static void __init mpc8xxx_add_controller(struct device_node *np)
> -{
> - struct mpc8xxx_gpio_chip *mpc8xxx_gc;
> - struct of_mm_gpio_chip *mm_gc;
> - struct gpio_chip *gc;
> - const struct of_device_id *id;
> - unsigned hwirq;
> - int ret;
> -
> - mpc8xxx_gc = kzalloc(sizeof(*mpc8xxx_gc), GFP_KERNEL);
> - if (!mpc8xxx_gc) {
> - ret = -ENOMEM;
> - goto err;
> - }
> -
> - spin_lock_init(&mpc8xxx_gc->lock);
> -
> - mm_gc = &mpc8xxx_gc->mm_gc;
> - gc = &mm_gc->gc;
> -
> - mm_gc->save_regs = mpc8xxx_gpio_save_regs;
> - gc->ngpio = MPC8XXX_GPIO_PINS;
> - gc->direction_input = mpc8xxx_gpio_dir_in;
> - gc->direction_output = mpc8xxx_gpio_dir_out;
> - if (of_device_is_compatible(np, "fsl,mpc8572-gpio"))
> - gc->get = mpc8572_gpio_get;
> - else
> - gc->get = mpc8xxx_gpio_get;
> - gc->set = mpc8xxx_gpio_set;
> - gc->to_irq = mpc8xxx_gpio_to_irq;
> -
> - ret = of_mm_gpiochip_add(np, mm_gc);
> - if (ret)
> - goto err;
> -
> - hwirq = irq_of_parse_and_map(np, 0);
> - if (hwirq == NO_IRQ)
> - goto skip_irq;
> -
> - mpc8xxx_gc->irq =
> - irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, MPC8XXX_GPIO_PINS,
> - &mpc8xxx_gpio_irq_ops, MPC8XXX_GPIO_PINS);
> - if (!mpc8xxx_gc->irq)
> - goto skip_irq;
> -
> - id = of_match_node(mpc8xxx_gpio_ids, np);
> - if (id)
> - mpc8xxx_gc->of_dev_id_data = id->data;
> -
> - mpc8xxx_gc->irq->host_data = mpc8xxx_gc;
> -
> - /* ack and mask all irqs */
> - out_be32(mm_gc->regs + GPIO_IER, 0xffffffff);
> - out_be32(mm_gc->regs + GPIO_IMR, 0);
> -
> - irq_set_handler_data(hwirq, mpc8xxx_gc);
> - irq_set_chained_handler(hwirq, mpc8xxx_gpio_irq_cascade);
> -
> -skip_irq:
> - return;
> -
> -err:
> - pr_err("%s: registration failed with status %d\n",
> - np->full_name, ret);
> - kfree(mpc8xxx_gc);
> -
> - return;
> -}
> -
> -static int __init mpc8xxx_add_gpiochips(void)
> -{
> - struct device_node *np;
> -
> - for_each_matching_node(np, mpc8xxx_gpio_ids)
> - mpc8xxx_add_controller(np);
> -
> - return 0;
> -}
> -arch_initcall(mpc8xxx_add_gpiochips);
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index d539efd..4744cf2 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -103,6 +103,14 @@ config GPIO_MPC5200
> def_bool y
> depends on PPC_MPC52xx
>
> +config GPIO_MPC8XXX
> + bool "MPC512x/MPC8xxx GPIO support"
> + depends on PPC_MPC512x || PPC_MPC831x || PPC_MPC834x || PPC_MPC837x || \
> + FSL_SOC_BOOKE || PPC_86xx
> + help
> + Say Y here if you're going to use hardware that connects to the
> + MPC512x/831x/834x/837x/8572/8610 GPIOs.
> +
> config GPIO_MSM_V1
> tristate "Qualcomm MSM GPIO v1"
> depends on GPIOLIB && ARCH_MSM
> diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
> index 9588948..828bba9 100644
> --- a/drivers/gpio/Makefile
> +++ b/drivers/gpio/Makefile
> @@ -27,6 +27,7 @@ obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o
> obj-$(CONFIG_GPIO_MCP23S08) += gpio-mcp23s08.o
> obj-$(CONFIG_GPIO_ML_IOH) += gpio-ml-ioh.o
> obj-$(CONFIG_GPIO_MPC5200) += gpio-mpc5200.o
> +obj-$(CONFIG_GPIO_MPC8XXX) += gpio-mpc8xxx.o
> obj-$(CONFIG_GPIO_MSM_V1) += gpio-msm-v1.o
> obj-$(CONFIG_GPIO_MSM_V2) += gpio-msm-v2.o
> obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o
> diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c
> new file mode 100644
> index 0000000..fb4963a
> --- /dev/null
> +++ b/drivers/gpio/gpio-mpc8xxx.c
> @@ -0,0 +1,395 @@
> +/*
> + * GPIOs on MPC512x/8349/8572/8610 and compatible
> + *
> + * Copyright (C) 2008 Peter Korsgaard <jacmet@sunsite.dk>
> + *
> + * This file is licensed under the terms of the GNU General Public License
> + * version 2. This program is licensed "as is" without any warranty of any
> + * kind, whether express or implied.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/spinlock.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/of_gpio.h>
> +#include <linux/gpio.h>
> +#include <linux/slab.h>
> +#include <linux/irq.h>
> +
> +#define MPC8XXX_GPIO_PINS 32
> +
> +#define GPIO_DIR 0x00
> +#define GPIO_ODR 0x04
> +#define GPIO_DAT 0x08
> +#define GPIO_IER 0x0c
> +#define GPIO_IMR 0x10
> +#define GPIO_ICR 0x14
> +#define GPIO_ICR2 0x18
> +
> +struct mpc8xxx_gpio_chip {
> + struct of_mm_gpio_chip mm_gc;
> + spinlock_t lock;
> +
> + /*
> + * shadowed data register to be able to clear/set output pins in
> + * open drain mode safely
> + */
> + u32 data;
> + struct irq_host *irq;
> + void *of_dev_id_data;
> +};
> +
> +static inline u32 mpc8xxx_gpio2mask(unsigned int gpio)
> +{
> + return 1u << (MPC8XXX_GPIO_PINS - 1 - gpio);
> +}
> +
> +static inline struct mpc8xxx_gpio_chip *
> +to_mpc8xxx_gpio_chip(struct of_mm_gpio_chip *mm)
> +{
> + return container_of(mm, struct mpc8xxx_gpio_chip, mm_gc);
> +}
> +
> +static void mpc8xxx_gpio_save_regs(struct of_mm_gpio_chip *mm)
> +{
> + struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
> +
> + mpc8xxx_gc->data = in_be32(mm->regs + GPIO_DAT);
> +}
> +
> +/* Workaround GPIO 1 errata on MPC8572/MPC8536. The status of GPIOs
> + * defined as output cannot be determined by reading GPDAT register,
> + * so we use shadow data register instead. The status of input pins
> + * is determined by reading GPDAT register.
> + */
> +static int mpc8572_gpio_get(struct gpio_chip *gc, unsigned int gpio)
> +{
> + u32 val;
> + struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
> + struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
> +
> + val = in_be32(mm->regs + GPIO_DAT) & ~in_be32(mm->regs + GPIO_DIR);
> +
> + return (val | mpc8xxx_gc->data) & mpc8xxx_gpio2mask(gpio);
> +}
> +
> +static int mpc8xxx_gpio_get(struct gpio_chip *gc, unsigned int gpio)
> +{
> + struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
> +
> + return in_be32(mm->regs + GPIO_DAT) & mpc8xxx_gpio2mask(gpio);
> +}
> +
> +static void mpc8xxx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
> +{
> + struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
> + struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
> + unsigned long flags;
> +
> + spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
> +
> + if (val)
> + mpc8xxx_gc->data |= mpc8xxx_gpio2mask(gpio);
> + else
> + mpc8xxx_gc->data &= ~mpc8xxx_gpio2mask(gpio);
> +
> + out_be32(mm->regs + GPIO_DAT, mpc8xxx_gc->data);
> +
> + spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
> +}
> +
> +static int mpc8xxx_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
> +{
> + struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
> + struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
> + unsigned long flags;
> +
> + spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
> +
> + clrbits32(mm->regs + GPIO_DIR, mpc8xxx_gpio2mask(gpio));
> +
> + spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
> +
> + return 0;
> +}
> +
> +static int mpc8xxx_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
> +{
> + struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
> + struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
> + unsigned long flags;
> +
> + mpc8xxx_gpio_set(gc, gpio, val);
> +
> + spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
> +
> + setbits32(mm->regs + GPIO_DIR, mpc8xxx_gpio2mask(gpio));
> +
> + spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
> +
> + return 0;
> +}
> +
> +static int mpc8xxx_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
> +{
> + struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
> + struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
> +
> + if (mpc8xxx_gc->irq && offset < MPC8XXX_GPIO_PINS)
> + return irq_create_mapping(mpc8xxx_gc->irq, offset);
> + else
> + return -ENXIO;
> +}
> +
> +static void mpc8xxx_gpio_irq_cascade(unsigned int irq, struct irq_desc *desc)
> +{
> + struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_desc_get_handler_data(desc);
> + struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
> + unsigned int mask;
> +
> + mask = in_be32(mm->regs + GPIO_IER) & in_be32(mm->regs + GPIO_IMR);
> + if (mask)
> + generic_handle_irq(irq_linear_revmap(mpc8xxx_gc->irq,
> + 32 - ffs(mask)));
> +}
> +
> +static void mpc8xxx_irq_unmask(struct irq_data *d)
> +{
> + struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
> + struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
> + unsigned long flags;
> +
> + spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
> +
> + setbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
> +
> + spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
> +}
> +
> +static void mpc8xxx_irq_mask(struct irq_data *d)
> +{
> + struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
> + struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
> + unsigned long flags;
> +
> + spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
> +
> + clrbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
> +
> + spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
> +}
> +
> +static void mpc8xxx_irq_ack(struct irq_data *d)
> +{
> + struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
> + struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
> +
> + out_be32(mm->regs + GPIO_IER, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
> +}
> +
> +static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
> +{
> + struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
> + struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
> + unsigned long flags;
> +
> + switch (flow_type) {
> + case IRQ_TYPE_EDGE_FALLING:
> + spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
> + setbits32(mm->regs + GPIO_ICR,
> + mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
> + spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
> + break;
> +
> + case IRQ_TYPE_EDGE_BOTH:
> + spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
> + clrbits32(mm->regs + GPIO_ICR,
> + mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
> + spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
> + break;
> +
> + default:
> + return -EINVAL;
> + }
> +
> + return 0;
> +}
> +
> +static int mpc512x_irq_set_type(struct irq_data *d, unsigned int flow_type)
> +{
> + struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
> + struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
> + unsigned long gpio = irqd_to_hwirq(d);
> + void __iomem *reg;
> + unsigned int shift;
> + unsigned long flags;
> +
> + if (gpio < 16) {
> + reg = mm->regs + GPIO_ICR;
> + shift = (15 - gpio) * 2;
> + } else {
> + reg = mm->regs + GPIO_ICR2;
> + shift = (15 - (gpio % 16)) * 2;
> + }
> +
> + switch (flow_type) {
> + case IRQ_TYPE_EDGE_FALLING:
> + case IRQ_TYPE_LEVEL_LOW:
> + spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
> + clrsetbits_be32(reg, 3 << shift, 2 << shift);
> + spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
> + break;
> +
> + case IRQ_TYPE_EDGE_RISING:
> + case IRQ_TYPE_LEVEL_HIGH:
> + spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
> + clrsetbits_be32(reg, 3 << shift, 1 << shift);
> + spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
> + break;
> +
> + case IRQ_TYPE_EDGE_BOTH:
> + spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
> + clrbits32(reg, 3 << shift);
> + spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
> + break;
> +
> + default:
> + return -EINVAL;
> + }
> +
> + return 0;
> +}
> +
> +static struct irq_chip mpc8xxx_irq_chip = {
> + .name = "mpc8xxx-gpio",
> + .irq_unmask = mpc8xxx_irq_unmask,
> + .irq_mask = mpc8xxx_irq_mask,
> + .irq_ack = mpc8xxx_irq_ack,
> + .irq_set_type = mpc8xxx_irq_set_type,
> +};
> +
> +static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq,
> + irq_hw_number_t hw)
> +{
> + struct mpc8xxx_gpio_chip *mpc8xxx_gc = h->host_data;
> +
> + if (mpc8xxx_gc->of_dev_id_data)
> + mpc8xxx_irq_chip.irq_set_type = mpc8xxx_gc->of_dev_id_data;
> +
> + irq_set_chip_data(virq, h->host_data);
> + irq_set_chip_and_handler(virq, &mpc8xxx_irq_chip, handle_level_irq);
> + irq_set_irq_type(virq, IRQ_TYPE_NONE);
> +
> + return 0;
> +}
> +
> +static int mpc8xxx_gpio_irq_xlate(struct irq_host *h, struct device_node *ct,
> + const u32 *intspec, unsigned int intsize,
> + irq_hw_number_t *out_hwirq,
> + unsigned int *out_flags)
> +
> +{
> + /* interrupt sense values coming from the device tree equal either
> + * EDGE_FALLING or EDGE_BOTH
> + */
> + *out_hwirq = intspec[0];
> + *out_flags = intspec[1];
> +
> + return 0;
> +}
> +
> +static struct irq_host_ops mpc8xxx_gpio_irq_ops = {
> + .map = mpc8xxx_gpio_irq_map,
> + .xlate = mpc8xxx_gpio_irq_xlate,
> +};
> +
> +static struct of_device_id mpc8xxx_gpio_ids[] __initdata = {
> + { .compatible = "fsl,mpc8349-gpio", },
> + { .compatible = "fsl,mpc8572-gpio", },
> + { .compatible = "fsl,mpc8610-gpio", },
> + { .compatible = "fsl,mpc5121-gpio", .data = mpc512x_irq_set_type, },
> + { .compatible = "fsl,qoriq-gpio", },
> + {}
> +};
> +
> +static void __init mpc8xxx_add_controller(struct device_node *np)
> +{
> + struct mpc8xxx_gpio_chip *mpc8xxx_gc;
> + struct of_mm_gpio_chip *mm_gc;
> + struct gpio_chip *gc;
> + const struct of_device_id *id;
> + unsigned hwirq;
> + int ret;
> +
> + mpc8xxx_gc = kzalloc(sizeof(*mpc8xxx_gc), GFP_KERNEL);
> + if (!mpc8xxx_gc) {
> + ret = -ENOMEM;
> + goto err;
> + }
> +
> + spin_lock_init(&mpc8xxx_gc->lock);
> +
> + mm_gc = &mpc8xxx_gc->mm_gc;
> + gc = &mm_gc->gc;
> +
> + mm_gc->save_regs = mpc8xxx_gpio_save_regs;
> + gc->ngpio = MPC8XXX_GPIO_PINS;
> + gc->direction_input = mpc8xxx_gpio_dir_in;
> + gc->direction_output = mpc8xxx_gpio_dir_out;
> + if (of_device_is_compatible(np, "fsl,mpc8572-gpio"))
> + gc->get = mpc8572_gpio_get;
> + else
> + gc->get = mpc8xxx_gpio_get;
> + gc->set = mpc8xxx_gpio_set;
> + gc->to_irq = mpc8xxx_gpio_to_irq;
> +
> + ret = of_mm_gpiochip_add(np, mm_gc);
> + if (ret)
> + goto err;
> +
> + hwirq = irq_of_parse_and_map(np, 0);
> + if (hwirq == NO_IRQ)
> + goto skip_irq;
> +
> + mpc8xxx_gc->irq =
> + irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, MPC8XXX_GPIO_PINS,
> + &mpc8xxx_gpio_irq_ops, MPC8XXX_GPIO_PINS);
> + if (!mpc8xxx_gc->irq)
> + goto skip_irq;
> +
> + id = of_match_node(mpc8xxx_gpio_ids, np);
> + if (id)
> + mpc8xxx_gc->of_dev_id_data = id->data;
> +
> + mpc8xxx_gc->irq->host_data = mpc8xxx_gc;
> +
> + /* ack and mask all irqs */
> + out_be32(mm_gc->regs + GPIO_IER, 0xffffffff);
> + out_be32(mm_gc->regs + GPIO_IMR, 0);
> +
> + irq_set_handler_data(hwirq, mpc8xxx_gc);
> + irq_set_chained_handler(hwirq, mpc8xxx_gpio_irq_cascade);
> +
> +skip_irq:
> + return;
> +
> +err:
> + pr_err("%s: registration failed with status %d\n",
> + np->full_name, ret);
> + kfree(mpc8xxx_gc);
> +
> + return;
> +}
> +
> +static int __init mpc8xxx_add_gpiochips(void)
> +{
> + struct device_node *np;
> +
> + for_each_matching_node(np, mpc8xxx_gpio_ids)
> + mpc8xxx_add_controller(np);
> +
> + return 0;
> +}
> +arch_initcall(mpc8xxx_add_gpiochips);
> --
> 1.7.5.4
>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2011-09-20 17:59 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-09-20 17:32 [PATCH 1/2] gpio: move mpc8xxx/512x gpio driver to drivers/gpio Wolfram Sang
2011-09-20 17:32 ` [PATCH 2/2] powerpc: update 512x-defconfig Wolfram Sang
2011-09-20 17:34 ` [PATCH 1/2] gpio: move mpc8xxx/512x gpio driver to drivers/gpio Wolfram Sang
2011-09-20 17:59 ` Grant Likely
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).