Version:  2.0.40 2.2.26 2.4.37 2.6.39 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15

Linux/drivers/staging/crystalhd/crystalhd_lnx.c

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

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us