/* Override for the open function */ static int media_open(struct inode *inode, struct file *filp) { struct media_devnode *mdev; int ret; /* Check if the media device is available. This needs to be done with * the media_devnode_lock held to prevent an open/unregister race: * without the lock, the device could be unregistered and freed between * the media_devnode_is_registered() and get_device() calls, leading to * a crash. */ mutex_lock(&media_devnode_lock); mdev = container_of(inode->i_cdev, struct media_devnode, cdev); /* return ENXIO if the media device has been removed already or if it is not registered anymore. */ if (!media_devnode_is_registered(mdev)) { mutex_unlock(&media_devnode_lock); return -ENXIO; } /* and increase the device refcount */ get_device(&mdev->dev); mutex_unlock(&media_devnode_lock); filp->private_data = mdev; if (mdev->fops->open) { ret = mdev->fops->open(filp); if (ret) { put_device(&mdev->dev); return ret; } } return 0; }
static ssize_t media_write(struct file *filp, const char __user *buf, size_t sz, loff_t *off) { struct media_devnode *mdev = media_devnode_data(filp); if (!mdev->fops->write) return -EINVAL; if (!media_devnode_is_registered(mdev)) return -EIO; return mdev->fops->write(filp, buf, sz, off); }
/** * media_devnode_unregister - unregister a media device node * @mdev: the device node to unregister * * This unregisters the passed device. Future open calls will be met with * errors. * * This function can safely be called if the device node has never been * registered or has already been unregistered. */ void media_devnode_unregister(struct media_devnode *mdev) { /* Check if mdev was ever registered at all */ if (!media_devnode_is_registered(mdev)) return; mutex_lock(&media_devnode_lock); clear_bit(MEDIA_FLAG_REGISTERED, &mdev->flags); mutex_unlock(&media_devnode_lock); device_unregister(&mdev->dev); }
static unsigned int media_poll(struct file *filp, struct poll_table_struct *poll) { struct media_devnode *mdev = media_devnode_data(filp); if (!media_devnode_is_registered(mdev)) return POLLERR | POLLHUP; if (!mdev->fops->poll) return DEFAULT_POLLMASK; return mdev->fops->poll(filp, poll); }
static long media_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct media_devnode *mdev = media_devnode_data(filp); if (!mdev->fops->ioctl) return -ENOTTY; if (!media_devnode_is_registered(mdev)) return -EIO; return mdev->fops->ioctl(filp, cmd, arg); }
static void au0828_unregister_media_device(struct au0828_dev *dev) { #ifdef CONFIG_MEDIA_CONTROLLER if (dev->media_dev && media_devnode_is_registered(&dev->media_dev->devnode)) { /* clear enable_source, disable_source */ dev->media_dev->source_priv = NULL; dev->media_dev->enable_source = NULL; dev->media_dev->disable_source = NULL; media_device_unregister(dev->media_dev); media_device_cleanup(dev->media_dev); kfree(dev->media_dev); dev->media_dev = NULL; } #endif }