static int __init ipcs_module_init(void)
{
	int rc = -1;
	struct proc_dir_entry *dir;

	if (ipc_crashsupport_init())
		goto out;

	dir =
	    create_proc_read_entry("driver/bcmipc", 0, NULL, ipcs_read_proc,
				   NULL);
	if (dir == NULL) {
		IPC_DEBUG(DBG_ERROR,
			  "ipcs_module_init: can't create /proc/driver/bcmipc\n");
		//return -1;
	}

	IPC_DEBUG(DBG_TRACE, "start ...\n");

	g_ipc_info.ipc_state = 0;

	g_ipc_info.mDriverClass = class_create(THIS_MODULE,
				BCM_KERNEL_IPC_NAME);
	if (IS_ERR(g_ipc_info.mDriverClass)) {
		IPC_DEBUG(DBG_ERROR, "driver class_create failed\n");
		goto out;
	}

	g_ipc_info.drvdata = device_create(g_ipc_info.mDriverClass, NULL,
				MKDEV(IPC_MAJOR, 0), NULL, BCM_KERNEL_IPC_NAME);
	if (IS_ERR(g_ipc_info.drvdata)) {
		IPC_DEBUG(DBG_ERROR, "device_create drvdata failed\n");
		goto out;
	}

	IPC_DEBUG(DBG_TRACE, "Allocate CP crash dump workqueue\n");
	g_ipc_info.crash_dump_workqueue = alloc_workqueue("dump-wq",
							  WQ_FREEZABLE |
							  WQ_MEM_RECLAIM, 0);

	if (!g_ipc_info.crash_dump_workqueue) {
		IPC_DEBUG(DBG_ERROR,
			  "Cannot allocate CP crash dump workqueue\n");
		goto out;
	}

	INIT_WORK(&g_ipc_info.cp_crash_dump_wq, ProcessCPCrashedDump);

	tasklet_init(&g_ipc_info.intr_tasklet, ipcs_intr_tasklet_handler, 0);

	/**
	 Make sure this is not cache'd because CP has to know about any changes
	 we write to this memory immediately.
	*/
	IPC_DEBUG(DBG_TRACE, "ioremap_nocache IPC_BASE\n");
	g_ipc_info.apcp_shmem = ioremap_nocache(IPC_BASE, IPC_SIZE);
	if (!g_ipc_info.apcp_shmem) {
		rc = -ENOMEM;
		IPC_DEBUG(DBG_ERROR, "Could not map shmem\n");
		goto out_shared_mem_fail;
	}

	IPC_DEBUG(DBG_TRACE, "ipcs_init\n");
	if (ipcs_init((void *)g_ipc_info.apcp_shmem, IPC_SIZE, 0)) {
		rc = -1;
		IPC_DEBUG(DBG_ERROR, "ipcs_init() failed\n");
		goto out_ipc_init_fail;
	}

	IPC_DEBUG(DBG_TRACE, "ok\n");

	wake_lock_init(&ipc_wake_lock, WAKE_LOCK_SUSPEND, "ipc_wake_lock");

	IPC_DEBUG(DBG_TRACE, "request_irq\n");
	rc = request_irq(IRQ_IPC_C2A, ipcs_interrupt, IRQF_NO_SUSPEND,
			 "ipc-intr", &g_ipc_info);

	if (rc) {
		IPC_DEBUG(DBG_ERROR, "request_irq error\n");
		goto out_irq_req_fail;
	}

	IPC_DEBUG(DBG_TRACE, "IRQ Clear and Enable\n");

	return 0;

out_irq_req_fail:

	wake_lock_destroy(&ipc_wake_lock);
out_ipc_init_fail:
	iounmap(g_ipc_info.apcp_shmem);

out_shared_mem_fail:
	flush_workqueue(g_ipc_info.crash_dump_workqueue);
	destroy_workqueue(g_ipc_info.crash_dump_workqueue);

out:
	IPC_DEBUG(DBG_ERROR, "IPC Driver Failed to initialise!\n");
	return rc;
}
示例#2
0
文件: snsc.c 项目: kzlin129/tt-gpl
/*
 * scdrv_init
 *
 * Called at boot time to initialize the system controller communication
 * facility.
 */
int __init
scdrv_init(void)
{
	geoid_t geoid;
	cnodeid_t cnode;
	char devname[32];
	char *devnamep;
	struct sysctl_data_s *scd;
	void *salbuf;
	dev_t first_dev, dev;
	nasid_t event_nasid = ia64_sn_get_console_nasid();

	if (alloc_chrdev_region(&first_dev, 0, numionodes,
				SYSCTL_BASENAME) < 0) {
		printk("%s: failed to register SN system controller device\n",
		       __FUNCTION__);
		return -ENODEV;
	}
	snsc_class = class_create(THIS_MODULE, SYSCTL_BASENAME);

	for (cnode = 0; cnode < numionodes; cnode++) {
			geoid = cnodeid_get_geoid(cnode);
			devnamep = devname;
			format_module_id(devnamep, geo_module(geoid),
					 MODULE_FORMAT_BRIEF);
			devnamep = devname + strlen(devname);
			sprintf(devnamep, "#%d", geo_slab(geoid));

			/* allocate sysctl device data */
			scd = kmalloc(sizeof (struct sysctl_data_s),
				      GFP_KERNEL);
			if (!scd) {
				printk("%s: failed to allocate device info"
				       "for %s/%s\n", __FUNCTION__,
				       SYSCTL_BASENAME, devname);
				continue;
			}
			memset(scd, 0, sizeof (struct sysctl_data_s));

			/* initialize sysctl device data fields */
			scd->scd_nasid = cnodeid_to_nasid(cnode);
			if (!(salbuf = kmalloc(SCDRV_BUFSZ, GFP_KERNEL))) {
				printk("%s: failed to allocate driver buffer"
				       "(%s%s)\n", __FUNCTION__,
				       SYSCTL_BASENAME, devname);
				kfree(scd);
				continue;
			}

			if (ia64_sn_irtr_init(scd->scd_nasid, salbuf,
					      SCDRV_BUFSZ) < 0) {
				printk
				    ("%s: failed to initialize SAL for"
				     " system controller communication"
				     " (%s/%s): outdated PROM?\n",
				     __FUNCTION__, SYSCTL_BASENAME, devname);
				kfree(scd);
				kfree(salbuf);
				continue;
			}

			dev = first_dev + cnode;
			cdev_init(&scd->scd_cdev, &scdrv_fops);
			if (cdev_add(&scd->scd_cdev, dev, 1)) {
				printk("%s: failed to register system"
				       " controller device (%s%s)\n",
				       __FUNCTION__, SYSCTL_BASENAME, devname);
				kfree(scd);
				kfree(salbuf);
				continue;
			}

			class_device_create(snsc_class, dev, NULL,
						"%s", devname);

			ia64_sn_irtr_intr_enable(scd->scd_nasid,
						 0 /*ignored */ ,
						 SAL_IROUTER_INTR_RECV);

                        /* on the console nasid, prepare to receive
                         * system controller environmental events
                         */
                        if(scd->scd_nasid == event_nasid) {
                                scdrv_event_init(scd);
                        }
	}
	return 0;
}
示例#3
0
static int gp2a_i2c_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	int ret = -ENODEV;
	struct input_dev *input_dev;
	struct gp2a_data *gp2a;
	struct gp2a_platform_data *pdata = client->dev.platform_data;

	pr_info("==============================\n");
	pr_info("=========     GP2A     =======\n");
	pr_info("==============================\n");

	if (!pdata) {
		pr_err("%s: missing pdata!\n", __func__);
		return ret;
	}
	/*
	if (!pdata->power || !pdata->light_adc_value) {
		pr_err("%s: incomplete pdata!\n", __func__);
		return ret;
	}
	*/
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		pr_err("%s: i2c functionality check failed!\n", __func__);
		return ret;
	}

	gp2a = kzalloc(sizeof(struct gp2a_data), GFP_KERNEL);
	if (!gp2a) {
		pr_err("%s: failed to alloc memory for module data\n",
			__func__);
		return -ENOMEM;
	}

#if defined(CONFIG_OPTICAL_WAKE_ENABLE)
	if (system_rev >= 0x03) {
		pr_info("GP2A Reset GPIO = GPX0(1) (rev%02d)\n", system_rev);
		gp2a->enable_wakeup = true;
	} else {
		pr_info("GP2A Reset GPIO = GPL0(6) (rev%02d)\n", system_rev);
		gp2a->enable_wakeup = false;
	}
#else
	gp2a->enable_wakeup = false;
#endif

	gp2a->pdata = pdata;
	gp2a->i2c_client = client;
	i2c_set_clientdata(client, gp2a);

	/* wake lock init */
	wake_lock_init(&gp2a->prx_wake_lock, WAKE_LOCK_SUSPEND,
			"prx_wake_lock");
	mutex_init(&gp2a->power_mutex);
	mutex_init(&gp2a->adc_mutex);

	ret = gp2a_setup_irq(gp2a);
	if (ret) {
		pr_err("%s: could not setup irq\n", __func__);
		goto err_setup_irq;
	}

	/* allocate proximity input_device */
	input_dev = input_allocate_device();
	if (!input_dev) {
		pr_err("%s: could not allocate input device\n", __func__);
		goto err_input_allocate_device_proximity;
	}

	gp2a->proximity_input_dev = input_dev;
	input_set_drvdata(input_dev, gp2a);
	input_dev->name = "proximity_sensor";
	input_set_capability(input_dev, EV_ABS, ABS_DISTANCE);
	input_set_abs_params(input_dev, ABS_DISTANCE, 0, 1, 0, 0);

	gp2a_dbgmsg("registering proximity input device\n");
	ret = input_register_device(input_dev);
	if (ret < 0) {
		pr_err("%s: could not register input device\n", __func__);
		input_free_device(input_dev);
		goto err_input_register_device_proximity;
	}

	ret = sysfs_create_group(&input_dev->dev.kobj,
				 &proximity_attribute_group);
	if (ret) {
		pr_err("%s: could not create sysfs group\n", __func__);
		goto err_sysfs_create_group_proximity;
	}

	/* hrtimer settings.  we poll for light values using a timer. */
	hrtimer_init(&gp2a->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	gp2a->light_poll_delay =
			ns_to_ktime(LIGHT_TIMER_PERIOD_MS * NSEC_PER_MSEC);
	gp2a->timer.function = gp2a_timer_func;

	/* the timer just fires off a work queue request.  we need a thread
	   to read the i2c (can be slow and blocking). */
	gp2a->wq = create_singlethread_workqueue("gp2a_wq");
	if (!gp2a->wq) {
		ret = -ENOMEM;
		pr_err("%s: could not create workqueue\n", __func__);
		goto err_create_workqueue;
	}

	/* this is the thread function we run on the work queue */
	INIT_WORK(&gp2a->work_light, gp2a_work_func_light);

#ifdef GP2A_MODE_B
	/* this is the thread function we run on the work queue */
	INIT_WORK(&gp2a->work_proximity, gp2a_work_func_proximity);
#endif

	/* allocate lightsensor-level input_device */
	input_dev = input_allocate_device();
	if (!input_dev) {
		pr_err("%s: could not allocate input device\n", __func__);
		ret = -ENOMEM;
		goto err_input_allocate_device_light;
	}

	input_set_drvdata(input_dev, gp2a);
	input_dev->name = "light_sensor";
	input_set_capability(input_dev, EV_ABS, ABS_MISC);
	input_set_abs_params(input_dev, ABS_MISC, 0, 1, 0, 0);

	gp2a_dbgmsg("registering lightsensor-level input device\n");
	ret = input_register_device(input_dev);
	if (ret < 0) {
		pr_err("%s: could not register input device\n", __func__);
		input_free_device(input_dev);
		goto err_input_register_device_light;
	}

	gp2a->light_input_dev = input_dev;
	ret = sysfs_create_group(&input_dev->dev.kobj,
				&light_attribute_group);
	if (ret) {
		pr_err("%s: could not create sysfs group\n", __func__);
		goto err_sysfs_create_group_light;
	}

	/* alloc platform device for adc client */
	pdev_gp2a_adc = platform_device_alloc("gp2a-adc", -1);
	if (!pdev_gp2a_adc) {
		pr_err("%s: could not allocation pdev_gp2a_adc.\n", __func__);
		ret = -ENOMEM;
		goto err_platform_allocate_device_adc;
	}

	/* Register adc client */
	gp2a->padc = s3c_adc_register(pdev_gp2a_adc, NULL, NULL, 0);

	if (IS_ERR(gp2a->padc)) {
		dev_err(&pdev_gp2a_adc->dev, "cannot register adc\n");
		ret = PTR_ERR(gp2a->padc);
		goto err_platform_register_device_adc;
	}

	/* set sysfs for light sensor */

	ret = misc_register(&light_device);
	if (ret)
		pr_err(KERN_ERR "misc_register failed - light\n");

	gp2a->lightsensor_class = class_create(THIS_MODULE, "lightsensor");
	if (IS_ERR(gp2a->lightsensor_class))
		pr_err("Failed to create class(lightsensor)!\n");

	gp2a->switch_cmd_dev = device_create(gp2a->lightsensor_class,
		NULL, 0, NULL, "switch_cmd");
	if (IS_ERR(gp2a->switch_cmd_dev))
		pr_err("Failed to create device(switch_cmd_dev)!\n");

	if (device_create_file(gp2a->switch_cmd_dev,
		&dev_attr_lightsensor_file_illuminance) < 0)
		pr_err("Failed to create device file(%s)!\n",
			dev_attr_lightsensor_file_illuminance.attr.name);

	dev_set_drvdata(gp2a->switch_cmd_dev, gp2a);

	/* set initial proximity value as 1 */
	input_report_abs(gp2a->proximity_input_dev, ABS_DISTANCE, 1);
	input_sync(gp2a->proximity_input_dev);

	gp2a->adc_total = 0;

	goto done;

	/* error, unwind it all */
err_sysfs_create_group_light:
	input_unregister_device(gp2a->light_input_dev);
err_input_register_device_light:
err_input_allocate_device_light:
	destroy_workqueue(gp2a->wq);
err_platform_allocate_device_adc:
	platform_device_unregister(pdev_gp2a_adc);
err_platform_register_device_adc:
	s3c_adc_release(gp2a->padc);
err_create_workqueue:
	sysfs_remove_group(&gp2a->proximity_input_dev->dev.kobj,
			&proximity_attribute_group);
err_sysfs_create_group_proximity:
	input_unregister_device(gp2a->proximity_input_dev);
err_input_register_device_proximity:
err_input_allocate_device_proximity:
	free_irq(gp2a->irq, 0);
	gpio_free(gp2a->pdata->p_out);
err_setup_irq:
	mutex_destroy(&gp2a->adc_mutex);
	mutex_destroy(&gp2a->power_mutex);

	wake_lock_destroy(&gp2a->prx_wake_lock);
	kfree(gp2a);
done:
	return ret;
}
示例#4
0
static int
dev_nvram_init(void)
{
	int order = 0, ret = 0;
	struct page *page, *end;
	unsigned int i;
	osl_t *osh;

	/* Allocate and reserve memory to mmap() */
	while ((PAGE_SIZE << order) < nvram_space)
		order++;
	end = virt_to_page(nvram_buf + (PAGE_SIZE << order) - 1);
	for (page = virt_to_page(nvram_buf); page <= end; page++) {
		SetPageReserved(page);
	}

#if defined(CONFIG_MTD) || defined(CONFIG_MTD_MODULE)
	/* Find associated MTD device */
	for (i = 0; i < MAX_MTD_DEVICES; i++) {
		nvram_mtd = get_mtd_device(NULL, i);
		if (!IS_ERR(nvram_mtd)) {
			if (!strcmp(nvram_mtd->name, "nvram") &&
			    nvram_mtd->size >= nvram_space) {
				break;
			}
			put_mtd_device(nvram_mtd);
		}
	}
	if (i >= MAX_MTD_DEVICES)
		nvram_mtd = NULL;
#endif

	/* Initialize hash table lock */
	spin_lock_init(&nvram_lock);

	/* Initialize commit semaphore */
	init_MUTEX(&nvram_sem);

	/* Register char device */
	if ((nvram_major = register_chrdev(0, "nvram", &dev_nvram_fops)) < 0) {
		ret = nvram_major;
		goto err;
	}

	if (si_osh(sih) == NULL) {
		osh = osl_attach(NULL, SI_BUS, FALSE);
		if (osh == NULL) {
			printk("Error allocating osh\n");
			unregister_chrdev(nvram_major, "nvram");
			goto err;
		}
		si_setosh(sih, osh);
	}

printk("dev_nvram_init: _nvram_init\n");
	/* Initialize hash table */
	_nvram_init((void *)sih);

	/* Create /dev/nvram handle */
	nvram_class = class_create(THIS_MODULE, "nvram");
	if (IS_ERR(nvram_class)) {
		printk("Error creating nvram class\n");
		goto err;
	}

	/* Add the device nvram0 */
	class_device_create(nvram_class, NULL, MKDEV(nvram_major, 0), NULL, "nvram");

	/* reserve commit read buffer */
	/* Backup sector blocks to be erased */
	if (!(nvram_commit_buf = kmalloc(ROUNDUP(nvram_space, nvram_mtd->erasesize), GFP_KERNEL))) {
		printk("dev_nvram_init: nvram_commit_buf out of memory\n");
		goto err;
	}

	/* Set the SDRAM NCDL value into NVRAM if not already done */
	if (getintvar(NULL, "sdram_ncdl") == 0) {
		unsigned int ncdl;
		char buf[] = "0x00000000";

		if ((ncdl = si_memc_get_ncdl(sih))) {
			sprintf(buf, "0x%08x", ncdl);
			nvram_set("sdram_ncdl", buf);
			nvram_commit();
		}
	}

	return 0;

err:
	dev_nvram_exit();
	return ret;
}
示例#5
0
static int mdnie_probe(struct platform_device *pdev)
{
#if defined(CONFIG_FB_MDNIE_PWM)
	struct platform_mdnie_data *pdata = pdev->dev.platform_data;
#endif
	struct mdnie_info *mdnie;
	int ret = 0;

	mdnie_class = class_create(THIS_MODULE, dev_name(&pdev->dev));
	if (IS_ERR_OR_NULL(mdnie_class)) {
		pr_err("failed to create mdnie class\n");
		ret = -EINVAL;
		goto error0;
	}

	mdnie_class->dev_attrs = mdnie_attributes;

	mdnie = kzalloc(sizeof(struct mdnie_info), GFP_KERNEL);
	if (!mdnie) {
		pr_err("failed to allocate mdnie\n");
		ret = -ENOMEM;
		goto error1;
	}

	mdnie->dev = device_create(mdnie_class, &pdev->dev, 0, &mdnie, "mdnie");
	if (IS_ERR_OR_NULL(mdnie->dev)) {
		pr_err("failed to create mdnie device\n");
		ret = -EINVAL;
		goto error2;
	}

#if defined(CONFIG_FB_MDNIE_PWM)
	mdnie->bd = backlight_device_register("panel", mdnie->dev,
		mdnie, &mdnie_backlight_ops, NULL);
	mdnie->bd->props.max_brightness = MAX_BRIGHTNESS_LEVEL;
	mdnie->bd->props.brightness = DEFAULT_BRIGHTNESS;
	mdnie->bd_enable = TRUE;
	mdnie->lcd_pd = pdata->lcd_pd;
#endif

	mdnie->scenario = UI_MODE;
	mdnie->mode = STANDARD;
	mdnie->tone = TONE_NORMAL;
	mdnie->outdoor = OUTDOOR_OFF;
#if defined(CONFIG_FB_MDNIE_PWM)
	mdnie->cabc = CABC_ON;
#else
	mdnie->cabc = CABC_OFF;
#endif
	mdnie->enable = TRUE;
	mdnie->tunning = FALSE;
	mdnie->negative = NEGATIVE_OFF;

	mutex_init(&mdnie->lock);
	mutex_init(&mdnie->dev_lock);

	platform_set_drvdata(pdev, mdnie);
	dev_set_drvdata(mdnie->dev, mdnie);

#ifdef CONFIG_HAS_WAKELOCK
#ifdef CONFIG_HAS_EARLYSUSPEND
#if defined(CONFIG_FB_MDNIE_PWM)
	mdnie->early_suspend.suspend = mdnie_early_suspend;
	mdnie->early_suspend.resume = mdnie_late_resume;
	mdnie->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 1;
	register_early_suspend(&mdnie->early_suspend);
#endif
#endif
#endif

#if defined(CONFIG_FB_S5P_S6C1372)
	check_lcd_type();
	dev_info(mdnie->dev, "lcdtype = %d\n", pdata->display_type);
	if (pdata->display_type == 1) {
		b_value.max = 1441;
		b_value.mid = 784;
		b_value.low = 16;
		b_value.dim = 16;
	} else {
		b_value.max = 1137;	/* 71% */
		b_value.mid = 482;	/* 38% */
		b_value.low = 16;	/* 1% */
		b_value.dim = 16;	/* 1% */
	}
#endif

#if defined(CONFIG_FB_S5P_S6F1202A)
	if (pdata->display_type == 0) {
		memcpy(tunning_table, tunning_table_hy, sizeof(tunning_table));
		memcpy(etc_table, etc_table_hy, sizeof(etc_table));
		tune_camera = tune_camera_hy;
		tune_camera_outdoor = tune_camera_outdoor_hy;
	} else if (pdata->display_type == 1) {
		memcpy(tunning_table, tunning_table_sec, sizeof(tunning_table));
		memcpy(etc_table, etc_table_sec, sizeof(etc_table));
		tune_camera = tune_camera_sec;
		tune_camera_outdoor = tune_camera_outdoor_sec;
	} else if (pdata->display_type == 2) {
		memcpy(tunning_table, tunning_table_bo, sizeof(tunning_table));
		memcpy(etc_table, etc_table_bo, sizeof(etc_table));
		tune_camera = tune_camera_bo;
		tune_camera_outdoor = tune_camera_outdoor_bo;
	}
#endif

	g_mdnie = mdnie;

	set_mdnie_value(mdnie, 0);

	dev_info(mdnie->dev, "registered successfully\n");

	return 0;

error2:
	kfree(mdnie);
error1:
	class_destroy(mdnie_class);
error0:
	return ret;
}
示例#6
0
static int __devinit chd_dec_init_chdev(struct crystalhd_adp *adp)
{
	struct crystalhd_ioctl_data *temp;
	struct device *dev;
	int rc = -ENODEV, i = 0;

	if (!adp)
		goto fail;

	adp->chd_dec_major = register_chrdev(0, CRYSTALHD_API_NAME,
					     &chd_dec_fops);
	if (adp->chd_dec_major < 0) {
		BCMLOG_ERR("Failed to create config dev\n");
		rc = adp->chd_dec_major;
		goto fail;
	}

	/* register crystalhd class */
	crystalhd_class = class_create(THIS_MODULE, "crystalhd");
	if (IS_ERR(crystalhd_class)) {
		BCMLOG_ERR("failed to create class\n");
		goto fail;
	}

	dev = device_create(crystalhd_class, NULL, MKDEV(adp->chd_dec_major, 0),
			    NULL, "crystalhd");
	if (IS_ERR(dev)) {
		BCMLOG_ERR("failed to create device\n");
		goto device_create_fail;
	}

	rc = crystalhd_create_elem_pool(adp, BC_LINK_ELEM_POOL_SZ);
	if (rc) {
		BCMLOG_ERR("failed to create device\n");
		goto elem_pool_fail;
	}

	/* Allocate general purpose ioctl pool. */
	for (i = 0; i < CHD_IODATA_POOL_SZ; i++) {
		/* FIXME: jarod: why atomic? */
		temp = kzalloc(sizeof(struct crystalhd_ioctl_data), GFP_ATOMIC);
		if (!temp) {
			BCMLOG_ERR("ioctl data pool kzalloc failed\n");
			rc = -ENOMEM;
			goto kzalloc_fail;
		}
		/* Add to global pool.. */
		chd_dec_free_iodata(adp, temp, 0);
	}

	return 0;

kzalloc_fail:
	crystalhd_delete_elem_pool(adp);
elem_pool_fail:
	device_destroy(crystalhd_class, MKDEV(adp->chd_dec_major, 0));
device_create_fail:
	class_destroy(crystalhd_class);
fail:
	return rc;
}
示例#7
0
static int g2d_probe(struct platform_device *pdev)
{
    struct class_device;
    struct class_device *class_dev = NULL;
    
    G2D_INF("\n\n\n===================== G2D probe ======================\n\n\n");

    if (alloc_chrdev_region(&g2d_devno, 0, 1, G2D_DEVNAME))
    {
        G2D_ERR("can't get device major number...\n");
        return -EFAULT;
    }

    G2D_INF("get device major number (%d)\n", g2d_devno);

    g2d_cdev = cdev_alloc();
    g2d_cdev->owner = THIS_MODULE;
    g2d_cdev->ops = &g2d_fops;

    cdev_add(g2d_cdev, g2d_devno, 1);

    g2d_class = class_create(THIS_MODULE, G2D_DEVNAME);
    class_dev = (struct class_device *)device_create(g2d_class, NULL, g2d_devno, NULL, G2D_DEVNAME);

    spin_lock_init(&g2d_cmd_spinlock);

#ifdef G2D_QUEUE
    if (_g2d_create_workqueue())
    {
        G2D_ERR("failed to create workqueue\n");
        return -EFAULT;
    }

    if (_g2d_create_queuebuffer())
    {
        G2D_ERR("failed to create queue buffer\n");
        return -EFAULT;
    }
#else
    init_waitqueue_head(&isr_wait_queue);

    if (!g2d_cmd_buffer)
    {
        g2d_cmd_buffer = (g2d_command_t *)kzalloc(sizeof(g2d_command_t), GFP_KERNEL);
        if (!g2d_cmd_buffer) return -EFAULT;
    }
#endif

    //mt_irq_set_sens(MT_G2D_IRQ_ID, MT65xx_EDGE_SENSITIVE);
    //mt_irq_set_polarity(MT_G2D_IRQ_ID, MT65xx_POLARITY_LOW);

    if (request_irq(MT_G2D_IRQ_ID, g2d_drv_isr, IRQF_TRIGGER_FALLING, "G2D ISR", NULL))
    {
        G2D_ERR("request irq failed\n");
    }

    G2D_INF("probe is done\n");

    NOT_REFERENCED(class_dev);
    return 0;
}
static int tab3_wm1811_init_paiftx(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_soc_codec *codec = rtd->codec;
	struct wm1811_machine_priv *wm1811
		= snd_soc_card_get_drvdata(codec->card);
	struct snd_soc_dai *aif1_dai = rtd->codec_dai;
	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
	int ret;

	midas_snd_set_mclk(true, false);

	rtd->codec_dai->driver->playback.channels_max =
				rtd->cpu_dai->driver->playback.channels_max;

	ret = snd_soc_add_controls(codec, tab3_controls,
					ARRAY_SIZE(tab3_controls));

#if defined(CONFIG_TAB3_00_BD)
	if(system_rev < 2) {
		ret = snd_soc_dapm_new_controls(&codec->dapm, tab3_dapm_widgets_rev0,
				ARRAY_SIZE(tab3_dapm_widgets_rev0));
		if (ret != 0)
			dev_err(codec->dev, "Failed to add DAPM widgets: %d\n", ret);

		ret = snd_soc_dapm_add_routes(&codec->dapm, tab3_dapm_routes_rev0,
				ARRAY_SIZE(tab3_dapm_routes_rev0));
		if (ret != 0)
			dev_err(codec->dev, "Failed to add DAPM routes: %d\n", ret);
	} else {
		ret = snd_soc_dapm_new_controls(&codec->dapm, tab3_dapm_widgets,
				ARRAY_SIZE(tab3_dapm_widgets));
		if (ret != 0)
			dev_err(codec->dev, "Failed to add DAPM widgets: %d\n", ret);

		ret = snd_soc_dapm_add_routes(&codec->dapm, tab3_dapm_routes,
				ARRAY_SIZE(tab3_dapm_routes));
		if (ret != 0)
			dev_err(codec->dev, "Failed to add DAPM routes: %d\n", ret);
	}
#else
	ret = snd_soc_dapm_new_controls(&codec->dapm, tab3_dapm_widgets,
			ARRAY_SIZE(tab3_dapm_widgets));
	if (ret != 0)
		dev_err(codec->dev, "Failed to add DAPM widgets: %d\n", ret);

	ret = snd_soc_dapm_add_routes(&codec->dapm, tab3_dapm_routes,
			ARRAY_SIZE(tab3_dapm_routes));
	if (ret != 0)
		dev_err(codec->dev, "Failed to add DAPM routes: %d\n", ret);

#endif

	ret = snd_soc_dai_set_sysclk(aif1_dai, WM8994_SYSCLK_MCLK2,
				     MIDAS_DEFAULT_MCLK2, SND_SOC_CLOCK_IN);
	if (ret < 0)
		dev_err(codec->dev, "Failed to boot clocking\n");

	/* Force AIF1CLK on as it will be master for jack detection */
	if (wm8994->revision > 1) {
		ret = snd_soc_dapm_force_enable_pin(&codec->dapm, "AIF1CLK");
		if (ret < 0)
			dev_err(codec->dev, "Failed to enable AIF1CLK: %d\n",
					ret);
	}

	ret = snd_soc_dapm_disable_pin(&codec->dapm, "S5P RP");
	if (ret < 0)
		dev_err(codec->dev, "Failed to disable S5P RP: %d\n", ret);

	snd_soc_dapm_ignore_suspend(&codec->dapm, "RCV");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "SPK");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "HP");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "Headset Mic");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "Sub Mic");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "Main Mic");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF1DACDAT");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF2DACDAT");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF3DACDAT");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF1ADCDAT");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF2ADCDAT");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF3ADCDAT");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "FM In");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "LINE");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "HDMI");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "Third Mic");

	wm1811->codec = codec;

	tab3_micd_set_rate(codec);

#ifdef CONFIG_SEC_DEV_JACK
	/* By default use idle_bias_off, will override for WM8994 */
	codec->dapm.idle_bias_off = 0;
#if defined (CONFIG_TAB3_00_BD)
	if(system_rev < 2) {
		ret = snd_soc_dapm_force_enable_pin(&codec->dapm, "MICBIAS2");
		if (ret < 0)
			dev_err(codec->dev, "Failed to enable MICBIAS2: %d\n",
					ret);
	}
#endif
#else /* CONFIG_SEC_DEV_JACK */
	wm1811->jack.status = 0;

	ret = snd_soc_jack_new(codec, "Tab3 Jack",
				SND_JACK_HEADSET | SND_JACK_BTN_0 |
				SND_JACK_BTN_1 | SND_JACK_BTN_2,
				&wm1811->jack);

	if (ret < 0)
		dev_err(codec->dev, "Failed to create jack: %d\n", ret);

	ret = snd_jack_set_key(wm1811->jack.jack, SND_JACK_BTN_0, KEY_MEDIA);

	if (ret < 0)
		dev_err(codec->dev, "Failed to set KEY_MEDIA: %d\n", ret);

	ret = snd_jack_set_key(wm1811->jack.jack, SND_JACK_BTN_1,
							KEY_VOLUMEUP);
	if (ret < 0)
		dev_err(codec->dev, "Failed to set KEY_VOLUMEUP: %d\n", ret);

	ret = snd_jack_set_key(wm1811->jack.jack, SND_JACK_BTN_2,
							KEY_VOLUMEDOWN);

	if (ret < 0)
		dev_err(codec->dev, "Failed to set KEY_VOLUMEDOWN: %d\n", ret);

	if (wm8994->revision > 1) {
		dev_info(codec->dev, "wm1811: Rev %c support mic detection\n",
			'A' + wm8994->revision);
		ret = wm8958_mic_detect(codec, &wm1811->jack, NULL,
				NULL, tab3_mic_id, wm1811);

		if (ret < 0)
			dev_err(codec->dev, "Failed start detection: %d\n",
				ret);
	} else {
		dev_info(codec->dev, "wm1811: Rev %c doesn't support mic detection\n",
			'A' + wm8994->revision);
		codec->dapm.idle_bias_off = 0;
	}
	/* To wakeup for earjack event in suspend mode */
	enable_irq_wake(control->irq);

	wake_lock_init(&wm1811->jackdet_wake_lock,
					WAKE_LOCK_SUSPEND, "Tab3_jackdet");

	/* To support PBA function test */
	jack_class = class_create(THIS_MODULE, "audio");

	if (IS_ERR(jack_class))
		pr_err("Failed to create class\n");

	jack_dev = device_create(jack_class, NULL, 0, codec, "earjack");

	if (device_create_file(jack_dev, &dev_attr_select_jack) < 0)
		pr_err("Failed to create device file (%s)!\n",
			dev_attr_select_jack.attr.name);

	if (device_create_file(jack_dev, &dev_attr_key_state) < 0)
		pr_err("Failed to create device file (%s)!\n",
			dev_attr_key_state.attr.name);

	if (device_create_file(jack_dev, &dev_attr_state) < 0)
		pr_err("Failed to create device file (%s)!\n",
			dev_attr_state.attr.name);

	if (device_create_file(jack_dev, &dev_attr_reselect_jack) < 0)
		pr_err("Failed to create device file (%s)!\n",
			dev_attr_reselect_jack.attr.name);

#endif /* CONFIG_SEC_DEV_JACK */
	return snd_soc_dapm_sync(&codec->dapm);
}
static int synaptics_ts_probe(
		struct i2c_client *client, const struct i2c_device_id *id)
{
	struct synaptics_ts_data *ts;
	int ret = 0;
	uint8_t i2c_addr = 0x05;
	uint8_t buf[3];
	int ret_temp=0;
	uint8_t buf_temp[3];
	uint8_t i2c_addr_temp = 0x02;

	printk("[TSP] %s, %d\n", __func__, __LINE__ );

	touch_ctrl_regulator(TOUCH_ON);

	msleep(100);

	ts = kzalloc(sizeof(*ts), GFP_KERNEL);
	if (ts == NULL) {
		ret = -ENOMEM;
		goto err_alloc_data_failed;
	}
	INIT_WORK(&ts->work, synaptics_ts_work_func);
	ts->client = client;
	i2c_set_clientdata(client, ts);

	ts_global = ts;

	/* Check point - i2c check - start */
	ret = tsp_i2c_read( i2c_addr, buf, sizeof(buf));

	if (ret <= 0) {
		printk(KERN_ERR "i2c_transfer failed\n");
		ret = tsp_i2c_read( i2c_addr, buf, sizeof(buf));

		if (ret <= 0) 
		{
			printk("[TSP] %s, ln:%d, Failed to register TSP!!!\n\tcheck the i2c line!!!, ret=%d\n", __func__,__LINE__, ret);
			goto err_check_functionality_failed;
		}
	}
	/* Check point - i2c check - end */

	ts->input_dev = input_allocate_device();
	if (ts->input_dev == NULL) {
		ret = -ENOMEM;
		printk(KERN_ERR "synaptics_ts_probe: Failed to allocate input device\n");
		goto err_input_dev_alloc_failed;
	}
	ts->input_dev->name = "synaptics-rmi-touchscreen";
	set_bit(EV_SYN, ts->input_dev->evbit);
	set_bit(EV_KEY, ts->input_dev->evbit);
	set_bit(BTN_TOUCH, ts->input_dev->keybit);
	set_bit(EV_ABS, ts->input_dev->evbit);

	printk(KERN_INFO "synaptics_ts_probe: max_x: 240, max_y: 320\n");

       input_set_abs_params(ts->input_dev, ABS_X, 0, MAX_X, 0, 0);
	input_set_abs_params(ts->input_dev, ABS_Y, 0, MAX_Y, 0, 0);
	input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, 255, 0, 0);
	input_set_abs_params(ts->input_dev, ABS_TOOL_WIDTH, 0, 15, 0, 0);

	/* ts->input_dev->name = ts->keypad_info->name; */
	ret = input_register_device(ts->input_dev);
	if (ret) {
		printk(KERN_ERR "synaptics_ts_probe: Unable to register %s input device\n", ts->input_dev->name);
		goto err_input_register_device_failed;
	}
	printk("[TSP] %s, irq=%d\n", __func__, client->irq );
	if (client->irq) {
		ret = request_irq(client->irq, synaptics_ts_irq_handler,/* IRQF_TRIGGER_RISING |*/ IRQF_TRIGGER_FALLING , client->name, ts);
		if (ret == 0) 
			ts->use_irq = 1;
		else
			dev_err(&client->dev, "request_irq failed\n");
	}

	//	hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	//	ts->timer.function = synaptics_ts_timer_func;

#ifdef CONFIG_HAS_EARLYSUSPEND
	ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
	ts->early_suspend.suspend = synaptics_ts_early_suspend;
	ts->early_suspend.resume = synaptics_ts_late_resume;
	register_early_suspend(&ts->early_suspend);
#endif

	printk(KERN_INFO "synaptics_ts_probe: Start touchscreen %s in %s mode\n", ts->input_dev->name, ts->use_irq ? "interrupt" : "polling");

	/* sys fs */
	touch_class = class_create(THIS_MODULE, "touch");
	if (IS_ERR(touch_class))
		pr_err("Failed to create class(touch)!\n");

	firmware_dev = device_create(touch_class, NULL, 0, NULL, "firmware");
	if (IS_ERR(firmware_dev))
		pr_err("Failed to create device(firmware)!\n");

	if (device_create_file(firmware_dev, &dev_attr_firmware) < 0)
		pr_err("Failed to create device file(%s)!\n", dev_attr_firmware.attr.name);
	if (device_create_file(firmware_dev, &dev_attr_firmware_ret) < 0)
		pr_err("Failed to create device file(%s)!\n", dev_attr_firmware_ret.attr.name);

	/* sys fs */

	/* Check point - Firmware */
	printk("[TSP] %s, ver CY=%x\n", __func__ , buf[0] );
	printk("[TSP] %s, ver HW=%x\n", __func__ , buf[1] );
	printk("[TSP] %s, ver SW=%x\n", __func__ , buf[2] );

	HW_ver = buf[1];
	printk(KERN_INFO "synaptics_ts_probe: Manufacturer ID: %x, HW ver=%d\n", buf[0], HW_ver);
    
	/* Check point - Firmware */

	ret_temp = tsp_i2c_read( i2c_addr_temp, buf_temp, sizeof(buf_temp));

	if (ret_temp <= 0) {
		printk("[TSP] i2c failed : ret=%d, ln=%d\n",ret_temp, __LINE__);
		goto err_check_functionality_failed;
	}

	return 0;

err_input_register_device_failed:
	input_free_device(ts->input_dev);

err_input_dev_alloc_failed:
	kfree(ts);
err_alloc_data_failed:
err_check_functionality_failed:
	return ret;
}
示例#10
0
static int __init msm_sensor_init_module(void)
{
	struct msm_sensor_init_t *s_init = NULL;
	struct device			*cam_dev_back;
	struct device			*cam_dev_front;
	int rc = 0;
	camera_class = class_create(THIS_MODULE, "camera");
	if (IS_ERR(camera_class))
		pr_err("failed to create device cam_dev_rear!\n");

	/* Allocate memory for msm_sensor_init control structure */
	s_init = kzalloc(sizeof(struct msm_sensor_init_t), GFP_KERNEL);
	if (!s_init) {
		class_destroy(camera_class);
		pr_err("failed: no memory s_init %p", NULL);
		return -ENOMEM;
	}

	pr_err("MSM_SENSOR_INIT_MODULE %p", NULL);

	/* Initialize mutex */
	mutex_init(&s_init->imutex);

	/* Create /dev/v4l-subdevX for msm_sensor_init */
	v4l2_subdev_init(&s_init->msm_sd.sd, &msm_sensor_init_subdev_ops);
	snprintf(s_init->msm_sd.sd.name, sizeof(s_init->msm_sd.sd.name), "%s",
		"msm_sensor_init");
	v4l2_set_subdevdata(&s_init->msm_sd.sd, s_init);
	s_init->msm_sd.sd.internal_ops = &msm_sensor_init_internal_ops;
	s_init->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
	rc = media_entity_init(&s_init->msm_sd.sd.entity, 0, NULL, 0);
	if (rc < 0)
		goto entity_fail;
	s_init->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
	s_init->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_SENSOR_INIT;
	s_init->msm_sd.sd.entity.name = s_init->msm_sd.sd.name;
	s_init->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x6;
	rc = msm_sd_register(&s_init->msm_sd);
	if (rc < 0)
		goto msm_sd_register_fail;

	cam_dev_back = device_create(camera_class, NULL,
			1, NULL, "rear");
	if (IS_ERR(cam_dev_back)) {
		printk("Failed to create cam_dev_back device!\n");
		goto device_create_fail;
	}

	if (device_create_file(cam_dev_back, &dev_attr_rear_camtype) < 0) {
		printk("Failed to create device file!(%s)!\n",
				dev_attr_rear_camtype.attr.name);
		goto device_create_fail;
	}
	if (device_create_file(cam_dev_back, &dev_attr_rear_camfw) < 0) {
		printk("Failed to create device file!(%s)!\n",
				dev_attr_rear_camfw.attr.name);
		goto device_create_fail;
	}

	if (device_create_file(cam_dev_back, &dev_attr_rear_checkfw_user) < 0) {
		printk("Failed to create device file!(%s)!\n",
			dev_attr_rear_checkfw_user.attr.name);
		rc = -ENODEV;
		goto device_create_fail;
	}
	if (device_create_file(cam_dev_back, &dev_attr_rear_checkfw_factory) < 0) {
		printk("Failed to create device file!(%s)!\n",
			dev_attr_rear_checkfw_factory.attr.name);
		rc = -ENODEV;
		goto device_create_fail;
	}

	if (device_create_file(cam_dev_back, &dev_attr_isp_core) < 0) {
		printk("Failed to create device file!(%s)!\n",
				dev_attr_isp_core.attr.name);
		goto device_create_fail;
	}

	if (device_create_file(cam_dev_back, &dev_attr_rear_camfw_load) < 0) {
		printk("Failed to create device file!(%s)!\n",
				dev_attr_rear_camfw_load.attr.name);
		goto device_create_fail;
	}

	if (device_create_file(cam_dev_back, &dev_attr_rear_camfw_full) < 0) {
		printk("Failed to create device file!(%s)!\n",
				dev_attr_rear_camfw_full.attr.name);
		goto device_create_fail;
	}

	if (device_create_file(cam_dev_back, &dev_attr_rear_vendorid) < 0) {
		printk("Failed to create device file!(%s)!\n",
			dev_attr_rear_vendorid.attr.name);
		goto device_create_fail;
	}

	cam_dev_front = device_create(camera_class, NULL,
		2, NULL, "front");
	if (IS_ERR(cam_dev_front)) {
		printk("Failed to create cam_dev_front device!");
		goto device_create_fail;
	}

	if (device_create_file(cam_dev_front, &dev_attr_front_camtype) < 0) {
		printk("Failed to create device file!(%s)!\n",
			dev_attr_front_camtype.attr.name);
		goto device_create_fail;
	}
	if (device_create_file(cam_dev_front, &dev_attr_front_camfw) < 0) {
		printk("Failed to create device file!(%s)!\n",
			dev_attr_front_camfw.attr.name);
		goto device_create_fail;
	}
	if (device_create_file(cam_dev_front, &dev_attr_front_camfw_load) < 0) {
		printk("Failed to create device file!(%s)!\n",
			dev_attr_rear_camfw_load.attr.name);
		goto device_create_fail;
	}
	if (device_create_file(cam_dev_front, &dev_attr_front_camfw_full) < 0) {
	    printk("Failed to create device file!(%s)!\n",
		    dev_attr_rear_camfw_full.attr.name);
		goto device_create_fail;
	}

	init_waitqueue_head(&s_init->state_wait);

	return 0;
device_create_fail:
	msm_sd_unregister(&s_init->msm_sd);
msm_sd_register_fail:
	media_entity_cleanup(&s_init->msm_sd.sd.entity);
entity_fail:
	mutex_destroy(&s_init->imutex);
	kfree(s_init);
	class_destroy(camera_class);
	return rc;
}
示例#11
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 */
}
static int leds_sm5701_probe(struct platform_device *pdev)
{
        struct SM5701_dev *iodev = dev_get_drvdata(pdev->dev.parent);
        struct SM5701_leds_data *chip;
        struct SM5701_fled_platform_data *pdata;

        int err;

        printk("******* %s *******\n",__func__);
        pdata = &sm5701_default_fled_pdata;

        chip = kzalloc(sizeof(struct SM5701_leds_data), GFP_KERNEL);
        if (!chip)
           return -ENOMEM;

        chip->dev = &pdev->dev;
        chip->iodev = iodev;
        platform_set_drvdata(pdev, chip);
        /*
        if (!(leds_sm5701_client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL))) {
            return -ENOMEM;
        }
        memset(leds_sm5701_client, 0, sizeof(struct i2c_client));
        */
        leds_sm5701_client = chip->iodev->i2c;

        mutex_init(&chip->lock);

        if (camera_class ==NULL){
                camera_class = class_create(THIS_MODULE, "camera");
                if (IS_ERR(camera_class))
			pr_err("failed to create device cam_dev_rear!\n");
        }
        /* flash */
        INIT_WORK(&chip->work_flash, sm5701_deferred_flash_brightness_set);
        chip->cdev_flash.name = "flash";
        chip->cdev_flash.max_brightness = 32-1;//0x1f
        chip->cdev_flash.brightness_set = sm5701_flash_brightness_set;
        chip->cdev_flash.default_trigger = "flash";
        err = led_classdev_register((struct device *)
                                    chip->dev, &chip->cdev_flash);

        if (err < 0) {
                dev_err(chip->dev, "failed to register flash\n");
                goto err_create_flash_file;
        }
        err = device_create_file(chip->cdev_flash.dev, &dev_attr_flash);
        if (err < 0) {
                dev_err(chip->dev, "failed to create flash file\n");
                goto err_create_flash_pin_file;
        }

	/* movie */
	INIT_WORK(&chip->work_movie, sm5701_deferred_movie_brightness_set);
	chip->cdev_movie.name = "flash";
	chip->cdev_movie.max_brightness = 32-1;//0x1f
	chip->cdev_movie.brightness_set = sm5701_movie_brightness_set;
	chip->cdev_movie.default_trigger = "flash";

        chip->cdev_movie.dev = device_create(camera_class, NULL, 0, NULL, "flash");
        if (IS_ERR(chip->cdev_movie.dev)) {
                pr_err("flash_sysfs: failed to create device(flash)\n");
                goto err_create_movie_file;
        }
        err = device_create_file(chip->cdev_movie.dev, &dev_attr_rear_flash);
        if (err < 0) {
                dev_err(chip->dev, "failed to create movie file\n");
                goto err_create_movie_pin_file;
        }

        err = sm5701_chip_init(chip);
        if (err < 0)
                goto err_out;
    #if  defined (CONFIG_MACH_VIVALTO5MVE3G) || defined(CONFIG_MACH_VIVALTO3MVE3G_LTN)
        if (!gpio_is_valid(flash_enable_gpio))
        {
              printk("flash_enable_gpio gpio pin error");
               return 1;
        }
        gpio_request(flash_enable_gpio, "gpioFlashhigh");
        gpio_direction_output(flash_enable_gpio,0);

        if (!gpio_is_valid(flash_torch_gpio)) 
        {
              printk("flash_torch_gpio gpio pin error");
               return 1;
        }
        gpio_request(flash_torch_gpio, "gpioFlashlow");
        gpio_direction_output(flash_torch_gpio,0);
    #endif
        //sm5701_dump_register();
        pdata->fled_pinctrl = devm_pinctrl_get(&pdev->dev);
        if (IS_ERR_OR_NULL(pdata->fled_pinctrl)) {
              pr_err("%s:%d Getting pinctrl handle failed\n", __func__, __LINE__);
              return -EINVAL;
        }

        pdata->gpio_state_active = pinctrl_lookup_state(pdata->fled_pinctrl, FLED_PINCTRL_STATE_DEFAULT);
        if (IS_ERR_OR_NULL(pdata->gpio_state_active)) {
              pr_err("%s:%d Failed to get the active state pinctrl handle\n", __func__, __LINE__);
              return -EINVAL;
        }

        pdata->gpio_state_suspend = pinctrl_lookup_state(pdata->fled_pinctrl, FLED_PINCTRL_STATE_SLEEP);
        if (IS_ERR_OR_NULL(pdata->gpio_state_suspend)) {
              pr_err("%s:%d Failed to get the active state pinctrl handle\n", __func__, __LINE__);
              return -EINVAL;
        }

        err = pinctrl_select_state(pdata->fled_pinctrl, pdata->gpio_state_suspend);
        if (err) {
              pr_err("%s:%d cannot set pin to active state", __func__, __LINE__);
              return err;
        }
        pr_err("%s End : X\n", __func__);

        dev_info(chip->dev, "LEDs_SM5701 Probe Done\n");
        return 0;

err_create_movie_file:
        device_remove_file(chip->cdev_movie.dev, &dev_attr_rear_flash);
err_create_movie_pin_file:
        led_classdev_unregister(&chip->cdev_movie);
err_create_flash_file:
        device_remove_file(chip->cdev_flash.dev, &dev_attr_flash);
err_create_flash_pin_file:
        led_classdev_unregister(&chip->cdev_flash);
err_out:
        return err;
}
示例#13
0
int rmnet_usb_ctrl_init(void)
{
	struct rmnet_ctrl_dev	*dev;
	int			n;
	int			status;

	for (n = 0; n < NUM_CTRL_CHANNELS; ++n) {

		dev = kzalloc(sizeof(*dev), GFP_KERNEL);
		if (!dev) {
			status = -ENOMEM;
			goto error0;
		}
		/*for debug purpose*/
		snprintf(dev->name, CTRL_DEV_MAX_LEN, "hsicctl%d", n);

		dev->wq = create_singlethread_workqueue(dev->name);
		if (!dev->wq) {
			pr_err("unable to allocate workqueue");
			kfree(dev);
			goto error0;
		}

		mutex_init(&dev->dev_lock);
		spin_lock_init(&dev->rx_lock);
		init_waitqueue_head(&dev->read_wait_queue);
		init_waitqueue_head(&dev->open_wait_queue);
		INIT_LIST_HEAD(&dev->rx_list);
		init_usb_anchor(&dev->tx_submitted);
		init_usb_anchor(&dev->rx_submitted);
		INIT_WORK(&dev->get_encap_work, get_encap_work);

		status = rmnet_usb_ctrl_alloc_rx(dev);
		if (status < 0) {
			kfree(dev);
			goto error0;
		}

		ctrl_dev[n] = dev;
	}

	status = alloc_chrdev_region(&ctrldev_num, 0, NUM_CTRL_CHANNELS,
			DEVICE_NAME);
	if (IS_ERR_VALUE(status)) {
		pr_err("ERROR:%s: alloc_chrdev_region() ret %i.\n",
		       __func__, status);
		goto error0;
	}

	ctrldev_classp = class_create(THIS_MODULE, DEVICE_NAME);
	if (IS_ERR(ctrldev_classp)) {
		pr_err("ERROR:%s: class_create() ENOMEM\n", __func__);
		status = -ENOMEM;
		goto error1;
	}
	for (n = 0; n < NUM_CTRL_CHANNELS; ++n) {
		cdev_init(&ctrl_dev[n]->cdev, &ctrldev_fops);
		ctrl_dev[n]->cdev.owner = THIS_MODULE;

		status = cdev_add(&ctrl_dev[n]->cdev, (ctrldev_num + n), 1);

		if (IS_ERR_VALUE(status)) {
			pr_err("%s: cdev_add() ret %i\n", __func__, status);
			kfree(ctrl_dev[n]);
			goto error2;
		}

		ctrl_dev[n]->devicep =
				device_create(ctrldev_classp, NULL,
				(ctrldev_num + n), NULL,
				DEVICE_NAME "%d", n);

		if (IS_ERR(ctrl_dev[n]->devicep)) {
			pr_err("%s: device_create() ENOMEM\n", __func__);
			status = -ENOMEM;
			cdev_del(&ctrl_dev[n]->cdev);
			kfree(ctrl_dev[n]);
			goto error2;
		}
		/*create /sys/class/hsicctl/hsicctlx/modem_wait*/
		status = device_create_file(ctrl_dev[n]->devicep,
					&dev_attr_modem_wait);
		if (status) {
			device_destroy(ctrldev_classp,
				MKDEV(MAJOR(ctrldev_num), n));
			cdev_del(&ctrl_dev[n]->cdev);
			kfree(ctrl_dev[n]);
			goto error2;
		}
		dev_set_drvdata(ctrl_dev[n]->devicep, ctrl_dev[n]);
	}

	rmnet_usb_ctrl_debugfs_init();
	pr_info("rmnet usb ctrl Initialized.\n");
	return 0;

error2:
		while (--n >= 0) {
			cdev_del(&ctrl_dev[n]->cdev);
			device_destroy(ctrldev_classp,
				MKDEV(MAJOR(ctrldev_num), n));
		}

		class_destroy(ctrldev_classp);
		n = NUM_CTRL_CHANNELS;
error1:
	unregister_chrdev_region(MAJOR(ctrldev_num), NUM_CTRL_CHANNELS);
error0:
	while (--n >= 0)
		kfree(ctrl_dev[n]);

	return status;
}
/*
 * First routine called when the kernel module is loaded
 */
static int __init tf_device_register(void)
{
	int error;
	struct tf_device *dev = &g_tf_dev;

	dprintk(KERN_INFO "tf_device_register()\n");

	/*
	 * Initialize the device
	 */
	dev->dev_number = MKDEV(device_major_number,
		TF_DEVICE_MINOR_NUMBER);
	cdev_init(&dev->cdev, &g_tf_device_file_ops);
	dev->cdev.owner = THIS_MODULE;

	INIT_LIST_HEAD(&dev->connection_list);
	spin_lock_init(&dev->connection_list_lock);

#if defined(MODULE) && defined(CONFIG_TF_ZEBRA)
	error = (*tf_comm_early_init)();
	if (error)
		goto module_early_init_failed;

	error = tf_device_mshield_init(smc_mem);
	if (error)
		goto mshield_init_failed;

#ifdef CONFIG_TF_DRIVER_CRYPTO_FIPS
	error = tf_crypto_hmac_module_init();
	if (error)
		goto hmac_init_failed;

	error = tf_self_test_register_device();
	if (error)
		goto self_test_register_device_failed;
#endif
#endif

	/* register the sysfs object driver stats */
	error = kobject_init_and_add(&dev->kobj,  &tf_ktype, NULL, "%s",
		 TF_DEVICE_BASE_NAME);
	if (error) {
		printk(KERN_ERR "tf_device_register(): "
			"kobject_init_and_add failed (error %d)!\n", error);
		kobject_put(&dev->kobj);
		goto kobject_init_and_add_failed;
	}

	register_syscore_ops((struct syscore_ops *)&g_tf_syscore_ops);

	/*
	 * Register the char device.
	 */
	printk(KERN_INFO "Registering char device %s (%u:%u)\n",
		TF_DEVICE_BASE_NAME,
		MAJOR(dev->dev_number),
		MINOR(dev->dev_number));
	error = register_chrdev_region(dev->dev_number, 1,
		TF_DEVICE_BASE_NAME);
	if (error != 0) {
		printk(KERN_ERR "tf_device_register():"
			" register_chrdev_region failed (error %d)!\n",
			error);
		goto register_chrdev_region_failed;
	}

	error = cdev_add(&dev->cdev, dev->dev_number, 1);
	if (error != 0) {
		printk(KERN_ERR "tf_device_register(): "
			"cdev_add failed (error %d)!\n",
			error);
		goto cdev_add_failed;
	}

	/*
	 * Initialize the communication with the Secure World.
	 */
#ifdef CONFIG_TF_TRUSTZONE
	dev->sm.soft_int_irq = soft_interrupt;
#endif
	error = tf_init(&g_tf_dev.sm);
	if (error != S_SUCCESS) {
		dprintk(KERN_ERR "tf_device_register(): "
			"tf_init failed (error %d)!\n",
			error);
		goto init_failed;
	}

#ifdef CONFIG_TF_DRIVER_CRYPTO_FIPS
	error = tf_self_test_post_init(&(g_tf_dev.kobj));
	/* N.B. error > 0 indicates a POST failure, which will not
	   prevent the module from loading. */
	if (error < 0) {
		dprintk(KERN_ERR "tf_device_register(): "
			"tf_self_test_post_vectors failed (error %d)!\n",
			error);
		goto post_failed;
	}
#endif

#ifdef CONFIG_ANDROID
	tf_class = class_create(THIS_MODULE, TF_DEVICE_BASE_NAME);
	device_create(tf_class, NULL,
		dev->dev_number,
		NULL, TF_DEVICE_BASE_NAME);
#endif

#ifdef CONFIG_TF_ZEBRA
	/*
	 * Initializes the /dev/tf_ctrl device node.
	 */
	error = tf_ctrl_device_register();
	if (error)
		goto ctrl_failed;
#endif

#ifdef CONFIG_TF_DRIVER_DEBUG_SUPPORT
	address_cache_property((unsigned long) &tf_device_register);
#endif
	/*
	 * Successful completion.
	 */

	dprintk(KERN_INFO "tf_device_register(): Success\n");
	return 0;

	/*
	 * Error: undo all operations in the reverse order
	 */
#ifdef CONFIG_TF_ZEBRA
ctrl_failed:
#endif
#ifdef CONFIG_TF_DRIVER_CRYPTO_FIPS
	tf_self_test_post_exit();
post_failed:
#endif
init_failed:
	cdev_del(&dev->cdev);
cdev_add_failed:
	unregister_chrdev_region(dev->dev_number, 1);
register_chrdev_region_failed:
	unregister_syscore_ops((struct syscore_ops *)&g_tf_syscore_ops);
kobject_init_and_add_failed:
	kobject_del(&g_tf_dev.kobj);

#if defined(MODULE) && defined(CONFIG_TF_ZEBRA)
#ifdef CONFIG_TF_DRIVER_CRYPTO_FIPS
	tf_self_test_unregister_device();
self_test_register_device_failed:
	tf_crypto_hmac_module_exit();
hmac_init_failed:
#endif
	tf_device_mshield_exit();
mshield_init_failed:
module_early_init_failed:
#endif
	dprintk(KERN_INFO "tf_device_register(): Failure (error %d)\n",
		error);
	return error;
}
示例#15
0
文件: mephisto.c 项目: imrehg/meids
// Init and exit of module.
static int __init mephisto_init(void)
{
	int result = 0;
	dev_t dev = MKDEV(major, 0);

 	PDEBUG("executed.\n");

 	ME_INIT_LOCK(&me_lock);

	// Register usb driver. This will return 0 if the USB subsystem is not available.
	result = usb_register(&me_usb_driver);
	if (result < 0)
	{
		if(result == -ENODEV)
		{
			PERROR("No USB subsystem available.\n");
		}
		else
		{
			PERROR("Can't register usb driver.\n");
		}
		goto INIT_ERROR_1;
	}

	// Register the character device.
	if (major)
	{
		result = register_chrdev_region(dev, 1, ME_NAME_DRIVER);
	}
	else
	{
		result = alloc_chrdev_region(&dev, 0, 1, ME_NAME_DRIVER);
		major = MAJOR(dev);
	}
	if (result < 0)
	{
		PERROR("Can't get major driver no.\n");
		goto INIT_ERROR_3;
	}

	cdevp = cdev_alloc();
	if (!cdevp)
	{
		PERROR("Can't get character device structure.\n");
		result = -ENOMEM;
		goto INIT_ERROR_4;
	}

	cdevp->ops = &me_file_operations;
	cdevp->owner = THIS_MODULE;

	result = cdev_add(cdevp, dev, 1);
	if (result < 0)
	{
		PERROR("Cannot add character device structure.\n");
		goto INIT_ERROR_5;
	}

	PLOG("Loaded: %s version: 0x%08x\n", ME_NAME_DRIVER, ME_VERSION_DRIVER);

	memain_class = class_create(THIS_MODULE, ME_NAME_DRIVER);
	memain_dev = device_create(memain_class,
								NULL,
								dev,
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)
								NULL,
#endif
								ME_NAME_NODE);

	return 0;

INIT_ERROR_5:
	cdev_del(cdevp);

INIT_ERROR_4:
	unregister_chrdev_region(dev, 1);

INIT_ERROR_3:
	usb_deregister(&me_usb_driver);

INIT_ERROR_1:
	return result;
}
static int synaptics_ts_probe(
	struct i2c_client *client, const struct i2c_device_id *id)
{
	struct synaptics_ts_data *ts;
	uint8_t i2c_addr = 0x1B;
  	uint8_t buf[3], buf_tmp[3]={0,0,0};  
	uint8_t addr[1];
	int i, ret;

#if defined (CONFIG_TOUCHSCREEN_MMS128_TASSCOOPER)
        printk("[TSP][Synaptics][%s] %s\n", __func__,"Called");

        if(Is_MMS128_Connected()== 1)
        {
            printk("[TSP][Synaptics][%s] %s\n", __func__,"Melfas already detected !!");

            return -ENXIO;
        }
#endif

	printk("[TSP] %s, %d\n", __func__, __LINE__ );

	touch_ctrl_regulator(TOUCH_ON);
	msleep(100);	
	touch_ctrl_regulator(TOUCH_OFF);
	msleep(200);
	touch_ctrl_regulator(TOUCH_ON);
	msleep(100);

	ts = kzalloc(sizeof(*ts), GFP_KERNEL);
	if (ts == NULL) {
		ret = -ENOMEM;
		goto err_alloc_data_failed;
	}
	
	#if USE_THREADED_IRQ

	#else
	INIT_WORK(&ts->work, synaptics_ts_work_func);
	#endif

	ts->client = client;
	i2c_set_clientdata(client, ts);

	ts_global = ts;

	tsp_irq=client->irq;


#if defined (CONFIG_TOUCHSCREEN_MMS128_TASSCOOPER)
    ret = synaptics_ts_check();
    if (ret <= 0) {
         i2c_release_client(client);		
         touch_ctrl_regulator(TOUCH_OFF);

         ret = -ENXIO;
         goto err_input_dev_alloc_failed;
     }
#else
	/* Check point - i2c check - start */	
    //ret = tsp_i2c_read( 0x1B, buf_tmp, sizeof(buf_tmp));
    for (i = 0; i < 1; i++)
	{
		printk("[TSP] %s, %d, send\n", __func__, __LINE__ );
		addr[0] = 0x1B; //address
		ret = i2c_master_send(ts_global->client, addr, 1);

		if (ret >= 0)
		{
			printk("[TSP] %s, %d, receive\n", __func__, __LINE__ );
			ret = i2c_master_recv(ts_global->client, buf_tmp, 3);
			if (ret >= 0)
				break; // i2c success
		}

		printk("[TSP] %s, %d, fail\n", __func__, __LINE__ );
	}

	touch_vendor_id = buf_tmp[0];
	touch_hw_ver = buf_tmp[1];
	touch_sw_ver = buf_tmp[2];
	printk("[TSP] %s:%d, ver tsp=%x, HW=%x, SW=%x\n", __func__,__LINE__, touch_vendor_id, touch_hw_ver, touch_sw_ver);
#endif

	HW_ver = touch_hw_ver;

	if (ret <= 0) {
		printk("[TSP] %s, ln:%d, Failed to register TSP!!!\n\tcheck the i2c line!!!, ret=%d\n", __func__,__LINE__, ret);
		goto err_check_functionality_failed;
	}
	/* Check point - i2c check - end */


	ts->input_dev = input_allocate_device();
	if (ts->input_dev == NULL) {
		ret = -ENOMEM;
		printk(KERN_ERR "synaptics_ts_probe: Failed to allocate input device\n");
		goto err_input_dev_alloc_failed;
	}
	ts->input_dev->name = "synaptics-rmi-touchscreen";

	ts->input_dev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
	ts->input_dev->keybit[BIT_WORD(KEY_POWER)] |= BIT_MASK(KEY_POWER);
	

	set_bit(BTN_TOUCH, ts->input_dev->keybit);
	set_bit(EV_ABS, ts->input_dev->evbit);
	ts->input_dev->evbit[0] =  BIT_MASK(EV_SYN) | BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);	


	input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, MAX_X, 0, 0);
	input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, MAX_Y, 0, 0);
	input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
	input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
    
	set_bit(EV_SYN, ts->input_dev->evbit);
	set_bit(EV_KEY, ts->input_dev->evbit);
    
	/* ts->input_dev->name = ts->keypad_info->name; */
	ret = input_register_device(ts->input_dev);
	if (ret) {
		printk(KERN_ERR "synaptics_ts_probe: Unable to register %s input device\n", ts->input_dev->name);
		goto err_input_register_device_failed;
	}

    	printk("[TSP] %s, irq=%d\n", __func__, client->irq );

    if (client->irq) {
		#if USE_THREADED_IRQ
		ret = request_threaded_irq(client->irq, synaptics_ts_irq_handler, synaptics_ts_work_func, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, client->name, ts);
		#else		
		ret = request_irq(client->irq, synaptics_ts_irq_handler, IRQF_TRIGGER_FALLING, client->name, ts);
		#endif
		
		if (ret == 0)
			ts->use_irq = 1;
		else
			dev_err(&client->dev, "request_irq failed\n");
	}

	if (!ts->use_irq) {
		hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
		ts->timer.function = synaptics_ts_timer_func;
		hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
	}
#if 1
#ifdef CONFIG_HAS_EARLYSUSPEND
	ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
	ts->early_suspend.suspend = synaptics_ts_early_suspend;
	ts->early_suspend.resume = synaptics_ts_late_resume;
	register_early_suspend(&ts->early_suspend);
#endif
#endif
	printk(KERN_INFO "synaptics_ts_probe: Start touchscreen %s in %s mode\n", ts->input_dev->name, ts->use_irq ? "interrupt" : "polling");

	/* sys fs */
	touch_class = class_create(THIS_MODULE, "touch");
	if (IS_ERR(touch_class))
		pr_err("Failed to create class(touch)!\n");

	firmware_dev = device_create(touch_class, NULL, 0, NULL, "firmware");
	if (IS_ERR(firmware_dev))
		pr_err("Failed to create device(firmware)!\n");

	if (device_create_file(firmware_dev, &dev_attr_firmware) < 0)
		pr_err("Failed to create device file(%s)!\n", dev_attr_firmware.attr.name);
	if (device_create_file(firmware_dev, &dev_attr_firmware_ret) < 0)
		pr_err("Failed to create device file(%s)!\n", dev_attr_firmware_ret.attr.name);

	/* sys fs */
    

#if 0
	if(buf_tmp[0]<HEX_HW_VER){	//Firmware Update
		firm_update();
	}else if((buf_tmp[1]<HEX_SW_VER)||((buf_tmp[1]&0xF0)==0xF0)||(buf_tmp[1]==0)){
		printk("[TSP] firm_update START!!, ln=%d\n",__LINE__);
		firm_update();
	}else{
		printk("[TSP] Firmware Version is Up-to-date.\n");
	}
#endif


	return 0;

err_input_register_device_failed:
	input_free_device(ts->input_dev);

err_input_dev_alloc_failed:
	kfree(ts);
err_alloc_data_failed:
err_check_functionality_failed:
	return ret;
}
示例#17
0
文件: pcmcom8.c 项目: ncareol/nidas
static int __init pcmcom8_init_module(void)
{
        int result, ib,itmp;
        dev_t devno;

        KLOG_NOTICE("version: %s\n", REPO_REVISION);

        for (ib = 0; ib < PCMCOM8_MAX_NR_DEVS; ib++)
          if (ioports[ib] == 0) break;
        pcmcom8_numboards = ib;
        KLOG_DEBUG("numboards=%d\n",pcmcom8_numboards);

        /*
         * Register your major, and accept a dynamic number. This is the
         * first thing to do, in order to avoid releasing other module's
         * fops in pcmcom8_cleanup_module()
         */
        result = alloc_chrdev_region(&pcmcom8_device, 0,
            pcmcom8_numboards,DRIVER_NAME);
        if (result < 0) goto fail;

        /*
         * allocate the board structures
         */
        pcmcom8_boards = kmalloc(pcmcom8_numboards * sizeof(pcmcom8_board), GFP_KERNEL);
        if (!pcmcom8_boards) {
                result = -ENOMEM;
                goto fail;
        }
        memset(pcmcom8_boards, 0, pcmcom8_numboards * sizeof(pcmcom8_board));

        pcmcom8_class = class_create(THIS_MODULE, DRIVER_NAME);
        if (IS_ERR(pcmcom8_class)) {
                result = PTR_ERR(pcmcom8_class);
                goto fail;
        }

        for (ib = 0; ib < pcmcom8_numboards; ib++) {
                pcmcom8_board* brd = pcmcom8_boards + ib;
                if (!request_region(ioports[ib],PCMCOM8_IO_REGION_SIZE,DRIVER_NAME)) {
                    result = -ENODEV;
                    goto fail;
                }
                brd->ioport = ioports[ib];
                brd->addr = brd->ioport + ioport_base;
                brd->region_req = 1;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
                mutex_init(&brd->mutex);
#else
                init_MUTEX(&brd->mutex);
#endif
                /*
                 * Read EEPROM configuration. If it doesn't return
                 * -ETIMEDOUT then it looks like there is a board at
                 * the given address.
                 */
                if (!pcmcom8_read_eeconfig(brd,&brd->config,0)) {
                        pcmcom8_nr_ok = ib + 1;
                        itmp = pcmcom8_check_config(&brd->config);
                        KLOG_INFO("EEPROM config for board %d,ioport %#x=%s\n",
                            ib,brd->ioport,(itmp ? "OK":"looks invalid"));
                }
                else {
                        release_region(brd->ioport, PCMCOM8_IO_REGION_SIZE);
                        brd->ioport = 0;
                        brd->region_req = 0;
                        break;
                }

                cdev_init(&brd->cdev,&pcmcom8_fops);
                brd->cdev.owner = THIS_MODULE;
                devno = MKDEV(MAJOR(pcmcom8_device),ib);
                // after calling cdev_add the device is ready for operations
                result = cdev_add(&brd->cdev,devno,1);
                if (result) goto fail;

                brd->device = device_create_x(pcmcom8_class, NULL,
                         devno, DRIVER_NAME "_%d", ib);
                if (IS_ERR(brd->device)) {
                        result = PTR_ERR(brd->device);
                        goto fail;
                }

        }
        if (pcmcom8_nr_ok == 0) {
                result = -ENODEV;
                goto fail;
        }
  
#ifdef DEBUG /* only when debugging */
        KLOG_DEBUG("create_proc\n");
        pcmcom8_create_proc();
#endif
        return result; /* succeed */

fail:
        pcmcom8_cleanup_module();
        return result;
}
static int ltr558_probe(struct i2c_client *client,
	const struct i2c_device_id *id)
{
    int ret = 0;
	  struct ltr558_info *lpi;
	  struct ltr558_platform_data *pdata;

	  D("[ltr558] %s\n", __func__);


	  lpi = kzalloc(sizeof(struct ltr558_info), GFP_KERNEL);
	  if (!lpi)
        return -ENOMEM;

	/*D("[ltr558] %s: client->irq = %d\n", __func__, client->irq);*/

	  lpi->i2c_client = client;
	  pdata = client->dev.platform_data;
	  if (!pdata) {
		    pr_err("[ltr558 error]%s: Assign platform_data error!!\n",__func__);
		    ret = -EBUSY;
		    goto err_platform_data_null;
	  }
    /*start to declare regulator and enable power*/
    lpi->ls_regulator = regulator_get(NULL, "hcldo1_3v3");
	  if (!lpi->ls_regulator || IS_ERR(lpi->ls_regulator)) {
		    printk(KERN_ERR "ltr558 No Regulator available\n");
		    ret = -EFAULT;
		    goto err_platform_data_null;
	  }
    
    if(lpi->ls_regulator){
            regulator_set_voltage(lpi->ls_regulator,3300000,3300000);
            regulator_enable(lpi->ls_regulator);/*enable power*/
    }
//[email protected] 2011.12.21 begin
//check device ID
      uint8_t device_id = 0;
	  ret = ltr558_i2c_read(LTR558_MANUFACTURER_ID,&device_id);
	  if((device_id == 0x05)||(!ret))
	  {
	  	   printk("=====ltr558 device found!!====\n");
	  }
	  else
	  {
	 	   printk("ltr558 device no found error!! id = %x\n",device_id);
		   goto err_platform_data_null;
	  }
	  
//[email protected] 2011.12.21 end


	  lpi->irq = client->irq;
	  i2c_set_clientdata(client, lpi);
          //ltr558_devinit();
         // if (ret) {
          //      printk("ltr558 device init failed.\n");
          
          //}
          pdata->init();/*init sensor gpio interrupt pin*/

	  lp_info = lpi;

	  mutex_init(&als_enable_mutex);
	  mutex_init(&als_disable_mutex);
	  mutex_init(&als_get_adc_mutex);

	  ret = lightsensor_setup(lpi);
	  if (ret < 0) {
		    pr_err("[ltr558 error]%s: lightsensor_setup error!!\n",__func__);
		    goto err_lightsensor_setup;
	  }

	  ret = psensor_setup(lpi);
	  if (ret < 0) {
		    pr_err("[ltr558 error]%s: psensor_setup error!!\n",__func__);
		    goto err_psensor_setup;
	  }

	  lpi->lp_wq = create_singlethread_workqueue("ltr558_wq");
	  if (!lpi->lp_wq) {
		    pr_err("[ltr558 error]%s: can't create workqueue\n", __func__);
		    ret = -ENOMEM;
		    goto err_create_singlethread_workqueue;
	  }

	  wake_lock_init(&(lpi->ps_wake_lock), WAKE_LOCK_SUSPEND, "proximity");


	 ret = ltr558_setup(lpi);
	 if (ret < 0) {
		   pr_err("[ltr558 error]%s: ltr558_setup error!\n", __func__);
		   goto err_ltr558_setup;
	 }

    lpi->ltr558_class = class_create(THIS_MODULE, "optical_sensors");
    if (IS_ERR(lpi->ltr558_class)) {
        ret = PTR_ERR(lpi->ltr558_class);
        lpi->ltr558_class = NULL;
        goto err_create_class;
    }
    lpi->ls_dev = device_create(lpi->ltr558_class,
                NULL, 0, "%s", "lightsensor");
    if (unlikely(IS_ERR(lpi->ls_dev))) {
        ret = PTR_ERR(lpi->ls_dev);
        lpi->ls_dev = NULL;
        goto err_create_ls_device;
    }

    /* register the attributes */
    ret = device_create_file(lpi->ls_dev, &dev_attr_als_enable);
    if (ret)
        goto err_create_ls_device_file;

    lpi->ps_dev = device_create(lpi->ltr558_class,
                NULL, 0, "%s", "proximity");
    if (unlikely(IS_ERR(lpi->ps_dev))) {
        ret = PTR_ERR(lpi->ps_dev);
        lpi->ps_dev = NULL;
        goto err_create_ps_device;
    }

    /* register the attributes */
    ret = device_create_file(lpi->ps_dev, &dev_attr_ps_enable);
    if (ret)
        goto err_create_ps_device_file1;

    /* register the attributes */

    lpi->early_suspend.level =
			EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
	  lpi->early_suspend.suspend = ltr558_early_suspend;
	  lpi->early_suspend.resume = ltr558_late_resume;
	  register_early_suspend(&lpi->early_suspend);

    lpi->als_enable = 1;
    lpi->ps_enable = 1;
    lpi->ps_irq_flag = 0;
    ltr558_devinit();

	  D("[ltr558] %s: Probe success!\n", __func__);
	  printk("[ltr558] Probe and setup success!\n");

	 return ret;

err_create_ps_device_file1:
	  device_unregister(lpi->ps_dev);
err_create_ps_device:
    device_remove_file(lpi->ls_dev, &dev_attr_als_enable);
err_create_ls_device_file:
	  device_unregister(lpi->ls_dev);
err_create_ls_device:
	  class_destroy(lpi->ltr558_class);
err_create_class:
err_ltr558_setup:
	  wake_lock_destroy(&(lpi->ps_wake_lock));
	  destroy_workqueue(lpi->lp_wq);
err_create_singlethread_workqueue:
    free_irq(lpi->irq, lpi);
	  input_unregister_device(lpi->ps_input_dev);
	  input_free_device(lpi->ps_input_dev);
	  misc_deregister(&ltr558_psensor_misc);
err_psensor_setup:
    regulator_disable(lpi->ls_regulator);/*disable power*/
	  input_unregister_device(lpi->ls_input_dev);
	  input_free_device(lpi->ls_input_dev);
	  misc_deregister(&lightsensor_misc);
err_lightsensor_setup:
	  mutex_destroy(&als_enable_mutex);
	  mutex_destroy(&als_disable_mutex);
	  mutex_destroy(&als_get_adc_mutex);
    pdata->exit(NULL); /* free gpio request */
    err_platform_data_null:
	  kfree(lpi);
	  return ret;
}
示例#19
0
static int __devinit dsps_probe(struct platform_device *pdev)
{
	int ret;

	pr_debug("%s.\n", __func__);

	if (pdev->dev.platform_data == NULL) {
		pr_err("%s: platform data is NULL.\n", __func__);
		return -ENODEV;
	}

	drv = kzalloc(sizeof(*drv), GFP_KERNEL);
	if (drv == NULL) {
		pr_err("%s: kzalloc fail.\n", __func__);
		goto alloc_err;
	}
	drv->pdata = pdev->dev.platform_data;

	drv->dev_class = class_create(THIS_MODULE, DRV_NAME);
	if (drv->dev_class == NULL) {
		pr_err("%s: class_create fail.\n", __func__);
		goto res_err;
	}

	ret = alloc_chrdev_region(&drv->dev_num, 0, 1, DRV_NAME);
	if (ret) {
		pr_err("%s: alloc_chrdev_region fail.\n", __func__);
		goto alloc_chrdev_region_err;
	}

	drv->dev = device_create(drv->dev_class, NULL,
				     drv->dev_num,
				     drv, DRV_NAME);
	if (IS_ERR(drv->dev)) {
		pr_err("%s: device_create fail.\n", __func__);
		goto device_create_err;
	}

	drv->cdev = cdev_alloc();
	if (drv->cdev == NULL) {
		pr_err("%s: cdev_alloc fail.\n", __func__);
		goto cdev_alloc_err;
	}
	cdev_init(drv->cdev, &dsps_fops);
	drv->cdev->owner = THIS_MODULE;

	ret = cdev_add(drv->cdev, drv->dev_num, 1);
	if (ret) {
		pr_err("%s: cdev_add fail.\n", __func__);
		goto cdev_add_err;
	}

	ret = dsps_alloc_resources(pdev);
	if (ret) {
		pr_err("%s: failed to allocate dsps resources.\n", __func__);
		goto cdev_add_err;
	}

	return 0;

cdev_add_err:
	kfree(drv->cdev);
cdev_alloc_err:
	device_destroy(drv->dev_class, drv->dev_num);
device_create_err:
	unregister_chrdev_region(drv->dev_num, 1);
alloc_chrdev_region_err:
	class_destroy(drv->dev_class);
res_err:
	kfree(drv);
	drv = NULL;
alloc_err:
	return -ENODEV;
}
示例#20
0
/** @brief The LKM initialization function
 *  The static keyword restricts the visibility of the function to within this C file. The __init
 *  macro means that for a built-in driver (not a LKM) the function is only used at initialization
 *  time and that it can be discarded and its memory freed up after that point.
 *  @return returns 0 if successful
 */
static int __init sysmon_init(void)
{
    int TOTAL_CARDS = 0, card = 0;
    char cardsBuffer[2];
    struct file *f = file_open(totalCardsPath, O_RDONLY, 0);

    printk(KERN_INFO "SysMon: Initializing the SYSMON LKM\n");
 
    if (f == NULL)
    {
        printk(KERN_ERR "can't find total cards count file.");
        return -1;
    }
    else
    {
        cardsBuffer[1] = '\0';
        file_read(f, cardsBuffer);
        TOTAL_CARDS = cardsBuffer[0] - '0';
        filp_close(f, NULL);
        
        for(card = 0; card < TOTAL_CARDS; ++card)
        {
            char cardAsString[2];
            char * totalEnginesPath = kmalloc((strlen(basePath) + 15) * sizeof(char), GFP_KERNEL);
            int enginesOnThisCard;
            strcpy(totalEnginesPath, basePath);
            
            cardAsString[0] = '0' + card;
            cardAsString[1] = '\0';
            strcat(totalEnginesPath, cardAsString);
            strcat(totalEnginesPath, "/engn_count");
            f = file_open(totalEnginesPath, O_RDONLY, 0);
            if(f == NULL)
            {
                printk(KERN_ERR "cound not find total engines on card %d.", card);
                return -1;
            }
            else
            {
                char enginesBuffer[2];
                file_read(f, enginesBuffer);
                enginesOnThisCard = enginesBuffer[0] - '0';
                TOTAL_ENGINES += enginesOnThisCard;
            }
        }
        firstFlipOnEngines = (bool *)kmalloc(TOTAL_ENGINES * sizeof(bool), GFP_KERNEL);
        lastFlipTime = (unsigned long long *) kmalloc(TOTAL_ENGINES * sizeof(unsigned long), GFP_KERNEL);
    }
 
    // Try to dynamically allocate a major number for the device -- more difficult but worth it
    majorNumber = register_chrdev(0, DEVICE_NAME, &fops);
    if (majorNumber<0)
    {
        printk(KERN_ALERT "SYSMON failed to register a major number\n");
        return majorNumber;
    }
    printk(KERN_INFO "SYSMON: registered correctly with major number %d\n", majorNumber);
 
    // Register the device class
    SYSMONClass = class_create(THIS_MODULE, CLASS_NAME);
    if (IS_ERR(SYSMONClass)) // Check for error and clean up if there is
    {                
        unregister_chrdev(majorNumber, DEVICE_NAME);
        printk(KERN_ALERT "Failed to register device class\n");
        return PTR_ERR(SYSMONClass);          // Correct way to return an error on a pointer
    }
    printk(KERN_INFO "SYSMON: device class registered correctly\n");
 
    // Register the device driver
    SYSMONDevice = device_create(SYSMONClass, NULL, MKDEV(majorNumber, 0), NULL, DEVICE_NAME);
    if (IS_ERR(SYSMONDevice))               // Clean up if there is an error
    {
         class_destroy(SYSMONClass);           // Repeated code but the alternative is goto statements
         unregister_chrdev(majorNumber, DEVICE_NAME);
         printk(KERN_ALERT "Failed to create the device\n");
         return PTR_ERR(SYSMONDevice);
    }
 
    printk(KERN_INFO "SYSMON: device class created correctly\n"); // Made it! device was initialized
 
    return 0;
}
示例#21
0
static int __init vme_user_probe(struct device *dev, int cur_bus, int cur_slot)
{
	int i, err;
	char name[12];

	/* Save pointer to the bridge device */
	if (vme_user_bridge != NULL) {
		printk(KERN_ERR "%s: Driver can only be loaded for 1 device\n",
			driver_name);
		err = -EINVAL;
		goto err_dev;
	}
	vme_user_bridge = dev;

	/* Initialise descriptors */
	for (i = 0; i < VME_DEVS; i++) {
		image[i].kern_buf = NULL;
		image[i].pci_buf = 0;
		init_MUTEX(&(image[i].sem));
		image[i].device = NULL;
		image[i].resource = NULL;
		image[i].users = 0;
	}

	/* Initialise statistics counters */
	reset_counters();

	/* Assign major and minor numbers for the driver */
	err = register_chrdev_region(MKDEV(VME_MAJOR, 0), VME_DEVS,
		driver_name);
	if (err) {
		printk(KERN_WARNING "%s: Error getting Major Number %d for "
		"driver.\n", driver_name, VME_MAJOR);
		goto err_region;
	}

	/* Register the driver as a char device */
	vme_user_cdev = cdev_alloc();
	vme_user_cdev->ops = &vme_user_fops;
	vme_user_cdev->owner = THIS_MODULE;
	err = cdev_add(vme_user_cdev, MKDEV(VME_MAJOR, 0), VME_DEVS);
	if (err) {
		printk(KERN_WARNING "%s: cdev_all failed\n", driver_name);
		goto err_char;
	}

	/* Request slave resources and allocate buffers (128kB wide) */
	for (i = SLAVE_MINOR; i < (SLAVE_MAX + 1); i++) {
		/* XXX Need to properly request attributes */
		/* For ca91cx42 bridge there are only two slave windows
		 * supporting A16 addressing, so we request A24 supported
		 * by all windows.
		 */
		image[i].resource = vme_slave_request(vme_user_bridge,
			VME_A24, VME_SCT);
		if (image[i].resource == NULL) {
			printk(KERN_WARNING "Unable to allocate slave "
				"resource\n");
			goto err_slave;
		}
		image[i].size_buf = PCI_BUF_SIZE;
		image[i].kern_buf = vme_alloc_consistent(image[i].resource,
			image[i].size_buf, &(image[i].pci_buf));
		if (image[i].kern_buf == NULL) {
			printk(KERN_WARNING "Unable to allocate memory for "
				"buffer\n");
			image[i].pci_buf = 0;
			vme_slave_free(image[i].resource);
			err = -ENOMEM;
			goto err_slave;
		}
	}

	/*
	 * Request master resources allocate page sized buffers for small
	 * reads and writes
	 */
	for (i = MASTER_MINOR; i < (MASTER_MAX + 1); i++) {
		/* XXX Need to properly request attributes */
		image[i].resource = vme_master_request(vme_user_bridge,
			VME_A32, VME_SCT, VME_D32);
		if (image[i].resource == NULL) {
			printk(KERN_WARNING "Unable to allocate master "
				"resource\n");
			goto err_master;
		}
		image[i].size_buf = PCI_BUF_SIZE;
		image[i].kern_buf = kmalloc(image[i].size_buf, GFP_KERNEL);
		if (image[i].kern_buf == NULL) {
			printk(KERN_WARNING "Unable to allocate memory for "
				"master window buffers\n");
			err = -ENOMEM;
			goto err_master_buf;
		}
	}

	/* Create sysfs entries - on udev systems this creates the dev files */
	vme_user_sysfs_class = class_create(THIS_MODULE, driver_name);
	if (IS_ERR(vme_user_sysfs_class)) {
		printk(KERN_ERR "Error creating vme_user class.\n");
		err = PTR_ERR(vme_user_sysfs_class);
		goto err_class;
	}

	/* Add sysfs Entries */
	for (i=0; i<VME_DEVS; i++) {
		switch (type[i]) {
		case MASTER_MINOR:
			sprintf(name,"bus/vme/m%%d");
			break;
		case CONTROL_MINOR:
			sprintf(name,"bus/vme/ctl");
			break;
		case SLAVE_MINOR:
			sprintf(name,"bus/vme/s%%d");
			break;
		default:
			err = -EINVAL;
			goto err_sysfs;
			break;
		}

		image[i].device =
			device_create(vme_user_sysfs_class, NULL,
				MKDEV(VME_MAJOR, i), NULL, name,
				(type[i] == SLAVE_MINOR)? i - (MASTER_MAX + 1) : i);
		if (IS_ERR(image[i].device)) {
			printk("%s: Error creating sysfs device\n",
				driver_name);
			err = PTR_ERR(image[i].device);
			goto err_sysfs;
		}
	}

	return 0;

	/* Ensure counter set correcty to destroy all sysfs devices */
	i = VME_DEVS;
err_sysfs:
	while (i > 0){
		i--;
		device_destroy(vme_user_sysfs_class, MKDEV(VME_MAJOR, i));
	}
	class_destroy(vme_user_sysfs_class);

	/* Ensure counter set correcty to unalloc all master windows */
	i = MASTER_MAX + 1;
err_master_buf:
	for (i = MASTER_MINOR; i < (MASTER_MAX + 1); i++)
		kfree(image[i].kern_buf);
err_master:
	while (i > MASTER_MINOR) {
		i--;
		vme_master_free(image[i].resource);
	}

	/*
	 * Ensure counter set correcty to unalloc all slave windows and buffers
	 */
	i = SLAVE_MAX + 1;
err_slave:
	while (i > SLAVE_MINOR) {
		i--;
		vme_slave_free(image[i].resource);
		buf_unalloc(i);
	}
err_class:
	cdev_del(vme_user_cdev);
err_char:
	unregister_chrdev_region(MKDEV(VME_MAJOR, 0), VME_DEVS);
err_region:
err_dev:
	return err;
}
示例#22
0
static int sii9244_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	struct sii9244_state *state;

	struct class *mhl_class;
	struct device *mhl_dev;
	//int ret;
	
       SII_DEV_DBG("");
	   
	state = kzalloc(sizeof(struct sii9244_state), GFP_KERNEL);
	if (state == NULL) {		
	
		MHL_DEV_INFO("failed to allocate memory \n");
	
		return -ENOMEM;
	}
	
	state->client = client;
	i2c_set_clientdata(client, state);
	
	/* rest of the initialisation goes here. */
	
	MHL_DEV_INFO("sii9244 attach success!!!\n");
	
	sii9244_i2c_client = client;

	MHL_i2c_init = 1;

	mhl_class = class_create(THIS_MODULE, "mhl");
	if (IS_ERR(mhl_class))
	{
		pr_err("Failed to create class(mhl)!\n");
	}

	mhl_dev = device_create(mhl_class, NULL, 0, NULL, "mhl_dev");
	if (IS_ERR(mhl_dev))
	{
		pr_err("Failed to create device(mhl_dev)!\n");
	}

	if (device_create_file(mhl_dev, &dev_attr_MHD_file) < 0){
		
		MHL_DEV_INFO("Failed to create device file(%s)!\n", dev_attr_MHD_file.attr.name);
	
	}
	mhl_detect_work_queue = create_singlethread_workqueue("mhl_detect_work_queue");
		if( mhl_detect_work_queue == NULL)    {																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																	  
		  pr_err(KERN_ERR "[SKY_MHL]+%s mhl_detect_work_queue is NULL \n", __FUNCTION__);
	}

	mhl_ctrl_connect_work_queue = create_singlethread_workqueue("mhl_ctrl_connect_work_queue");
	 if( mhl_ctrl_connect_work_queue == NULL)	{																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																	   
       pr_err(KERN_ERR "[SKY_MHL]+%s mhl_ctrl_connect_work_queue is NULL \n", __FUNCTION__);
 }
	
	INIT_DELAYED_WORK_DEFERRABLE(&mhl_ctrl_connect_work, mhl_cable_connect_ctrl);
	INIT_DELAYED_WORK_DEFERRABLE(&mhl_detect_work, is_mhl_cable);	
	INIT_DELAYED_WORK_DEFERRABLE(&mhl_detect_again_work, handle_pm_irq_again);	
	INIT_DELAYED_WORK_DEFERRABLE(&mhl_boot_work, handle_mhl_at_boot);
		//xsemiyas_debug
	if (device_create_file(mhl_dev, &dev_attr_hdmid_ready) < 0){

		MHL_DEV_INFO("Failed to create device file(%s)!\n", dev_attr_hdmid_ready.attr.name);

	}
	return 0;

}
static int msm_rng_probe(struct platform_device *pdev)
{
	struct resource *res;
	struct msm_rng_device *msm_rng_dev = NULL;
	void __iomem *base = NULL;
	int error = 0;
	int ret = 0;
	struct device *dev;

	struct msm_bus_scale_pdata *qrng_platform_support = NULL;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL) {
		dev_err(&pdev->dev, "invalid address\n");
		error = -EFAULT;
		goto err_exit;
	}

	msm_rng_dev = kzalloc(sizeof(msm_rng_dev), GFP_KERNEL);
	if (!msm_rng_dev) {
		dev_err(&pdev->dev, "cannot allocate memory\n");
		error = -ENOMEM;
		goto err_exit;
	}

	base = ioremap(res->start, resource_size(res));
	if (!base) {
		dev_err(&pdev->dev, "ioremap failed\n");
		error = -ENOMEM;
		goto err_iomap;
	}
	msm_rng_dev->base = base;

	/* create a handle for clock control */
	if ((pdev->dev.of_node) && (of_property_read_bool(pdev->dev.of_node,
					"qcom,msm-rng-iface-clk")))
		msm_rng_dev->prng_clk = clk_get(&pdev->dev,
							"iface_clk");
	else
		msm_rng_dev->prng_clk = clk_get(&pdev->dev, "core_clk");
	if (IS_ERR(msm_rng_dev->prng_clk)) {
		dev_err(&pdev->dev, "failed to register clock source\n");
		error = -EPERM;
		goto err_clk_get;
	}

	/* save away pdev and register driver data */
	msm_rng_dev->pdev = pdev;
	platform_set_drvdata(pdev, msm_rng_dev);

	if (pdev->dev.of_node) {
		/* Register bus client */
		qrng_platform_support = msm_bus_cl_get_pdata(pdev);
		msm_rng_dev->qrng_perf_client = msm_bus_scale_register_client(
						qrng_platform_support);
		msm_rng_device_info.qrng_perf_client =
					msm_rng_dev->qrng_perf_client;
		if (!msm_rng_dev->qrng_perf_client)
			pr_err("Unable to register bus client\n");
	}

	/* Enable rng h/w */
	error = msm_rng_enable_hw(msm_rng_dev);

	if (error)
		goto rollback_clk;

	/* register with hwrng framework */
	msm_rng.priv = (unsigned long) msm_rng_dev;
	error = hwrng_register(&msm_rng);
	if (error) {
		dev_err(&pdev->dev, "failed to register hwrng\n");
		error = -EPERM;
		goto rollback_clk;
	}
	ret = register_chrdev(QRNG_IOC_MAGIC, DRIVER_NAME, &msm_rng_fops);

	msm_rng_class = class_create(THIS_MODULE, "msm-rng");
	if (IS_ERR(msm_rng_class)) {
		pr_err("class_create failed\n");
		return PTR_ERR(msm_rng_class);
	}

	dev = device_create(msm_rng_class, NULL, MKDEV(QRNG_IOC_MAGIC, 0),
				NULL, "msm-rng");
	if (IS_ERR(dev)) {
		pr_err("Device create failed\n");
		error = PTR_ERR(dev);
		goto unregister_chrdev;
	}
	cdev_init(&msm_rng_cdev, &msm_rng_fops);

	return ret;

unregister_chrdev:
	unregister_chrdev(QRNG_IOC_MAGIC, DRIVER_NAME);
rollback_clk:
	clk_put(msm_rng_dev->prng_clk);
err_clk_get:
	iounmap(msm_rng_dev->base);
err_iomap:
	kfree(msm_rng_dev);
err_exit:
	return error;
}
static int __devinit msm_serial_hsl_probe_irda(struct platform_device *pdev)
{
	struct msm_hsl_port *msm_hsl_port;
	struct resource *uart_resource;
	struct resource *gsbi_resource;
	struct uart_port *port;
	const struct of_device_id *match;
	struct irda_platform_data *pdata;
	int ret;

	if (pdev->id == -1)
		pdev->id = atomic_inc_return(&msm_serial_hsl_next_id) - 1;

	if (unlikely(pdev->id < 0 || pdev->id >= UART_NR))
		return -ENXIO;

	printk(KERN_INFO "msm_serial_irda: detected port #%d\n", pdev->id);

	port = get_port_from_line(pdev->id);
	port->dev = &pdev->dev;
	pdata = pdev->dev.platform_data;
	if (!pdata) {
		E("[irdaerror]%s: Assign platform_data error!!\n",
			__func__);
		return -ENXIO;
	}
	msm_hsl_port = UART_TO_MSM(port);
	msm_hsl_port->irda_enable= pdata->irda_enable;
	htc_irda_port = msm_hsl_port;

	match = of_match_device(msm_hsl_match_table, &pdev->dev);
	if (!match)
		msm_hsl_port->ver_id = UARTDM_VERSION_11_13;
	else {
		D("%s () match:port->line %d, ir\n", __func__, port->line);
		msm_hsl_port->ver_id = (unsigned int)match->data;
	}

	gsbi_resource =	platform_get_resource_byname(pdev,
						     IORESOURCE_MEM,
						     "gsbi_resource");
	if (!gsbi_resource) {
		gsbi_resource = platform_get_resource(pdev, IORESOURCE_MEM, 1);
		D("%s () gsbi_resourc:port->line %d, ir\n", __func__, port->line);
	}
	msm_hsl_port->clk = clk_get(&pdev->dev, "core_clk");
	if (gsbi_resource) {
printk(KERN_INFO "msm_serial_irda: get gsbi_uart_clk and gsbi_pclk\n");
		msm_hsl_port->is_uartdm = 1;
		msm_hsl_port->pclk = clk_get(&pdev->dev, "iface_clk");
	} else {
printk(KERN_INFO "msm_serial_irda: get uartdm_clk\n");
		msm_hsl_port->is_uartdm = 0;
		msm_hsl_port->pclk = NULL;
	}

	if (unlikely(IS_ERR(msm_hsl_port->clk))) {
		printk(KERN_ERR "%s: Error getting clk\n", __func__);
		return PTR_ERR(msm_hsl_port->clk);
	}
	if (unlikely(IS_ERR(msm_hsl_port->pclk))) {
		printk(KERN_ERR "%s: Error getting pclk\n", __func__);
		return PTR_ERR(msm_hsl_port->pclk);
	}

	uart_resource = platform_get_resource_byname(pdev,
						     IORESOURCE_MEM,
						     "uartdm_resource");
	if (!uart_resource)
		uart_resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (unlikely(!uart_resource)) {
		printk(KERN_ERR "getting uartdm_resource failed\n");
		return -ENXIO;
	}
	port->mapbase = uart_resource->start;
printk(KERN_INFO "msm_serial_hsl: port[%d] mapbase:%x\n", port->line, port->mapbase);

	port->irq = platform_get_irq(pdev, 0);
	if (unlikely((int)port->irq < 0)) {
		printk(KERN_ERR "%s: getting irq failed\n", __func__);
		return -ENXIO;
	}

	device_set_wakeup_capable(&pdev->dev, 1);
	platform_set_drvdata(pdev, port);
	pm_runtime_enable(port->dev);
#ifdef CONFIG_SERIAL_MSM_HSL_CONSOLE
	ret = device_create_file(&pdev->dev, &dev_attr_console);
	D("%s () device_create_file, port->line %d, ir\n", __func__, port->line);
	if (unlikely(ret))
		E("%s():Can't create console attribute\n", __func__);
#endif
	msm_hsl_debugfs_init(msm_hsl_port, pdev->id);

	/* Temporarily increase the refcount on the GSBI clock to avoid a race
	 * condition with the earlyprintk handover mechanism.
	 */
	if (msm_hsl_port->pclk) {
		clk_prepare_enable(msm_hsl_port->pclk);
		D("%s () clk_enable, port->line %d, ir\n", __func__, port->line);
	}
	ret = uart_add_one_port(&msm_hsl_uart_driver, port);
	if (msm_hsl_port->pclk) {
		D("%s () clk_disabl, port->line %d, ir\n", __func__, port->line);
		clk_disable_unprepare(msm_hsl_port->pclk);
	}

	D("%s ():port->line %d, ir\n", __func__, port->line);
		msm_hsl_port->irda_class = class_create(THIS_MODULE, "htc_irda");
	if (IS_ERR(msm_hsl_port->irda_class)) {
		ret = PTR_ERR(msm_hsl_port->irda_class);
		msm_hsl_port->irda_class = NULL;
		return -ENXIO;
	}
	msm_hsl_port->irda_dev = device_create(msm_hsl_port->irda_class,
				NULL, 0, "%s", "irda");
	if (unlikely(IS_ERR(msm_hsl_port->irda_dev))) {
		ret = PTR_ERR(msm_hsl_port->irda_dev);
		msm_hsl_port->irda_dev = NULL;
		goto err_create_ls_device;
	}
		/* register the attributes */
	ret = device_create_file(msm_hsl_port->irda_dev, &dev_attr_enable_irda);
	if (ret)
		goto err_create_ls_device_file;

	msm_hsl_write(port, 3, UARTDM_IRDA_ADDR);
	enable_irda(0);/*0 disable, 3=enable, 9=loopback*/
	return ret;

err_create_ls_device_file:
	device_unregister(msm_hsl_port->irda_dev);
err_create_ls_device:
	class_destroy(msm_hsl_port->irda_class);
	return ret;
	return ret;
}
示例#25
0
int init_module(void)
{
struct path p;
int i;
struct inode * inod;


printk(KERN_INFO "init_module() called\n");

/*generate all the device name strings we'll need*/
for( i = 0; i < MINOR_COUNT; ++i )
	{
	target_ports[ i ] = kmalloc( strlen( target_port ) + 1 + strlen( suffixes[ i ] ), GFP_KERNEL );
	if( target_ports[ i ] == NULL )
		goto die;
	strcpy( target_ports[ i ], target_port );
	strcat( target_ports[ i ], suffixes[ i ] );
	}

if( !queue_init( &rx_queue, buffer_sz ) )
	{
	goto die;
	}

if( !queue_init( &tx_queue, buffer_sz ) )
	{
	goto die;
	}

Major = register_chrdev(0, DEVICE_NAME, &our_fops);
if (Major < 0)
	{
	printk ("Registering the character device failed with %d\n", Major);
	return Major;
	}

printk("<1>I was assigned major number %d.  To talk to the driver:\n", Major);
printk("'    mknod /dev/hello c %d 0'.\n", Major);
printk("<1>Remove the device file and module when done.\n");

dev_Class = class_create( THIS_MODULE, DEVICE_NAME );
if( dev_Class == NULL )
	{
	printk( KERN_ALERT "Error!Class couldn't be created!\n" );
	goto die;
	}

for( i = 0; i < MINOR_COUNT; ++i )
	{
	chr_dev[i] = device_create( dev_Class, NULL, MKDEV(Major,i), NULL, target_ports[ i ] );
	if( chr_dev[i] == NULL )
		{
		printk( KERN_ALERT "Error!Meta Device file couldnt be created\n" );
		goto die;
		}
	}

printk(KERN_INFO "init_module() complete\n\tRealDevice:%s\n\tMetaDevice:%s\n\tRxDevice:%s\n\tTxDevice:%s\n",
	target_port,
	target_ports[ MINOR_META ],
	target_ports[ MINOR_RX ],
	target_ports[ MINOR_TX ] );

if( kern_path( target_port, LOOKUP_FOLLOW, &p ) )
	goto die;

inod = p.dentry->d_inode;
if( inod == NULL )
	{
	printk( KERN_INFO "No inode for that filename" );
	goto die;
	}


their_orig_fops = inod->i_fop;
memcpy( &their_fops, inod->i_fop, sizeof( their_fops ) );
if( their_fops.read    )their_fops.read    = target_read;
if( their_fops.write   )their_fops.write   = target_write;
if( their_fops.release )their_fops.release = target_release;
inod->i_fop = &their_fops;

printk( KERN_INFO "Orig fops:" );
print_fops( their_orig_fops );

printk( KERN_INFO "New fops:" );
print_fops( &their_fops );


return SUCCESS;

die:
	cleanup_module();
	return ERROR;
}
static int max98506_probe(struct snd_soc_codec *codec)
{
	struct max98506_priv *max98506 = snd_soc_codec_get_drvdata(codec);
	struct max98506_volume_step_info *vstep = &max98506->vstep;
	int ret = 0;
	int reg = 0;

	dev_info(codec->dev, "build number %s\n", MAX98506_REVISION);

	max98506->codec = codec;
	codec->control_data = max98506->regmap;

	ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
	if (ret != 0) {
		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
		return ret;
	}

	reg = max98506_check_version(max98506);
	if (!reg) {
		dev_err(codec->dev,
			"device initialization error (0x%02X)\n",
			reg);
		goto err_version;
	}
	msg_maxim("device version 0x%02x", reg);

	regmap_write(max98506->regmap, MAX98506_R038_GLOBAL_ENABLE, 0x80);

	/* It's not the default but we need to set DAI_DLY */
	regmap_write(max98506->regmap, MAX98506_R020_FORMAT,
		MAX98506_DAI_DLY_MASK);

	regmap_write(max98506->regmap, MAX98506_R021_TDM_SLOT_SELECT, 0xC8);

	regmap_write(max98506->regmap, MAX98506_R027_DOUT_HIZ_CFG1, 0xFF);
	regmap_write(max98506->regmap, MAX98506_R028_DOUT_HIZ_CFG2, 0xFF);
	regmap_write(max98506->regmap, MAX98506_R029_DOUT_HIZ_CFG3, 0xFF);
	regmap_write(max98506->regmap, MAX98506_R02A_DOUT_HIZ_CFG4, 0xF0);
	regmap_write(max98506->regmap, MAX98506_R02C_FILTERS, 0xD9);

	regmap_update_bits(max98506->regmap,
		MAX98506_R02D_GAIN, MAX98506_DAC_IN_SEL_MASK,
		MAX98506_DAC_IN_SEL_DIV2_SUMMED_DAI);

	regmap_write(max98506->regmap, MAX98506_R02F_SPK_AMP, 0x02);
	regmap_write(max98506->regmap, MAX98506_R034_ALC_CONFIGURATION, 0x12);

	/* Enable ADC and Speaker */
	regmap_update_bits(max98506->regmap,
			MAX98506_R036_BLOCK_ENABLE,
			MAX98506_ADC_VIMON_EN_MASK |
			MAX98506_SPK_EN_MASK,
			MAX98506_ADC_VIMON_EN_MASK |
			MAX98506_SPK_EN_MASK);
	vstep->adc_status = 1;

	/* Set boost output to maximum */
	regmap_write(max98506->regmap, MAX98506_R037_CONFIGURATION, 0x00);

	/* Disable ALC muting */
	regmap_write(max98506->regmap, MAX98506_R03A_BOOST_LIMITER, 0xF8);

	max98506_set_slave(max98506);
	max98506_handle_pdata(codec);

#if defined(USE_DSM_LOG) || defined(USE_DSM_UPDATE_CAL)
	if (!g_class)
		g_class = class_create(THIS_MODULE, class_name_log);
	max98506->dev_log_class = g_class;
	if (max98506->dev_log_class) {
		max98506->dev_log =
			device_create(max98506->dev_log_class,
					NULL, 1, NULL, "max98506");
		if (IS_ERR(max98506->dev_log)) {
			ret = sysfs_create_group(&codec->dev->kobj,
				&max98506_attribute_group);
			if (ret)
				msg_maxim(
				"failed to create sysfs group [%d]", ret);
		} else {
			ret = sysfs_create_group(&max98506->dev_log->kobj,
				&max98506_attribute_group);
			if (ret)
				msg_maxim(
				"failed to create sysfs group [%d]", ret);
		}
	}
	msg_maxim("g_class=%p %p", g_class, max98506->dev_log_class);
#endif /* USE_DSM_LOG */

err_version:
	msg_maxim("exit %d", ret);

	return ret;
}
示例#27
0
static int __init nrf905_init(void)
{
	int retval = -ENODEV;
	dev_t devno = 0;
	char cdevno[20];
	struct nrf905_dev_data *dev;

	if (nrf905_major) {
		devno = MKDEV(nrf905_major, nrf905_minor);
		retval = register_chrdev_region(devno, NRF905_NR_DEVS,
			"nrf905");
	} else {
		retval = alloc_chrdev_region(&devno, nrf905_minor,
			NRF905_NR_DEVS,	"nrf905");
		nrf905_major = MAJOR(devno);
	}
	if (retval < 0) {
		pr_err("nrf905: can't get major %d\n", nrf905_major);
		goto err_major;
	}

	pr_info("nrf905: %s\n", format_dev_t(cdevno, devno));

	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
	if (IS_ERR_OR_NULL(dev)) {
		pr_err("nrf905: can't allocate memory for nrf905_dev\n");
		retval = -ENOMEM;
		goto err_nrf905_dev;
	}
	nrf905_dev = dev;

	init_waitqueue_head(&dev->recv_waitq);

	mutex_init(&dev->cdev_mutex);
	mutex_init(&dev->dev_mutex);

	spin_lock_init(&dev->chip.irq_lock);

	atomic_set(&nrf905_dev->fp_open, 0);

	dev->nrf905_class = class_create(THIS_MODULE, "nrf905");
	if (IS_ERR(dev->nrf905_class)) {
		pr_err("nrf905: class create fail\n");
		retval = PTR_ERR(dev->nrf905_class);
		goto err_class;
	}

	dev->nrf905_class->dev_groups = chip_config_groups;

	dev->char_dev =
		device_create(dev->nrf905_class, NULL,
			MKDEV(nrf905_major, nrf905_minor), NULL, "nrf905");

	if (IS_ERR(dev->char_dev)) {
		pr_err("nrf905: char device create failed\n");
		retval = PTR_ERR(dev->char_dev);
		goto err_char_dev;
	}

	dev_set_drvdata(dev->char_dev, dev);

	nrf905_dev->work_q = alloc_workqueue("nrf905", 0, 0);
	if (IS_ERR_OR_NULL(nrf905_dev->work_q)) {
		retval = -ENOMEM;
		goto err_workq;
	}

	INIT_WORK(&nrf905_dev->work, nrf905_data_ready);

	pr_info("nrf905: register spi driver\n");
	retval = spi_register_driver(&nrf905_driver);
	if (retval < 0) {
		pr_err("nrf905: spi driver register fail\n");
		goto err_spi_register;
	}

	cdev_init(&dev->cdev, &nrf905_fops);
	dev->cdev.owner = THIS_MODULE;

	retval = cdev_add(&dev->cdev, devno, 1);
	if (retval < 0) {
		pr_err("nrf905: cdev reg. failed, major %d, minor %d: %d\n",
			nrf905_major, nrf905_minor, retval);
		goto err_cdev;
	}

	pr_info("nrf905 init ready: %d\n", retval);
	return retval;

err_cdev:
	spi_unregister_driver(&nrf905_driver);

err_spi_register:
	remove_proc_entry("nrf905", NULL);
	device_destroy(dev->nrf905_class,
		MKDEV(nrf905_major, nrf905_minor));

err_workq:
	destroy_workqueue(nrf905_dev->work_q);

err_char_dev:
	class_destroy(dev->nrf905_class);

err_class:
	kfree(dev);

err_nrf905_dev:
	unregister_chrdev_region(devno, NRF905_NR_DEVS);

err_major:
	return retval;
}
示例#28
0
struct class *bcm_class_create (void)
{
	return class_create(THIS_MODULE, "tarang");
}
示例#29
0
文件: beep.c 项目: sky8336/mn201307
static int hello_init(void) //自定义加载函数
{
	int ret;
	dev_t devno = MKDEV(major,minor); //申请设备号

	ret = register_chrdev_region(devno,num_of_device,"xhello"); //注册设备号
	if(0 != ret){
		//alloc_chrdev_region(&devno,0,1,DEV_NAME); //自动分配设备号
		printk("register_chrdev_region : error\n");
		return -1;
	}

	cdev_init(&cdev,&hello_ops); //初始化cdev结构体
	ret = cdev_add(&cdev,devno,num_of_device); //注册cdev结构体
	if(0 != ret) {
		printk("cdev_add fail\n");
		goto err1;
	}

	cls = class_create(THIS_MODULE,"xhello"); //创建一个类
	device_create(cls, device, devno + 0, NULL, "xhello-0"); //创建设备结点,次设备号加1
	device_create(cls, device, devno + 1, NULL, "xhello-1");
	device_create(cls, device, devno + 2, NULL, "xhello-2");
	device_create(cls, device, devno + 3, NULL, "xhello-3");

	//	spin_lock_init(&lock); //初始化自旋锁
	init_waitqueue_head(&hello_readq); //初始化“等待队列头”
	init_waitqueue_head(&hello_writeq); //初始化“等待队列头”

	gpg3con = ioremap(GPG3CON,4); //LED
	if(NULL == gpg3con) {
		printk("pgp3con ioremap fail\n");
		goto err2;
	}

	gpg3dat = ioremap(GPG3DAT,4);
	if(NULL == gpg3dat) {
		printk("gpg3dat ioremap fail\n");
		goto err3;
	}

	//	*gpg3con = ((*gpg3con) & (~ 0xffff)) | 0x1111;
	//	*gpg3dat = ((*gpg3dat) & (~0xf)) | 0xf;
	writel((readl(gpg3con) & (~ 0xffff)) | 0x1111,gpg3con);
	writel(readl(gpg3dat) | 0xf,gpg3dat);

	/*pwm 和beep相关寄存器虚拟地址映射*/
	gpdcon = ioremap(GPDCON, 4);
	tcfg0= ioremap(TCFG0, 4);
	tcfg1= ioremap(TCFG1, 4);
	tcon= ioremap(TCON, 4);
	tcntb1= ioremap(TCNTB1, 4);
	tcmpb1= ioremap(TCMPB1, 4);

#if 0
	/*pwm和beep相关寄存器初始化*/
	writel((readl(gpdcon) & (~0xf << 4)) | (0x2 << 4),gpdcon); /*beep相连引脚为GDP1,gdpcon的[7:4]
																 设置为TOUT_1*/
	writel((readl(tcfg0) & (~0xff)) | 0xff,tcfg0); /*tcfg0*/
	writel((readl(tcfg1) & (~0xf << 4)) | (0x2 << 4),tcfg1);
	writel((readl(tcntb1) & (~0xffffffff)) | 0x200,tcntb1);
	writel((readl(tcmpb1) & (~0xffffffff)) | 0x100,tcmpb1);
	writel((readl(tcon) & (~0x3 << 8)) | (0x2 << 8),tcon);/*tcon [9:8]设置成10,手动装载,关定时器*/
	writel((readl(tcon) & (~0xf << 8)) | (0x9 << 8),tcon);

#endif

	writel((readl(gpdcon) & (~0xf << 4)) | (0x2 << 4),gpdcon); /*beep相连引脚为GDP1,gdpcon的[7:4]
																 设置为TOUT_1*/
	writel((readl(tcntb1) & (~0xffffffff)) | 0x200,tcntb1);
	writel((readl(tcmpb1) & (~0xffffffff)) | 0x100,tcmpb1);
	writel((readl(tcon) & (~0x3 << 8)) | (0x2 << 8),tcon);/*tcon [9:8]设置成10,手动装载,关定时器*/

	printk("hello_init\n");
	return 0;
err3:
	iounmap(gpg3con);
err2:
	cdev_del(&cdev); //卸载cdev结构体

err1:
	unregister_chrdev_region(devno,num_of_device); //cdev结构体注册失败,卸载设备号
	return ret;
}
static int frandom_init_module(void)
{
	int result;

	/* The buffer size MUST be at least 256 bytes, because we assume that
	   minimal length in init_rand_state().
	*/       
	if (frandom_bufsize < 256) {
		printk(KERN_ERR "frandom: Refused to load because frandom_bufsize=%d < 256\n",frandom_bufsize);
		return -EINVAL;
	}
	if ((frandom_chunklimit != 0) && (frandom_chunklimit < 256)) {
		printk(KERN_ERR "frandom: Refused to load because frandom_chunklimit=%d < 256 and != 0\n",frandom_chunklimit);
		return -EINVAL;
	}

	erandom_state = kmalloc(sizeof(struct frandom_state), GFP_KERNEL);
	if (!erandom_state)
		return -ENOMEM;

	/* This specific buffer is only used for seeding, so we need
	   256 bytes exactly */
	erandom_state->buf = kmalloc(256, GFP_KERNEL);
	if (!erandom_state->buf) {
		kfree(erandom_state);
		return -ENOMEM;
	}

	sema_init(&erandom_state->sem, 1); /* Init semaphore as a mutex */

	erandom_seeded = 0;

	frandom_class = class_create(THIS_MODULE, "fastrng");
	if (IS_ERR(frandom_class)) {
		result = PTR_ERR(frandom_class);
		printk(KERN_WARNING "frandom: Failed to register class fastrng\n");
		goto error0;
	}

	/*
	 * Register your major, and accept a dynamic number. This is the
	 * first thing to do, in order to avoid releasing other module's
	 * fops in frandom_cleanup_module()
	 */

	cdev_init(&frandom_cdev, &frandom_fops);
	frandom_cdev.owner = THIS_MODULE;
	result = cdev_add(&frandom_cdev, MKDEV(frandom_major, frandom_minor), 1);
	if (result) {
	  printk(KERN_WARNING "frandom: Failed to add cdev for /dev/frandom\n");
	  goto error1;
	}

	result = register_chrdev_region(MKDEV(frandom_major, frandom_minor), 1, "/dev/frandom");
	if (result < 0) {
		printk(KERN_WARNING "frandom: can't get major/minor %d/%d\n", frandom_major, frandom_minor);
	  goto error2;
	}

	frandom_device = device_create(frandom_class, NULL, MKDEV(frandom_major, frandom_minor), NULL, "frandom");

	if (IS_ERR(frandom_device)) {
		printk(KERN_WARNING "frandom: Failed to create frandom device\n");
		goto error3;
	}

	cdev_init(&erandom_cdev, &frandom_fops);
	erandom_cdev.owner = THIS_MODULE;
	result = cdev_add(&erandom_cdev, MKDEV(frandom_major, erandom_minor), 1);
	if (result) {
	  printk(KERN_WARNING "frandom: Failed to add cdev for /dev/erandom\n");
	  goto error4;
	}

	result = register_chrdev_region(MKDEV(frandom_major, erandom_minor), 1, "/dev/erandom");
	if (result < 0) {
		printk(KERN_WARNING "frandom: can't get major/minor %d/%d\n", frandom_major, erandom_minor);
		goto error5;
	}

	erandom_device = device_create(frandom_class, NULL, MKDEV(frandom_major, erandom_minor), NULL, "erandom");

	if (IS_ERR(erandom_device)) {
		printk(KERN_WARNING "frandom: Failed to create erandom device\n");
		goto error6;
	}
	return 0; /* succeed */

 error6:
	unregister_chrdev_region(MKDEV(frandom_major, erandom_minor), 1);
 error5:
	cdev_del(&erandom_cdev);
 error4:
	device_destroy(frandom_class, MKDEV(frandom_major, frandom_minor));
 error3:
	unregister_chrdev_region(MKDEV(frandom_major, frandom_minor), 1);
 error2:
	cdev_del(&frandom_cdev);
 error1:
	class_destroy(frandom_class);
 error0:
	kfree(erandom_state->buf);
	kfree(erandom_state);

	return result;	
}