コード例 #1
0
ファイル: rtc-ds1305.c プロジェクト: 33d/linux-2.6.21-hh20
static int __devinit ds1305_probe(struct spi_device *spi)
{
	struct ds1305			*ds1305;
	int				status;
	u8				addr, value;
	struct ds1305_platform_data	*pdata = spi->dev.platform_data;
	bool				write_ctrl = false;

	/* Sanity check board setup data.  This may be hooked up
	 * in 3wire mode, but we don't care.  Note that unless
	 * there's an inverter in place, this needs SPI_CS_HIGH!
	 */
	if ((spi->bits_per_word && spi->bits_per_word != 8)
			|| (spi->max_speed_hz > 2000000)
			|| !(spi->mode & SPI_CPHA))
		return -EINVAL;

	/* set up driver data */
	ds1305 = kzalloc(sizeof *ds1305, GFP_KERNEL);
	if (!ds1305)
		return -ENOMEM;
	ds1305->spi = spi;
	spi_set_drvdata(spi, ds1305);

	/* read and cache control registers */
	addr = DS1305_CONTROL;
	status = spi_write_then_read(spi, &addr, sizeof addr,
			ds1305->ctrl, sizeof ds1305->ctrl);
	if (status < 0) {
		dev_dbg(&spi->dev, "can't %s, %d\n",
				"read", status);
		goto fail0;
	}

	dev_dbg(&spi->dev, "ctrl %s: %02x %02x %02x\n",
			"read", ds1305->ctrl[0],
			ds1305->ctrl[1], ds1305->ctrl[2]);

	/* Sanity check register values ... partially compensating for the
	 * fact that SPI has no device handshake.  A pullup on MISO would
	 * make these tests fail; but not all systems will have one.  If
	 * some register is neither 0x00 nor 0xff, a chip is likely there.
	 */
	if ((ds1305->ctrl[0] & 0x38) != 0 || (ds1305->ctrl[1] & 0xfc) != 0) {
		dev_dbg(&spi->dev, "RTC chip is not present\n");
		status = -ENODEV;
		goto fail0;
	}
	if (ds1305->ctrl[2] == 0)
		dev_dbg(&spi->dev, "chip may not be present\n");

	/* enable writes if needed ... if we were paranoid it would
	 * make sense to enable them only when absolutely necessary.
	 */
	if (ds1305->ctrl[0] & DS1305_WP) {
		u8		buf[2];

		ds1305->ctrl[0] &= ~DS1305_WP;

		buf[0] = DS1305_WRITE | DS1305_CONTROL;
		buf[1] = ds1305->ctrl[0];
		status = spi_write_then_read(spi, buf, sizeof buf, NULL, 0);

		dev_dbg(&spi->dev, "clear WP --> %d\n", status);
		if (status < 0)
			goto fail0;
	}

	/* on DS1305, maybe start oscillator; like most low power
	 * oscillators, it may take a second to stabilize
	 */
	if (ds1305->ctrl[0] & DS1305_nEOSC) {
		ds1305->ctrl[0] &= ~DS1305_nEOSC;
		write_ctrl = true;
		dev_warn(&spi->dev, "SET TIME!\n");
	}

	/* ack any pending IRQs */
	if (ds1305->ctrl[1]) {
		ds1305->ctrl[1] = 0;
		write_ctrl = true;
	}

	/* this may need one-time (re)init */
	if (pdata) {
		/* maybe enable trickle charge */
		if (((ds1305->ctrl[2] & 0xf0) != DS1305_TRICKLE_MAGIC)) {
			ds1305->ctrl[2] = DS1305_TRICKLE_MAGIC
						| pdata->trickle;
			write_ctrl = true;
		}

		/* on DS1306, configure 1 Hz signal */
		if (pdata->is_ds1306) {
			if (pdata->en_1hz) {
				if (!(ds1305->ctrl[0] & DS1306_1HZ)) {
					ds1305->ctrl[0] |= DS1306_1HZ;
					write_ctrl = true;
				}
			} else {
				if (ds1305->ctrl[0] & DS1306_1HZ) {
					ds1305->ctrl[0] &= ~DS1306_1HZ;
					write_ctrl = true;
				}
			}
		}
	}

	if (write_ctrl) {
		u8		buf[4];

		buf[0] = DS1305_WRITE | DS1305_CONTROL;
		buf[1] = ds1305->ctrl[0];
		buf[2] = ds1305->ctrl[1];
		buf[3] = ds1305->ctrl[2];
		status = spi_write_then_read(spi, buf, sizeof buf, NULL, 0);
		if (status < 0) {
			dev_dbg(&spi->dev, "can't %s, %d\n",
					"write", status);
			goto fail0;
		}

		dev_dbg(&spi->dev, "ctrl %s: %02x %02x %02x\n",
				"write", ds1305->ctrl[0],
				ds1305->ctrl[1], ds1305->ctrl[2]);
	}

	/* see if non-Linux software set up AM/PM mode */
	addr = DS1305_HOUR;
	status = spi_write_then_read(spi, &addr, sizeof addr,
				&value, sizeof value);
	if (status < 0) {
		dev_dbg(&spi->dev, "read HOUR --> %d\n", status);
		goto fail0;
	}

	ds1305->hr12 = (DS1305_HR_12 & value) != 0;
	if (ds1305->hr12)
		dev_dbg(&spi->dev, "AM/PM\n");

	/* register RTC ... from here on, ds1305->ctrl needs locking */
	ds1305->rtc = rtc_device_register("ds1305", &spi->dev,
			&ds1305_ops, THIS_MODULE);
	if (IS_ERR(ds1305->rtc)) {
		status = PTR_ERR(ds1305->rtc);
		dev_dbg(&spi->dev, "register rtc --> %d\n", status);
		goto fail0;
	}

	/* Maybe set up alarm IRQ; be ready to handle it triggering right
	 * away.  NOTE that we don't share this.  The signal is active low,
	 * and we can't ack it before a SPI message delay.  We temporarily
	 * disable the IRQ until it's acked, which lets us work with more
	 * IRQ trigger modes (not all IRQ controllers can do falling edge).
	 */
	if (spi->irq) {
		INIT_WORK(&ds1305->work, ds1305_work);
		status = request_irq(spi->irq, ds1305_irq,
				0, dev_name(&ds1305->rtc->dev), ds1305);
		if (status < 0) {
			dev_dbg(&spi->dev, "request_irq %d --> %d\n",
					spi->irq, status);
			goto fail1;
		}

		device_set_wakeup_capable(&spi->dev, 1);
	}

	/* export NVRAM */
	status = sysfs_create_bin_file(&spi->dev.kobj, &nvram);
	if (status < 0) {
		dev_dbg(&spi->dev, "register nvram --> %d\n", status);
		goto fail2;
	}

	return 0;

fail2:
	free_irq(spi->irq, ds1305);
fail1:
	rtc_device_unregister(ds1305->rtc);
fail0:
	kfree(ds1305);
	return status;
}
コード例 #2
0
static int fimg2d_probe(struct platform_device *pdev)
{
	struct resource *res;
	struct fimg2d_platdata *pdata;
	int ret;

	pdata = to_fimg2d_plat(&pdev->dev);
	if (!pdata) {
		printk(KERN_ERR "FIMG2D failed to get platform data\n");
		ret = -ENOMEM;
		goto err_plat;
	}

	/* global structure */
	info = kzalloc(sizeof(*info), GFP_KERNEL);
	if (!info) {
		printk(KERN_ERR "FIMG2D failed to allocate memory for controller\n");
		ret = -ENOMEM;
		goto err_plat;
	}

	/* setup global info */
	ret = fimg2d_setup_controller(info);
	if (ret) {
		printk(KERN_ERR "FIMG2D failed to setup controller\n");
		goto err_setup;
	}
	info->dev = &pdev->dev;

	/* memory region */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		printk(KERN_ERR "FIMG2D failed to get resource\n");
		ret = -ENOENT;
		goto err_res;
	}

	info->mem = request_mem_region(res->start, resource_size(res),
					pdev->name);
	if (!info->mem) {
		printk(KERN_ERR "FIMG2D failed to request memory region\n");
		ret = -ENOMEM;
		goto err_region;
	}

	/* ioremap */
	info->regs = ioremap(res->start, resource_size(res));
	if (!info->regs) {
		printk(KERN_ERR "FIMG2D failed to ioremap for SFR\n");
		ret = -ENOENT;
		goto err_map;
	}
	fimg2d_debug("device name: %s base address: 0x%lx\n",
			pdev->name, (unsigned long)res->start);

	/* irq */
	info->irq = platform_get_irq(pdev, 0);
	if (!info->irq) {
		printk(KERN_ERR "FIMG2D failed to get irq resource\n");
		ret = -ENOENT;
		goto err_map;
	}
	fimg2d_debug("irq: %d\n", info->irq);

	ret = request_irq(info->irq, fimg2d_irq, IRQF_DISABLED, pdev->name, info);
	if (ret) {
		printk(KERN_ERR "FIMG2D failed to request irq\n");
		ret = -ENOENT;
		goto err_irq;
	}

	ret = fimg2d_clk_setup(info);
	if (ret) {
		printk(KERN_ERR "FIMG2D failed to setup clk\n");
		ret = -ENOENT;
		goto err_clk;
	}

#ifdef CONFIG_PM_RUNTIME
	pm_runtime_enable(info->dev);
	fimg2d_debug("enable runtime pm\n");
#endif
#ifdef CONFIG_BUSFREQ_OPP
#if defined(CONFIG_CPU_EXYNOS4412)
	/* To lock bus frequency in OPP mode */
	info->bus_dev = dev_get("exynos-busfreq");
#endif
#endif

//	info->bus_dev = dev_get("exynos-busfreq");
	s5p_sysmmu_set_fault_handler(info->dev, fimg2d_sysmmu_fault_handler);
	fimg2d_debug("register sysmmu page fault handler\n");

	/* misc register */
	ret = misc_register(&fimg2d_dev);
	if (ret) {
		printk(KERN_ERR "FIMG2D failed to register misc driver\n");
		goto err_reg;
	}

	printk(KERN_INFO "Samsung Graphics 2D driver, (c) 2011 Samsung Electronics\n");
	return 0;

err_reg:
	fimg2d_clk_release(info);

err_clk:
	free_irq(info->irq, NULL);

err_irq:
	iounmap(info->regs);

err_map:
	kfree(info->mem);

err_region:
	release_resource(info->mem);

err_res:
	destroy_workqueue(info->work_q);

err_setup:
	kfree(info);

err_plat:
	return ret;
}
コード例 #3
0
ファイル: advinit.c プロジェクト: rct225/scanside
/**
 * advdrv_init_one - Pnp to initialize the device, and allocate resource for the device.
 *
 * @dev: Points to the pci_dev device
 * @ent: Points to pci_device_id including the device info.
 */
static INT32S __devinit advdrv_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
{     
	private_data *privdata = NULL;
	struct semaphore *dio_sema = NULL;
	adv_device *device = NULL;
	INT32S ret;
     

	

	if ((ret = pci_enable_device(dev)) != 0) {
		KdPrint("pci_enable_device failed\n");
		return ret;
	}

	/* allocate urb sema */
	dio_sema = kmalloc(sizeof(struct semaphore), GFP_KERNEL);
	if (dio_sema == NULL) {
		return -ENOMEM;
	}
	init_MUTEX(dio_sema);

	/* initialize & zero the device structure */
	device = (adv_device *) kmalloc(sizeof(adv_device), GFP_KERNEL);
	if (device == NULL) {
		KdPrint("Could not kmalloc space for device!");
		kfree(dio_sema);
		return -ENOMEM;
	}
	memset(device, 0, sizeof(adv_device));
	

	/* alloc & initialize the private data structure */
	privdata = kmalloc(sizeof(private_data), GFP_KERNEL);
	if (!privdata) {
		kfree(device);
		kfree(dio_sema);
		return -ENOMEM;
	}

	memset(privdata, 0, sizeof(private_data));
	privdata->pci_slot = PCI_SLOT(dev->devfn);
	privdata->pci_bus = dev->bus->number;
	privdata->device_type = dev->device; /* multi-card support for new driver */     
	privdata->irq = dev->irq;
	privdata->dio_sema = dio_sema;

	printk(KERN_ERR "privdata->device = 0x%x\n", dev->device);
	

	switch (privdata->device_type) {
	case PCI1761:
	case PCI1762:
	case MIC3761:
		privdata->iobase = dev->resource[2].start & ~1UL;
		privdata->iolength = dev->resource[2].end - dev->resource[2].start;
		break;
	case PCI1763:
		privdata->iobase = dev->resource[0].start & ~1UL;
		privdata->iolength = dev->resource[0].end - dev->resource[0].start;
		break;
	}
	
	adv_process_info_header_init(&privdata->ptr_process_info);
	init_waitqueue_head(&privdata->event_wait);
	spin_lock_init(&privdata->spinlock);

	/* request I/O regions */
	if (request_region(privdata->iobase, privdata->iolength, "PCI-1761") == NULL) {
		kfree(device);
		kfree(privdata);
		kfree(dio_sema);
		KdPrint("Request region failed\n");
		return -ENXIO;
	}

	/* request irq */
	switch (privdata->device_type) {
	case PCI1761:
	case PCI1763:
	case MIC3761:
		ret = request_irq(privdata->irq, pci1761_interrupt_handler,
				  SA_SHIRQ, "adv1761", privdata); 
		if (ret != 0) {
			release_region(privdata->iobase, privdata->iolength);
			kfree(device);
			kfree(privdata);
			kfree(dio_sema);
			KdPrint("Request IRQ failed\n");
			return ret;
		}
		break;
	case PCI1762:
		ret = request_irq(privdata->irq, pci1762_interrupt_handler,
				  SA_SHIRQ, "adv1762", privdata); 
		if (ret != 0) {
			release_region(privdata->iobase, privdata->iolength);
			kfree(device);
			kfree(privdata);
			kfree(dio_sema);
			KdPrint("Request IRQ failed\n");
			return ret;
		}
		break;
	}
	
	/* support multi-card */
	switch (privdata->device_type) {
	case PCI1761:
		privdata->board_id = (INT16U) (advInp(privdata, 0x02) & 0x0f);
		advdrv_device_set_devname(device, "pci1761");
		break;
	case MIC3761:
		privdata->board_id = (INT16U) (advInp(privdata, 0x02) & 0x0f);
		advdrv_device_set_devname(device, "mic3761");
		break;

	case PCI1762:
		privdata->board_id = (INT16U) (advInp(privdata, 0x04) & 0x0f);
		advdrv_device_set_devname(device, "pci1762");
		break;
	case PCI1763:
		privdata->board_id = (INT16U) (advInp(privdata, 0x02) & 0x0f);
		advdrv_device_set_devname(device, "pci1763up");
		break;
	default:
		break;
	}


	/* link the info into the other structures */
	_ADV_SET_DEVICE_PRIVDATA(device, privdata);
	_ADV_SET_DEVICE_BOARDID(device, privdata->board_id);
	_ADV_SET_DEVICE_SLOT(device, privdata->pci_slot);
	_ADV_SET_DEVICE_IOBASE(device, privdata->iobase);
	_ADV_SET_DEVICE_IRQ(device, privdata->irq);
	pci_set_drvdata(dev, device);

	/* add device into driver list */
	ret = advdrv_add_device(&pci1761_driver, device);
	if (ret != 0) {
		release_region(privdata->iobase, privdata->iolength);
		free_irq(privdata->irq, privdata);
		kfree(device);
		kfree(privdata);
		kfree(dio_sema);
		KdPrint("Add device failed!\n");
		return ret;
	}

	printk("Add a PCI-%x device: iobase=%xh; irq=%xh; slot=%xh\n", 
	       dev->device,
	       privdata->iobase,
	       privdata->irq,
	       privdata->pci_slot);

	return 0;
}
コード例 #4
0
ファイル: pcm970-baseboard.c プロジェクト: 0x0f/adam-kernel
static void pcm970_sdhc2_exit(struct device *dev, void *data)
{
	free_irq(IRQ_GPIOC(29), data);
	gpio_free(GPIO_PORTC + 28);
}
コード例 #5
0
ファイル: gpio.c プロジェクト: helloworldzlg/nanopct2_develop
int gpioc4_release(struct inode *inode,struct file *filp)
{
    free_irq(PC04_IRQ.irq, (void*)0);
    return 0;    
}
コード例 #6
0
void drv_close() { int thread_id = corral_getThreadID();
  dev_down();
  napi_disable();
  free_irq();
}
コード例 #7
0
static int __init s3c_keypad_probe(struct platform_device *pdev)
{
	struct resource *res, *keypad_mem, *keypad_irq = NULL;
	struct input_dev *input_dev;
	struct s3c_keypad *s3c_keypad;
	int ret, size, key;
	struct s3c_keypad_extra    	*extra = NULL;
	struct s3c_keypad_slide    	*slide = NULL;
	struct s3c_keypad_special_key    *special_key;
	struct s3c_keypad_gpio_key 	*gpio_key;
	int i;
	char * input_dev_name;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL) {
		dev_err(&pdev->dev,"no memory resource specified\n");
		return -ENOENT;
	}

	size = (res->end - res->start) + 1;

	keypad_mem = request_mem_region(res->start, size, pdev->name);
	if (keypad_mem == NULL) {
		dev_err(&pdev->dev, "failed to get memory region\n");
		ret = -ENOENT;
		goto err_req;
	}

	key_base = ioremap(res->start, size);
	if (key_base == NULL) {
		printk(KERN_ERR "Failed to remap register block\n");
		ret = -ENOMEM;
		goto err_map;
	}

	keypad_clock = clk_get(&pdev->dev, "keypad");
	if (IS_ERR(keypad_clock)) {
		dev_err(&pdev->dev, "failed to find keypad clock source\n");
		ret = PTR_ERR(keypad_clock);
		goto err_clk;
	}

	clk_enable(keypad_clock);

	s3c_keypad = kzalloc(sizeof(struct s3c_keypad), GFP_KERNEL);
	input_dev = input_allocate_device();
	input_dev_name = (char *)kmalloc(sizeof("s3c-keypad-revxxxx"), GFP_KERNEL);

	if (!s3c_keypad || !input_dev || !input_dev_name) {
		ret = -ENOMEM;
		goto out;
	}

	platform_set_drvdata(pdev, s3c_keypad);

	DPRINTK(": system_rev 0x%04x\n", system_rev);
	for (i=0; i<sizeof(s3c_keypad_extra)/sizeof(struct s3c_keypad_extra); i++)
	{
		//if (s3c_keypad_extra[i].board_num == g_board_num) {
		if (s3c_keypad_extra[i].board_num == system_rev) {
			extra = &s3c_keypad_extra[i];
			sprintf(input_dev_name, "%s%s%04x", DEVICE_NAME, "-rev", system_rev);
			DPRINTK(": board rev 0x%04x is detected!\n", s3c_keypad_extra[i].board_num);
			break;
		}
	}

	/* Default revison */
	if(!extra)
	{
		extra = &s3c_keypad_extra[0];
#if defined(CONFIG_MACH_VINSQ) || defined(CONFIG_MACH_MAX) || defined(CONFIG_MACH_VITAL)
		sprintf(input_dev_name, "%s%s", DEVICE_NAME, "-rev0050");
#else
		sprintf(input_dev_name, "%s%s", DEVICE_NAME, "-rev0000");
#endif
		DPRINTK(": failed to detect board rev. set Default revison!\n");
	}
	DPRINTK(": input device name: %s.\n", input_dev_name);

	s3c_keypad->dev = input_dev;
	fake_slide_dev = input_dev;
	s3c_keypad->extra = extra;
	slide = extra->slide;
	special_key = extra->special_key;
	gpio_key = extra->gpio_key;

	writel(KEYIFCON_INIT, key_base+S3C_KEYIFCON);
	writel(KEYIFFC_DIV, key_base+S3C_KEYIFFC);

	/* Set GPIO Port for keypad mode and pull-up disable*/
	s3c_setup_keypad_cfg_gpio(KEYPAD_ROWS, KEYPAD_COLUMNS);

	writel(KEYIFCOL_CLEAR, key_base+S3C_KEYIFCOL);

	for(key = 0; key < 64; key++){
        	input_set_capability(input_dev, EV_KEY, key+1);
	}

	for (i=0; i<extra->special_key_num; i++ ){
        	input_set_capability(input_dev, EV_KEY, (special_key+i)->keycode);
	}

	for (i=0; i<extra->gpio_key_num; i++ ){
        	input_set_capability(input_dev, EV_KEY, (gpio_key+i)->keycode);
	}

	if (extra->slide != NULL)
   {
       input_set_capability(input_dev, EV_SW, SW_LID);
#if defined(CONFIG_MACH_VINSQ) || defined(CONFIG_MACH_MAX) || defined(CONFIG_MACH_VITAL)
       input_dev->sw[SW_LID] = 1;  //vinsq.boot
#endif
   }

	input_dev->name = input_dev_name;
	input_dev->phys = "s3c-keypad/input0";

	input_dev->id.bustype = BUS_HOST;
	input_dev->id.vendor = 0x0001;
	input_dev->id.product = 0x0001;
	input_dev->id.version = 0x0001;

	/* Scan timer init */
	init_timer(&keypad_timer);
	keypad_timer.function = keypad_timer_handler;
	keypad_timer.data = (unsigned long)s3c_keypad;

	init_timer(&gpiokey_timer);
	gpiokey_timer.function = gpiokey_timer_handler;
	gpiokey_timer.data = (unsigned long)s3c_keypad;


	/* For IRQ_KEYPAD */
	keypad_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (keypad_irq == NULL) {
		dev_err(&pdev->dev, "no irq resource specified\n");
		ret = -ENOENT;
		goto err_clk;
	}

	if (slide != NULL)
	{
		s3c_gpio_cfgpin(slide->gpio, S3C_GPIO_SFN(slide->gpio_af));
		s3c_gpio_setpull(slide->gpio, S3C_GPIO_PULL_NONE);

		set_irq_type(slide->eint, IRQ_TYPE_EDGE_BOTH);

		ret = request_irq(slide->eint, slide_int_handler, IRQF_DISABLED,
		    "s3c_keypad gpio key", (void *)s3c_keypad);
		if (ret) {
			printk(KERN_ERR "request_irq(%d) failed (IRQ for SLIDE) !!!\n", slide->eint);
			ret = -EIO;
			goto err_irq;
		}
	}

	for (i=0; i<extra->gpio_key_num; i++, gpio_key+=1)
	{
		s3c_gpio_cfgpin(gpio_key->gpio, S3C_GPIO_SFN(gpio_key->gpio_af));
		s3c_gpio_setpull(gpio_key->gpio, S3C_GPIO_PULL_NONE);

		set_irq_type(gpio_key->eint, IRQ_TYPE_EDGE_BOTH);

		ret = request_irq(gpio_key->eint, gpio_int_handler, IRQF_DISABLED,
			    "s3c_keypad gpio key", (void *)s3c_keypad);
		if (ret) {
			printk(KERN_ERR "request_irq(%d) failed (IRQ for GPIO KEY) !!!\n", gpio_key->eint);
			ret = -EIO;
			goto err_irq;
		}
	}

	ret = request_irq(keypad_irq->start, s3c_keypad_isr, IRQF_SAMPLE_RANDOM,
		DEVICE_NAME, (void *) pdev);
	if (ret) {
		printk("request_irq failed (IRQ_KEYPAD) !!!\n");
		ret = -EIO;
		goto err_irq;
	}

	ret = input_register_device(input_dev);
	if (ret) {
		printk("Unable to register s3c-keypad input device!!!\n");
		goto out;
	}

	keypad_timer.expires = jiffies + (HZ/10);
	mod_timer(&keypad_timer,keypad_timer.expires);

	printk( DEVICE_NAME " Initialized\n");
	return 0;

out:
	input_free_device(input_dev);
	kfree(s3c_keypad);

err_irq:
	free_irq(keypad_irq->start, input_dev);
	free_irq(keypad_irq->end, input_dev);

	if (slide != NULL)
		free_irq(extra->slide->eint, s3c_keypad);

	gpio_key = extra->gpio_key;
	for (i=0; i<extra->gpio_key_num; i++, gpio_key+=1)
		free_irq(gpio_key->eint, s3c_keypad);

err_clk:
	clk_disable(keypad_clock);
	clk_put(keypad_clock);

err_map:
	iounmap(key_base);

err_req:
	release_resource(keypad_mem);
	kfree(keypad_mem);

	return ret;
}
コード例 #8
0
ファイル: cpqarray.c プロジェクト: PennPanda/linux-repo
/* pdev is NULL for eisa */
static int __init cpqarray_register_ctlr( int i, struct pci_dev *pdev)
{
	struct request_queue *q;
	int j;

	/* 
	 * register block devices
	 * Find disks and fill in structs
	 * Get an interrupt, set the Q depth and get into /proc
	 */

	/* If this successful it should insure that we are the only */
	/* instance of the driver */
	if (register_blkdev(COMPAQ_SMART2_MAJOR+i, hba[i]->devname)) {
		goto Enomem4;
	}
	hba[i]->access.set_intr_mask(hba[i], 0);
	if (request_irq(hba[i]->intr, do_ida_intr,
		IRQF_DISABLED|IRQF_SHARED, hba[i]->devname, hba[i]))
	{
		printk(KERN_ERR "cpqarray: Unable to get irq %d for %s\n",
				hba[i]->intr, hba[i]->devname);
		goto Enomem3;
	}
		
	for (j=0; j<NWD; j++) {
		ida_gendisk[i][j] = alloc_disk(1 << NWD_SHIFT);
		if (!ida_gendisk[i][j])
			goto Enomem2;
	}

	hba[i]->cmd_pool = pci_alloc_consistent(
		hba[i]->pci_dev, NR_CMDS * sizeof(cmdlist_t),
		&(hba[i]->cmd_pool_dhandle));
	hba[i]->cmd_pool_bits = kcalloc(
		(NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG, sizeof(unsigned long),
		GFP_KERNEL);

	if (!hba[i]->cmd_pool_bits || !hba[i]->cmd_pool)
			goto Enomem1;

	memset(hba[i]->cmd_pool, 0, NR_CMDS * sizeof(cmdlist_t));
	printk(KERN_INFO "cpqarray: Finding drives on %s",
		hba[i]->devname);

	spin_lock_init(&hba[i]->lock);
	q = blk_init_queue(do_ida_request, &hba[i]->lock);
	if (!q)
		goto Enomem1;

	hba[i]->queue = q;
	q->queuedata = hba[i];

	getgeometry(i);
	start_fwbk(i);

	ida_procinit(i);

	if (pdev)
		blk_queue_bounce_limit(q, hba[i]->pci_dev->dma_mask);

	/* This is a hardware imposed limit. */
	blk_queue_max_hw_segments(q, SG_MAX);

	/* This is a driver limit and could be eliminated. */
	blk_queue_max_phys_segments(q, SG_MAX);
	
	init_timer(&hba[i]->timer);
	hba[i]->timer.expires = jiffies + IDA_TIMER;
	hba[i]->timer.data = (unsigned long)hba[i];
	hba[i]->timer.function = ida_timer;
	add_timer(&hba[i]->timer);

	/* Enable IRQ now that spinlock and rate limit timer are set up */
	hba[i]->access.set_intr_mask(hba[i], FIFO_NOT_EMPTY);

	for(j=0; j<NWD; j++) {
		struct gendisk *disk = ida_gendisk[i][j];
		drv_info_t *drv = &hba[i]->drv[j];
		sprintf(disk->disk_name, "ida/c%dd%d", i, j);
		disk->major = COMPAQ_SMART2_MAJOR + i;
		disk->first_minor = j<<NWD_SHIFT;
		disk->fops = &ida_fops;
		if (j && !drv->nr_blks)
			continue;
		blk_queue_hardsect_size(hba[i]->queue, drv->blk_size);
		set_capacity(disk, drv->nr_blks);
		disk->queue = hba[i]->queue;
		disk->private_data = drv;
		add_disk(disk);
	}

	/* done ! */
	return(i);

Enomem1:
	nr_ctlr = i; 
	kfree(hba[i]->cmd_pool_bits);
	if (hba[i]->cmd_pool)
		pci_free_consistent(hba[i]->pci_dev, NR_CMDS*sizeof(cmdlist_t), 
				    hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle);
Enomem2:
	while (j--) {
		put_disk(ida_gendisk[i][j]);
		ida_gendisk[i][j] = NULL;
	}
	free_irq(hba[i]->intr, hba[i]);
Enomem3:
	unregister_blkdev(COMPAQ_SMART2_MAJOR+i, hba[i]->devname);
Enomem4:
	if (pdev)
		pci_set_drvdata(pdev, NULL);
	release_io_mem(hba[i]);
	free_hba(i);

	printk( KERN_ERR "cpqarray: out of memory");

	return -1;
}
コード例 #9
0
ファイル: c4.c プロジェクト: Dronevery/JetsonTK1-kernel
static int c4_add_card(struct capicardparams *p, struct pci_dev *dev,
		       int nr_controllers)
{
	avmcard *card;
	avmctrl_info *cinfo;
	int retval;
	int i;

	card = b1_alloc_card(nr_controllers);
	if (!card) {
		printk(KERN_WARNING "c4: no memory.\n");
		retval = -ENOMEM;
		goto err;
	}
        card->dma = avmcard_dma_alloc("c4", dev, 2048+128, 2048+128);
	if (!card->dma) {
		printk(KERN_WARNING "c4: no memory.\n");
		retval = -ENOMEM;
		goto err_free;
	}

	sprintf(card->name, "c%d-%x", nr_controllers, p->port);
	card->port = p->port;
	card->irq = p->irq;
	card->membase = p->membase;
	card->cardtype = (nr_controllers == 4) ? avm_c4 : avm_c2;

	if (!request_region(card->port, AVMB1_PORTLEN, card->name)) {
		printk(KERN_WARNING "c4: ports 0x%03x-0x%03x in use.\n",
		       card->port, card->port + AVMB1_PORTLEN);
		retval = -EBUSY;
		goto err_free_dma;
	}

	card->mbase = ioremap(card->membase, 128);
	if (card->mbase == 0) {
		printk(KERN_NOTICE "c4: can't remap memory at 0x%lx\n",
		       card->membase);
		retval = -EIO;
		goto err_release_region;
	}

	retval = c4_detect(card);
	if (retval != 0) {
		printk(KERN_NOTICE "c4: NO card at 0x%x error(%d)\n",
		       card->port, retval);
		retval = -EIO;
		goto err_unmap;
	}
	c4_reset(card);

	retval = request_irq(card->irq, c4_interrupt, SA_SHIRQ, card->name, card);
	if (retval) {
		printk(KERN_ERR "c4: unable to get IRQ %d.\n",card->irq);
		retval = -EBUSY;
		goto err_unmap;
	}

	for (i=0; i < nr_controllers ; i++) {
		cinfo = &card->ctrlinfo[i];
		cinfo->capi_ctrl.owner = THIS_MODULE;
		cinfo->capi_ctrl.driver_name   = "c4";
		cinfo->capi_ctrl.driverdata    = cinfo;
		cinfo->capi_ctrl.register_appl = c4_register_appl;
		cinfo->capi_ctrl.release_appl  = c4_release_appl;
		cinfo->capi_ctrl.send_message  = c4_send_message;
		cinfo->capi_ctrl.load_firmware = c4_load_firmware;
		cinfo->capi_ctrl.reset_ctr     = c4_reset_ctr;
		cinfo->capi_ctrl.procinfo      = c4_procinfo;
		cinfo->capi_ctrl.ctr_read_proc = c4_read_proc;
		strcpy(cinfo->capi_ctrl.name, card->name);

		retval = attach_capi_ctr(&cinfo->capi_ctrl);
		if (retval) {
			printk(KERN_ERR "c4: attach controller failed (%d).\n", i);
			for (i--; i >= 0; i--) {
				cinfo = &card->ctrlinfo[i];
				detach_capi_ctr(&cinfo->capi_ctrl);
			}
			goto err_free_irq;
		}
		if (i == 0)
			card->cardnr = cinfo->capi_ctrl.cnr;
	}

	printk(KERN_INFO "c4: AVM C%d at i/o %#x, irq %d, mem %#lx\n",
	       nr_controllers, card->port, card->irq,
	       card->membase);
	pci_set_drvdata(dev, card);
	return 0;

 err_free_irq:
	free_irq(card->irq, card);
 err_unmap:
	iounmap(card->mbase);
 err_release_region:
	release_region(card->port, AVMB1_PORTLEN);
 err_free_dma:
	avmcard_dma_free(card->dma);
 err_free:
	b1_free_card(card);
 err:
	return retval;
}
コード例 #10
0
ファイル: omap-ir.c プロジェクト: mrtos/Logitech-Revue
static int omap_irda_start(struct net_device *dev)
{
	struct omap_irda *omap_ir = netdev_priv(dev);
	int err;

	omap_ir->speed = 9600;

	err = request_irq(dev->irq, omap_irda_irq, 0, dev->name, dev);
	if (err)
		goto err_irq;

	/*
	 * The interrupt must remain disabled for now.
	 */
	disable_irq(dev->irq);

	/*  Request DMA channels for IrDA hardware */
	if (omap_request_dma(omap_ir->pdata->rx_channel, "IrDA Rx DMA",
			(void *)omap_irda_rx_dma_callback,
			dev, &(omap_ir->rx_dma_channel))) {
		printk(KERN_ERR "Failed to request IrDA Rx DMA\n");
		goto err_irq;
	}

	if (omap_request_dma(omap_ir->pdata->tx_channel, "IrDA Tx DMA",
			(void *)omap_irda_tx_dma_callback,
			dev, &(omap_ir->tx_dma_channel))) {
		printk(KERN_ERR "Failed to request IrDA Tx DMA\n");
		goto err_irq;
	}

	/* Allocate TX and RX buffers for DMA channels */
	omap_ir->rx_buf_dma_virt =
		dma_alloc_coherent(NULL, IRDA_SKB_MAX_MTU,
				&(omap_ir->rx_buf_dma_phys),
				GFP_KERNEL);

	if (!omap_ir->rx_buf_dma_virt) {
		printk(KERN_ERR "Unable to allocate memory for rx_buf_dma\n");
		goto err_irq;
	}

	omap_ir->tx_buf_dma_virt =
		dma_alloc_coherent(NULL, IRDA_SIR_MAX_FRAME,
				&(omap_ir->tx_buf_dma_phys),
				GFP_KERNEL);

	if (!omap_ir->tx_buf_dma_virt) {
		printk(KERN_ERR "Unable to allocate memory for tx_buf_dma\n");
		goto err_mem1;
	}

	/*
	 * Setup the serial port for the specified config.
	 */
	if (omap_ir->pdata->select_irda)
		omap_ir->pdata->select_irda(omap_ir->dev, IR_SEL);

	err = omap_irda_startup(dev);

	if (err)
		goto err_startup;

	omap_irda_set_speed(dev, omap_ir->speed = 9600);

	/*
	 * Open a new IrLAP layer instance.
	 */
	omap_ir->irlap = irlap_open(dev, &omap_ir->qos, "omap_sir");

	err = -ENOMEM;
	if (!omap_ir->irlap)
		goto err_irlap;

	/* Now enable the interrupt and start the queue */
	omap_ir->open = 1;

	/* Start RX DMA */
	omap_irda_start_rx_dma(omap_ir);

	enable_irq(dev->irq);
	netif_start_queue(dev);

	return 0;

err_irlap:
	omap_ir->open = 0;
	omap_irda_shutdown(omap_ir);
err_startup:
	dma_free_coherent(NULL, IRDA_SIR_MAX_FRAME,
			omap_ir->tx_buf_dma_virt, omap_ir->tx_buf_dma_phys);
err_mem1:
	dma_free_coherent(NULL, IRDA_SKB_MAX_MTU,
			omap_ir->rx_buf_dma_virt, omap_ir->rx_buf_dma_phys);
err_irq:
	free_irq(dev->irq, dev);
	return err;
}
コード例 #11
0
static int __devinit tsc2005_ts_init(struct tsc2005 *ts,
				     struct tsc2005_platform_data *pdata)
{
	struct input_dev *idev;
	int r;
	int x_max, y_max;

	init_timer(&ts->penup_timer);
	setup_timer(&ts->penup_timer, tsc2005_ts_penup_timer_handler,
			(unsigned long)ts);

	spin_lock_init(&ts->lock);
	mutex_init(&ts->mutex);

	ts->x_plate_ohm		= pdata->ts_x_plate_ohm ? : 280;
	ts->hw_avg_max		= pdata->ts_hw_avg;
	ts->stab_time		= pdata->ts_stab_time;
	x_max			= pdata->ts_x_max ? : 4096;
	ts->fudge_x		= pdata->ts_x_fudge ? : 4;
	y_max			= pdata->ts_y_max ? : 4096;
	ts->fudge_y		= pdata->ts_y_fudge ? : 8;
	ts->p_max		= pdata->ts_pressure_max ? : MAX_12BIT;
	ts->touch_pressure	= pdata->ts_touch_pressure ? : ts->p_max;
	ts->fudge_p		= pdata->ts_pressure_fudge ? : 2;

	ts->set_reset		= pdata->set_reset;

	if (prescale) {
		x_max = x_size;
		y_max = y_size;
	}

	idev = input_allocate_device();
	if (idev == NULL) {
		r = -ENOMEM;
		goto err1;
	}

	idev->name = "TSC2005 touchscreen";
	snprintf(ts->phys, sizeof(ts->phys), "%s/input-ts",
		 ts->spi->dev.bus_id);
	idev->phys = ts->phys;

	idev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
	idev->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | BIT_MASK(ABS_PRESSURE);
	idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
	ts->idev = idev;

	tsc2005_ts_setup_spi_xfer(ts);

	input_set_abs_params(idev, ABS_X, 0, x_max, ts->fudge_x, 0);
	input_set_abs_params(idev, ABS_Y, 0, y_max, ts->fudge_y, 0);
	input_set_abs_params(idev, ABS_PRESSURE, 0, ts->p_max, ts->fudge_p, 0);

	tsc2005_start_scan(ts);

	r = request_irq(ts->spi->irq, tsc2005_ts_irq_handler,
			(((TSC2005_CFR2_INITVALUE & TSC2005_CFR2_IRQ_MASK) ==
			  TSC2005_CFR2_IRQ_PENDAV)
			 ? IRQF_TRIGGER_RISING
			 : IRQF_TRIGGER_FALLING) |
			IRQF_DISABLED | IRQF_SAMPLE_RANDOM, "tsc2005", ts);
	if (r < 0) {
		dev_err(&ts->spi->dev, "unable to get DAV IRQ");
		goto err2;
	}

	set_irq_wake(ts->spi->irq, 1);

	r = input_register_device(idev);
	if (r < 0) {
		dev_err(&ts->spi->dev, "can't register touchscreen device\n");
		goto err3;
	}

	/* We can tolerate these failing */
	r = device_create_file(&ts->spi->dev, &dev_attr_ts_ctrl_selftest);
	if (r < 0)
		dev_warn(&ts->spi->dev, "can't create sysfs file for %s: %d\n",
			 dev_attr_ts_ctrl_selftest.attr.name, r);

	r = device_create_file(&ts->spi->dev, &dev_attr_pen_down);
	if (r < 0)
		dev_warn(&ts->spi->dev, "can't create sysfs file for %s: %d\n",
			 dev_attr_pen_down.attr.name, r);

	r = device_create_file(&ts->spi->dev, &dev_attr_disable_ts);
	if (r < 0)
		dev_warn(&ts->spi->dev, "can't create sysfs file for %s: %d\n",
			 dev_attr_disable_ts.attr.name, r);

	/* Finally, configure and start the optional EDD watchdog. */
	ts->esd_timeout = pdata->esd_timeout;
	if (ts->esd_timeout && ts->set_reset) {
		unsigned long wdj;
		setup_timer(&ts->esd_timer, tsc2005_esd_timer_handler,
			    (unsigned long)ts);
		INIT_WORK(&ts->esd_work, tsc2005_rst_handler);
		wdj = msecs_to_jiffies(ts->esd_timeout);
		ts->esd_timer.expires = round_jiffies(jiffies+wdj);
		add_timer(&ts->esd_timer);
	}

	return 0;
err3:
	free_irq(ts->spi->irq, ts);
err2:
	tsc2005_stop_scan(ts);
	input_free_device(idev);
err1:
	return r;
}
コード例 #12
0
ファイル: fpga_irq_drv.c プロジェクト: PoppyRobot/codeStudy
int fpga_irq_drv_close(struct inode *inode, struct file *file)
{
	free_irq(fpga_irq, NULL/* &irq_no*/);
    printk(KERN_INFO "fpga_exit.\n");
	return 0;
}
コード例 #13
0
/*
 * si470x_i2c_probe - probe for the device
 */
static int __devinit si470x_i2c_probe(struct i2c_client *client,
		const struct i2c_device_id *id)
{
	struct si470x_device *radio;
	int retval = 0;
	unsigned char version_warning = 0;

	/* private data allocation and initialization */
	radio = kzalloc(sizeof(struct si470x_device), GFP_KERNEL);
	if (!radio) {
		retval = -ENOMEM;
		goto err_initial;
	}

	INIT_WORK(&radio->radio_work, si470x_i2c_interrupt_work);
	radio->users = 0;
	radio->client = client;
	mutex_init(&radio->lock);

	/* video device allocation and initialization */
	radio->videodev = video_device_alloc();
	if (!radio->videodev) {
		retval = -ENOMEM;
		goto err_radio;
	}
	memcpy(radio->videodev, &si470x_viddev_template,
			sizeof(si470x_viddev_template));
	video_set_drvdata(radio->videodev, radio);

	/* power up : need 110ms */
	radio->registers[POWERCFG] = POWERCFG_ENABLE;
	if (si470x_set_register(radio, POWERCFG) < 0) {
		retval = -EIO;
		goto err_all;
	}
	msleep(110);

	/* get device and chip versions */
	if (si470x_get_all_registers(radio) < 0) {
		retval = -EIO;
		goto err_video;
	}
	dev_info(&client->dev, "DeviceID=0x%4.4hx ChipID=0x%4.4hx\n",
			radio->registers[DEVICEID], radio->registers[CHIPID]);
	if ((radio->registers[CHIPID] & CHIPID_FIRMWARE) < RADIO_FW_VERSION) {
		dev_warn(&client->dev,
			"This driver is known to work with "
			"firmware version %hu,\n", RADIO_FW_VERSION);
		dev_warn(&client->dev,
			"but the device has firmware version %hu.\n",
			radio->registers[CHIPID] & CHIPID_FIRMWARE);
		version_warning = 1;
	}

	/* give out version warning */
	if (version_warning == 1) {
		dev_warn(&client->dev,
			"If you have some trouble using this driver,\n");
		dev_warn(&client->dev,
			"please report to V4L ML at "
			"[email protected]\n");
	}

	/* set initial frequency */
	si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */

	/* rds buffer allocation */
	radio->buf_size = rds_buf * 3;
	radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL);
	if (!radio->buffer) {
		retval = -EIO;
		goto err_video;
	}

	/* rds buffer configuration */
	radio->wr_index = 0;
	radio->rd_index = 0;
	init_waitqueue_head(&radio->read_queue);

	retval = request_irq(client->irq, si470x_i2c_interrupt,
			IRQF_TRIGGER_FALLING, DRIVER_NAME, radio);
	if (retval) {
		dev_err(&client->dev, "Failed to register interrupt\n");
		goto err_rds;
	}

	/* register video device */
	retval = video_register_device(radio->videodev, VFL_TYPE_RADIO,
			radio_nr);
	if (retval) {
		dev_warn(&client->dev, "Could not register video device\n");
		goto err_all;
	}
	i2c_set_clientdata(client, radio);

	return 0;
err_all:
	free_irq(client->irq, radio);
err_rds:
	kfree(radio->buffer);
err_video:
	video_device_release(radio->videodev);
err_radio:
	kfree(radio);
err_initial:
	return retval;
}
コード例 #14
0
static int __devinit apds990x_probe(struct i2c_client *client,
                   const struct i2c_device_id *id)
{
    struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
    struct apds990x_data *data;
    int err = 0;

    if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) {
        err = -EIO;
        goto exit;
    }

    data = kzalloc(sizeof(struct apds990x_data), GFP_KERNEL);
    if (!data) {
        err = -ENOMEM;
        goto exit;
    }
    data->client = client;
    i2c_set_clientdata(client, data);

    data->enable = 0;
    data->ps_threshold = 0;
    data->ps_hysteresis_threshold = 0;
    data->ps_detection = 0;
    data->enable_als_sensor = 0;
    data->enable_ps_sensor = 0;
    data->als_poll_delay = 250;
    data->als_atime = 0xC0;
    
    memset( data->luxValue_table, 0, sizeof(data->luxValue_table) );
    data->als_lux_ave = 0;
    data->als_polling_cnt = 0;
    data->als_mean_times = 4;
    data->als_polling_cnt_reset |= ALS_POLLING_CNT_RESET_INIT;
    
    APDS_DEBUG_LOG("enable = %x\n", data->enable);

    mutex_init(&data->update_lock);
    wake_lock_init( &apds_wake_lock, WAKE_LOCK_SUSPEND, "apds990x_ps" );

    err = gpio_request(APDS_PROXIMITY_SENSOR_GPIO,
                        APDS990x_DRV_NAME);
    if (err < 0) {
        APDS_DEBUG_LOG("[%s] failed to request GPIO=%d, ret=%d\n",
               __FUNCTION__,
               APDS_PROXIMITY_SENSOR_GPIO,
               err);
        goto exit_kfree;
    }
    err = gpio_direction_input(APDS_PROXIMITY_SENSOR_GPIO);
    if (err < 0) {
        APDS_DEBUG_LOG("[%s] failed to configure direction for GPIO=%d, ret=%d\n",
               __FUNCTION__,
               APDS_PROXIMITY_SENSOR_GPIO,
               err);
        goto exit_kfree;
    }
    data->ps_irq = gpio_to_irq(APDS_PROXIMITY_SENSOR_GPIO);

    err = request_any_context_irq(data->ps_irq, apds990x_interrupt, IRQ_TYPE_EDGE_FALLING,
        APDS990x_DRV_NAME, (void *)client);
    if(err < 0) {
        APDS_DEBUG_LOG("%s Could not allocate APDS990x_INT(%d) ! err=%d\n",
                 __func__,APDS_PROXIMITY_SENSOR_GPIO,err);
    
        goto exit_kfree;
    }
    apds990x_ps_irq_cnt++;
    apds990x_disable_ps_irq(data);

    INIT_DELAYED_WORK(&data->dwork, apds990x_work_handler);
    INIT_DELAYED_WORK(&data->als_dwork, apds990x_als_polling_work_handler); 

    APDS_DEBUG_LOG("%s interrupt is hooked\n", __func__);

    err = apds990x_init_client(client);
    if (err)
        goto exit_kfree;

    data->input_dev_als = input_allocate_device();
    if (!data->input_dev_als) {
        err = -ENOMEM;
        APDS_DEBUG_LOG("Failed to allocate input device als\n");
        goto exit_free_irq;
    }

    data->input_dev_ps = input_allocate_device();
    if (!data->input_dev_ps) {
        err = -ENOMEM;
        APDS_DEBUG_LOG("Failed to allocate input device ps\n");
        goto exit_free_dev_als;
    }
    
    set_bit(EV_ABS, data->input_dev_als->evbit);
    set_bit(EV_ABS, data->input_dev_ps->evbit);

    input_set_abs_params(data->input_dev_als, ABS_MISC, 0, APDS990X_LUXVALUE_MAX, 0, 0);
    input_set_abs_params(data->input_dev_ps, ABS_DISTANCE, 0, 1, 0, 0);

    data->input_dev_als->name = "Avago light sensor";
    data->input_dev_ps->name = "Avago proximity sensor";

    err = input_register_device(data->input_dev_als);
    if (err) {
        err = -ENOMEM;
        APDS_DEBUG_LOG("Unable to register input device als: %s\n",
               data->input_dev_als->name);
        goto exit_free_dev_ps;
    }

    err = input_register_device(data->input_dev_ps);
    if (err) {
        err = -ENOMEM;
        APDS_DEBUG_LOG("Unable to register input device ps: %s\n",
               data->input_dev_ps->name);
        goto exit_unregister_dev_als;
    }

    err = sysfs_create_group(&client->dev.kobj, &apds990x_attr_group);
    if (err)
        goto exit_unregister_dev_ps;

    device_init_wakeup(&client->dev, 1);
    atomic_set(&g_dev_status, APDS990X_DEV_STATUS_INIT);
    
    err = misc_register(&apds990x_device);
    if (err)
    {
        APDS_DEBUG_LOG(KERN_ERR
               "apds990x_probe: apds990x register failed\n");
        goto exit_sysfs_remove;
    }
    APDS_DEBUG_LOG("%s support ver. %s enabled\n", __func__, DRIVER_VERSION);

    return 0;

exit_sysfs_remove:
    sysfs_remove_group(&client->dev.kobj, &apds990x_attr_group);
exit_unregister_dev_ps:
    input_unregister_device(data->input_dev_ps);    
exit_unregister_dev_als:
    input_unregister_device(data->input_dev_als);
exit_free_dev_ps:
    input_free_device(data->input_dev_ps);
exit_free_dev_als:
    input_free_device(data->input_dev_als);
exit_free_irq:
    free_irq(data->ps_irq, client); 
exit_kfree:
    kfree(data);
exit:
    return err;
}
コード例 #15
0
static int iio_bfin_tmr_trigger_probe(struct platform_device *pdev)
{
	struct iio_bfin_timer_trigger_pdata *pdata = pdev->dev.platform_data;
	struct bfin_tmr_state *st;
	unsigned int config;
	int ret;

	st = kzalloc(sizeof(*st), GFP_KERNEL);
	if (st == NULL) {
		ret = -ENOMEM;
		goto out;
	}

	st->irq = platform_get_irq(pdev, 0);
	if (!st->irq) {
		dev_err(&pdev->dev, "No IRQs specified");
		ret = -ENODEV;
		goto out1;
	}

	ret = iio_bfin_tmr_get_number(st->irq);
	if (ret < 0)
		goto out1;

	st->timer_num = ret;
	st->t = &iio_bfin_timer_code[st->timer_num];

	st->trig = iio_trigger_alloc("bfintmr%d", st->timer_num);
	if (!st->trig) {
		ret = -ENOMEM;
		goto out1;
	}

	st->trig->ops = &iio_bfin_tmr_trigger_ops;
	st->trig->dev.groups = iio_bfin_tmr_trigger_attr_groups;
	iio_trigger_set_drvdata(st->trig, st);
	ret = iio_trigger_register(st->trig);
	if (ret)
		goto out2;

	ret = request_irq(st->irq, iio_bfin_tmr_trigger_isr,
			  0, st->trig->name, st);
	if (ret) {
		dev_err(&pdev->dev,
			"request IRQ-%d failed", st->irq);
		goto out4;
	}

	config = PWM_OUT | PERIOD_CNT | IRQ_ENA;

	if (pdata && pdata->output_enable) {
		unsigned long long val;

		st->output_enable = true;

		ret = peripheral_request(st->t->pin, st->trig->name);
		if (ret)
			goto out_free_irq;

		val = (unsigned long long)get_sclk() * pdata->duty_ns;
		do_div(val, NSEC_PER_SEC);
		st->duty = val;

		/**
		 * The interrupt will be generated at the end of the period,
		 * since we want the interrupt to be generated at end of the
		 * pulse we invert both polarity and duty cycle, so that the
		 * pulse will be generated directly before the interrupt.
		 */
		if (pdata->active_low)
			config |= PULSE_HI;
	} else {
		st->duty = 1;
		config |= OUT_DIS;
	}

	set_gptimer_config(st->t->id, config);

	dev_info(&pdev->dev, "iio trigger Blackfin TMR%d, IRQ-%d",
		 st->timer_num, st->irq);
	platform_set_drvdata(pdev, st);

	return 0;
out_free_irq:
	free_irq(st->irq, st);
out4:
	iio_trigger_unregister(st->trig);
out2:
	iio_trigger_put(st->trig);
out1:
	kfree(st);
out:
	return ret;
}
コード例 #16
0
ファイル: i2c-pnx.c プロジェクト: 12rafael/jellytimekernel
static int __devinit i2c_pnx_probe(struct platform_device *pdev)
{
	unsigned long tmp;
	int ret = 0;
	struct i2c_pnx_algo_data *alg_data;
	unsigned long freq;
	struct i2c_pnx_data *i2c_pnx = pdev->dev.platform_data;

	if (!i2c_pnx || !i2c_pnx->name) {
		dev_err(&pdev->dev, "%s: no platform data supplied\n",
		       __func__);
		ret = -EINVAL;
		goto out;
	}

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

	platform_set_drvdata(pdev, alg_data);

	strlcpy(alg_data->adapter.name, i2c_pnx->name,
		sizeof(alg_data->adapter.name));
	alg_data->adapter.dev.parent = &pdev->dev;
	alg_data->adapter.algo = &pnx_algorithm;
	alg_data->adapter.algo_data = alg_data;
	alg_data->adapter.nr = pdev->id;
	alg_data->i2c_pnx = i2c_pnx;

	alg_data->clk = clk_get(&pdev->dev, NULL);
	if (IS_ERR(alg_data->clk)) {
		ret = PTR_ERR(alg_data->clk);
		goto out_drvdata;
	}

	init_timer(&alg_data->mif.timer);
	alg_data->mif.timer.function = i2c_pnx_timeout;
	alg_data->mif.timer.data = (unsigned long)alg_data;

	/* Register I/O resource */
	if (!request_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE,
				pdev->name)) {
		dev_err(&pdev->dev,
		       "I/O region 0x%08x for I2C already in use.\n",
		       i2c_pnx->base);
		ret = -ENODEV;
		goto out_clkget;
	}

	alg_data->ioaddr = ioremap(i2c_pnx->base, I2C_PNX_REGION_SIZE);
	if (!alg_data->ioaddr) {
		dev_err(&pdev->dev, "Couldn't ioremap I2C I/O region\n");
		ret = -ENOMEM;
		goto out_release;
	}

	ret = clk_enable(alg_data->clk);
	if (ret)
		goto out_unmap;

	freq = clk_get_rate(alg_data->clk);

	/*
	 * Clock Divisor High This value is the number of system clocks
	 * the serial clock (SCL) will be high.
	 * For example, if the system clock period is 50 ns and the maximum
	 * desired serial period is 10000 ns (100 kHz), then CLKHI would be
	 * set to 0.5*(f_sys/f_i2c)-2=0.5*(20e6/100e3)-2=98. The actual value
	 * programmed into CLKHI will vary from this slightly due to
	 * variations in the output pad's rise and fall times as well as
	 * the deglitching filter length.
	 */

	tmp = ((freq / 1000) / I2C_PNX_SPEED_KHZ) / 2 - 2;
	if (tmp > 0x3FF)
		tmp = 0x3FF;
	iowrite32(tmp, I2C_REG_CKH(alg_data));
	iowrite32(tmp, I2C_REG_CKL(alg_data));

	iowrite32(mcntrl_reset, I2C_REG_CTL(alg_data));
	if (wait_reset(I2C_PNX_TIMEOUT, alg_data)) {
		ret = -ENODEV;
		goto out_clock;
	}
	init_completion(&alg_data->mif.complete);

	ret = request_irq(i2c_pnx->irq, i2c_pnx_interrupt,
			0, pdev->name, alg_data);
	if (ret)
		goto out_clock;

	/* Register this adapter with the I2C subsystem */
	ret = i2c_add_numbered_adapter(&alg_data->adapter);
	if (ret < 0) {
		dev_err(&pdev->dev, "I2C: Failed to add bus\n");
		goto out_irq;
	}

	dev_dbg(&pdev->dev, "%s: Master at %#8x, irq %d.\n",
	       alg_data->adapter.name, i2c_pnx->base, i2c_pnx->irq);

	return 0;

out_irq:
	free_irq(i2c_pnx->irq, alg_data);
out_clock:
	clk_disable(alg_data->clk);
out_unmap:
	iounmap(alg_data->ioaddr);
out_release:
	release_mem_region(i2c_pnx->base, I2C_PNX_REGION_SIZE);
out_clkget:
	clk_put(alg_data->clk);
out_drvdata:
	kfree(alg_data);
err_kzalloc:
	platform_set_drvdata(pdev, NULL);
out:
	return ret;
}
コード例 #17
0
s32 tsdemux_init(u32 vid, u32 aid, u32 sid)
{
    s32 r;
    u32 parser_sub_start_ptr;
    u32 parser_sub_end_ptr;
    u32 parser_sub_rp;

    parser_sub_start_ptr = READ_MPEG_REG(PARSER_SUB_START_PTR);
    parser_sub_end_ptr = READ_MPEG_REG(PARSER_SUB_END_PTR);
    parser_sub_rp = READ_MPEG_REG(PARSER_SUB_RP);

    WRITE_MPEG_REG(RESET1_REGISTER, RESET_PARSER);

#ifdef ENABLE_DEMUX_DRIVER
    tsdemux_reset();
#else
    WRITE_MPEG_REG(RESET1_REGISTER, RESET_PARSER | RESET_DEMUXSTB);

    WRITE_MPEG_REG(STB_TOP_CONFIG, 0);
    WRITE_MPEG_REG(DEMUX_CONTROL, 0);
#endif

    /* set PID filter */
    printk("tsdemux video_pid = 0x%x, audio_pid = 0x%x, sub_pid = 0x%x\n",
           vid, aid, sid);
#ifndef ENABLE_DEMUX_DRIVER
    WRITE_MPEG_REG(FM_WR_DATA,
                   (((vid & 0x1fff) | (VIDEO_PACKET << 13)) << 16) |
                   ((aid & 0x1fff) | (AUDIO_PACKET << 13)));
    WRITE_MPEG_REG(FM_WR_ADDR, 0x8000);
    while (READ_MPEG_REG(FM_WR_ADDR) & 0x8000) {
        ;
    }

    WRITE_MPEG_REG(FM_WR_DATA,
                   (((sid & 0x1fff) | (SUB_PACKET << 13)) << 16) | 0xffff);
    WRITE_MPEG_REG(FM_WR_ADDR, 0x8001);
    while (READ_MPEG_REG(FM_WR_ADDR) & 0x8000) {
        ;
    }

    WRITE_MPEG_REG(MAX_FM_COMP_ADDR, 1);

    WRITE_MPEG_REG(STB_INT_MASK, 0);
    WRITE_MPEG_REG(STB_INT_STATUS, 0xffff);

    /* TS data path */
    WRITE_MPEG_REG(FEC_INPUT_CONTROL, 0x7000);
    WRITE_MPEG_REG(DEMUX_MEM_REQ_EN,
                   (1 << VIDEO_PACKET) |
                   (1 << AUDIO_PACKET) |
                   (1 << SUB_PACKET));
    WRITE_MPEG_REG(DEMUX_ENDIAN,
                   (7 << OTHER_ENDIAN)  |
                   (7 << BYPASS_ENDIAN) |
                   (0 << SECTION_ENDIAN));
    WRITE_MPEG_REG(TS_HIU_CTL, 1 << USE_HI_BSF_INTERFACE);
    WRITE_MPEG_REG(TS_FILE_CONFIG,
                   (demux_skipbyte << 16)                  |
                   (6 << DES_OUT_DLY)                      |
                   (3 << TRANSPORT_SCRAMBLING_CONTROL_ODD) |
                   (1 << TS_HIU_ENABLE)                    |
                   (4 << FEC_FILE_CLK_DIV));

    /* enable TS demux */
    WRITE_MPEG_REG(DEMUX_CONTROL, (1 << STB_DEMUX_ENABLE) | (1 << KEEP_DUPLICATE_PACKAGE));
#endif

    if (fetchbuf == 0) {
        printk("%s: no fetchbuf\n", __FUNCTION__);
        return -ENOMEM;
    }

    /* hook stream buffer with PARSER */
    WRITE_MPEG_REG(PARSER_VIDEO_START_PTR,
                   READ_MPEG_REG(VLD_MEM_VIFIFO_START_PTR));
    WRITE_MPEG_REG(PARSER_VIDEO_END_PTR,
                   READ_MPEG_REG(VLD_MEM_VIFIFO_END_PTR));
    CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_VID_MAN_RD_PTR);

    WRITE_MPEG_REG(PARSER_AUDIO_START_PTR,
                   READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR));
    WRITE_MPEG_REG(PARSER_AUDIO_END_PTR,
                   READ_MPEG_REG(AIU_MEM_AIFIFO_END_PTR));
    CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_AUD_MAN_RD_PTR);

    WRITE_MPEG_REG(PARSER_CONFIG,
                   (10 << PS_CFG_PFIFO_EMPTY_CNT_BIT) |
                   (1  << PS_CFG_MAX_ES_WR_CYCLE_BIT) |
                   (16 << PS_CFG_MAX_FETCH_CYCLE_BIT));

    WRITE_MPEG_REG(VLD_MEM_VIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT);
    CLEAR_MPEG_REG_MASK(VLD_MEM_VIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT);

    WRITE_MPEG_REG(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT);
    CLEAR_MPEG_REG_MASK(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT);

    WRITE_MPEG_REG(PARSER_SUB_START_PTR, parser_sub_start_ptr);
    WRITE_MPEG_REG(PARSER_SUB_END_PTR, parser_sub_end_ptr);
    WRITE_MPEG_REG(PARSER_SUB_RP, parser_sub_rp);
    SET_MPEG_REG_MASK(PARSER_ES_CONTROL, (7 << ES_SUB_WR_ENDIAN_BIT) | ES_SUB_MAN_RD_PTR);

    if ((r = pts_start(PTS_TYPE_VIDEO)) < 0) {
        printk("Video pts start  failed.(%d)\n", r);
        goto err1;
    }

    if ((r = pts_start(PTS_TYPE_AUDIO)) < 0) {
        printk("Audio pts start failed.(%d)\n", r);
        goto err2;
    }

    r = request_irq(INT_PARSER, parser_isr,
                    IRQF_SHARED, "tsdemux-fetch",
                    (void *)tsdemux_fetch_id);
    if (r) {
        goto err3;
    }

    WRITE_MPEG_REG(PARSER_INT_STATUS, 0xffff);
    WRITE_MPEG_REG(PARSER_INT_ENABLE, PARSER_INTSTAT_FETCH_CMD << PARSER_INT_HOST_EN_BIT);

    WRITE_MPEG_REG(PARSER_VIDEO_HOLE, 0x400);
    WRITE_MPEG_REG(PARSER_AUDIO_HOLE, 0x400);

    discontinued_counter = 0;
#ifndef ENABLE_DEMUX_DRIVER
    r = request_irq(INT_DEMUX, tsdemux_isr,
                    IRQF_SHARED, "tsdemux-irq",
                    (void *)tsdemux_irq_id);
    WRITE_MPEG_REG(STB_INT_MASK,
                   (1 << SUB_PES_READY)
                   | (1 << NEW_PDTS_READY)
                   | (1 << DIS_CONTINUITY_PACKET));
    if (r) {
        goto err4;
    }
#else
    tsdemux_config();
    tsdemux_request_irq(tsdemux_isr, (void *)tsdemux_irq_id);
    if (vid < 0x1FFF) {
        tsdemux_set_vid(vid);
    }
    if (aid < 0x1FFF) {
        tsdemux_set_aid(aid);
    }
    if (sid < 0x1FFF) {
        tsdemux_set_sid(sid);
    }

#endif

    return 0;

#ifndef ENABLE_DEMUX_DRIVER
err4:
    free_irq(INT_PARSER, (void *)tsdemux_fetch_id);
#endif
err3:
    pts_stop(PTS_TYPE_AUDIO);
err2:
    pts_stop(PTS_TYPE_VIDEO);
err1:
    printk("TS Demux init failed.\n");
    return -ENOENT;
}
コード例 #18
0
int cy_as_hal_free_sd_isr(void)
{
	free_irq( OMAP_GPIO_IRQ(AST__rn_b), NULL );
	return 0;
}
コード例 #19
0
ファイル: phy-twl6030-usb.c プロジェクト: 020gzh/linux
static int twl6030_usb_probe(struct platform_device *pdev)
{
	u32 ret;
	struct twl6030_usb	*twl;
	int			status, err;
	struct device_node	*np = pdev->dev.of_node;
	struct device		*dev = &pdev->dev;
	struct twl4030_usb_data	*pdata = dev_get_platdata(dev);

	twl = devm_kzalloc(dev, sizeof(*twl), GFP_KERNEL);
	if (!twl)
		return -ENOMEM;

	twl->dev		= &pdev->dev;
	twl->irq1		= platform_get_irq(pdev, 0);
	twl->irq2		= platform_get_irq(pdev, 1);
	twl->linkstat		= MUSB_UNKNOWN;

	twl->comparator.set_vbus	= twl6030_set_vbus;
	twl->comparator.start_srp	= twl6030_start_srp;

	ret = omap_usb2_set_comparator(&twl->comparator);
	if (ret == -ENODEV) {
		dev_info(&pdev->dev, "phy not ready, deferring probe");
		return -EPROBE_DEFER;
	}

	if (np) {
		twl->regulator = "usb";
	} else if (pdata) {
		if (pdata->features & TWL6032_SUBCLASS)
			twl->regulator = "ldousb";
		else
			twl->regulator = "vusb";
	} else {
		dev_err(&pdev->dev, "twl6030 initialized without pdata\n");
		return -EINVAL;
	}

	/* init spinlock for workqueue */
	spin_lock_init(&twl->lock);

	err = twl6030_usb_ldo_init(twl);
	if (err) {
		dev_err(&pdev->dev, "ldo init failed\n");
		return err;
	}

	platform_set_drvdata(pdev, twl);
	if (device_create_file(&pdev->dev, &dev_attr_vbus))
		dev_warn(&pdev->dev, "could not create sysfs file\n");

	INIT_WORK(&twl->set_vbus_work, otg_set_vbus_work);

	status = request_threaded_irq(twl->irq1, NULL, twl6030_usbotg_irq,
			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT,
			"twl6030_usb", twl);
	if (status < 0) {
		dev_err(&pdev->dev, "can't get IRQ %d, err %d\n",
			twl->irq1, status);
		device_remove_file(twl->dev, &dev_attr_vbus);
		return status;
	}

	status = request_threaded_irq(twl->irq2, NULL, twl6030_usb_irq,
			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT,
			"twl6030_usb", twl);
	if (status < 0) {
		dev_err(&pdev->dev, "can't get IRQ %d, err %d\n",
			twl->irq2, status);
		free_irq(twl->irq1, twl);
		device_remove_file(twl->dev, &dev_attr_vbus);
		return status;
	}

	twl->asleep = 0;
	twl6030_enable_irq(twl);
	dev_info(&pdev->dev, "Initialized TWL6030 USB module\n");

	return 0;
}
コード例 #20
0
int init_link_device_pm(struct link_device *ld,
			struct modem_link_pm *pm,
			struct link_pm_svc *pm_svc,
			void (*fail_fn)(struct modem_link_pm *),
			void (*cp_fail_fn)(struct modem_link_pm *))
{
	struct lli_link_device *mld = container_of(ld, struct lli_link_device, ld);
	int err;
	int cp2ap_wakeup;
	int cp2ap_status;
	unsigned int num;
	unsigned long flags;
	char name[MAX_NAME_LEN];

	/*
	Set up variables for PM
	*/
	pm->link_name = ld->name;
	pm->fail_handler = fail_fn;
	pm->cp_fail_handler = cp_fail_fn;

	/*
	Retrieve GPIO pins and IRQ numbers for PM
	*/
	pm->gpio_cp2ap_wakeup = mld->gpio_ap_wakeup;
	pm->gpio_ap2cp_wakeup = mld->gpio_cp_wakeup;
	pm->gpio_cp2ap_status = mld->gpio_cp_status;
	pm->gpio_ap2cp_status = mld->gpio_ap_status;

	num = gpio_to_irq(pm->gpio_cp2ap_wakeup);
	flags = IRQF_NO_THREAD | IRQF_NO_SUSPEND | IRQF_ONESHOT;
	snprintf(name, MAX_NAME_LEN, "%s_cp2ap_wakeup", pm->link_name);
	mif_init_irq(&pm->cp2ap_wakeup_irq, num, name, flags);

	num = gpio_to_irq(pm->gpio_cp2ap_status);
	flags = IRQF_NO_THREAD | IRQF_NO_SUSPEND | IRQF_ONESHOT;
	snprintf(name, MAX_NAME_LEN, "%s_cp2ap_status", pm->link_name);
	mif_init_irq(&pm->cp2ap_status_irq, num, name, flags);

	mif_err("CP2AP_WAKEUP GPIO:%d IRQ:%d\n",
		pm->gpio_cp2ap_wakeup, pm->cp2ap_wakeup_irq.num);

	mif_err("AP2CP_WAKEUP GPIO:%d\n", pm->gpio_ap2cp_wakeup);

	mif_err("CP2AP_STATUS GPIO:%d IRQ:%d\n",
		pm->gpio_cp2ap_status, pm->cp2ap_status_irq.num);

	mif_err("AP2CP_STATUS GPIO:%d\n", pm->gpio_ap2cp_status);

	/*
	Register cp2ap_wakeup IRQ handler
	*/
	cp2ap_wakeup = gpio_get_value(pm->gpio_cp2ap_wakeup);
	change_irq_level(pm->cp2ap_wakeup_irq.num, cp2ap_wakeup);

	err = mif_request_irq(&pm->cp2ap_wakeup_irq, cp2ap_wakeup_handler, pm);
	if (err) {
		mif_err("%s: ERR! request_irq(%s#%d) fail (%d)\n",
			pm->link_name, pm->cp2ap_wakeup_irq.name,
			pm->cp2ap_wakeup_irq.num, err);
		return err;
	}
	mif_disable_irq(&pm->cp2ap_wakeup_irq);

	mif_err("%s: %s_irq#%d handler registered\n", pm->link_name,
		pm->cp2ap_wakeup_irq.name, pm->cp2ap_wakeup_irq.num);

	/*
	Register cp2ap_status IRQ handler
	*/
	cp2ap_status = gpio_get_value(pm->gpio_cp2ap_status);
	change_irq_level(pm->cp2ap_status_irq.num, cp2ap_status);

	err = mif_request_irq(&pm->cp2ap_status_irq, cp2ap_status_handler, pm);
	if (err) {
		mif_err("%s: ERR! request_irq(%s#%d) fail (%d)\n",
			pm->link_name, pm->cp2ap_status_irq.name,
			pm->cp2ap_status_irq.num, err);
		free_irq(pm->cp2ap_wakeup_irq.num, pm);
		return err;
	}
	mif_disable_irq(&pm->cp2ap_status_irq);

	mif_err("%s: %s_irq#%d handler registered\n", pm->link_name,
		pm->cp2ap_status_irq.name, pm->cp2ap_status_irq.num);

	/*
	Initialize common variables for PM
	*/
	spin_lock_init(&pm->lock);

	snprintf(pm->wlock_name, MAX_NAME_LEN, "%s_pm_wlock", pm->link_name);
	wake_lock_init(&pm->wlock, WAKE_LOCK_SUSPEND, pm->wlock_name);

	snprintf(pm->wq_name, MAX_NAME_LEN, "%s_pm_wq", pm->link_name);
	flags = WQ_NON_REENTRANT | WQ_UNBOUND | WQ_HIGHPRI;
	pm->wq = alloc_workqueue(pm->wq_name, flags, 1);
	if (!pm->wq) {
		mif_err("%s: ERR! fail to create %s\n",
			pm->link_name, pm->wq_name);
		return -EFAULT;
	}

	INIT_DELAYED_WORK(&pm->cp_free_dwork, cp_free_work_func);

	init_pm_fsm(pm);

	/*
	Register PM functions set by the common link PM framework and used by
	each link device driver
	*/
	pm->start = start_link_pm;
	pm->stop = stop_link_pm;
	pm->request_hold = request_hold;
	pm->release_hold = release_hold;
	pm->link_active = link_active;

	return 0;
}
コード例 #21
0
static int jpeg_probe(struct platform_device *pdev)
{
	struct	resource *res;
	int	ret;

	/* global structure */
	jpeg_ctrl = kzalloc(sizeof(*jpeg_ctrl), GFP_KERNEL);
	if (!jpeg_ctrl) {
		dev_err(&pdev->dev, "%s: not enough memory\n",
			__func__);
		ret = -ENOMEM;
		goto err_alloc;
	}

	/* setup jpeg control */
	ret = jpeg_setup_controller(jpeg_ctrl);
	if (ret) {
		jpeg_err("failed to setup controller\n");
		goto err_setup;
	}

	/* memory region */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		jpeg_err("failed to get jpeg memory region resource\n");
		ret = -ENOENT;
		goto err_res;
	}

	res = request_mem_region(res->start,
				res->end - res->start + 1, pdev->name);
	if (!res) {
		jpeg_err("failed to request jpeg io memory region\n");
		ret = -ENOMEM;
		goto err_region;
	}

	/* ioremap */
	jpeg_ctrl->reg_base = ioremap(res->start, res->end - res->start + 1);
	if (!jpeg_ctrl->reg_base) {
		jpeg_err("failed to remap jpeg io region\n");
		ret = -ENOENT;
		goto err_map;
	}

	/* irq */
	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res) {
		jpeg_err("failed to request jpeg irq resource\n");
		ret = -ENOENT;
		goto err_map;
	}

	jpeg_ctrl->irq_no = res->start;
	ret = request_irq(jpeg_ctrl->irq_no, (void *)jpeg_irq,
			IRQF_DISABLED, pdev->name, jpeg_ctrl);
	if (ret != 0) {
		jpeg_err("failed to jpeg request irq\n");
		ret = -ENOENT;
		goto err_irq;
	}

	/* clock */
	jpeg_ctrl->clk = clk_get(&pdev->dev, "jpeg");
	if (IS_ERR(jpeg_ctrl->clk)) {
		jpeg_err("failed to find jpeg clock source\n");
		ret = -ENOENT;
		goto err_clk;
	}

	ret = jpeg_init_mem(&pdev->dev, &jpeg_ctrl->mem.base);
	if (ret != 0) {
		jpeg_err("failed to init. jpeg mem");
		ret = -ENOMEM;
		goto err_mem;
	}

	ret = misc_register(&jpeg_miscdev);
	if (ret) {
		jpeg_err("failed to register misc driver\n");
		goto err_reg;
	}

#ifdef CONFIG_PM_RUNTIME
	jpeg_pm = &pdev->dev;
	pm_runtime_enable(jpeg_pm);
#endif
	return 0;

err_reg:
	clk_put(jpeg_ctrl->clk);
err_mem:
err_clk:
	free_irq(jpeg_ctrl->irq_no, NULL);
err_irq:
	iounmap(jpeg_ctrl->reg_base);
err_map:
err_region:
	kfree(res);
err_res:
	mutex_destroy(&jpeg_ctrl->lock);
err_setup:
	kfree(jpeg_ctrl);
err_alloc:
	return ret;

}
コード例 #22
0
ファイル: irq-renesas-irqc.c プロジェクト: Kirill2013/kasan
static int irqc_probe(struct platform_device *pdev)
{
	struct irqc_priv *p;
	struct resource *io;
	struct resource *irq;
	struct irq_chip *irq_chip;
	const char *name = dev_name(&pdev->dev);
	int ret;
	int k;

	p = kzalloc(sizeof(*p), GFP_KERNEL);
	if (!p) {
		dev_err(&pdev->dev, "failed to allocate driver data\n");
		ret = -ENOMEM;
		goto err0;
	}

	p->pdev = pdev;
	platform_set_drvdata(pdev, p);

	p->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(p->clk)) {
		dev_warn(&pdev->dev, "unable to get clock\n");
		p->clk = NULL;
	}

	pm_runtime_enable(&pdev->dev);
	pm_runtime_get_sync(&pdev->dev);

	/* get hold of manadatory IOMEM */
	io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!io) {
		dev_err(&pdev->dev, "not enough IOMEM resources\n");
		ret = -EINVAL;
		goto err1;
	}

	/* allow any number of IRQs between 1 and IRQC_IRQ_MAX */
	for (k = 0; k < IRQC_IRQ_MAX; k++) {
		irq = platform_get_resource(pdev, IORESOURCE_IRQ, k);
		if (!irq)
			break;

		p->irq[k].p = p;
		p->irq[k].requested_irq = irq->start;
	}

	p->number_of_irqs = k;
	if (p->number_of_irqs < 1) {
		dev_err(&pdev->dev, "not enough IRQ resources\n");
		ret = -EINVAL;
		goto err1;
	}

	/* ioremap IOMEM and setup read/write callbacks */
	p->iomem = ioremap_nocache(io->start, resource_size(io));
	if (!p->iomem) {
		dev_err(&pdev->dev, "failed to remap IOMEM\n");
		ret = -ENXIO;
		goto err2;
	}

	p->cpu_int_base = p->iomem + IRQC_INT_CPU_BASE(0); /* SYS-SPI */

	irq_chip = &p->irq_chip;
	irq_chip->name = name;
	irq_chip->irq_mask = irqc_irq_disable;
	irq_chip->irq_unmask = irqc_irq_enable;
	irq_chip->irq_set_type = irqc_irq_set_type;
	irq_chip->irq_set_wake = irqc_irq_set_wake;
	irq_chip->flags	= IRQCHIP_MASK_ON_SUSPEND;

	p->irq_domain = irq_domain_add_simple(pdev->dev.of_node,
					      p->number_of_irqs, 0,
					      &irqc_irq_domain_ops, p);
	if (!p->irq_domain) {
		ret = -ENXIO;
		dev_err(&pdev->dev, "cannot initialize irq domain\n");
		goto err2;
	}

	/* request interrupts one by one */
	for (k = 0; k < p->number_of_irqs; k++) {
		if (request_irq(p->irq[k].requested_irq, irqc_irq_handler,
				0, name, &p->irq[k])) {
			dev_err(&pdev->dev, "failed to request IRQ\n");
			ret = -ENOENT;
			goto err3;
		}
	}

	dev_info(&pdev->dev, "driving %d irqs\n", p->number_of_irqs);

	return 0;
err3:
	while (--k >= 0)
		free_irq(p->irq[k].requested_irq, &p->irq[k]);

	irq_domain_remove(p->irq_domain);
err2:
	iounmap(p->iomem);
err1:
	pm_runtime_put(&pdev->dev);
	pm_runtime_disable(&pdev->dev);
	kfree(p);
err0:
	return ret;
}
コード例 #23
0
static void p54p_stop(struct ieee80211_hw *dev)
{
	struct p54p_priv *priv = dev->priv;
	struct p54p_ring_control *ring_control = priv->ring_control;
	unsigned int i;
	struct p54p_desc *desc;

	P54P_WRITE(int_enable, cpu_to_le32(0));
	P54P_READ(int_enable);
	udelay(10);

	free_irq(priv->pdev->irq, dev);

	tasklet_kill(&priv->tasklet);

	P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET));

	for (i = 0; i < ARRAY_SIZE(priv->rx_buf_data); i++) {
		desc = &ring_control->rx_data[i];
		if (desc->host_addr)
			pci_unmap_single(priv->pdev,
					 le32_to_cpu(desc->host_addr),
					 priv->common.rx_mtu + 32,
					 PCI_DMA_FROMDEVICE);
		kfree_skb(priv->rx_buf_data[i]);
		priv->rx_buf_data[i] = NULL;
	}

	for (i = 0; i < ARRAY_SIZE(priv->rx_buf_mgmt); i++) {
		desc = &ring_control->rx_mgmt[i];
		if (desc->host_addr)
			pci_unmap_single(priv->pdev,
					 le32_to_cpu(desc->host_addr),
					 priv->common.rx_mtu + 32,
					 PCI_DMA_FROMDEVICE);
		kfree_skb(priv->rx_buf_mgmt[i]);
		priv->rx_buf_mgmt[i] = NULL;
	}

	for (i = 0; i < ARRAY_SIZE(priv->tx_buf_data); i++) {
		desc = &ring_control->tx_data[i];
		if (desc->host_addr)
			pci_unmap_single(priv->pdev,
					 le32_to_cpu(desc->host_addr),
					 le16_to_cpu(desc->len),
					 PCI_DMA_TODEVICE);

		p54_free_skb(dev, priv->tx_buf_data[i]);
		priv->tx_buf_data[i] = NULL;
	}

	for (i = 0; i < ARRAY_SIZE(priv->tx_buf_mgmt); i++) {
		desc = &ring_control->tx_mgmt[i];
		if (desc->host_addr)
			pci_unmap_single(priv->pdev,
					 le32_to_cpu(desc->host_addr),
					 le16_to_cpu(desc->len),
					 PCI_DMA_TODEVICE);

		p54_free_skb(dev, priv->tx_buf_mgmt[i]);
		priv->tx_buf_mgmt[i] = NULL;
	}

	memset(ring_control, 0, sizeof(*ring_control));
}
コード例 #24
0
int es705_gpio_init(struct es705_priv *es705)
{
	int rc = 0;
	es705->pdata->reset_gpio = reset_gpio;

	if (es705->pdata->wakeup_gpio != -1) {
		rc = gpio_request(es705->pdata->wakeup_gpio, "es705_wakeup");
		if (rc < 0) {
			dev_err(es705->dev, "%s(): es705_wakeup request failed",
				__func__);
			goto wakeup_gpio_request_error;
		}
		rc = gpio_direction_output(es705->pdata->wakeup_gpio, 0);
		if (rc < 0) {
			dev_err(es705->dev, "%s(): es705_wakeup direction failed",
				__func__);
			goto wakeup_gpio_direction_error;
		}
	} else {
		dev_warn(es705->dev, "%s(): wakeup_gpio undefined\n",
				__func__);
	}
	/* under H/W rev 0.5 */
	if (es705->pdata->uart_gpio != -1) {
		rc = gpio_request(es705->pdata->uart_gpio, "es705_uart");
		if (rc < 0) {
			dev_err(es705->dev, "%s(): es705_uart request failed",
				__func__);
			goto uart_gpio_request_error;
		}
		rc = gpio_direction_output(es705->pdata->uart_gpio, 0);
		if (rc < 0) {
			dev_err(es705->dev, "%s(): es705_uart direction failed",
				__func__);
			goto uart_gpio_direction_error;
		}
	} else {
		dev_warn(es705->dev, "%s(): es705_uart undefined\n",
				__func__);
	}

	if (es705->pdata->gpiob_gpio) {
		rc = request_threaded_irq(es705->pdata->irq_base, NULL,
					  es705_irq_event, IRQF_ONESHOT | IRQF_TRIGGER_RISING,
					  "es705-irq-event", es705);
		if (rc) {
			dev_err(es705->dev, "%s(): event request_irq() failed\n",
				__func__);
			goto event_irq_request_error;
		}
		rc = irq_set_irq_wake(es705->pdata->irq_base, 1);
		if (rc < 0) {
			dev_err(es705->dev, "%s(): set event irq wake failed\n",
				__func__);
			disable_irq(es705->pdata->irq_base);
			free_irq(es705->pdata->irq_base, es705);
			goto event_irq_wake_error;
		}
	}

	return rc;
uart_gpio_direction_error:
	gpio_free(es705->pdata->uart_gpio);
uart_gpio_request_error:
wakeup_gpio_direction_error:
	gpio_free(es705->pdata->wakeup_gpio);
wakeup_gpio_request_error:
event_irq_wake_error:
event_irq_request_error:
	return rc;
}
コード例 #25
0
/*
 * keypad controller should be initialized in the following sequence
 * only, otherwise it might get into FSM stuck state.
 *
 * - Initialize keypad control parameters, like no. of rows, columns,
 *   timing values etc.,
 * - configure rows and column gpios pull up/down.
 * - set irq edge type.
 * - enable the keypad controller.
 */
static int __devinit pmic8058_kp_probe(struct platform_device *pdev)
{
	struct pmic8058_keypad_data *pdata = pdev->dev.platform_data;
	struct pmic8058_kp *kp;
	int rc, i;
	unsigned short *keycodes;
	u8 ctrl_val;

	if (!pdata || !pdata->num_cols || !pdata->num_rows ||
		pdata->num_cols > MATRIX_MAX_COLS ||
		pdata->num_rows > MATRIX_MAX_ROWS ||
		!pdata->keymap) {
		dev_err(&pdev->dev, "invalid platform data\n");
		return -EINVAL;
	}

	if (pdata->rows_gpio_start < 0 || pdata->cols_gpio_start < 0) {
		dev_err(&pdev->dev, "invalid gpio_start platform data\n");
		return -EINVAL;
	}

	if (!pdata->scan_delay_ms || pdata->scan_delay_ms > MAX_SCAN_DELAY
		|| pdata->scan_delay_ms < MIN_SCAN_DELAY ||
		!is_power_of_2(pdata->scan_delay_ms)) {
		dev_err(&pdev->dev, "invalid keypad scan time supplied\n");
		return -EINVAL;
	}

	rc = pm8058_read(PM8058_REV, &rev, 1);
	pr_info("PMIC4 is at %X revision\n", rev);

	if (rev == PMIC8058_REV_A0) {
		if (!pdata->debounce_ms || !is_power_of_2(pdata->debounce_ms)
				|| pdata->debounce_ms > MAX_DEBOUNCE_A0_TIME
				|| pdata->debounce_ms < MIN_DEBOUNCE_A0_TIME) {
			dev_err(&pdev->dev, "invalid debounce time supplied\n");
			return -EINVAL;
		}
	} else {
		if (!pdata->debounce_ms || ((pdata->debounce_ms % 5) != 0)
				|| pdata->debounce_ms > MAX_DEBOUNCE_B0_TIME
				|| pdata->debounce_ms < MIN_DEBOUNCE_B0_TIME) {
			dev_err(&pdev->dev, "invalid debounce time supplied\n");
			return -EINVAL;
		}
	}

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

	keycodes = kzalloc(MATRIX_MAX_SIZE * sizeof(keycodes), GFP_KERNEL);
	if (!keycodes) {
		rc = -ENOMEM;
		goto err_alloc_mem;
	}

	platform_set_drvdata(pdev, kp);

	kp->pdata	= pdata;
	kp->dev		= &pdev->dev;
	kp->keycodes	= keycodes;

	/* REVISIT: actual revision with the fix */
	if (rev <= PMIC8058_REV_B0)
		kp->flags |= KEYF_FIX_LAST_ROW;

	kp->input = input_allocate_device();
	if (!kp->input) {
		dev_err(&pdev->dev, "unable to allocate input device\n");
		rc = -ENOMEM;
		goto err_alloc_device;
	}

	kp->key_sense_irq = platform_get_irq(pdev, 0);
	if (kp->key_sense_irq < 0) {
		dev_err(&pdev->dev, "unable to get keypad sense irq\n");
		rc = -ENXIO;
		goto err_get_irq;
	}

	kp->key_stuck_irq = platform_get_irq(pdev, 1);
	if (kp->key_stuck_irq < 0) {
		dev_err(&pdev->dev, "unable to get keypad stuck irq\n");
		rc = -ENXIO;
		goto err_get_irq;
	}

	if (pdata->input_name)
		kp->input->name = pdata->input_name;
	else
		kp->input->name = "PMIC8058 keypad";

	if (pdata->input_phys_device)
		kp->input->phys = pdata->input_phys_device;
	else
		kp->input->phys = "pmic8058_keypad/input0";

	kp->input->dev.parent	= &pdev->dev;

	kp->input->id.bustype	= BUS_HOST;
	kp->input->id.version	= 0x0001;
	kp->input->id.product	= 0x0001;
	kp->input->id.vendor	= 0x0001;

	kp->input->evbit[0]	= BIT_MASK(EV_KEY);

	if (pdata->rep)
		__set_bit(EV_REP, kp->input->evbit);

	kp->input->keycode	= keycodes;
	kp->input->keycodemax	= MATRIX_MAX_SIZE;
	kp->input->keycodesize	= sizeof(*keycodes);

	/* build keycodes for faster scanning */
	for (i = 0; i < pdata->keymap_size; i++) {
		unsigned int row = KEY_ROW(pdata->keymap[i]);
		unsigned int col = KEY_COL(pdata->keymap[i]);
		unsigned short keycode = KEY_VAL(pdata->keymap[i]);

		keycodes[(row << 3) + col] = keycode;
		__set_bit(keycode, kp->input->keybit);
	}
	__clear_bit(KEY_RESERVED, kp->input->keybit);

	input_set_capability(kp->input, EV_MSC, MSC_SCAN);
	input_set_drvdata(kp->input, kp);

	rc = input_register_device(kp->input);
	if (rc < 0) {
		dev_err(&pdev->dev, "unable to register keypad input device\n");
		goto err_get_irq;
	}

	/* initialize keypad state */
	memset(kp->keystate, 0xff, sizeof(kp->keystate));

	rc = pmic8058_kpd_init(kp);
	if (rc < 0) {
		dev_err(&pdev->dev, "unable to initialize keypad controller\n");
		goto err_kpd_init;
	}

	rc = pm8058_gpio_config_kypd_sns(pdata->cols_gpio_start,
						 pdata->num_cols);
	if (rc < 0) {
		dev_err(&pdev->dev, "unable to configure keypad sense lines\n");
		goto err_gpio_config;
	}

	rc = pm8058_gpio_config_kypd_drv(pdata->rows_gpio_start,
						 pdata->num_rows);
	if (rc < 0) {
		dev_err(&pdev->dev, "unable to configure keypad drive lines\n");
		goto err_gpio_config;
	}

	rc = request_irq(kp->key_sense_irq, pmic8058_kp_irq,
				 IRQF_TRIGGER_RISING, "pmic-keypad", kp);
	if (rc < 0) {
		dev_err(&pdev->dev, "failed to request keypad sense irq\n");
		goto err_req_sense_irq;
	}

	rc = request_irq(kp->key_stuck_irq, pmic8058_kp_stuck_irq,
				 IRQF_TRIGGER_RISING, "pmic-keypad-stuck", kp);
	if (rc < 0) {
		dev_err(&pdev->dev, "failed to request keypad stuck irq\n");
		goto err_req_stuck_irq;
	}

	rc = pmic8058_kp_read(kp, &ctrl_val, KEYP_CTRL, 1);
	ctrl_val |= KEYP_CTRL_KEYP_EN;
	rc = pmic8058_kp_write_u8(kp, ctrl_val, KEYP_CTRL);

	__dump_kp_regs(kp, "probe");

	device_init_wakeup(&pdev->dev, pdata->wakeup);

	return 0;

err_req_stuck_irq:
	free_irq(kp->key_sense_irq, NULL);
err_req_sense_irq:
err_gpio_config:
err_kpd_init:
	input_unregister_device(kp->input);
	kp->input = NULL;
err_get_irq:
	input_free_device(kp->input);
err_alloc_device:
	kfree(keycodes);
err_alloc_mem:
	kfree(kp);
	return rc;
}
コード例 #26
0
ファイル: i2c_bus_s3c2440.c プロジェクト: stormalex/driver
static void i2c_bus_s3c2440_exit(void)
{
	i2c_del_adapter(&s3c2440_i2c_adapter);
	free_irq(IRQ_IIC, NULL);
	iounmap(s3c2440_i2c_regs);
}
コード例 #27
0
ファイル: extcon-max8997.c プロジェクト: DenisLug/mptcp
static int max8997_muic_probe(struct platform_device *pdev)
{
	struct max8997_dev *max8997 = dev_get_drvdata(pdev->dev.parent);
	struct max8997_platform_data *pdata = dev_get_platdata(max8997->dev);
	struct max8997_muic_info *info;
	int delay_jiffies;
	int ret, i;

	info = devm_kzalloc(&pdev->dev, sizeof(struct max8997_muic_info),
			    GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	info->dev = &pdev->dev;
	info->muic = max8997->muic;

	platform_set_drvdata(pdev, info);
	mutex_init(&info->mutex);

	INIT_WORK(&info->irq_work, max8997_muic_irq_work);

	for (i = 0; i < ARRAY_SIZE(muic_irqs); i++) {
		struct max8997_muic_irq *muic_irq = &muic_irqs[i];
		unsigned int virq = 0;

		virq = irq_create_mapping(max8997->irq_domain, muic_irq->irq);
		if (!virq) {
			ret = -EINVAL;
			goto err_irq;
		}
		muic_irq->virq = virq;

		ret = request_threaded_irq(virq, NULL,
				max8997_muic_irq_handler,
				IRQF_NO_SUSPEND,
				muic_irq->name, info);
		if (ret) {
			dev_err(&pdev->dev,
				"failed: irq request (IRQ: %d, error :%d)\n",
				muic_irq->irq, ret);
			goto err_irq;
		}
	}

	/* External connector */
	info->edev = devm_extcon_dev_allocate(&pdev->dev, max8997_extcon_cable);
	if (IS_ERR(info->edev)) {
		dev_err(&pdev->dev, "failed to allocate memory for extcon\n");
		ret = -ENOMEM;
		goto err_irq;
	}

	ret = devm_extcon_dev_register(&pdev->dev, info->edev);
	if (ret) {
		dev_err(&pdev->dev, "failed to register extcon device\n");
		goto err_irq;
	}

	if (pdata && pdata->muic_pdata) {
		struct max8997_muic_platform_data *muic_pdata
			= pdata->muic_pdata;

		/* Initialize registers according to platform data */
		for (i = 0; i < muic_pdata->num_init_data; i++) {
			max8997_write_reg(info->muic,
					muic_pdata->init_data[i].addr,
					muic_pdata->init_data[i].data);
		}

		/*
		 * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB
		 * h/w path of COMP2/COMN1 on CONTROL1 register.
		 */
		if (muic_pdata->path_uart)
			info->path_uart = muic_pdata->path_uart;
		else
			info->path_uart = CONTROL1_SW_UART;

		if (muic_pdata->path_usb)
			info->path_usb = muic_pdata->path_usb;
		else
			info->path_usb = CONTROL1_SW_USB;

		/*
		 * Default delay time for detecting cable state
		 * after certain time.
		 */
		if (muic_pdata->detcable_delay_ms)
			delay_jiffies =
				msecs_to_jiffies(muic_pdata->detcable_delay_ms);
		else
			delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT);
	} else {
		info->path_uart = CONTROL1_SW_UART;
		info->path_usb = CONTROL1_SW_USB;
		delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT);
	}

	/* Set initial path for UART */
	 max8997_muic_set_path(info, info->path_uart, true);

	/* Set ADC debounce time */
	max8997_muic_set_debounce_time(info, ADC_DEBOUNCE_TIME_25MS);

	/*
	 * Detect accessory after completing the initialization of platform
	 *
	 * - Use delayed workqueue to detect cable state and then
	 * notify cable state to notifiee/platform through uevent.
	 * After completing the booting of platform, the extcon provider
	 * driver should notify cable state to upper layer.
	 */
	INIT_DELAYED_WORK(&info->wq_detcable, max8997_muic_detect_cable_wq);
	queue_delayed_work(system_power_efficient_wq, &info->wq_detcable,
			delay_jiffies);

	return 0;

err_irq:
	while (--i >= 0)
		free_irq(muic_irqs[i].virq, info);
	return ret;
}
コード例 #28
0
ファイル: slimport.c プロジェクト: joutcast/ASUS_A80_source
static int anx7808_i2c_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{

	struct anx7808_data *anx7808;
	struct regulator *anx7808_v10;
	int ret = 0;
	int irq=0;
	printk("##########anx7808_i2c_probe###################\n");
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) {
		DEV_ERR("%s: i2c bus does not support the anx7808\n", __func__);
		ret = -ENODEV;
		goto exit;
	}

	anx7808 = kzalloc(sizeof(struct anx7808_data), GFP_KERNEL);
	if (!anx7808) {
		DEV_ERR("%s: failed to allocate driver data\n", __func__);
		ret = -ENOMEM;
		goto exit;
	}
	
	anx7808->pdata = client->dev.platform_data;

	memcpy(&anx7808_client, &client, sizeof(client));

	mutex_init(&anx7808->lock);

	if (!anx7808->pdata) {
		ret = -EINVAL;
		goto err0;
	}

	myDPClass = class_create(THIS_MODULE, "myDP");
	if (IS_ERR(myDPClass)) {
		pr_info("myDP class_create failed %d\n", ret);
	      ret = PTR_ERR(myDPClass);
		goto err0;
	}

      myDPClass->dev_attrs = mydp_driver_attribs;

      g_myDP_pDevice  = device_create(myDPClass, NULL,
    									 MKDEV(g_myDP_devMajor, 0),  NULL,
    									 "%s", MYDP_DEVICE_NAME);
    if (IS_ERR(g_myDP_pDevice)) {
    	 pr_info("myDP class_device_create failed %s %d\n", MYDP_DEVICE_NAME, ret);
        ret = PTR_ERR(g_myDP_pDevice);
	  goto free_class;
    }

	ret = anx7808_init_gpio(anx7808);
	if (ret) {
		DEV_ERR("%s: failed to initialize gpio\n", __func__);
		goto err1;
	}

	anx7808_v10=regulator_get(NULL,"8921_l12");
	 if (IS_ERR(anx7808_v10)) {
		printk("unable to get anx7808_v10\n");
		return PTR_ERR(anx7808_v10);
	}
      ret = regulator_set_voltage(anx7808_v10, 1000000, 1000000);
	if (ret) {
		printk("%s: unable to set the voltage for regulator "
			"anx7808_v10\n", __func__);
		return ret;
	}
	regulator_enable(anx7808_v10);
	
//ASUS BSP wei lai +++
#if 1
	irq = MSM_GPIO_TO_INT(anx7808->pdata->gpio_usb_id);
	if (irq < 0) {
		printk( "%s: could not get USB_ID_DETECT IRQ resource, error=%d ", __func__, irq);		
	}
	ret = request_irq(irq, dp_usb_id_detect_handler,
		IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING , "dp usb id mode", anx7808);

	if (ret < 0) {
		printk( "%s: FACTORY USB IRQ#%d request failed with error=%d ", __func__, irq, ret);				
	}
	disable_irq(irq);
#endif
//ASUS BSP wei lai ---

	INIT_DELAYED_WORK(&anx7808->work, anx7808_work_func);
//ASUS BSP wei lai +++
	INIT_DELAYED_WORK(&anx7808->carKitwork, anx7808_carKitwork_func);
//ASUS BSP wei lai ---
	anx7808->workqueue = create_singlethread_workqueue("anx7808_work");
	if (anx7808->workqueue == NULL) {
		DEV_ERR("%s: failed to create work queue\n", __func__);
		ret = -ENOMEM;
		goto err2;
	}
//ASUS BSP wei lai +++
#ifdef CONFIG_HAS_EARLYSUSPEND
	register_early_suspend( &dp7808_early_suspend_desc );
#endif
//ASUS BSP wei lai ---
	ret = anx7808_system_init();
	if (ret) {
		DEV_ERR("%s: failed to initialize anx7808\n", __func__);
		goto err2;
	}
//ASUS_BSP larry lai :for ATD test +++	
	g_myDP_init_status = 1;
//ASUS_BSP larry lai :for ATD test ---

	client->irq = gpio_to_irq(anx7808->pdata->gpio_cbl_det);
	if (client->irq < 0) {
		DEV_ERR("%s : failed to get gpio irq\n", __func__);
		goto err3;
	}

	ret = request_threaded_irq(client->irq, NULL, anx7808_cbl_det_isr,
					IRQF_TRIGGER_RISING
					| IRQF_TRIGGER_FALLING,
					"anx7808_cabel_det", anx7808);
	if (ret  < 0) {
		DEV_ERR("%s : failed to request irq\n", __func__);
		goto err3;
	}
//wei debug irq
#if 1
//	ret = set_irq_wake(client->irq, 1);
//ASUS Wei_Lai +++
	ret = irq_set_irq_wake(client->irq, 1);
//ASUS Wei_Lai ---
	if (ret  < 0) {
		pr_err("%s : Request irq for cable detect"
			"interrupt wake set fail\n", __func__);
		goto err3;
	}
#endif
//wei debug irq
#if 1
	ret = enable_irq_wake(client->irq);
	if (ret  < 0) {
		DEV_ERR("%s : Enable irq for cable detect", __func__);
		DEV_ERR("interrupt wake enable fail\n");
		goto err3;
	}
#endif	

	//enable_irq(client->irq);
//ASUS BSP wei lai +++
	enable_irq(irq);
	i2c_set_clientdata(anx7808_client,anx7808);

	printk("########## #####anx7808_i2c_probe END###################\n");
	wake_lock_init(&anx7808->slimport_lock, WAKE_LOCK_SUSPEND, "slimport_wake_lock");

	if (gpio_get_value(anx7808->pdata->gpio_cbl_det) && (g_i2c_error_count==0))  {
		msleep(10);
		if(gpio_get_value(anx7808->pdata->gpio_cbl_det)==1){
			wake_lock(&anx7808->slimport_lock);
			DEV_DBG("%s : detect cable insertion\n", __func__);
			queue_delayed_work(anx7808->workqueue, &anx7808->work, 1000);
		}
	}
	if (gpio_get_value_cansleep(anx7808 ->pdata->gpio_usb_id) ==0 ){
		if(gpio_get_value_cansleep(anx7808->pdata->gpio_cbl_det) ==0){
			g_otg_state=true;
		}
	}
	
//ASUS BSP wei lai ---
	goto exit;

err3:
	free_irq(client->irq, anx7808);
err2:
	destroy_workqueue(anx7808->workqueue);
err1:
	anx7808_free_gpio(anx7808);
free_class:
	class_destroy(myDPClass);	
err0:
	kfree(anx7808);
exit:
	return ret;
}
コード例 #29
0
static int pn547_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct pn547_dev *dev;
	struct pn547_i2c_platform_data *pdata;
	struct pinctrl *pinctrl;
	struct clk *nfc_clk = NULL;
	int ret = 0;

	pdata = kzalloc(sizeof(struct pn547_i2c_platform_data),
			GFP_KERNEL);
	if (!pdata) {
		dev_err(&client->dev, "failed to get allocate memory\n");
		ret = -ENOMEM;
		goto probe_pdata;
	}

	pinctrl = devm_pinctrl_get(&client->dev);
	if (IS_ERR(pinctrl)) {
		dev_err(&client->dev, "devm_pinctrl_get error\n");
		goto probe_pinctrl;
	}

	ret = pn547_parse_dt(&client->dev, pdata);
	if (ret < 0) {
		dev_err(&client->dev, "failed to parse device tree: %d\n", ret);
		goto probe_parse_dt;
	}

	ret = pn547_gpio_request(&client->dev, pdata);
	if (ret) {
		dev_err(&client->dev, "failed to request gpio\n");
		goto probe_gpio_request;
	}
	dev_dbg(&client->dev, "%s:\n", __func__);

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		dev_err(&client->dev, "%s: i2c check failed\n", __func__);
		ret = -ENODEV;
		goto probe_i2c;
	}

	dev = kzalloc(sizeof(struct pn547_dev), GFP_KERNEL);
	if (!dev) {
		dev_err(&client->dev, "%s: no memory\n", __func__);
		ret = -ENOMEM;
		goto probe_mem;
	}
	dev->i2c_client = client;
	dev->dev = &client->dev;
	dev->pdata = pdata;
	dev->pinctrl = pinctrl;
	init_waitqueue_head(&dev->wq);
	wake_lock_init(&dev->wake_lock, WAKE_LOCK_SUSPEND, "pn547");
	i2c_set_clientdata(client, dev);
	dev->state = PN547_STATE_UNKNOWN;

	ret = request_threaded_irq(client->irq, NULL, pn547_dev_irq_handler,
			IRQF_TRIGGER_RISING | IRQF_ONESHOT, client->name, dev);
	if (IS_ERR_VALUE(ret)) {
		dev_err(&client->dev, "%s: irq request err %d\n",
			__func__, ret);
		goto probe_irq;
	}

	nfc_clk = clk_get(&client->dev, "nfc_clk");
	if (IS_ERR(nfc_clk)) {
		dev_err(&client->dev, "Couldn't get nfc_clk\n");
		goto probe_clk;
	}
	ret = clk_prepare_enable(nfc_clk);
	if (ret) {
		dev_err(&client->dev, "nfc_clk enable is failed\n");
		goto probe_clk_enable;
	}

	ret = pn547_dev_create_sysfs_entries(dev->i2c_client);
	if (IS_ERR_VALUE(ret)) {
		dev_err(&client->dev, "%s: create sysfs entries err %d\n",
			__func__, ret);
		goto probe_sysfs;
	}
	return ret;

probe_sysfs:
	free_irq(client->irq, dev);
probe_clk_enable:
	clk_put(nfc_clk);
probe_clk:
probe_irq:
	i2c_set_clientdata(client, NULL);
	wake_lock_destroy(&dev->wake_lock);
	kzfree(dev);
probe_mem:
probe_i2c:
	pn547_gpio_release(pdata);
probe_gpio_request:
probe_parse_dt:
	devm_pinctrl_put(pinctrl);
probe_pinctrl:
	kzfree(pdata);
probe_pdata:
	dev_err(&client->dev, "%s: err %d\n", __func__, ret);
	return ret;
}
コード例 #30
0
static void __exit riva_ssr_module_exit(void)
{
	free_irq(RIVA_APSS_WDOG_BITE_RESET_RDY_IRQ, NULL);
}