4 * Xilinx GPIO Adapter component to interface GPIO component to Linux
6 * Author: MontaVista Software, Inc.
9 * 2002 (c) MontaVista, Software, Inc. This file is licensed under the terms
10 * of the GNU General Public License version 2.1. This program is licensed
11 * "as is" without any warranty of any kind, whether express or implied.
15 * This driver is a bit unusual in that it is composed of two logical
16 * parts where one part is the OS independent code and the other part is
17 * the OS dependent code. Xilinx provides their drivers split in this
18 * fashion. This file represents the Linux OS dependent part known as
19 * the Linux adapter. The other files in this directory are the OS
20 * independent files as provided by Xilinx with no changes made to them.
21 * The names exported by those files begin with XGpio_. All functions
22 * in this file that are called by Linux have names that begin with
23 * xgpio_. Any other functions are static helper functions.
26 #include <linux/module.h>
27 #include <linux/init.h>
28 #include <linux/slab.h>
29 #include <linux/miscdevice.h>
32 #include <asm/uaccess.h>
34 /* Use the IBM OCP definitions for compatibility. */
35 #include <linux/ibm_ocp_gpio.h>
37 #include <xbasic_types.h>
41 MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>");
42 MODULE_DESCRIPTION("Xilinx GPIO driver");
43 MODULE_LICENSE("GPL");
45 /* Our private per interface data. */
46 struct xgpio_instance {
47 struct xgpio_instance *next_inst; /* The next instance in inst_list */
48 int index; /* Which interface is this */
49 u32 save_BaseAddress; /* Saved physical base address */
51 * The underlying OS independent code needs space as well. A
52 * pointer to the following XGpio structure will be passed to
53 * any XGpio_ function that requires it. However, we treat the
54 * data as an opaque object in this file (meaning that we never
55 * reference any of the fields inside of the structure).
59 /* List of instances we're handling. */
60 static struct xgpio_instance *inst_list = NULL;
62 /* SAATODO: This function will be moved into the Xilinx code. */
63 /*****************************************************************************/
66 * Lookup the device configuration based on the GPIO instance. The table
67 * XGpio_ConfigTable contains the configuration info for each device in the system.
69 * @param Instance is the index of the interface being looked up.
73 * A pointer to the configuration table entry corresponding to the given
74 * device ID, or NULL if no match is found.
80 ******************************************************************************/
81 XGpio_Config *XGpio_GetConfig(int Instance)
83 if (Instance < 0 || Instance >= XPAR_XGPIO_NUM_INSTANCES)
88 return &XGpio_ConfigTable[Instance];
91 /* SAATODO: This function will be moved into the Xilinx code. */
92 /****************************************************************************/
94 * Get the input/output direction of all discrete signals.
96 * @param InstancePtr is a pointer to an XGpio instance to be worked on.
98 * @return Current copy of the tristate (direction) register.
104 *****************************************************************************/
106 XGpio_GetDataDirection(XGpio * InstancePtr)
108 XASSERT_NONVOID(InstancePtr != NULL);
109 XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
110 return XGpio_mReadReg(InstancePtr->BaseAddress, XGPIO_TRI_OFFSET);
114 xgpio_open(struct inode *inode, struct file *file)
122 xgpio_release(struct inode *inode, struct file *file)
130 ioctl_setup(unsigned long arg,
131 struct ibm_gpio_ioctl_data *ioctl_data,
132 struct xgpio_instance **match)
134 struct xgpio_instance *inst;
136 if (copy_from_user(ioctl_data, (void *) arg, sizeof (*ioctl_data)))
140 while (inst && inst->index != ioctl_data->device)
141 inst = inst->next_inst;
144 return inst ? 0 : -ENODEV;
148 xgpio_ioctl(struct inode *inode, struct file *file,
149 unsigned int cmd, unsigned long arg)
151 struct ibm_gpio_ioctl_data ioctl_data;
152 struct xgpio_instance *inst;
158 status = ioctl_setup(arg, &ioctl_data, &inst);
162 /* Ensure that the GPIO bits in the mask are tristated. */
163 r = XGpio_GetDataDirection(&inst->Gpio);
164 XGpio_SetDataDirection(&inst->Gpio, r & ~ioctl_data.mask);
166 ioctl_data.data = (XGpio_DiscreteRead(&inst->Gpio)
168 if (copy_to_user((struct ibm_gpio_ioctl_data *) arg,
169 &ioctl_data, sizeof (ioctl_data))) {
175 status = ioctl_setup(arg, &ioctl_data, &inst);
179 /* Get the prior value. */
180 r = XGpio_DiscreteRead(&inst->Gpio);
181 /* Clear the bits that we're going to put in. */
182 r &= ~ioctl_data.mask;
183 /* Set the bits that were provided. */
184 r |= (ioctl_data.mask & ioctl_data.data);
186 XGpio_DiscreteWrite(&inst->Gpio, r);
188 /* Ensure that the GPIO bits in the mask are not tristated. */
189 r = XGpio_GetDataDirection(&inst->Gpio);
190 XGpio_SetDataDirection(&inst->Gpio, r | ioctl_data.mask);
194 case IBMGPIO_TRISTATE:
195 status = ioctl_setup(arg, &ioctl_data, &inst);
199 /* Get the prior value. */
200 r = XGpio_GetDataDirection(&inst->Gpio);
201 /* Clear the bits that we're going to put in. */
202 r &= ~ioctl_data.mask;
203 /* Set the bits that were provided. */
204 r |= (ioctl_data.mask & ioctl_data.data);
206 XGpio_SetDataDirection(&inst->Gpio, r);
217 remove_head_inst(void)
219 struct xgpio_instance *inst;
222 /* Pull the head off of inst_list. */
224 inst_list = inst->next_inst;
226 cfg = XGpio_GetConfig(inst->index);
227 iounmap((void *) cfg->BaseAddress);
228 cfg->BaseAddress = inst->save_BaseAddress;
231 static struct file_operations xfops = {
235 release:xgpio_release,
238 * We get to all of the GPIOs through one minor number. Here's the
239 * miscdevice that gets registered for that minor number.
241 static struct miscdevice miscdev = {
250 static const unsigned long remap_size
251 = XPAR_GPIO_0_HIGHADDR - XPAR_GPIO_0_BASEADDR + 1;
252 struct xgpio_instance *inst;
255 /* Find the config for our instance. */
256 cfg = XGpio_GetConfig(index);
260 /* Allocate the inst and zero it out. */
261 inst = (struct xgpio_instance *) kmalloc(sizeof (struct xgpio_instance),
264 printk(KERN_ERR "%s #%d: Could not allocate instance.\n",
265 miscdev.name, index);
268 memset(inst, 0, sizeof (struct xgpio_instance));
270 /* Make it the head of inst_list. */
271 inst->next_inst = inst_list;
274 /* Change the addresses to be virtual; save the old ones to restore. */
275 inst->save_BaseAddress = cfg->BaseAddress;
276 cfg->BaseAddress = (u32) ioremap(inst->save_BaseAddress, remap_size);
278 /* Tell the Xilinx code to bring this GPIO interface up. */
279 if (XGpio_Initialize(&inst->Gpio, cfg->DeviceId) != XST_SUCCESS) {
280 printk(KERN_ERR "%s #%d: Could not initialize instance.\n",
281 miscdev.name, inst->index);
286 printk(KERN_INFO "%s #%d at 0x%08X mapped to 0x%08X\n",
287 miscdev.name, inst->index,
288 inst->save_BaseAddress, cfg->BaseAddress);
298 while (probe(index++) == 0) ;
301 /* We found at least one instance. */
303 /* Register the driver with misc and report success. */
304 rtn = misc_register(&miscdev);
306 printk(KERN_ERR "%s: Could not register driver.\n",
313 /* Report success. */
316 /* No instances found. */
328 misc_deregister(&miscdev);
333 module_init(xgpio_init);
334 module_exit(xgpio_cleanup);