Blame view

drivers/gpio/gpio-zynq.c 24.6 KB
3242ba117   Harini Katakam   gpio: Add driver ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  /*
   * Xilinx Zynq GPIO device driver
   *
   * Copyright (C) 2009 - 2014 Xilinx, Inc.
   *
   * This program is free software; you can redistribute it and/or modify it under
   * the terms of the GNU General Public License as published by the Free Software
   * Foundation; either version 2 of the License, or (at your option) any later
   * version.
   */
  
  #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   Anurag Kumar Vulisha   gpio: Added suppo...
21
  #include <linux/of.h>
3242ba117   Harini Katakam   gpio: Add driver ...
22
23
24
25
26
  
  #define DRIVER_NAME "zynq-gpio"
  
  /* Maximum banks */
  #define ZYNQ_GPIO_MAX_BANK	4
bdf7a4ae3   Anurag Kumar Vulisha   gpio: Added suppo...
27
  #define ZYNQMP_GPIO_MAX_BANK	6
3242ba117   Harini Katakam   gpio: Add driver ...
28
29
30
31
32
  
  #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   Anurag Kumar Vulisha   gpio: Added suppo...
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
  #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   Harini Katakam   gpio: Add driver ...
61
62
63
64
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
93
94
95
96
  
  
  /* 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 */
  #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
e3296f19c   Nava kishore Manne   gpio: Added zynq ...
97
98
  /* For GPIO quirks */
  #define ZYNQ_GPIO_QUIRK_FOO	BIT(0)
3242ba117   Harini Katakam   gpio: Add driver ...
99
100
101
102
103
  /**
   * 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   Ezra Savard   gpio: zynq: Fixed...
104
   * @irq:	interrupt for the GPIO device
bdf7a4ae3   Anurag Kumar Vulisha   gpio: Added suppo...
105
   * @p_data:	pointer to platform data
3242ba117   Harini Katakam   gpio: Add driver ...
106
107
108
109
110
   */
  struct zynq_gpio {
  	struct gpio_chip chip;
  	void __iomem *base_addr;
  	struct clk *clk;
59e22114b   Ezra Savard   gpio: zynq: Fixed...
111
  	int irq;
bdf7a4ae3   Anurag Kumar Vulisha   gpio: Added suppo...
112
113
114
115
116
117
118
119
120
121
122
123
124
  	const struct zynq_platform_data *p_data;
  };
  
  /**
   * struct zynq_platform_data -  zynq gpio platform data structure
   * @label:	string to store in gpio->label
   * @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
  */
  struct zynq_platform_data {
  	const char *label;
e3296f19c   Nava kishore Manne   gpio: Added zynq ...
125
  	u32 quirks;
bdf7a4ae3   Anurag Kumar Vulisha   gpio: Added suppo...
126
127
128
129
  	u16 ngpio;
  	int max_bank;
  	int bank_min[ZYNQMP_GPIO_MAX_BANK];
  	int bank_max[ZYNQMP_GPIO_MAX_BANK];
3242ba117   Harini Katakam   gpio: Add driver ...
130
  };
6dd859508   Lars-Peter Clausen   gpio: zynq: Fix I...
131
132
  static struct irq_chip zynq_gpio_level_irqchip;
  static struct irq_chip zynq_gpio_edge_irqchip;
fa9795d11   Linus Walleij   gpio: zynq: use c...
133

3242ba117   Harini Katakam   gpio: Add driver ...
134
135
136
137
138
139
140
141
142
143
144
145
146
  /**
   * 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
   *
   * 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   Anurag Kumar Vulisha   gpio: Added suppo...
147
148
  					  unsigned int *bank_pin_num,
  					  struct zynq_gpio *gpio)
3242ba117   Harini Katakam   gpio: Add driver ...
149
  {
bdf7a4ae3   Anurag Kumar Vulisha   gpio: Added suppo...
150
151
152
153
154
155
156
157
158
159
  	int bank;
  
  	for (bank = 0; bank < gpio->p_data->max_bank; bank++) {
  		if ((pin_num >= gpio->p_data->bank_min[bank]) &&
  			(pin_num <= gpio->p_data->bank_max[bank])) {
  				*bank_num = bank;
  				*bank_pin_num = pin_num -
  						gpio->p_data->bank_min[bank];
  				return;
  		}
3242ba117   Harini Katakam   gpio: Add driver ...
160
  	}
3242ba117   Harini Katakam   gpio: Add driver ...
161

bdf7a4ae3   Anurag Kumar Vulisha   gpio: Added suppo...
162
163
164
165
166
  	/* default */
  	WARN(true, "invalid GPIO pin number: %u", pin_num);
  	*bank_num = 0;
  	*bank_pin_num = 0;
  }
016da1443   Lars-Peter Clausen   gpio: zynq: Take ...
167

3242ba117   Harini Katakam   gpio: Add driver ...
168
169
170
171
172
173
174
175
176
177
178
179
180
  /**
   * 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   Linus Walleij   gpio: zynq: use g...
181
  	struct zynq_gpio *gpio = gpiochip_get_data(chip);
3242ba117   Harini Katakam   gpio: Add driver ...
182

bdf7a4ae3   Anurag Kumar Vulisha   gpio: Added suppo...
183
  	zynq_gpio_get_bank_pin(pin, &bank_num, &bank_pin_num, gpio);
3242ba117   Harini Katakam   gpio: Add driver ...
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
  
  	data = readl_relaxed(gpio->base_addr +
  			     ZYNQ_GPIO_DATA_RO_OFFSET(bank_num));
  
  	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   Linus Walleij   gpio: zynq: use g...
205
  	struct zynq_gpio *gpio = gpiochip_get_data(chip);
3242ba117   Harini Katakam   gpio: Add driver ...
206

bdf7a4ae3   Anurag Kumar Vulisha   gpio: Added suppo...
207
  	zynq_gpio_get_bank_pin(pin, &bank_num, &bank_pin_num, gpio);
3242ba117   Harini Katakam   gpio: Add driver ...
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
  
  	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;
e3296f19c   Nava kishore Manne   gpio: Added zynq ...
241
  	bool is_zynq_gpio;
3242ba117   Harini Katakam   gpio: Add driver ...
242
  	unsigned int bank_num, bank_pin_num;
31a894475   Linus Walleij   gpio: zynq: use g...
243
  	struct zynq_gpio *gpio = gpiochip_get_data(chip);
3242ba117   Harini Katakam   gpio: Add driver ...
244

e3296f19c   Nava kishore Manne   gpio: Added zynq ...
245
  	is_zynq_gpio = gpio->p_data->quirks & ZYNQ_GPIO_QUIRK_FOO;
bdf7a4ae3   Anurag Kumar Vulisha   gpio: Added suppo...
246
  	zynq_gpio_get_bank_pin(pin, &bank_num, &bank_pin_num, gpio);
3242ba117   Harini Katakam   gpio: Add driver ...
247

e3296f19c   Nava kishore Manne   gpio: Added zynq ...
248
249
250
251
252
253
  	/*
  	 * On zynq bank 0 pins 7 and 8 are special and cannot be used
  	 * as inputs.
  	 */
  	if (is_zynq_gpio && bank_num == 0 &&
  		(bank_pin_num == 7 || bank_pin_num == 8))
3242ba117   Harini Katakam   gpio: Add driver ...
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
  		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   Linus Walleij   gpio: zynq: use g...
281
  	struct zynq_gpio *gpio = gpiochip_get_data(chip);
3242ba117   Harini Katakam   gpio: Add driver ...
282

bdf7a4ae3   Anurag Kumar Vulisha   gpio: Added suppo...
283
  	zynq_gpio_get_bank_pin(pin, &bank_num, &bank_pin_num, gpio);
3242ba117   Harini Katakam   gpio: Add driver ...
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
  
  	/* 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;
  }
  
  /**
   * 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   Linus Walleij   gpio: zynq: use c...
311
  	struct zynq_gpio *gpio =
31a894475   Linus Walleij   gpio: zynq: use g...
312
  		gpiochip_get_data(irq_data_get_irq_chip_data(irq_data));
3242ba117   Harini Katakam   gpio: Add driver ...
313
314
  
  	device_pin_num = irq_data->hwirq;
bdf7a4ae3   Anurag Kumar Vulisha   gpio: Added suppo...
315
  	zynq_gpio_get_bank_pin(device_pin_num, &bank_num, &bank_pin_num, gpio);
3242ba117   Harini Katakam   gpio: Add driver ...
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
  	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   Linus Walleij   gpio: zynq: use c...
332
  	struct zynq_gpio *gpio =
31a894475   Linus Walleij   gpio: zynq: use g...
333
  		gpiochip_get_data(irq_data_get_irq_chip_data(irq_data));
3242ba117   Harini Katakam   gpio: Add driver ...
334
335
  
  	device_pin_num = irq_data->hwirq;
bdf7a4ae3   Anurag Kumar Vulisha   gpio: Added suppo...
336
  	zynq_gpio_get_bank_pin(device_pin_num, &bank_num, &bank_pin_num, gpio);
3242ba117   Harini Katakam   gpio: Add driver ...
337
338
339
340
341
  	writel_relaxed(BIT(bank_pin_num),
  		       gpio->base_addr + ZYNQ_GPIO_INTEN_OFFSET(bank_num));
  }
  
  /**
190dc2e68   Lars-Peter Clausen   gpio: zynq: Clear...
342
343
344
345
346
347
348
349
350
351
   * 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   Linus Walleij   gpio: zynq: use c...
352
  	struct zynq_gpio *gpio =
31a894475   Linus Walleij   gpio: zynq: use g...
353
  		gpiochip_get_data(irq_data_get_irq_chip_data(irq_data));
190dc2e68   Lars-Peter Clausen   gpio: zynq: Clear...
354
355
  
  	device_pin_num = irq_data->hwirq;
bdf7a4ae3   Anurag Kumar Vulisha   gpio: Added suppo...
356
  	zynq_gpio_get_bank_pin(device_pin_num, &bank_num, &bank_pin_num, gpio);
190dc2e68   Lars-Peter Clausen   gpio: zynq: Clear...
357
358
359
360
361
362
363
364
365
  	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   Colin Cronin   Drivers: gpio: Fi...
366
   * Clears the INTSTS bit and unmasks the given interrupt.
190dc2e68   Lars-Peter Clausen   gpio: zynq: Clear...
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
   */
  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   Harini Katakam   gpio: Add driver ...
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
   * 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   Linus Walleij   gpio: zynq: use c...
403
  	struct zynq_gpio *gpio =
31a894475   Linus Walleij   gpio: zynq: use g...
404
  		gpiochip_get_data(irq_data_get_irq_chip_data(irq_data));
3242ba117   Harini Katakam   gpio: Add driver ...
405
406
  
  	device_pin_num = irq_data->hwirq;
bdf7a4ae3   Anurag Kumar Vulisha   gpio: Added suppo...
407
  	zynq_gpio_get_bank_pin(device_pin_num, &bank_num, &bank_pin_num, gpio);
3242ba117   Harini Katakam   gpio: Add driver ...
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
  
  	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   Lars-Peter Clausen   gpio: zynq: Fix I...
453
454
  
  	if (type & IRQ_TYPE_LEVEL_MASK) {
47c084629   Thomas Gleixner   gpio/zynq: Use ir...
455
  		irq_set_chip_handler_name_locked(irq_data,
6dd859508   Lars-Peter Clausen   gpio: zynq: Fix I...
456
457
  			&zynq_gpio_level_irqchip, handle_fasteoi_irq, NULL);
  	} else {
47c084629   Thomas Gleixner   gpio/zynq: Use ir...
458
  		irq_set_chip_handler_name_locked(irq_data,
6dd859508   Lars-Peter Clausen   gpio: zynq: Fix I...
459
460
  			&zynq_gpio_edge_irqchip, handle_level_irq, NULL);
  	}
3242ba117   Harini Katakam   gpio: Add driver ...
461
462
463
464
465
  	return 0;
  }
  
  static int zynq_gpio_set_wake(struct irq_data *data, unsigned int on)
  {
fa9795d11   Linus Walleij   gpio: zynq: use c...
466
  	struct zynq_gpio *gpio =
31a894475   Linus Walleij   gpio: zynq: use g...
467
  		gpiochip_get_data(irq_data_get_irq_chip_data(data));
59e22114b   Ezra Savard   gpio: zynq: Fixed...
468
469
  
  	irq_set_irq_wake(gpio->irq, on);
3242ba117   Harini Katakam   gpio: Add driver ...
470
471
472
473
474
  
  	return 0;
  }
  
  /* irq chip descriptor */
6dd859508   Lars-Peter Clausen   gpio: zynq: Fix I...
475
  static struct irq_chip zynq_gpio_level_irqchip = {
3242ba117   Harini Katakam   gpio: Add driver ...
476
  	.name		= DRIVER_NAME,
190dc2e68   Lars-Peter Clausen   gpio: zynq: Clear...
477
  	.irq_enable	= zynq_gpio_irq_enable,
6dd859508   Lars-Peter Clausen   gpio: zynq: Fix I...
478
479
480
481
482
  	.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,
a19467788   Ezra Savard   gpio: zynq: Mask ...
483
484
  	.flags		= IRQCHIP_EOI_THREADED | IRQCHIP_EOI_IF_HANDLED |
  			  IRQCHIP_MASK_ON_SUSPEND,
6dd859508   Lars-Peter Clausen   gpio: zynq: Fix I...
485
486
487
488
489
490
  };
  
  static struct irq_chip zynq_gpio_edge_irqchip = {
  	.name		= DRIVER_NAME,
  	.irq_enable	= zynq_gpio_irq_enable,
  	.irq_ack	= zynq_gpio_irq_ack,
3242ba117   Harini Katakam   gpio: Add driver ...
491
492
493
494
  	.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,
a19467788   Ezra Savard   gpio: zynq: Mask ...
495
  	.flags		= IRQCHIP_MASK_ON_SUSPEND,
3242ba117   Harini Katakam   gpio: Add driver ...
496
  };
5a2533a74   Lars-Peter Clausen   gpio: zynq: Reduc...
497
498
499
500
  static void zynq_gpio_handle_bank_irq(struct zynq_gpio *gpio,
  				      unsigned int bank_num,
  				      unsigned long pending)
  {
bdf7a4ae3   Anurag Kumar Vulisha   gpio: Added suppo...
501
  	unsigned int bank_offset = gpio->p_data->bank_min[bank_num];
5a2533a74   Lars-Peter Clausen   gpio: zynq: Reduc...
502
503
504
505
506
507
508
509
  	struct irq_domain *irqdomain = gpio->chip.irqdomain;
  	int offset;
  
  	if (!pending)
  		return;
  
  	for_each_set_bit(offset, &pending, 32) {
  		unsigned int gpio_irq;
016da1443   Lars-Peter Clausen   gpio: zynq: Take ...
510
  		gpio_irq = irq_find_mapping(irqdomain, offset + bank_offset);
5a2533a74   Lars-Peter Clausen   gpio: zynq: Reduc...
511
512
513
  		generic_handle_irq(gpio_irq);
  	}
  }
3242ba117   Harini Katakam   gpio: Add driver ...
514
515
516
517
518
519
520
521
522
523
524
  /**
   * zynq_gpio_irqhandler - IRQ handler for the gpio banks of a gpio device
   * @irq:	irq number of the gpio bank where interrupt has occurred
   * @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   Thomas Gleixner   genirq: Remove ir...
525
  static void zynq_gpio_irqhandler(struct irq_desc *desc)
3242ba117   Harini Katakam   gpio: Add driver ...
526
527
528
  {
  	u32 int_sts, int_enb;
  	unsigned int bank_num;
fa9795d11   Linus Walleij   gpio: zynq: use c...
529
  	struct zynq_gpio *gpio =
31a894475   Linus Walleij   gpio: zynq: use g...
530
  		gpiochip_get_data(irq_desc_get_handler_data(desc));
3242ba117   Harini Katakam   gpio: Add driver ...
531
532
533
  	struct irq_chip *irqchip = irq_desc_get_chip(desc);
  
  	chained_irq_enter(irqchip, desc);
bdf7a4ae3   Anurag Kumar Vulisha   gpio: Added suppo...
534
  	for (bank_num = 0; bank_num < gpio->p_data->max_bank; bank_num++) {
3242ba117   Harini Katakam   gpio: Add driver ...
535
536
537
538
  		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   Lars-Peter Clausen   gpio: zynq: Reduc...
539
  		zynq_gpio_handle_bank_irq(gpio, bank_num, int_sts & ~int_enb);
3242ba117   Harini Katakam   gpio: Add driver ...
540
541
542
543
544
545
546
  	}
  
  	chained_irq_exit(irqchip, desc);
  }
  
  static int __maybe_unused zynq_gpio_suspend(struct device *dev)
  {
59e22114b   Ezra Savard   gpio: zynq: Fixed...
547
548
549
550
551
  	struct platform_device *pdev = to_platform_device(dev);
  	int irq = platform_get_irq(pdev, 0);
  	struct irq_data *data = irq_get_irq_data(irq);
  
  	if (!irqd_is_wakeup_set(data))
3242ba117   Harini Katakam   gpio: Add driver ...
552
553
554
555
556
557
558
  		return pm_runtime_force_suspend(dev);
  
  	return 0;
  }
  
  static int __maybe_unused zynq_gpio_resume(struct device *dev)
  {
59e22114b   Ezra Savard   gpio: zynq: Fixed...
559
560
561
562
563
  	struct platform_device *pdev = to_platform_device(dev);
  	int irq = platform_get_irq(pdev, 0);
  	struct irq_data *data = irq_get_irq_data(irq);
  
  	if (!irqd_is_wakeup_set(data))
3242ba117   Harini Katakam   gpio: Add driver ...
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
  		return pm_runtime_force_resume(dev);
  
  	return 0;
  }
  
  static int __maybe_unused zynq_gpio_runtime_suspend(struct device *dev)
  {
  	struct platform_device *pdev = to_platform_device(dev);
  	struct zynq_gpio *gpio = platform_get_drvdata(pdev);
  
  	clk_disable_unprepare(gpio->clk);
  
  	return 0;
  }
  
  static int __maybe_unused zynq_gpio_runtime_resume(struct device *dev)
  {
  	struct platform_device *pdev = to_platform_device(dev);
  	struct zynq_gpio *gpio = platform_get_drvdata(pdev);
  
  	return clk_prepare_enable(gpio->clk);
  }
  
  static int zynq_gpio_request(struct gpio_chip *chip, unsigned offset)
  {
  	int ret;
58383c784   Linus Walleij   gpio: change memb...
590
  	ret = pm_runtime_get_sync(chip->parent);
3242ba117   Harini Katakam   gpio: Add driver ...
591
592
593
594
595
596
597
598
599
600
  
  	/*
  	 * 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;
  }
  
  static void zynq_gpio_free(struct gpio_chip *chip, unsigned offset)
  {
58383c784   Linus Walleij   gpio: change memb...
601
  	pm_runtime_put(chip->parent);
3242ba117   Harini Katakam   gpio: Add driver ...
602
603
604
605
  }
  
  static const struct dev_pm_ops zynq_gpio_dev_pm_ops = {
  	SET_SYSTEM_SLEEP_PM_OPS(zynq_gpio_suspend, zynq_gpio_resume)
6ed23b806   Rafael J. Wysocki   PM: Merge the SET...
606
  	SET_RUNTIME_PM_OPS(zynq_gpio_runtime_suspend,
3242ba117   Harini Katakam   gpio: Add driver ...
607
608
  			zynq_gpio_runtime_resume, NULL)
  };
bdf7a4ae3   Anurag Kumar Vulisha   gpio: Added suppo...
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
  static const struct zynq_platform_data zynqmp_gpio_def = {
  	.label = "zynqmp_gpio",
  	.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",
e3296f19c   Nava kishore Manne   gpio: Added zynq ...
629
  	.quirks = ZYNQ_GPIO_QUIRK_FOO,
bdf7a4ae3   Anurag Kumar Vulisha   gpio: Added suppo...
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
  	.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[] = {
  	{ .compatible = "xlnx,zynq-gpio-1.0", .data = (void *)&zynq_gpio_def },
  	{ .compatible = "xlnx,zynqmp-gpio-1.0",
  					.data = (void *)&zynqmp_gpio_def },
  	{ /* end of table */ }
  };
  MODULE_DEVICE_TABLE(of, zynq_gpio_of_match);
3242ba117   Harini Katakam   gpio: Add driver ...
649
650
651
652
653
654
655
656
657
658
659
660
661
  /**
   * 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   Ezra Savard   gpio: zynq: Fixed...
662
  	int ret, bank_num;
3242ba117   Harini Katakam   gpio: Add driver ...
663
664
665
  	struct zynq_gpio *gpio;
  	struct gpio_chip *chip;
  	struct resource *res;
bdf7a4ae3   Anurag Kumar Vulisha   gpio: Added suppo...
666
  	const struct of_device_id *match;
3242ba117   Harini Katakam   gpio: Add driver ...
667
668
669
670
  
  	gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
  	if (!gpio)
  		return -ENOMEM;
bdf7a4ae3   Anurag Kumar Vulisha   gpio: Added suppo...
671
672
673
674
675
676
677
  	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   Harini Katakam   gpio: Add driver ...
678
679
680
681
682
683
  	platform_set_drvdata(pdev, gpio);
  
  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  	gpio->base_addr = devm_ioremap_resource(&pdev->dev, res);
  	if (IS_ERR(gpio->base_addr))
  		return PTR_ERR(gpio->base_addr);
59e22114b   Ezra Savard   gpio: zynq: Fixed...
684
685
  	gpio->irq = platform_get_irq(pdev, 0);
  	if (gpio->irq < 0) {
3242ba117   Harini Katakam   gpio: Add driver ...
686
687
  		dev_err(&pdev->dev, "invalid IRQ
  ");
59e22114b   Ezra Savard   gpio: zynq: Fixed...
688
  		return gpio->irq;
3242ba117   Harini Katakam   gpio: Add driver ...
689
690
691
692
  	}
  
  	/* configure the gpio chip */
  	chip = &gpio->chip;
bdf7a4ae3   Anurag Kumar Vulisha   gpio: Added suppo...
693
  	chip->label = gpio->p_data->label;
3242ba117   Harini Katakam   gpio: Add driver ...
694
  	chip->owner = THIS_MODULE;
58383c784   Linus Walleij   gpio: change memb...
695
  	chip->parent = &pdev->dev;
3242ba117   Harini Katakam   gpio: Add driver ...
696
697
698
699
700
701
702
  	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;
  	chip->base = -1;
bdf7a4ae3   Anurag Kumar Vulisha   gpio: Added suppo...
703
  	chip->ngpio = gpio->p_data->ngpio;
3242ba117   Harini Katakam   gpio: Add driver ...
704

3773c195d   Michal Simek   gpio: zynq: Do PM...
705
  	/* Retrieve GPIO clock */
3242ba117   Harini Katakam   gpio: Add driver ...
706
707
708
709
710
711
  	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   Helmut Grohne   gpio: zynq: initi...
712
713
714
715
716
717
  	ret = clk_prepare_enable(gpio->clk);
  	if (ret) {
  		dev_err(&pdev->dev, "Unable to enable clock.
  ");
  		return ret;
  	}
3773c195d   Michal Simek   gpio: zynq: Do PM...
718

0f84f29ff   Helmut Grohne   gpio: zynq: initi...
719
  	pm_runtime_set_active(&pdev->dev);
3773c195d   Michal Simek   gpio: zynq: Do PM...
720
721
722
  	pm_runtime_enable(&pdev->dev);
  	ret = pm_runtime_get_sync(&pdev->dev);
  	if (ret < 0)
615d23f80   Shubhrajyoti Datta   gpio: zynq: Fix t...
723
  		goto err_pm_dis;
3242ba117   Harini Katakam   gpio: Add driver ...
724
725
  
  	/* report a bug if gpio chip registration fails */
31a894475   Linus Walleij   gpio: zynq: use g...
726
  	ret = gpiochip_add_data(chip, gpio);
3242ba117   Harini Katakam   gpio: Add driver ...
727
728
729
  	if (ret) {
  		dev_err(&pdev->dev, "Failed to add gpio chip
  ");
3773c195d   Michal Simek   gpio: zynq: Do PM...
730
  		goto err_pm_put;
3242ba117   Harini Katakam   gpio: Add driver ...
731
732
733
  	}
  
  	/* disable interrupts for all banks */
bdf7a4ae3   Anurag Kumar Vulisha   gpio: Added suppo...
734
  	for (bank_num = 0; bank_num < gpio->p_data->max_bank; bank_num++)
3242ba117   Harini Katakam   gpio: Add driver ...
735
736
  		writel_relaxed(ZYNQ_GPIO_IXR_DISABLE_ALL, gpio->base_addr +
  			       ZYNQ_GPIO_INTDIS_OFFSET(bank_num));
6dd859508   Lars-Peter Clausen   gpio: zynq: Fix I...
737
738
  	ret = gpiochip_irqchip_add(chip, &zynq_gpio_edge_irqchip, 0,
  				   handle_level_irq, IRQ_TYPE_NONE);
3242ba117   Harini Katakam   gpio: Add driver ...
739
740
741
742
743
  	if (ret) {
  		dev_err(&pdev->dev, "Failed to add irq chip
  ");
  		goto err_rm_gpiochip;
  	}
59e22114b   Ezra Savard   gpio: zynq: Fixed...
744
  	gpiochip_set_chained_irqchip(chip, &zynq_gpio_edge_irqchip, gpio->irq,
3242ba117   Harini Katakam   gpio: Add driver ...
745
  				     zynq_gpio_irqhandler);
3773c195d   Michal Simek   gpio: zynq: Do PM...
746
  	pm_runtime_put(&pdev->dev);
3242ba117   Harini Katakam   gpio: Add driver ...
747

3242ba117   Harini Katakam   gpio: Add driver ...
748
749
750
  	return 0;
  
  err_rm_gpiochip:
88d5e520a   abdoulaye berthe   driver:gpio remov...
751
  	gpiochip_remove(chip);
3773c195d   Michal Simek   gpio: zynq: Do PM...
752
753
  err_pm_put:
  	pm_runtime_put(&pdev->dev);
615d23f80   Shubhrajyoti Datta   gpio: zynq: Fix t...
754
755
  err_pm_dis:
  	pm_runtime_disable(&pdev->dev);
0f84f29ff   Helmut Grohne   gpio: zynq: initi...
756
  	clk_disable_unprepare(gpio->clk);
3242ba117   Harini Katakam   gpio: Add driver ...
757
758
759
760
761
762
763
764
765
766
767
768
  
  	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   Harini Katakam   gpio: Add driver ...
769
770
771
  	struct zynq_gpio *gpio = platform_get_drvdata(pdev);
  
  	pm_runtime_get_sync(&pdev->dev);
da26d5d80   Linus Walleij   gpio: remove rema...
772
  	gpiochip_remove(&gpio->chip);
3242ba117   Harini Katakam   gpio: Add driver ...
773
774
  	clk_disable_unprepare(gpio->clk);
  	device_set_wakeup_capable(&pdev->dev, 0);
6b956af08   Michal Simek   gpio: zynq: Fix p...
775
  	pm_runtime_disable(&pdev->dev);
3242ba117   Harini Katakam   gpio: Add driver ...
776
777
  	return 0;
  }
3242ba117   Harini Katakam   gpio: Add driver ...
778
779
780
  static struct platform_driver zynq_gpio_driver = {
  	.driver	= {
  		.name = DRIVER_NAME,
3242ba117   Harini Katakam   gpio: Add driver ...
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
  		.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   Masahiro Yamada   gpio: zynq: add m...
798
799
800
801
802
  static void __exit zynq_gpio_exit(void)
  {
  	platform_driver_unregister(&zynq_gpio_driver);
  }
  module_exit(zynq_gpio_exit);
3242ba117   Harini Katakam   gpio: Add driver ...
803
804
805
  MODULE_AUTHOR("Xilinx Inc.");
  MODULE_DESCRIPTION("Zynq GPIO driver");
  MODULE_LICENSE("GPL");