crystalhd_lnx.c revision b1f2ac07636aadee5cb077fc7e830908b00fcaae
1/*************************************************************************** 2 BCM70010 Linux driver 3 Copyright (c) 2005-2009, Broadcom Corporation. 4 5 This driver is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation, version 2 of the License. 8 9 This driver is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this driver. If not, see <http://www.gnu.org/licenses/>. 16***************************************************************************/ 17 18#include <linux/version.h> 19#include <linux/smp_lock.h> 20#include <linux/slab.h> 21 22#include "crystalhd_lnx.h" 23 24static struct class *crystalhd_class; 25 26static struct crystalhd_adp *g_adp_info; 27 28static irqreturn_t chd_dec_isr(int irq, void *arg) 29{ 30 struct crystalhd_adp *adp = (struct crystalhd_adp *) arg; 31 int rc = 0; 32 if (adp) 33 rc = crystalhd_cmd_interrupt(&adp->cmds); 34 35 return IRQ_RETVAL(rc); 36} 37 38static int chd_dec_enable_int(struct crystalhd_adp *adp) 39{ 40 int rc = 0; 41 42 if (!adp || !adp->pdev) { 43 BCMLOG_ERR("Invalid arg!!\n"); 44 return -EINVAL; 45 } 46 47 if (adp->pdev->msi_enabled) 48 adp->msi = 1; 49 else 50 adp->msi = pci_enable_msi(adp->pdev); 51 52 rc = request_irq(adp->pdev->irq, chd_dec_isr, IRQF_SHARED, 53 adp->name, (void *)adp); 54 if (rc) { 55 BCMLOG_ERR("Interrupt request failed..\n"); 56 pci_disable_msi(adp->pdev); 57 } 58 59 return rc; 60} 61 62static int chd_dec_disable_int(struct crystalhd_adp *adp) 63{ 64 if (!adp || !adp->pdev) { 65 BCMLOG_ERR("Invalid arg!!\n"); 66 return -EINVAL; 67 } 68 69 free_irq(adp->pdev->irq, adp); 70 71 if (adp->msi) 72 pci_disable_msi(adp->pdev); 73 74 return 0; 75} 76 77crystalhd_ioctl_data *chd_dec_alloc_iodata(struct crystalhd_adp *adp, bool isr) 78{ 79 unsigned long flags = 0; 80 crystalhd_ioctl_data *temp; 81 82 if (!adp) 83 return NULL; 84 85 spin_lock_irqsave(&adp->lock, flags); 86 87 temp = adp->idata_free_head; 88 if (temp) { 89 adp->idata_free_head = adp->idata_free_head->next; 90 memset(temp, 0, sizeof(*temp)); 91 } 92 93 spin_unlock_irqrestore(&adp->lock, flags); 94 return temp; 95} 96 97void chd_dec_free_iodata(struct crystalhd_adp *adp, crystalhd_ioctl_data *iodata, 98 bool isr) 99{ 100 unsigned long flags = 0; 101 102 if (!adp || !iodata) 103 return; 104 105 spin_lock_irqsave(&adp->lock, flags); 106 iodata->next = adp->idata_free_head; 107 adp->idata_free_head = iodata; 108 spin_unlock_irqrestore(&adp->lock, flags); 109} 110 111static inline int crystalhd_user_data(unsigned long ud, void *dr, int size, int set) 112{ 113 int rc; 114 115 if (!ud || !dr) { 116 BCMLOG_ERR("Invalid arg\n"); 117 return -EINVAL; 118 } 119 120 if (set) 121 rc = copy_to_user((void *)ud, dr, size); 122 else 123 rc = copy_from_user(dr, (void *)ud, size); 124 125 if (rc) { 126 BCMLOG_ERR("Invalid args for command\n"); 127 rc = -EFAULT; 128 } 129 130 return rc; 131} 132 133static int chd_dec_fetch_cdata(struct crystalhd_adp *adp, crystalhd_ioctl_data *io, 134 uint32_t m_sz, unsigned long ua) 135{ 136 unsigned long ua_off; 137 int rc = 0; 138 139 if (!adp || !io || !ua || !m_sz) { 140 BCMLOG_ERR("Invalid Arg!!\n"); 141 return -EINVAL; 142 } 143 144 io->add_cdata = vmalloc(m_sz); 145 if (!io->add_cdata) { 146 BCMLOG_ERR("kalloc fail for sz:%x\n", m_sz); 147 return -ENOMEM; 148 } 149 150 io->add_cdata_sz = m_sz; 151 ua_off = ua + sizeof(io->udata); 152 rc = crystalhd_user_data(ua_off, io->add_cdata, io->add_cdata_sz, 0); 153 if (rc) { 154 BCMLOG_ERR("failed to pull add_cdata sz:%x ua_off:%x\n", 155 io->add_cdata_sz, (unsigned int)ua_off); 156 if (io->add_cdata) { 157 kfree(io->add_cdata); 158 io->add_cdata = NULL; 159 } 160 return -ENODATA; 161 } 162 163 return rc; 164} 165 166static int chd_dec_release_cdata(struct crystalhd_adp *adp, 167 crystalhd_ioctl_data *io, unsigned long ua) 168{ 169 unsigned long ua_off; 170 int rc; 171 172 if (!adp || !io || !ua) { 173 BCMLOG_ERR("Invalid Arg!!\n"); 174 return -EINVAL; 175 } 176 177 if (io->cmd != BCM_IOC_FW_DOWNLOAD) { 178 ua_off = ua + sizeof(io->udata); 179 rc = crystalhd_user_data(ua_off, io->add_cdata, 180 io->add_cdata_sz, 1); 181 if (rc) { 182 BCMLOG_ERR("failed to push add_cdata sz:%x ua_off:%x\n", 183 io->add_cdata_sz, (unsigned int)ua_off); 184 return -ENODATA; 185 } 186 } 187 188 if (io->add_cdata) { 189 vfree(io->add_cdata); 190 io->add_cdata = NULL; 191 } 192 193 return 0; 194} 195 196static int chd_dec_proc_user_data(struct crystalhd_adp *adp, 197 crystalhd_ioctl_data *io, 198 unsigned long ua, int set) 199{ 200 int rc; 201 uint32_t m_sz = 0; 202 203 if (!adp || !io || !ua) { 204 BCMLOG_ERR("Invalid Arg!!\n"); 205 return -EINVAL; 206 } 207 208 rc = crystalhd_user_data(ua, &io->udata, sizeof(io->udata), set); 209 if (rc) { 210 BCMLOG_ERR("failed to %s iodata\n", (set ? "set" : "get")); 211 return rc; 212 } 213 214 switch (io->cmd) { 215 case BCM_IOC_MEM_RD: 216 case BCM_IOC_MEM_WR: 217 case BCM_IOC_FW_DOWNLOAD: 218 m_sz = io->udata.u.devMem.NumDwords * 4; 219 if (set) 220 rc = chd_dec_release_cdata(adp, io, ua); 221 else 222 rc = chd_dec_fetch_cdata(adp, io, m_sz, ua); 223 break; 224 default: 225 break; 226 } 227 228 return rc; 229} 230 231static int chd_dec_api_cmd(struct crystalhd_adp *adp, unsigned long ua, 232 uint32_t uid, uint32_t cmd, crystalhd_cmd_proc func) 233{ 234 int rc; 235 crystalhd_ioctl_data *temp; 236 BC_STATUS sts = BC_STS_SUCCESS; 237 238 temp = chd_dec_alloc_iodata(adp, 0); 239 if (!temp) { 240 BCMLOG_ERR("Failed to get iodata..\n"); 241 return -EINVAL; 242 } 243 244 temp->u_id = uid; 245 temp->cmd = cmd; 246 247 rc = chd_dec_proc_user_data(adp, temp, ua, 0); 248 if (!rc) { 249 sts = func(&adp->cmds, temp); 250 if (sts == BC_STS_PENDING) 251 sts = BC_STS_NOT_IMPL; 252 temp->udata.RetSts = sts; 253 rc = chd_dec_proc_user_data(adp, temp, ua, 1); 254 } 255 256 if (temp) { 257 chd_dec_free_iodata(adp, temp, 0); 258 temp = NULL; 259 } 260 261 return rc; 262} 263 264/* API interfaces */ 265static long chd_dec_ioctl(struct file *fd, unsigned int cmd, unsigned long ua) 266{ 267 struct crystalhd_adp *adp = chd_get_adp(); 268 crystalhd_cmd_proc cproc; 269 struct crystalhd_user *uc; 270 int ret; 271 272 if (!adp || !fd) { 273 BCMLOG_ERR("Invalid adp\n"); 274 return -EINVAL; 275 } 276 277 uc = (struct crystalhd_user *)fd->private_data; 278 if (!uc) { 279 BCMLOG_ERR("Failed to get uc\n"); 280 return -ENODATA; 281 } 282 283 lock_kernel(); 284 cproc = crystalhd_get_cmd_proc(&adp->cmds, cmd, uc); 285 if (!cproc) { 286 BCMLOG_ERR("Unhandled command: %d\n", cmd); 287 unlock_kernel(); 288 return -EINVAL; 289 } 290 291 ret = chd_dec_api_cmd(adp, ua, uc->uid, cmd, cproc); 292 unlock_kernel(); 293 return ret; 294} 295 296static int chd_dec_open(struct inode *in, struct file *fd) 297{ 298 struct crystalhd_adp *adp = chd_get_adp(); 299 int rc = 0; 300 BC_STATUS sts = BC_STS_SUCCESS; 301 struct crystalhd_user *uc = NULL; 302 303 BCMLOG_ENTER; 304 if (!adp) { 305 BCMLOG_ERR("Invalid adp\n"); 306 return -EINVAL; 307 } 308 309 if (adp->cfg_users >= BC_LINK_MAX_OPENS) { 310 BCMLOG(BCMLOG_INFO, "Already in use.%d\n", adp->cfg_users); 311 return -EBUSY; 312 } 313 314 sts = crystalhd_user_open(&adp->cmds, &uc); 315 if (sts != BC_STS_SUCCESS) { 316 BCMLOG_ERR("cmd_user_open - %d\n", sts); 317 rc = -EBUSY; 318 } 319 320 adp->cfg_users++; 321 322 fd->private_data = uc; 323 324 return rc; 325} 326 327static int chd_dec_close(struct inode *in, struct file *fd) 328{ 329 struct crystalhd_adp *adp = chd_get_adp(); 330 struct crystalhd_user *uc; 331 332 BCMLOG_ENTER; 333 if (!adp) { 334 BCMLOG_ERR("Invalid adp\n"); 335 return -EINVAL; 336 } 337 338 uc = (struct crystalhd_user *)fd->private_data; 339 if (!uc) { 340 BCMLOG_ERR("Failed to get uc\n"); 341 return -ENODATA; 342 } 343 344 crystalhd_user_close(&adp->cmds, uc); 345 346 adp->cfg_users--; 347 348 return 0; 349} 350 351static const struct file_operations chd_dec_fops = { 352 .owner = THIS_MODULE, 353 .unlocked_ioctl = chd_dec_ioctl, 354 .open = chd_dec_open, 355 .release = chd_dec_close, 356}; 357 358static int __devinit chd_dec_init_chdev(struct crystalhd_adp *adp) 359{ 360 crystalhd_ioctl_data *temp; 361 struct device *dev; 362 int rc = -ENODEV, i = 0; 363 364 if (!adp) 365 goto fail; 366 367 adp->chd_dec_major = register_chrdev(0, CRYSTALHD_API_NAME, 368 &chd_dec_fops); 369 if (adp->chd_dec_major < 0) { 370 BCMLOG_ERR("Failed to create config dev\n"); 371 rc = adp->chd_dec_major; 372 goto fail; 373 } 374 375 /* register crystalhd class */ 376 crystalhd_class = class_create(THIS_MODULE, "crystalhd"); 377 if (IS_ERR(crystalhd_class)) { 378 BCMLOG_ERR("failed to create class\n"); 379 goto fail; 380 } 381 382 dev = device_create(crystalhd_class, NULL, MKDEV(adp->chd_dec_major, 0), 383 NULL, "crystalhd"); 384 if (IS_ERR(dev)) { 385 BCMLOG_ERR("failed to create device\n"); 386 goto device_create_fail; 387 } 388 389 rc = crystalhd_create_elem_pool(adp, BC_LINK_ELEM_POOL_SZ); 390 if (rc) { 391 BCMLOG_ERR("failed to create device\n"); 392 goto elem_pool_fail; 393 } 394 395 /* Allocate general purpose ioctl pool. */ 396 for (i = 0; i < CHD_IODATA_POOL_SZ; i++) { 397 /* FIXME: jarod: why atomic? */ 398 temp = kzalloc(sizeof(crystalhd_ioctl_data), GFP_ATOMIC); 399 if (!temp) { 400 BCMLOG_ERR("ioctl data pool kzalloc failed\n"); 401 rc = -ENOMEM; 402 goto kzalloc_fail; 403 } 404 /* Add to global pool.. */ 405 chd_dec_free_iodata(adp, temp, 0); 406 } 407 408 return 0; 409 410kzalloc_fail: 411 crystalhd_delete_elem_pool(adp); 412elem_pool_fail: 413 device_destroy(crystalhd_class, MKDEV(adp->chd_dec_major, 0)); 414device_create_fail: 415 class_destroy(crystalhd_class); 416fail: 417 return rc; 418} 419 420static void __devexit chd_dec_release_chdev(struct crystalhd_adp *adp) 421{ 422 crystalhd_ioctl_data *temp = NULL; 423 if (!adp) 424 return; 425 426 if (adp->chd_dec_major > 0) { 427 /* unregister crystalhd class */ 428 device_destroy(crystalhd_class, MKDEV(adp->chd_dec_major, 0)); 429 unregister_chrdev(adp->chd_dec_major, CRYSTALHD_API_NAME); 430 BCMLOG(BCMLOG_INFO, "released api device - %d\n", 431 adp->chd_dec_major); 432 class_destroy(crystalhd_class); 433 } 434 adp->chd_dec_major = 0; 435 436 /* Clear iodata pool.. */ 437 do { 438 temp = chd_dec_alloc_iodata(adp, 0); 439 if (temp) 440 kfree(temp); 441 } while (temp); 442 443 crystalhd_delete_elem_pool(adp); 444} 445 446static int __devinit chd_pci_reserve_mem(struct crystalhd_adp *pinfo) 447{ 448 int rc; 449 unsigned long bar2 = pci_resource_start(pinfo->pdev, 2); 450 uint32_t mem_len = pci_resource_len(pinfo->pdev, 2); 451 unsigned long bar0 = pci_resource_start(pinfo->pdev, 0); 452 uint32_t i2o_len = pci_resource_len(pinfo->pdev, 0); 453 454 BCMLOG(BCMLOG_SSTEP, "bar2:0x%lx-0x%08x bar0:0x%lx-0x%08x\n", 455 bar2, mem_len, bar0, i2o_len); 456 457 rc = check_mem_region(bar2, mem_len); 458 if (rc) { 459 BCMLOG_ERR("No valid mem region...\n"); 460 return -ENOMEM; 461 } 462 463 pinfo->addr = ioremap_nocache(bar2, mem_len); 464 if (!pinfo->addr) { 465 BCMLOG_ERR("Failed to remap mem region...\n"); 466 return -ENOMEM; 467 } 468 469 pinfo->pci_mem_start = bar2; 470 pinfo->pci_mem_len = mem_len; 471 472 rc = check_mem_region(bar0, i2o_len); 473 if (rc) { 474 BCMLOG_ERR("No valid mem region...\n"); 475 return -ENOMEM; 476 } 477 478 pinfo->i2o_addr = ioremap_nocache(bar0, i2o_len); 479 if (!pinfo->i2o_addr) { 480 BCMLOG_ERR("Failed to remap mem region...\n"); 481 return -ENOMEM; 482 } 483 484 pinfo->pci_i2o_start = bar0; 485 pinfo->pci_i2o_len = i2o_len; 486 487 rc = pci_request_regions(pinfo->pdev, pinfo->name); 488 if (rc < 0) { 489 BCMLOG_ERR("Region request failed: %d\n", rc); 490 return rc; 491 } 492 493 BCMLOG(BCMLOG_SSTEP, "Mapped addr:0x%08lx i2o_addr:0x%08lx\n", 494 (unsigned long)pinfo->addr, (unsigned long)pinfo->i2o_addr); 495 496 return 0; 497} 498 499static void __devexit chd_pci_release_mem(struct crystalhd_adp *pinfo) 500{ 501 if (!pinfo) 502 return; 503 504 if (pinfo->addr) 505 iounmap(pinfo->addr); 506 507 if (pinfo->i2o_addr) 508 iounmap(pinfo->i2o_addr); 509 510 pci_release_regions(pinfo->pdev); 511} 512 513 514static void __devexit chd_dec_pci_remove(struct pci_dev *pdev) 515{ 516 struct crystalhd_adp *pinfo; 517 BC_STATUS sts = BC_STS_SUCCESS; 518 519 BCMLOG_ENTER; 520 521 pinfo = (struct crystalhd_adp *) pci_get_drvdata(pdev); 522 if (!pinfo) { 523 BCMLOG_ERR("could not get adp\n"); 524 return; 525 } 526 527 sts = crystalhd_delete_cmd_context(&pinfo->cmds); 528 if (sts != BC_STS_SUCCESS) 529 BCMLOG_ERR("cmd delete :%d\n", sts); 530 531 chd_dec_release_chdev(pinfo); 532 533 chd_dec_disable_int(pinfo); 534 535 chd_pci_release_mem(pinfo); 536 pci_disable_device(pinfo->pdev); 537 538 kfree(pinfo); 539 g_adp_info = NULL; 540} 541 542static int __devinit chd_dec_pci_probe(struct pci_dev *pdev, 543 const struct pci_device_id *entry) 544{ 545 struct crystalhd_adp *pinfo; 546 int rc; 547 BC_STATUS sts = BC_STS_SUCCESS; 548 549 BCMLOG(BCMLOG_DBG, "PCI_INFO: Vendor:0x%04x Device:0x%04x " 550 "s_vendor:0x%04x s_device: 0x%04x\n", 551 pdev->vendor, pdev->device, pdev->subsystem_vendor, 552 pdev->subsystem_device); 553 554 /* FIXME: jarod: why atomic? */ 555 pinfo = kzalloc(sizeof(struct crystalhd_adp), GFP_ATOMIC); 556 if (!pinfo) { 557 BCMLOG_ERR("Failed to allocate memory\n"); 558 return -ENOMEM; 559 } 560 561 pinfo->pdev = pdev; 562 563 rc = pci_enable_device(pdev); 564 if (rc) { 565 BCMLOG_ERR("Failed to enable PCI device\n"); 566 return rc; 567 } 568 569 snprintf(pinfo->name, 31, "crystalhd_pci_e:%d:%d:%d", 570 pdev->bus->number, PCI_SLOT(pdev->devfn), 571 PCI_FUNC(pdev->devfn)); 572 573 rc = chd_pci_reserve_mem(pinfo); 574 if (rc) { 575 BCMLOG_ERR("Failed to setup memory regions.\n"); 576 return -ENOMEM; 577 } 578 579 pinfo->present = 1; 580 pinfo->drv_data = entry->driver_data; 581 582 /* Setup adapter level lock.. */ 583 spin_lock_init(&pinfo->lock); 584 585 /* setup api stuff.. */ 586 chd_dec_init_chdev(pinfo); 587 rc = chd_dec_enable_int(pinfo); 588 if (rc) { 589 BCMLOG_ERR("_enable_int err:%d\n", rc); 590 pci_disable_device(pdev); 591 return -ENODEV; 592 } 593 594 /* Set dma mask... */ 595 if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { 596 pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); 597 pinfo->dmabits = 64; 598 } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { 599 pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); 600 pinfo->dmabits = 32; 601 } else { 602 BCMLOG_ERR("Unabled to setup DMA %d\n", rc); 603 pci_disable_device(pdev); 604 return -ENODEV; 605 } 606 607 sts = crystalhd_setup_cmd_context(&pinfo->cmds, pinfo); 608 if (sts != BC_STS_SUCCESS) { 609 BCMLOG_ERR("cmd setup :%d\n", sts); 610 pci_disable_device(pdev); 611 return -ENODEV; 612 } 613 614 pci_set_master(pdev); 615 616 pci_set_drvdata(pdev, pinfo); 617 618 g_adp_info = pinfo; 619 620 return 0; 621} 622 623#ifdef CONFIG_PM 624int chd_dec_pci_suspend(struct pci_dev *pdev, pm_message_t state) 625{ 626 struct crystalhd_adp *adp; 627 crystalhd_ioctl_data *temp; 628 BC_STATUS sts = BC_STS_SUCCESS; 629 630 adp = (struct crystalhd_adp *)pci_get_drvdata(pdev); 631 if (!adp) { 632 BCMLOG_ERR("could not get adp\n"); 633 return -ENODEV; 634 } 635 636 temp = chd_dec_alloc_iodata(adp, false); 637 if (!temp) { 638 BCMLOG_ERR("could not get ioctl data\n"); 639 return -ENODEV; 640 } 641 642 sts = crystalhd_suspend(&adp->cmds, temp); 643 if (sts != BC_STS_SUCCESS) { 644 BCMLOG_ERR("BCM70012 Suspend %d\n", sts); 645 return -ENODEV; 646 } 647 648 chd_dec_free_iodata(adp, temp, false); 649 chd_dec_disable_int(adp); 650 pci_save_state(pdev); 651 652 /* Disable IO/bus master/irq router */ 653 pci_disable_device(pdev); 654 pci_set_power_state(pdev, pci_choose_state(pdev, state)); 655 return 0; 656} 657 658int chd_dec_pci_resume(struct pci_dev *pdev) 659{ 660 struct crystalhd_adp *adp; 661 BC_STATUS sts = BC_STS_SUCCESS; 662 int rc; 663 664 adp = (struct crystalhd_adp *)pci_get_drvdata(pdev); 665 if (!adp) { 666 BCMLOG_ERR("could not get adp\n"); 667 return -ENODEV; 668 } 669 670 pci_set_power_state(pdev, PCI_D0); 671 pci_restore_state(pdev); 672 673 /* device's irq possibly is changed, driver should take care */ 674 if (pci_enable_device(pdev)) { 675 BCMLOG_ERR("Failed to enable PCI device\n"); 676 return 1; 677 } 678 679 pci_set_master(pdev); 680 681 rc = chd_dec_enable_int(adp); 682 if (rc) { 683 BCMLOG_ERR("_enable_int err:%d\n", rc); 684 pci_disable_device(pdev); 685 return -ENODEV; 686 } 687 688 sts = crystalhd_resume(&adp->cmds); 689 if (sts != BC_STS_SUCCESS) { 690 BCMLOG_ERR("BCM70012 Resume %d\n", sts); 691 pci_disable_device(pdev); 692 return -ENODEV; 693 } 694 695 return 0; 696} 697#endif 698 699static DEFINE_PCI_DEVICE_TABLE(chd_dec_pci_id_table) = { 700 { PCI_VDEVICE(BROADCOM, 0x1612), 8 }, 701 { 0, }, 702}; 703MODULE_DEVICE_TABLE(pci, chd_dec_pci_id_table); 704 705static struct pci_driver bc_chd_70012_driver = { 706 .name = "Broadcom 70012 Decoder", 707 .probe = chd_dec_pci_probe, 708 .remove = __devexit_p(chd_dec_pci_remove), 709 .id_table = chd_dec_pci_id_table, 710#ifdef CONFIG_PM 711 .suspend = chd_dec_pci_suspend, 712 .resume = chd_dec_pci_resume 713#endif 714}; 715 716void chd_set_log_level(struct crystalhd_adp *adp, char *arg) 717{ 718 if ((!arg) || (strlen(arg) < 3)) 719 g_linklog_level = BCMLOG_ERROR | BCMLOG_DATA; 720 else if (!strncmp(arg, "sstep", 5)) 721 g_linklog_level = BCMLOG_INFO | BCMLOG_DATA | BCMLOG_DBG | 722 BCMLOG_SSTEP | BCMLOG_ERROR; 723 else if (!strncmp(arg, "info", 4)) 724 g_linklog_level = BCMLOG_ERROR | BCMLOG_DATA | BCMLOG_INFO; 725 else if (!strncmp(arg, "debug", 5)) 726 g_linklog_level = BCMLOG_ERROR | BCMLOG_DATA | BCMLOG_INFO | 727 BCMLOG_DBG; 728 else if (!strncmp(arg, "pball", 5)) 729 g_linklog_level = 0xFFFFFFFF & ~(BCMLOG_SPINLOCK); 730 else if (!strncmp(arg, "silent", 6)) 731 g_linklog_level = 0; 732 else 733 g_linklog_level = 0; 734} 735 736struct crystalhd_adp *chd_get_adp(void) 737{ 738 return g_adp_info; 739} 740 741static int __init chd_dec_module_init(void) 742{ 743 int rc; 744 745 chd_set_log_level(NULL, "debug"); 746 BCMLOG(BCMLOG_DATA, "Loading crystalhd %d.%d.%d\n", 747 crystalhd_kmod_major, crystalhd_kmod_minor, crystalhd_kmod_rev); 748 749 rc = pci_register_driver(&bc_chd_70012_driver); 750 751 if (rc < 0) 752 BCMLOG_ERR("Could not find any devices. err:%d\n", rc); 753 754 return rc; 755} 756module_init(chd_dec_module_init); 757 758static void __exit chd_dec_module_cleanup(void) 759{ 760 BCMLOG(BCMLOG_DATA, "unloading crystalhd %d.%d.%d\n", 761 crystalhd_kmod_major, crystalhd_kmod_minor, crystalhd_kmod_rev); 762 763 pci_unregister_driver(&bc_chd_70012_driver); 764} 765module_exit(chd_dec_module_cleanup); 766 767MODULE_AUTHOR("Naren Sankar <nsankar@broadcom.com>"); 768MODULE_AUTHOR("Prasad Bolisetty <prasadb@broadcom.com>"); 769MODULE_DESCRIPTION(CRYSTAL_HD_NAME); 770MODULE_LICENSE("GPL"); 771MODULE_ALIAS("bcm70012"); 772