tpci200.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641
  1. /**
  2. * tpci200.c
  3. *
  4. * driver for the TEWS TPCI-200 device
  5. *
  6. * Copyright (C) 2009-2012 CERN (www.cern.ch)
  7. * Author: Nicolas Serafini, EIC2 SA
  8. * Author: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
  9. *
  10. * This program is free software; you can redistribute it and/or modify it
  11. * under the terms of the GNU General Public License as published by the Free
  12. * Software Foundation; version 2 of the License.
  13. */
  14. #include <linux/module.h>
  15. #include <linux/slab.h>
  16. #include "tpci200.h"
  17. static const u16 tpci200_status_timeout[] = {
  18. TPCI200_A_TIMEOUT,
  19. TPCI200_B_TIMEOUT,
  20. TPCI200_C_TIMEOUT,
  21. TPCI200_D_TIMEOUT,
  22. };
  23. static const u16 tpci200_status_error[] = {
  24. TPCI200_A_ERROR,
  25. TPCI200_B_ERROR,
  26. TPCI200_C_ERROR,
  27. TPCI200_D_ERROR,
  28. };
  29. static const size_t tpci200_space_size[IPACK_SPACE_COUNT] = {
  30. [IPACK_IO_SPACE] = TPCI200_IO_SPACE_SIZE,
  31. [IPACK_ID_SPACE] = TPCI200_ID_SPACE_SIZE,
  32. [IPACK_INT_SPACE] = TPCI200_INT_SPACE_SIZE,
  33. [IPACK_MEM8_SPACE] = TPCI200_MEM8_SPACE_SIZE,
  34. [IPACK_MEM16_SPACE] = TPCI200_MEM16_SPACE_SIZE,
  35. };
  36. static const size_t tpci200_space_interval[IPACK_SPACE_COUNT] = {
  37. [IPACK_IO_SPACE] = TPCI200_IO_SPACE_INTERVAL,
  38. [IPACK_ID_SPACE] = TPCI200_ID_SPACE_INTERVAL,
  39. [IPACK_INT_SPACE] = TPCI200_INT_SPACE_INTERVAL,
  40. [IPACK_MEM8_SPACE] = TPCI200_MEM8_SPACE_INTERVAL,
  41. [IPACK_MEM16_SPACE] = TPCI200_MEM16_SPACE_INTERVAL,
  42. };
  43. static struct tpci200_board *check_slot(struct ipack_device *dev)
  44. {
  45. struct tpci200_board *tpci200;
  46. if (dev == NULL)
  47. return NULL;
  48. tpci200 = dev_get_drvdata(dev->bus->parent);
  49. if (tpci200 == NULL) {
  50. dev_info(&dev->dev, "carrier board not found\n");
  51. return NULL;
  52. }
  53. if (dev->slot >= TPCI200_NB_SLOT) {
  54. dev_info(&dev->dev,
  55. "Slot [%d:%d] doesn't exist! Last tpci200 slot is %d.\n",
  56. dev->bus->bus_nr, dev->slot, TPCI200_NB_SLOT-1);
  57. return NULL;
  58. }
  59. return tpci200;
  60. }
  61. static void tpci200_clear_mask(struct tpci200_board *tpci200,
  62. __le16 __iomem *addr, u16 mask)
  63. {
  64. unsigned long flags;
  65. spin_lock_irqsave(&tpci200->regs_lock, flags);
  66. iowrite16(ioread16(addr) & (~mask), addr);
  67. spin_unlock_irqrestore(&tpci200->regs_lock, flags);
  68. }
  69. static void tpci200_set_mask(struct tpci200_board *tpci200,
  70. __le16 __iomem *addr, u16 mask)
  71. {
  72. unsigned long flags;
  73. spin_lock_irqsave(&tpci200->regs_lock, flags);
  74. iowrite16(ioread16(addr) | mask, addr);
  75. spin_unlock_irqrestore(&tpci200->regs_lock, flags);
  76. }
  77. static void tpci200_unregister(struct tpci200_board *tpci200)
  78. {
  79. free_irq(tpci200->info->pdev->irq, (void *) tpci200);
  80. pci_iounmap(tpci200->info->pdev, tpci200->info->interface_regs);
  81. pci_iounmap(tpci200->info->pdev, tpci200->info->cfg_regs);
  82. pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR);
  83. pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR);
  84. pci_release_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR);
  85. pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR);
  86. pci_release_region(tpci200->info->pdev, TPCI200_CFG_MEM_BAR);
  87. pci_disable_device(tpci200->info->pdev);
  88. pci_dev_put(tpci200->info->pdev);
  89. }
  90. static void tpci200_enable_irq(struct tpci200_board *tpci200,
  91. int islot)
  92. {
  93. tpci200_set_mask(tpci200,
  94. &tpci200->info->interface_regs->control[islot],
  95. TPCI200_INT0_EN | TPCI200_INT1_EN);
  96. }
  97. static void tpci200_disable_irq(struct tpci200_board *tpci200,
  98. int islot)
  99. {
  100. tpci200_clear_mask(tpci200,
  101. &tpci200->info->interface_regs->control[islot],
  102. TPCI200_INT0_EN | TPCI200_INT1_EN);
  103. }
  104. static irqreturn_t tpci200_slot_irq(struct slot_irq *slot_irq)
  105. {
  106. irqreturn_t ret;
  107. if (!slot_irq)
  108. return -ENODEV;
  109. ret = slot_irq->handler(slot_irq->arg);
  110. return ret;
  111. }
  112. static irqreturn_t tpci200_interrupt(int irq, void *dev_id)
  113. {
  114. struct tpci200_board *tpci200 = (struct tpci200_board *) dev_id;
  115. struct slot_irq *slot_irq;
  116. irqreturn_t ret;
  117. u16 status_reg;
  118. int i;
  119. /* Read status register */
  120. status_reg = ioread16(&tpci200->info->interface_regs->status);
  121. /* Did we cause the interrupt? */
  122. if (!(status_reg & TPCI200_SLOT_INT_MASK))
  123. return IRQ_NONE;
  124. /* callback to the IRQ handler for the corresponding slot */
  125. rcu_read_lock();
  126. for (i = 0; i < TPCI200_NB_SLOT; i++) {
  127. if (!(status_reg & ((TPCI200_A_INT0 | TPCI200_A_INT1) << (2 * i))))
  128. continue;
  129. slot_irq = rcu_dereference(tpci200->slots[i].irq);
  130. ret = tpci200_slot_irq(slot_irq);
  131. if (ret == -ENODEV) {
  132. dev_info(&tpci200->info->pdev->dev,
  133. "No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n",
  134. tpci200->number, i);
  135. tpci200_disable_irq(tpci200, i);
  136. }
  137. }
  138. rcu_read_unlock();
  139. return IRQ_HANDLED;
  140. }
  141. static int tpci200_free_irq(struct ipack_device *dev)
  142. {
  143. struct slot_irq *slot_irq;
  144. struct tpci200_board *tpci200;
  145. tpci200 = check_slot(dev);
  146. if (tpci200 == NULL)
  147. return -EINVAL;
  148. if (mutex_lock_interruptible(&tpci200->mutex))
  149. return -ERESTARTSYS;
  150. if (tpci200->slots[dev->slot].irq == NULL) {
  151. mutex_unlock(&tpci200->mutex);
  152. return -EINVAL;
  153. }
  154. tpci200_disable_irq(tpci200, dev->slot);
  155. slot_irq = tpci200->slots[dev->slot].irq;
  156. /* uninstall handler */
  157. RCU_INIT_POINTER(tpci200->slots[dev->slot].irq, NULL);
  158. synchronize_rcu();
  159. kfree(slot_irq);
  160. mutex_unlock(&tpci200->mutex);
  161. return 0;
  162. }
  163. static int tpci200_request_irq(struct ipack_device *dev,
  164. irqreturn_t (*handler)(void *), void *arg)
  165. {
  166. int res = 0;
  167. struct slot_irq *slot_irq;
  168. struct tpci200_board *tpci200;
  169. tpci200 = check_slot(dev);
  170. if (tpci200 == NULL)
  171. return -EINVAL;
  172. if (mutex_lock_interruptible(&tpci200->mutex))
  173. return -ERESTARTSYS;
  174. if (tpci200->slots[dev->slot].irq != NULL) {
  175. dev_err(&dev->dev,
  176. "Slot [%d:%d] IRQ already registered !\n",
  177. dev->bus->bus_nr,
  178. dev->slot);
  179. res = -EINVAL;
  180. goto out_unlock;
  181. }
  182. slot_irq = kzalloc(sizeof(struct slot_irq), GFP_KERNEL);
  183. if (slot_irq == NULL) {
  184. dev_err(&dev->dev,
  185. "Slot [%d:%d] unable to allocate memory for IRQ !\n",
  186. dev->bus->bus_nr, dev->slot);
  187. res = -ENOMEM;
  188. goto out_unlock;
  189. }
  190. /*
  191. * WARNING: Setup Interrupt Vector in the IndustryPack device
  192. * before an IRQ request.
  193. * Read the User Manual of your IndustryPack device to know
  194. * where to write the vector in memory.
  195. */
  196. slot_irq->handler = handler;
  197. slot_irq->arg = arg;
  198. slot_irq->holder = dev;
  199. rcu_assign_pointer(tpci200->slots[dev->slot].irq, slot_irq);
  200. tpci200_enable_irq(tpci200, dev->slot);
  201. out_unlock:
  202. mutex_unlock(&tpci200->mutex);
  203. return res;
  204. }
  205. static int tpci200_register(struct tpci200_board *tpci200)
  206. {
  207. int i;
  208. int res;
  209. phys_addr_t ioidint_base;
  210. unsigned short slot_ctrl;
  211. if (pci_enable_device(tpci200->info->pdev) < 0)
  212. return -ENODEV;
  213. /* Request IP interface register (Bar 2) */
  214. res = pci_request_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR,
  215. "Carrier IP interface registers");
  216. if (res) {
  217. dev_err(&tpci200->info->pdev->dev,
  218. "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 2 !",
  219. tpci200->info->pdev->bus->number,
  220. tpci200->info->pdev->devfn);
  221. goto out_disable_pci;
  222. }
  223. /* Request IO ID INT space (Bar 3) */
  224. res = pci_request_region(tpci200->info->pdev,
  225. TPCI200_IO_ID_INT_SPACES_BAR,
  226. "Carrier IO ID INT space");
  227. if (res) {
  228. dev_err(&tpci200->info->pdev->dev,
  229. "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 3 !",
  230. tpci200->info->pdev->bus->number,
  231. tpci200->info->pdev->devfn);
  232. goto out_release_ip_space;
  233. }
  234. /* Request MEM8 space (Bar 5) */
  235. res = pci_request_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR,
  236. "Carrier MEM8 space");
  237. if (res) {
  238. dev_err(&tpci200->info->pdev->dev,
  239. "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 5!",
  240. tpci200->info->pdev->bus->number,
  241. tpci200->info->pdev->devfn);
  242. goto out_release_ioid_int_space;
  243. }
  244. /* Request MEM16 space (Bar 4) */
  245. res = pci_request_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR,
  246. "Carrier MEM16 space");
  247. if (res) {
  248. dev_err(&tpci200->info->pdev->dev,
  249. "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 4!",
  250. tpci200->info->pdev->bus->number,
  251. tpci200->info->pdev->devfn);
  252. goto out_release_mem8_space;
  253. }
  254. /* Map internal tpci200 driver user space */
  255. tpci200->info->interface_regs =
  256. ioremap_nocache(pci_resource_start(tpci200->info->pdev,
  257. TPCI200_IP_INTERFACE_BAR),
  258. TPCI200_IFACE_SIZE);
  259. /* Initialize lock that protects interface_regs */
  260. spin_lock_init(&tpci200->regs_lock);
  261. ioidint_base = pci_resource_start(tpci200->info->pdev,
  262. TPCI200_IO_ID_INT_SPACES_BAR);
  263. tpci200->mod_mem[IPACK_IO_SPACE] = ioidint_base + TPCI200_IO_SPACE_OFF;
  264. tpci200->mod_mem[IPACK_ID_SPACE] = ioidint_base + TPCI200_ID_SPACE_OFF;
  265. tpci200->mod_mem[IPACK_INT_SPACE] =
  266. ioidint_base + TPCI200_INT_SPACE_OFF;
  267. tpci200->mod_mem[IPACK_MEM8_SPACE] =
  268. pci_resource_start(tpci200->info->pdev,
  269. TPCI200_MEM8_SPACE_BAR);
  270. tpci200->mod_mem[IPACK_MEM16_SPACE] =
  271. pci_resource_start(tpci200->info->pdev,
  272. TPCI200_MEM16_SPACE_BAR);
  273. /* Set the default parameters of the slot
  274. * INT0 disabled, level sensitive
  275. * INT1 disabled, level sensitive
  276. * error interrupt disabled
  277. * timeout interrupt disabled
  278. * recover time disabled
  279. * clock rate 8 MHz
  280. */
  281. slot_ctrl = 0;
  282. for (i = 0; i < TPCI200_NB_SLOT; i++)
  283. writew(slot_ctrl, &tpci200->info->interface_regs->control[i]);
  284. res = request_irq(tpci200->info->pdev->irq,
  285. tpci200_interrupt, IRQF_SHARED,
  286. KBUILD_MODNAME, (void *) tpci200);
  287. if (res) {
  288. dev_err(&tpci200->info->pdev->dev,
  289. "(bn 0x%X, sn 0x%X) unable to register IRQ !",
  290. tpci200->info->pdev->bus->number,
  291. tpci200->info->pdev->devfn);
  292. goto out_release_ioid_int_space;
  293. }
  294. return 0;
  295. out_release_mem8_space:
  296. pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR);
  297. out_release_ioid_int_space:
  298. pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR);
  299. out_release_ip_space:
  300. pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR);
  301. out_disable_pci:
  302. pci_disable_device(tpci200->info->pdev);
  303. return res;
  304. }
  305. static int tpci200_get_clockrate(struct ipack_device *dev)
  306. {
  307. struct tpci200_board *tpci200 = check_slot(dev);
  308. __le16 __iomem *addr;
  309. if (!tpci200)
  310. return -ENODEV;
  311. addr = &tpci200->info->interface_regs->control[dev->slot];
  312. return (ioread16(addr) & TPCI200_CLK32) ? 32 : 8;
  313. }
  314. static int tpci200_set_clockrate(struct ipack_device *dev, int mherz)
  315. {
  316. struct tpci200_board *tpci200 = check_slot(dev);
  317. __le16 __iomem *addr;
  318. if (!tpci200)
  319. return -ENODEV;
  320. addr = &tpci200->info->interface_regs->control[dev->slot];
  321. switch (mherz) {
  322. case 8:
  323. tpci200_clear_mask(tpci200, addr, TPCI200_CLK32);
  324. break;
  325. case 32:
  326. tpci200_set_mask(tpci200, addr, TPCI200_CLK32);
  327. break;
  328. default:
  329. return -EINVAL;
  330. }
  331. return 0;
  332. }
  333. static int tpci200_get_error(struct ipack_device *dev)
  334. {
  335. struct tpci200_board *tpci200 = check_slot(dev);
  336. __le16 __iomem *addr;
  337. u16 mask;
  338. if (!tpci200)
  339. return -ENODEV;
  340. addr = &tpci200->info->interface_regs->status;
  341. mask = tpci200_status_error[dev->slot];
  342. return (ioread16(addr) & mask) ? 1 : 0;
  343. }
  344. static int tpci200_get_timeout(struct ipack_device *dev)
  345. {
  346. struct tpci200_board *tpci200 = check_slot(dev);
  347. __le16 __iomem *addr;
  348. u16 mask;
  349. if (!tpci200)
  350. return -ENODEV;
  351. addr = &tpci200->info->interface_regs->status;
  352. mask = tpci200_status_timeout[dev->slot];
  353. return (ioread16(addr) & mask) ? 1 : 0;
  354. }
  355. static int tpci200_reset_timeout(struct ipack_device *dev)
  356. {
  357. struct tpci200_board *tpci200 = check_slot(dev);
  358. __le16 __iomem *addr;
  359. u16 mask;
  360. if (!tpci200)
  361. return -ENODEV;
  362. addr = &tpci200->info->interface_regs->status;
  363. mask = tpci200_status_timeout[dev->slot];
  364. iowrite16(mask, addr);
  365. return 0;
  366. }
  367. static void tpci200_uninstall(struct tpci200_board *tpci200)
  368. {
  369. tpci200_unregister(tpci200);
  370. kfree(tpci200->slots);
  371. }
  372. static const struct ipack_bus_ops tpci200_bus_ops = {
  373. .request_irq = tpci200_request_irq,
  374. .free_irq = tpci200_free_irq,
  375. .get_clockrate = tpci200_get_clockrate,
  376. .set_clockrate = tpci200_set_clockrate,
  377. .get_error = tpci200_get_error,
  378. .get_timeout = tpci200_get_timeout,
  379. .reset_timeout = tpci200_reset_timeout,
  380. };
  381. static int tpci200_install(struct tpci200_board *tpci200)
  382. {
  383. int res;
  384. tpci200->slots = kzalloc(
  385. TPCI200_NB_SLOT * sizeof(struct tpci200_slot), GFP_KERNEL);
  386. if (tpci200->slots == NULL)
  387. return -ENOMEM;
  388. res = tpci200_register(tpci200);
  389. if (res) {
  390. kfree(tpci200->slots);
  391. tpci200->slots = NULL;
  392. return res;
  393. }
  394. mutex_init(&tpci200->mutex);
  395. return 0;
  396. }
  397. static void tpci200_release_device(struct ipack_device *dev)
  398. {
  399. kfree(dev);
  400. }
  401. static int tpci200_create_device(struct tpci200_board *tpci200, int i)
  402. {
  403. int ret;
  404. enum ipack_space space;
  405. struct ipack_device *dev =
  406. kzalloc(sizeof(struct ipack_device), GFP_KERNEL);
  407. if (!dev)
  408. return -ENOMEM;
  409. dev->slot = i;
  410. dev->bus = tpci200->info->ipack_bus;
  411. dev->release = tpci200_release_device;
  412. for (space = 0; space < IPACK_SPACE_COUNT; space++) {
  413. dev->region[space].start =
  414. tpci200->mod_mem[space]
  415. + tpci200_space_interval[space] * i;
  416. dev->region[space].size = tpci200_space_size[space];
  417. }
  418. ret = ipack_device_init(dev);
  419. if (ret < 0) {
  420. ipack_put_device(dev);
  421. return ret;
  422. }
  423. ret = ipack_device_add(dev);
  424. if (ret < 0)
  425. ipack_put_device(dev);
  426. return ret;
  427. }
  428. static int tpci200_pci_probe(struct pci_dev *pdev,
  429. const struct pci_device_id *id)
  430. {
  431. int ret, i;
  432. struct tpci200_board *tpci200;
  433. u32 reg32;
  434. tpci200 = kzalloc(sizeof(struct tpci200_board), GFP_KERNEL);
  435. if (!tpci200)
  436. return -ENOMEM;
  437. tpci200->info = kzalloc(sizeof(struct tpci200_infos), GFP_KERNEL);
  438. if (!tpci200->info) {
  439. ret = -ENOMEM;
  440. goto out_err_info;
  441. }
  442. pci_dev_get(pdev);
  443. /* Obtain a mapping of the carrier's PCI configuration registers */
  444. ret = pci_request_region(pdev, TPCI200_CFG_MEM_BAR,
  445. KBUILD_MODNAME " Configuration Memory");
  446. if (ret) {
  447. dev_err(&pdev->dev, "Failed to allocate PCI Configuration Memory");
  448. ret = -EBUSY;
  449. goto out_err_pci_request;
  450. }
  451. tpci200->info->cfg_regs = ioremap_nocache(
  452. pci_resource_start(pdev, TPCI200_CFG_MEM_BAR),
  453. pci_resource_len(pdev, TPCI200_CFG_MEM_BAR));
  454. if (!tpci200->info->cfg_regs) {
  455. dev_err(&pdev->dev, "Failed to map PCI Configuration Memory");
  456. ret = -EFAULT;
  457. goto out_err_ioremap;
  458. }
  459. /* Disable byte swapping for 16 bit IP module access. This will ensure
  460. * that the Industrypack big endian byte order is preserved by the
  461. * carrier. */
  462. reg32 = ioread32(tpci200->info->cfg_regs + LAS1_DESC);
  463. reg32 |= 1 << LAS_BIT_BIGENDIAN;
  464. iowrite32(reg32, tpci200->info->cfg_regs + LAS1_DESC);
  465. reg32 = ioread32(tpci200->info->cfg_regs + LAS2_DESC);
  466. reg32 |= 1 << LAS_BIT_BIGENDIAN;
  467. iowrite32(reg32, tpci200->info->cfg_regs + LAS2_DESC);
  468. /* Save struct pci_dev pointer */
  469. tpci200->info->pdev = pdev;
  470. tpci200->info->id_table = (struct pci_device_id *)id;
  471. /* register the device and initialize it */
  472. ret = tpci200_install(tpci200);
  473. if (ret) {
  474. dev_err(&pdev->dev, "error during tpci200 install\n");
  475. ret = -ENODEV;
  476. goto out_err_install;
  477. }
  478. /* Register the carrier in the industry pack bus driver */
  479. tpci200->info->ipack_bus = ipack_bus_register(&pdev->dev,
  480. TPCI200_NB_SLOT,
  481. &tpci200_bus_ops,
  482. THIS_MODULE);
  483. if (!tpci200->info->ipack_bus) {
  484. dev_err(&pdev->dev,
  485. "error registering the carrier on ipack driver\n");
  486. ret = -EFAULT;
  487. goto out_err_bus_register;
  488. }
  489. /* save the bus number given by ipack to logging purpose */
  490. tpci200->number = tpci200->info->ipack_bus->bus_nr;
  491. dev_set_drvdata(&pdev->dev, tpci200);
  492. for (i = 0; i < TPCI200_NB_SLOT; i++)
  493. tpci200_create_device(tpci200, i);
  494. return 0;
  495. out_err_bus_register:
  496. tpci200_uninstall(tpci200);
  497. out_err_install:
  498. iounmap(tpci200->info->cfg_regs);
  499. out_err_ioremap:
  500. pci_release_region(pdev, TPCI200_CFG_MEM_BAR);
  501. out_err_pci_request:
  502. pci_dev_put(pdev);
  503. kfree(tpci200->info);
  504. out_err_info:
  505. kfree(tpci200);
  506. return ret;
  507. }
  508. static void __tpci200_pci_remove(struct tpci200_board *tpci200)
  509. {
  510. ipack_bus_unregister(tpci200->info->ipack_bus);
  511. tpci200_uninstall(tpci200);
  512. kfree(tpci200->info);
  513. kfree(tpci200);
  514. }
  515. static void tpci200_pci_remove(struct pci_dev *dev)
  516. {
  517. struct tpci200_board *tpci200 = pci_get_drvdata(dev);
  518. __tpci200_pci_remove(tpci200);
  519. }
  520. static const struct pci_device_id tpci200_idtable[] = {
  521. { TPCI200_VENDOR_ID, TPCI200_DEVICE_ID, TPCI200_SUBVENDOR_ID,
  522. TPCI200_SUBDEVICE_ID },
  523. { 0, },
  524. };
  525. MODULE_DEVICE_TABLE(pci, tpci200_idtable);
  526. static struct pci_driver tpci200_pci_drv = {
  527. .name = "tpci200",
  528. .id_table = tpci200_idtable,
  529. .probe = tpci200_pci_probe,
  530. .remove = tpci200_pci_remove,
  531. };
  532. module_pci_driver(tpci200_pci_drv);
  533. MODULE_DESCRIPTION("TEWS TPCI-200 device driver");
  534. MODULE_LICENSE("GPL");