405 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * TQ-Systems TQMx86 PLD GPIO driver4 *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 823#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#define TQMX86_GPII_NONE 033#define TQMX86_GPII_FALLING BIT(0)34#define TQMX86_GPII_RISING BIT(1)35/* Stored in irq_type as a trigger type, but not actually valid as a register36 * value, so the name doesn't use "GPII"37 */38#define TQMX86_INT_BOTH (BIT(0) | BIT(1))39#define TQMX86_GPII_MASK (BIT(0) | BIT(1))40#define TQMX86_GPII_BITS 241/* Stored in irq_type with GPII bits */42#define TQMX86_INT_UNMASKED BIT(2)43 44struct tqmx86_gpio_data {45 struct gpio_chip chip;46 void __iomem *io_base;47 int irq;48 /* Lock must be held for accessing output and irq_type fields */49 raw_spinlock_t spinlock;50 DECLARE_BITMAP(output, TQMX86_NGPIO);51 u8 irq_type[TQMX86_NGPI];52};53 54static u8 tqmx86_gpio_read(struct tqmx86_gpio_data *gd, unsigned int reg)55{56 return ioread8(gd->io_base + reg);57}58 59static void tqmx86_gpio_write(struct tqmx86_gpio_data *gd, u8 val,60 unsigned int reg)61{62 iowrite8(val, gd->io_base + reg);63}64 65static int tqmx86_gpio_get(struct gpio_chip *chip, unsigned int offset)66{67 struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);68 69 return !!(tqmx86_gpio_read(gpio, TQMX86_GPIOD) & BIT(offset));70}71 72static void tqmx86_gpio_set(struct gpio_chip *chip, unsigned int offset,73 int value)74{75 struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);76 unsigned long flags;77 78 raw_spin_lock_irqsave(&gpio->spinlock, flags);79 __assign_bit(offset, gpio->output, value);80 tqmx86_gpio_write(gpio, bitmap_get_value8(gpio->output, 0), TQMX86_GPIOD);81 raw_spin_unlock_irqrestore(&gpio->spinlock, flags);82}83 84static int tqmx86_gpio_direction_input(struct gpio_chip *chip,85 unsigned int offset)86{87 /* Direction cannot be changed. Validate is an input. */88 if (BIT(offset) & TQMX86_DIR_INPUT_MASK)89 return 0;90 else91 return -EINVAL;92}93 94static int tqmx86_gpio_direction_output(struct gpio_chip *chip,95 unsigned int offset,96 int value)97{98 /* Direction cannot be changed, validate is an output */99 if (BIT(offset) & TQMX86_DIR_INPUT_MASK)100 return -EINVAL;101 102 tqmx86_gpio_set(chip, offset, value);103 return 0;104}105 106static int tqmx86_gpio_get_direction(struct gpio_chip *chip,107 unsigned int offset)108{109 if (TQMX86_DIR_INPUT_MASK & BIT(offset))110 return GPIO_LINE_DIRECTION_IN;111 112 return GPIO_LINE_DIRECTION_OUT;113}114 115static void tqmx86_gpio_irq_config(struct tqmx86_gpio_data *gpio, int offset)116 __must_hold(&gpio->spinlock)117{118 u8 type = TQMX86_GPII_NONE, gpiic;119 120 if (gpio->irq_type[offset] & TQMX86_INT_UNMASKED) {121 type = gpio->irq_type[offset] & TQMX86_GPII_MASK;122 123 if (type == TQMX86_INT_BOTH)124 type = tqmx86_gpio_get(&gpio->chip, offset + TQMX86_NGPO)125 ? TQMX86_GPII_FALLING126 : TQMX86_GPII_RISING;127 }128 129 gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC);130 gpiic &= ~(TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS));131 gpiic |= type << (offset * TQMX86_GPII_BITS);132 tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC);133}134 135static void tqmx86_gpio_irq_mask(struct irq_data *data)136{137 unsigned int offset = (data->hwirq - TQMX86_NGPO);138 struct tqmx86_gpio_data *gpio = gpiochip_get_data(139 irq_data_get_irq_chip_data(data));140 unsigned long flags;141 142 raw_spin_lock_irqsave(&gpio->spinlock, flags);143 gpio->irq_type[offset] &= ~TQMX86_INT_UNMASKED;144 tqmx86_gpio_irq_config(gpio, offset);145 raw_spin_unlock_irqrestore(&gpio->spinlock, flags);146 147 gpiochip_disable_irq(&gpio->chip, irqd_to_hwirq(data));148}149 150static void tqmx86_gpio_irq_unmask(struct irq_data *data)151{152 unsigned int offset = (data->hwirq - TQMX86_NGPO);153 struct tqmx86_gpio_data *gpio = gpiochip_get_data(154 irq_data_get_irq_chip_data(data));155 unsigned long flags;156 157 gpiochip_enable_irq(&gpio->chip, irqd_to_hwirq(data));158 159 raw_spin_lock_irqsave(&gpio->spinlock, flags);160 gpio->irq_type[offset] |= TQMX86_INT_UNMASKED;161 tqmx86_gpio_irq_config(gpio, offset);162 raw_spin_unlock_irqrestore(&gpio->spinlock, flags);163}164 165static int tqmx86_gpio_irq_set_type(struct irq_data *data, unsigned int type)166{167 struct tqmx86_gpio_data *gpio = gpiochip_get_data(168 irq_data_get_irq_chip_data(data));169 unsigned int offset = (data->hwirq - TQMX86_NGPO);170 unsigned int edge_type = type & IRQF_TRIGGER_MASK;171 unsigned long flags;172 u8 new_type;173 174 switch (edge_type) {175 case IRQ_TYPE_EDGE_RISING:176 new_type = TQMX86_GPII_RISING;177 break;178 case IRQ_TYPE_EDGE_FALLING:179 new_type = TQMX86_GPII_FALLING;180 break;181 case IRQ_TYPE_EDGE_BOTH:182 new_type = TQMX86_INT_BOTH;183 break;184 default:185 return -EINVAL; /* not supported */186 }187 188 raw_spin_lock_irqsave(&gpio->spinlock, flags);189 gpio->irq_type[offset] &= ~TQMX86_GPII_MASK;190 gpio->irq_type[offset] |= new_type;191 tqmx86_gpio_irq_config(gpio, offset);192 raw_spin_unlock_irqrestore(&gpio->spinlock, flags);193 194 return 0;195}196 197static void tqmx86_gpio_irq_handler(struct irq_desc *desc)198{199 struct gpio_chip *chip = irq_desc_get_handler_data(desc);200 struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);201 struct irq_chip *irq_chip = irq_desc_get_chip(desc);202 unsigned long irq_bits, flags;203 int i;204 u8 irq_status;205 206 chained_irq_enter(irq_chip, desc);207 208 irq_status = tqmx86_gpio_read(gpio, TQMX86_GPIIS);209 tqmx86_gpio_write(gpio, irq_status, TQMX86_GPIIS);210 211 irq_bits = irq_status;212 213 raw_spin_lock_irqsave(&gpio->spinlock, flags);214 for_each_set_bit(i, &irq_bits, TQMX86_NGPI) {215 /*216 * Edge-both triggers are implemented by flipping the edge217 * trigger after each interrupt, as the controller only supports218 * either rising or falling edge triggers, but not both.219 *220 * Internally, the TQMx86 GPIO controller has separate status221 * registers for rising and falling edge interrupts. GPIIC222 * configures which bits from which register are visible in the223 * interrupt status register GPIIS and defines what triggers the224 * parent IRQ line. Writing to GPIIS always clears both rising225 * and falling interrupt flags internally, regardless of the226 * currently configured trigger.227 *228 * In consequence, we can cleanly implement the edge-both229 * trigger in software by first clearing the interrupt and then230 * setting the new trigger based on the current GPIO input in231 * tqmx86_gpio_irq_config() - even if an edge arrives between232 * reading the input and setting the trigger, we will have a new233 * interrupt pending.234 */235 if ((gpio->irq_type[i] & TQMX86_GPII_MASK) == TQMX86_INT_BOTH)236 tqmx86_gpio_irq_config(gpio, i);237 }238 raw_spin_unlock_irqrestore(&gpio->spinlock, flags);239 240 for_each_set_bit(i, &irq_bits, TQMX86_NGPI)241 generic_handle_domain_irq(gpio->chip.irq.domain,242 i + TQMX86_NGPO);243 244 chained_irq_exit(irq_chip, desc);245}246 247/* Minimal runtime PM is needed by the IRQ subsystem */248static int __maybe_unused tqmx86_gpio_runtime_suspend(struct device *dev)249{250 return 0;251}252 253static int __maybe_unused tqmx86_gpio_runtime_resume(struct device *dev)254{255 return 0;256}257 258static const struct dev_pm_ops tqmx86_gpio_dev_pm_ops = {259 SET_RUNTIME_PM_OPS(tqmx86_gpio_runtime_suspend,260 tqmx86_gpio_runtime_resume, NULL)261};262 263static void tqmx86_init_irq_valid_mask(struct gpio_chip *chip,264 unsigned long *valid_mask,265 unsigned int ngpios)266{267 /* Only GPIOs 4-7 are valid for interrupts. Clear the others */268 clear_bit(0, valid_mask);269 clear_bit(1, valid_mask);270 clear_bit(2, valid_mask);271 clear_bit(3, valid_mask);272}273 274static void tqmx86_gpio_irq_print_chip(struct irq_data *d, struct seq_file *p)275{276 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);277 278 seq_printf(p, gc->label);279}280 281static const struct irq_chip tqmx86_gpio_irq_chip = {282 .irq_mask = tqmx86_gpio_irq_mask,283 .irq_unmask = tqmx86_gpio_irq_unmask,284 .irq_set_type = tqmx86_gpio_irq_set_type,285 .irq_print_chip = tqmx86_gpio_irq_print_chip,286 .flags = IRQCHIP_IMMUTABLE,287 GPIOCHIP_IRQ_RESOURCE_HELPERS,288};289 290static int tqmx86_gpio_probe(struct platform_device *pdev)291{292 struct device *dev = &pdev->dev;293 struct tqmx86_gpio_data *gpio;294 struct gpio_chip *chip;295 struct gpio_irq_chip *girq;296 void __iomem *io_base;297 struct resource *res;298 int ret, irq;299 300 irq = platform_get_irq_optional(pdev, 0);301 if (irq < 0 && irq != -ENXIO)302 return irq;303 304 res = platform_get_resource(pdev, IORESOURCE_IO, 0);305 if (!res) {306 dev_err(&pdev->dev, "Cannot get I/O\n");307 return -ENODEV;308 }309 310 io_base = devm_ioport_map(&pdev->dev, res->start, resource_size(res));311 if (!io_base)312 return -ENOMEM;313 314 gpio = devm_kzalloc(dev, sizeof(*gpio), GFP_KERNEL);315 if (!gpio)316 return -ENOMEM;317 318 raw_spin_lock_init(&gpio->spinlock);319 gpio->io_base = io_base;320 321 tqmx86_gpio_write(gpio, (u8)~TQMX86_DIR_INPUT_MASK, TQMX86_GPIODD);322 323 /*324 * Reading the previous output state is not possible with TQMx86 hardware.325 * Initialize all outputs to 0 to have a defined state that matches the326 * shadow register.327 */328 tqmx86_gpio_write(gpio, 0, TQMX86_GPIOD);329 330 chip = &gpio->chip;331 chip->label = "gpio-tqmx86";332 chip->owner = THIS_MODULE;333 chip->can_sleep = false;334 chip->base = -1;335 chip->direction_input = tqmx86_gpio_direction_input;336 chip->direction_output = tqmx86_gpio_direction_output;337 chip->get_direction = tqmx86_gpio_get_direction;338 chip->get = tqmx86_gpio_get;339 chip->set = tqmx86_gpio_set;340 chip->ngpio = TQMX86_NGPIO;341 chip->parent = pdev->dev.parent;342 343 pm_runtime_enable(&pdev->dev);344 345 if (irq > 0) {346 u8 irq_status;347 348 /* Mask all interrupts */349 tqmx86_gpio_write(gpio, 0, TQMX86_GPIIC);350 351 /* Clear all pending interrupts */352 irq_status = tqmx86_gpio_read(gpio, TQMX86_GPIIS);353 tqmx86_gpio_write(gpio, irq_status, TQMX86_GPIIS);354 355 girq = &chip->irq;356 gpio_irq_chip_set_chip(girq, &tqmx86_gpio_irq_chip);357 girq->parent_handler = tqmx86_gpio_irq_handler;358 girq->num_parents = 1;359 girq->parents = devm_kcalloc(&pdev->dev, 1,360 sizeof(*girq->parents),361 GFP_KERNEL);362 if (!girq->parents) {363 ret = -ENOMEM;364 goto out_pm_dis;365 }366 girq->parents[0] = irq;367 girq->default_type = IRQ_TYPE_NONE;368 girq->handler = handle_simple_irq;369 girq->init_valid_mask = tqmx86_init_irq_valid_mask;370 371 irq_domain_set_pm_device(girq->domain, dev);372 }373 374 ret = devm_gpiochip_add_data(dev, chip, gpio);375 if (ret) {376 dev_err(dev, "Could not register GPIO chip\n");377 goto out_pm_dis;378 }379 380 dev_info(dev, "GPIO functionality initialized with %d pins\n",381 chip->ngpio);382 383 return 0;384 385out_pm_dis:386 pm_runtime_disable(&pdev->dev);387 388 return ret;389}390 391static struct platform_driver tqmx86_gpio_driver = {392 .driver = {393 .name = "tqmx86-gpio",394 .pm = &tqmx86_gpio_dev_pm_ops,395 },396 .probe = tqmx86_gpio_probe,397};398 399module_platform_driver(tqmx86_gpio_driver);400 401MODULE_DESCRIPTION("TQMx86 PLD GPIO Driver");402MODULE_AUTHOR("Andrew Lunn <andrew@lunn.ch>");403MODULE_LICENSE("GPL");404MODULE_ALIAS("platform:tqmx86-gpio");405