1 /***************************************************************************** 2 * 3 * Author: Xilinx, Inc. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License as published by the 7 * Free Software Foundation; either version 2 of the License, or (at your 8 * option) any later version. 9 * 10 * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" 11 * AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND 12 * SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, 13 * OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, 14 * APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION 15 * THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, 16 * AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE 17 * FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY 18 * WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE 19 * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR 20 * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF 21 * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 22 * FOR A PARTICULAR PURPOSE. 23 * 24 * (c) Copyright 2002 Xilinx Inc., Systems Engineering Group 25 * (c) Copyright 2004 Xilinx Inc., Systems Engineering Group 26 * (c) Copyright 2007-2008 Xilinx Inc. 27 * All rights reserved. 28 * 29 * You should have received a copy of the GNU General Public License along 30 * with this program; if not, write to the Free Software Foundation, Inc., 31 * 675 Mass Ave, Cambridge, MA 02139, USA. 32 * 33 *****************************************************************************/ 34 35 /* 36 * This is the code behind /dev/icap* -- it allows a user-space 37 * application to use the Xilinx ICAP subsystem. 38 * 39 * The following operations are possible: 40 * 41 * open open the port and initialize for access. 42 * release release port 43 * write Write a bitstream to the configuration processor. 44 * read Read a data stream from the configuration processor. 45 * 46 * After being opened, the port is initialized and accessed to avoid a 47 * corrupted first read which may occur with some hardware. The port 48 * is left in a desynched state, requiring that a synch sequence be 49 * transmitted before any valid configuration data. A user will have 50 * exclusive access to the device while it remains open, and the state 51 * of the ICAP cannot be guaranteed after the device is closed. Note 52 * that a complete reset of the core and the state of the ICAP cannot 53 * be performed on many versions of the cores, hence users of this 54 * device should avoid making inconsistent accesses to the device. In 55 * particular, accessing the read interface, without first generating 56 * a write containing a readback packet can leave the ICAP in an 57 * inaccessible state. 58 * 59 * Note that in order to use the read interface, it is first necessary 60 * to write a request packet to the write interface. i.e., it is not 61 * possible to simply readback the bitstream (or any configuration 62 * bits) from a device without specifically requesting them first. 63 * The code to craft such packets is intended to be part of the 64 * user-space application code that uses this device. The simplest 65 * way to use this interface is simply: 66 * 67 * cp foo.bit /dev/icap0 68 * 69 * Note that unless foo.bit is an appropriately constructed partial 70 * bitstream, this has a high likelihood of overwriting the design 71 * currently programmed in the FPGA. 72 */ 73 74 #include <linux/module.h> 75 #include <linux/kernel.h> 76 #include <linux/types.h> 77 #include <linux/ioport.h> 78 #include <linux/interrupt.h> 79 #include <linux/fcntl.h> 80 #include <linux/init.h> 81 #include <linux/poll.h> 82 #include <linux/proc_fs.h> 83 #include <linux/mutex.h> 84 #include <linux/sysctl.h> 85 #include <linux/fs.h> 86 #include <linux/cdev.h> 87 #include <linux/of.h> 88 #include <linux/platform_device.h> 89 #include <linux/property.h> 90 #include <linux/slab.h> 91 #include <linux/io.h> 92 #include <linux/uaccess.h> 93 94 #include "xilinx_hwicap.h" 95 #include "buffer_icap.h" 96 #include "fifo_icap.h" 97 98 #define DRIVER_NAME "icap" 99 100 #define HWICAP_REGS (0x10000) 101 102 #define XHWICAP_MAJOR 259 103 #define XHWICAP_MINOR 0 104 #define HWICAP_DEVICES 1 105 106 /* An array, which is set to true when the device is registered. */ 107 static DEFINE_MUTEX(hwicap_mutex); 108 static bool probed_devices[HWICAP_DEVICES]; 109 static struct mutex icap_sem; 110 111 static const struct class icap_class = { 112 .name = "xilinx_config", 113 }; 114 115 #define UNIMPLEMENTED 0xFFFF 116 117 static const struct config_registers v2_config_registers = { 118 .CRC = 0, 119 .FAR = 1, 120 .FDRI = 2, 121 .FDRO = 3, 122 .CMD = 4, 123 .CTL = 5, 124 .MASK = 6, 125 .STAT = 7, 126 .LOUT = 8, 127 .COR = 9, 128 .MFWR = 10, 129 .FLR = 11, 130 .KEY = 12, 131 .CBC = 13, 132 .IDCODE = 14, 133 .AXSS = UNIMPLEMENTED, 134 .C0R_1 = UNIMPLEMENTED, 135 .CSOB = UNIMPLEMENTED, 136 .WBSTAR = UNIMPLEMENTED, 137 .TIMER = UNIMPLEMENTED, 138 .BOOTSTS = UNIMPLEMENTED, 139 .CTL_1 = UNIMPLEMENTED, 140 }; 141 142 static const struct config_registers v4_config_registers = { 143 .CRC = 0, 144 .FAR = 1, 145 .FDRI = 2, 146 .FDRO = 3, 147 .CMD = 4, 148 .CTL = 5, 149 .MASK = 6, 150 .STAT = 7, 151 .LOUT = 8, 152 .COR = 9, 153 .MFWR = 10, 154 .FLR = UNIMPLEMENTED, 155 .KEY = UNIMPLEMENTED, 156 .CBC = 11, 157 .IDCODE = 12, 158 .AXSS = 13, 159 .C0R_1 = UNIMPLEMENTED, 160 .CSOB = UNIMPLEMENTED, 161 .WBSTAR = UNIMPLEMENTED, 162 .TIMER = UNIMPLEMENTED, 163 .BOOTSTS = UNIMPLEMENTED, 164 .CTL_1 = UNIMPLEMENTED, 165 }; 166 167 static const struct config_registers v5_config_registers = { 168 .CRC = 0, 169 .FAR = 1, 170 .FDRI = 2, 171 .FDRO = 3, 172 .CMD = 4, 173 .CTL = 5, 174 .MASK = 6, 175 .STAT = 7, 176 .LOUT = 8, 177 .COR = 9, 178 .MFWR = 10, 179 .FLR = UNIMPLEMENTED, 180 .KEY = UNIMPLEMENTED, 181 .CBC = 11, 182 .IDCODE = 12, 183 .AXSS = 13, 184 .C0R_1 = 14, 185 .CSOB = 15, 186 .WBSTAR = 16, 187 .TIMER = 17, 188 .BOOTSTS = 18, 189 .CTL_1 = 19, 190 }; 191 192 static const struct config_registers v6_config_registers = { 193 .CRC = 0, 194 .FAR = 1, 195 .FDRI = 2, 196 .FDRO = 3, 197 .CMD = 4, 198 .CTL = 5, 199 .MASK = 6, 200 .STAT = 7, 201 .LOUT = 8, 202 .COR = 9, 203 .MFWR = 10, 204 .FLR = UNIMPLEMENTED, 205 .KEY = UNIMPLEMENTED, 206 .CBC = 11, 207 .IDCODE = 12, 208 .AXSS = 13, 209 .C0R_1 = 14, 210 .CSOB = 15, 211 .WBSTAR = 16, 212 .TIMER = 17, 213 .BOOTSTS = 22, 214 .CTL_1 = 24, 215 }; 216 217 /** 218 * hwicap_command_desync - Send a DESYNC command to the ICAP port. 219 * @drvdata: a pointer to the drvdata. 220 * 221 * Returns: '0' on success and failure value on error 222 * 223 * This command desynchronizes the ICAP After this command, a 224 * bitstream containing a NULL packet, followed by a SYNCH packet is 225 * required before the ICAP will recognize commands. 226 */ 227 static int hwicap_command_desync(struct hwicap_drvdata *drvdata) 228 { 229 u32 buffer[4]; 230 u32 index = 0; 231 232 /* 233 * Create the data to be written to the ICAP. 234 */ 235 buffer[index++] = hwicap_type_1_write(drvdata->config_regs->CMD) | 1; 236 buffer[index++] = XHI_CMD_DESYNCH; 237 buffer[index++] = XHI_NOOP_PACKET; 238 buffer[index++] = XHI_NOOP_PACKET; 239 240 /* 241 * Write the data to the FIFO and initiate the transfer of data present 242 * in the FIFO to the ICAP device. 243 */ 244 return drvdata->config->set_configuration(drvdata, 245 &buffer[0], index); 246 } 247 248 /** 249 * hwicap_get_configuration_register - Query a configuration register. 250 * @drvdata: a pointer to the drvdata. 251 * @reg: a constant which represents the configuration 252 * register value to be returned. 253 * Examples: XHI_IDCODE, XHI_FLR. 254 * @reg_data: returns the value of the register. 255 * 256 * Returns: '0' on success and failure value on error 257 * 258 * Sends a query packet to the ICAP and then receives the response. 259 * The icap is left in Synched state. 260 */ 261 static int hwicap_get_configuration_register(struct hwicap_drvdata *drvdata, 262 u32 reg, u32 *reg_data) 263 { 264 int status; 265 u32 buffer[6]; 266 u32 index = 0; 267 268 /* 269 * Create the data to be written to the ICAP. 270 */ 271 buffer[index++] = XHI_DUMMY_PACKET; 272 buffer[index++] = XHI_NOOP_PACKET; 273 buffer[index++] = XHI_SYNC_PACKET; 274 buffer[index++] = XHI_NOOP_PACKET; 275 buffer[index++] = XHI_NOOP_PACKET; 276 277 /* 278 * Write the data to the FIFO and initiate the transfer of data present 279 * in the FIFO to the ICAP device. 280 */ 281 status = drvdata->config->set_configuration(drvdata, 282 &buffer[0], index); 283 if (status) 284 return status; 285 286 /* If the syncword was not found, then we need to start over. */ 287 status = drvdata->config->get_status(drvdata); 288 if ((status & XHI_SR_DALIGN_MASK) != XHI_SR_DALIGN_MASK) 289 return -EIO; 290 291 index = 0; 292 buffer[index++] = hwicap_type_1_read(reg) | 1; 293 buffer[index++] = XHI_NOOP_PACKET; 294 buffer[index++] = XHI_NOOP_PACKET; 295 296 /* 297 * Write the data to the FIFO and initiate the transfer of data present 298 * in the FIFO to the ICAP device. 299 */ 300 status = drvdata->config->set_configuration(drvdata, 301 &buffer[0], index); 302 if (status) 303 return status; 304 305 /* 306 * Read the configuration register 307 */ 308 status = drvdata->config->get_configuration(drvdata, reg_data, 1); 309 if (status) 310 return status; 311 312 return 0; 313 } 314 315 static int hwicap_initialize_hwicap(struct hwicap_drvdata *drvdata) 316 { 317 int status; 318 u32 idcode; 319 320 dev_dbg(drvdata->dev, "initializing\n"); 321 322 /* Abort any current transaction, to make sure we have the 323 * ICAP in a good state. 324 */ 325 dev_dbg(drvdata->dev, "Reset...\n"); 326 drvdata->config->reset(drvdata); 327 328 dev_dbg(drvdata->dev, "Desync...\n"); 329 status = hwicap_command_desync(drvdata); 330 if (status) 331 return status; 332 333 /* Attempt to read the IDCODE from ICAP. This 334 * may not be returned correctly, due to the design of the 335 * hardware. 336 */ 337 dev_dbg(drvdata->dev, "Reading IDCODE...\n"); 338 status = hwicap_get_configuration_register( 339 drvdata, drvdata->config_regs->IDCODE, &idcode); 340 dev_dbg(drvdata->dev, "IDCODE = %x\n", idcode); 341 if (status) 342 return status; 343 344 dev_dbg(drvdata->dev, "Desync...\n"); 345 status = hwicap_command_desync(drvdata); 346 if (status) 347 return status; 348 349 return 0; 350 } 351 352 static ssize_t 353 hwicap_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) 354 { 355 struct hwicap_drvdata *drvdata = file->private_data; 356 ssize_t bytes_to_read = 0; 357 u32 *kbuf; 358 u32 words; 359 u32 bytes_remaining; 360 int status; 361 362 status = mutex_lock_interruptible(&drvdata->sem); 363 if (status) 364 return status; 365 366 if (drvdata->read_buffer_in_use) { 367 /* If there are leftover bytes in the buffer, just */ 368 /* return them and don't try to read more from the */ 369 /* ICAP device. */ 370 bytes_to_read = 371 (count < drvdata->read_buffer_in_use) ? count : 372 drvdata->read_buffer_in_use; 373 374 /* Return the data currently in the read buffer. */ 375 if (copy_to_user(buf, drvdata->read_buffer, bytes_to_read)) { 376 status = -EFAULT; 377 goto error; 378 } 379 drvdata->read_buffer_in_use -= bytes_to_read; 380 memmove(drvdata->read_buffer, 381 drvdata->read_buffer + bytes_to_read, 382 4 - bytes_to_read); 383 } else { 384 /* Get new data from the ICAP, and return what was requested. */ 385 kbuf = (u32 *) get_zeroed_page(GFP_KERNEL); 386 if (!kbuf) { 387 status = -ENOMEM; 388 goto error; 389 } 390 391 /* The ICAP device is only able to read complete */ 392 /* words. If a number of bytes that do not correspond */ 393 /* to complete words is requested, then we read enough */ 394 /* words to get the required number of bytes, and then */ 395 /* save the remaining bytes for the next read. */ 396 397 /* Determine the number of words to read, rounding up */ 398 /* if necessary. */ 399 words = ((count + 3) >> 2); 400 bytes_to_read = words << 2; 401 402 if (bytes_to_read > PAGE_SIZE) 403 bytes_to_read = PAGE_SIZE; 404 405 /* Ensure we only read a complete number of words. */ 406 bytes_remaining = bytes_to_read & 3; 407 bytes_to_read &= ~3; 408 words = bytes_to_read >> 2; 409 410 status = drvdata->config->get_configuration(drvdata, 411 kbuf, words); 412 413 /* If we didn't read correctly, then bail out. */ 414 if (status) { 415 free_page((unsigned long)kbuf); 416 goto error; 417 } 418 419 /* If we fail to return the data to the user, then bail out. */ 420 if (copy_to_user(buf, kbuf, bytes_to_read)) { 421 free_page((unsigned long)kbuf); 422 status = -EFAULT; 423 goto error; 424 } 425 memcpy(drvdata->read_buffer, 426 kbuf, 427 bytes_remaining); 428 drvdata->read_buffer_in_use = bytes_remaining; 429 free_page((unsigned long)kbuf); 430 } 431 status = bytes_to_read; 432 error: 433 mutex_unlock(&drvdata->sem); 434 return status; 435 } 436 437 static ssize_t 438 hwicap_write(struct file *file, const char __user *buf, 439 size_t count, loff_t *ppos) 440 { 441 struct hwicap_drvdata *drvdata = file->private_data; 442 ssize_t written = 0; 443 ssize_t left = count; 444 u32 *kbuf; 445 ssize_t len; 446 ssize_t status; 447 448 status = mutex_lock_interruptible(&drvdata->sem); 449 if (status) 450 return status; 451 452 left += drvdata->write_buffer_in_use; 453 454 /* Only write multiples of 4 bytes. */ 455 if (left < 4) { 456 status = 0; 457 goto error; 458 } 459 460 kbuf = (u32 *) __get_free_page(GFP_KERNEL); 461 if (!kbuf) { 462 status = -ENOMEM; 463 goto error; 464 } 465 466 while (left > 3) { 467 /* only write multiples of 4 bytes, so there might */ 468 /* be as many as 3 bytes left (at the end). */ 469 len = left; 470 471 if (len > PAGE_SIZE) 472 len = PAGE_SIZE; 473 len &= ~3; 474 475 if (drvdata->write_buffer_in_use) { 476 memcpy(kbuf, drvdata->write_buffer, 477 drvdata->write_buffer_in_use); 478 if (copy_from_user( 479 (((char *)kbuf) + drvdata->write_buffer_in_use), 480 buf + written, 481 len - (drvdata->write_buffer_in_use))) { 482 free_page((unsigned long)kbuf); 483 status = -EFAULT; 484 goto error; 485 } 486 } else { 487 if (copy_from_user(kbuf, buf + written, len)) { 488 free_page((unsigned long)kbuf); 489 status = -EFAULT; 490 goto error; 491 } 492 } 493 494 status = drvdata->config->set_configuration(drvdata, 495 kbuf, len >> 2); 496 497 if (status) { 498 free_page((unsigned long)kbuf); 499 status = -EFAULT; 500 goto error; 501 } 502 if (drvdata->write_buffer_in_use) { 503 len -= drvdata->write_buffer_in_use; 504 left -= drvdata->write_buffer_in_use; 505 drvdata->write_buffer_in_use = 0; 506 } 507 written += len; 508 left -= len; 509 } 510 if ((left > 0) && (left < 4)) { 511 if (!copy_from_user(drvdata->write_buffer, 512 buf + written, left)) { 513 drvdata->write_buffer_in_use = left; 514 written += left; 515 left = 0; 516 } 517 } 518 519 free_page((unsigned long)kbuf); 520 status = written; 521 error: 522 mutex_unlock(&drvdata->sem); 523 return status; 524 } 525 526 static int hwicap_open(struct inode *inode, struct file *file) 527 { 528 struct hwicap_drvdata *drvdata; 529 int status; 530 531 mutex_lock(&hwicap_mutex); 532 drvdata = container_of(inode->i_cdev, struct hwicap_drvdata, cdev); 533 534 status = mutex_lock_interruptible(&drvdata->sem); 535 if (status) 536 goto out; 537 538 if (drvdata->is_open) { 539 status = -EBUSY; 540 goto error; 541 } 542 543 status = hwicap_initialize_hwicap(drvdata); 544 if (status) { 545 dev_err(drvdata->dev, "Failed to open file"); 546 goto error; 547 } 548 549 file->private_data = drvdata; 550 drvdata->write_buffer_in_use = 0; 551 drvdata->read_buffer_in_use = 0; 552 drvdata->is_open = 1; 553 554 error: 555 mutex_unlock(&drvdata->sem); 556 out: 557 mutex_unlock(&hwicap_mutex); 558 return status; 559 } 560 561 static int hwicap_release(struct inode *inode, struct file *file) 562 { 563 struct hwicap_drvdata *drvdata = file->private_data; 564 int i; 565 int status = 0; 566 567 mutex_lock(&drvdata->sem); 568 569 if (drvdata->write_buffer_in_use) { 570 /* Flush write buffer. */ 571 for (i = drvdata->write_buffer_in_use; i < 4; i++) 572 drvdata->write_buffer[i] = 0; 573 574 status = drvdata->config->set_configuration(drvdata, 575 (u32 *) drvdata->write_buffer, 1); 576 if (status) 577 goto error; 578 } 579 580 status = hwicap_command_desync(drvdata); 581 if (status) 582 goto error; 583 584 error: 585 drvdata->is_open = 0; 586 mutex_unlock(&drvdata->sem); 587 return status; 588 } 589 590 static const struct file_operations hwicap_fops = { 591 .owner = THIS_MODULE, 592 .write = hwicap_write, 593 .read = hwicap_read, 594 .open = hwicap_open, 595 .release = hwicap_release, 596 .llseek = noop_llseek, 597 }; 598 599 static int hwicap_setup(struct platform_device *pdev, int id, 600 const struct hwicap_driver_config *config, 601 const struct config_registers *config_regs) 602 { 603 dev_t devt; 604 struct hwicap_drvdata *drvdata = NULL; 605 struct device *dev = &pdev->dev; 606 int retval; 607 608 dev_info(dev, "Xilinx icap port driver\n"); 609 610 mutex_lock(&icap_sem); 611 612 if (id < 0) { 613 for (id = 0; id < HWICAP_DEVICES; id++) 614 if (!probed_devices[id]) 615 break; 616 } 617 if (id < 0 || id >= HWICAP_DEVICES) { 618 mutex_unlock(&icap_sem); 619 dev_err(dev, "%s%i too large\n", DRIVER_NAME, id); 620 return -EINVAL; 621 } 622 if (probed_devices[id]) { 623 mutex_unlock(&icap_sem); 624 dev_err(dev, "cannot assign to %s%i; it is already in use\n", 625 DRIVER_NAME, id); 626 return -EBUSY; 627 } 628 629 probed_devices[id] = 1; 630 mutex_unlock(&icap_sem); 631 632 devt = MKDEV(XHWICAP_MAJOR, XHWICAP_MINOR + id); 633 634 drvdata = devm_kzalloc(dev, sizeof(struct hwicap_drvdata), GFP_KERNEL); 635 if (!drvdata) { 636 retval = -ENOMEM; 637 goto failed; 638 } 639 dev_set_drvdata(dev, drvdata); 640 641 drvdata->base_address = devm_platform_ioremap_resource(pdev, 0); 642 if (IS_ERR(drvdata->base_address)) { 643 retval = PTR_ERR(drvdata->base_address); 644 goto failed; 645 } 646 647 drvdata->devt = devt; 648 drvdata->dev = dev; 649 drvdata->config = config; 650 drvdata->config_regs = config_regs; 651 652 mutex_init(&drvdata->sem); 653 drvdata->is_open = 0; 654 655 cdev_init(&drvdata->cdev, &hwicap_fops); 656 drvdata->cdev.owner = THIS_MODULE; 657 retval = cdev_add(&drvdata->cdev, devt, 1); 658 if (retval) { 659 dev_err(dev, "cdev_add() failed\n"); 660 goto failed; 661 } 662 663 device_create(&icap_class, dev, devt, NULL, "%s%d", DRIVER_NAME, id); 664 return 0; /* success */ 665 666 failed: 667 mutex_lock(&icap_sem); 668 probed_devices[id] = 0; 669 mutex_unlock(&icap_sem); 670 671 return retval; 672 } 673 674 static struct hwicap_driver_config buffer_icap_config = { 675 .get_configuration = buffer_icap_get_configuration, 676 .set_configuration = buffer_icap_set_configuration, 677 .get_status = buffer_icap_get_status, 678 .reset = buffer_icap_reset, 679 }; 680 681 static struct hwicap_driver_config fifo_icap_config = { 682 .get_configuration = fifo_icap_get_configuration, 683 .set_configuration = fifo_icap_set_configuration, 684 .get_status = fifo_icap_get_status, 685 .reset = fifo_icap_reset, 686 }; 687 688 static int hwicap_drv_probe(struct platform_device *pdev) 689 { 690 const struct config_registers *regs; 691 const struct hwicap_driver_config *config; 692 const char *family; 693 int id = -1; 694 695 config = device_get_match_data(&pdev->dev); 696 697 of_property_read_u32(pdev->dev.of_node, "port-number", &id); 698 699 /* It's most likely that we're using V4, if the family is not 700 * specified 701 */ 702 regs = &v4_config_registers; 703 if (!of_property_read_string(pdev->dev.of_node, "xlnx,family", &family)) { 704 if (!strcmp(family, "virtex2p")) 705 regs = &v2_config_registers; 706 else if (!strcmp(family, "virtex4")) 707 regs = &v4_config_registers; 708 else if (!strcmp(family, "virtex5")) 709 regs = &v5_config_registers; 710 else if (!strcmp(family, "virtex6")) 711 regs = &v6_config_registers; 712 } 713 return hwicap_setup(pdev, id, config, regs); 714 } 715 716 static void hwicap_drv_remove(struct platform_device *pdev) 717 { 718 struct device *dev = &pdev->dev; 719 struct hwicap_drvdata *drvdata; 720 721 drvdata = dev_get_drvdata(dev); 722 723 device_destroy(&icap_class, drvdata->devt); 724 cdev_del(&drvdata->cdev); 725 726 mutex_lock(&icap_sem); 727 probed_devices[MINOR(dev->devt)-XHWICAP_MINOR] = 0; 728 mutex_unlock(&icap_sem); 729 } 730 731 /* Match table for device tree binding */ 732 static const struct of_device_id hwicap_of_match[] = { 733 { .compatible = "xlnx,opb-hwicap-1.00.b", .data = &buffer_icap_config}, 734 { .compatible = "xlnx,xps-hwicap-1.00.a", .data = &fifo_icap_config}, 735 {}, 736 }; 737 MODULE_DEVICE_TABLE(of, hwicap_of_match); 738 739 static struct platform_driver hwicap_platform_driver = { 740 .probe = hwicap_drv_probe, 741 .remove = hwicap_drv_remove, 742 .driver = { 743 .name = DRIVER_NAME, 744 .of_match_table = hwicap_of_match, 745 }, 746 }; 747 748 static int __init hwicap_module_init(void) 749 { 750 dev_t devt; 751 int retval; 752 753 retval = class_register(&icap_class); 754 if (retval) 755 return retval; 756 mutex_init(&icap_sem); 757 758 devt = MKDEV(XHWICAP_MAJOR, XHWICAP_MINOR); 759 retval = register_chrdev_region(devt, 760 HWICAP_DEVICES, 761 DRIVER_NAME); 762 if (retval < 0) 763 return retval; 764 765 retval = platform_driver_register(&hwicap_platform_driver); 766 if (retval) 767 goto failed; 768 769 return retval; 770 771 failed: 772 unregister_chrdev_region(devt, HWICAP_DEVICES); 773 774 return retval; 775 } 776 777 static void __exit hwicap_module_cleanup(void) 778 { 779 dev_t devt = MKDEV(XHWICAP_MAJOR, XHWICAP_MINOR); 780 781 class_unregister(&icap_class); 782 783 platform_driver_unregister(&hwicap_platform_driver); 784 785 unregister_chrdev_region(devt, HWICAP_DEVICES); 786 } 787 788 module_init(hwicap_module_init); 789 module_exit(hwicap_module_cleanup); 790 791 MODULE_AUTHOR("Xilinx, Inc; Xilinx Research Labs Group"); 792 MODULE_DESCRIPTION("Xilinx ICAP Port Driver"); 793 MODULE_LICENSE("GPL"); 794