17b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini/* 27b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini * STMicroelectronics ConneXt (STA2X11) GPIO driver 37b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini * 47b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini * Copyright 2012 ST Microelectronics (Alessandro Rubini) 57b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini * Based on gpio-ml-ioh.c, Copyright 2010 OKI Semiconductors Ltd. 67b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini * Also based on previous sta2x11 work, Copyright 2011 Wind River Systems, Inc. 77b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini * 87b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini * This program is free software; you can redistribute it and/or modify 97b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini * it under the terms of the GNU General Public License version 2 as 107b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini * published by the Free Software Foundation. 117b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini * 127b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini * This program is distributed in the hope that it will be useful, 137b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini * but WITHOUT ANY WARRANTY; without even the implied warranty of 147b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 157b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini * See the GNU General Public License for more details. 167b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini * 177b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini * You should have received a copy of the GNU General Public License 187b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini * along with this program; if not, write to the Free Software 197b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 207b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini * 217b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini */ 227b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 237b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini#include <linux/module.h> 247b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini#include <linux/kernel.h> 257b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini#include <linux/slab.h> 267b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini#include <linux/gpio.h> 277b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini#include <linux/interrupt.h> 287b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini#include <linux/irq.h> 297b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini#include <linux/pci.h> 307b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini#include <linux/platform_device.h> 317b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini#include <linux/mfd/sta2x11-mfd.h> 327b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 337b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubinistruct gsta_regs { 347b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini u32 dat; /* 0x00 */ 357b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini u32 dats; 367b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini u32 datc; 377b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini u32 pdis; 387b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini u32 dir; /* 0x10 */ 397b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini u32 dirs; 407b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini u32 dirc; 417b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini u32 unused_1c; 427b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini u32 afsela; /* 0x20 */ 437b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini u32 unused_24[7]; 447b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini u32 rimsc; /* 0x40 */ 457b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini u32 fimsc; 467b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini u32 is; 477b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini u32 ic; 487b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini}; 497b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 507b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubinistruct gsta_gpio { 517b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini spinlock_t lock; 527b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini struct device *dev; 537b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini void __iomem *reg_base; 547b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini struct gsta_regs __iomem *regs[GSTA_NR_BLOCKS]; 557b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini struct gpio_chip gpio; 567b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini int irq_base; 577b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini /* FIXME: save the whole config here (AF, ...) */ 587b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini unsigned irq_type[GSTA_NR_GPIO]; 597b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini}; 607b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 617b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubinistatic inline struct gsta_regs __iomem *__regs(struct gsta_gpio *chip, int nr) 627b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini{ 637b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini return chip->regs[nr / GSTA_GPIO_PER_BLOCK]; 647b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini} 657b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 667b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubinistatic inline u32 __bit(int nr) 677b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini{ 687b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini return 1U << (nr % GSTA_GPIO_PER_BLOCK); 697b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini} 707b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 717b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini/* 727b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini * gpio methods 737b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini */ 747b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 757b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubinistatic void gsta_gpio_set(struct gpio_chip *gpio, unsigned nr, int val) 767b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini{ 777b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini struct gsta_gpio *chip = container_of(gpio, struct gsta_gpio, gpio); 787b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini struct gsta_regs __iomem *regs = __regs(chip, nr); 797b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini u32 bit = __bit(nr); 807b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 817b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini if (val) 827b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini writel(bit, ®s->dats); 837b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini else 847b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini writel(bit, ®s->datc); 857b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini} 867b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 877b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubinistatic int gsta_gpio_get(struct gpio_chip *gpio, unsigned nr) 887b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini{ 897b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini struct gsta_gpio *chip = container_of(gpio, struct gsta_gpio, gpio); 907b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini struct gsta_regs __iomem *regs = __regs(chip, nr); 917b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini u32 bit = __bit(nr); 927b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 937b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini return readl(®s->dat) & bit; 947b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini} 957b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 967b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubinistatic int gsta_gpio_direction_output(struct gpio_chip *gpio, unsigned nr, 977b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini int val) 987b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini{ 997b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini struct gsta_gpio *chip = container_of(gpio, struct gsta_gpio, gpio); 1007b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini struct gsta_regs __iomem *regs = __regs(chip, nr); 1017b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini u32 bit = __bit(nr); 1027b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 1037b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini writel(bit, ®s->dirs); 1047b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini /* Data register after direction, otherwise pullup/down is selected */ 1057b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini if (val) 1067b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini writel(bit, ®s->dats); 1077b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini else 1087b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini writel(bit, ®s->datc); 1097b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini return 0; 1107b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini} 1117b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 1127b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubinistatic int gsta_gpio_direction_input(struct gpio_chip *gpio, unsigned nr) 1137b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini{ 1147b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini struct gsta_gpio *chip = container_of(gpio, struct gsta_gpio, gpio); 1157b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini struct gsta_regs __iomem *regs = __regs(chip, nr); 1167b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini u32 bit = __bit(nr); 1177b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 1187b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini writel(bit, ®s->dirc); 1197b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini return 0; 1207b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini} 1217b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 1227b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubinistatic int gsta_gpio_to_irq(struct gpio_chip *gpio, unsigned offset) 1237b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini{ 1247b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini struct gsta_gpio *chip = container_of(gpio, struct gsta_gpio, gpio); 1257b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini return chip->irq_base + offset; 1267b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini} 1277b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 1287b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubinistatic void gsta_gpio_setup(struct gsta_gpio *chip) /* called from probe */ 1297b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini{ 1307b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini struct gpio_chip *gpio = &chip->gpio; 1317b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 1327b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini /* 1337b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini * ARCH_NR_GPIOS is currently 256 and dynamic allocation starts 1347b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini * from the end. However, for compatibility, we need the first 1357b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini * ConneXt device to start from gpio 0: it's the main chipset 1367b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini * on most boards so documents and drivers assume gpio0..gpio127 1377b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini */ 1387b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini static int gpio_base; 1397b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 1407b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini gpio->label = dev_name(chip->dev); 1417b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini gpio->owner = THIS_MODULE; 1427b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini gpio->direction_input = gsta_gpio_direction_input; 1437b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini gpio->get = gsta_gpio_get; 1447b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini gpio->direction_output = gsta_gpio_direction_output; 1457b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini gpio->set = gsta_gpio_set; 1467b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini gpio->dbg_show = NULL; 1477b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini gpio->base = gpio_base; 1487b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini gpio->ngpio = GSTA_NR_GPIO; 1499fb1f39eb2d6707d265087ee186376e24995f55aLinus Walleij gpio->can_sleep = false; 1507b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini gpio->to_irq = gsta_gpio_to_irq; 1517b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 1527b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini /* 1537b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini * After the first device, turn to dynamic gpio numbers. 1547b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini * For example, with ARCH_NR_GPIOS = 256 we can fit two cards 1557b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini */ 1567b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini if (!gpio_base) 1577b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini gpio_base = -1; 1587b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini} 1597b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 1607b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini/* 1617b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini * Special method: alternate functions and pullup/pulldown. This is only 1627b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini * invoked on startup to configure gpio's according to platform data. 1637b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini * FIXME : this functionality shall be managed (and exported to other drivers) 1647b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini * via the pin control subsystem. 1657b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini */ 1667b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubinistatic void gsta_set_config(struct gsta_gpio *chip, int nr, unsigned cfg) 1677b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini{ 1687b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini struct gsta_regs __iomem *regs = __regs(chip, nr); 1697b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini unsigned long flags; 1707b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini u32 bit = __bit(nr); 1717b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini u32 val; 1727b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini int err = 0; 1737b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 1747b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini pr_info("%s: %p %i %i\n", __func__, chip, nr, cfg); 1757b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 1767b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini if (cfg == PINMUX_TYPE_NONE) 1777b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini return; 1787b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 1797b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini /* Alternate function or not? */ 1807b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini spin_lock_irqsave(&chip->lock, flags); 1817b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini val = readl(®s->afsela); 1827b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini if (cfg == PINMUX_TYPE_FUNCTION) 1837b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini val |= bit; 1847b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini else 1857b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini val &= ~bit; 1867b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini writel(val | bit, ®s->afsela); 1877b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini if (cfg == PINMUX_TYPE_FUNCTION) { 1887b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini spin_unlock_irqrestore(&chip->lock, flags); 1897b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini return; 1907b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini } 1917b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 1927b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini /* not alternate function: set details */ 1937b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini switch (cfg) { 1947b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini case PINMUX_TYPE_OUTPUT_LOW: 1957b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini writel(bit, ®s->dirs); 1967b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini writel(bit, ®s->datc); 1977b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini break; 1987b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini case PINMUX_TYPE_OUTPUT_HIGH: 1997b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini writel(bit, ®s->dirs); 2007b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini writel(bit, ®s->dats); 2017b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini break; 2027b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini case PINMUX_TYPE_INPUT: 2037b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini writel(bit, ®s->dirc); 2047b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini val = readl(®s->pdis) | bit; 2057b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini writel(val, ®s->pdis); 2067b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini break; 2077b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini case PINMUX_TYPE_INPUT_PULLUP: 2087b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini writel(bit, ®s->dirc); 2097b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini val = readl(®s->pdis) & ~bit; 2107b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini writel(val, ®s->pdis); 2117b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini writel(bit, ®s->dats); 2127b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini break; 2137b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini case PINMUX_TYPE_INPUT_PULLDOWN: 2147b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini writel(bit, ®s->dirc); 2157b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini val = readl(®s->pdis) & ~bit; 2167b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini writel(val, ®s->pdis); 2177b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini writel(bit, ®s->datc); 2187b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini break; 2197b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini default: 2207b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini err = 1; 2217b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini } 2227b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini spin_unlock_irqrestore(&chip->lock, flags); 2237b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini if (err) 2247b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini pr_err("%s: chip %p, pin %i, cfg %i is invalid\n", 2257b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini __func__, chip, nr, cfg); 2267b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini} 2277b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 2287b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini/* 2297b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini * Irq methods 2307b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini */ 2317b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 2327b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubinistatic void gsta_irq_disable(struct irq_data *data) 2337b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini{ 2347b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data); 2357b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini struct gsta_gpio *chip = gc->private; 2367b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini int nr = data->irq - chip->irq_base; 2377b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini struct gsta_regs __iomem *regs = __regs(chip, nr); 2387b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini u32 bit = __bit(nr); 2397b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini u32 val; 2407b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini unsigned long flags; 2417b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 2427b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini spin_lock_irqsave(&chip->lock, flags); 2437b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini if (chip->irq_type[nr] & IRQ_TYPE_EDGE_RISING) { 2447b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini val = readl(®s->rimsc) & ~bit; 2457b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini writel(val, ®s->rimsc); 2467b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini } 2477b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini if (chip->irq_type[nr] & IRQ_TYPE_EDGE_FALLING) { 2487b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini val = readl(®s->fimsc) & ~bit; 2497b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini writel(val, ®s->fimsc); 2507b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini } 2517b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini spin_unlock_irqrestore(&chip->lock, flags); 2527b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini return; 2537b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini} 2547b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 2557b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubinistatic void gsta_irq_enable(struct irq_data *data) 2567b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini{ 2577b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data); 2587b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini struct gsta_gpio *chip = gc->private; 2597b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini int nr = data->irq - chip->irq_base; 2607b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini struct gsta_regs __iomem *regs = __regs(chip, nr); 2617b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini u32 bit = __bit(nr); 2627b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini u32 val; 2637b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini int type; 2647b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini unsigned long flags; 2657b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 2667b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini type = chip->irq_type[nr]; 2677b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 2687b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini spin_lock_irqsave(&chip->lock, flags); 2697b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini val = readl(®s->rimsc); 2707b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini if (type & IRQ_TYPE_EDGE_RISING) 2717b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini writel(val | bit, ®s->rimsc); 2727b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini else 2737b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini writel(val & ~bit, ®s->rimsc); 2747b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini val = readl(®s->rimsc); 2757b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini if (type & IRQ_TYPE_EDGE_FALLING) 2767b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini writel(val | bit, ®s->fimsc); 2777b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini else 2787b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini writel(val & ~bit, ®s->fimsc); 2797b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini spin_unlock_irqrestore(&chip->lock, flags); 2807b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini return; 2817b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini} 2827b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 2837b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubinistatic int gsta_irq_type(struct irq_data *d, unsigned int type) 2847b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini{ 2857b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 2867b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini struct gsta_gpio *chip = gc->private; 2877b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini int nr = d->irq - chip->irq_base; 2887b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 2897b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini /* We only support edge interrupts */ 2907b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini if (!(type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))) { 2917b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini pr_debug("%s: unsupported type 0x%x\n", __func__, type); 2927b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini return -EINVAL; 2937b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini } 2947b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 2957b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini chip->irq_type[nr] = type; /* used for enable/disable */ 2967b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 2977b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini gsta_irq_enable(d); 2987b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini return 0; 2997b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini} 3007b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 3017b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubinistatic irqreturn_t gsta_gpio_handler(int irq, void *dev_id) 3027b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini{ 3037b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini struct gsta_gpio *chip = dev_id; 3047b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini struct gsta_regs __iomem *regs; 3057b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini u32 is; 3067b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini int i, nr, base; 3077b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini irqreturn_t ret = IRQ_NONE; 3087b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 3097b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini for (i = 0; i < GSTA_NR_BLOCKS; i++) { 3107b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini regs = chip->regs[i]; 3117b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini base = chip->irq_base + i * GSTA_GPIO_PER_BLOCK; 3127b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini while ((is = readl(®s->is))) { 3137b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini nr = __ffs(is); 3147b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini irq = base + nr; 3157b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini generic_handle_irq(irq); 3167b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini writel(1 << nr, ®s->ic); 3177b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini ret = IRQ_HANDLED; 3187b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini } 3197b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini } 3207b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini return ret; 3217b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini} 3227b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 3233836309d93462bbf34851c078be6e5e77d888e3dBill Pembertonstatic void gsta_alloc_irq_chip(struct gsta_gpio *chip) 3247b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini{ 3257b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini struct irq_chip_generic *gc; 3267b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini struct irq_chip_type *ct; 3277b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 3287b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini gc = irq_alloc_generic_chip(KBUILD_MODNAME, 1, chip->irq_base, 3297b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini chip->reg_base, handle_simple_irq); 3307b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini gc->private = chip; 3317b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini ct = gc->chip_types; 3327b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 3337b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini ct->chip.irq_set_type = gsta_irq_type; 3347b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini ct->chip.irq_disable = gsta_irq_disable; 3357b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini ct->chip.irq_enable = gsta_irq_enable; 3367b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 3377b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini /* FIXME: this makes at most 32 interrupts. Request 0 by now */ 3387b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini irq_setup_generic_chip(gc, 0 /* IRQ_MSK(GSTA_GPIO_PER_BLOCK) */, 0, 3397b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini IRQ_NOREQUEST | IRQ_NOPROBE, 0); 3407b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 3417b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini /* Set up all all 128 interrupts: code from setup_generic_chip */ 3427b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini { 3437b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini struct irq_chip_type *ct = gc->chip_types; 3447b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini int i, j; 3457b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini for (j = 0; j < GSTA_NR_GPIO; j++) { 3467b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini i = chip->irq_base + j; 3477b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini irq_set_chip_and_handler(i, &ct->chip, ct->handler); 3487b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini irq_set_chip_data(i, gc); 3497b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini irq_modify_status(i, IRQ_NOREQUEST | IRQ_NOPROBE, 0); 3507b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini } 3517b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini gc->irq_cnt = i - gc->irq_base; 3527b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini } 3537b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini} 3547b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 3557b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini/* The platform device used here is instantiated by the MFD device */ 3563836309d93462bbf34851c078be6e5e77d888e3dBill Pembertonstatic int gsta_probe(struct platform_device *dev) 3577b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini{ 3587b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini int i, err; 3597b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini struct pci_dev *pdev; 3607b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini struct sta2x11_gpio_pdata *gpio_pdata; 3617b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini struct gsta_gpio *chip; 3627b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini struct resource *res; 3637b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 364e56aee1897fd27631c1cb28e12b0fb8f8f9736f7Jingoo Han pdev = *(struct pci_dev **)dev_get_platdata(&dev->dev); 3657b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini gpio_pdata = dev_get_platdata(&pdev->dev); 3667b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 3677b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini if (gpio_pdata == NULL) 3687b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini dev_err(&dev->dev, "no gpio config\n"); 3697b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini pr_debug("gpio config: %p\n", gpio_pdata); 3707b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 3717b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini res = platform_get_resource(dev, IORESOURCE_MEM, 0); 3727b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 3737b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini chip = devm_kzalloc(&dev->dev, sizeof(*chip), GFP_KERNEL); 374cd73891647a19f4b52f23d23f5c68175b93b56feSachin Kamat if (!chip) 375cd73891647a19f4b52f23d23f5c68175b93b56feSachin Kamat return -ENOMEM; 3767b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini chip->dev = &dev->dev; 37762ffac141e82334ed0065c118b0544e23f3f5243Tushar Behera chip->reg_base = devm_ioremap_resource(&dev->dev, res); 37862ffac141e82334ed0065c118b0544e23f3f5243Tushar Behera if (IS_ERR(chip->reg_base)) 37962ffac141e82334ed0065c118b0544e23f3f5243Tushar Behera return PTR_ERR(chip->reg_base); 3807b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 3817b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini for (i = 0; i < GSTA_NR_BLOCKS; i++) { 3827b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini chip->regs[i] = chip->reg_base + i * 4096; 3837b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini /* disable all irqs */ 3847b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini writel(0, &chip->regs[i]->rimsc); 3857b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini writel(0, &chip->regs[i]->fimsc); 3867b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini writel(~0, &chip->regs[i]->ic); 3877b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini } 3887b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini spin_lock_init(&chip->lock); 3897b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini gsta_gpio_setup(chip); 3902e2070c85aa19f6c5bb3642a1429abf42f101e8dAlessandro Rubini if (gpio_pdata) 3912e2070c85aa19f6c5bb3642a1429abf42f101e8dAlessandro Rubini for (i = 0; i < GSTA_NR_GPIO; i++) 3922e2070c85aa19f6c5bb3642a1429abf42f101e8dAlessandro Rubini gsta_set_config(chip, i, gpio_pdata->pinconfig[i]); 3937b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 3947b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini /* 384 was used in previous code: be compatible for other drivers */ 3957b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini err = irq_alloc_descs(-1, 384, GSTA_NR_GPIO, NUMA_NO_NODE); 3967b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini if (err < 0) { 3977b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini dev_warn(&dev->dev, "sta2x11 gpio: Can't get irq base (%i)\n", 3987b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini -err); 3997b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini return err; 4007b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini } 4017b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini chip->irq_base = err; 4027b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini gsta_alloc_irq_chip(chip); 4037b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 4047b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini err = request_irq(pdev->irq, gsta_gpio_handler, 4057b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini IRQF_SHARED, KBUILD_MODNAME, chip); 4067b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini if (err < 0) { 4077b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini dev_err(&dev->dev, "sta2x11 gpio: Can't request irq (%i)\n", 4087b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini -err); 4097b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini goto err_free_descs; 4107b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini } 4117b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 4127b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini err = gpiochip_add(&chip->gpio); 4137b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini if (err < 0) { 4147b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini dev_err(&dev->dev, "sta2x11 gpio: Can't register (%i)\n", 4157b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini -err); 4167b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini goto err_free_irq; 4177b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini } 4187b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 4197b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini platform_set_drvdata(dev, chip); 4207b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini return 0; 4217b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 4227b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubinierr_free_irq: 4237b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini free_irq(pdev->irq, chip); 4247b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubinierr_free_descs: 4257b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini irq_free_descs(chip->irq_base, GSTA_NR_GPIO); 4267b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini return err; 4277b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini} 4287b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 4297b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubinistatic struct platform_driver sta2x11_gpio_platform_driver = { 4307b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini .driver = { 4317b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini .name = "sta2x11-gpio", 4327b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini .owner = THIS_MODULE, 4337b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini }, 4347b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini .probe = gsta_probe, 4357b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini}; 4367b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 4377b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubinimodule_platform_driver(sta2x11_gpio_platform_driver); 4387b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro Rubini 4397b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro RubiniMODULE_LICENSE("GPL v2"); 4407b0d44f3b7cec0ae6f5e81d18df4a4077bbabb7cAlessandro RubiniMODULE_DESCRIPTION("sta2x11_gpio GPIO driver"); 441