| .. | .. |
|---|
| 274 | 274 | .dev_groups = uio_groups, |
|---|
| 275 | 275 | }; |
|---|
| 276 | 276 | |
|---|
| 277 | | -bool uio_class_registered; |
|---|
| 277 | +static bool uio_class_registered; |
|---|
| 278 | 278 | |
|---|
| 279 | 279 | /* |
|---|
| 280 | 280 | * device functions |
|---|
| .. | .. |
|---|
| 398 | 398 | |
|---|
| 399 | 399 | static int uio_get_minor(struct uio_device *idev) |
|---|
| 400 | 400 | { |
|---|
| 401 | | - int retval = -ENOMEM; |
|---|
| 401 | + int retval; |
|---|
| 402 | 402 | |
|---|
| 403 | 403 | mutex_lock(&minor_lock); |
|---|
| 404 | 404 | retval = idr_alloc(&uio_idr, idev, 0, UIO_MAX_DEVICES, GFP_KERNEL); |
|---|
| .. | .. |
|---|
| 491 | 491 | if (!idev->info) { |
|---|
| 492 | 492 | mutex_unlock(&idev->info_lock); |
|---|
| 493 | 493 | ret = -EINVAL; |
|---|
| 494 | | - goto err_alloc_listener; |
|---|
| 494 | + goto err_infoopen; |
|---|
| 495 | 495 | } |
|---|
| 496 | 496 | |
|---|
| 497 | | - if (idev->info && idev->info->open) |
|---|
| 497 | + if (idev->info->open) |
|---|
| 498 | 498 | ret = idev->info->open(idev->info, inode); |
|---|
| 499 | 499 | mutex_unlock(&idev->info_lock); |
|---|
| 500 | 500 | if (ret) |
|---|
| .. | .. |
|---|
| 569 | 569 | ssize_t retval = 0; |
|---|
| 570 | 570 | s32 event_count; |
|---|
| 571 | 571 | |
|---|
| 572 | | - mutex_lock(&idev->info_lock); |
|---|
| 573 | | - if (!idev->info || !idev->info->irq) |
|---|
| 574 | | - retval = -EIO; |
|---|
| 575 | | - mutex_unlock(&idev->info_lock); |
|---|
| 576 | | - |
|---|
| 577 | | - if (retval) |
|---|
| 578 | | - return retval; |
|---|
| 579 | | - |
|---|
| 580 | 572 | if (count != sizeof(s32)) |
|---|
| 581 | 573 | return -EINVAL; |
|---|
| 582 | 574 | |
|---|
| 583 | 575 | add_wait_queue(&idev->wait, &wait); |
|---|
| 584 | 576 | |
|---|
| 585 | 577 | do { |
|---|
| 578 | + mutex_lock(&idev->info_lock); |
|---|
| 579 | + if (!idev->info || !idev->info->irq) { |
|---|
| 580 | + retval = -EIO; |
|---|
| 581 | + mutex_unlock(&idev->info_lock); |
|---|
| 582 | + break; |
|---|
| 583 | + } |
|---|
| 584 | + mutex_unlock(&idev->info_lock); |
|---|
| 585 | + |
|---|
| 586 | 586 | set_current_state(TASK_INTERRUPTIBLE); |
|---|
| 587 | 587 | |
|---|
| 588 | 588 | event_count = atomic_read(&idev->event); |
|---|
| .. | .. |
|---|
| 635 | 635 | goto out; |
|---|
| 636 | 636 | } |
|---|
| 637 | 637 | |
|---|
| 638 | | - if (!idev->info || !idev->info->irq) { |
|---|
| 638 | + if (!idev->info->irq) { |
|---|
| 639 | 639 | retval = -EIO; |
|---|
| 640 | 640 | goto out; |
|---|
| 641 | 641 | } |
|---|
| .. | .. |
|---|
| 670 | 670 | struct page *page; |
|---|
| 671 | 671 | unsigned long offset; |
|---|
| 672 | 672 | void *addr; |
|---|
| 673 | | - int ret = 0; |
|---|
| 673 | + vm_fault_t ret = 0; |
|---|
| 674 | 674 | int mi; |
|---|
| 675 | 675 | |
|---|
| 676 | 676 | mutex_lock(&idev->info_lock); |
|---|
| .. | .. |
|---|
| 738 | 738 | return -EINVAL; |
|---|
| 739 | 739 | |
|---|
| 740 | 740 | vma->vm_ops = &uio_physical_vm_ops; |
|---|
| 741 | | - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
|---|
| 741 | + if (idev->info->mem[mi].memtype == UIO_MEM_PHYS) |
|---|
| 742 | + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
|---|
| 742 | 743 | |
|---|
| 743 | 744 | /* |
|---|
| 744 | 745 | * We cannot use the vm_iomap_memory() helper here, |
|---|
| .. | .. |
|---|
| 795 | 796 | } |
|---|
| 796 | 797 | |
|---|
| 797 | 798 | switch (idev->info->mem[mi].memtype) { |
|---|
| 798 | | - case UIO_MEM_PHYS: |
|---|
| 799 | | - ret = uio_mmap_physical(vma); |
|---|
| 800 | | - break; |
|---|
| 801 | | - case UIO_MEM_LOGICAL: |
|---|
| 802 | | - case UIO_MEM_VIRTUAL: |
|---|
| 803 | | - ret = uio_mmap_logical(vma); |
|---|
| 804 | | - break; |
|---|
| 805 | | - default: |
|---|
| 806 | | - ret = -EINVAL; |
|---|
| 799 | + case UIO_MEM_IOVA: |
|---|
| 800 | + case UIO_MEM_PHYS: |
|---|
| 801 | + ret = uio_mmap_physical(vma); |
|---|
| 802 | + break; |
|---|
| 803 | + case UIO_MEM_LOGICAL: |
|---|
| 804 | + case UIO_MEM_VIRTUAL: |
|---|
| 805 | + ret = uio_mmap_logical(vma); |
|---|
| 806 | + break; |
|---|
| 807 | + default: |
|---|
| 808 | + ret = -EINVAL; |
|---|
| 807 | 809 | } |
|---|
| 808 | 810 | |
|---|
| 809 | | -out: |
|---|
| 811 | + out: |
|---|
| 810 | 812 | mutex_unlock(&idev->info_lock); |
|---|
| 811 | 813 | return ret; |
|---|
| 812 | 814 | } |
|---|
| .. | .. |
|---|
| 994 | 996 | } |
|---|
| 995 | 997 | EXPORT_SYMBOL_GPL(__uio_register_device); |
|---|
| 996 | 998 | |
|---|
| 999 | +static void devm_uio_unregister_device(struct device *dev, void *res) |
|---|
| 1000 | +{ |
|---|
| 1001 | + uio_unregister_device(*(struct uio_info **)res); |
|---|
| 1002 | +} |
|---|
| 1003 | + |
|---|
| 1004 | +/** |
|---|
| 1005 | + * devm_uio_register_device - Resource managed uio_register_device() |
|---|
| 1006 | + * @owner: module that creates the new device |
|---|
| 1007 | + * @parent: parent device |
|---|
| 1008 | + * @info: UIO device capabilities |
|---|
| 1009 | + * |
|---|
| 1010 | + * returns zero on success or a negative error code. |
|---|
| 1011 | + */ |
|---|
| 1012 | +int __devm_uio_register_device(struct module *owner, |
|---|
| 1013 | + struct device *parent, |
|---|
| 1014 | + struct uio_info *info) |
|---|
| 1015 | +{ |
|---|
| 1016 | + struct uio_info **ptr; |
|---|
| 1017 | + int ret; |
|---|
| 1018 | + |
|---|
| 1019 | + ptr = devres_alloc(devm_uio_unregister_device, sizeof(*ptr), |
|---|
| 1020 | + GFP_KERNEL); |
|---|
| 1021 | + if (!ptr) |
|---|
| 1022 | + return -ENOMEM; |
|---|
| 1023 | + |
|---|
| 1024 | + *ptr = info; |
|---|
| 1025 | + ret = __uio_register_device(owner, parent, info); |
|---|
| 1026 | + if (ret) { |
|---|
| 1027 | + devres_free(ptr); |
|---|
| 1028 | + return ret; |
|---|
| 1029 | + } |
|---|
| 1030 | + |
|---|
| 1031 | + devres_add(parent, ptr); |
|---|
| 1032 | + |
|---|
| 1033 | + return 0; |
|---|
| 1034 | +} |
|---|
| 1035 | +EXPORT_SYMBOL_GPL(__devm_uio_register_device); |
|---|
| 1036 | + |
|---|
| 997 | 1037 | /** |
|---|
| 998 | 1038 | * uio_unregister_device - unregister a industrial IO device |
|---|
| 999 | 1039 | * @info: UIO device capabilities |
|---|
| .. | .. |
|---|
| 1019 | 1059 | idev->info = NULL; |
|---|
| 1020 | 1060 | mutex_unlock(&idev->info_lock); |
|---|
| 1021 | 1061 | |
|---|
| 1062 | + wake_up_interruptible(&idev->wait); |
|---|
| 1063 | + kill_fasync(&idev->async_queue, SIGIO, POLL_HUP); |
|---|
| 1064 | + |
|---|
| 1022 | 1065 | device_unregister(&idev->dev); |
|---|
| 1023 | 1066 | |
|---|
| 1024 | 1067 | uio_free_minor(minor); |
|---|