crystalhd_lnx.c revision 6038f373a3dc1f1c26496e60b6c40b164716f07e
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 /* FIXME: jarod: why atomic? */ 397 temp = kzalloc(sizeof(struct crystalhd_ioctl_data), GFP_ATOMIC); 398 if (!temp) { 399 BCMLOG_ERR("ioctl data pool kzalloc failed\n"); 400 rc = -ENOMEM; 401 goto kzalloc_fail; 402 } 403 /* Add to global pool.. */ 404 chd_dec_free_iodata(adp, temp, 0); 405 } 406 407 return 0; 408 409kzalloc_fail: 410 crystalhd_delete_elem_pool(adp); 411elem_pool_fail: 412 device_destroy(crystalhd_class, MKDEV(adp->chd_dec_major, 0)); 413device_create_fail: 414 class_destroy(crystalhd_class); 415fail: 416 return rc; 417} 418 419static void __devexit chd_dec_release_chdev(struct crystalhd_adp *adp) 420{ 421 struct crystalhd_ioctl_data *temp = NULL; 422 if (!adp) 423 return; 424 425 if (adp->chd_dec_major > 0) { 426 /* unregister crystalhd class */ 427 device_destroy(crystalhd_class, MKDEV(adp->chd_dec_major, 0)); 428 unregister_chrdev(adp->chd_dec_major, CRYSTALHD_API_NAME); 429 BCMLOG(BCMLOG_INFO, "released api device - %d\n", 430 adp->chd_dec_major); 431 class_destroy(crystalhd_class); 432 } 433 adp->chd_dec_major = 0; 434 435 /* Clear iodata pool.. */ 436 do { 437 temp = chd_dec_alloc_iodata(adp, 0); 438 kfree(temp); 439 } while (temp); 440 441 crystalhd_delete_elem_pool(adp); 442} 443 444static int __devinit chd_pci_reserve_mem(struct crystalhd_adp *pinfo) 445{ 446 int rc; 447 unsigned long bar2 = pci_resource_start(pinfo->pdev, 2); 448 uint32_t mem_len = pci_resource_len(pinfo->pdev, 2); 449 unsigned long bar0 = pci_resource_start(pinfo->pdev, 0); 450 uint32_t i2o_len = pci_resource_len(pinfo->pdev, 0); 451 452 BCMLOG(BCMLOG_SSTEP, "bar2:0x%lx-0x%08x bar0:0x%lx-0x%08x\n", 453 bar2, mem_len, bar0, i2o_len); 454 455 rc = check_mem_region(bar2, mem_len); 456 if (rc) { 457 BCMLOG_ERR("No valid mem region...\n"); 458 return -ENOMEM; 459 } 460 461 pinfo->addr = ioremap_nocache(bar2, mem_len); 462 if (!pinfo->addr) { 463 BCMLOG_ERR("Failed to remap mem region...\n"); 464 return -ENOMEM; 465 } 466 467 pinfo->pci_mem_start = bar2; 468 pinfo->pci_mem_len = mem_len; 469 470 rc = check_mem_region(bar0, i2o_len); 471 if (rc) { 472 BCMLOG_ERR("No valid mem region...\n"); 473 return -ENOMEM; 474 } 475 476 pinfo->i2o_addr = ioremap_nocache(bar0, i2o_len); 477 if (!pinfo->i2o_addr) { 478 BCMLOG_ERR("Failed to remap mem region...\n"); 479 return -ENOMEM; 480 } 481 482 pinfo->pci_i2o_start = bar0; 483 pinfo->pci_i2o_len = i2o_len; 484 485 rc = pci_request_regions(pinfo->pdev, pinfo->name); 486 if (rc < 0) { 487 BCMLOG_ERR("Region request failed: %d\n", rc); 488 return rc; 489 } 490 491 BCMLOG(BCMLOG_SSTEP, "Mapped addr:0x%08lx i2o_addr:0x%08lx\n", 492 (unsigned long)pinfo->addr, (unsigned long)pinfo->i2o_addr); 493 494 return 0; 495} 496 497static void __devexit chd_pci_release_mem(struct crystalhd_adp *pinfo) 498{ 499 if (!pinfo) 500 return; 501 502 if (pinfo->addr) 503 iounmap(pinfo->addr); 504 505 if (pinfo->i2o_addr) 506 iounmap(pinfo->i2o_addr); 507 508 pci_release_regions(pinfo->pdev); 509} 510 511 512static void __devexit chd_dec_pci_remove(struct pci_dev *pdev) 513{ 514 struct crystalhd_adp *pinfo; 515 enum BC_STATUS sts = BC_STS_SUCCESS; 516 517 BCMLOG_ENTER; 518 519 pinfo = (struct crystalhd_adp *) pci_get_drvdata(pdev); 520 if (!pinfo) { 521 BCMLOG_ERR("could not get adp\n"); 522 return; 523 } 524 525 sts = crystalhd_delete_cmd_context(&pinfo->cmds); 526 if (sts != BC_STS_SUCCESS) 527 BCMLOG_ERR("cmd delete :%d\n", sts); 528 529 chd_dec_release_chdev(pinfo); 530 531 chd_dec_disable_int(pinfo); 532 533 chd_pci_release_mem(pinfo); 534 pci_disable_device(pinfo->pdev); 535 536 kfree(pinfo); 537 g_adp_info = NULL; 538} 539 540static int __devinit chd_dec_pci_probe(struct pci_dev *pdev, 541 const struct pci_device_id *entry) 542{ 543 struct crystalhd_adp *pinfo; 544 int rc; 545 enum BC_STATUS sts = BC_STS_SUCCESS; 546 547 BCMLOG(BCMLOG_DBG, "PCI_INFO: Vendor:0x%04x Device:0x%04x " 548 "s_vendor:0x%04x s_device: 0x%04x\n", 549 pdev->vendor, pdev->device, pdev->subsystem_vendor, 550 pdev->subsystem_device); 551 552 /* FIXME: jarod: why atomic? */ 553 pinfo = kzalloc(sizeof(struct crystalhd_adp), GFP_ATOMIC); 554 if (!pinfo) { 555 BCMLOG_ERR("Failed to allocate memory\n"); 556 return -ENOMEM; 557 } 558 559 pinfo->pdev = pdev; 560 561 rc = pci_enable_device(pdev); 562 if (rc) { 563 BCMLOG_ERR("Failed to enable PCI device\n"); 564 return rc; 565 } 566 567 snprintf(pinfo->name, 31, "crystalhd_pci_e:%d:%d:%d", 568 pdev->bus->number, PCI_SLOT(pdev->devfn), 569 PCI_FUNC(pdev->devfn)); 570 571 rc = chd_pci_reserve_mem(pinfo); 572 if (rc) { 573 BCMLOG_ERR("Failed to setup memory regions.\n"); 574 return -ENOMEM; 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 return -ENODEV; 590 } 591 592 /* Set dma mask... */ 593 if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { 594 pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); 595 pinfo->dmabits = 64; 596 } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { 597 pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); 598 pinfo->dmabits = 32; 599 } else { 600 BCMLOG_ERR("Unabled to setup DMA %d\n", rc); 601 pci_disable_device(pdev); 602 return -ENODEV; 603 } 604 605 sts = crystalhd_setup_cmd_context(&pinfo->cmds, pinfo); 606 if (sts != BC_STS_SUCCESS) { 607 BCMLOG_ERR("cmd setup :%d\n", sts); 608 pci_disable_device(pdev); 609 return -ENODEV; 610 } 611 612 pci_set_master(pdev); 613 614 pci_set_drvdata(pdev, pinfo); 615 616 g_adp_info = pinfo; 617 618 return 0; 619} 620 621#ifdef CONFIG_PM 622int chd_dec_pci_suspend(struct pci_dev *pdev, pm_message_t state) 623{ 624 struct crystalhd_adp *adp; 625 struct crystalhd_ioctl_data *temp; 626 enum BC_STATUS sts = BC_STS_SUCCESS; 627 628 adp = (struct crystalhd_adp *)pci_get_drvdata(pdev); 629 if (!adp) { 630 BCMLOG_ERR("could not get adp\n"); 631 return -ENODEV; 632 } 633 634 temp = chd_dec_alloc_iodata(adp, false); 635 if (!temp) { 636 BCMLOG_ERR("could not get ioctl data\n"); 637 return -ENODEV; 638 } 639 640 sts = crystalhd_suspend(&adp->cmds, temp); 641 if (sts != BC_STS_SUCCESS) { 642 BCMLOG_ERR("BCM70012 Suspend %d\n", sts); 643 return -ENODEV; 644 } 645 646 chd_dec_free_iodata(adp, temp, false); 647 chd_dec_disable_int(adp); 648 pci_save_state(pdev); 649 650 /* Disable IO/bus master/irq router */ 651 pci_disable_device(pdev); 652 pci_set_power_state(pdev, pci_choose_state(pdev, state)); 653 return 0; 654} 655 656int chd_dec_pci_resume(struct pci_dev *pdev) 657{ 658 struct crystalhd_adp *adp; 659 enum BC_STATUS sts = BC_STS_SUCCESS; 660 int rc; 661 662 adp = (struct crystalhd_adp *)pci_get_drvdata(pdev); 663 if (!adp) { 664 BCMLOG_ERR("could not get adp\n"); 665 return -ENODEV; 666 } 667 668 pci_set_power_state(pdev, PCI_D0); 669 pci_restore_state(pdev); 670 671 /* device's irq possibly is changed, driver should take care */ 672 if (pci_enable_device(pdev)) { 673 BCMLOG_ERR("Failed to enable PCI device\n"); 674 return 1; 675 } 676 677 pci_set_master(pdev); 678 679 rc = chd_dec_enable_int(adp); 680 if (rc) { 681 BCMLOG_ERR("_enable_int err:%d\n", rc); 682 pci_disable_device(pdev); 683 return -ENODEV; 684 } 685 686 sts = crystalhd_resume(&adp->cmds); 687 if (sts != BC_STS_SUCCESS) { 688 BCMLOG_ERR("BCM70012 Resume %d\n", sts); 689 pci_disable_device(pdev); 690 return -ENODEV; 691 } 692 693 return 0; 694} 695#endif 696 697static DEFINE_PCI_DEVICE_TABLE(chd_dec_pci_id_table) = { 698 { PCI_VDEVICE(BROADCOM, 0x1612), 8 }, 699 { 0, }, 700}; 701MODULE_DEVICE_TABLE(pci, chd_dec_pci_id_table); 702 703static struct pci_driver bc_chd_70012_driver = { 704 .name = "Broadcom 70012 Decoder", 705 .probe = chd_dec_pci_probe, 706 .remove = __devexit_p(chd_dec_pci_remove), 707 .id_table = chd_dec_pci_id_table, 708#ifdef CONFIG_PM 709 .suspend = chd_dec_pci_suspend, 710 .resume = chd_dec_pci_resume 711#endif 712}; 713 714void chd_set_log_level(struct crystalhd_adp *adp, char *arg) 715{ 716 if ((!arg) || (strlen(arg) < 3)) 717 g_linklog_level = BCMLOG_ERROR | BCMLOG_DATA; 718 else if (!strncmp(arg, "sstep", 5)) 719 g_linklog_level = BCMLOG_INFO | BCMLOG_DATA | BCMLOG_DBG | 720 BCMLOG_SSTEP | BCMLOG_ERROR; 721 else if (!strncmp(arg, "info", 4)) 722 g_linklog_level = BCMLOG_ERROR | BCMLOG_DATA | BCMLOG_INFO; 723 else if (!strncmp(arg, "debug", 5)) 724 g_linklog_level = BCMLOG_ERROR | BCMLOG_DATA | BCMLOG_INFO | 725 BCMLOG_DBG; 726 else if (!strncmp(arg, "pball", 5)) 727 g_linklog_level = 0xFFFFFFFF & ~(BCMLOG_SPINLOCK); 728 else if (!strncmp(arg, "silent", 6)) 729 g_linklog_level = 0; 730 else 731 g_linklog_level = 0; 732} 733 734struct crystalhd_adp *chd_get_adp(void) 735{ 736 return g_adp_info; 737} 738 739static int __init chd_dec_module_init(void) 740{ 741 int rc; 742 743 chd_set_log_level(NULL, "debug"); 744 BCMLOG(BCMLOG_DATA, "Loading crystalhd %d.%d.%d\n", 745 crystalhd_kmod_major, crystalhd_kmod_minor, crystalhd_kmod_rev); 746 747 rc = pci_register_driver(&bc_chd_70012_driver); 748 749 if (rc < 0) 750 BCMLOG_ERR("Could not find any devices. err:%d\n", rc); 751 752 return rc; 753} 754module_init(chd_dec_module_init); 755 756static void __exit chd_dec_module_cleanup(void) 757{ 758 BCMLOG(BCMLOG_DATA, "unloading crystalhd %d.%d.%d\n", 759 crystalhd_kmod_major, crystalhd_kmod_minor, crystalhd_kmod_rev); 760 761 pci_unregister_driver(&bc_chd_70012_driver); 762} 763module_exit(chd_dec_module_cleanup); 764 765MODULE_AUTHOR("Naren Sankar <nsankar@broadcom.com>"); 766MODULE_AUTHOR("Prasad Bolisetty <prasadb@broadcom.com>"); 767MODULE_DESCRIPTION(CRYSTAL_HD_NAME); 768MODULE_LICENSE("GPL"); 769MODULE_ALIAS("bcm70012"); 770