static int __init shm_driver_init(void) { int res, i; struct device_node *np; struct resource r; struct proc_dir_entry *pent = NULL; struct proc_dir_entry *pstat = NULL; np = of_find_compatible_node(NULL, NULL, "mrvl,berlin-shm"); if (!np) goto err_node; res = of_address_to_resource(np, 0, &r); if (res) goto err_reg_device; shm_base_cache = r.start; shm_size_cache = resource_size(&r); res = of_address_to_resource(np, 1, &r); if (res) goto err_reg_device; shm_base_noncache = r.start; shm_size_noncache = resource_size(&r); of_node_put(np); /* Figure out our device number. */ res = register_chrdev_region(MKDEV(GALOIS_SHM_MAJOR, 0), GALOIS_SHM_MINORS, SHM_DEVICE_NAME); if (res < 0) { shm_error("unable to get shm device major [%d]\n", GALOIS_SHM_MAJOR); goto err_reg_device; } shm_debug("register cdev device major [%d]\n", GALOIS_SHM_MAJOR); /* Now setup cdevs. */ for (i = 0; i < ARRAY_SIZE(shm_driver_dev_list); i++) { res = shm_driver_setup_cdev(shm_driver_dev_list[i].cdev, GALOIS_SHM_MAJOR, shm_driver_dev_list[i].minor, shm_driver_dev_list[i].fops); if (res) { shm_error("shm_driver_setup_cdev failed in [%d].\n", i); goto err_add_device; } shm_debug("setup cdevs device minor [%d]\n", shm_driver_dev_list[i].minor); } /* add shm devices to sysfs */ shm_dev_class = class_create(THIS_MODULE, SHM_DEVICE_NAME); if (IS_ERR(shm_dev_class)) { shm_error("class_create failed.\n"); res = -ENODEV; goto err_add_device; } for (i = 0; i < ARRAY_SIZE(shm_driver_dev_list); i++) { device_create(shm_dev_class, NULL, MKDEV(GALOIS_SHM_MAJOR, shm_driver_dev_list[i].minor), NULL, shm_driver_dev_list[i].name); shm_debug("create device sysfs [%s]\n", shm_driver_dev_list[i].name); } /* create shm cache device */ res = shm_device_create(&shm_device, shm_base_cache, shm_size_cache, SHM_DEVICE_THRESHOLD); if (res != 0) { shm_error("shm_device_create failed.\n"); goto err_add_device; } /* init shrinker */ shm_device->m_shrinker = shm_lowmem_shrink_killer; /* create shm cache device */ res = shm_device_create(&shm_device_noncache, shm_base_noncache, shm_size_noncache, SHM_DEVICE_THRESHOLD); if (res != 0) { shm_error("shm_device_create failed.\n"); goto err_add_device; } /* init shrinker */ shm_device_noncache->m_shrinker = NULL; /* create shm kernel API, need map for noncache and cache device!!! */ res = MV_SHM_Init(shm_device_noncache, shm_device); if (res != 0) { shm_error("MV_SHM_Init failed !!!\n"); goto err_SHM_Init; } /* create shm device proc file */ shm_driver_procdir = proc_mkdir(SHM_DEVICE_NAME, NULL); if (!shm_driver_procdir) { shm_error(KERN_WARNING "Failed to mkdir /proc/%s\n", SHM_DEVICE_NAME); return 0; } proc_create("meminfo", 0, shm_driver_procdir, &meminfo_proc_fops); proc_create("baseinfo", 0, shm_driver_procdir, &baseinfo_proc_fops); pent = create_proc_entry("detail", 0, shm_driver_procdir); if (pent) pent->proc_fops = &detail_proc_ops; pstat = create_proc_entry("stat", 0, shm_driver_procdir); if (pstat) pstat->proc_fops = &shm_stat_file_ops; task_free_register(&shm_task_nb); shm_trace("shm_driver_init OK\n"); return 0; err_SHM_Init: shm_trace("shm_driver_init Undo ...\n"); shm_device_destroy(&shm_device); shm_device_destroy(&shm_device_noncache); /* del sysfs entries */ for (i = 0; i < ARRAY_SIZE(shm_driver_dev_list); i++) { device_destroy(shm_dev_class, MKDEV(GALOIS_SHM_MAJOR, shm_driver_dev_list[i].minor)); shm_debug("delete device sysfs [%s]\n", shm_driver_dev_list[i].name); } class_destroy(shm_dev_class); err_add_device: for (i = 0; i < ARRAY_SIZE(shm_driver_dev_list); i++) { cdev_del(shm_driver_dev_list[i].cdev); } unregister_chrdev_region(MKDEV(GALOIS_SHM_MAJOR, 0), GALOIS_SHM_MINORS); err_reg_device: of_node_put(np); err_node: shm_trace("shm_driver_init failed !!! (%d)\n", res); return res; }
static int __init shm_driver_init(void) { int res, i; /* Figure out our device number. */ res = register_chrdev_region(MKDEV(GALOIS_SHM_MAJOR, 0), GALOIS_SHM_MINORS, SHM_DEVICE_NAME); if (res < 0) { shm_error("unable to get shm device major [%d]\n", GALOIS_SHM_MAJOR); goto err_reg_device; } shm_debug("register cdev device major [%d]\n", GALOIS_SHM_MAJOR); /* Now setup cdevs. */ for (i = 0; i < ARRAY_SIZE(shm_driver_dev_list); i++) { res = shm_driver_setup_cdev(shm_driver_dev_list[i].cdev, GALOIS_SHM_MAJOR, shm_driver_dev_list[i].minor, shm_driver_dev_list[i].fops); if (res) { shm_error("shm_driver_setup_cdev failed in [%d].\n", i); goto err_add_device; } shm_debug("setup cdevs device minor [%d]\n", shm_driver_dev_list[i].minor); } /* add shm devices to sysfs */ shm_dev_class = class_create(THIS_MODULE, SHM_DEVICE_NAME); if (IS_ERR(shm_dev_class)) { shm_error("class_create failed.\n"); res = -ENODEV; goto err_add_device; } for (i = 0; i < ARRAY_SIZE(shm_driver_dev_list); i++) { device_create(shm_dev_class, NULL, MKDEV(GALOIS_SHM_MAJOR, shm_driver_dev_list[i].minor), NULL, shm_driver_dev_list[i].name); shm_debug("create device sysfs [%s]\n", shm_driver_dev_list[i].name); } /* create shm device*/ res = shm_device_create(&shm_device, shm_base, shm_size, SHM_DEVICE_THRESHOLD); if (res != 0) { shm_error("shm_device_create failed.\n"); goto err_add_device; } /* create shm kernel API */ res = MV_SHM_Init(shm_device); if (res != 0) { shm_error("MV_SHM_Init failed !!!\n"); goto err_SHM_Init; } /* create shm device proc file*/ shm_driver_procdir = proc_mkdir(SHM_DEVICE_NAME, NULL); shm_driver_procdir->owner = THIS_MODULE; create_proc_read_entry(SHM_DEVICE_PROCFILE_MEMINFO, 0, shm_driver_procdir, read_proc_meminfo, NULL); create_proc_read_entry(SHM_DEVICE_PROCFILE_BASEINFO, 0, shm_driver_procdir, read_proc_baseinfo, NULL); create_proc_read_entry(SHM_DEVICE_PROCFILE_DETAIL, 0, shm_driver_procdir, read_proc_detail, NULL); shm_trace("shm_driver_init OK\n"); return 0; err_SHM_Init: shm_trace("shm_driver_init Undo ...\n"); shm_device_destroy(&shm_device); /* del sysfs entries */ for (i = 0; i < ARRAY_SIZE(shm_driver_dev_list); i++) { device_destroy(shm_dev_class, MKDEV(GALOIS_SHM_MAJOR, shm_driver_dev_list[i].minor)); shm_debug("delete device sysfs [%s]\n", shm_driver_dev_list[i].name); } class_destroy(shm_dev_class); err_add_device: for (i = 0; i < ARRAY_SIZE(shm_driver_dev_list); i++) { cdev_del(shm_driver_dev_list[i].cdev); } unregister_chrdev_region(MKDEV(GALOIS_SHM_MAJOR, 0), GALOIS_SHM_MINORS); err_reg_device: shm_trace("shm_driver_init failed !!! (%d)\n", res); return res; }