1/* 2 * Toumaz Xenif TZ1090 PDC GPIO handling. 3 * 4 * Copyright (C) 2012-2013 Imagination Technologies Ltd. 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 as 8 * published by the Free Software Foundation. 9 */ 10 11#include <linux/bitops.h> 12#include <linux/gpio.h> 13#include <linux/io.h> 14#include <linux/module.h> 15#include <linux/of_irq.h> 16#include <linux/pinctrl/consumer.h> 17#include <linux/platform_device.h> 18#include <linux/slab.h> 19#include <linux/syscore_ops.h> 20#include <asm/global_lock.h> 21 22/* Register offsets from SOC_GPIO_CONTROL0 */ 23#define REG_SOC_GPIO_CONTROL0 0x00 24#define REG_SOC_GPIO_CONTROL1 0x04 25#define REG_SOC_GPIO_CONTROL2 0x08 26#define REG_SOC_GPIO_CONTROL3 0x0c 27#define REG_SOC_GPIO_STATUS 0x80 28 29/* PDC GPIOs go after normal GPIOs */ 30#define GPIO_PDC_BASE 90 31#define GPIO_PDC_NGPIO 7 32 33/* Out of PDC gpios, only syswakes have irqs */ 34#define GPIO_PDC_IRQ_FIRST 2 35#define GPIO_PDC_NIRQ 3 36 37/** 38 * struct tz1090_pdc_gpio - GPIO bank private data 39 * @chip: Generic GPIO chip for GPIO bank 40 * @reg: Base of registers, offset for this GPIO bank 41 * @irq: IRQ numbers for Syswake GPIOs 42 * 43 * This is the main private data for the PDC GPIO driver. It encapsulates a 44 * gpio_chip, and the callbacks for the gpio_chip can access the private data 45 * with the to_pdc() macro below. 46 */ 47struct tz1090_pdc_gpio { 48 struct gpio_chip chip; 49 void __iomem *reg; 50 int irq[GPIO_PDC_NIRQ]; 51}; 52#define to_pdc(c) container_of(c, struct tz1090_pdc_gpio, chip) 53 54/* Register accesses into the PDC MMIO area */ 55 56static inline void pdc_write(struct tz1090_pdc_gpio *priv, unsigned int reg_offs, 57 unsigned int data) 58{ 59 writel(data, priv->reg + reg_offs); 60} 61 62static inline unsigned int pdc_read(struct tz1090_pdc_gpio *priv, 63 unsigned int reg_offs) 64{ 65 return readl(priv->reg + reg_offs); 66} 67 68/* Generic GPIO interface */ 69 70static int tz1090_pdc_gpio_direction_input(struct gpio_chip *chip, 71 unsigned int offset) 72{ 73 struct tz1090_pdc_gpio *priv = to_pdc(chip); 74 u32 value; 75 int lstat; 76 77 __global_lock2(lstat); 78 value = pdc_read(priv, REG_SOC_GPIO_CONTROL1); 79 value |= BIT(offset); 80 pdc_write(priv, REG_SOC_GPIO_CONTROL1, value); 81 __global_unlock2(lstat); 82 83 return 0; 84} 85 86static int tz1090_pdc_gpio_direction_output(struct gpio_chip *chip, 87 unsigned int offset, 88 int output_value) 89{ 90 struct tz1090_pdc_gpio *priv = to_pdc(chip); 91 u32 value; 92 int lstat; 93 94 __global_lock2(lstat); 95 /* EXT_POWER doesn't seem to have an output value bit */ 96 if (offset < 6) { 97 value = pdc_read(priv, REG_SOC_GPIO_CONTROL0); 98 if (output_value) 99 value |= BIT(offset); 100 else 101 value &= ~BIT(offset); 102 pdc_write(priv, REG_SOC_GPIO_CONTROL0, value); 103 } 104 105 value = pdc_read(priv, REG_SOC_GPIO_CONTROL1); 106 value &= ~BIT(offset); 107 pdc_write(priv, REG_SOC_GPIO_CONTROL1, value); 108 __global_unlock2(lstat); 109 110 return 0; 111} 112 113static int tz1090_pdc_gpio_get(struct gpio_chip *chip, unsigned int offset) 114{ 115 struct tz1090_pdc_gpio *priv = to_pdc(chip); 116 return pdc_read(priv, REG_SOC_GPIO_STATUS) & BIT(offset); 117} 118 119static void tz1090_pdc_gpio_set(struct gpio_chip *chip, unsigned int offset, 120 int output_value) 121{ 122 struct tz1090_pdc_gpio *priv = to_pdc(chip); 123 u32 value; 124 int lstat; 125 126 /* EXT_POWER doesn't seem to have an output value bit */ 127 if (offset >= 6) 128 return; 129 130 __global_lock2(lstat); 131 value = pdc_read(priv, REG_SOC_GPIO_CONTROL0); 132 if (output_value) 133 value |= BIT(offset); 134 else 135 value &= ~BIT(offset); 136 pdc_write(priv, REG_SOC_GPIO_CONTROL0, value); 137 __global_unlock2(lstat); 138} 139 140static int tz1090_pdc_gpio_to_irq(struct gpio_chip *chip, unsigned int offset) 141{ 142 struct tz1090_pdc_gpio *priv = to_pdc(chip); 143 unsigned int syswake = offset - GPIO_PDC_IRQ_FIRST; 144 int irq; 145 146 /* only syswakes have irqs */ 147 if (syswake >= GPIO_PDC_NIRQ) 148 return -EINVAL; 149 150 irq = priv->irq[syswake]; 151 if (!irq) 152 return -EINVAL; 153 154 return irq; 155} 156 157static int tz1090_pdc_gpio_probe(struct platform_device *pdev) 158{ 159 struct device_node *np = pdev->dev.of_node; 160 struct resource *res_regs; 161 struct tz1090_pdc_gpio *priv; 162 unsigned int i; 163 164 if (!np) { 165 dev_err(&pdev->dev, "must be instantiated via devicetree\n"); 166 return -ENOENT; 167 } 168 169 res_regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 170 if (!res_regs) { 171 dev_err(&pdev->dev, "cannot find registers resource\n"); 172 return -ENOENT; 173 } 174 175 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 176 if (!priv) { 177 dev_err(&pdev->dev, "unable to allocate driver data\n"); 178 return -ENOMEM; 179 } 180 181 /* Ioremap the registers */ 182 priv->reg = devm_ioremap(&pdev->dev, res_regs->start, 183 resource_size(res_regs)); 184 if (!priv->reg) { 185 dev_err(&pdev->dev, "unable to ioremap registers\n"); 186 return -ENOMEM; 187 } 188 189 /* Set up GPIO chip */ 190 priv->chip.label = "tz1090-pdc-gpio"; 191 priv->chip.dev = &pdev->dev; 192 priv->chip.direction_input = tz1090_pdc_gpio_direction_input; 193 priv->chip.direction_output = tz1090_pdc_gpio_direction_output; 194 priv->chip.get = tz1090_pdc_gpio_get; 195 priv->chip.set = tz1090_pdc_gpio_set; 196 priv->chip.free = gpiochip_generic_free; 197 priv->chip.request = gpiochip_generic_request; 198 priv->chip.to_irq = tz1090_pdc_gpio_to_irq; 199 priv->chip.of_node = np; 200 201 /* GPIO numbering */ 202 priv->chip.base = GPIO_PDC_BASE; 203 priv->chip.ngpio = GPIO_PDC_NGPIO; 204 205 /* Map the syswake irqs */ 206 for (i = 0; i < GPIO_PDC_NIRQ; ++i) 207 priv->irq[i] = irq_of_parse_and_map(np, i); 208 209 /* Add the GPIO bank */ 210 gpiochip_add(&priv->chip); 211 212 return 0; 213} 214 215static struct of_device_id tz1090_pdc_gpio_of_match[] = { 216 { .compatible = "img,tz1090-pdc-gpio" }, 217 { }, 218}; 219 220static struct platform_driver tz1090_pdc_gpio_driver = { 221 .driver = { 222 .name = "tz1090-pdc-gpio", 223 .of_match_table = tz1090_pdc_gpio_of_match, 224 }, 225 .probe = tz1090_pdc_gpio_probe, 226}; 227 228static int __init tz1090_pdc_gpio_init(void) 229{ 230 return platform_driver_register(&tz1090_pdc_gpio_driver); 231} 232subsys_initcall(tz1090_pdc_gpio_init); 233