{"id":448,"url":"http://patchwork.ozlabs.org/api/1.0/patches/448/?format=json","project":{"id":2,"url":"http://patchwork.ozlabs.org/api/1.0/projects/2/?format=json","name":"Linux PPC development","link_name":"linuxppc-dev","list_id":"linuxppc-dev.lists.ozlabs.org","list_email":"linuxppc-dev@lists.ozlabs.org","web_url":"https://github.com/linuxppc/wiki/wiki","scm_url":"https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git","webscm_url":"https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git/"},"msgid":"<20080917175820.GA22539@oksana.dev.rtsoft.ru>","date":"2008-09-17T17:58:20","name":"[v2] powerpc: implement support for MPC8349-compatible SOC GPIOs","commit_ref":null,"pull_url":null,"state":"superseded","archived":true,"hash":"f6eb331487845fd7d4ddd1a8a2c03c57ea4b9f58","submitter":{"id":45,"url":"http://patchwork.ozlabs.org/api/1.0/people/45/?format=json","name":"Anton Vorontsov","email":"avorontsov@ru.mvista.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/linuxppc-dev/patch/20080917175820.GA22539@oksana.dev.rtsoft.ru/mbox/","series":[],"check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/448/checks/","tags":{},"headers":{"Return-Path":"<linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@ozlabs.org>","X-Original-To":["patchwork-incoming@ozlabs.org","linuxppc-dev@ozlabs.org"],"Delivered-To":["patchwork-incoming@ozlabs.org","linuxppc-dev@ozlabs.org"],"Received":["from ozlabs.org (localhost [127.0.0.1])\n\tby ozlabs.org (Postfix) with ESMTP id D98CEDE11E\n\tfor <patchwork-incoming@ozlabs.org>;\n\tThu, 18 Sep 2008 03:58:50 +1000 (EST)","from buildserver.ru.mvista.com (unknown [85.21.88.6])\n\tby ozlabs.org (Postfix) with ESMTP id 39970DDEF1\n\tfor <linuxppc-dev@ozlabs.org>; Thu, 18 Sep 2008 03:58:25 +1000 (EST)","from localhost (unknown [10.150.0.9])\n\tby buildserver.ru.mvista.com (Postfix) with ESMTP\n\tid A23FB881A; Wed, 17 Sep 2008 22:58:20 +0500 (SAMST)"],"Date":"Wed, 17 Sep 2008 21:58:20 +0400","From":"Anton Vorontsov <avorontsov@ru.mvista.com>","To":"Kumar Gala <galak@kernel.crashing.org>","Subject":"[PATCH v2] powerpc: implement support for MPC8349-compatible SOC\n\tGPIOs","Message-ID":"<20080917175820.GA22539@oksana.dev.rtsoft.ru>","MIME-Version":"1.0","Content-Disposition":"inline","User-Agent":"Mutt/1.5.18 (2008-05-17)","Cc":"linuxppc-dev@ozlabs.org","X-BeenThere":"linuxppc-dev@ozlabs.org","X-Mailman-Version":"2.1.11","Precedence":"list","List-Id":"Linux on PowerPC Developers Mail List <linuxppc-dev.ozlabs.org>","List-Unsubscribe":"<https://ozlabs.org/mailman/options/linuxppc-dev>,\n\t<mailto:linuxppc-dev-request@ozlabs.org?subject=unsubscribe>","List-Archive":"<http://ozlabs.org/pipermail/linuxppc-dev>","List-Post":"<mailto:linuxppc-dev@ozlabs.org>","List-Help":"<mailto:linuxppc-dev-request@ozlabs.org?subject=help>","List-Subscribe":"<https://ozlabs.org/mailman/listinfo/linuxppc-dev>,\n\t<mailto:linuxppc-dev-request@ozlabs.org?subject=subscribe>","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Sender":"linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@ozlabs.org","Errors-To":"linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@ozlabs.org"},"content":"This patch implements GPIOLIB support for MPC8349-compatible SOC GPIOs.\nMPC8610 adopted this GPIO unit, so let's place it into sysdev.\n\nWe'll need these gpios to support IrDA transceiver on MPC8610HPCD.\n\nSigned-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>","diff":"diff --git a/arch/powerpc/sysdev/Kconfig b/arch/powerpc/sysdev/Kconfig\nindex 30d6e4d..4cbfda0 100644\n--- a/arch/powerpc/sysdev/Kconfig\n+++ b/arch/powerpc/sysdev/Kconfig\n@@ -17,3 +17,13 @@ config OF_SIMPLE_GPIO\n \t  These are usually BCSRs used to control board's switches, LEDs,\n \t  chip-selects, Ethernet/USB PHY's power and various other small\n \t  on-board peripherals.\n+\n+config FSL_MPC8349_GPIO\n+\tbool \"Support for MPC8349-compatible GPIO controllers\"\n+\tdepends on PPC32\n+\tselect GENERIC_GPIO\n+\tselect ARCH_REQUIRE_GPIOLIB\n+\thelp\n+\t  Say Y here to support Freescale MPC8349-compatible GPIO controllers.\n+\t  The controllers can be found in MPC831x, MPC834x, MPC837x and\n+\t  MPC8610 processors.\ndiff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile\nindex 239d7e8..afbc3a4 100644\n--- a/arch/powerpc/sysdev/Makefile\n+++ b/arch/powerpc/sysdev/Makefile\n@@ -37,6 +37,7 @@ obj-$(CONFIG_4xx)\t\t+= ppc4xx_pci.o\n endif\n \n obj-$(CONFIG_OF_SIMPLE_GPIO)\t+= of_simple_gpio.o\n+obj-$(CONFIG_FSL_MPC8349_GPIO)\t+= fsl_mpc8349_gpio.o\n \n # Temporary hack until we have migrated to asm-powerpc\n ifeq ($(ARCH),powerpc)\ndiff --git a/arch/powerpc/sysdev/fsl_mpc8349_gpio.c b/arch/powerpc/sysdev/fsl_mpc8349_gpio.c\nnew file mode 100644\nindex 0000000..c8c77f4\n--- /dev/null\n+++ b/arch/powerpc/sysdev/fsl_mpc8349_gpio.c\n@@ -0,0 +1,161 @@\n+/*\n+ * MPC8349-compatible SOC GPIOs\n+ *\n+ * Copyright (c) MontaVista Software, Inc. 2008.\n+ *\n+ * Author: Anton Vorontsov <avorontsov@ru.mvista.com>\n+ *\n+ * This program is free software; you can redistribute  it and/or modify it\n+ * under  the terms of  the GNU General  Public License as published by the\n+ * Free Software Foundation;  either version 2 of the  License, or (at your\n+ * option) any later version.\n+ */\n+\n+#include <linux/init.h>\n+#include <linux/types.h>\n+#include <linux/kernel.h>\n+#include <linux/compiler.h>\n+#include <linux/spinlock.h>\n+#include <linux/io.h>\n+#include <linux/of.h>\n+#include <linux/of_gpio.h>\n+#include <linux/gpio.h>\n+\n+#define FSL_GPIO_PINS 32\n+\n+struct fsl_gpio_regs {\n+\t__be32 gpdir;\n+\t__be32 gpodr;\n+\t__be32 gpdat;\n+\t__be32 gpier;\n+\t__be32 gpimr;\n+\t__be32 gpicr;\n+};\n+\n+struct fsl_gpio_chip {\n+\tstruct of_mm_gpio_chip mm_gc;\n+\tspinlock_t lock;\n+\n+\t/* shadowed data register to clear/set bits safely */\n+\tu32 gpdat;\n+};\n+\n+static inline u32 pin2mask(unsigned int pin)\n+{\n+\treturn 1 << (FSL_GPIO_PINS - 1 - pin);\n+}\n+\n+static inline struct fsl_gpio_chip *\n+to_fsl_gpio_chip(struct of_mm_gpio_chip *mm_gc)\n+{\n+\treturn container_of(mm_gc, struct fsl_gpio_chip, mm_gc);\n+}\n+\n+static void fsl_gpio_save_regs(struct of_mm_gpio_chip *mm_gc)\n+{\n+\tstruct fsl_gpio_chip *fsl_gc = to_fsl_gpio_chip(mm_gc);\n+\tstruct fsl_gpio_regs __iomem *regs = mm_gc->regs;\n+\n+\tfsl_gc->gpdat = in_be32(&regs->gpdat);\n+}\n+\n+static int fsl_gpio_get(struct gpio_chip *gc, unsigned int gpio)\n+{\n+\tstruct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);\n+\tstruct fsl_gpio_regs __iomem *regs = mm_gc->regs;\n+\n+\treturn in_be32(&regs->gpdat) & pin2mask(gpio);\n+}\n+\n+static void fsl_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)\n+{\n+\tstruct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);\n+\tstruct fsl_gpio_chip *fsl_gc = to_fsl_gpio_chip(mm_gc);\n+\tstruct fsl_gpio_regs __iomem *regs = mm_gc->regs;\n+\tunsigned long flags;\n+\n+\tspin_lock_irqsave(&fsl_gc->lock, flags);\n+\n+\tif (val)\n+\t\tfsl_gc->gpdat |= pin2mask(gpio);\n+\telse\n+\t\tfsl_gc->gpdat &= ~pin2mask(gpio);\n+\n+\tout_be32(&regs->gpdat, fsl_gc->gpdat);\n+\n+\tspin_unlock_irqrestore(&fsl_gc->lock, flags);\n+}\n+\n+static int fsl_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)\n+{\n+\tstruct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);\n+\tstruct fsl_gpio_chip *fsl_gc = to_fsl_gpio_chip(mm_gc);\n+\tstruct fsl_gpio_regs __iomem *regs = mm_gc->regs;\n+\tunsigned long flags;\n+\n+\tspin_lock_irqsave(&fsl_gc->lock, flags);\n+\tclrbits32(&regs->gpdir, pin2mask(gpio));\n+\tspin_unlock_irqrestore(&fsl_gc->lock, flags);\n+\treturn 0;\n+}\n+\n+static int fsl_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio,\n+\t\t\t\tint val)\n+{\n+\tstruct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);\n+\tstruct fsl_gpio_chip *fsl_gc = to_fsl_gpio_chip(mm_gc);\n+\tstruct fsl_gpio_regs __iomem *regs = mm_gc->regs;\n+\tunsigned long flags;\n+\n+\tfsl_gpio_set(gc, gpio, val);\n+\n+\tspin_lock_irqsave(&fsl_gc->lock, flags);\n+\tsetbits32(&regs->gpdir, pin2mask(gpio));\n+\tspin_unlock_irqrestore(&fsl_gc->lock, flags);\n+\treturn 0;\n+}\n+\n+static int __init fsl_gpio_init(void)\n+{\n+\tstruct device_node *np;\n+\n+\tfor_each_compatible_node(np, NULL, \"fsl,mpc8349-gpio-bank\") {\n+\t\tint ret;\n+\t\tstruct fsl_gpio_chip *fsl_gc;\n+\t\tstruct of_mm_gpio_chip *mm_gc;\n+\t\tstruct of_gpio_chip *of_gc;\n+\t\tstruct gpio_chip *gc;\n+\n+\t\tfsl_gc = kzalloc(sizeof(*fsl_gc), GFP_KERNEL);\n+\t\tif (!fsl_gc) {\n+\t\t\tret = -ENOMEM;\n+\t\t\tgoto err;\n+\t\t}\n+\n+\t\tspin_lock_init(&fsl_gc->lock);\n+\n+\t\tmm_gc = &fsl_gc->mm_gc;\n+\t\tof_gc = &mm_gc->of_gc;\n+\t\tgc = &of_gc->gc;\n+\n+\t\tmm_gc->save_regs = fsl_gpio_save_regs;\n+\t\tof_gc->gpio_cells = 2;\n+\t\tgc->ngpio = FSL_GPIO_PINS;\n+\t\tgc->direction_input = fsl_gpio_dir_in;\n+\t\tgc->direction_output = fsl_gpio_dir_out;\n+\t\tgc->get = fsl_gpio_get;\n+\t\tgc->set = fsl_gpio_set;\n+\n+\t\tret = of_mm_gpiochip_add(np, mm_gc);\n+\t\tif (ret)\n+\t\t\tgoto err;\n+\t\tcontinue;\n+err:\n+\t\tpr_err(\"%s: registration failed with status %d\\n\",\n+\t\t       np->full_name, ret);\n+\t\tkfree(fsl_gc);\n+\t\t/* try others anyway */\n+\t}\n+\treturn 0;\n+}\n+arch_initcall(fsl_gpio_init);\n","prefixes":["v2"]}