Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/gpio/xilinx_gpio.c
15109 views
1
/*
2
* Xilinx gpio driver
3
*
4
* Copyright 2008 Xilinx, Inc.
5
*
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License version 2
8
* as published by the Free Software Foundation.
9
*
10
* You should have received a copy of the GNU General Public License
11
* along with this program; if not, write to the Free Software
12
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
13
*/
14
15
#include <linux/init.h>
16
#include <linux/errno.h>
17
#include <linux/of_device.h>
18
#include <linux/of_platform.h>
19
#include <linux/of_gpio.h>
20
#include <linux/io.h>
21
#include <linux/gpio.h>
22
#include <linux/slab.h>
23
24
/* Register Offset Definitions */
25
#define XGPIO_DATA_OFFSET (0x0) /* Data register */
26
#define XGPIO_TRI_OFFSET (0x4) /* I/O direction register */
27
28
struct xgpio_instance {
29
struct of_mm_gpio_chip mmchip;
30
u32 gpio_state; /* GPIO state shadow register */
31
u32 gpio_dir; /* GPIO direction shadow register */
32
spinlock_t gpio_lock; /* Lock used for synchronization */
33
};
34
35
/**
36
* xgpio_get - Read the specified signal of the GPIO device.
37
* @gc: Pointer to gpio_chip device structure.
38
* @gpio: GPIO signal number.
39
*
40
* This function reads the specified signal of the GPIO device. It returns 0 if
41
* the signal clear, 1 if signal is set or negative value on error.
42
*/
43
static int xgpio_get(struct gpio_chip *gc, unsigned int gpio)
44
{
45
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
46
47
return (in_be32(mm_gc->regs + XGPIO_DATA_OFFSET) >> gpio) & 1;
48
}
49
50
/**
51
* xgpio_set - Write the specified signal of the GPIO device.
52
* @gc: Pointer to gpio_chip device structure.
53
* @gpio: GPIO signal number.
54
* @val: Value to be written to specified signal.
55
*
56
* This function writes the specified value in to the specified signal of the
57
* GPIO device.
58
*/
59
static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
60
{
61
unsigned long flags;
62
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
63
struct xgpio_instance *chip =
64
container_of(mm_gc, struct xgpio_instance, mmchip);
65
66
spin_lock_irqsave(&chip->gpio_lock, flags);
67
68
/* Write to GPIO signal and set its direction to output */
69
if (val)
70
chip->gpio_state |= 1 << gpio;
71
else
72
chip->gpio_state &= ~(1 << gpio);
73
out_be32(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state);
74
75
spin_unlock_irqrestore(&chip->gpio_lock, flags);
76
}
77
78
/**
79
* xgpio_dir_in - Set the direction of the specified GPIO signal as input.
80
* @gc: Pointer to gpio_chip device structure.
81
* @gpio: GPIO signal number.
82
*
83
* This function sets the direction of specified GPIO signal as input.
84
* It returns 0 if direction of GPIO signals is set as input otherwise it
85
* returns negative error value.
86
*/
87
static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
88
{
89
unsigned long flags;
90
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
91
struct xgpio_instance *chip =
92
container_of(mm_gc, struct xgpio_instance, mmchip);
93
94
spin_lock_irqsave(&chip->gpio_lock, flags);
95
96
/* Set the GPIO bit in shadow register and set direction as input */
97
chip->gpio_dir |= (1 << gpio);
98
out_be32(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir);
99
100
spin_unlock_irqrestore(&chip->gpio_lock, flags);
101
102
return 0;
103
}
104
105
/**
106
* xgpio_dir_out - Set the direction of the specified GPIO signal as output.
107
* @gc: Pointer to gpio_chip device structure.
108
* @gpio: GPIO signal number.
109
* @val: Value to be written to specified signal.
110
*
111
* This function sets the direction of specified GPIO signal as output. If all
112
* GPIO signals of GPIO chip is configured as input then it returns
113
* error otherwise it returns 0.
114
*/
115
static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
116
{
117
unsigned long flags;
118
struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
119
struct xgpio_instance *chip =
120
container_of(mm_gc, struct xgpio_instance, mmchip);
121
122
spin_lock_irqsave(&chip->gpio_lock, flags);
123
124
/* Write state of GPIO signal */
125
if (val)
126
chip->gpio_state |= 1 << gpio;
127
else
128
chip->gpio_state &= ~(1 << gpio);
129
out_be32(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state);
130
131
/* Clear the GPIO bit in shadow register and set direction as output */
132
chip->gpio_dir &= (~(1 << gpio));
133
out_be32(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir);
134
135
spin_unlock_irqrestore(&chip->gpio_lock, flags);
136
137
return 0;
138
}
139
140
/**
141
* xgpio_save_regs - Set initial values of GPIO pins
142
* @mm_gc: pointer to memory mapped GPIO chip structure
143
*/
144
static void xgpio_save_regs(struct of_mm_gpio_chip *mm_gc)
145
{
146
struct xgpio_instance *chip =
147
container_of(mm_gc, struct xgpio_instance, mmchip);
148
149
out_be32(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state);
150
out_be32(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir);
151
}
152
153
/**
154
* xgpio_of_probe - Probe method for the GPIO device.
155
* @np: pointer to device tree node
156
*
157
* This function probes the GPIO device in the device tree. It initializes the
158
* driver data structure. It returns 0, if the driver is bound to the GPIO
159
* device, or a negative value if there is an error.
160
*/
161
static int __devinit xgpio_of_probe(struct device_node *np)
162
{
163
struct xgpio_instance *chip;
164
int status = 0;
165
const u32 *tree_info;
166
167
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
168
if (!chip)
169
return -ENOMEM;
170
171
/* Update GPIO state shadow register with default value */
172
tree_info = of_get_property(np, "xlnx,dout-default", NULL);
173
if (tree_info)
174
chip->gpio_state = be32_to_cpup(tree_info);
175
176
/* Update GPIO direction shadow register with default value */
177
chip->gpio_dir = 0xFFFFFFFF; /* By default, all pins are inputs */
178
tree_info = of_get_property(np, "xlnx,tri-default", NULL);
179
if (tree_info)
180
chip->gpio_dir = be32_to_cpup(tree_info);
181
182
/* Check device node and parent device node for device width */
183
chip->mmchip.gc.ngpio = 32; /* By default assume full GPIO controller */
184
tree_info = of_get_property(np, "xlnx,gpio-width", NULL);
185
if (!tree_info)
186
tree_info = of_get_property(np->parent,
187
"xlnx,gpio-width", NULL);
188
if (tree_info)
189
chip->mmchip.gc.ngpio = be32_to_cpup(tree_info);
190
191
spin_lock_init(&chip->gpio_lock);
192
193
chip->mmchip.gc.direction_input = xgpio_dir_in;
194
chip->mmchip.gc.direction_output = xgpio_dir_out;
195
chip->mmchip.gc.get = xgpio_get;
196
chip->mmchip.gc.set = xgpio_set;
197
198
chip->mmchip.save_regs = xgpio_save_regs;
199
200
/* Call the OF gpio helper to setup and register the GPIO device */
201
status = of_mm_gpiochip_add(np, &chip->mmchip);
202
if (status) {
203
kfree(chip);
204
pr_err("%s: error in probe function with status %d\n",
205
np->full_name, status);
206
return status;
207
}
208
pr_info("XGpio: %s: registered\n", np->full_name);
209
return 0;
210
}
211
212
static struct of_device_id xgpio_of_match[] __devinitdata = {
213
{ .compatible = "xlnx,xps-gpio-1.00.a", },
214
{ /* end of list */ },
215
};
216
217
static int __init xgpio_init(void)
218
{
219
struct device_node *np;
220
221
for_each_matching_node(np, xgpio_of_match)
222
xgpio_of_probe(np);
223
224
return 0;
225
}
226
227
/* Make sure we get initialized before anyone else tries to use us */
228
subsys_initcall(xgpio_init);
229
/* No exit call at the moment as we cannot unregister of GPIO chips */
230
231
MODULE_AUTHOR("Xilinx, Inc.");
232
MODULE_DESCRIPTION("Xilinx GPIO driver");
233
MODULE_LICENSE("GPL");
234
235