xilinx_hwicap.c 23 KB

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