Blame view
drivers/gpio/gpio-zynq.c
29.2 KB
2874c5fd2 treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-or-later |
3242ba117 gpio: Add driver ... |
2 3 4 5 |
/* * Xilinx Zynq GPIO device driver * * Copyright (C) 2009 - 2014 Xilinx, Inc. |
3242ba117 gpio: Add driver ... |
6 7 8 9 10 11 12 13 14 15 16 |
*/ #include <linux/bitops.h> #include <linux/clk.h> #include <linux/gpio/driver.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/io.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> |
bdf7a4ae3 gpio: Added suppo... |
17 |
#include <linux/of.h> |
3242ba117 gpio: Add driver ... |
18 19 20 21 22 |
#define DRIVER_NAME "zynq-gpio" /* Maximum banks */ #define ZYNQ_GPIO_MAX_BANK 4 |
bdf7a4ae3 gpio: Added suppo... |
23 |
#define ZYNQMP_GPIO_MAX_BANK 6 |
3242ba117 gpio: Add driver ... |
24 25 26 27 28 |
#define ZYNQ_GPIO_BANK0_NGPIO 32 #define ZYNQ_GPIO_BANK1_NGPIO 22 #define ZYNQ_GPIO_BANK2_NGPIO 32 #define ZYNQ_GPIO_BANK3_NGPIO 32 |
bdf7a4ae3 gpio: Added suppo... |
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
#define ZYNQMP_GPIO_BANK0_NGPIO 26 #define ZYNQMP_GPIO_BANK1_NGPIO 26 #define ZYNQMP_GPIO_BANK2_NGPIO 26 #define ZYNQMP_GPIO_BANK3_NGPIO 32 #define ZYNQMP_GPIO_BANK4_NGPIO 32 #define ZYNQMP_GPIO_BANK5_NGPIO 32 #define ZYNQ_GPIO_NR_GPIOS 118 #define ZYNQMP_GPIO_NR_GPIOS 174 #define ZYNQ_GPIO_BANK0_PIN_MIN(str) 0 #define ZYNQ_GPIO_BANK0_PIN_MAX(str) (ZYNQ_GPIO_BANK0_PIN_MIN(str) + \ ZYNQ##str##_GPIO_BANK0_NGPIO - 1) #define ZYNQ_GPIO_BANK1_PIN_MIN(str) (ZYNQ_GPIO_BANK0_PIN_MAX(str) + 1) #define ZYNQ_GPIO_BANK1_PIN_MAX(str) (ZYNQ_GPIO_BANK1_PIN_MIN(str) + \ ZYNQ##str##_GPIO_BANK1_NGPIO - 1) #define ZYNQ_GPIO_BANK2_PIN_MIN(str) (ZYNQ_GPIO_BANK1_PIN_MAX(str) + 1) #define ZYNQ_GPIO_BANK2_PIN_MAX(str) (ZYNQ_GPIO_BANK2_PIN_MIN(str) + \ ZYNQ##str##_GPIO_BANK2_NGPIO - 1) #define ZYNQ_GPIO_BANK3_PIN_MIN(str) (ZYNQ_GPIO_BANK2_PIN_MAX(str) + 1) #define ZYNQ_GPIO_BANK3_PIN_MAX(str) (ZYNQ_GPIO_BANK3_PIN_MIN(str) + \ ZYNQ##str##_GPIO_BANK3_NGPIO - 1) #define ZYNQ_GPIO_BANK4_PIN_MIN(str) (ZYNQ_GPIO_BANK3_PIN_MAX(str) + 1) #define ZYNQ_GPIO_BANK4_PIN_MAX(str) (ZYNQ_GPIO_BANK4_PIN_MIN(str) + \ ZYNQ##str##_GPIO_BANK4_NGPIO - 1) #define ZYNQ_GPIO_BANK5_PIN_MIN(str) (ZYNQ_GPIO_BANK4_PIN_MAX(str) + 1) #define ZYNQ_GPIO_BANK5_PIN_MAX(str) (ZYNQ_GPIO_BANK5_PIN_MIN(str) + \ ZYNQ##str##_GPIO_BANK5_NGPIO - 1) |
3242ba117 gpio: Add driver ... |
57 |
|
3242ba117 gpio: Add driver ... |
58 59 60 61 62 63 |
/* Register offsets for the GPIO device */ /* LSW Mask & Data -WO */ #define ZYNQ_GPIO_DATA_LSW_OFFSET(BANK) (0x000 + (8 * BANK)) /* MSW Mask & Data -WO */ #define ZYNQ_GPIO_DATA_MSW_OFFSET(BANK) (0x004 + (8 * BANK)) /* Data Register-RW */ |
06aa09081 gpio: zynq: Provi... |
64 |
#define ZYNQ_GPIO_DATA_OFFSET(BANK) (0x040 + (4 * BANK)) |
3242ba117 gpio: Add driver ... |
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
#define ZYNQ_GPIO_DATA_RO_OFFSET(BANK) (0x060 + (4 * BANK)) /* Direction mode reg-RW */ #define ZYNQ_GPIO_DIRM_OFFSET(BANK) (0x204 + (0x40 * BANK)) /* Output enable reg-RW */ #define ZYNQ_GPIO_OUTEN_OFFSET(BANK) (0x208 + (0x40 * BANK)) /* Interrupt mask reg-RO */ #define ZYNQ_GPIO_INTMASK_OFFSET(BANK) (0x20C + (0x40 * BANK)) /* Interrupt enable reg-WO */ #define ZYNQ_GPIO_INTEN_OFFSET(BANK) (0x210 + (0x40 * BANK)) /* Interrupt disable reg-WO */ #define ZYNQ_GPIO_INTDIS_OFFSET(BANK) (0x214 + (0x40 * BANK)) /* Interrupt status reg-RO */ #define ZYNQ_GPIO_INTSTS_OFFSET(BANK) (0x218 + (0x40 * BANK)) /* Interrupt type reg-RW */ #define ZYNQ_GPIO_INTTYPE_OFFSET(BANK) (0x21C + (0x40 * BANK)) /* Interrupt polarity reg-RW */ #define ZYNQ_GPIO_INTPOL_OFFSET(BANK) (0x220 + (0x40 * BANK)) /* Interrupt on any, reg-RW */ #define ZYNQ_GPIO_INTANY_OFFSET(BANK) (0x224 + (0x40 * BANK)) /* Disable all interrupts mask */ #define ZYNQ_GPIO_IXR_DISABLE_ALL 0xFFFFFFFF /* Mid pin number of a bank */ #define ZYNQ_GPIO_MID_PIN_NUM 16 /* GPIO upper 16 bit mask */ #define ZYNQ_GPIO_UPPER_MASK 0xFFFF0000 |
3638bd4a0 gpio: zynq: Clari... |
93 94 |
/* set to differentiate zynq from zynqmp, 0=zynqmp, 1=zynq */ #define ZYNQ_GPIO_QUIRK_IS_ZYNQ BIT(0) |
06aa09081 gpio: zynq: Provi... |
95 |
#define GPIO_QUIRK_DATA_RO_BUG BIT(1) |
e3296f19c gpio: Added zynq ... |
96 |
|
e11de4de2 gpio: zynq: Add s... |
97 98 99 100 101 102 103 104 105 106 107 |
struct gpio_regs { u32 datamsw[ZYNQMP_GPIO_MAX_BANK]; u32 datalsw[ZYNQMP_GPIO_MAX_BANK]; u32 dirm[ZYNQMP_GPIO_MAX_BANK]; u32 outen[ZYNQMP_GPIO_MAX_BANK]; u32 int_en[ZYNQMP_GPIO_MAX_BANK]; u32 int_dis[ZYNQMP_GPIO_MAX_BANK]; u32 int_type[ZYNQMP_GPIO_MAX_BANK]; u32 int_polarity[ZYNQMP_GPIO_MAX_BANK]; u32 int_any[ZYNQMP_GPIO_MAX_BANK]; }; |
eb73d6eaa gpio: zynq: Fix e... |
108 |
|
3242ba117 gpio: Add driver ... |
109 110 111 112 113 |
/** * struct zynq_gpio - gpio device private data structure * @chip: instance of the gpio_chip * @base_addr: base address of the GPIO device * @clk: clock resource for this controller |
59e22114b gpio: zynq: Fixed... |
114 |
* @irq: interrupt for the GPIO device |
bdf7a4ae3 gpio: Added suppo... |
115 |
* @p_data: pointer to platform data |
e11de4de2 gpio: zynq: Add s... |
116 |
* @context: context registers |
3242ba117 gpio: Add driver ... |
117 118 119 120 121 |
*/ struct zynq_gpio { struct gpio_chip chip; void __iomem *base_addr; struct clk *clk; |
59e22114b gpio: zynq: Fixed... |
122 |
int irq; |
bdf7a4ae3 gpio: Added suppo... |
123 |
const struct zynq_platform_data *p_data; |
e11de4de2 gpio: zynq: Add s... |
124 |
struct gpio_regs context; |
bdf7a4ae3 gpio: Added suppo... |
125 126 127 128 129 |
}; /** * struct zynq_platform_data - zynq gpio platform data structure * @label: string to store in gpio->label |
6ae5104cb gpio: zynq: Fix k... |
130 |
* @quirks: Flags is used to identify the platform |
bdf7a4ae3 gpio: Added suppo... |
131 132 133 134 |
* @ngpio: max number of gpio pins * @max_bank: maximum number of gpio banks * @bank_min: this array represents bank's min pin * @bank_max: this array represents bank's max pin |
6ae5104cb gpio: zynq: Fix k... |
135 |
*/ |
bdf7a4ae3 gpio: Added suppo... |
136 137 |
struct zynq_platform_data { const char *label; |
e3296f19c gpio: Added zynq ... |
138 |
u32 quirks; |
bdf7a4ae3 gpio: Added suppo... |
139 140 141 142 |
u16 ngpio; int max_bank; int bank_min[ZYNQMP_GPIO_MAX_BANK]; int bank_max[ZYNQMP_GPIO_MAX_BANK]; |
3242ba117 gpio: Add driver ... |
143 |
}; |
6dd859508 gpio: zynq: Fix I... |
144 145 |
static struct irq_chip zynq_gpio_level_irqchip; static struct irq_chip zynq_gpio_edge_irqchip; |
fa9795d11 gpio: zynq: use c... |
146 |
|
3242ba117 gpio: Add driver ... |
147 |
/** |
3638bd4a0 gpio: zynq: Clari... |
148 149 150 151 152 153 154 155 156 157 158 |
* zynq_gpio_is_zynq - test if HW is zynq or zynqmp * @gpio: Pointer to driver data struct * * Return: 0 if zynqmp, 1 if zynq. */ static int zynq_gpio_is_zynq(struct zynq_gpio *gpio) { return !!(gpio->p_data->quirks & ZYNQ_GPIO_QUIRK_IS_ZYNQ); } /** |
06aa09081 gpio: zynq: Provi... |
159 160 161 162 163 164 165 166 167 168 169 |
* gpio_data_ro_bug - test if HW bug exists or not * @gpio: Pointer to driver data struct * * Return: 0 if bug doesnot exist, 1 if bug exists. */ static int gpio_data_ro_bug(struct zynq_gpio *gpio) { return !!(gpio->p_data->quirks & GPIO_QUIRK_DATA_RO_BUG); } /** |
3242ba117 gpio: Add driver ... |
170 171 172 173 174 175 176 |
* zynq_gpio_get_bank_pin - Get the bank number and pin number within that bank * for a given pin in the GPIO device * @pin_num: gpio pin number within the device * @bank_num: an output parameter used to return the bank number of the gpio * pin * @bank_pin_num: an output parameter used to return pin number within a bank * for the given gpio pin |
6ae5104cb gpio: zynq: Fix k... |
177 |
* @gpio: gpio device data structure |
3242ba117 gpio: Add driver ... |
178 179 180 181 182 |
* * Returns the bank number and pin offset within the bank. */ static inline void zynq_gpio_get_bank_pin(unsigned int pin_num, unsigned int *bank_num, |
bdf7a4ae3 gpio: Added suppo... |
183 184 |
unsigned int *bank_pin_num, struct zynq_gpio *gpio) |
3242ba117 gpio: Add driver ... |
185 |
{ |
bdf7a4ae3 gpio: Added suppo... |
186 187 188 189 |
int bank; for (bank = 0; bank < gpio->p_data->max_bank; bank++) { if ((pin_num >= gpio->p_data->bank_min[bank]) && |
16ee62e56 gpio: zynq: Fix d... |
190 |
(pin_num <= gpio->p_data->bank_max[bank])) { |
2717cfcaf gpio: zynq: Fix w... |
191 192 193 194 |
*bank_num = bank; *bank_pin_num = pin_num - gpio->p_data->bank_min[bank]; return; |
bdf7a4ae3 gpio: Added suppo... |
195 |
} |
3242ba117 gpio: Add driver ... |
196 |
} |
3242ba117 gpio: Add driver ... |
197 |
|
bdf7a4ae3 gpio: Added suppo... |
198 199 200 201 202 |
/* default */ WARN(true, "invalid GPIO pin number: %u", pin_num); *bank_num = 0; *bank_pin_num = 0; } |
016da1443 gpio: zynq: Take ... |
203 |
|
3242ba117 gpio: Add driver ... |
204 205 206 207 208 209 210 211 212 213 214 215 216 |
/** * zynq_gpio_get_value - Get the state of the specified pin of GPIO device * @chip: gpio_chip instance to be worked on * @pin: gpio pin number within the device * * This function reads the state of the specified pin of the GPIO device. * * Return: 0 if the pin is low, 1 if pin is high. */ static int zynq_gpio_get_value(struct gpio_chip *chip, unsigned int pin) { u32 data; unsigned int bank_num, bank_pin_num; |
31a894475 gpio: zynq: use g... |
217 |
struct zynq_gpio *gpio = gpiochip_get_data(chip); |
3242ba117 gpio: Add driver ... |
218 |
|
bdf7a4ae3 gpio: Added suppo... |
219 |
zynq_gpio_get_bank_pin(pin, &bank_num, &bank_pin_num, gpio); |
3242ba117 gpio: Add driver ... |
220 |
|
06aa09081 gpio: zynq: Provi... |
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 |
if (gpio_data_ro_bug(gpio)) { if (zynq_gpio_is_zynq(gpio)) { if (bank_num <= 1) { data = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_DATA_RO_OFFSET(bank_num)); } else { data = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_DATA_OFFSET(bank_num)); } } else { if (bank_num <= 2) { data = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_DATA_RO_OFFSET(bank_num)); } else { data = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_DATA_OFFSET(bank_num)); } } } else { data = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_DATA_RO_OFFSET(bank_num)); } |
3242ba117 gpio: Add driver ... |
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 |
return (data >> bank_pin_num) & 1; } /** * zynq_gpio_set_value - Modify the state of the pin with specified value * @chip: gpio_chip instance to be worked on * @pin: gpio pin number within the device * @state: value used to modify the state of the specified pin * * This function calculates the register offset (i.e to lower 16 bits or * upper 16 bits) based on the given pin number and sets the state of a * gpio pin to the specified value. The state is either 0 or non-zero. */ static void zynq_gpio_set_value(struct gpio_chip *chip, unsigned int pin, int state) { unsigned int reg_offset, bank_num, bank_pin_num; |
31a894475 gpio: zynq: use g... |
260 |
struct zynq_gpio *gpio = gpiochip_get_data(chip); |
3242ba117 gpio: Add driver ... |
261 |
|
bdf7a4ae3 gpio: Added suppo... |
262 |
zynq_gpio_get_bank_pin(pin, &bank_num, &bank_pin_num, gpio); |
3242ba117 gpio: Add driver ... |
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 |
if (bank_pin_num >= ZYNQ_GPIO_MID_PIN_NUM) { /* only 16 data bits in bit maskable reg */ bank_pin_num -= ZYNQ_GPIO_MID_PIN_NUM; reg_offset = ZYNQ_GPIO_DATA_MSW_OFFSET(bank_num); } else { reg_offset = ZYNQ_GPIO_DATA_LSW_OFFSET(bank_num); } /* * get the 32 bit value to be written to the mask/data register where * the upper 16 bits is the mask and lower 16 bits is the data */ state = !!state; state = ~(1 << (bank_pin_num + ZYNQ_GPIO_MID_PIN_NUM)) & ((state << bank_pin_num) | ZYNQ_GPIO_UPPER_MASK); writel_relaxed(state, gpio->base_addr + reg_offset); } /** * zynq_gpio_dir_in - Set the direction of the specified GPIO pin as input * @chip: gpio_chip instance to be worked on * @pin: gpio pin number within the device * * This function uses the read-modify-write sequence to set the direction of * the gpio pin as input. * * Return: 0 always */ static int zynq_gpio_dir_in(struct gpio_chip *chip, unsigned int pin) { u32 reg; unsigned int bank_num, bank_pin_num; |
31a894475 gpio: zynq: use g... |
297 |
struct zynq_gpio *gpio = gpiochip_get_data(chip); |
3242ba117 gpio: Add driver ... |
298 |
|
bdf7a4ae3 gpio: Added suppo... |
299 |
zynq_gpio_get_bank_pin(pin, &bank_num, &bank_pin_num, gpio); |
3242ba117 gpio: Add driver ... |
300 |
|
e3296f19c gpio: Added zynq ... |
301 302 303 304 |
/* * On zynq bank 0 pins 7 and 8 are special and cannot be used * as inputs. */ |
3638bd4a0 gpio: zynq: Clari... |
305 |
if (zynq_gpio_is_zynq(gpio) && bank_num == 0 && |
16ee62e56 gpio: zynq: Fix d... |
306 |
(bank_pin_num == 7 || bank_pin_num == 8)) |
3242ba117 gpio: Add driver ... |
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 |
return -EINVAL; /* clear the bit in direction mode reg to set the pin as input */ reg = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); reg &= ~BIT(bank_pin_num); writel_relaxed(reg, gpio->base_addr + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); return 0; } /** * zynq_gpio_dir_out - Set the direction of the specified GPIO pin as output * @chip: gpio_chip instance to be worked on * @pin: gpio pin number within the device * @state: value to be written to specified pin * * This function sets the direction of specified GPIO pin as output, configures * the Output Enable register for the pin and uses zynq_gpio_set to set * the state of the pin to the value specified. * * Return: 0 always */ static int zynq_gpio_dir_out(struct gpio_chip *chip, unsigned int pin, int state) { u32 reg; unsigned int bank_num, bank_pin_num; |
31a894475 gpio: zynq: use g... |
334 |
struct zynq_gpio *gpio = gpiochip_get_data(chip); |
3242ba117 gpio: Add driver ... |
335 |
|
bdf7a4ae3 gpio: Added suppo... |
336 |
zynq_gpio_get_bank_pin(pin, &bank_num, &bank_pin_num, gpio); |
3242ba117 gpio: Add driver ... |
337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 |
/* set the GPIO pin as output */ reg = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); reg |= BIT(bank_pin_num); writel_relaxed(reg, gpio->base_addr + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); /* configure the output enable reg for the pin */ reg = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_OUTEN_OFFSET(bank_num)); reg |= BIT(bank_pin_num); writel_relaxed(reg, gpio->base_addr + ZYNQ_GPIO_OUTEN_OFFSET(bank_num)); /* set the state of the pin */ zynq_gpio_set_value(chip, pin, state); return 0; } /** |
6169005ce gpio: zynq: Repor... |
354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 |
* zynq_gpio_get_direction - Read the direction of the specified GPIO pin * @chip: gpio_chip instance to be worked on * @pin: gpio pin number within the device * * This function returns the direction of the specified GPIO. * * Return: 0 for output, 1 for input */ static int zynq_gpio_get_direction(struct gpio_chip *chip, unsigned int pin) { u32 reg; unsigned int bank_num, bank_pin_num; struct zynq_gpio *gpio = gpiochip_get_data(chip); zynq_gpio_get_bank_pin(pin, &bank_num, &bank_pin_num, gpio); reg = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); return !(reg & BIT(bank_pin_num)); } /** |
3242ba117 gpio: Add driver ... |
376 377 378 379 380 381 382 383 384 385 |
* zynq_gpio_irq_mask - Disable the interrupts for a gpio pin * @irq_data: per irq and chip data passed down to chip functions * * This function calculates gpio pin number from irq number and sets the * bit in the Interrupt Disable register of the corresponding bank to disable * interrupts for that pin. */ static void zynq_gpio_irq_mask(struct irq_data *irq_data) { unsigned int device_pin_num, bank_num, bank_pin_num; |
fa9795d11 gpio: zynq: use c... |
386 |
struct zynq_gpio *gpio = |
31a894475 gpio: zynq: use g... |
387 |
gpiochip_get_data(irq_data_get_irq_chip_data(irq_data)); |
3242ba117 gpio: Add driver ... |
388 389 |
device_pin_num = irq_data->hwirq; |
bdf7a4ae3 gpio: Added suppo... |
390 |
zynq_gpio_get_bank_pin(device_pin_num, &bank_num, &bank_pin_num, gpio); |
3242ba117 gpio: Add driver ... |
391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 |
writel_relaxed(BIT(bank_pin_num), gpio->base_addr + ZYNQ_GPIO_INTDIS_OFFSET(bank_num)); } /** * zynq_gpio_irq_unmask - Enable the interrupts for a gpio pin * @irq_data: irq data containing irq number of gpio pin for the interrupt * to enable * * This function calculates the gpio pin number from irq number and sets the * bit in the Interrupt Enable register of the corresponding bank to enable * interrupts for that pin. */ static void zynq_gpio_irq_unmask(struct irq_data *irq_data) { unsigned int device_pin_num, bank_num, bank_pin_num; |
fa9795d11 gpio: zynq: use c... |
407 |
struct zynq_gpio *gpio = |
31a894475 gpio: zynq: use g... |
408 |
gpiochip_get_data(irq_data_get_irq_chip_data(irq_data)); |
3242ba117 gpio: Add driver ... |
409 410 |
device_pin_num = irq_data->hwirq; |
bdf7a4ae3 gpio: Added suppo... |
411 |
zynq_gpio_get_bank_pin(device_pin_num, &bank_num, &bank_pin_num, gpio); |
3242ba117 gpio: Add driver ... |
412 413 414 415 416 |
writel_relaxed(BIT(bank_pin_num), gpio->base_addr + ZYNQ_GPIO_INTEN_OFFSET(bank_num)); } /** |
190dc2e68 gpio: zynq: Clear... |
417 418 419 420 421 422 423 424 425 426 |
* zynq_gpio_irq_ack - Acknowledge the interrupt of a gpio pin * @irq_data: irq data containing irq number of gpio pin for the interrupt * to ack * * This function calculates gpio pin number from irq number and sets the bit * in the Interrupt Status Register of the corresponding bank, to ACK the irq. */ static void zynq_gpio_irq_ack(struct irq_data *irq_data) { unsigned int device_pin_num, bank_num, bank_pin_num; |
fa9795d11 gpio: zynq: use c... |
427 |
struct zynq_gpio *gpio = |
31a894475 gpio: zynq: use g... |
428 |
gpiochip_get_data(irq_data_get_irq_chip_data(irq_data)); |
190dc2e68 gpio: zynq: Clear... |
429 430 |
device_pin_num = irq_data->hwirq; |
bdf7a4ae3 gpio: Added suppo... |
431 |
zynq_gpio_get_bank_pin(device_pin_num, &bank_num, &bank_pin_num, gpio); |
190dc2e68 gpio: zynq: Clear... |
432 433 434 435 436 437 438 439 440 |
writel_relaxed(BIT(bank_pin_num), gpio->base_addr + ZYNQ_GPIO_INTSTS_OFFSET(bank_num)); } /** * zynq_gpio_irq_enable - Enable the interrupts for a gpio pin * @irq_data: irq data containing irq number of gpio pin for the interrupt * to enable * |
20a8a9687 Drivers: gpio: Fi... |
441 |
* Clears the INTSTS bit and unmasks the given interrupt. |
190dc2e68 gpio: zynq: Clear... |
442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 |
*/ static void zynq_gpio_irq_enable(struct irq_data *irq_data) { /* * The Zynq GPIO controller does not disable interrupt detection when * the interrupt is masked and only disables the propagation of the * interrupt. This means when the controller detects an interrupt * condition while the interrupt is logically disabled it will propagate * that interrupt event once the interrupt is enabled. This will cause * the interrupt consumer to see spurious interrupts to prevent this * first make sure that the interrupt is not asserted and then enable * it. */ zynq_gpio_irq_ack(irq_data); zynq_gpio_irq_unmask(irq_data); } /** |
3242ba117 gpio: Add driver ... |
460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 |
* zynq_gpio_set_irq_type - Set the irq type for a gpio pin * @irq_data: irq data containing irq number of gpio pin * @type: interrupt type that is to be set for the gpio pin * * This function gets the gpio pin number and its bank from the gpio pin number * and configures the INT_TYPE, INT_POLARITY and INT_ANY registers. * * Return: 0, negative error otherwise. * TYPE-EDGE_RISING, INT_TYPE - 1, INT_POLARITY - 1, INT_ANY - 0; * TYPE-EDGE_FALLING, INT_TYPE - 1, INT_POLARITY - 0, INT_ANY - 0; * TYPE-EDGE_BOTH, INT_TYPE - 1, INT_POLARITY - NA, INT_ANY - 1; * TYPE-LEVEL_HIGH, INT_TYPE - 0, INT_POLARITY - 1, INT_ANY - NA; * TYPE-LEVEL_LOW, INT_TYPE - 0, INT_POLARITY - 0, INT_ANY - NA */ static int zynq_gpio_set_irq_type(struct irq_data *irq_data, unsigned int type) { u32 int_type, int_pol, int_any; unsigned int device_pin_num, bank_num, bank_pin_num; |
fa9795d11 gpio: zynq: use c... |
478 |
struct zynq_gpio *gpio = |
31a894475 gpio: zynq: use g... |
479 |
gpiochip_get_data(irq_data_get_irq_chip_data(irq_data)); |
3242ba117 gpio: Add driver ... |
480 481 |
device_pin_num = irq_data->hwirq; |
bdf7a4ae3 gpio: Added suppo... |
482 |
zynq_gpio_get_bank_pin(device_pin_num, &bank_num, &bank_pin_num, gpio); |
3242ba117 gpio: Add driver ... |
483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 |
int_type = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_INTTYPE_OFFSET(bank_num)); int_pol = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_INTPOL_OFFSET(bank_num)); int_any = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_INTANY_OFFSET(bank_num)); /* * based on the type requested, configure the INT_TYPE, INT_POLARITY * and INT_ANY registers */ switch (type) { case IRQ_TYPE_EDGE_RISING: int_type |= BIT(bank_pin_num); int_pol |= BIT(bank_pin_num); int_any &= ~BIT(bank_pin_num); break; case IRQ_TYPE_EDGE_FALLING: int_type |= BIT(bank_pin_num); int_pol &= ~BIT(bank_pin_num); int_any &= ~BIT(bank_pin_num); break; case IRQ_TYPE_EDGE_BOTH: int_type |= BIT(bank_pin_num); int_any |= BIT(bank_pin_num); break; case IRQ_TYPE_LEVEL_HIGH: int_type &= ~BIT(bank_pin_num); int_pol |= BIT(bank_pin_num); break; case IRQ_TYPE_LEVEL_LOW: int_type &= ~BIT(bank_pin_num); int_pol &= ~BIT(bank_pin_num); break; default: return -EINVAL; } writel_relaxed(int_type, gpio->base_addr + ZYNQ_GPIO_INTTYPE_OFFSET(bank_num)); writel_relaxed(int_pol, gpio->base_addr + ZYNQ_GPIO_INTPOL_OFFSET(bank_num)); writel_relaxed(int_any, gpio->base_addr + ZYNQ_GPIO_INTANY_OFFSET(bank_num)); |
6dd859508 gpio: zynq: Fix I... |
528 |
|
16ee62e56 gpio: zynq: Fix d... |
529 |
if (type & IRQ_TYPE_LEVEL_MASK) |
47c084629 gpio/zynq: Use ir... |
530 |
irq_set_chip_handler_name_locked(irq_data, |
16ee62e56 gpio: zynq: Fix d... |
531 532 533 |
&zynq_gpio_level_irqchip, handle_fasteoi_irq, NULL); else |
47c084629 gpio/zynq: Use ir... |
534 |
irq_set_chip_handler_name_locked(irq_data, |
16ee62e56 gpio: zynq: Fix d... |
535 536 |
&zynq_gpio_edge_irqchip, handle_level_irq, NULL); |
6dd859508 gpio: zynq: Fix I... |
537 |
|
3242ba117 gpio: Add driver ... |
538 539 540 541 542 |
return 0; } static int zynq_gpio_set_wake(struct irq_data *data, unsigned int on) { |
fa9795d11 gpio: zynq: use c... |
543 |
struct zynq_gpio *gpio = |
31a894475 gpio: zynq: use g... |
544 |
gpiochip_get_data(irq_data_get_irq_chip_data(data)); |
59e22114b gpio: zynq: Fixed... |
545 546 |
irq_set_irq_wake(gpio->irq, on); |
3242ba117 gpio: Add driver ... |
547 548 549 |
return 0; } |
c2df3de0d gpio: zynq: prope... |
550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 |
static int zynq_gpio_irq_reqres(struct irq_data *d) { struct gpio_chip *chip = irq_data_get_irq_chip_data(d); int ret; ret = pm_runtime_get_sync(chip->parent); if (ret < 0) return ret; return gpiochip_reqres_irq(chip, d->hwirq); } static void zynq_gpio_irq_relres(struct irq_data *d) { struct gpio_chip *chip = irq_data_get_irq_chip_data(d); gpiochip_relres_irq(chip, d->hwirq); pm_runtime_put(chip->parent); } |
3242ba117 gpio: Add driver ... |
569 |
/* irq chip descriptor */ |
6dd859508 gpio: zynq: Fix I... |
570 |
static struct irq_chip zynq_gpio_level_irqchip = { |
3242ba117 gpio: Add driver ... |
571 |
.name = DRIVER_NAME, |
190dc2e68 gpio: zynq: Clear... |
572 |
.irq_enable = zynq_gpio_irq_enable, |
6dd859508 gpio: zynq: Fix I... |
573 574 575 576 577 |
.irq_eoi = zynq_gpio_irq_ack, .irq_mask = zynq_gpio_irq_mask, .irq_unmask = zynq_gpio_irq_unmask, .irq_set_type = zynq_gpio_set_irq_type, .irq_set_wake = zynq_gpio_set_wake, |
c2df3de0d gpio: zynq: prope... |
578 579 |
.irq_request_resources = zynq_gpio_irq_reqres, .irq_release_resources = zynq_gpio_irq_relres, |
a19467788 gpio: zynq: Mask ... |
580 581 |
.flags = IRQCHIP_EOI_THREADED | IRQCHIP_EOI_IF_HANDLED | IRQCHIP_MASK_ON_SUSPEND, |
6dd859508 gpio: zynq: Fix I... |
582 583 584 585 586 587 |
}; static struct irq_chip zynq_gpio_edge_irqchip = { .name = DRIVER_NAME, .irq_enable = zynq_gpio_irq_enable, .irq_ack = zynq_gpio_irq_ack, |
3242ba117 gpio: Add driver ... |
588 589 590 591 |
.irq_mask = zynq_gpio_irq_mask, .irq_unmask = zynq_gpio_irq_unmask, .irq_set_type = zynq_gpio_set_irq_type, .irq_set_wake = zynq_gpio_set_wake, |
c2df3de0d gpio: zynq: prope... |
592 593 |
.irq_request_resources = zynq_gpio_irq_reqres, .irq_release_resources = zynq_gpio_irq_relres, |
a19467788 gpio: zynq: Mask ... |
594 |
.flags = IRQCHIP_MASK_ON_SUSPEND, |
3242ba117 gpio: Add driver ... |
595 |
}; |
5a2533a74 gpio: zynq: Reduc... |
596 597 598 599 |
static void zynq_gpio_handle_bank_irq(struct zynq_gpio *gpio, unsigned int bank_num, unsigned long pending) { |
bdf7a4ae3 gpio: Added suppo... |
600 |
unsigned int bank_offset = gpio->p_data->bank_min[bank_num]; |
f0fbe7bce gpio: Move irqdom... |
601 |
struct irq_domain *irqdomain = gpio->chip.irq.domain; |
5a2533a74 gpio: zynq: Reduc... |
602 603 604 605 606 607 608 |
int offset; if (!pending) return; for_each_set_bit(offset, &pending, 32) { unsigned int gpio_irq; |
016da1443 gpio: zynq: Take ... |
609 |
gpio_irq = irq_find_mapping(irqdomain, offset + bank_offset); |
5a2533a74 gpio: zynq: Reduc... |
610 611 612 |
generic_handle_irq(gpio_irq); } } |
3242ba117 gpio: Add driver ... |
613 614 |
/** * zynq_gpio_irqhandler - IRQ handler for the gpio banks of a gpio device |
3242ba117 gpio: Add driver ... |
615 616 617 618 619 620 621 622 |
* @desc: irq descriptor instance of the 'irq' * * This function reads the Interrupt Status Register of each bank to get the * gpio pin number which has triggered an interrupt. It then acks the triggered * interrupt and calls the pin specific handler set by the higher layer * application for that pin. * Note: A bug is reported if no handler is set for the gpio pin. */ |
bd0b9ac40 genirq: Remove ir... |
623 |
static void zynq_gpio_irqhandler(struct irq_desc *desc) |
3242ba117 gpio: Add driver ... |
624 625 626 |
{ u32 int_sts, int_enb; unsigned int bank_num; |
fa9795d11 gpio: zynq: use c... |
627 |
struct zynq_gpio *gpio = |
31a894475 gpio: zynq: use g... |
628 |
gpiochip_get_data(irq_desc_get_handler_data(desc)); |
3242ba117 gpio: Add driver ... |
629 630 631 |
struct irq_chip *irqchip = irq_desc_get_chip(desc); chained_irq_enter(irqchip, desc); |
bdf7a4ae3 gpio: Added suppo... |
632 |
for (bank_num = 0; bank_num < gpio->p_data->max_bank; bank_num++) { |
3242ba117 gpio: Add driver ... |
633 634 635 636 |
int_sts = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_INTSTS_OFFSET(bank_num)); int_enb = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_INTMASK_OFFSET(bank_num)); |
5a2533a74 gpio: zynq: Reduc... |
637 |
zynq_gpio_handle_bank_irq(gpio, bank_num, int_sts & ~int_enb); |
3242ba117 gpio: Add driver ... |
638 639 640 641 |
} chained_irq_exit(irqchip, desc); } |
e11de4de2 gpio: zynq: Add s... |
642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 |
static void zynq_gpio_save_context(struct zynq_gpio *gpio) { unsigned int bank_num; for (bank_num = 0; bank_num < gpio->p_data->max_bank; bank_num++) { gpio->context.datalsw[bank_num] = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_DATA_LSW_OFFSET(bank_num)); gpio->context.datamsw[bank_num] = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_DATA_MSW_OFFSET(bank_num)); gpio->context.dirm[bank_num] = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); gpio->context.int_en[bank_num] = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_INTMASK_OFFSET(bank_num)); gpio->context.int_type[bank_num] = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_INTTYPE_OFFSET(bank_num)); gpio->context.int_polarity[bank_num] = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_INTPOL_OFFSET(bank_num)); gpio->context.int_any[bank_num] = readl_relaxed(gpio->base_addr + ZYNQ_GPIO_INTANY_OFFSET(bank_num)); } } static void zynq_gpio_restore_context(struct zynq_gpio *gpio) { unsigned int bank_num; for (bank_num = 0; bank_num < gpio->p_data->max_bank; bank_num++) { |
8457f26af gpio: zynq: Fix f... |
674 675 |
writel_relaxed(ZYNQ_GPIO_IXR_DISABLE_ALL, gpio->base_addr + ZYNQ_GPIO_INTDIS_OFFSET(bank_num)); |
e11de4de2 gpio: zynq: Add s... |
676 677 678 679 680 681 682 683 684 |
writel_relaxed(gpio->context.datalsw[bank_num], gpio->base_addr + ZYNQ_GPIO_DATA_LSW_OFFSET(bank_num)); writel_relaxed(gpio->context.datamsw[bank_num], gpio->base_addr + ZYNQ_GPIO_DATA_MSW_OFFSET(bank_num)); writel_relaxed(gpio->context.dirm[bank_num], gpio->base_addr + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); |
e11de4de2 gpio: zynq: Add s... |
685 686 687 688 689 690 691 692 693 |
writel_relaxed(gpio->context.int_type[bank_num], gpio->base_addr + ZYNQ_GPIO_INTTYPE_OFFSET(bank_num)); writel_relaxed(gpio->context.int_polarity[bank_num], gpio->base_addr + ZYNQ_GPIO_INTPOL_OFFSET(bank_num)); writel_relaxed(gpio->context.int_any[bank_num], gpio->base_addr + ZYNQ_GPIO_INTANY_OFFSET(bank_num)); |
8457f26af gpio: zynq: Fix f... |
694 695 696 |
writel_relaxed(~(gpio->context.int_en[bank_num]), gpio->base_addr + ZYNQ_GPIO_INTEN_OFFSET(bank_num)); |
e11de4de2 gpio: zynq: Add s... |
697 698 |
} } |
eb73d6eaa gpio: zynq: Fix e... |
699 |
|
3242ba117 gpio: Add driver ... |
700 701 |
static int __maybe_unused zynq_gpio_suspend(struct device *dev) { |
a76e865ee gpio: zynq: simpl... |
702 |
struct zynq_gpio *gpio = dev_get_drvdata(dev); |
5e3a8ecd7 gpio: zynq: Remov... |
703 |
struct irq_data *data = irq_get_irq_data(gpio->irq); |
59e22114b gpio: zynq: Fixed... |
704 |
|
e11de4de2 gpio: zynq: Add s... |
705 706 |
if (!irqd_is_wakeup_set(data)) { zynq_gpio_save_context(gpio); |
3242ba117 gpio: Add driver ... |
707 |
return pm_runtime_force_suspend(dev); |
e11de4de2 gpio: zynq: Add s... |
708 |
} |
3242ba117 gpio: Add driver ... |
709 710 711 712 713 714 |
return 0; } static int __maybe_unused zynq_gpio_resume(struct device *dev) { |
a76e865ee gpio: zynq: simpl... |
715 |
struct zynq_gpio *gpio = dev_get_drvdata(dev); |
5e3a8ecd7 gpio: zynq: Remov... |
716 |
struct irq_data *data = irq_get_irq_data(gpio->irq); |
e11de4de2 gpio: zynq: Add s... |
717 |
int ret; |
59e22114b gpio: zynq: Fixed... |
718 |
|
e11de4de2 gpio: zynq: Add s... |
719 720 721 722 723 |
if (!irqd_is_wakeup_set(data)) { ret = pm_runtime_force_resume(dev); zynq_gpio_restore_context(gpio); return ret; } |
3242ba117 gpio: Add driver ... |
724 725 726 727 728 729 |
return 0; } static int __maybe_unused zynq_gpio_runtime_suspend(struct device *dev) { |
38ccad024 gpio: gpio-zynq: ... |
730 |
struct zynq_gpio *gpio = dev_get_drvdata(dev); |
3242ba117 gpio: Add driver ... |
731 732 733 734 735 736 737 738 |
clk_disable_unprepare(gpio->clk); return 0; } static int __maybe_unused zynq_gpio_runtime_resume(struct device *dev) { |
38ccad024 gpio: gpio-zynq: ... |
739 |
struct zynq_gpio *gpio = dev_get_drvdata(dev); |
3242ba117 gpio: Add driver ... |
740 741 742 |
return clk_prepare_enable(gpio->clk); } |
2717cfcaf gpio: zynq: Fix w... |
743 |
static int zynq_gpio_request(struct gpio_chip *chip, unsigned int offset) |
3242ba117 gpio: Add driver ... |
744 745 |
{ int ret; |
58383c784 gpio: change memb... |
746 |
ret = pm_runtime_get_sync(chip->parent); |
3242ba117 gpio: Add driver ... |
747 748 749 750 751 752 753 |
/* * If the device is already active pm_runtime_get() will return 1 on * success, but gpio_request still needs to return 0. */ return ret < 0 ? ret : 0; } |
2717cfcaf gpio: zynq: Fix w... |
754 |
static void zynq_gpio_free(struct gpio_chip *chip, unsigned int offset) |
3242ba117 gpio: Add driver ... |
755 |
{ |
58383c784 gpio: change memb... |
756 |
pm_runtime_put(chip->parent); |
3242ba117 gpio: Add driver ... |
757 758 759 760 |
} static const struct dev_pm_ops zynq_gpio_dev_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(zynq_gpio_suspend, zynq_gpio_resume) |
6ed23b806 PM: Merge the SET... |
761 |
SET_RUNTIME_PM_OPS(zynq_gpio_runtime_suspend, |
16ee62e56 gpio: zynq: Fix d... |
762 |
zynq_gpio_runtime_resume, NULL) |
3242ba117 gpio: Add driver ... |
763 |
}; |
bdf7a4ae3 gpio: Added suppo... |
764 765 |
static const struct zynq_platform_data zynqmp_gpio_def = { .label = "zynqmp_gpio", |
06aa09081 gpio: zynq: Provi... |
766 |
.quirks = GPIO_QUIRK_DATA_RO_BUG, |
bdf7a4ae3 gpio: Added suppo... |
767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 |
.ngpio = ZYNQMP_GPIO_NR_GPIOS, .max_bank = ZYNQMP_GPIO_MAX_BANK, .bank_min[0] = ZYNQ_GPIO_BANK0_PIN_MIN(MP), .bank_max[0] = ZYNQ_GPIO_BANK0_PIN_MAX(MP), .bank_min[1] = ZYNQ_GPIO_BANK1_PIN_MIN(MP), .bank_max[1] = ZYNQ_GPIO_BANK1_PIN_MAX(MP), .bank_min[2] = ZYNQ_GPIO_BANK2_PIN_MIN(MP), .bank_max[2] = ZYNQ_GPIO_BANK2_PIN_MAX(MP), .bank_min[3] = ZYNQ_GPIO_BANK3_PIN_MIN(MP), .bank_max[3] = ZYNQ_GPIO_BANK3_PIN_MAX(MP), .bank_min[4] = ZYNQ_GPIO_BANK4_PIN_MIN(MP), .bank_max[4] = ZYNQ_GPIO_BANK4_PIN_MAX(MP), .bank_min[5] = ZYNQ_GPIO_BANK5_PIN_MIN(MP), .bank_max[5] = ZYNQ_GPIO_BANK5_PIN_MAX(MP), }; static const struct zynq_platform_data zynq_gpio_def = { .label = "zynq_gpio", |
06aa09081 gpio: zynq: Provi... |
785 |
.quirks = ZYNQ_GPIO_QUIRK_IS_ZYNQ | GPIO_QUIRK_DATA_RO_BUG, |
bdf7a4ae3 gpio: Added suppo... |
786 787 788 789 790 791 792 793 794 795 796 797 798 |
.ngpio = ZYNQ_GPIO_NR_GPIOS, .max_bank = ZYNQ_GPIO_MAX_BANK, .bank_min[0] = ZYNQ_GPIO_BANK0_PIN_MIN(), .bank_max[0] = ZYNQ_GPIO_BANK0_PIN_MAX(), .bank_min[1] = ZYNQ_GPIO_BANK1_PIN_MIN(), .bank_max[1] = ZYNQ_GPIO_BANK1_PIN_MAX(), .bank_min[2] = ZYNQ_GPIO_BANK2_PIN_MIN(), .bank_max[2] = ZYNQ_GPIO_BANK2_PIN_MAX(), .bank_min[3] = ZYNQ_GPIO_BANK3_PIN_MIN(), .bank_max[3] = ZYNQ_GPIO_BANK3_PIN_MAX(), }; static const struct of_device_id zynq_gpio_of_match[] = { |
7808c42b4 gpio: zynq: remov... |
799 800 |
{ .compatible = "xlnx,zynq-gpio-1.0", .data = &zynq_gpio_def }, { .compatible = "xlnx,zynqmp-gpio-1.0", .data = &zynqmp_gpio_def }, |
bdf7a4ae3 gpio: Added suppo... |
801 802 803 |
{ /* end of table */ } }; MODULE_DEVICE_TABLE(of, zynq_gpio_of_match); |
3242ba117 gpio: Add driver ... |
804 805 806 807 808 809 810 811 812 813 814 815 816 |
/** * zynq_gpio_probe - Initialization method for a zynq_gpio device * @pdev: platform device instance * * This function allocates memory resources for the gpio device and registers * all the banks of the device. It will also set up interrupts for the gpio * pins. * Note: Interrupts are disabled for all the banks during initialization. * * Return: 0 on success, negative error otherwise. */ static int zynq_gpio_probe(struct platform_device *pdev) { |
59e22114b gpio: zynq: Fixed... |
817 |
int ret, bank_num; |
3242ba117 gpio: Add driver ... |
818 819 |
struct zynq_gpio *gpio; struct gpio_chip *chip; |
f6a7053dd gpio: zynq: Pass ... |
820 |
struct gpio_irq_chip *girq; |
bdf7a4ae3 gpio: Added suppo... |
821 |
const struct of_device_id *match; |
3242ba117 gpio: Add driver ... |
822 823 824 825 |
gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); if (!gpio) return -ENOMEM; |
bdf7a4ae3 gpio: Added suppo... |
826 827 828 829 830 831 832 |
match = of_match_node(zynq_gpio_of_match, pdev->dev.of_node); if (!match) { dev_err(&pdev->dev, "of_match_node() failed "); return -EINVAL; } gpio->p_data = match->data; |
3242ba117 gpio: Add driver ... |
833 |
platform_set_drvdata(pdev, gpio); |
77bc0e69c gpio: zynq: use d... |
834 |
gpio->base_addr = devm_platform_ioremap_resource(pdev, 0); |
3242ba117 gpio: Add driver ... |
835 836 |
if (IS_ERR(gpio->base_addr)) return PTR_ERR(gpio->base_addr); |
59e22114b gpio: zynq: Fixed... |
837 |
gpio->irq = platform_get_irq(pdev, 0); |
15bddb7d7 gpio: Remove dev_... |
838 |
if (gpio->irq < 0) |
59e22114b gpio: zynq: Fixed... |
839 |
return gpio->irq; |
3242ba117 gpio: Add driver ... |
840 841 842 |
/* configure the gpio chip */ chip = &gpio->chip; |
bdf7a4ae3 gpio: Added suppo... |
843 |
chip->label = gpio->p_data->label; |
3242ba117 gpio: Add driver ... |
844 |
chip->owner = THIS_MODULE; |
58383c784 gpio: change memb... |
845 |
chip->parent = &pdev->dev; |
3242ba117 gpio: Add driver ... |
846 847 848 849 850 851 |
chip->get = zynq_gpio_get_value; chip->set = zynq_gpio_set_value; chip->request = zynq_gpio_request; chip->free = zynq_gpio_free; chip->direction_input = zynq_gpio_dir_in; chip->direction_output = zynq_gpio_dir_out; |
6169005ce gpio: zynq: Repor... |
852 |
chip->get_direction = zynq_gpio_get_direction; |
060f3ebf6 gpio: zynq: Setup... |
853 |
chip->base = of_alias_get_id(pdev->dev.of_node, "gpio"); |
bdf7a4ae3 gpio: Added suppo... |
854 |
chip->ngpio = gpio->p_data->ngpio; |
3242ba117 gpio: Add driver ... |
855 |
|
3773c195d gpio: zynq: Do PM... |
856 |
/* Retrieve GPIO clock */ |
3242ba117 gpio: Add driver ... |
857 858 859 860 861 862 |
gpio->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(gpio->clk)) { dev_err(&pdev->dev, "input clock not found. "); return PTR_ERR(gpio->clk); } |
0f84f29ff gpio: zynq: initi... |
863 864 865 866 867 868 |
ret = clk_prepare_enable(gpio->clk); if (ret) { dev_err(&pdev->dev, "Unable to enable clock. "); return ret; } |
3773c195d gpio: zynq: Do PM... |
869 |
|
0f84f29ff gpio: zynq: initi... |
870 |
pm_runtime_set_active(&pdev->dev); |
3773c195d gpio: zynq: Do PM... |
871 872 873 |
pm_runtime_enable(&pdev->dev); ret = pm_runtime_get_sync(&pdev->dev); if (ret < 0) |
615d23f80 gpio: zynq: Fix t... |
874 |
goto err_pm_dis; |
3242ba117 gpio: Add driver ... |
875 |
|
3242ba117 gpio: Add driver ... |
876 |
/* disable interrupts for all banks */ |
bdf7a4ae3 gpio: Added suppo... |
877 |
for (bank_num = 0; bank_num < gpio->p_data->max_bank; bank_num++) |
3242ba117 gpio: Add driver ... |
878 879 |
writel_relaxed(ZYNQ_GPIO_IXR_DISABLE_ALL, gpio->base_addr + ZYNQ_GPIO_INTDIS_OFFSET(bank_num)); |
f6a7053dd gpio: zynq: Pass ... |
880 881 882 883 884 885 886 887 888 889 890 |
/* Set up the GPIO irqchip */ girq = &chip->irq; girq->chip = &zynq_gpio_edge_irqchip; girq->parent_handler = zynq_gpio_irqhandler; girq->num_parents = 1; girq->parents = devm_kcalloc(&pdev->dev, 1, sizeof(*girq->parents), GFP_KERNEL); if (!girq->parents) { ret = -ENOMEM; goto err_pm_put; |
3242ba117 gpio: Add driver ... |
891 |
} |
f6a7053dd gpio: zynq: Pass ... |
892 893 894 |
girq->parents[0] = gpio->irq; girq->default_type = IRQ_TYPE_NONE; girq->handler = handle_level_irq; |
3242ba117 gpio: Add driver ... |
895 |
|
f6a7053dd gpio: zynq: Pass ... |
896 897 898 899 900 901 902 |
/* report a bug if gpio chip registration fails */ ret = gpiochip_add_data(chip, gpio); if (ret) { dev_err(&pdev->dev, "Failed to add gpio chip "); goto err_pm_put; } |
3242ba117 gpio: Add driver ... |
903 |
|
3773c195d gpio: zynq: Do PM... |
904 |
pm_runtime_put(&pdev->dev); |
3242ba117 gpio: Add driver ... |
905 |
|
3242ba117 gpio: Add driver ... |
906 |
return 0; |
3773c195d gpio: zynq: Do PM... |
907 908 |
err_pm_put: pm_runtime_put(&pdev->dev); |
615d23f80 gpio: zynq: Fix t... |
909 910 |
err_pm_dis: pm_runtime_disable(&pdev->dev); |
0f84f29ff gpio: zynq: initi... |
911 |
clk_disable_unprepare(gpio->clk); |
3242ba117 gpio: Add driver ... |
912 913 914 915 916 917 918 919 920 921 922 923 |
return ret; } /** * zynq_gpio_remove - Driver removal function * @pdev: platform device instance * * Return: 0 always */ static int zynq_gpio_remove(struct platform_device *pdev) { |
3242ba117 gpio: Add driver ... |
924 925 926 |
struct zynq_gpio *gpio = platform_get_drvdata(pdev); pm_runtime_get_sync(&pdev->dev); |
da26d5d80 gpio: remove rema... |
927 |
gpiochip_remove(&gpio->chip); |
3242ba117 gpio: Add driver ... |
928 929 |
clk_disable_unprepare(gpio->clk); device_set_wakeup_capable(&pdev->dev, 0); |
6b956af08 gpio: zynq: Fix p... |
930 |
pm_runtime_disable(&pdev->dev); |
3242ba117 gpio: Add driver ... |
931 932 |
return 0; } |
3242ba117 gpio: Add driver ... |
933 934 935 |
static struct platform_driver zynq_gpio_driver = { .driver = { .name = DRIVER_NAME, |
3242ba117 gpio: Add driver ... |
936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 |
.pm = &zynq_gpio_dev_pm_ops, .of_match_table = zynq_gpio_of_match, }, .probe = zynq_gpio_probe, .remove = zynq_gpio_remove, }; /** * zynq_gpio_init - Initial driver registration call * * Return: value from platform_driver_register */ static int __init zynq_gpio_init(void) { return platform_driver_register(&zynq_gpio_driver); } postcore_initcall(zynq_gpio_init); |
80d2bf55a gpio: zynq: add m... |
953 954 955 956 957 |
static void __exit zynq_gpio_exit(void) { platform_driver_unregister(&zynq_gpio_driver); } module_exit(zynq_gpio_exit); |
3242ba117 gpio: Add driver ... |
958 959 960 |
MODULE_AUTHOR("Xilinx Inc."); MODULE_DESCRIPTION("Zynq GPIO driver"); MODULE_LICENSE("GPL"); |