static int __init sstore_init (void) { int i; int rv; if(alloc_chrdev_region(&sstore_dev_number, sstore_minor, NUM_SSTORE_DEVICES, DEV_NAME) < 0){ printk(KERN_DEBUG "sstore: unable to register device.\n"); rv = -EPERM; goto init_out; } sstore_major = MAJOR(sstore_dev_number); sstore_class = class_create(THIS_MODULE, DEV_NAME); for(i = 0; i < NUM_SSTORE_DEVICES; ++i){ /* Allocate memory for the per-device structure */ sstore_devp[i] = kmalloc(sizeof(struct sstore_dev), GFP_KERNEL); if (!sstore_devp[i]){ printk(KERN_DEBUG "sstore: bad kmalloc\n"); rv = -ENOMEM; goto no_devs; } sstore_devp[i]->open_count = 0; sstore_devp[i]->read_count = 0; sstore_devp[i]->write_count = 0; sstore_devp[i]->del_count = 0; sstore_devp[i]->sstore_number = i; sstore_devp[i]->sstore_blobp = kzalloc(num_of_blobs * sizeof(struct sstore_dev *), GFP_KERNEL); if (!sstore_devp[i]->sstore_blobp){ printk(KERN_DEBUG "sstore: bad kzalloc\n"); rv = -ENOMEM; goto no_blobs; } /* Init lock(s) */ mutex_init(&sstore_devp[i]->sstore_lock); init_waitqueue_head(&sstore_devp[i]->sstore_wq); /* Connect the file operations with the cdev */ cdev_init(&sstore_devp[i]->cdev, &sstore_fops); sstore_devp[i]->cdev.owner = THIS_MODULE; /* Connect the major/minor number to the cdev */ rv = cdev_add(&sstore_devp[i]->cdev, MKDEV(sstore_major, sstore_minor + i), 1); if (rv) { printk(KERN_DEBUG "sstore: bad cdev\n"); goto no_cdev_connection; } /* Send uevents to udev, so it'll create /dev nodes */ device_create(sstore_class, NULL, MKDEV(sstore_major, sstore_minor + i), "sstore%d", i); } rv = sstore_proc_init(); if(rv){ printk(KERN_DEBUG "sstore: unable to init /proc files.\n"); goto no_proc_files; } printk(KERN_INFO "sstore: driver initialized.\n"); return 0; /* Evil goto error handling. */ no_proc_files: for(; i >=0; --i){ device_destroy (sstore_class, MKDEV(sstore_major, sstore_minor + i)); cdev_del(&sstore_devp[i]->cdev); no_cdev_connection: kfree(sstore_devp[i]->sstore_blobp); no_blobs: kfree(sstore_devp[i]); no_devs: continue; } class_destroy(sstore_class); init_out: return rv; }
void vc_mem_connected_init(void) { int rc = -EFAULT; struct device *dev; LOG_DBG("%s: called", __func__); vc_mem_get_size(); printk("vc-mem: mm_vc_mem_phys_addr = 0x%08lx\n", mm_vc_mem_phys_addr); printk("vc-mem: mm_vc_mem_size = 0x%08x (%u MiB)\n", mm_vc_mem_size, mm_vc_mem_size / (1024 * 1024)); if ((rc = alloc_chrdev_region(&vc_mem_devnum, 0, 1, DRIVER_NAME)) < 0) { LOG_ERR("%s: alloc_chrdev_region failed (rc=%d)", __func__, rc); goto out_err; } cdev_init(&vc_mem_cdev, &vc_mem_fops); if ((rc = cdev_add(&vc_mem_cdev, vc_mem_devnum, 1)) != 0) { LOG_ERR("%s: cdev_add failed (rc=%d)", __func__, rc); goto out_unregister; } vc_mem_class = class_create(THIS_MODULE, DRIVER_NAME); if (IS_ERR(vc_mem_class)) { rc = PTR_ERR(vc_mem_class); LOG_ERR("%s: class_create failed (rc=%d)", __func__, rc); goto out_cdev_del; } dev = device_create(vc_mem_class, NULL, vc_mem_devnum, NULL, DRIVER_NAME); if (IS_ERR(dev)) { rc = PTR_ERR(dev); LOG_ERR("%s: device_create failed (rc=%d)", __func__, rc); goto out_class_destroy; } vc_mem_proc_entry = create_proc_entry(DRIVER_NAME, 0444, NULL); if (vc_mem_proc_entry == NULL) { rc = -EFAULT; LOG_ERR("%s: create_proc_entry failed", __func__); goto out_device_destroy; } vc_mem_proc_entry->read_proc = vc_mem_proc_read; vc_mem_proc_entry->write_proc = vc_mem_proc_write; vc_mem_inited = 1; return; out_device_destroy: device_destroy(vc_mem_class, vc_mem_devnum); out_class_destroy: class_destroy(vc_mem_class); vc_mem_class = NULL; out_cdev_del: cdev_del(&vc_mem_cdev); out_unregister: unregister_chrdev_region(vc_mem_devnum, 1); out_err: return; }
void globalfifo_exit(void) { cdev_del(&globalfifo_devp->cdev); kfree(globalfifo_devp); unregister_chrdev_region(MKDEV(globalfifo_major, 0), 1); }
static int WMT_init(void) { dev_t devID = MKDEV(gWmtMajor, 0); INT32 cdevErr = -1; INT32 ret = -1; WMT_INFO_FUNC("WMT Version= %s DATE=%s\n" , MTK_WMT_VERSION, MTK_WMT_DATE); /* Prepare a UCHAR device */ /*static allocate chrdev*/ stp_drv_init(); ret = register_chrdev_region(devID, WMT_DEV_NUM, WMT_DRIVER_NAME); if (ret) { WMT_ERR_FUNC("fail to register chrdev\n"); return ret; } cdev_init(&gWmtCdev, &gWmtFops); gWmtCdev.owner = THIS_MODULE; cdevErr = cdev_add(&gWmtCdev, devID, WMT_DEV_NUM); if (cdevErr) { WMT_ERR_FUNC("cdev_add() fails (%d) \n", cdevErr); goto error; } WMT_INFO_FUNC("driver(major %d) installed \n", gWmtMajor); #if 0 pWmtDevCtx = wmt_drv_create(); if (!pWmtDevCtx) { WMT_ERR_FUNC("wmt_drv_create() fails \n"); goto error; } ret = wmt_drv_init(pWmtDevCtx); if (ret) { WMT_ERR_FUNC("wmt_drv_init() fails (%d) \n", ret); goto error; } WMT_INFO_FUNC("stp_btmcb_reg\n"); wmt_cdev_btmcb_reg(); ret = wmt_drv_start(pWmtDevCtx); if (ret) { WMT_ERR_FUNC("wmt_drv_start() fails (%d) \n", ret); goto error; } #endif ret = wmt_lib_init(); if (ret) { WMT_ERR_FUNC("wmt_lib_init() fails (%d) \n", ret); goto error; } #if CFG_WMT_DBG_SUPPORT wmt_dev_dbg_setup(); #endif #if defined(CONFIG_THERMAL) && defined(CONFIG_THERMAL_OPEN) WMT_INFO_FUNC("wmt_dev_tm_setup\n"); wmt_dev_tm_setup(); mtk_wcn_hif_sdio_update_cb_reg(wmt_dev_tra_sdio_update); #endif WMT_INFO_FUNC("success \n"); return 0; error: wmt_lib_deinit(); #if CFG_WMT_DBG_SUPPORT wmt_dev_dbg_remove(); #endif if (cdevErr == 0) { cdev_del(&gWmtCdev); } if (ret == 0) { unregister_chrdev_region(devID, WMT_DEV_NUM); gWmtMajor = -1; } WMT_ERR_FUNC("fail \n"); return -1; }
/*模块卸载函数*/ void second_exit(void) { cdev_del(&second_devp->cdev); /*注销cdev*/ kfree(second_devp); /*释放设备结构体内存*/ unregister_chrdev_region(MKDEV(second_major, 0), 1); /*释放设备号*/ }
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; }
static void simple_cleanup(void) { cdev_del(SimpleDevs); cdev_del(SimpleDevs + 1); unregister_chrdev_region(MKDEV(simple_major, 0), 2); }
/*------------------------------------------------------------------------------ * Context: process */ int oz_cdev_deregister(void) { cdev_del(&g_cdev.cdev); unregister_chrdev_region(g_cdev.devnum, 1); return 0; }
/* * 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 the system device. */ register_syscore_ops(&g_tf_device_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(&g_tf_device_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; }
__exit static void hello_driver_exit (void) { unregister_chrdev_region (MKDEV(major, minor), 1) ; cdev_del (&hello_cdev) ; printk(KERN_ALERT"cleanup module\r\n") ; }
static void __exit globalmem_exit(void) { cdev_del(&globalmem_devp->cdev); kfree(globalmem_devp); unregister_chrdev_region(MKDEV(globalmem_major, 0), 1); }
void globalfifo_exit(void) { cdev_del(&devp->cdev);//注销cdev kfree((void*)devp);//释放设备结构体内存 unregister_chrdev_region(MKDEV(globalfifo_major,0),1);//释放设备号 }
/*模块加载方法*/ static int __init hello_init(void){ int err = -1; dev_t dev = 0; struct device* temp = NULL; printk(KERN_ALERT"Initializing hello device.\n"); /*动态分配主设备和从设备号*/ err = alloc_chrdev_region(&dev, 0, 1, HELLO_DEVICE_NODE_NAME); if(err < 0) { printk(KERN_ALERT"Failed to alloc char dev region.\n"); goto fail; } hello_major = MAJOR(dev); hello_minor = MINOR(dev); /*分配helo设备结构体变量*/ hello_dev = kmalloc(sizeof(struct hello_android_dev), GFP_KERNEL); if(!hello_dev) { err = -ENOMEM; printk(KERN_ALERT"Failed to alloc hello_dev.\n"); goto unregister; } /*初始化设备*/ err = __hello_setup_dev(hello_dev); if(err) { printk(KERN_ALERT"Failed to setup dev: %d.\n", err); goto cleanup; } /*在/sys/class/目录下创建设备类别目录hello*/ hello_class = class_create(THIS_MODULE, HELLO_DEVICE_CLASS_NAME); if(IS_ERR(hello_class)) { err = PTR_ERR(hello_class); printk(KERN_ALERT"Failed to create hello class.\n"); goto destroy_cdev; } /*在/dev/目录和/sys/class/hello目录下分别创建设备文件hello*/ temp = device_create(hello_class, NULL, dev, "%s", HELLO_DEVICE_FILE_NAME); if(IS_ERR(temp)) { err = PTR_ERR(temp); printk(KERN_ALERT"Failed to create hello device."); goto destroy_class; } /*在/sys/class/hello/hello目录下创建属性文件val*/ err = device_create_file(temp, &dev_attr_val); if(err < 0) { printk(KERN_ALERT"Failed to create attribute val."); goto destroy_device; } dev_set_drvdata(temp, hello_dev); /*创建/proc/hello文件*/ hello_create_proc(); printk(KERN_ALERT"Succedded to initialize hello device.\n"); return 0; destroy_device: device_destroy(hello_class, dev); destroy_class: class_destroy(hello_class); destroy_cdev: cdev_del(&(hello_dev->dev)); cleanup: kfree(hello_dev); unregister: unregister_chrdev_region(MKDEV(hello_major, hello_minor), 1); fail: return err; }
/***************************************************************************** * MODULE : sizrot2_init_module * FUNCTION : initialize module * RETURN : 0 : success * : negative : fail * NOTE : none ******************************************************************************/ static int sizrot2_init_module(void) { int ret = 0; dbg_printk((_DEBUG_SIZROT2 & 0x01), "sizrot2_init_module() <start>\n"); /* register_chrdev_region */ dev_t_siz = MKDEV(DEV_MAJOR, DEV_MINOR_SIZ); ret = register_chrdev_region(dev_t_siz, 1, "siz"); if (ret < 0) { printk(KERN_ERR " @sizrot2: Fail to regist device (SIZ).\n"); goto fail_register_chrdev_siz; } dev_t_rot0 = MKDEV(DEV_MAJOR, DEV_MINOR_ROT0); ret = register_chrdev_region(dev_t_rot0, 1, "rot0"); if (ret < 0) { printk(KERN_ERR " @sizrot2: Fail to regist device (ROT0).\n"); goto fail_register_chrdev_rot0; } /* cdev_init */ cdev_init(&siz_cdev, &sizrot2_fops); siz_cdev.owner = THIS_MODULE; cdev_init(&rot0_cdev, &sizrot2_fops); rot0_cdev.owner = THIS_MODULE; /* cdev_add */ ret = cdev_add(&siz_cdev, dev_t_siz, 1); if (ret) { printk(KERN_ERR " @sizrot2: Fail to add cdev (SIZ).\n"); goto fail_cdev_add_siz; } ret = cdev_add(&rot0_cdev, dev_t_rot0, 1); if (ret) { printk(KERN_ERR " @sizrot2: Fail to add cdev (ROT0).\n"); goto fail_cdev_add_rot0; } /* class_create */ sizrot2_class = class_create(THIS_MODULE, sizrot2_dev_name); if (IS_ERR(sizrot2_class)) { printk(KERN_ERR " @sizrot2: Fail to create class.\n"); ret = PTR_ERR(sizrot2_class); goto fail_class_create; } /* device_create */ class_dev_siz = device_create(sizrot2_class, NULL, dev_t_siz, NULL, "siz"); if (IS_ERR(class_dev_siz)) { printk(KERN_ERR " @sizrot2: Fail to create class device (SIZ).\n"); ret = PTR_ERR(class_dev_siz); goto fail_class_device_create_siz; } class_dev_rot0 = device_create(sizrot2_class, NULL, dev_t_rot0, NULL, "rot0"); if (IS_ERR(class_dev_rot0)) { printk(KERN_ERR " @sizrot2: Fail to create class device (ROT0).\n"); ret = PTR_ERR(class_dev_rot0); goto fail_class_device_create_rot0; } /* platform_device_register */ dev_set_drvdata(&sizrot2_device.dev, NULL); if (platform_device_register(&sizrot2_device) < 0) { printk(KERN_ERR " @sizrot2: Fail to register platform_device\n"); goto fail_platform_device; } /* platform_driver_register */ if (platform_driver_register(&sizrot2_driver) < 0) { printk(KERN_ERR " @sizrot2: Fail to register platform_driver\n"); goto fail_platform_driver; } spin_lock_init(&sizrot2_lock); /* init SIZ */ ret = init_siz(); if (ret < 0) { printk(KERN_INFO " @sizrot2: SIZ driver initialize <failed>\n"); goto fail_init_hw; } /* init ROT */ ret = init_rot(); if (ret < 0) { printk(KERN_INFO " @sizrot2: ROT driver initialize <failed>\n"); goto fail_init_hw; } dbg_printk(_DEBUG_SIZROT2, "register_chrdev %d\n", DEV_MAJOR); dbg_printk(_DEBUG_SIZROT2, "sizrot2 driver initialize <success>\n"); goto success; fail_init_hw: platform_driver_unregister(&sizrot2_driver); fail_platform_driver: platform_device_unregister(&sizrot2_device); fail_platform_device: device_destroy(sizrot2_class, MKDEV(DEV_MAJOR, DEV_MINOR_ROT0)); fail_class_device_create_rot0: device_destroy(sizrot2_class, MKDEV(DEV_MAJOR, DEV_MINOR_SIZ)); fail_class_device_create_siz: class_destroy(sizrot2_class); fail_class_create: cdev_del(&rot0_cdev); fail_cdev_add_rot0: cdev_del(&siz_cdev); fail_cdev_add_siz: unregister_chrdev_region(dev_t_rot0, 1); fail_register_chrdev_rot0: unregister_chrdev_region(dev_t_siz, 1); fail_register_chrdev_siz: success: dbg_printk((_DEBUG_SIZROT2 & 0x02), "sizrot2_init_module() <end> return (%d)\n", ret); return ret; }
/** * platform driver * */ 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; } atomic_set(&drv->crash_in_progress, 0); 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; } ret = smsm_state_cb_register(SMSM_DSPS_STATE, SMSM_RESET, dsps_smsm_state_cb, 0); if (ret) { pr_err("%s: smsm_state_cb_register fail %d\n", __func__, ret); goto smsm_register_err; } dsps_dev = subsys_register(&dsps_ssrops); if (IS_ERR(dsps_dev)) { ret = PTR_ERR(dsps_dev); pr_err("%s: subsys_register fail %d\n", __func__, ret); goto ssr_register_err; } return 0; ssr_register_err: smsm_state_cb_deregister(SMSM_DSPS_STATE, SMSM_RESET, dsps_smsm_state_cb, 0); smsm_register_err: cdev_del(drv->cdev); 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; }
/* function called at module load time */ static int __init timing_dev_init(void) { int i, rc; dev_t dev_num; #if DEBUG != 0 printk(KERN_DEBUG "timing_dev_init entry\n"); #endif /* dynamically assign device number */ rc = alloc_chrdev_region(&dev_num, FIRST_MINOR, TIMING_DEV_COUNT, MODULE_NAME); if (rc) { printk(KERN_ALERT "Error allocating dev numbers - timing.c\n"); return rc; } /* record major number */ timing_maj_num = MAJOR(dev_num); /* set up individual data for each char dev */ /* for the 8 IO Ports */ for ( i = 0; i < TIMING_DEV_COUNT; i++ ) { timing_card[i].offset = 0x00; /* device number */ timing_card[i].num = MKDEV(timing_maj_num, FIRST_MINOR + i); /* part of device that this addresses */ if ( i < TIMING_IOPORT_COUNT ) timing_card[i].component = PCI7300_ID; else if ( i < TIMING_IOPORT_COUNT + TIMING_8254_COUNT ) timing_card[i].component = TIMER8254_ID; else timing_card[i].component = PLX9080_ID; /* vital driver structures */ timing_card[i].driver = &timing_driver; timing_card[i].fops = &timing_fops ; /* set up actual cdev */ cdev_init(&timing_card[i].cdev, &timing_fops); timing_card[i].cdev.owner = THIS_MODULE; timing_card[i].cdev.ops = &timing_fops; /* actual cdev registration */ /* magic # 1 is "count" */ rc = cdev_add(&timing_card[i].cdev, timing_card[i].num, 1); if ( rc < 0 ) { printk(KERN_ALERT "Error adding timing cdev %d to sys\n", i); goto del_cdev; } } /* end data initialization for IO port loop */ #if DEBUG != 0 printk(KERN_DEBUG "timing_dev_init() exit success\n"); #endif /* finally, register as pci dev */ /* END FLOW OF NORMAL OPERATION */ return pci_register_driver(&timing_driver); /* ERROR HANDLING */ del_cdev: /* unregister char drivers */ unregister_chrdev_region(dev_num, TIMING_DEV_COUNT); /* delete the cdevs that succeeded (up to i) */ for ( ; !(i < 0); i-- ) cdev_del(&timing_card[i].cdev); return rc; } /* end timing_init */
/*文件释放函数*/ static int dev_release(struct inode *inode, struct file *filp){ cdev_del(&mydevice->cdev); /*注销cdev*/ printk(KERN_INFO "mydev closed!\n"); return 0; }
static void __exit sk_exit(void) { printk("The module is down...\n"); cdev_del(&sk_cdev); unregister_chrdev_region(sk_dev, 1); }
/*模块卸载函数*/ void globalfifo_exit(void) { cdev_del(&globalfifo_devp->cdev); /*注销cdev*/ kfree(globalfifo_devp); /*释放设备结构体内存*/ unregister_chrdev_region(MKDEV(globalfifo_major, 0), 1); /*释放设备号*/ }
static int wmt_detect_init(void) { dev_t devID = MKDEV(gWmtDetectMajor, 0); int cdevErr = -1; int ret = -1; ret = register_chrdev_region(devID, WMT_DETECT_DEV_NUM, WMT_DETECT_DRVIER_NAME); if (ret) { WMT_DETECT_ERR_FUNC("fail to register chrdev\n"); return ret; } cdev_init(&gWmtDetectCdev, &gWmtDetectFops); gWmtDetectCdev.owner = THIS_MODULE; cdevErr = cdev_add(&gWmtDetectCdev, devID, WMT_DETECT_DEV_NUM); if (cdevErr) { WMT_DETECT_ERR_FUNC("cdev_add() fails (%d) \n", cdevErr); goto err1; } pDetectClass = class_create(THIS_MODULE, WMT_DETECT_DEVICE_NAME); if(IS_ERR(pDetectClass)) { WMT_DETECT_ERR_FUNC("class create fail, error code(%ld)\n",PTR_ERR(pDetectClass)); goto err1; } pDetectDev = device_create(pDetectClass,NULL,devID,NULL,WMT_DETECT_DEVICE_NAME); if(IS_ERR(pDetectDev)) { WMT_DETECT_ERR_FUNC("device create fail, error code(%ld)\n",PTR_ERR(pDetectDev)); goto err2; } WMT_DETECT_INFO_FUNC("driver(major %d) installed success\n", gWmtDetectMajor); /*init SDIO-DETECT module*/ sdio_detect_init(); return 0; err2: if(pDetectClass) { class_destroy(pDetectClass); pDetectClass = NULL; } err1: if (cdevErr == 0) { cdev_del(&gWmtDetectCdev); } if (ret == 0) { unregister_chrdev_region(devID, WMT_DETECT_DEV_NUM); gWmtDetectMajor = -1; } WMT_DETECT_ERR_FUNC("fail \n"); return -1; }
static int __init bt_hwctl_init(void) { int ret = -1, err = -1; platform_driver_register(&mt6622_driver); if (!(bh = kzalloc(sizeof(struct bt_hwctl), GFP_KERNEL))) { BT_HWCTL_ERR("bt_hwctl_init allocate dev struct failed\n"); err = -ENOMEM; goto ERR_EXIT; } ret = alloc_chrdev_region(&bh->dev_t, 0, 1, BTHWCTL_NAME); if (ret) { BT_HWCTL_ERR("alloc chrdev region failed\n"); goto ERR_EXIT; } BT_HWCTL_INFO("alloc %s: %d:%d\n", BTHWCTL_NAME, MAJOR(bh->dev_t), MINOR(bh->dev_t)); cdev_init(&bh->cdev, &bt_hwctl_fops); bh->cdev.owner = THIS_MODULE; bh->cdev.ops = &bt_hwctl_fops; err = cdev_add(&bh->cdev, bh->dev_t, 1); if (err) { BT_HWCTL_ERR("add chrdev failed\n"); goto ERR_EXIT; } bh->cls = class_create(THIS_MODULE, BTHWCTL_NAME); if (IS_ERR(bh->cls)) { err = PTR_ERR(bh->cls); BT_HWCTL_ERR("class_create failed, errno:%d\n", err); goto ERR_EXIT; } bh->dev = device_create(bh->cls, NULL, bh->dev_t, NULL, BTHWCTL_NAME); mutex_init(&bh->sem); init_waitqueue_head(&eint_wait); wake_lock_init(&mt6622_irq_wakelock, WAKE_LOCK_SUSPEND, "mt6622_irq_wakelock"); /* request gpio used by BT */ //mt_bt_gpio_init(); BT_HWCTL_INFO("Bluetooth hardware control driver initialized\n"); return 0; ERR_EXIT: if (err == 0) cdev_del(&bh->cdev); if (ret == 0) unregister_chrdev_region(bh->dev_t, 1); if (bh){ kfree(bh); bh = NULL; } return -1; }
static int __init power_loss_init(void) { int err; printk(KERN_NOTICE "%s Power Loss Test Module Init\n", TAG); err = alloc_chrdev_region(&sg_pwr_loss_devno, PWR_LOSS_FIRST_MINOR, PWR_LOSS_MAX_MINOR_COUNT, PWR_LOSS_DEVNAME); if (err != 0){ printk(KERN_ERR "%s Power Loss Test: alloc_chardev_region Failed!\n", TAG); return err; } #ifdef PWR_LOSS_DEBUG printk(KERN_NOTICE "%s Power Loss Test: MAJOR =%d, MINOR=%d\n", TAG, MAJOR(sg_pwr_loss_devno), MINOR(sg_pwr_loss_devno)); #endif sg_pwr_loss_dev = cdev_alloc(); if (NULL == sg_pwr_loss_dev){ printk(KERN_ERR "%s Power Loss Test: cdev_alloc Failed\n", TAG); goto out2; } sg_pwr_loss_dev->owner = THIS_MODULE; sg_pwr_loss_dev->ops = &pwr_loss_fops; err = cdev_add(sg_pwr_loss_dev, sg_pwr_loss_devno, 1); if (err != 0){ printk(KERN_ERR "%s Power Loss Test: cdev_add Failed!\n", TAG); goto out2; } sg_pwr_loss_dev_class = class_create(THIS_MODULE, PWR_LOSS_DEVNAME); if (NULL == sg_pwr_loss_dev_class){ printk(KERN_ERR "%s Power Loss Test: class_create Failed!\n", TAG); goto out1; } sg_pwr_loss_dev_file = device_create(sg_pwr_loss_dev_class, NULL, sg_pwr_loss_devno, NULL, PWR_LOSS_DEVNAME); if (NULL == sg_pwr_loss_dev_file){ printk(KERN_ERR "%s Power Loss Test: device_create Failed!\n", TAG); goto out; } #ifdef PWR_LOSS_SW_RESET power_loss_info_init(); err = power_loss_debug_init(); if(err < 0) goto out; #endif printk(KERN_ERR "%s Power Loss Test: Init Successfully!\n", TAG); #ifdef PWR_LOSS_SW_RESET kernel_thread(pwr_loss_reset_thread, NULL, CLONE_VM); //CLONE_KERNEL printk(KERN_ERR "%s Power Loss Test: kernel thread create Successful!\n", TAG); #endif return 0; out: class_destroy(sg_pwr_loss_dev_class); out1: cdev_del(sg_pwr_loss_dev); out2: unregister_chrdev_region(sg_pwr_loss_devno, PWR_LOSS_MAX_MINOR_COUNT); #ifdef PWR_LOSS_SW_RESET remove_proc_entry("power_loss_debug", NULL); #endif return err; }
/* init driver module */ static int __init pn54x_init(void){ int err = -1; dev_t dev = 0; struct device* temp = NULL; printk(KERN_ALERT"Initializing pn54x device.\n"); /* alloc major/minor verison no. */ err = alloc_chrdev_region(&dev, 0, 1, PN54X_DEVICE_NODE_NAME); if(err < 0) { printk(KERN_ALERT"Failed to alloc char dev region.\n"); goto fail; } pn54x_major = MAJOR(dev); pn54x_minor = MINOR(dev); /* alloc dev data structure */ pn54x_dev = kmalloc(sizeof(pn54x_android_dev_t), GFP_KERNEL); if(!pn54x_dev) { err = -ENOMEM; printk(KERN_ALERT"Failed to alloc pn54x_dev.\n"); goto unregister; } /* init device */ err = __pn54x_setup_dev(pn54x_dev); if(err) { printk(KERN_ALERT"Failed to setup dev: %d.\n", err); goto cleanup; } /*在/sys/class/目录下创建设备类别目录pn54x*/ pn54x_class = class_create(THIS_MODULE, PN54X_DEVICE_CLASS_NAME); if(IS_ERR(pn54x_class)) { err = PTR_ERR(pn54x_class); printk(KERN_ALERT"Failed to create pn54x class.\n"); goto destroy_cdev; } /*在/dev/目录和/sys/class/pn54x目录下分别创建设备文件pn54x*/ temp = device_create(pn54x_class, NULL, dev, "%s", PN54X_DEVICE_FILE_NAME); if(IS_ERR(temp)) { err = PTR_ERR(temp); printk(KERN_ALERT"Failed to create pn54x device."); goto destroy_class; } /*在/sys/class/pn54x/pn54x目录下创建属性文件val*/ err = device_create_file(temp, &dev_attr_val); if(err < 0) { printk(KERN_ALERT"Failed to create attribute val."); goto destroy_device; } dev_set_drvdata(temp, pn54x_dev); /*创建/proc/pn54x文件*/ pn54x_create_proc(); /* init mutex and queues */ init_waitqueue_head(&pn54x_dev->is_reading_wq); init_waitqueue_head(&pn54x_dev->read_wq); init_waitqueue_head(&pn54x_dev->write_wq); init_waitqueue_head(&pn54x_dev->write_complete_wq); mutex_init(&pn54x_dev->read_mutex); pn54x_dev->is_ready_to_go = false; /* init fifo for nci commands */ nci_kfifo_init(); printk(KERN_ALERT"Succedded to initialize pn54x device.\n"); return 0; destroy_device: device_destroy(pn54x_class, dev); destroy_class: class_destroy(pn54x_class); destroy_cdev: cdev_del(&(pn54x_dev->dev)); cleanup: kfree(pn54x_dev); unregister: unregister_chrdev_region(MKDEV(pn54x_major, pn54x_minor), 1); fail: return err; }
static int henry_drv_probe(struct see_client *clnt) { int ret = 0; struct henry_drv *drv = NULL; drv = kzalloc(sizeof(struct henry_drv), GFP_KERNEL); if (!drv) return -ENOMEM; ret = alloc_chrdev_region(&drv->dev_num, 0, 1, HENRY_DEV); if (ret < 0) return ret; cdev_init(&drv->cdev, &g_henry_fops); drv->cdev.owner = THIS_MODULE; ret = cdev_add(&drv->cdev, drv->dev_num, 1); if (ret < 0) goto out; drv->dev_class = class_create(THIS_MODULE, HENRY_CLASS); if (IS_ERR_OR_NULL(drv->dev_class)) { ret = PTR_ERR(drv->dev_class); goto out; } drv->dev = device_create(drv->dev_class, NULL, drv->dev_num, drv, HENRY_DEV); if (IS_ERR_OR_NULL(drv->dev)) { ret = PTR_ERR(drv->dev); goto out; } mutex_init(&drv->mutex); drv->num_exist = 0; drv->debug_mode = 0; ida_init(&drv->sess_ida); dev_set_drvdata(&clnt->dev, drv); henry_sysfs_create(drv); henry_dbgfs_create(drv); dev_info(&clnt->dev, "HENRY driver probed\n"); out: if (unlikely(ret)) { if (drv->dev_class) { /* device_create */ device_destroy(drv->dev_class, drv->dev_num); /* cdev_add */ cdev_del(&drv->cdev); /* class_create */ class_destroy(drv->dev_class); /* alloc_chrdev_region */ unregister_chrdev_region(drv->dev_num, 1); } kfree(drv); } return ret; }
void __exit cleanup_module() { cdev_del(&c_dev); unregister_chrdev_region(dev, MINOR_CNT); printk(KERN_INFO "Bye Universe\n"); }
static __init int scull_init(void) { int i,ret; dev_t dev; printk(KERN_ERR "%s :enter\n",__FUNCTION__); if( scull_major ) { dev = MKDEV(scull_major,0); ret = register_chrdev_region(dev, scull_num, SCULL_NAME); if(ret) { return -EIO; } } else { ret = alloc_chrdev_region( &dev, 0, scull_num,SCULL_NAME); if(ret) { return -EIO; } scull_major = MAJOR( dev); } scull_devices = (struct scull_device *)kmalloc( sizeof(struct scull_device)*scull_num, GFP_KERNEL); if(!scull_devices) goto DEV; memset(scull_devices, 0, sizeof(struct scull_device)*scull_num); for ( i=0; i< scull_num; i++) { mutex_init( &scull_devices[i].lock); cdev_init( &scull_devices[i].s_cdev,&scull_file_operation); scull_devices[i].s_cdev.owner = THIS_MODULE; ret = cdev_add( &scull_devices[i].s_cdev, MKDEV(scull_major,i), 1); if(ret) { goto REMOVE; } } scull_proc_init(SCULL_NAME); return 0; REMOVE: for( i=0; i< scull_num; i++) { cdev_del( &scull_devices[i].s_cdev ); } kfree(scull_devices); DEV: unregister_chrdev_region( MKDEV(scull_major,0), scull_num); return -EIO; }
static void nemaweaver_major_cleanup(void) { printk ("Cleanup character device.\n"); unregister_chrdev_region(MKDEV(nemaweaver_major, 0), MAX_NEMAWEAVER_DEVS); cdev_del(nemaweaver_cdev); }
static int __init netchar_init(void) { int error; struct sockaddr_in server_addr; _PKI("initializing"); /** * create socket **/ error = sock_create(AF_INET, SOCK_STREAM, IPPROTO_TCP, &nc_socket); if (error != 0) { _PKE("error creating socket: %i", error); goto init_err_sock_create; } /** * setup server address **/ memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = in_aton(server); server_addr.sin_port = htons(port); /** * connect to server **/ error = nc_socket->ops->connect(nc_socket, (struct sockaddr*) &server_addr, sizeof(server_addr), 0); if (error != 0) { _PKE("error connecting to server: %i", error); goto init_err_connect; } /** * reserve a randomly allocated dev_t major/minor number **/ error = alloc_chrdev_region(&nc_dev_t, 0, 1, _MODULE_NAME); if (error != 0) { _PKE("error registering major/minors: %i", error); goto init_err_region; } /** * create device class (subsystem) * * this creates a class to which all of our devices will belong (both * control devices and import devices). besides that it is required for * a device to have a class, it gives us the SUBSYSTEM tag in udev so * we can change the permissions on all /dev nones of interest **/ nc_class = class_create(THIS_MODULE, "netchar"); error = PTR_ERR(nc_class); if (IS_ERR_VALUE(error)) { _PKE("failed to create class: %i", -error); goto init_err_class; } /** * setup cdev * * the cdev ties a set of file_operations (handlers for fs system calls) * to a range of major,minor pairs. **/ nc_cdev = cdev_alloc(); error = PTR_ERR(nc_cdev); if (IS_ERR_VALUE(error)) { _PKE("error allocating ctl cdev: %i", -error); goto init_err_cdev; } nc_cdev->owner = THIS_MODULE; nc_cdev->ops = &nc_fops; /** * add cdev * * once the cdev is initailized, we need to tell the kernel gods about * it. it's important to do this after the bulk of the module is * initialized because once the add happens, we're expected to be able * to handle fs calls in full **/ error = cdev_add(nc_cdev, nc_dev_t, 1); if (error != 0) { _PKE("error adding ctl cdev: %i", -error); goto init_err_cdev; } /** * create device node in userspace **/ nc_device = device_create(nc_class, NULL, nc_dev_t, NULL, _MODULE_NAME "/import"); error = PTR_ERR(nc_device); if (IS_ERR_VALUE(error)) { _PKE("error creating device node: %i", error); goto init_err_device; } /** * proper cleanup * * any memory the we've allocated and kobjects that we've created * need to be cleaned up in more or less the reverse order * **/ return 0; init_err_device: cdev_del(nc_cdev); init_err_cdev: class_destroy(nc_class); init_err_class: unregister_chrdev_region(nc_dev_t, 1); init_err_region: nc_socket->ops->shutdown(nc_socket, 0); init_err_connect: sock_release(nc_socket); init_err_sock_create: return error; }
static int __init s_tt_init(void) { int rc; /* Local enumeration used to free up the resources in an orderly fashion if one of the calls should fail. Intended to stop resource/memory leaks */ enum { S_TT_INIT_NONE = 0, S_TT_CHRDEV_REGION_REGISTERED, /* register_chrdev_region() called */ S_TT_CDEV_ADDED, /* cdev_add() called */ } enInitStage = S_TT_INIT_NONE; /* Initialise the instance data structure */ memset(&S_TT_Instance, '\0', sizeof(S_TT_Instance)); /* Allocate all character device numbers */ rc = register_chrdev_region(MKDEV(S_TT_MAJOR, S_TT_MINOR_START), S_TT_MINOR_MAX, S_TT_DEV_NAME); if (rc == 0) { enInitStage = S_TT_CHRDEV_REGION_REGISTERED; /* Initialise character device settings */ cdev_init(&S_TT_Instance.cdev, &s_tt_fops); S_TT_Instance.cdev.owner = THIS_MODULE; S_TT_Instance.cdev.ops = &s_tt_fops; /* Our device becomes live here */ rc = cdev_add(&S_TT_Instance.cdev, MKDEV(S_TT_MAJOR, S_TT_MINOR_START), 1); if ( rc == 0) { enInitStage = S_TT_CDEV_ADDED; /* Initialise local lock */ mutex_init(&S_TT_Instance.s_tt_lock); } /* if ( rc != 0) */ } /* if (rc = 0) */ /* If we failed to fully initialise, free up the resources in an orderly fashion, depending upon how far we got. This code is intended to stop resource/memory leaks */ if (rc != 0) { switch (enInitStage) { case S_TT_CDEV_ADDED: /* Remove the added character device from the system */ cdev_del(&S_TT_Instance.cdev); /* Note: no "break" here, fall through is intended */ case S_TT_CHRDEV_REGION_REGISTERED: /* Deallocate all character device numbers */ unregister_chrdev_region(MKDEV(S_TT_MAJOR, S_TT_MINOR_START), S_TT_MINOR_MAX); /* Note: no "break" here, fall through is intended */ case S_TT_INIT_NONE: default: /* Nothing to clean up here! */ break; } /* switch (enInitStage) */ } /* if (rc != 0) */ return rc; }
static void cdev_cleanup(struct vir_device *vir_device) { if( vir_device->buf !=NULL) vfree(vir_device->buf); cdev_del(&vir_device->cdev); }