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