1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2015-2018 Pengutronix, Uwe Kleine-König <kernel@pengutronix.de> 4 */ 5 6 #include <linux/module.h> 7 #include <linux/siox.h> 8 #include <linux/gpio/driver.h> 9 #include <linux/of.h> 10 11 struct gpio_siox_ddata { 12 struct gpio_chip gchip; 13 struct irq_chip ichip; 14 struct mutex lock; 15 u8 setdata[1]; 16 u8 getdata[3]; 17 18 spinlock_t irqlock; 19 u32 irq_enable; 20 u32 irq_status; 21 u32 irq_type[20]; 22 }; 23 24 /* 25 * Note that this callback only sets the value that is clocked out in the next 26 * cycle. 27 */ 28 static int gpio_siox_set_data(struct siox_device *sdevice, u8 status, u8 buf[]) 29 { 30 struct gpio_siox_ddata *ddata = dev_get_drvdata(&sdevice->dev); 31 32 mutex_lock(&ddata->lock); 33 buf[0] = ddata->setdata[0]; 34 mutex_unlock(&ddata->lock); 35 36 return 0; 37 } 38 39 static int gpio_siox_get_data(struct siox_device *sdevice, const u8 buf[]) 40 { 41 struct gpio_siox_ddata *ddata = dev_get_drvdata(&sdevice->dev); 42 size_t offset; 43 u32 trigger; 44 45 mutex_lock(&ddata->lock); 46 47 spin_lock_irq(&ddata->irqlock); 48 49 for (offset = 0; offset < 12; ++offset) { 50 unsigned int bitpos = 11 - offset; 51 unsigned int gpiolevel = buf[bitpos / 8] & (1 << bitpos % 8); 52 unsigned int prev_level = 53 ddata->getdata[bitpos / 8] & (1 << (bitpos % 8)); 54 u32 irq_type = ddata->irq_type[offset]; 55 56 if (gpiolevel) { 57 if ((irq_type & IRQ_TYPE_LEVEL_HIGH) || 58 ((irq_type & IRQ_TYPE_EDGE_RISING) && !prev_level)) 59 ddata->irq_status |= 1 << offset; 60 } else { 61 if ((irq_type & IRQ_TYPE_LEVEL_LOW) || 62 ((irq_type & IRQ_TYPE_EDGE_FALLING) && prev_level)) 63 ddata->irq_status |= 1 << offset; 64 } 65 } 66 67 trigger = ddata->irq_status & ddata->irq_enable; 68 69 spin_unlock_irq(&ddata->irqlock); 70 71 ddata->getdata[0] = buf[0]; 72 ddata->getdata[1] = buf[1]; 73 ddata->getdata[2] = buf[2]; 74 75 mutex_unlock(&ddata->lock); 76 77 for (offset = 0; offset < 12; ++offset) { 78 if (trigger & (1 << offset)) { 79 struct irq_domain *irqdomain = ddata->gchip.irq.domain; 80 unsigned int irq = irq_find_mapping(irqdomain, offset); 81 82 /* 83 * Conceptually handle_nested_irq should call the flow 84 * handler of the irq chip. But it doesn't, so we have 85 * to clean the irq_status here. 86 */ 87 spin_lock_irq(&ddata->irqlock); 88 ddata->irq_status &= ~(1 << offset); 89 spin_unlock_irq(&ddata->irqlock); 90 91 handle_nested_irq(irq); 92 } 93 } 94 95 return 0; 96 } 97 98 static void gpio_siox_irq_ack(struct irq_data *d) 99 { 100 struct irq_chip *ic = irq_data_get_irq_chip(d); 101 struct gpio_siox_ddata *ddata = 102 container_of(ic, struct gpio_siox_ddata, ichip); 103 104 spin_lock_irq(&ddata->irqlock); 105 ddata->irq_status &= ~(1 << d->hwirq); 106 spin_unlock_irq(&ddata->irqlock); 107 } 108 109 static void gpio_siox_irq_mask(struct irq_data *d) 110 { 111 struct irq_chip *ic = irq_data_get_irq_chip(d); 112 struct gpio_siox_ddata *ddata = 113 container_of(ic, struct gpio_siox_ddata, ichip); 114 115 spin_lock_irq(&ddata->irqlock); 116 ddata->irq_enable &= ~(1 << d->hwirq); 117 spin_unlock_irq(&ddata->irqlock); 118 } 119 120 static void gpio_siox_irq_unmask(struct irq_data *d) 121 { 122 struct irq_chip *ic = irq_data_get_irq_chip(d); 123 struct gpio_siox_ddata *ddata = 124 container_of(ic, struct gpio_siox_ddata, ichip); 125 126 spin_lock_irq(&ddata->irqlock); 127 ddata->irq_enable |= 1 << d->hwirq; 128 spin_unlock_irq(&ddata->irqlock); 129 } 130 131 static int gpio_siox_irq_set_type(struct irq_data *d, u32 type) 132 { 133 struct irq_chip *ic = irq_data_get_irq_chip(d); 134 struct gpio_siox_ddata *ddata = 135 container_of(ic, struct gpio_siox_ddata, ichip); 136 137 spin_lock_irq(&ddata->irqlock); 138 ddata->irq_type[d->hwirq] = type; 139 spin_unlock_irq(&ddata->irqlock); 140 141 return 0; 142 } 143 144 static int gpio_siox_get(struct gpio_chip *chip, unsigned int offset) 145 { 146 struct gpio_siox_ddata *ddata = 147 container_of(chip, struct gpio_siox_ddata, gchip); 148 int ret; 149 150 mutex_lock(&ddata->lock); 151 152 if (offset >= 12) { 153 unsigned int bitpos = 19 - offset; 154 155 ret = ddata->setdata[0] & (1 << bitpos); 156 } else { 157 unsigned int bitpos = 11 - offset; 158 159 ret = ddata->getdata[bitpos / 8] & (1 << (bitpos % 8)); 160 } 161 162 mutex_unlock(&ddata->lock); 163 164 return ret; 165 } 166 167 static void gpio_siox_set(struct gpio_chip *chip, 168 unsigned int offset, int value) 169 { 170 struct gpio_siox_ddata *ddata = 171 container_of(chip, struct gpio_siox_ddata, gchip); 172 u8 mask = 1 << (19 - offset); 173 174 mutex_lock(&ddata->lock); 175 176 if (value) 177 ddata->setdata[0] |= mask; 178 else 179 ddata->setdata[0] &= ~mask; 180 181 mutex_unlock(&ddata->lock); 182 } 183 184 static int gpio_siox_direction_input(struct gpio_chip *chip, 185 unsigned int offset) 186 { 187 if (offset >= 12) 188 return -EINVAL; 189 190 return 0; 191 } 192 193 static int gpio_siox_direction_output(struct gpio_chip *chip, 194 unsigned int offset, int value) 195 { 196 if (offset < 12) 197 return -EINVAL; 198 199 gpio_siox_set(chip, offset, value); 200 return 0; 201 } 202 203 static int gpio_siox_get_direction(struct gpio_chip *chip, unsigned int offset) 204 { 205 if (offset < 12) 206 return 1; /* input */ 207 else 208 return 0; /* output */ 209 } 210 211 static int gpio_siox_probe(struct siox_device *sdevice) 212 { 213 struct gpio_siox_ddata *ddata; 214 int ret; 215 216 ddata = devm_kzalloc(&sdevice->dev, sizeof(*ddata), GFP_KERNEL); 217 if (!ddata) 218 return -ENOMEM; 219 220 dev_set_drvdata(&sdevice->dev, ddata); 221 222 mutex_init(&ddata->lock); 223 spin_lock_init(&ddata->irqlock); 224 225 ddata->gchip.base = -1; 226 ddata->gchip.can_sleep = 1; 227 ddata->gchip.parent = &sdevice->dev; 228 ddata->gchip.owner = THIS_MODULE; 229 ddata->gchip.get = gpio_siox_get; 230 ddata->gchip.set = gpio_siox_set; 231 ddata->gchip.direction_input = gpio_siox_direction_input; 232 ddata->gchip.direction_output = gpio_siox_direction_output; 233 ddata->gchip.get_direction = gpio_siox_get_direction; 234 ddata->gchip.ngpio = 20; 235 236 ddata->ichip.name = "siox-gpio"; 237 ddata->ichip.irq_ack = gpio_siox_irq_ack; 238 ddata->ichip.irq_mask = gpio_siox_irq_mask; 239 ddata->ichip.irq_unmask = gpio_siox_irq_unmask; 240 ddata->ichip.irq_set_type = gpio_siox_irq_set_type; 241 242 ret = gpiochip_add(&ddata->gchip); 243 if (ret) { 244 dev_err(&sdevice->dev, 245 "Failed to register gpio chip (%d)\n", ret); 246 goto err_gpiochip; 247 } 248 249 ret = gpiochip_irqchip_add(&ddata->gchip, &ddata->ichip, 250 0, handle_level_irq, IRQ_TYPE_EDGE_RISING); 251 if (ret) { 252 dev_err(&sdevice->dev, 253 "Failed to register irq chip (%d)\n", ret); 254 err_gpiochip: 255 gpiochip_remove(&ddata->gchip); 256 } 257 258 return ret; 259 } 260 261 static int gpio_siox_remove(struct siox_device *sdevice) 262 { 263 struct gpio_siox_ddata *ddata = dev_get_drvdata(&sdevice->dev); 264 265 gpiochip_remove(&ddata->gchip); 266 return 0; 267 } 268 269 static struct siox_driver gpio_siox_driver = { 270 .probe = gpio_siox_probe, 271 .remove = gpio_siox_remove, 272 .set_data = gpio_siox_set_data, 273 .get_data = gpio_siox_get_data, 274 .driver = { 275 .name = "gpio-siox", 276 }, 277 }; 278 279 static int __init gpio_siox_init(void) 280 { 281 return siox_driver_register(&gpio_siox_driver); 282 } 283 module_init(gpio_siox_init); 284 285 static void __exit gpio_siox_exit(void) 286 { 287 siox_driver_unregister(&gpio_siox_driver); 288 } 289 module_exit(gpio_siox_exit); 290 291 MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>"); 292 MODULE_DESCRIPTION("SIOX gpio driver"); 293 MODULE_LICENSE("GPL v2"); 294