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

Configure Feed

Select the types of activity you want to include in your feed.

at v6.16 436 lines 12 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * TQ-Systems TQMx86 PLD GPIO driver 4 * 5 * Based on vendor driver by: 6 * Vadim V.Vlasov <vvlasov@dev.rtsoft.ru> 7 */ 8 9#include <linux/bitmap.h> 10#include <linux/bitops.h> 11#include <linux/errno.h> 12#include <linux/gpio/driver.h> 13#include <linux/init.h> 14#include <linux/interrupt.h> 15#include <linux/kernel.h> 16#include <linux/module.h> 17#include <linux/platform_device.h> 18#include <linux/pm_runtime.h> 19#include <linux/seq_file.h> 20#include <linux/slab.h> 21 22#define TQMX86_NGPIO 8 23#define TQMX86_NGPO 4 /* 0-3 - output */ 24#define TQMX86_NGPI 4 /* 4-7 - input */ 25#define TQMX86_DIR_INPUT_MASK 0xf0 /* 0-3 - output, 4-7 - input */ 26 27#define TQMX86_GPIODD 0 /* GPIO Data Direction Register */ 28#define TQMX86_GPIOD 1 /* GPIO Data Register */ 29#define TQMX86_GPIIC 3 /* GPI Interrupt Configuration Register */ 30#define TQMX86_GPIIS 4 /* GPI Interrupt Status Register */ 31 32/* 33 * NONE, FALLING and RISING use the same bit patterns that can be programmed to 34 * the GPII register (after passing them to the TQMX86_GPII_ macros to shift 35 * them to the right position) 36 */ 37#define TQMX86_INT_TRIG_NONE 0 38#define TQMX86_INT_TRIG_FALLING BIT(0) 39#define TQMX86_INT_TRIG_RISING BIT(1) 40#define TQMX86_INT_TRIG_BOTH (BIT(0) | BIT(1)) 41#define TQMX86_INT_TRIG_MASK (BIT(0) | BIT(1)) 42/* Stored in irq_type with GPII bits */ 43#define TQMX86_INT_UNMASKED BIT(2) 44 45#define TQMX86_GPIIC_CONFIG(i, v) ((v) << (2 * (i))) 46#define TQMX86_GPIIC_MASK(i) TQMX86_GPIIC_CONFIG(i, TQMX86_INT_TRIG_MASK) 47 48struct tqmx86_gpio_data { 49 struct gpio_chip chip; 50 void __iomem *io_base; 51 int irq; 52 /* Lock must be held for accessing output and irq_type fields */ 53 raw_spinlock_t spinlock; 54 DECLARE_BITMAP(output, TQMX86_NGPIO); 55 u8 irq_type[TQMX86_NGPIO]; 56}; 57 58static u8 tqmx86_gpio_read(struct tqmx86_gpio_data *gd, unsigned int reg) 59{ 60 return ioread8(gd->io_base + reg); 61} 62 63static void tqmx86_gpio_write(struct tqmx86_gpio_data *gd, u8 val, 64 unsigned int reg) 65{ 66 iowrite8(val, gd->io_base + reg); 67} 68 69static void tqmx86_gpio_clrsetbits(struct tqmx86_gpio_data *gpio, 70 u8 clr, u8 set, unsigned int reg) 71 __must_hold(&gpio->spinlock) 72{ 73 u8 val = tqmx86_gpio_read(gpio, reg); 74 75 val &= ~clr; 76 val |= set; 77 78 tqmx86_gpio_write(gpio, val, reg); 79} 80 81static int tqmx86_gpio_get(struct gpio_chip *chip, unsigned int offset) 82{ 83 struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip); 84 85 return !!(tqmx86_gpio_read(gpio, TQMX86_GPIOD) & BIT(offset)); 86} 87 88static void _tqmx86_gpio_set(struct tqmx86_gpio_data *gpio, unsigned int offset, 89 int value) 90 __must_hold(&gpio->spinlock) 91{ 92 __assign_bit(offset, gpio->output, value); 93 tqmx86_gpio_write(gpio, bitmap_get_value8(gpio->output, 0), TQMX86_GPIOD); 94} 95 96static void tqmx86_gpio_set(struct gpio_chip *chip, unsigned int offset, 97 int value) 98{ 99 struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip); 100 101 guard(raw_spinlock_irqsave)(&gpio->spinlock); 102 103 _tqmx86_gpio_set(gpio, offset, value); 104} 105 106static int tqmx86_gpio_direction_input(struct gpio_chip *chip, 107 unsigned int offset) 108{ 109 struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip); 110 111 guard(raw_spinlock_irqsave)(&gpio->spinlock); 112 113 tqmx86_gpio_clrsetbits(gpio, BIT(offset), 0, TQMX86_GPIODD); 114 115 return 0; 116} 117 118static int tqmx86_gpio_direction_output(struct gpio_chip *chip, 119 unsigned int offset, 120 int value) 121{ 122 struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip); 123 124 guard(raw_spinlock_irqsave)(&gpio->spinlock); 125 126 _tqmx86_gpio_set(gpio, offset, value); 127 tqmx86_gpio_clrsetbits(gpio, 0, BIT(offset), TQMX86_GPIODD); 128 129 return 0; 130} 131 132static int tqmx86_gpio_get_direction(struct gpio_chip *chip, 133 unsigned int offset) 134{ 135 struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip); 136 u8 val; 137 138 val = tqmx86_gpio_read(gpio, TQMX86_GPIODD); 139 140 if (val & BIT(offset)) 141 return GPIO_LINE_DIRECTION_OUT; 142 143 return GPIO_LINE_DIRECTION_IN; 144} 145 146static void tqmx86_gpio_irq_config(struct tqmx86_gpio_data *gpio, int hwirq) 147 __must_hold(&gpio->spinlock) 148{ 149 u8 type = TQMX86_INT_TRIG_NONE; 150 int gpiic_irq = hwirq - TQMX86_NGPO; 151 152 if (gpio->irq_type[hwirq] & TQMX86_INT_UNMASKED) { 153 type = gpio->irq_type[hwirq] & TQMX86_INT_TRIG_MASK; 154 155 if (type == TQMX86_INT_TRIG_BOTH) 156 type = tqmx86_gpio_get(&gpio->chip, hwirq) 157 ? TQMX86_INT_TRIG_FALLING 158 : TQMX86_INT_TRIG_RISING; 159 } 160 161 tqmx86_gpio_clrsetbits(gpio, 162 TQMX86_GPIIC_MASK(gpiic_irq), 163 TQMX86_GPIIC_CONFIG(gpiic_irq, type), 164 TQMX86_GPIIC); 165} 166 167static void tqmx86_gpio_irq_mask(struct irq_data *data) 168{ 169 struct tqmx86_gpio_data *gpio = gpiochip_get_data( 170 irq_data_get_irq_chip_data(data)); 171 172 scoped_guard(raw_spinlock_irqsave, &gpio->spinlock) { 173 gpio->irq_type[data->hwirq] &= ~TQMX86_INT_UNMASKED; 174 tqmx86_gpio_irq_config(gpio, data->hwirq); 175 } 176 177 gpiochip_disable_irq(&gpio->chip, irqd_to_hwirq(data)); 178} 179 180static void tqmx86_gpio_irq_unmask(struct irq_data *data) 181{ 182 struct tqmx86_gpio_data *gpio = gpiochip_get_data( 183 irq_data_get_irq_chip_data(data)); 184 185 gpiochip_enable_irq(&gpio->chip, irqd_to_hwirq(data)); 186 187 guard(raw_spinlock_irqsave)(&gpio->spinlock); 188 189 gpio->irq_type[data->hwirq] |= TQMX86_INT_UNMASKED; 190 tqmx86_gpio_irq_config(gpio, data->hwirq); 191} 192 193static int tqmx86_gpio_irq_set_type(struct irq_data *data, unsigned int type) 194{ 195 struct tqmx86_gpio_data *gpio = gpiochip_get_data( 196 irq_data_get_irq_chip_data(data)); 197 unsigned int edge_type = type & IRQF_TRIGGER_MASK; 198 u8 new_type; 199 200 switch (edge_type) { 201 case IRQ_TYPE_EDGE_RISING: 202 new_type = TQMX86_INT_TRIG_RISING; 203 break; 204 case IRQ_TYPE_EDGE_FALLING: 205 new_type = TQMX86_INT_TRIG_FALLING; 206 break; 207 case IRQ_TYPE_EDGE_BOTH: 208 new_type = TQMX86_INT_TRIG_BOTH; 209 break; 210 default: 211 return -EINVAL; /* not supported */ 212 } 213 214 guard(raw_spinlock_irqsave)(&gpio->spinlock); 215 216 gpio->irq_type[data->hwirq] &= ~TQMX86_INT_TRIG_MASK; 217 gpio->irq_type[data->hwirq] |= new_type; 218 tqmx86_gpio_irq_config(gpio, data->hwirq); 219 220 return 0; 221} 222 223static void tqmx86_gpio_irq_handler(struct irq_desc *desc) 224{ 225 struct gpio_chip *chip = irq_desc_get_handler_data(desc); 226 struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip); 227 struct irq_chip *irq_chip = irq_desc_get_chip(desc); 228 unsigned long irq_bits; 229 int i, hwirq; 230 u8 irq_status; 231 232 chained_irq_enter(irq_chip, desc); 233 234 irq_status = tqmx86_gpio_read(gpio, TQMX86_GPIIS); 235 tqmx86_gpio_write(gpio, irq_status, TQMX86_GPIIS); 236 237 irq_bits = irq_status; 238 239 scoped_guard(raw_spinlock_irqsave, &gpio->spinlock) { 240 for_each_set_bit(i, &irq_bits, TQMX86_NGPI) { 241 hwirq = i + TQMX86_NGPO; 242 243 /* 244 * Edge-both triggers are implemented by flipping the 245 * edge trigger after each interrupt, as the controller 246 * only supports either rising or falling edge triggers, 247 * but not both. 248 * 249 * Internally, the TQMx86 GPIO controller has separate 250 * status registers for rising and falling edge 251 * interrupts. GPIIC configures which bits from which 252 * register are visible in the interrupt status register 253 * GPIIS and defines what triggers the parent IRQ line. 254 * Writing to GPIIS always clears both rising and 255 * falling interrupt flags internally, regardless of the 256 * currently configured trigger. 257 * 258 * In consequence, we can cleanly implement the 259 * edge-both trigger in software by first clearing the 260 * interrupt and then setting the new trigger based on 261 * the current GPIO input in tqmx86_gpio_irq_config() - 262 * even if an edge arrives between reading the input and 263 * setting the trigger, we will have a new interrupt 264 * pending. 265 */ 266 if ((gpio->irq_type[hwirq] & TQMX86_INT_TRIG_MASK) == 267 TQMX86_INT_TRIG_BOTH) 268 tqmx86_gpio_irq_config(gpio, hwirq); 269 } 270 } 271 272 for_each_set_bit(i, &irq_bits, TQMX86_NGPI) 273 generic_handle_domain_irq(gpio->chip.irq.domain, 274 i + TQMX86_NGPO); 275 276 chained_irq_exit(irq_chip, desc); 277} 278 279/* Minimal runtime PM is needed by the IRQ subsystem */ 280static int __maybe_unused tqmx86_gpio_runtime_suspend(struct device *dev) 281{ 282 return 0; 283} 284 285static int __maybe_unused tqmx86_gpio_runtime_resume(struct device *dev) 286{ 287 return 0; 288} 289 290static const struct dev_pm_ops tqmx86_gpio_dev_pm_ops = { 291 SET_RUNTIME_PM_OPS(tqmx86_gpio_runtime_suspend, 292 tqmx86_gpio_runtime_resume, NULL) 293}; 294 295static void tqmx86_init_irq_valid_mask(struct gpio_chip *chip, 296 unsigned long *valid_mask, 297 unsigned int ngpios) 298{ 299 /* Only GPIOs 4-7 are valid for interrupts. Clear the others */ 300 clear_bit(0, valid_mask); 301 clear_bit(1, valid_mask); 302 clear_bit(2, valid_mask); 303 clear_bit(3, valid_mask); 304} 305 306static void tqmx86_gpio_irq_print_chip(struct irq_data *d, struct seq_file *p) 307{ 308 struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 309 310 seq_puts(p, gc->label); 311} 312 313static const struct irq_chip tqmx86_gpio_irq_chip = { 314 .irq_mask = tqmx86_gpio_irq_mask, 315 .irq_unmask = tqmx86_gpio_irq_unmask, 316 .irq_set_type = tqmx86_gpio_irq_set_type, 317 .irq_print_chip = tqmx86_gpio_irq_print_chip, 318 .flags = IRQCHIP_IMMUTABLE, 319 GPIOCHIP_IRQ_RESOURCE_HELPERS, 320}; 321 322static int tqmx86_gpio_probe(struct platform_device *pdev) 323{ 324 struct device *dev = &pdev->dev; 325 struct tqmx86_gpio_data *gpio; 326 struct gpio_chip *chip; 327 struct gpio_irq_chip *girq; 328 void __iomem *io_base; 329 struct resource *res; 330 int ret, irq; 331 332 irq = platform_get_irq_optional(pdev, 0); 333 if (irq < 0 && irq != -ENXIO) 334 return irq; 335 336 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 337 if (!res) { 338 dev_err(&pdev->dev, "Cannot get I/O\n"); 339 return -ENODEV; 340 } 341 342 io_base = devm_ioport_map(&pdev->dev, res->start, resource_size(res)); 343 if (!io_base) 344 return -ENOMEM; 345 346 gpio = devm_kzalloc(dev, sizeof(*gpio), GFP_KERNEL); 347 if (!gpio) 348 return -ENOMEM; 349 350 raw_spin_lock_init(&gpio->spinlock); 351 gpio->io_base = io_base; 352 353 tqmx86_gpio_write(gpio, (u8)~TQMX86_DIR_INPUT_MASK, TQMX86_GPIODD); 354 355 /* 356 * Reading the previous output state is not possible with TQMx86 hardware. 357 * Initialize all outputs to 0 to have a defined state that matches the 358 * shadow register. 359 */ 360 tqmx86_gpio_write(gpio, 0, TQMX86_GPIOD); 361 362 chip = &gpio->chip; 363 chip->label = "gpio-tqmx86"; 364 chip->owner = THIS_MODULE; 365 chip->can_sleep = false; 366 chip->base = -1; 367 chip->direction_input = tqmx86_gpio_direction_input; 368 chip->direction_output = tqmx86_gpio_direction_output; 369 chip->get_direction = tqmx86_gpio_get_direction; 370 chip->get = tqmx86_gpio_get; 371 chip->set = tqmx86_gpio_set; 372 chip->ngpio = TQMX86_NGPIO; 373 chip->parent = pdev->dev.parent; 374 375 pm_runtime_enable(&pdev->dev); 376 377 if (irq > 0) { 378 u8 irq_status; 379 380 /* Mask all interrupts */ 381 tqmx86_gpio_write(gpio, 0, TQMX86_GPIIC); 382 383 /* Clear all pending interrupts */ 384 irq_status = tqmx86_gpio_read(gpio, TQMX86_GPIIS); 385 tqmx86_gpio_write(gpio, irq_status, TQMX86_GPIIS); 386 387 girq = &chip->irq; 388 gpio_irq_chip_set_chip(girq, &tqmx86_gpio_irq_chip); 389 girq->parent_handler = tqmx86_gpio_irq_handler; 390 girq->num_parents = 1; 391 girq->parents = devm_kcalloc(&pdev->dev, 1, 392 sizeof(*girq->parents), 393 GFP_KERNEL); 394 if (!girq->parents) { 395 ret = -ENOMEM; 396 goto out_pm_dis; 397 } 398 girq->parents[0] = irq; 399 girq->default_type = IRQ_TYPE_NONE; 400 girq->handler = handle_simple_irq; 401 girq->init_valid_mask = tqmx86_init_irq_valid_mask; 402 403 irq_domain_set_pm_device(girq->domain, dev); 404 } 405 406 ret = devm_gpiochip_add_data(dev, chip, gpio); 407 if (ret) { 408 dev_err(dev, "Could not register GPIO chip\n"); 409 goto out_pm_dis; 410 } 411 412 dev_info(dev, "GPIO functionality initialized with %d pins\n", 413 chip->ngpio); 414 415 return 0; 416 417out_pm_dis: 418 pm_runtime_disable(&pdev->dev); 419 420 return ret; 421} 422 423static struct platform_driver tqmx86_gpio_driver = { 424 .driver = { 425 .name = "tqmx86-gpio", 426 .pm = &tqmx86_gpio_dev_pm_ops, 427 }, 428 .probe = tqmx86_gpio_probe, 429}; 430 431module_platform_driver(tqmx86_gpio_driver); 432 433MODULE_DESCRIPTION("TQMx86 PLD GPIO Driver"); 434MODULE_AUTHOR("Andrew Lunn <andrew@lunn.ch>"); 435MODULE_LICENSE("GPL"); 436MODULE_ALIAS("platform:tqmx86-gpio");