Beispiel #1
0
/* ------------------------------------------------------------------------------------
 *		irdaeg file operation
 * ------------------------------------------------------------------------------------ */
static int irdaeg_fop_open(struct inode *inode, struct file *file)
{
	int rc;


	printk( "%s:%d\n", __func__, __LINE__ );
	printk( "%s: major %d minor %d (pid %d)\n", __func__, imajor(inode), iminor(inode), current->pid);

	file->private_data = irdaeg_info ;

/* Set IrDA mode at the MUX register at IrDA/Felica of PM8058 */
	pm8058_misc_control(NULL, PM8058_UART_MUX_MASK, PM8058_UART_MUX_3);

/* Set pm port */
	rc = irda_eg_set_pm_port();
	if(rc != 0){
		printk( "Error set pm port\n" );
		return rc;
	}

	printk( "%s:%d\n", __func__, __LINE__ );
	return 0;
}
Beispiel #2
0
static int msm_uart_aux_chg_irda( void )
{
	int rc = 0;

	// TX
	uart_tx2_en_22.function = PM_GPIO_FUNC_2;
/* FUJITSU:2011-10-21 gpio chg start  */
#if defined(CONFIG_MACH_F11APO) || defined(CONFIG_MACH_F12APON)
	if((system_rev != 0x08) || (system_rev != 0x0F))
	{
		uart_tx2_en_22.out_strength = PM_GPIO_STRENGTH_MED;
	}
#elif defined(CONFIG_MACH_FJI12)
	if((system_rev != 0x00) || (system_rev != 0x07))
	{
		uart_tx2_en_22.out_strength = PM_GPIO_STRENGTH_MED;
	}
#endif
/* FUJITSU:2011-10-21 gpio chg end  */
/* FUJITSU:2011-12-01 mod irda start  */
#if 0
	rc = pm8058_gpio_config( PM8058_UART_TX2_22, &uart_tx2_en_22 );
#else
	rc = pm8xxx_gpio_config( PM8058_UART_TX2_22, &uart_tx2_en_22 );
#endif
/* FUJITSU:2011-12-01 mod irda end  */
	if ( rc )
	{
		printk( KERN_ERR "%s: PM8058_UART_TX config failed\n", __func__ );
		return -EIO;
	}
	// RX
/* FUJITSU:2011-09-28 gpio chg start  */
#if defined(CONFIG_MACH_F11APO) || defined(CONFIG_MACH_F12APON)
	if((system_rev != 0x08) || (system_rev != 0x0F))
	{
		uart_rx2_en_34.pull = PM_GPIO_PULL_UP_1P5;
	}
#elif defined(CONFIG_MACH_FJI12)
	if((system_rev != 0x00) || (system_rev != 0x07))
	{
		uart_rx2_en_34.pull = PM_GPIO_PULL_UP_1P5;
	}
#endif
/* FUJITSU:2011-09-28 gpio chg end  */
/* FUJITSU:2011-12-01 mod irda start  */
#if 0
	rc = pm8058_gpio_config( PM8058_UART_RX2_34, &uart_rx2_en_34 );
#else
	rc = pm8xxx_gpio_config( PM8058_UART_RX2_34, &uart_rx2_en_34 );
#endif
/* FUJITSU:2011-12-01 mod irda end  */
	if ( rc )
	{
		printk( KERN_ERR "%s: PM8058_UART_RX config failed\n", __func__ );
		return -EIO;
	}
	// PMIC
/* FUJITSU:2011-12-01 mod irda start */
#if 0
	rc = pm8058_misc_control( NULL, PM8058_UART_MUX_MASK, PM8058_UART_MUX_2 );
#else
	rc = pm8xxx_uart_gpio_mux_ctrl(UART_TX2_RX2);
#endif
/* FUJITSU:2011-12-01 mod irda end  */
	if ( rc )
	{
/* FUJITSU:2011-12-01 mod irda start */
#if 0
		printk( KERN_ERR "%s:pmM8058_misc_control failed=%d\n", __func__, rc );
#else
		printk( KERN_ERR "%s:pm8xxx_uart_gpio_mux_ctrl failed=%d\n", __func__, rc );
#endif
/* FUJITSU:2011-12-01 mod irda end  */
	}
	printk( KERN_INFO DEV_NAME " %s: UART Change -> IRDA\n", __func__ );
	// TXD
/* FUJITSU:2011-09-28 gpio chg start  */
#if defined(CONFIG_MACH_F11APO) || defined(CONFIG_MACH_F12APON)
	if((system_rev != 0x08) || (system_rev != 0x0F))
	{
		uart_pmic_txd_en_36.pull = PM_GPIO_PULL_UP_1P5;
	}
#elif(defined CONFIG_MACH_FJI12)
	if((system_rev != 0x00) || (system_rev != 0x07))
	{
		uart_pmic_txd_en_36.pull = PM_GPIO_PULL_UP_1P5;
	}
#endif
/* FUJITSU:2011-09-28 gpio chg end  */
/* FUJITSU:2011-12-01 mod irda start  */
#if 0
	rc = pm8058_gpio_config( PM8058_UART_PMIC_TXD_36, &uart_pmic_txd_en_36 );
#else
	rc = pm8xxx_gpio_config( PM8058_UART_PMIC_TXD_36, &uart_pmic_txd_en_36 );
#endif
/* FUJITSU:2011-12-01 mod irda end  */
	if ( rc )
	{
		printk( KERN_ERR "%s: PM8058_UART_PMIC_TXD config failed\n", __func__ );
		return -EIO;
	}
	// RXD
/* FUJITSU:2011-09-28 gpio chg start  */
#if defined(CONFIG_MACH_F11APO) || defined(CONFIG_MACH_F12APON)
	if((system_rev != 0x08) || (system_rev != 0x0F))
	{
		uart_pmic_rxd_en_37.out_strength = PM_GPIO_STRENGTH_MED;
		uart_pmic_rxd_en_37.pull = PM_GPIO_PULL_UP_1P5;
	}
#elif defined(CONFIG_MACH_FJI12)
	if((system_rev != 0x00) || (system_rev != 0x07))
	{
		uart_pmic_rxd_en_37.out_strength = PM_GPIO_STRENGTH_MED;
		uart_pmic_rxd_en_37.pull = PM_GPIO_PULL_UP_1P5;
	}
#endif
/* FUJITSU:2011-09-28 gpio chg end  */
/* FUJITSU:2011-12-01 mod irda start  */
#if 0
	rc = pm8058_gpio_config( PM8058_UART_PMIC_RXD_37, &uart_pmic_rxd_en_37 );
#else
	rc = pm8xxx_gpio_config( PM8058_UART_PMIC_RXD_37, &uart_pmic_rxd_en_37 );
#endif
/* FUJITSU:2011-12-01 mod irda end  */
	if ( rc )
	{
		printk( KERN_ERR "%s: PM8058_UART_PMIC_RXD config failed\n", __func__ );
		return -EIO;
	}

	// MSM
	rc = gpio_tlmm_config( GPIO_CFG( 51, 1, GPIO_CFG_INPUT,  GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE );
	if ( rc )
	{
		printk( KERN_ERR "%s: MSM8655_UART_RXD_A config failed\n", __func__ );
		return -EIO;
	}
/* FUJITSU:2011-09-28 gpio chg start  */
#if defined(CONFIG_MACH_F11APO) || defined(CONFIG_MACH_F12APON)
	if((system_rev != 0x08) || (system_rev != 0x0F))
	{
		rc = gpio_tlmm_config( GPIO_CFG( 52, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA), GPIO_CFG_ENABLE );
	}else{
		rc = gpio_tlmm_config( GPIO_CFG( 52, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE );
	}
#elif defined(CONFIG_MACH_FJI12)
	if((system_rev != 0x00) || (system_rev != 0x07))
	{
		rc = gpio_tlmm_config( GPIO_CFG( 52, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA), GPIO_CFG_ENABLE );
	}else{
		rc = gpio_tlmm_config( GPIO_CFG( 52, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE );
	}
#else
	rc = gpio_tlmm_config( GPIO_CFG( 52, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE );
#endif
/* FUJITSU:2011-09-28 gpio chg end  */
	if ( rc )
	{
		printk( KERN_ERR "%s: MSM8655_UART_TXD_A config failed\n", __func__ );
		return -EIO;
	}

	// SD
/* FUJITSU:2011-09-28 gpio chg start  */
#if defined(CONFIG_MACH_F11APO) || defined(CONFIG_MACH_F12APON)
	if((system_rev != 0x08) || (system_rev != 0x0F))
	{
		irda_pwdown_26.output_buffer = PM_GPIO_OUT_BUF_OPEN_DRAIN;
		irda_pwdown_26.out_strength = PM_GPIO_STRENGTH_NO;
	}
#elif defined(CONFIG_MACH_FJI12)
	if((system_rev != 0x00) || (system_rev != 0x07))
	{
		irda_pwdown_26.output_buffer = PM_GPIO_OUT_BUF_OPEN_DRAIN;
		irda_pwdown_26.out_strength = PM_GPIO_STRENGTH_NO;
	}
#endif
/* FUJITSU:2011-09-28 gpio chg end  */
/* FUJITSU:2011-12-01 mod irda start  */
#if 0
	rc = pm8058_gpio_config( PM8058_IRDA_PWD_26, &irda_pwdown_26 );
#else
	rc = pm8xxx_gpio_config( PM8058_IRDA_PWD_26, &irda_pwdown_26 );
#endif
/* FUJITSU:2011-12-01 mod irda end  */
	if( rc < 0 )
	{
		printk( KERN_ERR "%s: PM8058_IRDA_PWD_26 config failed[%d]\n", __func__, rc );
		return -EIO;
	}
	printk( KERN_INFO DEV_NAME " %s: IRDA GPIO Config Complete\n", __func__ );

	return 0;
}
static int irda_uart_release(struct inode *inode, struct file *file)
{
	down(&irc->sem);
	printk(KERN_INFO DRV_NAME ": %s\n", __func__);

	/* Decrement refcount */
	irc->refcount--;

	/* Check refcount */
	if (irc->refcount == 0) {
		/* do discard flush */
		if (irc->rx_state == IRDA_RX_START) {
			irc->rx_state = IRDA_RX_IDLE;
			msm_dmov_stop_cmd(irc->pfdata->chan_uartdm_rx,
						&irc->rxdmov_cmd, 0);
		}

		/* Deactivate RXLEV IRQ */
		irc->imr_reg &= ~BIT_RXLEV;
		msm_uartdm_write(UARTDM_IMR, irc->imr_reg);
		/* (state change)--> IRDA_UART_OPEN */
		irc->state = IRDA_UART_CLOSE;
		/* Disable the IRDA transceiver */
		msm_uartdm_write(UARTDM_IRDA, IRUART_IRDA_DISABLE);
		/* Disable Transmitter and Receiver */
		msm_uartdm_write(UARTDM_CR, BIT_UART_TX_DISABLE);
		msm_uartdm_write(UARTDM_CR, BIT_UART_RX_DISABLE);

		/* Desable TXDM and RXDM mode */
		msm_uartdm_write(UARTDM_DMEN, IRUART_IRDA_DISABLE);

		/* Wait 1usec */
		udelay(1);
		/* Setting PM power off (Hig) */
		pm8058_gpio_config(irc->pfdata->gpio_pow,
				   irc->pfdata->gpio_pwcfg_hig);

		/* Clear UART SW buffer */
		irda_txbuf_clear(&irc->txbuf);
		irda_rxbuf_clear(&irc->rxbuf);
		/* Reset TX and RX*/
		msm_uartdm_write(UARTDM_CR, CCMD_RESET_RECEIVER);
		msm_uartdm_write(UARTDM_CR, CCMD_RESET_TRANSMITTER);
		msm_uartdm_write(UARTDM_CR, CCMD_RESET_ERROR_STATUS);
		msm_uartdm_write(UARTDM_CR, CCMD_RESET_STALE_INTERRUPT);
		/* Release DMOV data */
		dma_free_coherent(NULL, sizeof(dmov_box),
					irc->txbox, irc->mapped_txbox);
		dma_free_coherent(NULL, sizeof(dmov_box),
					irc->rxbox, irc->mapped_rxbox);
		dma_free_coherent(NULL, sizeof(u32 *),
					irc->txbox_ptr, irc->mapped_txbox_ptr);
		dma_free_coherent(NULL, sizeof(u32 *),
					irc->rxbox_ptr, irc->mapped_rxbox_ptr);
		/* UARTDM clock stop */
		clk_disable(irc->clk_uartdm);
		/* UARTDM iounmap */
		if (irc->iores_uartdm)
			release_mem_region((u32) irc->pfdata->paddr_uartdm,
						UARTDM_SIZE);
		iounmap(irc->vaddr_uartdm);
		/* Remove IRQ for UARTDM */
		free_irq(irc->pfdata->irq_uartdm, irc);
		/* Remove tasklets for UARTDM */
		tasklet_kill(&irc->tasklet_rxfer_s);
		tasklet_kill(&irc->tasklet_rxfer_e);
		tasklet_kill(&irc->tasklet_txfer);
		/* PM8058 UART MUX reset */
		pm8058_misc_control(irc->nfcdev->pm_chip,
				PM8058_UART_MUX_MASK, PM8058_UART_MUX_NO);
		{
			u8 misc = 0x0;
			int ret = pm8058_read(irc->nfcdev->pm_chip,
						SSBI_REG_ADDR_MISC, &misc, 1);
			if (ret)
				printk(KERN_ERR DRV_NAME
					": cannot read pm8058 UART MUX reg.\n");
			else
				printk(KERN_INFO DRV_NAME
					": misc register = %x\n", misc);
		}
	}
	printk(KERN_INFO DRV_NAME ": Closed. Refcount = %d\n", irc->refcount);
	up(&irc->sem);

	return 0;
}
static int irda_uart_open(struct inode *inode, struct file *file)
{
	int ret;
	u8 misc = 0x0;

	down(&irc->sem);
	printk(KERN_INFO DRV_NAME ": %s\n", __func__);

	/* Check refcount */
	if (irc->refcount > 0) {
		irc->refcount++;
		printk(KERN_INFO DRV_NAME
			": refirence counter count up(%d).\n", irc->refcount);
		up(&irc->sem);
		return 0;
	}
	/* PM8058-NFC Request */
	irc->nfcdev = pm8058_nfc_request();
	if (irc->nfcdev == NULL) {
		printk(KERN_ERR DRV_NAME ": pm8058 nfc not found.\n");
		ret = -ENODEV;
		goto error_pm_nfc_request;
	}

	/* PM8058 UART MUX setting */
	ret = pm8058_read(irc->nfcdev->pm_chip, SSBI_REG_ADDR_MISC, &misc, 1);
	if (ret)
		printk(KERN_ERR DRV_NAME
			": cannot read pm8058 UART MUX reg.\n");
	else
		printk(KERN_INFO DRV_NAME ": misc register = %x\n", misc);
	misc &= PM8058_UART_MUX_MASK;
	switch (misc) {
	case PM8058_UART_MUX_NO:
		pm8058_misc_control(irc->nfcdev->pm_chip,
				PM8058_UART_MUX_MASK, PM8058_UART_MUX_3);
		printk(KERN_INFO DRV_NAME
			": OK. UART MUX = neutral --> IrDA.\n");
		break;
	case PM8058_UART_MUX_1:
		printk(KERN_ERR DRV_NAME ": Now, uart_mux = 1 (FeliCa)\n");
		ret = -EBUSY;
		goto err_set_uart_mux;
	case PM8058_UART_MUX_2:
		printk(KERN_ERR DRV_NAME ": Now, uart_mux = 2 (unknown)\n");
		ret = -EBUSY;
		goto err_set_uart_mux;
	default:
		printk(KERN_ERR DRV_NAME ": UART MUX unavaible.\n");
		ret = -EIO;
		goto err_set_uart_mux;
	}

	/* init IMR value */
	irc->imr_reg = 0x0;

	/* init wait queue */
	init_waitqueue_head(&irc->wait_tx);
	init_waitqueue_head(&irc->wait_rx);

	/* init tasklet */
	tasklet_init(&irc->tasklet_rxfer_s, irda_uart_rxfer_start, 0);
	tasklet_init(&irc->tasklet_rxfer_e, irda_uart_rxfer_end,   0);
	tasklet_init(&irc->tasklet_txfer,   irda_uart_txfer_exec,  0);

	/* Register UARTDM IRQ */
	ret = request_irq(irc->pfdata->irq_uartdm, irda_uart_irq_handler,
				IRQF_TRIGGER_HIGH,  "irda_uart", irc);
	if (ret) {
		printk(KERN_ERR DRV_NAME ": request IRQ failed. (UARTDM)\n");
		goto err_request_irq_uart;
	}

	/* UARTDM ioremap */
	/* memory protection */
	irc->iores_uartdm = request_mem_region((u32) irc->pfdata->paddr_uartdm,
						UARTDM_SIZE, "irda_uart");
	if (!irc->iores_uartdm) {
		printk(KERN_ERR DRV_NAME
			": UARTDM request_mem_region failed.\n");
		ret = -EBUSY;
		goto err_request_mem_region;
	}
	irc->vaddr_uartdm = ioremap_nocache((u32) irc->pfdata->paddr_uartdm,
						UARTDM_SIZE);
	if (!irc->vaddr_uartdm) {
		printk(KERN_ERR DRV_NAME ": UARTDM ioremap failed.\n");
		ret = -ENOMEM;
		goto err_ioremap_uartdm;
	}

	/* UARTDM clock set and start */
	/* default 9600 bps */
	irc->bps = 9600;
	clk_set_rate(irc->clk_uartdm, IRUART_UARTDM_CLK(9600));
	clk_enable(irc->clk_uartdm);
	msm_uartdm_write(UARTDM_CSR, IRUART_DEF_BAUDRATE_CSR);

	/* UARTDM register setting */
	/* Data-stop-parity setting (MR2) */
	msm_uartdm_write(UARTDM_MR2, IRUART_DATA_STOP_PARITY);

	/* RX&TX wartermark setting */
	msm_uartdm_write(UARTDM_TFWR, 0x0);
	msm_uartdm_write(UARTDM_RFWR, 0x0);

	/* Stale time-out setting */
	msm_uartdm_write(UARTDM_IPR,
			(IRUART_DEF_RXSTALE & BIT_STALE_TIMEOUT_LSB)
			| ((IRUART_DEF_RXSTALE << 2) & BIT_STALE_TIMEOUT_MSB));

	/* Enable TXDM and RXDM mode */
	msm_uartdm_write(UARTDM_DMEN, BIT_RX_DM_EN|BIT_TX_DM_EN);

	/* Enable the IRDA transceiver */
	msm_uartdm_write(UARTDM_IRDA, IRUART_IRDA_EN);

	/* TX DMOV mapping */
	irc->txbox = dma_alloc_coherent(NULL, sizeof(dmov_box),
					&irc->mapped_txbox, GFP_KERNEL);
	if (!irc->txbox) {
		printk(KERN_ERR DRV_NAME ": no enough mem for TX DMOV(1).\n");
		ret = -ENOMEM;
		goto err_alloc_txbox;
	}
	irc->txbox_ptr = dma_alloc_coherent(NULL, sizeof(u32 *),
					&irc->mapped_txbox_ptr, GFP_KERNEL);
	if (!irc->txbox_ptr) {
		printk(KERN_ERR DRV_NAME ": no enough mem for TX DMOV(2).\n");
		ret = -ENOMEM;
		goto err_alloc_txbox_ptr;
	}
	*irc->txbox_ptr = CMD_PTR_LP | DMOV_CMD_ADDR(irc->mapped_txbox);
	irc->txdmov_cmd.cmdptr = DMOV_CMD_ADDR(irc->mapped_txbox_ptr);
	irc->txdmov_cmd.complete_func = irda_txdmov_callback;
	irc->txdmov_cmd.cmdptr = DMOV_CMD_ADDR(irc->mapped_txbox_ptr);
	irc->txbox->cmd =
		CMD_LC
		| CMD_DST_CRCI(irc->pfdata->crci_uartdm_tx) | CMD_MODE_BOX;
	/* TX DMOV BOX command */
	irc->txbox->src_row_addr = 0x0;
	irc->txbox->dst_row_addr = (u32)irc->pfdata->paddr_uartdm + UARTDM_TF;
	irc->txbox->src_dst_len = (UARTDM_BURST_SIZE<<16)|UARTDM_BURST_SIZE;
	irc->txbox->num_rows = 0x0;
	irc->txbox->row_offset = (UARTDM_BURST_SIZE<<16);

	/* RX DMOV mapping */
	irc->rxbox = dma_alloc_coherent(NULL, sizeof(dmov_box),
					&irc->mapped_rxbox, GFP_KERNEL);
	if (!irc->rxbox) {
		printk(KERN_ERR DRV_NAME ": no enough mem for RX DMOV(1).\n");
		ret = -ENOMEM;
		goto err_alloc_rxbox;
	}
	irc->rxbox_ptr = dma_alloc_coherent(NULL, sizeof(u32 *),
					&irc->mapped_rxbox_ptr, GFP_KERNEL);
	if (!irc->rxbox_ptr) {
		printk(KERN_ERR DRV_NAME ": no enough mem for RX DMOV(2).\n");
		ret = -ENOMEM;
		goto err_alloc_rxbox_ptr;
	}
	*irc->rxbox_ptr = CMD_PTR_LP | DMOV_CMD_ADDR(irc->mapped_rxbox);
	irc->rxdmov_cmd.cmdptr = DMOV_CMD_ADDR(irc->mapped_rxbox_ptr);
	irc->rxdmov_cmd.complete_func = irda_rxdmov_callback;
	irc->rxdmov_cmd.cmdptr = DMOV_CMD_ADDR(irc->mapped_rxbox_ptr);
	irc->rxbox->cmd =
		CMD_LC
		| CMD_SRC_CRCI(irc->pfdata->crci_uartdm_rx)
		| CMD_MODE_BOX;
	/* RX DMOV BOX command */
	irc->rxbox->src_row_addr =
		(u32)irc->pfdata->paddr_uartdm + UARTDM_RF;
	irc->rxbox->dst_row_addr = 0x0;
	irc->rxbox->src_dst_len = (UARTDM_BURST_SIZE<<16)|UARTDM_BURST_SIZE;
	irc->rxbox->num_rows =
		(IRUART_SW_RXBUF_SIZE >> 4 << 16) | IRUART_SW_RXBUF_SIZE >> 4;
	irc->rxbox->row_offset = UARTDM_BURST_SIZE;

	/* Enable Command Register Protection */
	msm_uartdm_write(UARTDM_CR, GCMD_CR_PROTECTION_ENABLE);

	/* Reset TX and RX */
	msm_uartdm_write(UARTDM_CR, CCMD_RESET_RECEIVER);
	msm_uartdm_write(UARTDM_CR, CCMD_RESET_TRANSMITTER);
	msm_uartdm_write(UARTDM_CR, CCMD_RESET_ERROR_STATUS);
	msm_uartdm_write(UARTDM_CR, CCMD_RESET_STALE_INTERRUPT);

	/* Setting PM power on (Low) */
	ret = pm8058_gpio_config(irc->pfdata->gpio_pow,
				 irc->pfdata->gpio_pwcfg_low);
	if (ret) {
		printk(KERN_ERR DRV_NAME ": pmic gpio write failed\n");
		goto err_gpio_config;
	}
	/* Wait 200usec */
	udelay(200);

	/* Enable Transmitter and Receiver */
	msm_uartdm_write(UARTDM_CR, BIT_UART_TX_EN);
	msm_uartdm_write(UARTDM_CR, BIT_UART_RX_EN);

	/* Clear UART SW buffer */
	irda_txbuf_clear(&irc->txbuf);
	irda_rxbuf_clear(&irc->rxbuf);

	/* init Overflow flag */
	irc->rx_overflow = IRDA_NORMAL;

	/* Increment refcount */
	irc->refcount++;

	/* (state change)--> IRDA_UART_OPEN */
	irc->state = IRDA_UART_OPEN;
	irc->rx_state = IRDA_RX_IDLE;

	printk(KERN_INFO DRV_NAME
		": succecssfly opened, refcount = %d\n", irc->refcount);

	/* Activate RXLEV IRQ */
	irc->imr_reg |= BIT_RXLEV;
	msm_uartdm_write(UARTDM_IMR, irc->imr_reg);

	up(&irc->sem);
	return 0;

/* Error handling */
err_gpio_config:
	dma_free_coherent(NULL,
			sizeof(u32 *), irc->rxbox_ptr, irc->mapped_txbox_ptr);
err_alloc_rxbox_ptr:
	dma_free_coherent(NULL,
			sizeof(dmov_box), irc->rxbox, irc->mapped_rxbox);
err_alloc_rxbox:
	dma_free_coherent(NULL,
			sizeof(u32 *), irc->txbox_ptr, irc->mapped_txbox_ptr);
err_alloc_txbox_ptr:
	dma_free_coherent(NULL,
			sizeof(dmov_box), irc->txbox, irc->mapped_txbox);
err_alloc_txbox:
	msm_uartdm_write(UARTDM_IRDA, IRUART_IRDA_DISABLE);
	clk_disable(irc->clk_uartdm);
	iounmap(irc->vaddr_uartdm);
err_ioremap_uartdm:
	release_mem_region((u32) irc->pfdata->paddr_uartdm, UARTDM_SIZE);
err_request_mem_region:
	free_irq(irc->pfdata->irq_uartdm, irc);
err_request_irq_uart:
	tasklet_kill(&irc->tasklet_rxfer_s);
	tasklet_kill(&irc->tasklet_rxfer_e);
	tasklet_kill(&irc->tasklet_txfer);
	pm8058_misc_control(irc->nfcdev->pm_chip,
				PM8058_UART_MUX_MASK, PM8058_UART_MUX_NO);
err_set_uart_mux:
error_pm_nfc_request:
	up(&irc->sem);
	return ret;
}