crystalhd_lnx.c revision b4c77848600906055c66dd32074d23858e6e200d
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/mutex.h> 19#include <linux/slab.h> 20 21#include "crystalhd_lnx.h" 22 23static DEFINE_MUTEX(chd_dec_mutex); 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 77struct crystalhd_ioctl_data *chd_dec_alloc_iodata(struct crystalhd_adp *adp, bool isr) 78{ 79 unsigned long flags = 0; 80 struct 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, struct 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, struct 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 kfree(io->add_cdata); 157 io->add_cdata = NULL; 158 return -ENODATA; 159 } 160 161 return rc; 162} 163 164static int chd_dec_release_cdata(struct crystalhd_adp *adp, 165 struct crystalhd_ioctl_data *io, unsigned long ua) 166{ 167 unsigned long ua_off; 168 int rc; 169 170 if (!adp || !io || !ua) { 171 BCMLOG_ERR("Invalid Arg!!\n"); 172 return -EINVAL; 173 } 174 175 if (io->cmd != BCM_IOC_FW_DOWNLOAD) { 176 ua_off = ua + sizeof(io->udata); 177 rc = crystalhd_user_data(ua_off, io->add_cdata, 178 io->add_cdata_sz, 1); 179 if (rc) { 180 BCMLOG_ERR("failed to push add_cdata sz:%x ua_off:%x\n", 181 io->add_cdata_sz, (unsigned int)ua_off); 182 return -ENODATA; 183 } 184 } 185 186 if (io->add_cdata) { 187 vfree(io->add_cdata); 188 io->add_cdata = NULL; 189 } 190 191 return 0; 192} 193 194static int chd_dec_proc_user_data(struct crystalhd_adp *adp, 195 struct crystalhd_ioctl_data *io, 196 unsigned long ua, int set) 197{ 198 int rc; 199 uint32_t m_sz = 0; 200 201 if (!adp || !io || !ua) { 202 BCMLOG_ERR("Invalid Arg!!\n"); 203 return -EINVAL; 204 } 205 206 rc = crystalhd_user_data(ua, &io->udata, sizeof(io->udata), set); 207 if (rc) { 208 BCMLOG_ERR("failed to %s iodata\n", (set ? "set" : "get")); 209 return rc; 210 } 211 212 switch (io->cmd) { 213 case BCM_IOC_MEM_RD: 214 case BCM_IOC_MEM_WR: 215 case BCM_IOC_FW_DOWNLOAD: 216 m_sz = io->udata.u.devMem.NumDwords * 4; 217 if (set) 218 rc = chd_dec_release_cdata(adp, io, ua); 219 else 220 rc = chd_dec_fetch_cdata(adp, io, m_sz, ua); 221 break; 222 default: 223 break; 224 } 225 226 return rc; 227} 228 229static int chd_dec_api_cmd(struct crystalhd_adp *adp, unsigned long ua, 230 uint32_t uid, uint32_t cmd, crystalhd_cmd_proc func) 231{ 232 int rc; 233 struct crystalhd_ioctl_data *temp; 234 enum BC_STATUS sts = BC_STS_SUCCESS; 235 236 temp = chd_dec_alloc_iodata(adp, 0); 237 if (!temp) { 238 BCMLOG_ERR("Failed to get iodata..\n"); 239 return -EINVAL; 240 } 241 242 temp->u_id = uid; 243 temp->cmd = cmd; 244 245 rc = chd_dec_proc_user_data(adp, temp, ua, 0); 246 if (!rc) { 247 sts = func(&adp->cmds, temp); 248 if (sts == BC_STS_PENDING) 249 sts = BC_STS_NOT_IMPL; 250 temp->udata.RetSts = sts; 251 rc = chd_dec_proc_user_data(adp, temp, ua, 1); 252 } 253 254 if (temp) { 255 chd_dec_free_iodata(adp, temp, 0); 256 temp = NULL; 257 } 258 259 return rc; 260} 261 262/* API interfaces */ 263static long chd_dec_ioctl(struct file *fd, unsigned int cmd, unsigned long ua) 264{ 265 struct crystalhd_adp *adp = chd_get_adp(); 266 crystalhd_cmd_proc cproc; 267 struct crystalhd_user *uc; 268 int ret; 269 270 if (!adp || !fd) { 271 BCMLOG_ERR("Invalid adp\n"); 272 return -EINVAL; 273 } 274 275 uc = fd->private_data; 276 if (!uc) { 277 BCMLOG_ERR("Failed to get uc\n"); 278 return -ENODATA; 279 } 280 281 mutex_lock(&chd_dec_mutex); 282 cproc = crystalhd_get_cmd_proc(&adp->cmds, cmd, uc); 283 if (!cproc) { 284 BCMLOG_ERR("Unhandled command: %d\n", cmd); 285 mutex_unlock(&chd_dec_mutex); 286 return -EINVAL; 287 } 288 289 ret = chd_dec_api_cmd(adp, ua, uc->uid, cmd, cproc); 290 mutex_unlock(&chd_dec_mutex); 291 return ret; 292} 293 294static int chd_dec_open(struct inode *in, struct file *fd) 295{ 296 struct crystalhd_adp *adp = chd_get_adp(); 297 int rc = 0; 298 enum BC_STATUS sts = BC_STS_SUCCESS; 299 struct crystalhd_user *uc = NULL; 300 301 BCMLOG_ENTER; 302 if (!adp) { 303 BCMLOG_ERR("Invalid adp\n"); 304 return -EINVAL; 305 } 306 307 if (adp->cfg_users >= BC_LINK_MAX_OPENS) { 308 BCMLOG(BCMLOG_INFO, "Already in use.%d\n", adp->cfg_users); 309 return -EBUSY; 310 } 311 312 sts = crystalhd_user_open(&adp->cmds, &uc); 313 if (sts != BC_STS_SUCCESS) { 314 BCMLOG_ERR("cmd_user_open - %d\n", sts); 315 rc = -EBUSY; 316 } 317 318 adp->cfg_users++; 319 320 fd->private_data = uc; 321 322 return rc; 323} 324 325static int chd_dec_close(struct inode *in, struct file *fd) 326{ 327 struct crystalhd_adp *adp = chd_get_adp(); 328 struct crystalhd_user *uc; 329 330 BCMLOG_ENTER; 331 if (!adp) { 332 BCMLOG_ERR("Invalid adp\n"); 333 return -EINVAL; 334 } 335 336 uc = fd->private_data; 337 if (!uc) { 338 BCMLOG_ERR("Failed to get uc\n"); 339 return -ENODATA; 340 } 341 342 crystalhd_user_close(&adp->cmds, uc); 343 344 adp->cfg_users--; 345 346 return 0; 347} 348 349static const struct file_operations chd_dec_fops = { 350 .owner = THIS_MODULE, 351 .unlocked_ioctl = chd_dec_ioctl, 352 .open = chd_dec_open, 353 .release = chd_dec_close, 354 .llseek = noop_llseek, 355}; 356 357static int __devinit chd_dec_init_chdev(struct crystalhd_adp *adp) 358{ 359 struct crystalhd_ioctl_data *temp; 360 struct device *dev; 361 int rc = -ENODEV, i = 0; 362 363 if (!adp) 364 goto fail; 365 366 adp->chd_dec_major = register_chrdev(0, CRYSTALHD_API_NAME, 367 &chd_dec_fops); 368 if (adp->chd_dec_major < 0) { 369 BCMLOG_ERR("Failed to create config dev\n"); 370 rc = adp->chd_dec_major; 371 goto fail; 372 } 373 374 /* register crystalhd class */ 375 crystalhd_class = class_create(THIS_MODULE, "crystalhd"); 376 if (IS_ERR(crystalhd_class)) { 377 BCMLOG_ERR("failed to create class\n"); 378 goto fail; 379 } 380 381 dev = device_create(crystalhd_class, NULL, MKDEV(adp->chd_dec_major, 0), 382 NULL, "crystalhd"); 383 if (IS_ERR(dev)) { 384 BCMLOG_ERR("failed to create device\n"); 385 goto device_create_fail; 386 } 387 388 rc = crystalhd_create_elem_pool(adp, BC_LINK_ELEM_POOL_SZ); 389 if (rc) { 390 BCMLOG_ERR("failed to create device\n"); 391 goto elem_pool_fail; 392 } 393 394 /* Allocate general purpose ioctl pool. */ 395 for (i = 0; i < CHD_IODATA_POOL_SZ; i++) { 396 temp = kzalloc(sizeof(struct crystalhd_ioctl_data), GFP_KERNEL); 397 if (!temp) { 398 BCMLOG_ERR("ioctl data pool kzalloc failed\n"); 399 rc = -ENOMEM; 400 goto kzalloc_fail; 401 } 402 /* Add to global pool.. */ 403 chd_dec_free_iodata(adp, temp, 0); 404 } 405 406 return 0; 407 408kzalloc_fail: 409 crystalhd_delete_elem_pool(adp); 410elem_pool_fail: 411 device_destroy(crystalhd_class, MKDEV(adp->chd_dec_major, 0)); 412device_create_fail: 413 class_destroy(crystalhd_class); 414fail: 415 return rc; 416} 417 418static void __devexit chd_dec_release_chdev(struct crystalhd_adp *adp) 419{ 420 struct crystalhd_ioctl_data *temp = NULL; 421 if (!adp) 422 return; 423 424 if (adp->chd_dec_major > 0) { 425 /* unregister crystalhd class */ 426 device_destroy(crystalhd_class, MKDEV(adp->chd_dec_major, 0)); 427 unregister_chrdev(adp->chd_dec_major, CRYSTALHD_API_NAME); 428 BCMLOG(BCMLOG_INFO, "released api device - %d\n", 429 adp->chd_dec_major); 430 class_destroy(crystalhd_class); 431 } 432 adp->chd_dec_major = 0; 433 434 /* Clear iodata pool.. */ 435 do { 436 temp = chd_dec_alloc_iodata(adp, 0); 437 kfree(temp); 438 } while (temp); 439 440 crystalhd_delete_elem_pool(adp); 441} 442 443static int __devinit chd_pci_reserve_mem(struct crystalhd_adp *pinfo) 444{ 445 int rc; 446 unsigned long bar2 = pci_resource_start(pinfo->pdev, 2); 447 uint32_t mem_len = pci_resource_len(pinfo->pdev, 2); 448 unsigned long bar0 = pci_resource_start(pinfo->pdev, 0); 449 uint32_t i2o_len = pci_resource_len(pinfo->pdev, 0); 450 451 BCMLOG(BCMLOG_SSTEP, "bar2:0x%lx-0x%08x bar0:0x%lx-0x%08x\n", 452 bar2, mem_len, bar0, i2o_len); 453 454 rc = check_mem_region(bar2, mem_len); 455 if (rc) { 456 BCMLOG_ERR("No valid mem region...\n"); 457 return -ENOMEM; 458 } 459 460 pinfo->addr = ioremap_nocache(bar2, mem_len); 461 if (!pinfo->addr) { 462 BCMLOG_ERR("Failed to remap mem region...\n"); 463 return -ENOMEM; 464 } 465 466 pinfo->pci_mem_start = bar2; 467 pinfo->pci_mem_len = mem_len; 468 469 rc = check_mem_region(bar0, i2o_len); 470 if (rc) { 471 BCMLOG_ERR("No valid mem region...\n"); 472 return -ENOMEM; 473 } 474 475 pinfo->i2o_addr = ioremap_nocache(bar0, i2o_len); 476 if (!pinfo->i2o_addr) { 477 BCMLOG_ERR("Failed to remap mem region...\n"); 478 return -ENOMEM; 479 } 480 481 pinfo->pci_i2o_start = bar0; 482 pinfo->pci_i2o_len = i2o_len; 483 484 rc = pci_request_regions(pinfo->pdev, pinfo->name); 485 if (rc < 0) { 486 BCMLOG_ERR("Region request failed: %d\n", rc); 487 return rc; 488 } 489 490 BCMLOG(BCMLOG_SSTEP, "Mapped addr:0x%08lx i2o_addr:0x%08lx\n", 491 (unsigned long)pinfo->addr, (unsigned long)pinfo->i2o_addr); 492 493 return 0; 494} 495 496static void __devexit chd_pci_release_mem(struct crystalhd_adp *pinfo) 497{ 498 if (!pinfo) 499 return; 500 501 if (pinfo->addr) 502 iounmap(pinfo->addr); 503 504 if (pinfo->i2o_addr) 505 iounmap(pinfo->i2o_addr); 506 507 pci_release_regions(pinfo->pdev); 508} 509 510 511static void __devexit chd_dec_pci_remove(struct pci_dev *pdev) 512{ 513 struct crystalhd_adp *pinfo; 514 enum BC_STATUS sts = BC_STS_SUCCESS; 515 516 BCMLOG_ENTER; 517 518 pinfo = pci_get_drvdata(pdev); 519 if (!pinfo) { 520 BCMLOG_ERR("could not get adp\n"); 521 return; 522 } 523 524 sts = crystalhd_delete_cmd_context(&pinfo->cmds); 525 if (sts != BC_STS_SUCCESS) 526 BCMLOG_ERR("cmd delete :%d\n", sts); 527 528 chd_dec_release_chdev(pinfo); 529 530 chd_dec_disable_int(pinfo); 531 532 chd_pci_release_mem(pinfo); 533 pci_disable_device(pinfo->pdev); 534 535 kfree(pinfo); 536 g_adp_info = NULL; 537} 538 539static int __devinit chd_dec_pci_probe(struct pci_dev *pdev, 540 const struct pci_device_id *entry) 541{ 542 struct crystalhd_adp *pinfo; 543 int rc; 544 enum BC_STATUS sts = BC_STS_SUCCESS; 545 546 BCMLOG(BCMLOG_DBG, "PCI_INFO: Vendor:0x%04x Device:0x%04x " 547 "s_vendor:0x%04x s_device: 0x%04x\n", 548 pdev->vendor, pdev->device, pdev->subsystem_vendor, 549 pdev->subsystem_device); 550 551 pinfo = kzalloc(sizeof(struct crystalhd_adp), GFP_KERNEL); 552 if (!pinfo) { 553 BCMLOG_ERR("Failed to allocate memory\n"); 554 return -ENOMEM; 555 } 556 557 pinfo->pdev = pdev; 558 559 rc = pci_enable_device(pdev); 560 if (rc) { 561 BCMLOG_ERR("Failed to enable PCI device\n"); 562 goto err; 563 } 564 565 snprintf(pinfo->name, sizeof(pinfo->name), "crystalhd_pci_e:%d:%d:%d", 566 pdev->bus->number, PCI_SLOT(pdev->devfn), 567 PCI_FUNC(pdev->devfn)); 568 569 rc = chd_pci_reserve_mem(pinfo); 570 if (rc) { 571 BCMLOG_ERR("Failed to setup memory regions.\n"); 572 pci_disable_device(pdev); 573 rc = -ENOMEM; 574 goto err; 575 } 576 577 pinfo->present = 1; 578 pinfo->drv_data = entry->driver_data; 579 580 /* Setup adapter level lock.. */ 581 spin_lock_init(&pinfo->lock); 582 583 /* setup api stuff.. */ 584 chd_dec_init_chdev(pinfo); 585 rc = chd_dec_enable_int(pinfo); 586 if (rc) { 587 BCMLOG_ERR("_enable_int err:%d\n", rc); 588 pci_disable_device(pdev); 589 rc = -ENODEV; 590 goto err; 591 } 592 593 /* Set dma mask... */ 594 if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { 595 pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); 596 pinfo->dmabits = 64; 597 } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { 598 pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); 599 pinfo->dmabits = 32; 600 } else { 601 BCMLOG_ERR("Unabled to setup DMA %d\n", rc); 602 pci_disable_device(pdev); 603 rc = -ENODEV; 604 goto err; 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 rc = -ENODEV; 612 goto err; 613 } 614 615 pci_set_master(pdev); 616 617 pci_set_drvdata(pdev, pinfo); 618 619 g_adp_info = pinfo; 620 621 return 0; 622 623err: 624 kfree(pinfo); 625 return rc; 626} 627 628#ifdef CONFIG_PM 629int chd_dec_pci_suspend(struct pci_dev *pdev, pm_message_t state) 630{ 631 struct crystalhd_adp *adp; 632 struct crystalhd_ioctl_data *temp; 633 enum BC_STATUS sts = BC_STS_SUCCESS; 634 635 adp = pci_get_drvdata(pdev); 636 if (!adp) { 637 BCMLOG_ERR("could not get adp\n"); 638 return -ENODEV; 639 } 640 641 temp = chd_dec_alloc_iodata(adp, false); 642 if (!temp) { 643 BCMLOG_ERR("could not get ioctl data\n"); 644 return -ENODEV; 645 } 646 647 sts = crystalhd_suspend(&adp->cmds, temp); 648 if (sts != BC_STS_SUCCESS) { 649 BCMLOG_ERR("BCM70012 Suspend %d\n", sts); 650 return -ENODEV; 651 } 652 653 chd_dec_free_iodata(adp, temp, false); 654 chd_dec_disable_int(adp); 655 pci_save_state(pdev); 656 657 /* Disable IO/bus master/irq router */ 658 pci_disable_device(pdev); 659 pci_set_power_state(pdev, pci_choose_state(pdev, state)); 660 return 0; 661} 662 663int chd_dec_pci_resume(struct pci_dev *pdev) 664{ 665 struct crystalhd_adp *adp; 666 enum BC_STATUS sts = BC_STS_SUCCESS; 667 int rc; 668 669 adp = pci_get_drvdata(pdev); 670 if (!adp) { 671 BCMLOG_ERR("could not get adp\n"); 672 return -ENODEV; 673 } 674 675 pci_set_power_state(pdev, PCI_D0); 676 pci_restore_state(pdev); 677 678 /* device's irq possibly is changed, driver should take care */ 679 if (pci_enable_device(pdev)) { 680 BCMLOG_ERR("Failed to enable PCI device\n"); 681 return 1; 682 } 683 684 pci_set_master(pdev); 685 686 rc = chd_dec_enable_int(adp); 687 if (rc) { 688 BCMLOG_ERR("_enable_int err:%d\n", rc); 689 pci_disable_device(pdev); 690 return -ENODEV; 691 } 692 693 sts = crystalhd_resume(&adp->cmds); 694 if (sts != BC_STS_SUCCESS) { 695 BCMLOG_ERR("BCM70012 Resume %d\n", sts); 696 pci_disable_device(pdev); 697 return -ENODEV; 698 } 699 700 return 0; 701} 702#endif 703 704static DEFINE_PCI_DEVICE_TABLE(chd_dec_pci_id_table) = { 705 { PCI_VDEVICE(BROADCOM, 0x1612), 8 }, 706 { 0, }, 707}; 708MODULE_DEVICE_TABLE(pci, chd_dec_pci_id_table); 709 710static struct pci_driver bc_chd_70012_driver = { 711 .name = "Broadcom 70012 Decoder", 712 .probe = chd_dec_pci_probe, 713 .remove = __devexit_p(chd_dec_pci_remove), 714 .id_table = chd_dec_pci_id_table, 715#ifdef CONFIG_PM 716 .suspend = chd_dec_pci_suspend, 717 .resume = chd_dec_pci_resume 718#endif 719}; 720 721void chd_set_log_level(struct crystalhd_adp *adp, char *arg) 722{ 723 if ((!arg) || (strlen(arg) < 3)) 724 g_linklog_level = BCMLOG_ERROR | BCMLOG_DATA; 725 else if (!strncmp(arg, "sstep", 5)) 726 g_linklog_level = BCMLOG_INFO | BCMLOG_DATA | BCMLOG_DBG | 727 BCMLOG_SSTEP | BCMLOG_ERROR; 728 else if (!strncmp(arg, "info", 4)) 729 g_linklog_level = BCMLOG_ERROR | BCMLOG_DATA | BCMLOG_INFO; 730 else if (!strncmp(arg, "debug", 5)) 731 g_linklog_level = BCMLOG_ERROR | BCMLOG_DATA | BCMLOG_INFO | 732 BCMLOG_DBG; 733 else if (!strncmp(arg, "pball", 5)) 734 g_linklog_level = 0xFFFFFFFF & ~(BCMLOG_SPINLOCK); 735 else if (!strncmp(arg, "silent", 6)) 736 g_linklog_level = 0; 737 else 738 g_linklog_level = 0; 739} 740 741struct crystalhd_adp *chd_get_adp(void) 742{ 743 return g_adp_info; 744} 745 746static int __init chd_dec_module_init(void) 747{ 748 int rc; 749 750 chd_set_log_level(NULL, "debug"); 751 BCMLOG(BCMLOG_DATA, "Loading crystalhd %d.%d.%d\n", 752 crystalhd_kmod_major, crystalhd_kmod_minor, crystalhd_kmod_rev); 753 754 rc = pci_register_driver(&bc_chd_70012_driver); 755 756 if (rc < 0) 757 BCMLOG_ERR("Could not find any devices. err:%d\n", rc); 758 759 return rc; 760} 761module_init(chd_dec_module_init); 762 763static void __exit chd_dec_module_cleanup(void) 764{ 765 BCMLOG(BCMLOG_DATA, "unloading crystalhd %d.%d.%d\n", 766 crystalhd_kmod_major, crystalhd_kmod_minor, crystalhd_kmod_rev); 767 768 pci_unregister_driver(&bc_chd_70012_driver); 769} 770module_exit(chd_dec_module_cleanup); 771 772MODULE_AUTHOR("Naren Sankar <nsankar@broadcom.com>"); 773MODULE_AUTHOR("Prasad Bolisetty <prasadb@broadcom.com>"); 774MODULE_DESCRIPTION(CRYSTAL_HD_NAME); 775MODULE_LICENSE("GPL"); 776MODULE_ALIAS("bcm70012"); 777