Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fpga manager: Add Altera CvP driver

Add FPGA manager driver for loading Arria-V/Cyclone-V/Stratix-V
and Arria-10 FPGAs via CvP.

Signed-off-by: Anatolij Gustschin <agust@denx.de>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Alan Tull <atull@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Anatolij Gustschin and committed by
Greg Kroah-Hartman
34d1dc17 b37fa560

+516
+8
Documentation/ABI/testing/sysfs-driver-altera-cvp
··· 1 + What: /sys/bus/pci/drivers/altera-cvp/chkcfg 2 + Date: May 2017 3 + Kernel Version: 4.13 4 + Contact: Anatolij Gustschin <agust@denx.de> 5 + Description: 6 + Contains either 1 or 0 and controls if configuration 7 + error checking in altera-cvp driver is turned on or 8 + off.
+7
drivers/fpga/Kconfig
··· 24 24 help 25 25 FPGA manager driver support for Lattice iCE40 FPGAs over SPI. 26 26 27 + config FPGA_MGR_ALTERA_CVP 28 + tristate "Altera Arria-V/Cyclone-V/Stratix-V CvP FPGA Manager" 29 + depends on PCI 30 + help 31 + FPGA manager driver support for Arria-V, Cyclone-V, Stratix-V 32 + and Arria 10 Altera FPGAs using the CvP interface over PCIe. 33 + 27 34 config FPGA_MGR_ALTERA_PS_SPI 28 35 tristate "Altera FPGA Passive Serial over SPI" 29 36 depends on SPI
+1
drivers/fpga/Makefile
··· 6 6 obj-$(CONFIG_FPGA) += fpga-mgr.o 7 7 8 8 # FPGA Manager Drivers 9 + obj-$(CONFIG_FPGA_MGR_ALTERA_CVP) += altera-cvp.o 9 10 obj-$(CONFIG_FPGA_MGR_ALTERA_PS_SPI) += altera-ps-spi.o 10 11 obj-$(CONFIG_FPGA_MGR_ICE40_SPI) += ice40-spi.o 11 12 obj-$(CONFIG_FPGA_MGR_SOCFPGA) += socfpga.o
+500
drivers/fpga/altera-cvp.c
··· 1 + /* 2 + * FPGA Manager Driver for Altera Arria/Cyclone/Stratix CvP 3 + * 4 + * Copyright (C) 2017 DENX Software Engineering 5 + * 6 + * Anatolij Gustschin <agust@denx.de> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License as published by 10 + * the Free Software Foundation; version 2 of the License. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * Manage Altera FPGA firmware using PCIe CvP. 18 + * Firmware must be in binary "rbf" format. 19 + */ 20 + 21 + #include <linux/delay.h> 22 + #include <linux/device.h> 23 + #include <linux/fpga/fpga-mgr.h> 24 + #include <linux/module.h> 25 + #include <linux/pci.h> 26 + #include <linux/sizes.h> 27 + 28 + #define CVP_BAR 0 /* BAR used for data transfer in memory mode */ 29 + #define CVP_DUMMY_WR 244 /* dummy writes to clear CvP state machine */ 30 + #define TIMEOUT_US 2000 /* CVP STATUS timeout for USERMODE polling */ 31 + 32 + /* Vendor Specific Extended Capability Registers */ 33 + #define VSE_PCIE_EXT_CAP_ID 0x200 34 + #define VSE_PCIE_EXT_CAP_ID_VAL 0x000b /* 16bit */ 35 + 36 + #define VSE_CVP_STATUS 0x21c /* 32bit */ 37 + #define VSE_CVP_STATUS_CFG_RDY BIT(18) /* CVP_CONFIG_READY */ 38 + #define VSE_CVP_STATUS_CFG_ERR BIT(19) /* CVP_CONFIG_ERROR */ 39 + #define VSE_CVP_STATUS_CVP_EN BIT(20) /* ctrl block is enabling CVP */ 40 + #define VSE_CVP_STATUS_USERMODE BIT(21) /* USERMODE */ 41 + #define VSE_CVP_STATUS_CFG_DONE BIT(23) /* CVP_CONFIG_DONE */ 42 + #define VSE_CVP_STATUS_PLD_CLK_IN_USE BIT(24) /* PLD_CLK_IN_USE */ 43 + 44 + #define VSE_CVP_MODE_CTRL 0x220 /* 32bit */ 45 + #define VSE_CVP_MODE_CTRL_CVP_MODE BIT(0) /* CVP (1) or normal mode (0) */ 46 + #define VSE_CVP_MODE_CTRL_HIP_CLK_SEL BIT(1) /* PMA (1) or fabric clock (0) */ 47 + #define VSE_CVP_MODE_CTRL_NUMCLKS_OFF 8 /* NUMCLKS bits offset */ 48 + #define VSE_CVP_MODE_CTRL_NUMCLKS_MASK GENMASK(15, 8) 49 + 50 + #define VSE_CVP_DATA 0x228 /* 32bit */ 51 + #define VSE_CVP_PROG_CTRL 0x22c /* 32bit */ 52 + #define VSE_CVP_PROG_CTRL_CONFIG BIT(0) 53 + #define VSE_CVP_PROG_CTRL_START_XFER BIT(1) 54 + 55 + #define VSE_UNCOR_ERR_STATUS 0x234 /* 32bit */ 56 + #define VSE_UNCOR_ERR_CVP_CFG_ERR BIT(5) /* CVP_CONFIG_ERROR_LATCHED */ 57 + 58 + #define DRV_NAME "altera-cvp" 59 + #define ALTERA_CVP_MGR_NAME "Altera CvP FPGA Manager" 60 + 61 + /* Optional CvP config error status check for debugging */ 62 + static bool altera_cvp_chkcfg; 63 + 64 + struct altera_cvp_conf { 65 + struct fpga_manager *mgr; 66 + struct pci_dev *pci_dev; 67 + void __iomem *map; 68 + void (*write_data)(struct altera_cvp_conf *, u32); 69 + char mgr_name[64]; 70 + u8 numclks; 71 + }; 72 + 73 + static enum fpga_mgr_states altera_cvp_state(struct fpga_manager *mgr) 74 + { 75 + struct altera_cvp_conf *conf = mgr->priv; 76 + u32 status; 77 + 78 + pci_read_config_dword(conf->pci_dev, VSE_CVP_STATUS, &status); 79 + 80 + if (status & VSE_CVP_STATUS_CFG_DONE) 81 + return FPGA_MGR_STATE_OPERATING; 82 + 83 + if (status & VSE_CVP_STATUS_CVP_EN) 84 + return FPGA_MGR_STATE_POWER_UP; 85 + 86 + return FPGA_MGR_STATE_UNKNOWN; 87 + } 88 + 89 + static void altera_cvp_write_data_iomem(struct altera_cvp_conf *conf, u32 val) 90 + { 91 + writel(val, conf->map); 92 + } 93 + 94 + static void altera_cvp_write_data_config(struct altera_cvp_conf *conf, u32 val) 95 + { 96 + pci_write_config_dword(conf->pci_dev, VSE_CVP_DATA, val); 97 + } 98 + 99 + /* switches between CvP clock and internal clock */ 100 + static void altera_cvp_dummy_write(struct altera_cvp_conf *conf) 101 + { 102 + unsigned int i; 103 + u32 val; 104 + 105 + /* set 1 CVP clock cycle for every CVP Data Register Write */ 106 + pci_read_config_dword(conf->pci_dev, VSE_CVP_MODE_CTRL, &val); 107 + val &= ~VSE_CVP_MODE_CTRL_NUMCLKS_MASK; 108 + val |= 1 << VSE_CVP_MODE_CTRL_NUMCLKS_OFF; 109 + pci_write_config_dword(conf->pci_dev, VSE_CVP_MODE_CTRL, val); 110 + 111 + for (i = 0; i < CVP_DUMMY_WR; i++) 112 + conf->write_data(conf, 0); /* dummy data, could be any value */ 113 + } 114 + 115 + static int altera_cvp_wait_status(struct altera_cvp_conf *conf, u32 status_mask, 116 + u32 status_val, int timeout_us) 117 + { 118 + unsigned int retries; 119 + u32 val; 120 + 121 + retries = timeout_us / 10; 122 + if (timeout_us % 10) 123 + retries++; 124 + 125 + do { 126 + pci_read_config_dword(conf->pci_dev, VSE_CVP_STATUS, &val); 127 + if ((val & status_mask) == status_val) 128 + return 0; 129 + 130 + /* use small usleep value to re-check and break early */ 131 + usleep_range(10, 11); 132 + } while (--retries); 133 + 134 + return -ETIMEDOUT; 135 + } 136 + 137 + static int altera_cvp_teardown(struct fpga_manager *mgr, 138 + struct fpga_image_info *info) 139 + { 140 + struct altera_cvp_conf *conf = mgr->priv; 141 + struct pci_dev *pdev = conf->pci_dev; 142 + int ret; 143 + u32 val; 144 + 145 + /* STEP 12 - reset START_XFER bit */ 146 + pci_read_config_dword(pdev, VSE_CVP_PROG_CTRL, &val); 147 + val &= ~VSE_CVP_PROG_CTRL_START_XFER; 148 + pci_write_config_dword(pdev, VSE_CVP_PROG_CTRL, val); 149 + 150 + /* STEP 13 - reset CVP_CONFIG bit */ 151 + val &= ~VSE_CVP_PROG_CTRL_CONFIG; 152 + pci_write_config_dword(pdev, VSE_CVP_PROG_CTRL, val); 153 + 154 + /* 155 + * STEP 14 156 + * - set CVP_NUMCLKS to 1 and then issue CVP_DUMMY_WR dummy 157 + * writes to the HIP 158 + */ 159 + altera_cvp_dummy_write(conf); /* from CVP clock to internal clock */ 160 + 161 + /* STEP 15 - poll CVP_CONFIG_READY bit for 0 with 10us timeout */ 162 + ret = altera_cvp_wait_status(conf, VSE_CVP_STATUS_CFG_RDY, 0, 10); 163 + if (ret) 164 + dev_err(&mgr->dev, "CFG_RDY == 0 timeout\n"); 165 + 166 + return ret; 167 + } 168 + 169 + static int altera_cvp_write_init(struct fpga_manager *mgr, 170 + struct fpga_image_info *info, 171 + const char *buf, size_t count) 172 + { 173 + struct altera_cvp_conf *conf = mgr->priv; 174 + struct pci_dev *pdev = conf->pci_dev; 175 + u32 iflags, val; 176 + int ret; 177 + 178 + iflags = info ? info->flags : 0; 179 + 180 + if (iflags & FPGA_MGR_PARTIAL_RECONFIG) { 181 + dev_err(&mgr->dev, "Partial reconfiguration not supported.\n"); 182 + return -EINVAL; 183 + } 184 + 185 + /* Determine allowed clock to data ratio */ 186 + if (iflags & FPGA_MGR_COMPRESSED_BITSTREAM) 187 + conf->numclks = 8; /* ratio for all compressed images */ 188 + else if (iflags & FPGA_MGR_ENCRYPTED_BITSTREAM) 189 + conf->numclks = 4; /* for uncompressed and encrypted images */ 190 + else 191 + conf->numclks = 1; /* for uncompressed and unencrypted images */ 192 + 193 + /* STEP 1 - read CVP status and check CVP_EN flag */ 194 + pci_read_config_dword(pdev, VSE_CVP_STATUS, &val); 195 + if (!(val & VSE_CVP_STATUS_CVP_EN)) { 196 + dev_err(&mgr->dev, "CVP mode off: 0x%04x\n", val); 197 + return -ENODEV; 198 + } 199 + 200 + if (val & VSE_CVP_STATUS_CFG_RDY) { 201 + dev_warn(&mgr->dev, "CvP already started, teardown first\n"); 202 + ret = altera_cvp_teardown(mgr, info); 203 + if (ret) 204 + return ret; 205 + } 206 + 207 + /* 208 + * STEP 2 209 + * - set HIP_CLK_SEL and CVP_MODE (must be set in the order mentioned) 210 + */ 211 + /* switch from fabric to PMA clock */ 212 + pci_read_config_dword(pdev, VSE_CVP_MODE_CTRL, &val); 213 + val |= VSE_CVP_MODE_CTRL_HIP_CLK_SEL; 214 + pci_write_config_dword(pdev, VSE_CVP_MODE_CTRL, val); 215 + 216 + /* set CVP mode */ 217 + pci_read_config_dword(pdev, VSE_CVP_MODE_CTRL, &val); 218 + val |= VSE_CVP_MODE_CTRL_CVP_MODE; 219 + pci_write_config_dword(pdev, VSE_CVP_MODE_CTRL, val); 220 + 221 + /* 222 + * STEP 3 223 + * - set CVP_NUMCLKS to 1 and issue CVP_DUMMY_WR dummy writes to the HIP 224 + */ 225 + altera_cvp_dummy_write(conf); 226 + 227 + /* STEP 4 - set CVP_CONFIG bit */ 228 + pci_read_config_dword(pdev, VSE_CVP_PROG_CTRL, &val); 229 + /* request control block to begin transfer using CVP */ 230 + val |= VSE_CVP_PROG_CTRL_CONFIG; 231 + pci_write_config_dword(pdev, VSE_CVP_PROG_CTRL, val); 232 + 233 + /* STEP 5 - poll CVP_CONFIG READY for 1 with 10us timeout */ 234 + ret = altera_cvp_wait_status(conf, VSE_CVP_STATUS_CFG_RDY, 235 + VSE_CVP_STATUS_CFG_RDY, 10); 236 + if (ret) { 237 + dev_warn(&mgr->dev, "CFG_RDY == 1 timeout\n"); 238 + return ret; 239 + } 240 + 241 + /* 242 + * STEP 6 243 + * - set CVP_NUMCLKS to 1 and issue CVP_DUMMY_WR dummy writes to the HIP 244 + */ 245 + altera_cvp_dummy_write(conf); 246 + 247 + /* STEP 7 - set START_XFER */ 248 + pci_read_config_dword(pdev, VSE_CVP_PROG_CTRL, &val); 249 + val |= VSE_CVP_PROG_CTRL_START_XFER; 250 + pci_write_config_dword(pdev, VSE_CVP_PROG_CTRL, val); 251 + 252 + /* STEP 8 - start transfer (set CVP_NUMCLKS for bitstream) */ 253 + pci_read_config_dword(pdev, VSE_CVP_MODE_CTRL, &val); 254 + val &= ~VSE_CVP_MODE_CTRL_NUMCLKS_MASK; 255 + val |= conf->numclks << VSE_CVP_MODE_CTRL_NUMCLKS_OFF; 256 + pci_write_config_dword(pdev, VSE_CVP_MODE_CTRL, val); 257 + 258 + return 0; 259 + } 260 + 261 + static inline int altera_cvp_chk_error(struct fpga_manager *mgr, size_t bytes) 262 + { 263 + struct altera_cvp_conf *conf = mgr->priv; 264 + u32 val; 265 + 266 + /* STEP 10 (optional) - check CVP_CONFIG_ERROR flag */ 267 + pci_read_config_dword(conf->pci_dev, VSE_CVP_STATUS, &val); 268 + if (val & VSE_CVP_STATUS_CFG_ERR) { 269 + dev_err(&mgr->dev, "CVP_CONFIG_ERROR after %zu bytes!\n", 270 + bytes); 271 + return -EPROTO; 272 + } 273 + return 0; 274 + } 275 + 276 + static int altera_cvp_write(struct fpga_manager *mgr, const char *buf, 277 + size_t count) 278 + { 279 + struct altera_cvp_conf *conf = mgr->priv; 280 + const u32 *data; 281 + size_t done, remaining; 282 + int status = 0; 283 + u32 mask; 284 + 285 + /* STEP 9 - write 32-bit data from RBF file to CVP data register */ 286 + data = (u32 *)buf; 287 + remaining = count; 288 + done = 0; 289 + 290 + while (remaining >= 4) { 291 + conf->write_data(conf, *data++); 292 + done += 4; 293 + remaining -= 4; 294 + 295 + /* 296 + * STEP 10 (optional) and STEP 11 297 + * - check error flag 298 + * - loop until data transfer completed 299 + * Config images can be huge (more than 40 MiB), so 300 + * only check after a new 4k data block has been written. 301 + * This reduces the number of checks and speeds up the 302 + * configuration process. 303 + */ 304 + if (altera_cvp_chkcfg && !(done % SZ_4K)) { 305 + status = altera_cvp_chk_error(mgr, done); 306 + if (status < 0) 307 + return status; 308 + } 309 + } 310 + 311 + /* write up to 3 trailing bytes, if any */ 312 + mask = BIT(remaining * 8) - 1; 313 + if (mask) 314 + conf->write_data(conf, *data & mask); 315 + 316 + if (altera_cvp_chkcfg) 317 + status = altera_cvp_chk_error(mgr, count); 318 + 319 + return status; 320 + } 321 + 322 + static int altera_cvp_write_complete(struct fpga_manager *mgr, 323 + struct fpga_image_info *info) 324 + { 325 + struct altera_cvp_conf *conf = mgr->priv; 326 + struct pci_dev *pdev = conf->pci_dev; 327 + int ret; 328 + u32 mask; 329 + u32 val; 330 + 331 + ret = altera_cvp_teardown(mgr, info); 332 + if (ret) 333 + return ret; 334 + 335 + /* STEP 16 - check CVP_CONFIG_ERROR_LATCHED bit */ 336 + pci_read_config_dword(pdev, VSE_UNCOR_ERR_STATUS, &val); 337 + if (val & VSE_UNCOR_ERR_CVP_CFG_ERR) { 338 + dev_err(&mgr->dev, "detected CVP_CONFIG_ERROR_LATCHED!\n"); 339 + return -EPROTO; 340 + } 341 + 342 + /* STEP 17 - reset CVP_MODE and HIP_CLK_SEL bit */ 343 + pci_read_config_dword(pdev, VSE_CVP_MODE_CTRL, &val); 344 + val &= ~VSE_CVP_MODE_CTRL_HIP_CLK_SEL; 345 + val &= ~VSE_CVP_MODE_CTRL_CVP_MODE; 346 + pci_write_config_dword(pdev, VSE_CVP_MODE_CTRL, val); 347 + 348 + /* STEP 18 - poll PLD_CLK_IN_USE and USER_MODE bits */ 349 + mask = VSE_CVP_STATUS_PLD_CLK_IN_USE | VSE_CVP_STATUS_USERMODE; 350 + ret = altera_cvp_wait_status(conf, mask, mask, TIMEOUT_US); 351 + if (ret) 352 + dev_err(&mgr->dev, "PLD_CLK_IN_USE|USERMODE timeout\n"); 353 + 354 + return ret; 355 + } 356 + 357 + static const struct fpga_manager_ops altera_cvp_ops = { 358 + .state = altera_cvp_state, 359 + .write_init = altera_cvp_write_init, 360 + .write = altera_cvp_write, 361 + .write_complete = altera_cvp_write_complete, 362 + }; 363 + 364 + static ssize_t show_chkcfg(struct device_driver *dev, char *buf) 365 + { 366 + return snprintf(buf, 3, "%d\n", altera_cvp_chkcfg); 367 + } 368 + 369 + static ssize_t store_chkcfg(struct device_driver *drv, const char *buf, 370 + size_t count) 371 + { 372 + int ret; 373 + 374 + ret = kstrtobool(buf, &altera_cvp_chkcfg); 375 + if (ret) 376 + return ret; 377 + 378 + return count; 379 + } 380 + 381 + static DRIVER_ATTR(chkcfg, 0600, show_chkcfg, store_chkcfg); 382 + 383 + static int altera_cvp_probe(struct pci_dev *pdev, 384 + const struct pci_device_id *dev_id); 385 + static void altera_cvp_remove(struct pci_dev *pdev); 386 + 387 + #define PCI_VENDOR_ID_ALTERA 0x1172 388 + 389 + static struct pci_device_id altera_cvp_id_tbl[] = { 390 + { PCI_VDEVICE(ALTERA, PCI_ANY_ID) }, 391 + { } 392 + }; 393 + MODULE_DEVICE_TABLE(pci, altera_cvp_id_tbl); 394 + 395 + static struct pci_driver altera_cvp_driver = { 396 + .name = DRV_NAME, 397 + .id_table = altera_cvp_id_tbl, 398 + .probe = altera_cvp_probe, 399 + .remove = altera_cvp_remove, 400 + }; 401 + 402 + static int altera_cvp_probe(struct pci_dev *pdev, 403 + const struct pci_device_id *dev_id) 404 + { 405 + struct altera_cvp_conf *conf; 406 + u16 cmd, val; 407 + int ret; 408 + 409 + /* 410 + * First check if this is the expected FPGA device. PCI config 411 + * space access works without enabling the PCI device, memory 412 + * space access is enabled further down. 413 + */ 414 + pci_read_config_word(pdev, VSE_PCIE_EXT_CAP_ID, &val); 415 + if (val != VSE_PCIE_EXT_CAP_ID_VAL) { 416 + dev_err(&pdev->dev, "Wrong EXT_CAP_ID value 0x%x\n", val); 417 + return -ENODEV; 418 + } 419 + 420 + conf = devm_kzalloc(&pdev->dev, sizeof(*conf), GFP_KERNEL); 421 + if (!conf) 422 + return -ENOMEM; 423 + 424 + /* 425 + * Enable memory BAR access. We cannot use pci_enable_device() here 426 + * because it will make the driver unusable with FPGA devices that 427 + * have additional big IOMEM resources (e.g. 4GiB BARs) on 32-bit 428 + * platform. Such BARs will not have an assigned address range and 429 + * pci_enable_device() will fail, complaining about not claimed BAR, 430 + * even if the concerned BAR is not needed for FPGA configuration 431 + * at all. Thus, enable the device via PCI config space command. 432 + */ 433 + pci_read_config_word(pdev, PCI_COMMAND, &cmd); 434 + if (!(cmd & PCI_COMMAND_MEMORY)) { 435 + cmd |= PCI_COMMAND_MEMORY; 436 + pci_write_config_word(pdev, PCI_COMMAND, cmd); 437 + } 438 + 439 + ret = pci_request_region(pdev, CVP_BAR, "CVP"); 440 + if (ret) { 441 + dev_err(&pdev->dev, "Requesting CVP BAR region failed\n"); 442 + goto err_disable; 443 + } 444 + 445 + conf->pci_dev = pdev; 446 + conf->write_data = altera_cvp_write_data_iomem; 447 + 448 + conf->map = pci_iomap(pdev, CVP_BAR, 0); 449 + if (!conf->map) { 450 + dev_warn(&pdev->dev, "Mapping CVP BAR failed\n"); 451 + conf->write_data = altera_cvp_write_data_config; 452 + } 453 + 454 + snprintf(conf->mgr_name, sizeof(conf->mgr_name), "%s @%s", 455 + ALTERA_CVP_MGR_NAME, pci_name(pdev)); 456 + 457 + ret = fpga_mgr_register(&pdev->dev, conf->mgr_name, 458 + &altera_cvp_ops, conf); 459 + if (ret) 460 + goto err_unmap; 461 + 462 + ret = driver_create_file(&altera_cvp_driver.driver, 463 + &driver_attr_chkcfg); 464 + if (ret) { 465 + dev_err(&pdev->dev, "Can't create sysfs chkcfg file\n"); 466 + fpga_mgr_unregister(&pdev->dev); 467 + goto err_unmap; 468 + } 469 + 470 + return 0; 471 + 472 + err_unmap: 473 + pci_iounmap(pdev, conf->map); 474 + pci_release_region(pdev, CVP_BAR); 475 + err_disable: 476 + cmd &= ~PCI_COMMAND_MEMORY; 477 + pci_write_config_word(pdev, PCI_COMMAND, cmd); 478 + return ret; 479 + } 480 + 481 + static void altera_cvp_remove(struct pci_dev *pdev) 482 + { 483 + struct fpga_manager *mgr = pci_get_drvdata(pdev); 484 + struct altera_cvp_conf *conf = mgr->priv; 485 + u16 cmd; 486 + 487 + driver_remove_file(&altera_cvp_driver.driver, &driver_attr_chkcfg); 488 + fpga_mgr_unregister(&pdev->dev); 489 + pci_iounmap(pdev, conf->map); 490 + pci_release_region(pdev, CVP_BAR); 491 + pci_read_config_word(pdev, PCI_COMMAND, &cmd); 492 + cmd &= ~PCI_COMMAND_MEMORY; 493 + pci_write_config_word(pdev, PCI_COMMAND, cmd); 494 + } 495 + 496 + module_pci_driver(altera_cvp_driver); 497 + 498 + MODULE_LICENSE("GPL v2"); 499 + MODULE_AUTHOR("Anatolij Gustschin <agust@denx.de>"); 500 + MODULE_DESCRIPTION("Module to load Altera FPGA over CvP");