示例#1
0
void __init setup_arch(char **cmdline_p)
{
	unsigned long bootmap_size;
	unsigned long start_pfn, max_pfn, max_low_pfn;

#ifdef CONFIG_EARLY_PRINTK
	extern void enable_early_printk(void);

	enable_early_printk();
#endif
#ifdef CONFIG_CMDLINE_BOOL
        strcpy(COMMAND_LINE, CONFIG_CMDLINE);
#endif

	ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);

#ifdef CONFIG_BLK_DEV_RAM
	rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
	rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
	rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
#endif

	if (!MOUNT_ROOT_RDONLY)
		root_mountflags &= ~MS_RDONLY;
	init_mm.start_code = (unsigned long) _text;
	init_mm.end_code = (unsigned long) _etext;
	init_mm.end_data = (unsigned long) _edata;
	init_mm.brk = (unsigned long) _end;

	code_resource.start = virt_to_bus(_text);
	code_resource.end = virt_to_bus(_etext)-1;
	data_resource.start = virt_to_bus(_etext);
	data_resource.end = virt_to_bus(_edata)-1;

	sh_mv_setup(cmdline_p);

#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
#define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
#define PFN_PHYS(x)	((x) << PAGE_SHIFT)

#ifdef CONFIG_DISCONTIGMEM
	NODE_DATA(0)->bdata = &discontig_node_bdata[0];
	NODE_DATA(1)->bdata = &discontig_node_bdata[1];

	bootmap_size = init_bootmem_node(NODE_DATA(1), 
					 PFN_UP(__MEMORY_START_2ND),
					 PFN_UP(__MEMORY_START_2ND),
					 PFN_DOWN(__MEMORY_START_2ND+__MEMORY_SIZE_2ND));
	free_bootmem_node(NODE_DATA(1), __MEMORY_START_2ND, __MEMORY_SIZE_2ND);
	reserve_bootmem_node(NODE_DATA(1), __MEMORY_START_2ND, bootmap_size);
#endif

	/*
	 * Find the highest page frame number we have available
	 */
	max_pfn = PFN_DOWN(__pa(memory_end));

	/*
	 * Determine low and high memory ranges:
	 */
	max_low_pfn = max_pfn;

 	/*
	 * Partially used pages are not usable - thus
	 * we are rounding upwards:
 	 */
	start_pfn = PFN_UP(__pa(_end));

	/*
	 * Find a proper area for the bootmem bitmap. After this
	 * bootstrap step all allocations (until the page allocator
	 * is intact) must be done via bootmem_alloc().
	 */
	bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn,
					 __MEMORY_START>>PAGE_SHIFT,
					 max_low_pfn);
	/*
	 * Register fully available low RAM pages with the bootmem allocator.
	 */
	{
		unsigned long curr_pfn, last_pfn, pages;

		/*
		 * We are rounding up the start address of usable memory:
		 */
		curr_pfn = PFN_UP(__MEMORY_START);
		/*
		 * ... and at the end of the usable range downwards:
		 */
		last_pfn = PFN_DOWN(__pa(memory_end));

		if (last_pfn > max_low_pfn)
			last_pfn = max_low_pfn;

		pages = last_pfn - curr_pfn;
		free_bootmem_node(NODE_DATA(0), PFN_PHYS(curr_pfn),
				  PFN_PHYS(pages));
	}

	/*
	 * Reserve the kernel text and
	 * Reserve the bootmem bitmap. We do this in two steps (first step
	 * was init_bootmem()), because this catches the (definitely buggy)
	 * case of us accidentally initializing the bootmem allocator with
	 * an invalid RAM area.
	 */
	reserve_bootmem_node(NODE_DATA(0), __MEMORY_START+PAGE_SIZE,
		(PFN_PHYS(start_pfn)+bootmap_size+PAGE_SIZE-1)-__MEMORY_START);

	/*
	 * reserve physical page 0 - it's a special BIOS page on many boxes,
	 * enabling clean reboots, SMP operation, laptop functions.
	 */
	reserve_bootmem_node(NODE_DATA(0), __MEMORY_START, PAGE_SIZE);

#ifdef CONFIG_BLK_DEV_INITRD
 	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
 	if (&__rd_start != &__rd_end) {
		LOADER_TYPE = 1;
		INITRD_START = PHYSADDR((unsigned long)&__rd_start) - __MEMORY_START;
		INITRD_SIZE = (unsigned long)&__rd_end - (unsigned long)&__rd_start;
 	}

	if (LOADER_TYPE && INITRD_START) {
		if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
			reserve_bootmem_node(NODE_DATA(0), INITRD_START+__MEMORY_START, INITRD_SIZE);
			initrd_start =
				INITRD_START ? INITRD_START + PAGE_OFFSET + __MEMORY_START : 0;
			initrd_end = initrd_start + INITRD_SIZE;
		} else {
			printk("initrd extends beyond end of memory "
			    "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
				    INITRD_START + INITRD_SIZE,
				    max_low_pfn << PAGE_SHIFT);
			initrd_start = 0;
		}
	}
#endif

#ifdef CONFIG_DUMMY_CONSOLE
	conswitchp = &dummy_con;
#endif

	/* Perform the machine specific initialisation */
	platform_setup();

	paging_init();
}
示例#2
0
static void __exit mod_exit(void)
{
    struct list_head *u;
    struct list_head *unext;
    struct list_head *registeredlistp;
    struct registered_user *user;
    int found_user;
    int i;

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

    unregister_chrdev(major, "edma");

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

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

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

            unext = u->next;

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

            u = unext;
        }

        if (found_user) {
            release_channel(i);
        }

        mutex_unlock(&edma_mutex);
    }

    __D("edma unregistered\n");
}
示例#3
0
文件: device.c 项目: Anjali05/linux
/*
 * device_setup_cdev - setup cdev and device for habanalabs device
 *
 * @hdev: pointer to habanalabs device structure
 * @hclass: pointer to the class object of the device
 * @minor: minor number of the specific device
 * @fpos : file operations to install for this device
 *
 * Create a cdev and a Linux device for habanalabs's device. Need to be
 * called at the end of the habanalabs device initialization process,
 * because this function exposes the device to the user
 */
static int device_setup_cdev(struct hl_device *hdev, struct class *hclass,
				int minor, const struct file_operations *fops)
{
	int err, devno = MKDEV(hdev->major, minor);
	struct cdev *hdev_cdev = &hdev->cdev;
	char *name;

	name = kasprintf(GFP_KERNEL, "hl%d", hdev->id);
	if (!name)
		return -ENOMEM;

	cdev_init(hdev_cdev, fops);
	hdev_cdev->owner = THIS_MODULE;
	err = cdev_add(hdev_cdev, devno, 1);
	if (err) {
		pr_err("Failed to add char device %s\n", name);
		goto err_cdev_add;
	}
示例#4
0
static void uio_major_cleanup(void)
{
    unregister_chrdev_region(MKDEV(uio_major, 0), UIO_MAX_DEVICES);
    cdev_del(uio_cdev);
}
示例#5
0
/*
 * 模块加载方法
 */
static ini __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);
	/*
	 * 分配hello设备结构体变量
	 */
	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 = PRT_ERR(temp);
		printk(KERN_ALERT"Failed to create hello device.\n");
		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.\n");
		goto destroy_device;
	}
	dev_set_drvdata(temp, hello_dev);
	/*
	 * 创建/proc/hello文件
	 */
	hello_create_proc();
	printk(KERN_ALERT"Successed to initalize 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;
}
void timed_output_dev_unregister(struct timed_output_dev *tdev)
{
	device_remove_file(tdev->dev, &dev_attr_enable);
	dev_set_drvdata(tdev->dev, NULL);
	device_destroy(timed_output_class, MKDEV(0, tdev->index));
}
示例#7
0
static int __init rtlx_module_init(void)
{
	struct device *dev;
	int i, err;

	if (!cpu_has_mipsmt) {
		printk("VPE loader: not a MIPS MT capable processor\n");
		return -ENODEV;
	}

	if (tclimit == 0) {
		printk(KERN_WARNING "No TCs reserved for AP/SP, not "
		       "initializing RTLX.\nPass maxtcs=<n> argument as kernel "
		       "argument\n");

		return -ENODEV;
	}

	major = register_chrdev(0, module_name, &rtlx_fops);
	if (major < 0) {
		printk(register_chrdev_failed);
		return major;
	}

	/* initialise the wait queues */
	for (i = 0; i < RTLX_CHANNELS; i++) {
		init_waitqueue_head(&channel_wqs[i].rt_queue);
		init_waitqueue_head(&channel_wqs[i].lx_queue);
		atomic_set(&channel_wqs[i].in_open, 0);
		mutex_init(&channel_wqs[i].mutex);

		dev = device_create(mt_class, NULL, MKDEV(major, i), NULL,
				    "%s%d", module_name, i);
		if (IS_ERR(dev)) {
			err = PTR_ERR(dev);
			goto out_chrdev;
		}
	}

	/* set up notifiers */
	notify.start = starting;
	notify.stop = stopping;
	vpe_notify(tclimit, &notify);

	if (cpu_has_vint)
		set_vi_handler(MIPS_CPU_RTLX_IRQ, rtlx_dispatch);
	else {
		pr_err("APRP RTLX init on non-vectored-interrupt processor\n");
		err = -ENODEV;
		goto out_chrdev;
	}

	rtlx_irq.dev_id = rtlx;
	setup_irq(rtlx_irq_num, &rtlx_irq);

	return 0;

out_chrdev:
	for (i = 0; i < RTLX_CHANNELS; i++)
		device_destroy(mt_class, MKDEV(major, i));

	return err;
}
示例#8
0
dev_t name_to_dev_t(char *name)
{
	char s[32];
	char *p;
	dev_t res = 0;
	int part;

#ifdef CONFIG_BLOCK
	if (strncmp(name, "PARTUUID=", 9) == 0) {
		name += 9;
		if (strlen(name) != 36)
			goto fail;
		res = devt_from_partuuid(name);
		if (!res)
			goto fail;
		goto done;
	}
#endif

	if (strncmp(name, "/dev/", 5) != 0) {
		unsigned maj, min;

		if (sscanf(name, "%u:%u", &maj, &min) == 2) {
			res = MKDEV(maj, min);
			if (maj != MAJOR(res) || min != MINOR(res))
				goto fail;
		} else {
			res = new_decode_dev(simple_strtoul(name, &p, 16));
			if (*p)
				goto fail;
		}
		goto done;
	}

	name += 5;
	res = Root_NFS;
	if (strcmp(name, "nfs") == 0)
		goto done;
	res = Root_RAM0;
	if (strcmp(name, "ram") == 0)
		goto done;

	if (strlen(name) > 31)
		goto fail;
	strcpy(s, name);
	for (p = s; *p; p++)
		if (*p == '/')
			*p = '!';
	res = blk_lookup_devt(s, 0);
	if (res)
		goto done;

	/*
	 * try non-existent, but valid partition, which may only exist
	 * after revalidating the disk, like partitioned md devices
	 */
	while (p > s && isdigit(p[-1]))
		p--;
	if (p == s || !*p || *p == '0')
		goto fail;

	/* try disk name without <part number> */
	part = simple_strtoul(p, NULL, 10);
	*p = '\0';
	res = blk_lookup_devt(s, part);
	if (res)
		goto done;

	/* try disk name without p<part number> */
	if (p < s + 2 || !isdigit(p[-2]) || p[-1] != 'p')
		goto fail;
	p[-1] = '\0';
	res = blk_lookup_devt(s, part);
	if (res)
		goto done;

fail:
	return 0;
done:
	return res;
}
示例#9
0
static int __init init_function(void)
{
int ret,l;
	#ifdef DEBUG
	printk(KERN_INFO "Begin: %s\n",__func__);
	#endif	
	quantum = QUANTUMSIZ;
	qset = QSETSIZ;
	size = DEVICESIZ;
	minor_no = MINOR_NO; 
//	scull.c_dev.owner = THIS_MODULE;
//	scull.c_dev.ops = &fops;
	nod = NOD;

	ret = alloc_chrdev_region(&devno,minor_no,NOD,DEV_NAME);		// if i give minor no 0 here thn alloc_chrdev_region will register only for minor_no 0 ??????
	if(ret < 0)
	{
		#ifdef DEBUG
		printk(KERN_ALERT "alloc_chrdev_region() fails\n");
		#endif
		return ret;
	}
		temp_devno = devno;
		major_no = MAJOR(temp_devno);
	
	for(l = 0;l< NOD; l++)
	{
		temp_devno = MKDEV(major_no,minor_no + l);	//devno changed here which is causing trouble in unregistre_chrdev_region due to which allocated devno device is not unregisterd?????????
	
		dev[l] = (struct scull_dev *)kmalloc(sizeof(struct scull_dev),GFP_KERNEL);
		memset(dev[l],'\0',sizeof(struct scull_dev));
		
		dev[l]->quantum = quantum;
		dev[l]->qset = qset;
		dev[l]->size = size;
		dev[l]->c_dev.owner = THIS_MODULE;
		dev[l]->c_dev.ops = &fops;
		dev[l]->c_dev.dev = temp_devno;
		dev[l]->c_dev.count = nod;
		
		//major_no = MAJOR(devno);
		//minor_no = MINOR(devno);
		
		if(check_region(0x378,3) < 0)
		{		
			release_region(0x378,3);
		}
		
		if(request_region(0x378,3,"MYPP") == NULL)
		{
			#ifdef DEBUG
			printk(KERN_INFO "requset_region fails\n");
			#endif
			return -1;
		}


		cdev_init(&dev[l]->c_dev,&fops);
		sema_init(&dev[l]->sem,1);
		ret = cdev_add(&dev[l]->c_dev,temp_devno,nod);
		if(ret <= -1){
			#ifdef DEBUG
			printk(KERN_ERR "cdev_add() fails\n");
			#endif
			return ret;
		}

		#ifdef DEBUG
		printk(KERN_INFO "major_no: %d minor_no: %d\n",MAJOR(temp_devno),MINOR(temp_devno));
		#endif
	
	}
	//minor_no = 1;	
	#ifdef DEBUG
	printk(KERN_INFO "End: %s\n",__func__);
	#endif

return 0;
}
示例#10
0
static dev_t try_name(char *name, int part)
{
	char path[64];
	char buf[32];
	int range;
	dev_t res;
	char *s;
	int len;
	int fd;
	unsigned int maj, min;

	/* read device number from .../dev */

	sprintf(path, "/sys/block/%s/dev", name);
	fd = sys_open(path, 0, 0);
	if (fd < 0)
		goto fail;
	len = sys_read(fd, buf, 32);
	sys_close(fd);
	if (len <= 0 || len == 32 || buf[len - 1] != '\n')
		goto fail;
	buf[len - 1] = '\0';
	if (sscanf(buf, "%u:%u", &maj, &min) == 2) {
		/*
		 * Try the %u:%u format -- see print_dev_t()
		 */
		res = MKDEV(maj, min);
		if (maj != MAJOR(res) || min != MINOR(res))
			goto fail;
	} else {
		/*
		 * Nope.  Try old-style "0321"
		 */
		res = new_decode_dev(simple_strtoul(buf, &s, 16));
		if (*s)
			goto fail;
	}

	/* if it's there and we are not looking for a partition - that's it */
	if (!part)
		return res;

	/* otherwise read range from .../range */
	sprintf(path, "/sys/block/%s/range", name);
	fd = sys_open(path, 0, 0);
	if (fd < 0)
		goto fail;
	len = sys_read(fd, buf, 32);
	sys_close(fd);
	if (len <= 0 || len == 32 || buf[len - 1] != '\n')
		goto fail;
	buf[len - 1] = '\0';
	range = simple_strtoul(buf, &s, 10);
	if (*s)
		goto fail;

	/* if partition is within range - we got it */
	if (part < range)
		return res + part;
fail:
	return 0;
}
#define MTK_MJC_DEV_MAJOR_NUMBER 168
#define MJC_FORCE_REG_NUM 100
#define EFUSE_MJC_IDX (3)
#define EFUSE_MJC_BIT (1<<16)

//**************************************************//
// variable
//**************************************************//
static DEFINE_SPINLOCK(ContextLock);
static DEFINE_SPINLOCK(HWLock);


static MJC_CONTEXT_T grContext;        //spinlock : ContextLock
static MJC_CONTEXT_T grHWLockContext;  //spinlock : HWLock

static dev_t mjc_devno = MKDEV(MTK_MJC_DEV_MAJOR_NUMBER,0);
static struct cdev *g_mjc_cdev;
static struct class *pMjcClass = NULL;
static struct device* mjcDevice = NULL;
unsigned long gulRegister, gu1PaReg, gu1PaSize;
int gi4IrqID;
MJC_WRITE_REG_T gfWriteReg[MJC_FORCE_REG_NUM];


/*****************************************************************************
 * FUNCTION
 *    _mjc_CreateEvent
 * DESCRIPTION
 *
 * PARAMETERS
 *    None.
示例#12
0
dev_t name_to_dev_t(char *name)
{
	char s[32];
	char *p;
	dev_t res = 0;
	int part;

#ifdef CONFIG_SYSFS
	int mkdir_err = sys_mkdir("/sys", 0700);
	if (sys_mount("sysfs", "/sys", "sysfs", 0, NULL) < 0)
		goto out;
#endif

	if (strncmp(name, "/dev/", 5) != 0) {
		unsigned maj, min;

		if (sscanf(name, "%u:%u", &maj, &min) == 2) {
			res = MKDEV(maj, min);
			if (maj != MAJOR(res) || min != MINOR(res))
				goto fail;
		} else {
			res = new_decode_dev(simple_strtoul(name, &p, 16));
			if (*p)
				goto fail;
		}
		goto done;
	}
	name += 5;
	res = Root_NFS;
	if (strcmp(name, "nfs") == 0)
		goto done;
	res = Root_RAM0;
	if (strcmp(name, "ram") == 0)
		goto done;

	if (strlen(name) > 31)
		goto fail;
	strcpy(s, name);
	for (p = s; *p; p++)
		if (*p == '/')
			*p = '!';
	res = try_name(s, 0);
	if (res)
		goto done;

	while (p > s && isdigit(p[-1]))
		p--;
	if (p == s || !*p || *p == '0')
		goto fail;
	part = simple_strtoul(p, NULL, 10);
	*p = '\0';
	res = try_name(s, part);
	if (res)
		goto done;

	if (p < s + 2 || !isdigit(p[-2]) || p[-1] != 'p')
		goto fail;
	p[-1] = '\0';
	res = try_name(s, part);
done:
#ifdef CONFIG_SYSFS
	sys_umount("/sys", 0);
out:
	if (!mkdir_err)
		sys_rmdir("/sys");
#endif
	return res;
fail:
	res = 0;
	goto done;
}
示例#13
0
/*----------------------------------------------------------
 *	pipe_init
 *---------------------------------------------------------*/
static int pipe_init(void)
{
	dev_t dev = MKDEV(pipe_major, 0);
	int alloc_ret = 0;
	int cdev_err = 0;
    struct device *class_dev = NULL;

	/*
	* register major number
	*/
	/* reserve major number */
	if (pipe_major) {
		alloc_ret = register_chrdev_region(dev, pipe_dev_count, DRIVER_NAME);
		if (alloc_ret < 0) {
			printk(KERN_ERR "pipe: unable to get major %d\n", pipe_major);
			goto error;
		}
		if (pipe_major == 0)
			pipe_major = alloc_ret;
	}
	else {
		alloc_ret = alloc_chrdev_region(&dev, pipe_minor, pipe_dev_count, DRIVER_NAME);
		if (alloc_ret) {
			printk(KERN_ERR "pipe: unable to get major \n");
			goto error;
		}
		pipe_major = MAJOR(dev);
	}

	/* register system call handler(fops) */
	cdev_init(&pipe_cdev, &pipe_ops);

	/* register to kernel */
	pipe_cdev.owner = THIS_MODULE;
	pipe_cdev.ops = &pipe_ops;
	cdev_err = cdev_add (&pipe_cdev, MKDEV(pipe_major, pipe_minor), pipe_dev_count);

	if (cdev_err) {
		goto error;
	}

	/* register class */
	pipe_class = class_create(THIS_MODULE, DRIVER_NAME);
	if (IS_ERR(pipe_class)) {
		goto error;
	}
	class_dev = device_create(pipe_class, NULL, MKDEV(pipe_major, pipe_minor), NULL, DRIVER_NAME);

	if (IS_ERR(class_dev))
		printk(KERN_ERR "pipe: can't create device\n");

	return 0;
  
error:
	if (cdev_err == 0)
		cdev_del(&pipe_cdev);
	
	if (alloc_ret == 0)
		unregister_chrdev_region(MKDEV(pipe_major, 0), pipe_dev_count);

	return -1;
}
示例#14
0
                                              
#define SENSOR_LOG_DEBUG(fmt, args...) printk(KERN_DEBUG "[%s] [%s: %d] "  fmt,\
                                              LOG_TAG,__FUNCTION__, __LINE__, ##args)
    #else
#define SENSOR_LOG_INFO(fmt, args...)
#define SENSOR_LOG_DEBUG(fmt, args...)
    #endif

#else
#define SENSOR_LOG_ERROR(fmt, args...)
#define SENSOR_LOG_INFO(fmt, args...)
#define SENSOR_LOG_DEBUG(fmt, args...)
#endif

 
static dev_t const   hall_device_dev_t   = MKDEV(MISC_MAJOR, 252);

static struct class  *hall_device_class;

static const struct dev_pm_ops hall_device_pm_ops = {
    .suspend = hall_device_suspend,
    .resume  = hall_device_resume,
};

static const struct i2c_device_id hall_device_idtable_id[] = {
     { "zte,hall_pair_out", 0 },
     { },
 };
 
static struct of_device_id of_hall_device_idtable[] = {
     { .compatible = "zte,hall_pair_out",},
示例#15
0
/*!
 * This function is called by the driver framework to initialize the LDB
 * device.
 *
 * @param	dev	The device structure for the LDB passed in by the
 *			driver framework.
 *
 * @return      Returns 0 on success or negative error code on error
 */
static int ldb_probe(struct platform_device *pdev)
{
	int ret = 0;
	struct resource *res;
	struct ldb_platform_data *plat_data = pdev->dev.platform_data;
	uint32_t reg;
	struct device *temp;
	int mxc_ldb_major;
	struct class *mxc_ldb_class;

	if ((plat_data->boot_enable & (MXC_LDBDI0 | MXC_LDBDI1))
		&& !g_enable_ldb) {
		g_enable_ldb = MXC_ENABLE;
		if (plat_data->boot_enable & MXC_LDBDI0)
			g_di0_used = true;
		if (plat_data->boot_enable & MXC_LDBDI1)
			g_di1_used = true;
	}

	if (!g_enable_ldb)
		g_enable_ldb = MXC_DISABLE;

	if (g_enable_ldb == MXC_DISABLE) {
		printk(KERN_WARNING "By setting, LDB driver will not be enabled\n");
		return -ENODEV;
	}

	spin_lock_init(&ldb_lock);

	g_ldb_dev = &pdev->dev;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (IS_ERR(res))
		return -ENODEV;

	memset(&ldb, 0, sizeof(struct ldb_data));
	ldb.chan_mode_opt = g_chan_mode_opt;
	ldb.chan_bit_map[0] = g_chan_bit_map[0];
	ldb.chan_bit_map[1] = g_chan_bit_map[1];

	ldb.base_addr = res->start;
	ldb_reg = ioremap(ldb.base_addr, res->end - res->start + 1);
	ldb.control_reg = ldb_reg + 2;

	ldb.bgref_rmode = plat_data->ext_ref;
	ldb.lvds_bg_reg = regulator_get(&pdev->dev, plat_data->lvds_bg_reg);
	if (!IS_ERR(ldb.lvds_bg_reg)) {
		regulator_set_voltage(ldb.lvds_bg_reg, 2500000, 2500000);
		regulator_enable(ldb.lvds_bg_reg);
	}

	reg = __raw_readl(ldb.control_reg);
	if (ldb.bgref_rmode == LDB_EXT_REF)
		__raw_writel((reg & ~LDB_BGREF_RMODE_MASK) |
			      LDB_BGREF_RMODE_EXT, ldb.control_reg);
	else
		__raw_writel((reg & ~LDB_BGREF_RMODE_MASK) |
			      LDB_BGREF_RMODE_INT, ldb.control_reg);

	mxc_ldb_major = register_chrdev(0, "mxc_ldb", &mxc_ldb_fops);
	if (mxc_ldb_major < 0) {
		dev_err(g_ldb_dev, "Unable to register MXC LDB as a char "
				   "device\n");
		ret = mxc_ldb_major;
		goto err0;
	}

	mxc_ldb_class = class_create(THIS_MODULE, "mxc_ldb");
	if (IS_ERR(mxc_ldb_class)) {
		dev_err(g_ldb_dev, "Unable to create class for MXC LDB\n");
		ret = PTR_ERR(mxc_ldb_class);
		goto err1;
	}

	temp = device_create(mxc_ldb_class, NULL, MKDEV(mxc_ldb_major, 0),
			NULL, "mxc_ldb");
	if (IS_ERR(temp)) {
		dev_err(g_ldb_dev, "Unable to create class device for "
				   "MXC LDB\n");
		ret = PTR_ERR(temp);
		goto err2;
	}

	if (g_di0_used) {
		mxcfb_register_mode(0, mxcfb_ldb_modedb,
				mxcfb_ldb_modedb_sz,
				MXC_DISP_SPEC_DEV);
		mxcfb_register_presetup(0, ldb_fb_pre_setup);
	}
	if (g_di1_used) {
		mxcfb_register_mode(1, mxcfb_ldb_modedb,
				mxcfb_ldb_modedb_sz,
				MXC_DISP_SPEC_DEV);
		mxcfb_register_presetup(1, ldb_fb_pre_setup);
	}

	ret = fb_register_client(&nb);
	if (ret < 0)
		goto err2;

	ldb.blank[0] = ldb.blank[1] = -1;

	return ret;
err2:
	class_destroy(mxc_ldb_class);
err1:
	unregister_chrdev(mxc_ldb_major, "mxc_ldb");
err0:
	iounmap(ldb_reg);
	return ret;
}
static int WIFI_init(void)
{
    dev_t dev = MKDEV(WIFI_major, 0);
    INT32 alloc_ret = 0;
    INT32 cdev_err = 0;
#if WMT_CREATE_NODE_DYNAMIC
    struct device * wmtwifi_dev = NULL;
#endif

    /* static allocate chrdev */
    alloc_ret = register_chrdev_region(dev, 1, WIFI_DRIVER_NAME);
    if (alloc_ret) {
        WIFI_ERR_FUNC("Fail to register chrdev\n");
        return alloc_ret;
    }

    cdev_init(&WIFI_cdev, &WIFI_fops);
    WIFI_cdev.owner = THIS_MODULE;

    cdev_err = cdev_add(&WIFI_cdev, dev, WIFI_devs);
    if (cdev_err) {
        goto error;
    }

#if WMT_CREATE_NODE_DYNAMIC  //mknod replace
    wmtwifi_class = class_create(THIS_MODULE,"wmtWifi");
    if(IS_ERR(wmtwifi_class))
        goto error;
    wmtwifi_dev = device_create(wmtwifi_class,NULL,dev,NULL,"wmtWifi");
    if(IS_ERR(wmtwifi_dev))
        goto error;
#endif

    sema_init(&wr_mtx, 1);

    WIFI_INFO_FUNC("%s driver(major %d) installed.\n", WIFI_DRIVER_NAME, WIFI_major);
    retflag = 0;
    wlan_mode = WLAN_MODE_HALT;
    pf_set_p2p_mode = NULL;

    return 0;

error:
#if WMT_CREATE_NODE_DYNAMIC
    if(!IS_ERR(wmtwifi_dev))
        device_destroy(wmtwifi_class,dev);
    if(!IS_ERR(wmtwifi_class)){
        class_destroy(wmtwifi_class);
        wmtwifi_class = NULL;
    }
#endif

    if (cdev_err == 0) {
        cdev_del(&WIFI_cdev);
    }

    if (alloc_ret == 0) {
        unregister_chrdev_region(dev, WIFI_devs);
    }

    return -1;
}
示例#17
0
\************************************************************************/

#include <linux/interrupt.h>
#include <linux/version.h>
#include <linux/ioport.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/cdev.h>
#include <linux/fs.h>

#include <asm/uaccess.h>
#include <asm/io.h>

	static char * nom_module = "exemple_13_B";

	static dev_t dev_exemple = MKDEV(0, 0);

	static int numero = 0;
	module_param(numero, int, 0644);

	static int irq_number = 1;
	module_param(irq_number, int, 0444);

	static struct cdev cdev_exemple;

	static int read_exemple  (struct file * filp, char * buffer,
	                          size_t length, loff_t * offset);

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
	static irqreturn_t irq_handler(int irq, void * ident, struct pt_regs * unused);
#else
示例#18
0
static void __init unix98_pty_init(void)
{
	ptm_driver = alloc_tty_driver(NR_UNIX98_PTY_MAX);
	if (!ptm_driver)
		panic("Couldn't allocate Unix98 ptm driver");
	pts_driver = alloc_tty_driver(NR_UNIX98_PTY_MAX);
	if (!pts_driver)
		panic("Couldn't allocate Unix98 pts driver");

	ptm_driver->owner = THIS_MODULE;
	ptm_driver->driver_name = "pty_master";
	ptm_driver->name = "ptm";
	ptm_driver->major = UNIX98_PTY_MASTER_MAJOR;
	ptm_driver->minor_start = 0;
	ptm_driver->type = TTY_DRIVER_TYPE_PTY;
	ptm_driver->subtype = PTY_TYPE_MASTER;
	ptm_driver->init_termios = tty_std_termios;
	ptm_driver->init_termios.c_iflag = 0;
	ptm_driver->init_termios.c_oflag = 0;
	ptm_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
	ptm_driver->init_termios.c_lflag = 0;
	ptm_driver->init_termios.c_ispeed = 38400;
	ptm_driver->init_termios.c_ospeed = 38400;
	ptm_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW |
		TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM;
	ptm_driver->other = pts_driver;
	tty_set_operations(ptm_driver, &ptm_unix98_ops);

	pts_driver->owner = THIS_MODULE;
	pts_driver->driver_name = "pty_slave";
	pts_driver->name = "pts";
	pts_driver->major = UNIX98_PTY_SLAVE_MAJOR;
	pts_driver->minor_start = 0;
	pts_driver->type = TTY_DRIVER_TYPE_PTY;
	pts_driver->subtype = PTY_TYPE_SLAVE;
	pts_driver->init_termios = tty_std_termios;
	pts_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
	pts_driver->init_termios.c_ispeed = 38400;
	pts_driver->init_termios.c_ospeed = 38400;
	pts_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW |
		TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM;
	pts_driver->other = ptm_driver;
	tty_set_operations(pts_driver, &pty_unix98_ops);

	if (tty_register_driver(ptm_driver))
		panic("Couldn't register Unix98 ptm driver");
	if (tty_register_driver(pts_driver))
		panic("Couldn't register Unix98 pts driver");

	register_sysctl_table(pty_root_table);

	/* Now create the /dev/ptmx special device */
	tty_default_fops(&ptmx_fops);
	ptmx_fops.open = ptmx_open;

	cdev_init(&ptmx_cdev, &ptmx_fops);
	if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) ||
	    register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0)
		panic("Couldn't register /dev/ptmx driver\n");
	device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
}
示例#19
0
void __init prom_init(void)
{
	char *ptr;

	cfe_init(cfe_handle, cfe_entry);

	bchip_check_compat();
	board_pinmux_setup();

	bchip_mips_setup();
	set_board_nmi_handler();

	/* default to SATA (where available) or MTD rootfs */
#ifdef CONFIG_BRCM_HAS_SATA
	ROOT_DEV = Root_SDA1;
#else
	ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, 0);
#endif
	root_mountflags &= ~MS_RDONLY;

	bchip_set_features();

#if defined(CONFIG_BRCM_IKOS_DEBUG)
	strcpy(arcs_cmdline, "debug initcall_debug");
#elif !defined(CONFIG_BRCM_IKOS)
	cfe_read_configuration();
#endif
	brcm_setup_early_printk();

#ifdef CONFIG_CMDLINE_BOOL
#ifdef CONFIG_CMDLINE_OVERRIDE
	strlcpy(arcs_cmdline, builtin_cmdline, COMMAND_LINE_SIZE);
#else
	if (builtin_cmdline[0]) {
		strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
		strlcat(arcs_cmdline, builtin_cmdline, COMMAND_LINE_SIZE);
	}
#endif
#endif
	/* provide "ubiroot" alias to reduce typing */
	if (strstr(arcs_cmdline, "ubiroot"))
		strcat(arcs_cmdline, " ubi.mtd=rootfs rootfstype=ubifs "
			"root=ubi0:rootfs");

	ptr = strstr(arcs_cmdline, "memc1=");
	if (ptr)
		brcm_dram1_linux_mb = memparse(ptr + 6, &ptr) >> 20;

	printk(KERN_INFO "Options: enet_en=%d enet0_mii=%d enet_no_mdio=%d "
		"enet1_en=%d moca=%d\n",
		brcm_enet_enabled, brcm_enet0_force_ext_mii,
		brcm_enet_no_mdio, brcm_enet1_enabled, brcm_moca_enabled);
	printk(KERN_INFO "         sata=%d docsis=%d pci=%d pcie=%d smp=%d "
		"usb=%d\n",
		brcm_sata_enabled, brcm_docsis_platform, brcm_pci_enabled,
		brcm_pcie_enabled, brcm_smp_enabled, brcm_usb_enabled);

	bchip_early_setup();

	board_get_ram_size(&brcm_dram0_size_mb, &brcm_dram1_size_mb);

	do {
		unsigned long dram0_mb = brcm_dram0_size_mb, mb;

		mb = min(dram0_mb, BRCM_MAX_LOWER_MB);
		dram0_mb -= mb;

		add_memory_region(0, mb << 20, BOOT_MEM_RAM);
		if (!dram0_mb)
			break;

#ifdef CONFIG_BRCM_UPPER_MEMORY
		mb = min(dram0_mb, BRCM_MAX_UPPER_MB);
		dram0_mb -= mb;

		brcm_upper_tlb_setup();
		add_memory_region(UPPERMEM_START, mb << 20, BOOT_MEM_RAM);
		if (!dram0_mb)
			break;
#endif

#if defined(CONFIG_HIGHMEM)
		add_memory_region(HIGHMEM_START, dram0_mb << 20, BOOT_MEM_RAM);
		break;
#endif
		/*
		 * We wound up here because the chip's architecture cannot
		 * make use of all MEMC0 RAM in Linux.  i.e. no suitable
		 * HIGHMEM or upper memory options are supported by the CPU.
		 *
		 * But we can still report the excess memory as a "bonus"
		 * reserved (bmem) region, so the application can manage it.
		 */
		mb = brcm_dram0_size_mb - dram0_mb;	/* Linux memory */
		if (!brcm_dram1_size_mb && mb == 256) {
			printk(KERN_INFO "MEMC0 split: %lu MB -> Linux; "
				"%lu MB -> extra bmem\n", mb, dram0_mb);
			brcm_dram1_size_mb = dram0_mb;
			brcm_dram1_start = UPPERMEM_START;
		}
	} while (0);

#if defined(CONFIG_HIGHMEM) && defined(CONFIG_BRCM_HAS_1GB_MEMC1)
	if (brcm_dram1_linux_mb > brcm_dram1_size_mb) {
		printk(KERN_WARNING "warning: 'memc1=%luM' exceeds "
			"available memory (%lu MB); ignoring\n",
			brcm_dram1_linux_mb, brcm_dram1_size_mb);
		brcm_dram1_linux_mb = 0;
	} else if (brcm_dram1_linux_mb) {
		/* Since the bootloader can only map the first 256M of memc1
		 * when it boots, if we get memc1= request from bootloader, we
		 * should try to pull the memory from the end to avoid crossing
		 * over the memory that is allocated for boot logo image by
		 * bootloader.
		 */
		unsigned long start_mb, start_b, size, splash_bound = 0;
		if (0 == parse_splash_mem(arcs_cmdline, &splash_bound, &size)) {
			splash_bound += size;
		}

		start_mb = brcm_dram1_size_mb - brcm_dram1_linux_mb;
		start_b  = start_mb << 20;
		if (splash_bound > start_b) {
			unsigned long orig_dram1 = brcm_dram1_linux_mb;
			start_mb = (splash_bound + 0x000FFFFF) >> 20;
			start_b = start_mb << 20;
			brcm_dram1_linux_mb = brcm_dram1_size_mb - start_mb;
			printk(KERN_WARNING "warning: 'memc1=%luM' starts "
			       " before splash memory bound (0x%lx);"
			       " adjusting to (memc1=%luM)\n",
			       orig_dram1, splash_bound, brcm_dram1_linux_mb);
		}
		printk(KERN_INFO "memc1: adding %luMB at %luMB "
		       "(0x%08lx@0x%08lx)",
		       brcm_dram1_linux_mb, (MEMC1_START >> 20) + start_mb,
		       brcm_dram1_linux_mb << 20, MEMC1_START + start_b);
		add_memory_region(MEMC1_START + start_b,
				  brcm_dram1_linux_mb << 20,
				  BOOT_MEM_RAM);
	}
示例#20
0
文件: zvol.c 项目: 10144161/zfs
static int
__zvol_create_minor(const char *name, boolean_t ignore_snapdev)
{
	zvol_state_t *zv;
	objset_t *os;
	dmu_object_info_t *doi;
	uint64_t volsize;
	uint64_t len;
	unsigned minor = 0;
	int error = 0;

	ASSERT(MUTEX_HELD(&zvol_state_lock));

	zv = zvol_find_by_name(name);
	if (zv) {
		error = SET_ERROR(EEXIST);
		goto out;
	}

	if (ignore_snapdev == B_FALSE) {
		error = __zvol_snapdev_hidden(name);
		if (error)
			goto out;
	}

	doi = kmem_alloc(sizeof (dmu_object_info_t), KM_SLEEP);

	error = dmu_objset_own(name, DMU_OST_ZVOL, B_TRUE, zvol_tag, &os);
	if (error)
		goto out_doi;

	error = dmu_object_info(os, ZVOL_OBJ, doi);
	if (error)
		goto out_dmu_objset_disown;

	error = zap_lookup(os, ZVOL_ZAP_OBJ, "size", 8, 1, &volsize);
	if (error)
		goto out_dmu_objset_disown;

	error = zvol_find_minor(&minor);
	if (error)
		goto out_dmu_objset_disown;

	zv = zvol_alloc(MKDEV(zvol_major, minor), name);
	if (zv == NULL) {
		error = SET_ERROR(EAGAIN);
		goto out_dmu_objset_disown;
	}

	if (dmu_objset_is_snapshot(os))
		zv->zv_flags |= ZVOL_RDONLY;

	zv->zv_volblocksize = doi->doi_data_block_size;
	zv->zv_volsize = volsize;
	zv->zv_objset = os;

	set_capacity(zv->zv_disk, zv->zv_volsize >> 9);

	blk_queue_max_hw_sectors(zv->zv_queue, (DMU_MAX_ACCESS / 4) >> 9);
	blk_queue_max_segments(zv->zv_queue, UINT16_MAX);
	blk_queue_max_segment_size(zv->zv_queue, UINT_MAX);
	blk_queue_physical_block_size(zv->zv_queue, zv->zv_volblocksize);
	blk_queue_io_opt(zv->zv_queue, zv->zv_volblocksize);
	blk_queue_max_discard_sectors(zv->zv_queue,
	    (zvol_max_discard_blocks * zv->zv_volblocksize) >> 9);
	blk_queue_discard_granularity(zv->zv_queue, zv->zv_volblocksize);
	queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, zv->zv_queue);
#ifdef QUEUE_FLAG_NONROT
	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, zv->zv_queue);
#endif
#ifdef QUEUE_FLAG_ADD_RANDOM
	queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, zv->zv_queue);
#endif

	if (spa_writeable(dmu_objset_spa(os))) {
		if (zil_replay_disable)
			zil_destroy(dmu_objset_zil(os), B_FALSE);
		else
			zil_replay(os, zv, zvol_replay_vector);
	}

	/*
	 * When udev detects the addition of the device it will immediately
	 * invoke blkid(8) to determine the type of content on the device.
	 * Prefetching the blocks commonly scanned by blkid(8) will speed
	 * up this process.
	 */
	len = MIN(MAX(zvol_prefetch_bytes, 0), SPA_MAXBLOCKSIZE);
	if (len > 0) {
		dmu_prefetch(os, ZVOL_OBJ, 0, 0, len, ZIO_PRIORITY_SYNC_READ);
		dmu_prefetch(os, ZVOL_OBJ, 0, volsize - len, len,
			ZIO_PRIORITY_SYNC_READ);
	}

	zv->zv_objset = NULL;
out_dmu_objset_disown:
	dmu_objset_disown(os, zvol_tag);
out_doi:
	kmem_free(doi, sizeof (dmu_object_info_t));
out:

	if (error == 0) {
		zvol_insert(zv);
		add_disk(zv->zv_disk);
	}

	return (SET_ERROR(error));
}
示例#21
0
static int __init pc8736x_gpio_init(void)
{
	int rc;
	dev_t devid;

	pdev = platform_device_alloc(DEVNAME, 0);
	if (!pdev)
		return -ENOMEM;

	rc = platform_device_add(pdev);
	if (rc) {
		rc = -ENODEV;
		goto undo_platform_dev_alloc;
	}
	dev_info(&pdev->dev, "NatSemi pc8736x GPIO Driver Initializing\n");

	if (!pc8736x_superio_present()) {
		rc = -ENODEV;
		dev_err(&pdev->dev, "no device found\n");
		goto undo_platform_dev_add;
	}
	pc8736x_gpio_ops.dev = &pdev->dev;
        __VERIFIER_assert(pc8736x_gpio_ops.dev == &pdev->dev);

	/* Verify that chip and it's GPIO unit are both enabled.
	   My BIOS does this, so I take minimum action here
	 */
	rc = superio_inb(SIO_CF1);
	if (!(rc & 0x01)) {
		rc = -ENODEV;
		dev_err(&pdev->dev, "device not enabled\n");
		goto undo_platform_dev_add;
	}
	device_select(SIO_GPIO_UNIT);
	if (!superio_inb(SIO_UNIT_ACT)) {
		rc = -ENODEV;
		dev_err(&pdev->dev, "GPIO unit not enabled\n");
		goto undo_platform_dev_add;
	}

	/* read the GPIO unit base addr that chip responds to */
	pc8736x_gpio_base = (superio_inb(SIO_BASE_HADDR) << 8
			     | superio_inb(SIO_BASE_LADDR));

	if (!request_region(pc8736x_gpio_base, PC8736X_GPIO_RANGE, DEVNAME)) {
		rc = -ENODEV;
		dev_err(&pdev->dev, "GPIO ioport %x busy\n",
			pc8736x_gpio_base);
		goto undo_platform_dev_add;
	}
	dev_info(&pdev->dev, "GPIO ioport %x reserved\n", pc8736x_gpio_base);

	if (major) {
		devid = MKDEV(major, 0);
		rc = register_chrdev_region(devid, PC8736X_GPIO_CT, DEVNAME);
	} else {
		rc = alloc_chrdev_region(&devid, 0, PC8736X_GPIO_CT, DEVNAME);
		major = MAJOR(devid);
	}

	if (rc < 0) {
		dev_err(&pdev->dev, "register-chrdev failed: %d\n", rc);
		goto undo_request_region;
	}
	if (!major) {
		major = rc;
		dev_dbg(&pdev->dev, "got dynamic major %d\n", major);
	}

	pc8736x_init_shadow();

	/* ignore minor errs, and succeed */
	cdev_init(&pc8736x_gpio_cdev, &pc8736x_gpio_fileops);
	cdev_add(&pc8736x_gpio_cdev, devid, PC8736X_GPIO_CT);

	return 0;

undo_request_region:
	release_region(pc8736x_gpio_base, PC8736X_GPIO_RANGE);
undo_platform_dev_add:
	platform_device_del(pdev);
undo_platform_dev_alloc:
	platform_device_put(pdev);

	return rc;
}
static int __init initfunc(void)
{
	int ret1;
	int minorno;	
	dev_t devno;
	int ret2;

	minorno=MINORNO;

	#ifdef DEBUG 
		printk(KERN_ALERT"Hello Kernel \n");
	#endif

	ret1=alloc_chrdev_region(&devid,minorno,1,DEVNAME);

	if(ret1<0)
	{
		#ifdef DEBUG
			printk(KERN_ERR"Error : alloc_chrdev_region failed!! \n");
			goto OUT;
		#endif
	}

	#ifdef DEBUG 
		printk(KERN_ALERT"Registration Successful!! \n");
	#endif

	dev=kmalloc(sizeof(struct Dev),GFP_KERNEL);
	
	if(!dev)
	{
		#ifdef DEBUG
			printk(KERN_ERR"Error : kmalloc failed!! \n");
			goto OUT;
		#endif
	}

	memset(dev,'\0',sizeof(struct Dev));

	#ifdef DEBUG
		printk(KERN_ALERT"Memory Allocation Successful!! \n");
	#endif

	device_initialization();

	devno = MKDEV(MAJOR(devid),0);

	cdev_init(&dev->c_dev,&fops);

	dev->c_dev.owner = THIS_MODULE;
	dev->c_dev.ops = &fops;

	ret2=cdev_add(&dev->c_dev,devno,1);
	
	if(ret2<0)
	{
		#ifdef DEBUG
			printk(KERN_ERR"Error : cdev_add failed!! \n");
			goto OUT;
		#endif
	}

	#ifdef DEBUG
		printk(KERN_ALERT"(Major = %d,Minor = %d)",MAJOR(devno),MINOR(devno));
	#endif

	if( check_region(BASE,8) < 8 )
	{
		#ifdef DEBUG
			printk(KERN_ALERT"Releasing resources!! \n");
		#endif

		release_region(BASE,8);
	}	

	if( !request_region(BASE,8,DEVNAME) )
	{
		#ifdef DEBUG
			printk(KERN_ERR"Error : request_region failed!! \n");
			goto OUT;
		#endif
	}

	return 0;
OUT:
	return -1;
}
示例#23
0
/**
 * uio_register_device - register a new userspace IO device
 * @owner:	module that creates the new device
 * @parent:	parent device
 * @info:	UIO device capabilities
 *
 * returns zero on success or a negative error code.
 */
int __uio_register_device(struct module *owner,
                          struct device *parent,
                          struct uio_info *info)
{
    struct uio_device *idev;
    int ret = 0;

    if (!parent || !info || !info->name || !info->version)
        return -EINVAL;

    info->uio_dev = NULL;

    idev = kzalloc(sizeof(*idev), GFP_KERNEL);
    if (!idev) {
        ret = -ENOMEM;
        goto err_kzalloc;
    }

    idev->owner = owner;
    idev->info = info;
    init_waitqueue_head(&idev->wait);
    atomic_set(&idev->event, 0);

    ret = uio_get_minor(idev);
    if (ret)
        goto err_get_minor;

    idev->dev = device_create(&uio_class, parent,
                              MKDEV(uio_major, idev->minor), idev,
                              "uio%d", idev->minor);
    if (IS_ERR(idev->dev)) {
        printk(KERN_ERR "UIO: device register failed\n");
        ret = PTR_ERR(idev->dev);
        goto err_device_create;
    }

    ret = uio_dev_add_attributes(idev);
    if (ret)
        goto err_uio_dev_add_attributes;

    info->uio_dev = idev;

    if (info->irq && (info->irq != UIO_IRQ_CUSTOM)) {
        ret = request_irq(info->irq, uio_interrupt,
                          info->irq_flags, info->name, idev);
        if (ret)
            goto err_request_irq;
    }

    return 0;

err_request_irq:
    uio_dev_del_attributes(idev);
err_uio_dev_add_attributes:
    device_destroy(&uio_class, MKDEV(uio_major, idev->minor));
err_device_create:
    uio_free_minor(idev);
err_get_minor:
    kfree(idev);
err_kzalloc:
    return ret;
}
static int __devinit chd_dec_init_chdev(struct crystalhd_adp *adp)
{
	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 (!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(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;
}
示例#25
0
文件: pi433_if.c 项目: avagin/linux
static int pi433_probe(struct spi_device *spi)
{
	struct pi433_device	*device;
	int			retval;

	/* setup spi parameters */
	spi->mode = 0x00;
	spi->bits_per_word = 8;
	/*
	 * spi->max_speed_hz = 10000000;
	 * 1MHz already set by device tree overlay
	 */

	retval = spi_setup(spi);
	if (retval) {
		dev_dbg(&spi->dev, "configuration of SPI interface failed!\n");
		return retval;
	}

	dev_dbg(&spi->dev,
		"spi interface setup: mode 0x%2x, %d bits per word, %dhz max speed",
		spi->mode, spi->bits_per_word, spi->max_speed_hz);

	/* Ping the chip by reading the version register */
	retval = spi_w8r8(spi, 0x10);
	if (retval < 0)
		return retval;

	switch (retval) {
	case 0x24:
		dev_dbg(&spi->dev, "found pi433 (ver. 0x%x)", retval);
		break;
	default:
		dev_dbg(&spi->dev, "unknown chip version: 0x%x", retval);
		return -ENODEV;
	}

	/* Allocate driver data */
	device = kzalloc(sizeof(*device), GFP_KERNEL);
	if (!device)
		return -ENOMEM;

	/* Initialize the driver data */
	device->spi = spi;
	device->rx_active = false;
	device->tx_active = false;
	device->interrupt_rx_allowed = false;

	/* init rx buffer */
	device->rx_buffer = kmalloc(MAX_MSG_SIZE, GFP_KERNEL);
	if (!device->rx_buffer) {
		retval = -ENOMEM;
		goto RX_failed;
	}

	/* init wait queues */
	init_waitqueue_head(&device->tx_wait_queue);
	init_waitqueue_head(&device->rx_wait_queue);
	init_waitqueue_head(&device->fifo_wait_queue);

	/* init fifo */
	INIT_KFIFO(device->tx_fifo);

	/* init mutexes and locks */
	mutex_init(&device->tx_fifo_lock);
	mutex_init(&device->rx_lock);

	/* setup GPIO (including irq_handler) for the different DIOs */
	retval = setup_gpio(device);
	if (retval) {
		dev_dbg(&spi->dev, "setup of GPIOs failed");
		goto GPIO_failed;
	}

	/* setup the radio module */
	retval = rf69_set_mode(spi, standby);
	if (retval < 0)
		goto minor_failed;
	retval = rf69_set_data_mode(spi, DATAMODUL_MODE_PACKET);
	if (retval < 0)
		goto minor_failed;
	retval = rf69_enable_amplifier(spi, MASK_PALEVEL_PA0);
	if (retval < 0)
		goto minor_failed;
	retval = rf69_disable_amplifier(spi, MASK_PALEVEL_PA1);
	if (retval < 0)
		goto minor_failed;
	retval = rf69_disable_amplifier(spi, MASK_PALEVEL_PA2);
	if (retval < 0)
		goto minor_failed;
	retval = rf69_set_output_power_level(spi, 13);
	if (retval < 0)
		goto minor_failed;
	retval = rf69_set_antenna_impedance(spi, fifty_ohm);
	if (retval < 0)
		goto minor_failed;

	/* determ minor number */
	retval = pi433_get_minor(device);
	if (retval) {
		dev_dbg(&spi->dev, "get of minor number failed");
		goto minor_failed;
	}

	/* create device */
	device->devt = MKDEV(MAJOR(pi433_dev), device->minor);
	device->dev = device_create(pi433_class,
				    &spi->dev,
				    device->devt,
				    device,
				    "pi433.%d",
				    device->minor);
	if (IS_ERR(device->dev)) {
		pr_err("pi433: device register failed\n");
		retval = PTR_ERR(device->dev);
		goto device_create_failed;
	} else {
		dev_dbg(device->dev,
			"created device for major %d, minor %d\n",
			MAJOR(pi433_dev),
			device->minor);
	}

	/* start tx thread */
	device->tx_task_struct = kthread_run(pi433_tx_thread,
					     device,
					     "pi433.%d_tx_task",
					     device->minor);
	if (IS_ERR(device->tx_task_struct)) {
		dev_dbg(device->dev, "start of send thread failed");
		retval = PTR_ERR(device->tx_task_struct);
		goto send_thread_failed;
	}

	/* create cdev */
	device->cdev = cdev_alloc();
	if (!device->cdev) {
		dev_dbg(device->dev, "allocation of cdev failed");
		goto cdev_failed;
	}
	device->cdev->owner = THIS_MODULE;
	cdev_init(device->cdev, &pi433_fops);
	retval = cdev_add(device->cdev, device->devt, 1);
	if (retval) {
		dev_dbg(device->dev, "register of cdev failed");
		goto del_cdev;
	}

	/* spi setup */
	spi_set_drvdata(spi, device);

	return 0;

del_cdev:
	cdev_del(device->cdev);
cdev_failed:
	kthread_stop(device->tx_task_struct);
send_thread_failed:
	device_destroy(pi433_class, device->devt);
device_create_failed:
	pi433_free_minor(device);
minor_failed:
	free_gpio(device);
GPIO_failed:
	kfree(device->rx_buffer);
RX_failed:
	kfree(device);

	return retval;
}
示例#26
0
文件: main.c 项目: thr708285/Test
/*[Tag000]
 * 当模块加载时,调用;但是为什么要放在最后来实现他呢,看到Tag002时,你应该就明白了;
*/
int scull_init_module(void)
{
	int result, i;
	dev_t dev = 0;

/* [Tag001] */
/* [1]分配设备编号 */
/*
 * Get a range of minor numbers to work with, asking for a dynamic
 * major unless directed otherwise at load time.
 */
	if (scull_major) { 	/* 预先自己指定了主设备号 */
		dev = MKDEV(scull_major, scull_minor); /* 利用主设备号,找到设备编号给方法1用 */
		result = register_chrdev_region(dev, scull_nr_devs, "scull");
	} else {		/* 动态自己生成设备编号,然后再利用设备编号得到主设备号;
						记住如果用这个方法那么就要后建设备文件了,因为不能提前知道主号
						当然也可以利用ldd3书中提供的脚本,巨方便&&通用 */
		result = alloc_chrdev_region(&dev, scull_minor, scull_nr_devs,
				"scull");
		scull_major = MAJOR(dev);
	}
	if (result < 0) {
		printk(KERN_WARNING "scull: can't get major %d\n", scull_major);
		return result;
	}

    /*[2]设备对象实例化*/ 
        /* 
	 * allocate the devices -- we can't have them static, as the number
	 * can be specified at load time
	 */
	scull_devices = kmalloc(scull_nr_devs * sizeof(struct scull_dev), GFP_KERNEL);
	if (!scull_devices) {
		result = -ENOMEM;
		goto fail;  /* Make this more graceful */
	}
	memset(scull_devices, 0, scull_nr_devs * sizeof(struct scull_dev));

/* [3]在这里初始化设备用了2.6的新方法,在scull_setup_cdev里完成 */
        /* Initialize each device. */
	for (i = 0; i < scull_nr_devs; i++) {
		scull_devices[i].quantum = scull_quantum;	/* 可以根据自己insmod时传参
														来自己改变量子和量子集(指针数组)的大小 */
		scull_devices[i].qset = scull_qset;
		init_MUTEX(&scull_devices[i].sem);
		scull_setup_cdev(&scull_devices[i], i);	/* 在分别完主设备编号后goto Tag002 设备注册 */
	}

        /* At this point call the init function for any friend device */
	dev = MKDEV(scull_major, scull_minor + scull_nr_devs);
	dev += scull_p_init(dev);
	dev += scull_access_init(dev);

#ifdef SCULL_DEBUG /* only when debugging */
	scull_create_proc();
#endif

	return 0; /* succeed */

  fail:
	scull_cleanup_module();
	return result;
}