460 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2 3#include <linux/gpio/driver.h>4#include <linux/cpumask.h>5#include <linux/irq.h>6#include <linux/minmax.h>7#include <linux/mod_devicetable.h>8#include <linux/module.h>9#include <linux/platform_device.h>10#include <linux/property.h>11 12/*13 * Total register block size is 0x1C for one bank of four ports (A, B, C, D).14 * An optional second bank, with ports E, F, G, and H, may be present, starting15 * at register offset 0x1C.16 */17 18/*19 * Pin select: (0) "normal", (1) "dedicate peripheral"20 * Not used on RTL8380/RTL8390, peripheral selection is managed by control bits21 * in the peripheral registers.22 */23#define REALTEK_GPIO_REG_CNR 0x0024/* Clear bit (0) for input, set bit (1) for output */25#define REALTEK_GPIO_REG_DIR 0x0826#define REALTEK_GPIO_REG_DATA 0x0C27/* Read bit for IRQ status, write 1 to clear IRQ */28#define REALTEK_GPIO_REG_ISR 0x1029/* Two bits per GPIO in IMR registers */30#define REALTEK_GPIO_REG_IMR 0x1431#define REALTEK_GPIO_REG_IMR_AB 0x1432#define REALTEK_GPIO_REG_IMR_CD 0x1833#define REALTEK_GPIO_IMR_LINE_MASK GENMASK(1, 0)34#define REALTEK_GPIO_IRQ_EDGE_FALLING 135#define REALTEK_GPIO_IRQ_EDGE_RISING 236#define REALTEK_GPIO_IRQ_EDGE_BOTH 337 38#define REALTEK_GPIO_MAX 3239#define REALTEK_GPIO_PORTS_PER_BANK 440 41/**42 * realtek_gpio_ctrl - Realtek Otto GPIO driver data43 *44 * @gc: Associated gpio_chip instance45 * @base: Base address of the register block for a GPIO bank46 * @lock: Lock for accessing the IRQ registers and values47 * @intr_mask: Mask for interrupts lines48 * @intr_type: Interrupt type selection49 * @bank_read: Read a bank setting as a single 32-bit value50 * @bank_write: Write a bank setting as a single 32-bit value51 * @imr_line_pos: Bit shift of an IRQ line's IMR value.52 *53 * The DIR, DATA, and ISR registers consist of four 8-bit port values, packed54 * into a single 32-bit register. Use @bank_read (@bank_write) to get (assign)55 * a value from (to) these registers. The IMR register consists of four 16-bit56 * port values, packed into two 32-bit registers. Use @imr_line_pos to get the57 * bit shift of the 2-bit field for a line's IMR settings. Shifts larger than58 * 32 overflow into the second register.59 *60 * Because the interrupt mask register (IMR) combines the function of IRQ type61 * selection and masking, two extra values are stored. @intr_mask is used to62 * mask/unmask the interrupts for a GPIO line, and @intr_type is used to store63 * the selected interrupt types. The logical AND of these values is written to64 * IMR on changes.65 */66struct realtek_gpio_ctrl {67 struct gpio_chip gc;68 void __iomem *base;69 void __iomem *cpumask_base;70 struct cpumask cpu_irq_maskable;71 raw_spinlock_t lock;72 u8 intr_mask[REALTEK_GPIO_MAX];73 u8 intr_type[REALTEK_GPIO_MAX];74 u32 (*bank_read)(void __iomem *reg);75 void (*bank_write)(void __iomem *reg, u32 value);76 unsigned int (*line_imr_pos)(unsigned int line);77};78 79/* Expand with more flags as devices with other quirks are added */80enum realtek_gpio_flags {81 /*82 * Allow disabling interrupts, for cases where the port order is83 * unknown. This may result in a port mismatch between ISR and IMR.84 * An interrupt would appear to come from a different line than the85 * line the IRQ handler was assigned to, causing uncaught interrupts.86 */87 GPIO_INTERRUPTS_DISABLED = BIT(0),88 /*89 * Port order is reversed, meaning DCBA register layout for 1-bit90 * fields, and [BA, DC] for 2-bit fields.91 */92 GPIO_PORTS_REVERSED = BIT(1),93 /*94 * Interrupts can be enabled per cpu. This requires a secondary IO95 * range, where the per-cpu enable masks are located.96 */97 GPIO_INTERRUPTS_PER_CPU = BIT(2),98};99 100static struct realtek_gpio_ctrl *irq_data_to_ctrl(struct irq_data *data)101{102 struct gpio_chip *gc = irq_data_get_irq_chip_data(data);103 104 return container_of(gc, struct realtek_gpio_ctrl, gc);105}106 107/*108 * Normal port order register access109 *110 * Port information is stored with the first port at offset 0, followed by the111 * second, etc. Most registers store one bit per GPIO and use a u8 value per112 * port. The two interrupt mask registers store two bits per GPIO, so use u16113 * values.114 */115static u32 realtek_gpio_bank_read_swapped(void __iomem *reg)116{117 return ioread32be(reg);118}119 120static void realtek_gpio_bank_write_swapped(void __iomem *reg, u32 value)121{122 iowrite32be(value, reg);123}124 125static unsigned int realtek_gpio_line_imr_pos_swapped(unsigned int line)126{127 unsigned int port_pin = line % 8;128 unsigned int port = line / 8;129 130 return 2 * (8 * (port ^ 1) + port_pin);131}132 133/*134 * Reversed port order register access135 *136 * For registers with one bit per GPIO, all ports are stored as u8-s in one137 * register in reversed order. The two interrupt mask registers store two bits138 * per GPIO, so use u16 values. The first register contains ports 1 and 0, the139 * second ports 3 and 2.140 */141static u32 realtek_gpio_bank_read(void __iomem *reg)142{143 return ioread32(reg);144}145 146static void realtek_gpio_bank_write(void __iomem *reg, u32 value)147{148 iowrite32(value, reg);149}150 151static unsigned int realtek_gpio_line_imr_pos(unsigned int line)152{153 return 2 * line;154}155 156static void realtek_gpio_clear_isr(struct realtek_gpio_ctrl *ctrl, u32 mask)157{158 ctrl->bank_write(ctrl->base + REALTEK_GPIO_REG_ISR, mask);159}160 161static u32 realtek_gpio_read_isr(struct realtek_gpio_ctrl *ctrl)162{163 return ctrl->bank_read(ctrl->base + REALTEK_GPIO_REG_ISR);164}165 166/* Set the rising and falling edge mask bits for a GPIO pin */167static void realtek_gpio_update_line_imr(struct realtek_gpio_ctrl *ctrl, unsigned int line)168{169 void __iomem *reg = ctrl->base + REALTEK_GPIO_REG_IMR;170 unsigned int line_shift = ctrl->line_imr_pos(line);171 unsigned int shift = line_shift % 32;172 u32 irq_type = ctrl->intr_type[line];173 u32 irq_mask = ctrl->intr_mask[line];174 u32 reg_val;175 176 reg += 4 * (line_shift / 32);177 reg_val = ioread32(reg);178 reg_val &= ~(REALTEK_GPIO_IMR_LINE_MASK << shift);179 reg_val |= (irq_type & irq_mask & REALTEK_GPIO_IMR_LINE_MASK) << shift;180 iowrite32(reg_val, reg);181}182 183static void realtek_gpio_irq_ack(struct irq_data *data)184{185 struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data);186 irq_hw_number_t line = irqd_to_hwirq(data);187 188 realtek_gpio_clear_isr(ctrl, BIT(line));189}190 191static void realtek_gpio_irq_unmask(struct irq_data *data)192{193 struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data);194 unsigned int line = irqd_to_hwirq(data);195 unsigned long flags;196 197 gpiochip_enable_irq(&ctrl->gc, line);198 199 raw_spin_lock_irqsave(&ctrl->lock, flags);200 ctrl->intr_mask[line] = REALTEK_GPIO_IMR_LINE_MASK;201 realtek_gpio_update_line_imr(ctrl, line);202 raw_spin_unlock_irqrestore(&ctrl->lock, flags);203}204 205static void realtek_gpio_irq_mask(struct irq_data *data)206{207 struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data);208 unsigned int line = irqd_to_hwirq(data);209 unsigned long flags;210 211 raw_spin_lock_irqsave(&ctrl->lock, flags);212 ctrl->intr_mask[line] = 0;213 realtek_gpio_update_line_imr(ctrl, line);214 raw_spin_unlock_irqrestore(&ctrl->lock, flags);215 216 gpiochip_disable_irq(&ctrl->gc, line);217}218 219static int realtek_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type)220{221 struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data);222 unsigned int line = irqd_to_hwirq(data);223 unsigned long flags;224 u8 type;225 226 switch (flow_type & IRQ_TYPE_SENSE_MASK) {227 case IRQ_TYPE_EDGE_FALLING:228 type = REALTEK_GPIO_IRQ_EDGE_FALLING;229 break;230 case IRQ_TYPE_EDGE_RISING:231 type = REALTEK_GPIO_IRQ_EDGE_RISING;232 break;233 case IRQ_TYPE_EDGE_BOTH:234 type = REALTEK_GPIO_IRQ_EDGE_BOTH;235 break;236 default:237 return -EINVAL;238 }239 240 irq_set_handler_locked(data, handle_edge_irq);241 242 raw_spin_lock_irqsave(&ctrl->lock, flags);243 ctrl->intr_type[line] = type;244 realtek_gpio_update_line_imr(ctrl, line);245 raw_spin_unlock_irqrestore(&ctrl->lock, flags);246 247 return 0;248}249 250static void realtek_gpio_irq_handler(struct irq_desc *desc)251{252 struct gpio_chip *gc = irq_desc_get_handler_data(desc);253 struct realtek_gpio_ctrl *ctrl = gpiochip_get_data(gc);254 struct irq_chip *irq_chip = irq_desc_get_chip(desc);255 unsigned long status;256 int offset;257 258 chained_irq_enter(irq_chip, desc);259 260 status = realtek_gpio_read_isr(ctrl);261 for_each_set_bit(offset, &status, gc->ngpio)262 generic_handle_domain_irq(gc->irq.domain, offset);263 264 chained_irq_exit(irq_chip, desc);265}266 267static inline void __iomem *realtek_gpio_irq_cpu_mask(struct realtek_gpio_ctrl *ctrl, int cpu)268{269 return ctrl->cpumask_base + REALTEK_GPIO_PORTS_PER_BANK * cpu;270}271 272static int realtek_gpio_irq_set_affinity(struct irq_data *data,273 const struct cpumask *dest, bool force)274{275 struct realtek_gpio_ctrl *ctrl = irq_data_to_ctrl(data);276 unsigned int line = irqd_to_hwirq(data);277 void __iomem *irq_cpu_mask;278 unsigned long flags;279 int cpu;280 u32 v;281 282 if (!ctrl->cpumask_base)283 return -ENXIO;284 285 raw_spin_lock_irqsave(&ctrl->lock, flags);286 287 for_each_cpu(cpu, &ctrl->cpu_irq_maskable) {288 irq_cpu_mask = realtek_gpio_irq_cpu_mask(ctrl, cpu);289 v = ctrl->bank_read(irq_cpu_mask);290 291 if (cpumask_test_cpu(cpu, dest))292 v |= BIT(line);293 else294 v &= ~BIT(line);295 296 ctrl->bank_write(irq_cpu_mask, v);297 }298 299 raw_spin_unlock_irqrestore(&ctrl->lock, flags);300 301 irq_data_update_effective_affinity(data, dest);302 303 return 0;304}305 306static int realtek_gpio_irq_init(struct gpio_chip *gc)307{308 struct realtek_gpio_ctrl *ctrl = gpiochip_get_data(gc);309 u32 mask_all = GENMASK(gc->ngpio - 1, 0);310 unsigned int line;311 int cpu;312 313 for (line = 0; line < gc->ngpio; line++)314 realtek_gpio_update_line_imr(ctrl, line);315 316 realtek_gpio_clear_isr(ctrl, mask_all);317 318 for_each_cpu(cpu, &ctrl->cpu_irq_maskable)319 ctrl->bank_write(realtek_gpio_irq_cpu_mask(ctrl, cpu), mask_all);320 321 return 0;322}323 324static const struct irq_chip realtek_gpio_irq_chip = {325 .name = "realtek-otto-gpio",326 .irq_ack = realtek_gpio_irq_ack,327 .irq_mask = realtek_gpio_irq_mask,328 .irq_unmask = realtek_gpio_irq_unmask,329 .irq_set_type = realtek_gpio_irq_set_type,330 .irq_set_affinity = realtek_gpio_irq_set_affinity,331 .flags = IRQCHIP_IMMUTABLE,332 GPIOCHIP_IRQ_RESOURCE_HELPERS,333};334 335static const struct of_device_id realtek_gpio_of_match[] = {336 {337 .compatible = "realtek,otto-gpio",338 .data = (void *)GPIO_INTERRUPTS_DISABLED,339 },340 {341 .compatible = "realtek,rtl8380-gpio",342 },343 {344 .compatible = "realtek,rtl8390-gpio",345 },346 {347 .compatible = "realtek,rtl9300-gpio",348 .data = (void *)(GPIO_PORTS_REVERSED | GPIO_INTERRUPTS_PER_CPU)349 },350 {351 .compatible = "realtek,rtl9310-gpio",352 },353 {}354};355MODULE_DEVICE_TABLE(of, realtek_gpio_of_match);356 357static int realtek_gpio_probe(struct platform_device *pdev)358{359 struct device *dev = &pdev->dev;360 unsigned long bgpio_flags;361 unsigned int dev_flags;362 struct gpio_irq_chip *girq;363 struct realtek_gpio_ctrl *ctrl;364 struct resource *res;365 u32 ngpios;366 unsigned int nr_cpus;367 int cpu, err, irq;368 369 ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);370 if (!ctrl)371 return -ENOMEM;372 373 dev_flags = (unsigned int) device_get_match_data(dev);374 375 ngpios = REALTEK_GPIO_MAX;376 device_property_read_u32(dev, "ngpios", &ngpios);377 378 if (ngpios > REALTEK_GPIO_MAX) {379 dev_err(&pdev->dev, "invalid ngpios (max. %d)\n",380 REALTEK_GPIO_MAX);381 return -EINVAL;382 }383 384 ctrl->base = devm_platform_ioremap_resource(pdev, 0);385 if (IS_ERR(ctrl->base))386 return PTR_ERR(ctrl->base);387 388 raw_spin_lock_init(&ctrl->lock);389 390 if (dev_flags & GPIO_PORTS_REVERSED) {391 bgpio_flags = 0;392 ctrl->bank_read = realtek_gpio_bank_read;393 ctrl->bank_write = realtek_gpio_bank_write;394 ctrl->line_imr_pos = realtek_gpio_line_imr_pos;395 } else {396 bgpio_flags = BGPIOF_BIG_ENDIAN_BYTE_ORDER;397 ctrl->bank_read = realtek_gpio_bank_read_swapped;398 ctrl->bank_write = realtek_gpio_bank_write_swapped;399 ctrl->line_imr_pos = realtek_gpio_line_imr_pos_swapped;400 }401 402 err = bgpio_init(&ctrl->gc, dev, 4,403 ctrl->base + REALTEK_GPIO_REG_DATA, NULL, NULL,404 ctrl->base + REALTEK_GPIO_REG_DIR, NULL,405 bgpio_flags);406 if (err) {407 dev_err(dev, "unable to init generic GPIO");408 return err;409 }410 411 ctrl->gc.ngpio = ngpios;412 ctrl->gc.owner = THIS_MODULE;413 414 irq = platform_get_irq_optional(pdev, 0);415 if (!(dev_flags & GPIO_INTERRUPTS_DISABLED) && irq > 0) {416 girq = &ctrl->gc.irq;417 gpio_irq_chip_set_chip(girq, &realtek_gpio_irq_chip);418 girq->default_type = IRQ_TYPE_NONE;419 girq->handler = handle_bad_irq;420 girq->parent_handler = realtek_gpio_irq_handler;421 girq->num_parents = 1;422 girq->parents = devm_kcalloc(dev, girq->num_parents,423 sizeof(*girq->parents), GFP_KERNEL);424 if (!girq->parents)425 return -ENOMEM;426 girq->parents[0] = irq;427 girq->init_hw = realtek_gpio_irq_init;428 }429 430 cpumask_clear(&ctrl->cpu_irq_maskable);431 432 if ((dev_flags & GPIO_INTERRUPTS_PER_CPU) && irq > 0) {433 ctrl->cpumask_base = devm_platform_get_and_ioremap_resource(pdev, 1, &res);434 if (IS_ERR(ctrl->cpumask_base))435 return dev_err_probe(dev, PTR_ERR(ctrl->cpumask_base),436 "missing CPU IRQ mask registers");437 438 nr_cpus = resource_size(res) / REALTEK_GPIO_PORTS_PER_BANK;439 nr_cpus = min(nr_cpus, num_present_cpus());440 441 for (cpu = 0; cpu < nr_cpus; cpu++)442 cpumask_set_cpu(cpu, &ctrl->cpu_irq_maskable);443 }444 445 return devm_gpiochip_add_data(dev, &ctrl->gc, ctrl);446}447 448static struct platform_driver realtek_gpio_driver = {449 .driver = {450 .name = "realtek-otto-gpio",451 .of_match_table = realtek_gpio_of_match,452 },453 .probe = realtek_gpio_probe,454};455module_platform_driver(realtek_gpio_driver);456 457MODULE_DESCRIPTION("Realtek Otto GPIO support");458MODULE_AUTHOR("Sander Vanheule <sander@svanheule.net>");459MODULE_LICENSE("GPL v2");460