Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

GPIO: add new Xilinx driver for powerpc

This driver supports the Xilinx XPS GPIO IP core which has the typical
GPIO features.

Signed-off-by: Kiran Sutariya <kirans@xilinx.com>
Signed-off-by: John Linn <john.linn@xilinx.com>
Cc: David Brownell <david-b@pacbell.net>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Kumar Gala <galak@gate.crashing.org>
Cc: "Grant Likely" <grant.likely@secretlab.ca>
Cc: <avorontsov@ru.mvista.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

John Linn and committed by
Linus Torvalds
0bcb6069 e33c3b5e

+244
+8
drivers/gpio/Kconfig
··· 65 65 66 66 # put expanders in the right section, in alphabetical order 67 67 68 + comment "Memory mapped GPIO expanders:" 69 + 70 + config GPIO_XILINX 71 + bool "Xilinx GPIO support" 72 + depends on PPC_OF 73 + help 74 + Say yes here to support the Xilinx FPGA GPIO device 75 + 68 76 comment "I2C GPIO expanders:" 69 77 70 78 config GPIO_MAX732X
+1
drivers/gpio/Makefile
··· 10 10 obj-$(CONFIG_GPIO_PCA953X) += pca953x.o 11 11 obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o 12 12 obj-$(CONFIG_GPIO_TWL4030) += twl4030-gpio.o 13 + obj-$(CONFIG_GPIO_XILINX) += xilinx_gpio.o 13 14 obj-$(CONFIG_GPIO_BT8XX) += bt8xxgpio.o
+235
drivers/gpio/xilinx_gpio.c
··· 1 + /* 2 + * Xilinx gpio driver 3 + * 4 + * Copyright 2008 Xilinx, Inc. 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 8 + * as published by the Free Software Foundation. 9 + * 10 + * You should have received a copy of the GNU General Public License 11 + * along with this program; if not, write to the Free Software 12 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 13 + */ 14 + 15 + #include <linux/init.h> 16 + #include <linux/errno.h> 17 + #include <linux/of_device.h> 18 + #include <linux/of_platform.h> 19 + #include <linux/of_gpio.h> 20 + #include <linux/io.h> 21 + #include <linux/gpio.h> 22 + 23 + /* Register Offset Definitions */ 24 + #define XGPIO_DATA_OFFSET (0x0) /* Data register */ 25 + #define XGPIO_TRI_OFFSET (0x4) /* I/O direction register */ 26 + 27 + struct xgpio_instance { 28 + struct of_mm_gpio_chip mmchip; 29 + u32 gpio_state; /* GPIO state shadow register */ 30 + u32 gpio_dir; /* GPIO direction shadow register */ 31 + spinlock_t gpio_lock; /* Lock used for synchronization */ 32 + }; 33 + 34 + /** 35 + * xgpio_get - Read the specified signal of the GPIO device. 36 + * @gc: Pointer to gpio_chip device structure. 37 + * @gpio: GPIO signal number. 38 + * 39 + * This function reads the specified signal of the GPIO device. It returns 0 if 40 + * the signal clear, 1 if signal is set or negative value on error. 41 + */ 42 + static int xgpio_get(struct gpio_chip *gc, unsigned int gpio) 43 + { 44 + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 45 + 46 + return (in_be32(mm_gc->regs + XGPIO_DATA_OFFSET) >> gpio) & 1; 47 + } 48 + 49 + /** 50 + * xgpio_set - Write the specified signal of the GPIO device. 51 + * @gc: Pointer to gpio_chip device structure. 52 + * @gpio: GPIO signal number. 53 + * @val: Value to be written to specified signal. 54 + * 55 + * This function writes the specified value in to the specified signal of the 56 + * GPIO device. 57 + */ 58 + static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val) 59 + { 60 + unsigned long flags; 61 + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 62 + struct xgpio_instance *chip = 63 + container_of(mm_gc, struct xgpio_instance, mmchip); 64 + 65 + spin_lock_irqsave(&chip->gpio_lock, flags); 66 + 67 + /* Write to GPIO signal and set its direction to output */ 68 + if (val) 69 + chip->gpio_state |= 1 << gpio; 70 + else 71 + chip->gpio_state &= ~(1 << gpio); 72 + out_be32(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state); 73 + 74 + spin_unlock_irqrestore(&chip->gpio_lock, flags); 75 + } 76 + 77 + /** 78 + * xgpio_dir_in - Set the direction of the specified GPIO signal as input. 79 + * @gc: Pointer to gpio_chip device structure. 80 + * @gpio: GPIO signal number. 81 + * 82 + * This function sets the direction of specified GPIO signal as input. 83 + * It returns 0 if direction of GPIO signals is set as input otherwise it 84 + * returns negative error value. 85 + */ 86 + static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio) 87 + { 88 + unsigned long flags; 89 + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 90 + struct xgpio_instance *chip = 91 + container_of(mm_gc, struct xgpio_instance, mmchip); 92 + 93 + spin_lock_irqsave(&chip->gpio_lock, flags); 94 + 95 + /* Set the GPIO bit in shadow register and set direction as input */ 96 + chip->gpio_dir |= (1 << gpio); 97 + out_be32(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir); 98 + 99 + spin_unlock_irqrestore(&chip->gpio_lock, flags); 100 + 101 + return 0; 102 + } 103 + 104 + /** 105 + * xgpio_dir_out - Set the direction of the specified GPIO signal as output. 106 + * @gc: Pointer to gpio_chip device structure. 107 + * @gpio: GPIO signal number. 108 + * @val: Value to be written to specified signal. 109 + * 110 + * This function sets the direction of specified GPIO signal as output. If all 111 + * GPIO signals of GPIO chip is configured as input then it returns 112 + * error otherwise it returns 0. 113 + */ 114 + static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) 115 + { 116 + unsigned long flags; 117 + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); 118 + struct xgpio_instance *chip = 119 + container_of(mm_gc, struct xgpio_instance, mmchip); 120 + 121 + spin_lock_irqsave(&chip->gpio_lock, flags); 122 + 123 + /* Write state of GPIO signal */ 124 + if (val) 125 + chip->gpio_state |= 1 << gpio; 126 + else 127 + chip->gpio_state &= ~(1 << gpio); 128 + out_be32(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state); 129 + 130 + /* Clear the GPIO bit in shadow register and set direction as output */ 131 + chip->gpio_dir &= (~(1 << gpio)); 132 + out_be32(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir); 133 + 134 + spin_unlock_irqrestore(&chip->gpio_lock, flags); 135 + 136 + return 0; 137 + } 138 + 139 + /** 140 + * xgpio_save_regs - Set initial values of GPIO pins 141 + * @mm_gc: pointer to memory mapped GPIO chip structure 142 + */ 143 + static void xgpio_save_regs(struct of_mm_gpio_chip *mm_gc) 144 + { 145 + struct xgpio_instance *chip = 146 + container_of(mm_gc, struct xgpio_instance, mmchip); 147 + 148 + out_be32(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state); 149 + out_be32(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir); 150 + } 151 + 152 + /** 153 + * xgpio_of_probe - Probe method for the GPIO device. 154 + * @np: pointer to device tree node 155 + * 156 + * This function probes the GPIO device in the device tree. It initializes the 157 + * driver data structure. It returns 0, if the driver is bound to the GPIO 158 + * device, or a negative value if there is an error. 159 + */ 160 + static int __devinit xgpio_of_probe(struct device_node *np) 161 + { 162 + struct xgpio_instance *chip; 163 + struct of_gpio_chip *ofchip; 164 + int status = 0; 165 + const u32 *tree_info; 166 + 167 + chip = kzalloc(sizeof(*chip), GFP_KERNEL); 168 + if (!chip) 169 + return -ENOMEM; 170 + ofchip = &chip->mmchip.of_gc; 171 + 172 + /* Update GPIO state shadow register with default value */ 173 + tree_info = of_get_property(np, "xlnx,dout-default", NULL); 174 + if (tree_info) 175 + chip->gpio_state = *tree_info; 176 + 177 + /* Update GPIO direction shadow register with default value */ 178 + chip->gpio_dir = 0xFFFFFFFF; /* By default, all pins are inputs */ 179 + tree_info = of_get_property(np, "xlnx,tri-default", NULL); 180 + if (tree_info) 181 + chip->gpio_dir = *tree_info; 182 + 183 + /* Check device node and parent device node for device width */ 184 + ofchip->gc.ngpio = 32; /* By default assume full GPIO controller */ 185 + tree_info = of_get_property(np, "xlnx,gpio-width", NULL); 186 + if (!tree_info) 187 + tree_info = of_get_property(np->parent, 188 + "xlnx,gpio-width", NULL); 189 + if (tree_info) 190 + ofchip->gc.ngpio = *tree_info; 191 + 192 + spin_lock_init(&chip->gpio_lock); 193 + 194 + ofchip->gpio_cells = 2; 195 + ofchip->gc.direction_input = xgpio_dir_in; 196 + ofchip->gc.direction_output = xgpio_dir_out; 197 + ofchip->gc.get = xgpio_get; 198 + ofchip->gc.set = xgpio_set; 199 + 200 + chip->mmchip.save_regs = xgpio_save_regs; 201 + 202 + /* Call the OF gpio helper to setup and register the GPIO device */ 203 + status = of_mm_gpiochip_add(np, &chip->mmchip); 204 + if (status) { 205 + kfree(chip); 206 + pr_err("%s: error in probe function with status %d\n", 207 + np->full_name, status); 208 + return status; 209 + } 210 + pr_info("XGpio: %s: registered\n", np->full_name); 211 + return 0; 212 + } 213 + 214 + static struct of_device_id xgpio_of_match[] __devinitdata = { 215 + { .compatible = "xlnx,xps-gpio-1.00.a", }, 216 + { /* end of list */ }, 217 + }; 218 + 219 + static int __init xgpio_init(void) 220 + { 221 + struct device_node *np; 222 + 223 + for_each_matching_node(np, xgpio_of_match) 224 + xgpio_of_probe(np); 225 + 226 + return 0; 227 + } 228 + 229 + /* Make sure we get initialized before anyone else tries to use us */ 230 + subsys_initcall(xgpio_init); 231 + /* No exit call at the moment as we cannot unregister of GPIO chips */ 232 + 233 + MODULE_AUTHOR("Xilinx, Inc."); 234 + MODULE_DESCRIPTION("Xilinx GPIO driver"); 235 + MODULE_LICENSE("GPL");