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.

gpio: cadence: Add quirk for Axiado AX3000 platform

On the Axiado AX3000 platform, pinmux and pin configuration (such as
direction and output enable) are configured by the hardware/firmware
at boot time before Linux boots.

To prevent conflicts, introduce a platform-specific quirk triggered by
the "axiado,ax3000-gpio" compatible string.

When this quirk is active, the driver will skip its default
initialization of pinmux configuration and direction settings during
probe.

Co-developed-by: Tzu-Hao Wei <twei@axiado.com>
Signed-off-by: Tzu-Hao Wei <twei@axiado.com>
Signed-off-by: Swark Yang <syang@axiado.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Link: https://lore.kernel.org/r/20260109-axiado-ax3000-cadence-gpio-support-v2-1-fc1e28edf68a@axiado.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>

authored by

Swark Yang and committed by
Bartosz Golaszewski
ea5b4c68 a88d9589

+45 -11
+45 -11
drivers/gpio/gpio-cadence.c
··· 2 2 3 3 /* 4 4 * Copyright 2017-2018 Cadence 5 + * Copyright (C) 2025 Axiado Corporation. 5 6 * 6 7 * Authors: 7 8 * Jan Kotas <jank@cadence.com> ··· 32 31 #define CDNS_GPIO_IRQ_VALUE 0x28 33 32 #define CDNS_GPIO_IRQ_ANY_EDGE 0x2c 34 33 34 + struct cdns_gpio_quirks { 35 + bool skip_init; 36 + }; 37 + 35 38 struct cdns_gpio_chip { 36 39 struct gpio_generic_chip gen_gc; 37 40 void __iomem *regs; 38 41 u32 bypass_orig; 42 + const struct cdns_gpio_quirks *quirks; 43 + }; 44 + 45 + static const struct cdns_gpio_quirks cdns_default_quirks = { 46 + .skip_init = false, 47 + }; 48 + 49 + static const struct cdns_gpio_quirks ax3000_gpio_quirks = { 50 + .skip_init = true, 39 51 }; 40 52 41 53 static int cdns_gpio_request(struct gpio_chip *chip, unsigned int offset) ··· 155 141 GPIOCHIP_IRQ_RESOURCE_HELPERS, 156 142 }; 157 143 144 + static const struct of_device_id cdns_of_ids[] = { 145 + { 146 + .compatible = "axiado,ax3000-gpio", 147 + .data = &ax3000_gpio_quirks 148 + }, 149 + { 150 + .compatible = "cdns,gpio-r1p02", 151 + .data = &cdns_default_quirks 152 + }, 153 + { /* sentinel */ }, 154 + }; 155 + MODULE_DEVICE_TABLE(of, cdns_of_ids); 156 + 158 157 static int cdns_gpio_probe(struct platform_device *pdev) 159 158 { 160 159 struct gpio_generic_chip_config config = { }; ··· 192 165 return -EINVAL; 193 166 } 194 167 168 + cgpio->quirks = device_get_match_data(&pdev->dev); 169 + if (!cgpio->quirks) 170 + cgpio->quirks = &cdns_default_quirks; 171 + 195 172 /* 196 173 * Set all pins as inputs by default, otherwise: 197 174 * gpiochip_lock_as_irq: ··· 204 173 * so it needs to be changed before gpio_generic_chip_init() is called. 205 174 */ 206 175 dir_prev = ioread32(cgpio->regs + CDNS_GPIO_DIRECTION_MODE); 207 - iowrite32(GENMASK(num_gpios - 1, 0), 208 - cgpio->regs + CDNS_GPIO_DIRECTION_MODE); 176 + 177 + /* 178 + * The AX3000 platform performs the required configuration at boot time 179 + * before Linux boots, so this quirk disables pinmux initialization. 180 + */ 181 + if (!cgpio->quirks->skip_init) { 182 + iowrite32(GENMASK(num_gpios - 1, 0), 183 + cgpio->regs + CDNS_GPIO_DIRECTION_MODE); 184 + } 209 185 210 186 config.dev = &pdev->dev; 211 187 config.sz = 4; ··· 278 240 /* 279 241 * Enable gpio outputs, ignored for input direction 280 242 */ 281 - iowrite32(GENMASK(num_gpios - 1, 0), 282 - cgpio->regs + CDNS_GPIO_OUTPUT_EN); 283 - iowrite32(0, cgpio->regs + CDNS_GPIO_BYPASS_MODE); 243 + if (!cgpio->quirks->skip_init) { 244 + iowrite32(GENMASK(num_gpios - 1, 0), 245 + cgpio->regs + CDNS_GPIO_OUTPUT_EN); 246 + iowrite32(0, cgpio->regs + CDNS_GPIO_BYPASS_MODE); 247 + } 284 248 285 249 platform_set_drvdata(pdev, cgpio); 286 250 return 0; ··· 299 259 300 260 iowrite32(cgpio->bypass_orig, cgpio->regs + CDNS_GPIO_BYPASS_MODE); 301 261 } 302 - 303 - static const struct of_device_id cdns_of_ids[] = { 304 - { .compatible = "cdns,gpio-r1p02" }, 305 - { /* sentinel */ }, 306 - }; 307 - MODULE_DEVICE_TABLE(of, cdns_of_ids); 308 262 309 263 static struct platform_driver cdns_gpio_driver = { 310 264 .driver = {