Beispiel #1
0
/*
 * reg_dev() - registers a device & initializes the structure components
 */
static int reg_dev(int base_addr, int minor, int irq)
{
	int err;
	err = register_chrdev_region(MKDEV(major, minor), 1, MODULE_NAME);
	if (err != 0) {
		printk(LOG_LEVEL "ERROR registering chrdev region: error %d\n",
		       err);
		goto out_reg_chrdev;
	}

	if ((request_irq(irq, uart_interrupt_handler, IRQF_SHARED, MODULE_NAME,
			 &devs[minor])) != 0) {
		printk(LOG_LEVEL "ERROR requesting irq: error %d\n", err);
		goto out_req_irq;
	}

	if (!request_region(base_addr, COM_NR_PORTS, MODULE_NAME)) {
		printk(LOG_LEVEL "ERROR registering region\n");
		err = -ENODEV;
		goto out_req_reg;
	}

	atomic_set(&devs[minor].access, 1);
	devs[minor].base_addr = base_addr;

	INIT_KFIFO(devs[minor].read_buffer);
	spin_lock_init(&devs[minor].read_lock);
	init_waitqueue_head(&devs[minor].read_wq);

	INIT_KFIFO(devs[minor].write_buffer);
	spin_lock_init(&devs[minor].write_lock);
	init_waitqueue_head(&devs[minor].write_wq);

	outb(0x0, base_addr + IER);
	outb(0x1, base_addr + IER);
	outb(0x0, base_addr + FCR);
	outb(0x7, base_addr + FCR);
	outb(0xb, base_addr + MCR);

	cdev_init(&devs[minor].cdev, &uart_fops);
	cdev_add(&devs[minor].cdev, MKDEV(major, minor), 1);
	return 0;

 out_reg_chrdev:
	return err;
 out_req_reg:
	free_irq(irq, &devs[minor]);
 out_req_irq:
	unregister_chrdev_region(MKDEV(major, minor), 1);
	return err;

}
static int __init example_init(void)
{
#ifdef DYNAMIC
	int ret;

	ret = kfifo_alloc(&test, FIFO_SIZE, GFP_KERNEL);
	if (ret) {
		printk(KERN_ERR "error kfifo_alloc\n");
		return ret;
	}
#else
	INIT_KFIFO(test);
#endif
	if (testfunc() < 0) {
#ifdef DYNAMIC
		kfifo_free(&test);
#endif
		return -EIO;
	}

	if (proc_create(PROC_FIFO, 0, NULL, &fifo_fops) == NULL) {
#ifdef DYNAMIC
		kfifo_free(&test);
#endif
		return -ENOMEM;
	}
	return 0;
}
Beispiel #3
0
static int kgdb_nmi_tty_install(struct tty_driver *drv, struct tty_struct *tty)
{
	struct kgdb_nmi_tty_priv *priv;
	int ret;

	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	INIT_KFIFO(priv->fifo);
	setup_timer(&priv->timer, kgdb_nmi_tty_receiver, (unsigned long)priv);
	tty_port_init(&priv->port);
	priv->port.ops = &kgdb_nmi_tty_port_ops;
	tty->driver_data = priv;

	ret = tty_port_install(&priv->port, drv, tty);
	if (ret) {
		pr_err("%s: can't install tty port: %d\n", __func__, ret);
		goto err;
	}
	return 0;
err:
	tty_port_destroy(&priv->port);
	kfree(priv);
	return ret;
}
Beispiel #4
0
static int uart16550_open(struct inode *inode, struct file *file){
    
    struct device_data *devicedata;
       
    devicedata=kmalloc(sizeof(struct device_data), GFP_KERNEL);
    if(!devicedata){
        return -1;
    }
    file -> private_data=devicedata; 
    INIT_KFIFO(devicedata->data_from_user);   
    INIT_KFIFO(devicedata->data_from_device);   
    devicedata -> task_user_push_data = kmalloc(sizeof(struct task_struct*),GFP_KERNEL);
    devicedata -> task_user_get_data = kmalloc(sizeof(struct task_struct*),GFP_KERNEL);
    *(devicedata -> task_user_push_data) = NULL; 
    *(devicedata -> task_user_get_data) = NULL;

    return 0;
}
Beispiel #5
0
/* Module initialization and release */
static int __init parrot_module_init(void)
{
	int retval;
	dbg("");

	/* First, see if we can dynamically allocate a major for our device */
	parrot_major = register_chrdev(0, DEVICE_NAME, &fops);
	if (parrot_major < 0) {
		err("failed to register device: error %d\n", parrot_major);
		retval = parrot_major;
		goto failed_chrdevreg;
	}

	/* We can either tie our device to a bus (existing, or one that we create)
	 * or use a "virtual" device class. For this example, we choose the latter */
	parrot_class = class_create(THIS_MODULE, CLASS_NAME);
	if (IS_ERR(parrot_class)) {
		err("failed to register device class '%s'\n", CLASS_NAME);
		retval = PTR_ERR(parrot_class);
		goto failed_classreg;
	}

	/* With a class, the easiest way to instantiate a device is to call device_create() */
	parrot_device = device_create(parrot_class, NULL, MKDEV(parrot_major, 0), NULL, CLASS_NAME "_" DEVICE_NAME);
	if (IS_ERR(parrot_device)) {
		err("failed to create device '%s_%s'\n", CLASS_NAME, DEVICE_NAME);
		retval = PTR_ERR(parrot_device);
		goto failed_devreg;
	}

	/* Now we can create the sysfs endpoints (don't care about errors).
	 * dev_attr_fifo and dev_attr_reset come from the DEVICE_ATTR(...) earlier */
	retval = device_create_file(parrot_device, &dev_attr_fifo);
	if (retval < 0) {
		warn("failed to create write /sys endpoint - continuing without\n");
	}
	retval = device_create_file(parrot_device, &dev_attr_reset);
	if (retval < 0) {
		warn("failed to create reset /sys endpoint - continuing without\n");
	}

	mutex_init(&parrot_device_mutex);
	/* This device uses a Kernel FIFO for its read operation */
	INIT_KFIFO(parrot_msg_fifo);
	parrot_msg_idx_rd = parrot_msg_idx_wr = 0;

	return 0;

failed_devreg:
	class_unregister(parrot_class);
	class_destroy(parrot_class);
failed_classreg:
	unregister_chrdev(parrot_major, DEVICE_NAME);
failed_chrdevreg:
	return -1;
}
int __init initialise(void)	{
    data1 = "procEntry";
    data2 = "rwCount";
    pfs = proc_create_data(file1, 0, NULL, &pfs_fops, data1);
    pfsCount = proc_create_data(file2, 0, NULL, &pfsCount_fops, data2);
    INIT_KFIFO(myfifo);

    if(pfs == NULL)	{
        remove_proc_entry(file1,NULL);
        kfifo_free(&myfifo);
        printk(KERN_ALERT "Error : Couldn't initialise /proc/%s\n", file1);
        return -ENOMEM;
    }
    if(pfsCount == NULL)	{
        remove_proc_entry(file2,NULL);
        printk(KERN_ALERT "Error : Couldn't initialise /proc/%s\n", file2);
        return -ENOMEM;
    }
    return 0;
}
/*****************************************************************************
Syntax:      	    Init_FIFO_voice_rtp_buf ();
Remarks:			This Function Init FIFO buffers 
Return Value:	    Returns 1 on success and negative value on failure.
 					Value		 									Description
					--------------------------------------------------------------
					= 1												Success
					=-1												Failure
*******************************************************************************/
void Init_FIFO_voice_rtp_buf ()
{	
 #ifdef DYNAMIC
	int ret;
	ret = kfifo_alloc(&test, FIFO_SIZE, GFP_KERNEL);
	if (ret) 
	{
	printk("?error kfifo_alloc?\n");
	return ret;
	}
	#else
	INIT_KFIFO(test);
#endif

	
	/*
	if (testfunc() < 0) 
	{
	#ifdef DYNAMIC
	kfifo_free(&test);
	#endif
    */
return -EIO;
}
Beispiel #8
0
/* Main entry */
static int r592_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
    int error = -ENOMEM;
    struct memstick_host *host;
    struct r592_device *dev;

    /* Allocate memory */
    host = memstick_alloc_host(sizeof(struct r592_device), &pdev->dev);
    if (!host)
        goto error1;

    dev = memstick_priv(host);
    dev->host = host;
    dev->pci_dev = pdev;
    pci_set_drvdata(pdev, dev);

    /* pci initialization */
    error = pci_enable_device(pdev);
    if (error)
        goto error2;

    pci_set_master(pdev);
    error = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
    if (error)
        goto error3;

    error = pci_request_regions(pdev, DRV_NAME);
    if (error)
        goto error3;

    dev->mmio = pci_ioremap_bar(pdev, 0);
    if (!dev->mmio)
        goto error4;

    dev->irq = pdev->irq;
    spin_lock_init(&dev->irq_lock);
    spin_lock_init(&dev->io_thread_lock);
    init_completion(&dev->dma_done);
    INIT_KFIFO(dev->pio_fifo);
    setup_timer(&dev->detect_timer,
                r592_detect_timer, (long unsigned int)dev);

    /* Host initialization */
    host->caps = MEMSTICK_CAP_PAR4;
    host->request = r592_submit_req;
    host->set_param = r592_set_param;
    r592_check_dma(dev);

    dev->io_thread = kthread_run(r592_process_thread, dev, "r592_io");
    if (IS_ERR(dev->io_thread)) {
        error = PTR_ERR(dev->io_thread);
        goto error5;
    }

    /* This is just a precation, so don't fail */
    dev->dummy_dma_page = pci_alloc_consistent(pdev, PAGE_SIZE,
                          &dev->dummy_dma_page_physical_address);
    r592_stop_dma(dev , 0);

    if (request_irq(dev->irq, &r592_irq, IRQF_SHARED,
                    DRV_NAME, dev))
        goto error6;

    r592_update_card_detect(dev);
    if (memstick_add_host(host))
        goto error7;

    message("driver successfully loaded");
    return 0;
error7:
    free_irq(dev->irq, dev);
error6:
    if (dev->dummy_dma_page)
        pci_free_consistent(pdev, PAGE_SIZE, dev->dummy_dma_page,
                            dev->dummy_dma_page_physical_address);

    kthread_stop(dev->io_thread);
error5:
    iounmap(dev->mmio);
error4:
    pci_release_regions(pdev);
error3:
    pci_disable_device(pdev);
error2:
    memstick_free_host(host);
error1:
    return error;
}
Beispiel #9
0
static int armada_drm_load(struct drm_device *dev, unsigned long flags)
{
    const struct platform_device_id *id;
    const struct armada_variant *variant;
    struct armada_private *priv;
    struct resource *res[ARRAY_SIZE(priv->dcrtc)];
    struct resource *mem = NULL;
    int ret, n, i;

    memset(res, 0, sizeof(res));

    for (n = i = 0; ; n++) {
        struct resource *r = platform_get_resource(dev->platformdev,
                             IORESOURCE_MEM, n);
        if (!r)
            break;

        /* Resources above 64K are graphics memory */
        if (resource_size(r) > SZ_64K)
            mem = r;
        else if (i < ARRAY_SIZE(priv->dcrtc))
            res[i++] = r;
        else
            return -EINVAL;
    }

    if (!mem)
        return -ENXIO;

    if (!devm_request_mem_region(dev->dev, mem->start,
                                 resource_size(mem), "armada-drm"))
        return -EBUSY;

    priv = devm_kzalloc(dev->dev, sizeof(*priv), GFP_KERNEL);
    if (!priv) {
        DRM_ERROR("failed to allocate private\n");
        return -ENOMEM;
    }

    platform_set_drvdata(dev->platformdev, dev);
    dev->dev_private = priv;

    /* Get the implementation specific driver data. */
    id = platform_get_device_id(dev->platformdev);
    if (!id)
        return -ENXIO;

    variant = (const struct armada_variant *)id->driver_data;

    INIT_WORK(&priv->fb_unref_work, armada_drm_unref_work);
    INIT_KFIFO(priv->fb_unref);

    /* Mode setting support */
    drm_mode_config_init(dev);
    dev->mode_config.min_width = 320;
    dev->mode_config.min_height = 200;

    /*
     * With vscale enabled, the maximum width is 1920 due to the
     * 1920 by 3 lines RAM
     */
    dev->mode_config.max_width = 1920;
    dev->mode_config.max_height = 2048;

    dev->mode_config.preferred_depth = 24;
    dev->mode_config.funcs = &armada_drm_mode_config_funcs;
    drm_mm_init(&priv->linear, mem->start, resource_size(mem));

    /* Create all LCD controllers */
    for (n = 0; n < ARRAY_SIZE(priv->dcrtc); n++) {
        int irq;

        if (!res[n])
            break;

        irq = platform_get_irq(dev->platformdev, n);
        if (irq < 0)
            goto err_kms;

        ret = armada_drm_crtc_create(dev, dev->dev, res[n], irq,
                                     variant, NULL);
        if (ret)
            goto err_kms;
    }

    if (is_componentized(dev->dev)) {
        ret = component_bind_all(dev->dev, dev);
        if (ret)
            goto err_kms;
    } else {
#ifdef CONFIG_DRM_ARMADA_TDA1998X
        ret = armada_drm_connector_slave_create(dev, &tda19988_config);
        if (ret)
            goto err_kms;
#endif
    }

    ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
    if (ret)
        goto err_comp;

    dev->irq_enabled = true;
    dev->vblank_disable_allowed = 1;

    ret = armada_fbdev_init(dev);
    if (ret)
        goto err_comp;

    drm_kms_helper_poll_init(dev);

    return 0;

err_comp:
    if (is_componentized(dev->dev))
        component_unbind_all(dev->dev, dev);
err_kms:
    drm_mode_config_cleanup(dev);
    drm_mm_takedown(&priv->linear);
    flush_work(&priv->fb_unref_work);

    return ret;
}
Beispiel #10
0
static int armada_drm_load(struct drm_device *dev, unsigned long flags)
{
	struct armada_private *priv;
	struct resource *mem = NULL;
	int ret, n;

	for (n = 0; ; n++) {
		struct resource *r = platform_get_resource(dev->platformdev,
							   IORESOURCE_MEM, n);
		if (!r)
			break;

		/* Resources above 64K are graphics memory */
		if (resource_size(r) > SZ_64K)
			mem = r;
		else
			return -EINVAL;
	}

	if (!mem)
		return -ENXIO;

	if (!devm_request_mem_region(dev->dev, mem->start,
			resource_size(mem), "armada-drm"))
		return -EBUSY;

	priv = devm_kzalloc(dev->dev, sizeof(*priv), GFP_KERNEL);
	if (!priv) {
		DRM_ERROR("failed to allocate private\n");
		return -ENOMEM;
	}

	platform_set_drvdata(dev->platformdev, dev);
	dev->dev_private = priv;

	INIT_WORK(&priv->fb_unref_work, armada_drm_unref_work);
	INIT_KFIFO(priv->fb_unref);

	/* Mode setting support */
	drm_mode_config_init(dev);
	dev->mode_config.min_width = 320;
	dev->mode_config.min_height = 200;

	/*
	 * With vscale enabled, the maximum width is 1920 due to the
	 * 1920 by 3 lines RAM
	 */
	dev->mode_config.max_width = 1920;
	dev->mode_config.max_height = 2048;

	dev->mode_config.preferred_depth = 24;
	dev->mode_config.funcs = &armada_drm_mode_config_funcs;
	drm_mm_init(&priv->linear, mem->start, resource_size(mem));
	mutex_init(&priv->linear_lock);

	ret = component_bind_all(dev->dev, dev);
	if (ret)
		goto err_kms;

	ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
	if (ret)
		goto err_comp;

	dev->irq_enabled = true;
	dev->vblank_disable_allowed = 1;

	ret = armada_fbdev_init(dev);
	if (ret)
		goto err_comp;

	drm_kms_helper_poll_init(dev);

	return 0;

 err_comp:
	component_unbind_all(dev->dev, dev);
 err_kms:
	drm_mode_config_cleanup(dev);
	drm_mm_takedown(&priv->linear);
	flush_work(&priv->fb_unref_work);

	return ret;
}
Beispiel #11
0
/*
 * The ES2 USB Bridge device has 15 endpoints
 * 1 Control - usual USB stuff + AP -> APBridgeA messages
 * 7 Bulk IN - CPort data in
 * 7 Bulk OUT - CPort data out
 */
static int ap_probe(struct usb_interface *interface,
		    const struct usb_device_id *id)
{
	struct es2_ap_dev *es2;
	struct gb_host_device *hd;
	struct usb_device *udev;
	struct usb_host_interface *iface_desc;
	struct usb_endpoint_descriptor *endpoint;
	int bulk_in = 0;
	int bulk_out = 0;
	int retval = -ENOMEM;
	int i;
	int num_cports;
	int cport_id;

	udev = usb_get_dev(interface_to_usbdev(interface));

	num_cports = apb_get_cport_count(udev);
	if (num_cports < 0) {
		usb_put_dev(udev);
		dev_err(&udev->dev, "Cannot retrieve CPort count: %d\n",
			num_cports);
		return num_cports;
	}

	hd = gb_hd_create(&es2_driver, &udev->dev, ES2_GBUF_MSG_SIZE_MAX,
				num_cports);
	if (IS_ERR(hd)) {
		usb_put_dev(udev);
		return PTR_ERR(hd);
	}

	/*
	 * CPorts 16 and 17 are reserved for CDSI0 and CDSI1, make sure they
	 * won't be allocated dynamically.
	 */
	do {
		cport_id = ida_simple_get(&hd->cport_id_map, 16, 18, GFP_KERNEL);
	} while (cport_id > 0);

	es2 = hd_to_es2(hd);
	es2->hd = hd;
	es2->usb_intf = interface;
	es2->usb_dev = udev;
	spin_lock_init(&es2->cport_out_urb_lock);
	INIT_KFIFO(es2->apb_log_fifo);
	usb_set_intfdata(interface, es2);

	es2->cport_to_ep = kcalloc(hd->num_cports, sizeof(*es2->cport_to_ep),
				   GFP_KERNEL);
	if (!es2->cport_to_ep) {
		retval = -ENOMEM;
		goto error;
	}

	/* find all bulk endpoints */
	iface_desc = interface->cur_altsetting;
	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
		endpoint = &iface_desc->endpoint[i].desc;

		if (usb_endpoint_is_bulk_in(endpoint)) {
			es2->cport_in[bulk_in++].endpoint =
				endpoint->bEndpointAddress;
		} else if (usb_endpoint_is_bulk_out(endpoint)) {
			es2->cport_out[bulk_out++].endpoint =
				endpoint->bEndpointAddress;
		} else {
			dev_err(&udev->dev,
				"Unknown endpoint type found, address 0x%02x\n",
				endpoint->bEndpointAddress);
		}
	}
	if (bulk_in != NUM_BULKS || bulk_out != NUM_BULKS) {
		dev_err(&udev->dev, "Not enough endpoints found in device, aborting!\n");
		goto error;
	}

	/* Allocate buffers for our cport in messages */
	for (bulk_in = 0; bulk_in < NUM_BULKS; bulk_in++) {
		struct es2_cport_in *cport_in = &es2->cport_in[bulk_in];

		for (i = 0; i < NUM_CPORT_IN_URB; ++i) {
			struct urb *urb;
			u8 *buffer;

			urb = usb_alloc_urb(0, GFP_KERNEL);
			if (!urb)
				goto error;
			buffer = kmalloc(ES2_GBUF_MSG_SIZE_MAX, GFP_KERNEL);
			if (!buffer)
				goto error;

			usb_fill_bulk_urb(urb, udev,
					  usb_rcvbulkpipe(udev,
							  cport_in->endpoint),
					  buffer, ES2_GBUF_MSG_SIZE_MAX,
					  cport_in_callback, hd);
			cport_in->urb[i] = urb;
			cport_in->buffer[i] = buffer;
		}
	}

	/* Allocate urbs for our CPort OUT messages */
	for (i = 0; i < NUM_CPORT_OUT_URB; ++i) {
		struct urb *urb;

		urb = usb_alloc_urb(0, GFP_KERNEL);
		if (!urb)
			goto error;

		es2->cport_out_urb[i] = urb;
		es2->cport_out_urb_busy[i] = false;	/* just to be anal */
	}

	/* XXX We will need to rename this per APB */
	es2->apb_log_enable_dentry = debugfs_create_file("apb_log_enable",
							(S_IWUSR | S_IRUGO),
							gb_debugfs_get(), es2,
							&apb_log_enable_fops);

	retval = gb_hd_add(hd);
	if (retval)
		goto error;

	for (i = 0; i < NUM_BULKS; ++i) {
		retval = es2_cport_in_enable(es2, &es2->cport_in[i]);
		if (retval)
			goto err_disable_cport_in;
	}

	return 0;

err_disable_cport_in:
	for (--i; i >= 0; --i)
		es2_cport_in_disable(es2, &es2->cport_in[i]);
	gb_hd_del(hd);
error:
	es2_destroy(es2);

	return retval;
}
/*---------------------------------------------------------------------------*/
static int __devinit ami_probe(struct i2c_client *client,
			       const struct i2c_device_id *devid)
{
	int res = 0;
	struct ami306_dev_data *pdev = NULL;
	struct ami306_platform_data  *pdata = NULL;

	AMI_LOG("%s %s %s", AMI_DRV_NAME, __func__, "start");
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		AMI_LOG("AMI : adapter can NOT support I2C_FUNC_I2C.");
		return -ENODEV;
	}

	pdev = (struct ami306_dev_data *)kzalloc(sizeof(struct ami306_dev_data), GFP_KERNEL);
	if (!pdev) {
		AMI_LOG("AMI: no memory to allocate ami306_dev_data\n");
		return -ENOMEM;
	}

	pdata = (struct ami306_platform_data *)client->dev.platform_data;
	if (!pdata) {
		printk("ami_probe: missing platform data info\n");
	}
	else {
		/* Set up axis */
		pdev->ami_dir = pdata->dir;
		pdev->ami_polarity = pdata->polarity;
		pdev->gpio_drdy = pdata->gpio_drdy;
		pdev->gpio_intr = pdata->gpio_intr;

		/* Init gpio */
		if(pdata->gpio_drdy) {
			if((res = gpio_request(pdata->gpio_drdy, "AMI306 DRDY"))) {
				printk(KERN_ERR "ami_probe: failed to request GPIO %d err=%d\n", pdata->gpio_drdy, res);
				goto err_free_pdev;
			}
			if((res = gpio_direction_input(pdata->gpio_drdy))) {
				printk(KERN_ERR "ami_probe: failed to set input direction for GPIO %d err=%d\n", pdata->gpio_drdy, res);
				goto err_free_pdev;
			}
		}

		if(pdata->gpio_intr) {
			if((res = gpio_request(pdata->gpio_intr, "AMI306 INTR"))) {
				printk(KERN_ERR "ami_probe: failed to request GPIO %d err=%d\n", pdata->gpio_intr, res);
				goto err_free_pdev;
			}
			if((res = gpio_direction_input(pdata->gpio_intr))) {
				printk(KERN_ERR "ami_probe: failed to set input direction for GPIO %d err=%d\n", pdata->gpio_intr, res);
				goto err_free_pdev;
			}
		}

		printk("ami_probe: setup ami_dir:%d, ami_polarity:%d, intr:%d, drdy:%d\n",
			pdev->ami_dir, pdev->ami_polarity, pdata->gpio_intr, pdata->gpio_drdy);
	}

	sema_init(&pdev->mutex, 1);
	pdev->dev.minor = MISC_DYNAMIC_MINOR;
	pdev->dev.name = AMI_DRV_NAME;
	pdev->dev.fops = &ami_fops;
	
	res = misc_register(&pdev->dev);
	if(res < 0) {
		printk(KERN_ERR "ami_probe: failed to do misc_regsiter return %d\n", res);
		goto err_free_pdev;
	}

#ifdef USER_MEMORY
	/* Initialize driver command */
	k_mem = kmalloc(AMI_GetMemSize(), GFP_KERNEL);
	if(k_mem == NULL) {
		printk(KERN_ERR "ami_probe: kmalloc error");
		res = -ENODEV;
		goto err_misc_deregister;
	}

	pdev->handle = AMI_InitDriver(k_mem, client, pdev->ami_dir, pdev->ami_polarity);
#else
	pdev->handle = AMI_InitDriver(client, pdev->ami_dir, pdev->ami_polarity);
#endif
	if(pdev->handle == NULL) {
		AMI_LOG("AMI : AMI_InitDriver error.");
		res = -ENODEV;
		goto err_free_kmem;
	}
	pdev->client = client;
	i2c_set_clientdata(client, pdev);

	/* initialize the waitq */
	init_waitqueue_head(&pdev->waitq);

	/* initialize the kfifo */
	INIT_KFIFO(pdev->ebuff);

	/* create workqueue */
	pdev->wq = create_singlethread_workqueue("ami306_wq");
	if (!pdev->wq) {
		AMI_LOG("AMI: Failed to create workqueue\n");
		res = -ENOMEM;
		goto err_free_kmem;
	}

	/* initialize the work struct */
	INIT_WORK(&pdev->work, ami_work_func);
	pdev->enable_wq = 0;

	/* create hrtimer, we don't just do msleep_interruptible as android
	   would pass something in unit of nanoseconds */
	hrtimer_init(&pdev->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	pdev->poll_delay = ns_to_ktime(500 * NSEC_PER_MSEC);
	pdev->timer.function = ami_timer_func;

	/* Register sysfs hooks */
	res = sysfs_create_group(&client->dev.kobj, &ami_attr_group);
	if (res) {
		AMI_LOG("AMI: sysfs_create_group failed with error %d\n", res);
		res = -ENODEV;
		goto err_destroy_workqueue;
	}

#ifdef CONFIG_ARCH_KONA
	pdev->regulator = regulator_get(&client->dev, "hv8");
	res = IS_ERR_OR_NULL(pdev->regulator);
	if (res) {
		pdev->regulator = NULL;
		AMI_LOG("AMI: %s, can't get hv8 regulator!\n", __func__);
		res = -EIO;
		goto err_destroy_workqueue;
	}

	/* make sure that regulator is enabled if device is successfully
	   bound */
	res = regulator_enable(pdev->regulator);
	AMI_LOG("AMI: %s, called regulator_enable for hv8 regulator. "
		"Status: %d\n", __func__, res);
	if (res) {
		AMI_LOG("AMI: %s, regulator_enable for hv8 regulator "
			"failed with status: %d\n",
			__func__, res);
		regulator_put(pdev->regulator);
	}
#endif

	AMI_LOG("%s %s %s", AMI_DRV_NAME, __func__, "end");
	return res;

err_destroy_workqueue:
	destroy_workqueue(pdev->wq);
err_free_kmem:
#ifdef USER_MEMORY
	if(k_mem) {
		kfree(k_mem);
		k_mem = NULL;
	}
err_misc_deregister:
#endif
	misc_deregister(&pdev->dev);
err_free_pdev:
	kfree(pdev);
	i2c_set_clientdata(client, NULL);

	return res;
}
Beispiel #13
0
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;
}