Back to home page

OSCL-LXR

 
 

    


0001 /*****************************************************************************
0002  *
0003  *     Author: Xilinx, Inc.
0004  *
0005  *     This program is free software; you can redistribute it and/or modify it
0006  *     under the terms of the GNU General Public License as published by the
0007  *     Free Software Foundation; either version 2 of the License, or (at your
0008  *     option) any later version.
0009  *
0010  *     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
0011  *     AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
0012  *     SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
0013  *     OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
0014  *     APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
0015  *     THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
0016  *     AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
0017  *     FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
0018  *     WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
0019  *     IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
0020  *     REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
0021  *     INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
0022  *     FOR A PARTICULAR PURPOSE.
0023  *
0024  *     (c) Copyright 2002 Xilinx Inc., Systems Engineering Group
0025  *     (c) Copyright 2004 Xilinx Inc., Systems Engineering Group
0026  *     (c) Copyright 2007-2008 Xilinx Inc.
0027  *     All rights reserved.
0028  *
0029  *     You should have received a copy of the GNU General Public License along
0030  *     with this program; if not, write to the Free Software Foundation, Inc.,
0031  *     675 Mass Ave, Cambridge, MA 02139, USA.
0032  *
0033  *****************************************************************************/
0034 
0035 /*
0036  * This is the code behind /dev/icap* -- it allows a user-space
0037  * application to use the Xilinx ICAP subsystem.
0038  *
0039  * The following operations are possible:
0040  *
0041  * open         open the port and initialize for access.
0042  * release      release port
0043  * write        Write a bitstream to the configuration processor.
0044  * read         Read a data stream from the configuration processor.
0045  *
0046  * After being opened, the port is initialized and accessed to avoid a
0047  * corrupted first read which may occur with some hardware.  The port
0048  * is left in a desynched state, requiring that a synch sequence be
0049  * transmitted before any valid configuration data.  A user will have
0050  * exclusive access to the device while it remains open, and the state
0051  * of the ICAP cannot be guaranteed after the device is closed.  Note
0052  * that a complete reset of the core and the state of the ICAP cannot
0053  * be performed on many versions of the cores, hence users of this
0054  * device should avoid making inconsistent accesses to the device.  In
0055  * particular, accessing the read interface, without first generating
0056  * a write containing a readback packet can leave the ICAP in an
0057  * inaccessible state.
0058  *
0059  * Note that in order to use the read interface, it is first necessary
0060  * to write a request packet to the write interface.  i.e., it is not
0061  * possible to simply readback the bitstream (or any configuration
0062  * bits) from a device without specifically requesting them first.
0063  * The code to craft such packets is intended to be part of the
0064  * user-space application code that uses this device.  The simplest
0065  * way to use this interface is simply:
0066  *
0067  * cp foo.bit /dev/icap0
0068  *
0069  * Note that unless foo.bit is an appropriately constructed partial
0070  * bitstream, this has a high likelihood of overwriting the design
0071  * currently programmed in the FPGA.
0072  */
0073 
0074 #include <linux/module.h>
0075 #include <linux/kernel.h>
0076 #include <linux/types.h>
0077 #include <linux/ioport.h>
0078 #include <linux/interrupt.h>
0079 #include <linux/fcntl.h>
0080 #include <linux/init.h>
0081 #include <linux/poll.h>
0082 #include <linux/proc_fs.h>
0083 #include <linux/mutex.h>
0084 #include <linux/sysctl.h>
0085 #include <linux/fs.h>
0086 #include <linux/cdev.h>
0087 #include <linux/platform_device.h>
0088 #include <linux/slab.h>
0089 #include <linux/io.h>
0090 #include <linux/uaccess.h>
0091 
0092 #ifdef CONFIG_OF
0093 /* For open firmware. */
0094 #include <linux/of_address.h>
0095 #include <linux/of_device.h>
0096 #include <linux/of_platform.h>
0097 #endif
0098 
0099 #include "xilinx_hwicap.h"
0100 #include "buffer_icap.h"
0101 #include "fifo_icap.h"
0102 
0103 #define DRIVER_NAME "icap"
0104 
0105 #define HWICAP_REGS   (0x10000)
0106 
0107 #define XHWICAP_MAJOR 259
0108 #define XHWICAP_MINOR 0
0109 #define HWICAP_DEVICES 1
0110 
0111 /* An array, which is set to true when the device is registered. */
0112 static DEFINE_MUTEX(hwicap_mutex);
0113 static bool probed_devices[HWICAP_DEVICES];
0114 static struct mutex icap_sem;
0115 
0116 static struct class *icap_class;
0117 
0118 #define UNIMPLEMENTED 0xFFFF
0119 
0120 static const struct config_registers v2_config_registers = {
0121     .CRC = 0,
0122     .FAR = 1,
0123     .FDRI = 2,
0124     .FDRO = 3,
0125     .CMD = 4,
0126     .CTL = 5,
0127     .MASK = 6,
0128     .STAT = 7,
0129     .LOUT = 8,
0130     .COR = 9,
0131     .MFWR = 10,
0132     .FLR = 11,
0133     .KEY = 12,
0134     .CBC = 13,
0135     .IDCODE = 14,
0136     .AXSS = UNIMPLEMENTED,
0137     .C0R_1 = UNIMPLEMENTED,
0138     .CSOB = UNIMPLEMENTED,
0139     .WBSTAR = UNIMPLEMENTED,
0140     .TIMER = UNIMPLEMENTED,
0141     .BOOTSTS = UNIMPLEMENTED,
0142     .CTL_1 = UNIMPLEMENTED,
0143 };
0144 
0145 static const struct config_registers v4_config_registers = {
0146     .CRC = 0,
0147     .FAR = 1,
0148     .FDRI = 2,
0149     .FDRO = 3,
0150     .CMD = 4,
0151     .CTL = 5,
0152     .MASK = 6,
0153     .STAT = 7,
0154     .LOUT = 8,
0155     .COR = 9,
0156     .MFWR = 10,
0157     .FLR = UNIMPLEMENTED,
0158     .KEY = UNIMPLEMENTED,
0159     .CBC = 11,
0160     .IDCODE = 12,
0161     .AXSS = 13,
0162     .C0R_1 = UNIMPLEMENTED,
0163     .CSOB = UNIMPLEMENTED,
0164     .WBSTAR = UNIMPLEMENTED,
0165     .TIMER = UNIMPLEMENTED,
0166     .BOOTSTS = UNIMPLEMENTED,
0167     .CTL_1 = UNIMPLEMENTED,
0168 };
0169 
0170 static const struct config_registers v5_config_registers = {
0171     .CRC = 0,
0172     .FAR = 1,
0173     .FDRI = 2,
0174     .FDRO = 3,
0175     .CMD = 4,
0176     .CTL = 5,
0177     .MASK = 6,
0178     .STAT = 7,
0179     .LOUT = 8,
0180     .COR = 9,
0181     .MFWR = 10,
0182     .FLR = UNIMPLEMENTED,
0183     .KEY = UNIMPLEMENTED,
0184     .CBC = 11,
0185     .IDCODE = 12,
0186     .AXSS = 13,
0187     .C0R_1 = 14,
0188     .CSOB = 15,
0189     .WBSTAR = 16,
0190     .TIMER = 17,
0191     .BOOTSTS = 18,
0192     .CTL_1 = 19,
0193 };
0194 
0195 static const struct config_registers v6_config_registers = {
0196     .CRC = 0,
0197     .FAR = 1,
0198     .FDRI = 2,
0199     .FDRO = 3,
0200     .CMD = 4,
0201     .CTL = 5,
0202     .MASK = 6,
0203     .STAT = 7,
0204     .LOUT = 8,
0205     .COR = 9,
0206     .MFWR = 10,
0207     .FLR = UNIMPLEMENTED,
0208     .KEY = UNIMPLEMENTED,
0209     .CBC = 11,
0210     .IDCODE = 12,
0211     .AXSS = 13,
0212     .C0R_1 = 14,
0213     .CSOB = 15,
0214     .WBSTAR = 16,
0215     .TIMER = 17,
0216     .BOOTSTS = 22,
0217     .CTL_1 = 24,
0218 };
0219 
0220 /**
0221  * hwicap_command_desync - Send a DESYNC command to the ICAP port.
0222  * @drvdata: a pointer to the drvdata.
0223  *
0224  * Returns: '0' on success and failure value on error
0225  *
0226  * This command desynchronizes the ICAP After this command, a
0227  * bitstream containing a NULL packet, followed by a SYNCH packet is
0228  * required before the ICAP will recognize commands.
0229  */
0230 static int hwicap_command_desync(struct hwicap_drvdata *drvdata)
0231 {
0232     u32 buffer[4];
0233     u32 index = 0;
0234 
0235     /*
0236      * Create the data to be written to the ICAP.
0237      */
0238     buffer[index++] = hwicap_type_1_write(drvdata->config_regs->CMD) | 1;
0239     buffer[index++] = XHI_CMD_DESYNCH;
0240     buffer[index++] = XHI_NOOP_PACKET;
0241     buffer[index++] = XHI_NOOP_PACKET;
0242 
0243     /*
0244      * Write the data to the FIFO and initiate the transfer of data present
0245      * in the FIFO to the ICAP device.
0246      */
0247     return drvdata->config->set_configuration(drvdata,
0248             &buffer[0], index);
0249 }
0250 
0251 /**
0252  * hwicap_get_configuration_register - Query a configuration register.
0253  * @drvdata: a pointer to the drvdata.
0254  * @reg: a constant which represents the configuration
0255  * register value to be returned.
0256  * Examples: XHI_IDCODE, XHI_FLR.
0257  * @reg_data: returns the value of the register.
0258  *
0259  * Returns: '0' on success and failure value on error
0260  *
0261  * Sends a query packet to the ICAP and then receives the response.
0262  * The icap is left in Synched state.
0263  */
0264 static int hwicap_get_configuration_register(struct hwicap_drvdata *drvdata,
0265         u32 reg, u32 *reg_data)
0266 {
0267     int status;
0268     u32 buffer[6];
0269     u32 index = 0;
0270 
0271     /*
0272      * Create the data to be written to the ICAP.
0273      */
0274     buffer[index++] = XHI_DUMMY_PACKET;
0275     buffer[index++] = XHI_NOOP_PACKET;
0276     buffer[index++] = XHI_SYNC_PACKET;
0277     buffer[index++] = XHI_NOOP_PACKET;
0278     buffer[index++] = XHI_NOOP_PACKET;
0279 
0280     /*
0281      * Write the data to the FIFO and initiate the transfer of data present
0282      * in the FIFO to the ICAP device.
0283      */
0284     status = drvdata->config->set_configuration(drvdata,
0285                             &buffer[0], index);
0286     if (status)
0287         return status;
0288 
0289     /* If the syncword was not found, then we need to start over. */
0290     status = drvdata->config->get_status(drvdata);
0291     if ((status & XHI_SR_DALIGN_MASK) != XHI_SR_DALIGN_MASK)
0292         return -EIO;
0293 
0294     index = 0;
0295     buffer[index++] = hwicap_type_1_read(reg) | 1;
0296     buffer[index++] = XHI_NOOP_PACKET;
0297     buffer[index++] = XHI_NOOP_PACKET;
0298 
0299     /*
0300      * Write the data to the FIFO and initiate the transfer of data present
0301      * in the FIFO to the ICAP device.
0302      */
0303     status = drvdata->config->set_configuration(drvdata,
0304             &buffer[0], index);
0305     if (status)
0306         return status;
0307 
0308     /*
0309      * Read the configuration register
0310      */
0311     status = drvdata->config->get_configuration(drvdata, reg_data, 1);
0312     if (status)
0313         return status;
0314 
0315     return 0;
0316 }
0317 
0318 static int hwicap_initialize_hwicap(struct hwicap_drvdata *drvdata)
0319 {
0320     int status;
0321     u32 idcode;
0322 
0323     dev_dbg(drvdata->dev, "initializing\n");
0324 
0325     /* Abort any current transaction, to make sure we have the
0326      * ICAP in a good state.
0327      */
0328     dev_dbg(drvdata->dev, "Reset...\n");
0329     drvdata->config->reset(drvdata);
0330 
0331     dev_dbg(drvdata->dev, "Desync...\n");
0332     status = hwicap_command_desync(drvdata);
0333     if (status)
0334         return status;
0335 
0336     /* Attempt to read the IDCODE from ICAP.  This
0337      * may not be returned correctly, due to the design of the
0338      * hardware.
0339      */
0340     dev_dbg(drvdata->dev, "Reading IDCODE...\n");
0341     status = hwicap_get_configuration_register(
0342             drvdata, drvdata->config_regs->IDCODE, &idcode);
0343     dev_dbg(drvdata->dev, "IDCODE = %x\n", idcode);
0344     if (status)
0345         return status;
0346 
0347     dev_dbg(drvdata->dev, "Desync...\n");
0348     status = hwicap_command_desync(drvdata);
0349     if (status)
0350         return status;
0351 
0352     return 0;
0353 }
0354 
0355 static ssize_t
0356 hwicap_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
0357 {
0358     struct hwicap_drvdata *drvdata = file->private_data;
0359     ssize_t bytes_to_read = 0;
0360     u32 *kbuf;
0361     u32 words;
0362     u32 bytes_remaining;
0363     int status;
0364 
0365     status = mutex_lock_interruptible(&drvdata->sem);
0366     if (status)
0367         return status;
0368 
0369     if (drvdata->read_buffer_in_use) {
0370         /* If there are leftover bytes in the buffer, just */
0371         /* return them and don't try to read more from the */
0372         /* ICAP device. */
0373         bytes_to_read =
0374             (count < drvdata->read_buffer_in_use) ? count :
0375             drvdata->read_buffer_in_use;
0376 
0377         /* Return the data currently in the read buffer. */
0378         if (copy_to_user(buf, drvdata->read_buffer, bytes_to_read)) {
0379             status = -EFAULT;
0380             goto error;
0381         }
0382         drvdata->read_buffer_in_use -= bytes_to_read;
0383         memmove(drvdata->read_buffer,
0384                drvdata->read_buffer + bytes_to_read,
0385                4 - bytes_to_read);
0386     } else {
0387         /* Get new data from the ICAP, and return what was requested. */
0388         kbuf = (u32 *) get_zeroed_page(GFP_KERNEL);
0389         if (!kbuf) {
0390             status = -ENOMEM;
0391             goto error;
0392         }
0393 
0394         /* The ICAP device is only able to read complete */
0395         /* words.  If a number of bytes that do not correspond */
0396         /* to complete words is requested, then we read enough */
0397         /* words to get the required number of bytes, and then */
0398         /* save the remaining bytes for the next read. */
0399 
0400         /* Determine the number of words to read, rounding up */
0401         /* if necessary. */
0402         words = ((count + 3) >> 2);
0403         bytes_to_read = words << 2;
0404 
0405         if (bytes_to_read > PAGE_SIZE)
0406             bytes_to_read = PAGE_SIZE;
0407 
0408         /* Ensure we only read a complete number of words. */
0409         bytes_remaining = bytes_to_read & 3;
0410         bytes_to_read &= ~3;
0411         words = bytes_to_read >> 2;
0412 
0413         status = drvdata->config->get_configuration(drvdata,
0414                 kbuf, words);
0415 
0416         /* If we didn't read correctly, then bail out. */
0417         if (status) {
0418             free_page((unsigned long)kbuf);
0419             goto error;
0420         }
0421 
0422         /* If we fail to return the data to the user, then bail out. */
0423         if (copy_to_user(buf, kbuf, bytes_to_read)) {
0424             free_page((unsigned long)kbuf);
0425             status = -EFAULT;
0426             goto error;
0427         }
0428         memcpy(drvdata->read_buffer,
0429                kbuf,
0430                bytes_remaining);
0431         drvdata->read_buffer_in_use = bytes_remaining;
0432         free_page((unsigned long)kbuf);
0433     }
0434     status = bytes_to_read;
0435  error:
0436     mutex_unlock(&drvdata->sem);
0437     return status;
0438 }
0439 
0440 static ssize_t
0441 hwicap_write(struct file *file, const char __user *buf,
0442         size_t count, loff_t *ppos)
0443 {
0444     struct hwicap_drvdata *drvdata = file->private_data;
0445     ssize_t written = 0;
0446     ssize_t left = count;
0447     u32 *kbuf;
0448     ssize_t len;
0449     ssize_t status;
0450 
0451     status = mutex_lock_interruptible(&drvdata->sem);
0452     if (status)
0453         return status;
0454 
0455     left += drvdata->write_buffer_in_use;
0456 
0457     /* Only write multiples of 4 bytes. */
0458     if (left < 4) {
0459         status = 0;
0460         goto error;
0461     }
0462 
0463     kbuf = (u32 *) __get_free_page(GFP_KERNEL);
0464     if (!kbuf) {
0465         status = -ENOMEM;
0466         goto error;
0467     }
0468 
0469     while (left > 3) {
0470         /* only write multiples of 4 bytes, so there might */
0471         /* be as many as 3 bytes left (at the end). */
0472         len = left;
0473 
0474         if (len > PAGE_SIZE)
0475             len = PAGE_SIZE;
0476         len &= ~3;
0477 
0478         if (drvdata->write_buffer_in_use) {
0479             memcpy(kbuf, drvdata->write_buffer,
0480                     drvdata->write_buffer_in_use);
0481             if (copy_from_user(
0482                 (((char *)kbuf) + drvdata->write_buffer_in_use),
0483                 buf + written,
0484                 len - (drvdata->write_buffer_in_use))) {
0485                 free_page((unsigned long)kbuf);
0486                 status = -EFAULT;
0487                 goto error;
0488             }
0489         } else {
0490             if (copy_from_user(kbuf, buf + written, len)) {
0491                 free_page((unsigned long)kbuf);
0492                 status = -EFAULT;
0493                 goto error;
0494             }
0495         }
0496 
0497         status = drvdata->config->set_configuration(drvdata,
0498                 kbuf, len >> 2);
0499 
0500         if (status) {
0501             free_page((unsigned long)kbuf);
0502             status = -EFAULT;
0503             goto error;
0504         }
0505         if (drvdata->write_buffer_in_use) {
0506             len -= drvdata->write_buffer_in_use;
0507             left -= drvdata->write_buffer_in_use;
0508             drvdata->write_buffer_in_use = 0;
0509         }
0510         written += len;
0511         left -= len;
0512     }
0513     if ((left > 0) && (left < 4)) {
0514         if (!copy_from_user(drvdata->write_buffer,
0515                         buf + written, left)) {
0516             drvdata->write_buffer_in_use = left;
0517             written += left;
0518             left = 0;
0519         }
0520     }
0521 
0522     free_page((unsigned long)kbuf);
0523     status = written;
0524  error:
0525     mutex_unlock(&drvdata->sem);
0526     return status;
0527 }
0528 
0529 static int hwicap_open(struct inode *inode, struct file *file)
0530 {
0531     struct hwicap_drvdata *drvdata;
0532     int status;
0533 
0534     mutex_lock(&hwicap_mutex);
0535     drvdata = container_of(inode->i_cdev, struct hwicap_drvdata, cdev);
0536 
0537     status = mutex_lock_interruptible(&drvdata->sem);
0538     if (status)
0539         goto out;
0540 
0541     if (drvdata->is_open) {
0542         status = -EBUSY;
0543         goto error;
0544     }
0545 
0546     status = hwicap_initialize_hwicap(drvdata);
0547     if (status) {
0548         dev_err(drvdata->dev, "Failed to open file");
0549         goto error;
0550     }
0551 
0552     file->private_data = drvdata;
0553     drvdata->write_buffer_in_use = 0;
0554     drvdata->read_buffer_in_use = 0;
0555     drvdata->is_open = 1;
0556 
0557  error:
0558     mutex_unlock(&drvdata->sem);
0559  out:
0560     mutex_unlock(&hwicap_mutex);
0561     return status;
0562 }
0563 
0564 static int hwicap_release(struct inode *inode, struct file *file)
0565 {
0566     struct hwicap_drvdata *drvdata = file->private_data;
0567     int i;
0568     int status = 0;
0569 
0570     mutex_lock(&drvdata->sem);
0571 
0572     if (drvdata->write_buffer_in_use) {
0573         /* Flush write buffer. */
0574         for (i = drvdata->write_buffer_in_use; i < 4; i++)
0575             drvdata->write_buffer[i] = 0;
0576 
0577         status = drvdata->config->set_configuration(drvdata,
0578                 (u32 *) drvdata->write_buffer, 1);
0579         if (status)
0580             goto error;
0581     }
0582 
0583     status = hwicap_command_desync(drvdata);
0584     if (status)
0585         goto error;
0586 
0587  error:
0588     drvdata->is_open = 0;
0589     mutex_unlock(&drvdata->sem);
0590     return status;
0591 }
0592 
0593 static const struct file_operations hwicap_fops = {
0594     .owner = THIS_MODULE,
0595     .write = hwicap_write,
0596     .read = hwicap_read,
0597     .open = hwicap_open,
0598     .release = hwicap_release,
0599     .llseek = noop_llseek,
0600 };
0601 
0602 static int hwicap_setup(struct device *dev, int id,
0603         const struct resource *regs_res,
0604         const struct hwicap_driver_config *config,
0605         const struct config_registers *config_regs)
0606 {
0607     dev_t devt;
0608     struct hwicap_drvdata *drvdata = NULL;
0609     int retval = 0;
0610 
0611     dev_info(dev, "Xilinx icap port driver\n");
0612 
0613     mutex_lock(&icap_sem);
0614 
0615     if (id < 0) {
0616         for (id = 0; id < HWICAP_DEVICES; id++)
0617             if (!probed_devices[id])
0618                 break;
0619     }
0620     if (id < 0 || id >= HWICAP_DEVICES) {
0621         mutex_unlock(&icap_sem);
0622         dev_err(dev, "%s%i too large\n", DRIVER_NAME, id);
0623         return -EINVAL;
0624     }
0625     if (probed_devices[id]) {
0626         mutex_unlock(&icap_sem);
0627         dev_err(dev, "cannot assign to %s%i; it is already in use\n",
0628             DRIVER_NAME, id);
0629         return -EBUSY;
0630     }
0631 
0632     probed_devices[id] = 1;
0633     mutex_unlock(&icap_sem);
0634 
0635     devt = MKDEV(XHWICAP_MAJOR, XHWICAP_MINOR + id);
0636 
0637     drvdata = kzalloc(sizeof(struct hwicap_drvdata), GFP_KERNEL);
0638     if (!drvdata) {
0639         retval = -ENOMEM;
0640         goto failed0;
0641     }
0642     dev_set_drvdata(dev, (void *)drvdata);
0643 
0644     if (!regs_res) {
0645         dev_err(dev, "Couldn't get registers resource\n");
0646         retval = -EFAULT;
0647         goto failed1;
0648     }
0649 
0650     drvdata->mem_start = regs_res->start;
0651     drvdata->mem_end = regs_res->end;
0652     drvdata->mem_size = resource_size(regs_res);
0653 
0654     if (!request_mem_region(drvdata->mem_start,
0655                     drvdata->mem_size, DRIVER_NAME)) {
0656         dev_err(dev, "Couldn't lock memory region at %Lx\n",
0657             (unsigned long long) regs_res->start);
0658         retval = -EBUSY;
0659         goto failed1;
0660     }
0661 
0662     drvdata->devt = devt;
0663     drvdata->dev = dev;
0664     drvdata->base_address = ioremap(drvdata->mem_start, drvdata->mem_size);
0665     if (!drvdata->base_address) {
0666         dev_err(dev, "ioremap() failed\n");
0667         retval = -ENOMEM;
0668         goto failed2;
0669     }
0670 
0671     drvdata->config = config;
0672     drvdata->config_regs = config_regs;
0673 
0674     mutex_init(&drvdata->sem);
0675     drvdata->is_open = 0;
0676 
0677     dev_info(dev, "ioremap %llx to %p with size %llx\n",
0678          (unsigned long long) drvdata->mem_start,
0679          drvdata->base_address,
0680          (unsigned long long) drvdata->mem_size);
0681 
0682     cdev_init(&drvdata->cdev, &hwicap_fops);
0683     drvdata->cdev.owner = THIS_MODULE;
0684     retval = cdev_add(&drvdata->cdev, devt, 1);
0685     if (retval) {
0686         dev_err(dev, "cdev_add() failed\n");
0687         goto failed3;
0688     }
0689 
0690     device_create(icap_class, dev, devt, NULL, "%s%d", DRIVER_NAME, id);
0691     return 0;       /* success */
0692 
0693  failed3:
0694     iounmap(drvdata->base_address);
0695 
0696  failed2:
0697     release_mem_region(regs_res->start, drvdata->mem_size);
0698 
0699  failed1:
0700     kfree(drvdata);
0701 
0702  failed0:
0703     mutex_lock(&icap_sem);
0704     probed_devices[id] = 0;
0705     mutex_unlock(&icap_sem);
0706 
0707     return retval;
0708 }
0709 
0710 static struct hwicap_driver_config buffer_icap_config = {
0711     .get_configuration = buffer_icap_get_configuration,
0712     .set_configuration = buffer_icap_set_configuration,
0713     .get_status = buffer_icap_get_status,
0714     .reset = buffer_icap_reset,
0715 };
0716 
0717 static struct hwicap_driver_config fifo_icap_config = {
0718     .get_configuration = fifo_icap_get_configuration,
0719     .set_configuration = fifo_icap_set_configuration,
0720     .get_status = fifo_icap_get_status,
0721     .reset = fifo_icap_reset,
0722 };
0723 
0724 static int hwicap_remove(struct device *dev)
0725 {
0726     struct hwicap_drvdata *drvdata;
0727 
0728     drvdata = dev_get_drvdata(dev);
0729 
0730     if (!drvdata)
0731         return 0;
0732 
0733     device_destroy(icap_class, drvdata->devt);
0734     cdev_del(&drvdata->cdev);
0735     iounmap(drvdata->base_address);
0736     release_mem_region(drvdata->mem_start, drvdata->mem_size);
0737     kfree(drvdata);
0738 
0739     mutex_lock(&icap_sem);
0740     probed_devices[MINOR(dev->devt)-XHWICAP_MINOR] = 0;
0741     mutex_unlock(&icap_sem);
0742     return 0;       /* success */
0743 }
0744 
0745 #ifdef CONFIG_OF
0746 static int hwicap_of_probe(struct platform_device *op,
0747                      const struct hwicap_driver_config *config)
0748 {
0749     struct resource res;
0750     const unsigned int *id;
0751     const char *family;
0752     int rc;
0753     const struct config_registers *regs;
0754 
0755 
0756     rc = of_address_to_resource(op->dev.of_node, 0, &res);
0757     if (rc) {
0758         dev_err(&op->dev, "invalid address\n");
0759         return rc;
0760     }
0761 
0762     id = of_get_property(op->dev.of_node, "port-number", NULL);
0763 
0764     /* It's most likely that we're using V4, if the family is not
0765      * specified
0766      */
0767     regs = &v4_config_registers;
0768     family = of_get_property(op->dev.of_node, "xlnx,family", NULL);
0769 
0770     if (family) {
0771         if (!strcmp(family, "virtex2p"))
0772             regs = &v2_config_registers;
0773         else if (!strcmp(family, "virtex4"))
0774             regs = &v4_config_registers;
0775         else if (!strcmp(family, "virtex5"))
0776             regs = &v5_config_registers;
0777         else if (!strcmp(family, "virtex6"))
0778             regs = &v6_config_registers;
0779     }
0780     return hwicap_setup(&op->dev, id ? *id : -1, &res, config,
0781             regs);
0782 }
0783 #else
0784 static inline int hwicap_of_probe(struct platform_device *op,
0785                   const struct hwicap_driver_config *config)
0786 {
0787     return -EINVAL;
0788 }
0789 #endif /* CONFIG_OF */
0790 
0791 static const struct of_device_id hwicap_of_match[];
0792 static int hwicap_drv_probe(struct platform_device *pdev)
0793 {
0794     const struct of_device_id *match;
0795     struct resource *res;
0796     const struct config_registers *regs;
0797     const char *family;
0798 
0799     match = of_match_device(hwicap_of_match, &pdev->dev);
0800     if (match)
0801         return hwicap_of_probe(pdev, match->data);
0802 
0803     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0804     if (!res)
0805         return -ENODEV;
0806 
0807     /* It's most likely that we're using V4, if the family is not
0808      * specified
0809      */
0810     regs = &v4_config_registers;
0811     family = pdev->dev.platform_data;
0812 
0813     if (family) {
0814         if (!strcmp(family, "virtex2p"))
0815             regs = &v2_config_registers;
0816         else if (!strcmp(family, "virtex4"))
0817             regs = &v4_config_registers;
0818         else if (!strcmp(family, "virtex5"))
0819             regs = &v5_config_registers;
0820         else if (!strcmp(family, "virtex6"))
0821             regs = &v6_config_registers;
0822     }
0823 
0824     return hwicap_setup(&pdev->dev, pdev->id, res,
0825             &buffer_icap_config, regs);
0826 }
0827 
0828 static int hwicap_drv_remove(struct platform_device *pdev)
0829 {
0830     return hwicap_remove(&pdev->dev);
0831 }
0832 
0833 #ifdef CONFIG_OF
0834 /* Match table for device tree binding */
0835 static const struct of_device_id hwicap_of_match[] = {
0836     { .compatible = "xlnx,opb-hwicap-1.00.b", .data = &buffer_icap_config},
0837     { .compatible = "xlnx,xps-hwicap-1.00.a", .data = &fifo_icap_config},
0838     {},
0839 };
0840 MODULE_DEVICE_TABLE(of, hwicap_of_match);
0841 #else
0842 #define hwicap_of_match NULL
0843 #endif
0844 
0845 static struct platform_driver hwicap_platform_driver = {
0846     .probe = hwicap_drv_probe,
0847     .remove = hwicap_drv_remove,
0848     .driver = {
0849         .name = DRIVER_NAME,
0850         .of_match_table = hwicap_of_match,
0851     },
0852 };
0853 
0854 static int __init hwicap_module_init(void)
0855 {
0856     dev_t devt;
0857     int retval;
0858 
0859     icap_class = class_create(THIS_MODULE, "xilinx_config");
0860     mutex_init(&icap_sem);
0861 
0862     devt = MKDEV(XHWICAP_MAJOR, XHWICAP_MINOR);
0863     retval = register_chrdev_region(devt,
0864                     HWICAP_DEVICES,
0865                     DRIVER_NAME);
0866     if (retval < 0)
0867         return retval;
0868 
0869     retval = platform_driver_register(&hwicap_platform_driver);
0870     if (retval)
0871         goto failed;
0872 
0873     return retval;
0874 
0875  failed:
0876     unregister_chrdev_region(devt, HWICAP_DEVICES);
0877 
0878     return retval;
0879 }
0880 
0881 static void __exit hwicap_module_cleanup(void)
0882 {
0883     dev_t devt = MKDEV(XHWICAP_MAJOR, XHWICAP_MINOR);
0884 
0885     class_destroy(icap_class);
0886 
0887     platform_driver_unregister(&hwicap_platform_driver);
0888 
0889     unregister_chrdev_region(devt, HWICAP_DEVICES);
0890 }
0891 
0892 module_init(hwicap_module_init);
0893 module_exit(hwicap_module_cleanup);
0894 
0895 MODULE_AUTHOR("Xilinx, Inc; Xilinx Research Labs Group");
0896 MODULE_DESCRIPTION("Xilinx ICAP Port Driver");
0897 MODULE_LICENSE("GPL");