Example #1
0
/* Function to register the AF character device driver. */
int __init af_init(void)
{
	int err;
	int result = 0;
	result = AF_GET_CCDC_FMTCFG;
	result = result & AF_VPEN_MASK;
	result = result >> AF_FMTCG_VPEN;
	/* H3A Module cannot be inserted if CCDC
	   path for H3A is not registered */
	if (!(result)) {
		/* Module cannot be inserted if CCDC is not configured */
		printk("\n Davinci AF driver cannot be loaded");
		printk("\n VIDEO PORT is not enabled ");
		printk("\n CCDC needs to be configured");
		return -1;
	}
	/*Register the driver in the kernel. Get major number dynamically */
	result = alloc_chrdev_region(&dev, AF_MAJOR_NUMBER,
				     AF_NR_DEVS, DEVICE_NAME);
	if (result < 0) {
		printk("Error :  Could not register character device");
		return -ENODEV;
	}

	/*allocate memory for device structure and initialize it with 0 */
	af_dev_configptr =
	    (struct af_device *)kmalloc(sizeof(struct af_device), GFP_KERNEL);
	if (!af_dev_configptr) {
		printk("Error : kmalloc fail");
		unregister_chrdev_region(dev, AF_NR_DEVS);
		return -ENOMEM;

	}

	/* Initialize  character device */
	cdev_init(&c_dev, &af_fops);
	c_dev.owner = THIS_MODULE;
	c_dev.ops = &af_fops;
	err = cdev_add(&c_dev, dev, 1);
	if (err) {
		printk("Error : Error in  Adding Davinci AF");
		unregister_chrdev_region(dev, AF_NR_DEVS);
		if (af_dev_configptr)
			kfree(af_dev_configptr);
		return -err;
	}

	/* Registe Character device */
	register_chrdev(MAJOR(dev), DEVICE_NAME, &af_fops);
	/* register driver as a platform driver */
	if (driver_register(&af_driver) != 0) {
		unregister_chrdev_region(dev, 1);
		cdev_del(&c_dev);
		return -EINVAL;
	}

	/* Register the drive as a platform device */
	if (platform_device_register(&afdevice) != 0) {
		driver_unregister(&af_driver);
		unregister_chrdev_region(dev, 1);
		unregister_chrdev(MAJOR(dev), DEVICE_NAME);
		cdev_del(&c_dev);
		return -EINVAL;
	}
	af_class = class_create(THIS_MODULE, "davinci_af");

	if (!af_class) {
		platform_device_unregister(&afdevice);
		printk("Error : Error in creating device class");
		unregister_chrdev_region(dev, AF_NR_DEVS);
		if (af_dev_configptr)
			kfree(af_dev_configptr);
		cdev_del(&c_dev);
		return -EIO;
	}

	class_device_create(af_class, NULL, dev, NULL, "davinci_af");

	/* Set up the Interrupt handler for H3AINT interrupt */
	result =
	    vpss_request_irq(VPSS_H3AINT, af_isr, SA_SHIRQ, "dm644xh3a_af",
			     (void *)af_dev_configptr);

	if (result != 0) {
		printk("Error : Request IRQ Failed");
		unregister_chrdev_region(dev, AF_NR_DEVS);
		if (af_dev_configptr)
			kfree(af_dev_configptr);
		class_device_destroy(af_class, dev);
		driver_unregister(&af_driver);
		platform_device_unregister(&afdevice);
		class_destroy(af_class);
		cdev_del(&c_dev);
		unregister_chrdev(MAJOR(dev), DEVICE_NAME);
		return result;
	}

	/* Initialize device structure */
	memset(af_dev_configptr, 0, sizeof(struct af_device));

	af_dev_configptr->in_use = AF_NOT_IN_USE;
	af_dev_configptr->buffer_filled = 0;

	return 0;		/*Sucess */
}
Example #2
0
static void __exit mod_exit(void)
{
    struct list_head *u;
    struct list_head *unext;
    struct list_head *registeredlistp;
    struct registered_user *user;
    int found_user;
    int i;

#ifdef USE_CLASS_SIMPLE
    class_simple_device_remove(MKDEV(major, 0));
    class_simple_destroy(dma_class);
#else
#ifdef USE_CLASS_DEVICE
    class_device_destroy(dma_class, MKDEV(major, 0));
#else
    device_destroy(dma_class, MKDEV(major, 0));
#endif // USE_CLASS_DEVICE
    class_destroy(dma_class);
#endif // USE_CLASS_SIMPLE

    unregister_chrdev(major, "edma");

    /*
     * Free all "owned" channels now.  They're supposed to get either
     * explicitly freed, or auto-freed when the file descriptor for
     * this device driver is closed by a process (which itself might happen
     * during auto-close if the process doesn't explicitly close the file
     * descriptor), but a process might crash or otherwise not get to the
     * auto-close point.  The following code will run when the module is
     * removed from the kernel (w/ rmmod).
     */
    for (i = 0; i < NCHAN; i++) {
        found_user = 0;

        if (mutex_lock_interruptible(&edma_mutex)) {
            return;
        }

        registeredlistp = &channels[i].users;
        u = registeredlistp->next;
        while (u != registeredlistp) {
            found_user = 1;

            unext = u->next;

            user = list_entry(u, struct registered_user, element);
            list_del(u);
            kfree(user);

            u = unext;
        }

        if (found_user) {
            release_channel(i);
        }

        mutex_unlock(&edma_mutex);
    }

    __D("edma unregistered\n");
}