/* Freescale QUICC Engine HDLC Device Driver
 *
 * Copyright 2016 Freescale Semiconductor Inc.
 *
 * This program is free software; you can redistribute  it and/or modify it
 * under  the terms of  the GNU General  Public License as published by the
 * Free Software Foundation;  either version 2 of the  License, or (at your
 * option) any later version.
 */

#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/hdlc.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/stddef.h>
#include <soc/fsl/qe/qe_tdm.h>
#include <uapi/linux/if_arp.h>

#include "fsl_ucc_hdlc.h"

#define DRV_DESC "Freescale QE UCC HDLC Driver"
#define DRV_NAME "ucc_hdlc"

#define TDM_PPPOHT_SLIC_MAXIN

static struct ucc_tdm_info utdm_primary_info = {
	.uf_info = {
		.tsa = 0,
		.cdp = 0,
		.cds = 1,
		.ctsp = 1,
		.ctss = 1,
		.revd = 0,
		.urfs = 256,
		.utfs = 256,
		.urfet = 128,
		.urfset = 192,
		.utfet = 128,
		.utftt = 0x40,
		.ufpt = 256,
		.mode = UCC_FAST_PROTOCOL_MODE_HDLC,
		.ttx_trx = UCC_FAST_GUMR_TRANSPARENT_TTX_TRX_NORMAL,
		.tenc = UCC_FAST_TX_ENCODING_NRZ,
		.renc = UCC_FAST_RX_ENCODING_NRZ,
		.tcrc = UCC_FAST_16_BIT_CRC,
		.synl = UCC_FAST_SYNC_LEN_NOT_USED,
	},

	.si_info = {
#ifdef TDM_PPPOHT_SLIC_MAXIN
		.simr_rfsd = 1,
		.simr_tfsd = 2,
#else
		.simr_rfsd = 0,
		.simr_tfsd = 0,
#endif
		.simr_crt = 0,
		.simr_sl = 0,
		.simr_ce = 1,
		.simr_fe = 1,
		.simr_gm = 0,
	},
};

static struct ucc_tdm_info utdm_info[UCC_MAX_NUM];

static int uhdlc_init(struct ucc_hdlc_private *priv)
{
	struct ucc_tdm_info *ut_info;
	struct ucc_fast_info *uf_info;
	u32 cecr_subblock;
	u16 bd_status;
	int ret, i;
	void *bd_buffer;
	dma_addr_t bd_dma_addr;
	u32 riptr;
	u32 tiptr;
	u32 gumr;

	ut_info = priv->ut_info;
	uf_info = &ut_info->uf_info;

	if (priv->tsa) {
		uf_info->tsa = 1;
		uf_info->ctsp = 1;
	}

	/* This sets HPM register in CMXUCR register which configures a
	 * open drain connected HDLC bus
	 */
	if (priv->hdlc_bus)
		uf_info->brkpt_support = 1;

	uf_info->uccm_mask = ((UCC_HDLC_UCCE_RXB | UCC_HDLC_UCCE_RXF |
				UCC_HDLC_UCCE_TXB) << 16);

	ret = ucc_fast_init(uf_info, &priv->uccf);
	if (ret) {
		dev_err(priv->dev, "Failed to init uccf.");
		return ret;
	}

	priv->uf_regs = priv->uccf->uf_regs;
	ucc_fast_disable(priv->uccf, COMM_DIR_RX | COMM_DIR_TX);

	/* Loopback mode */
	if (priv->loopback) {
		dev_info(priv->dev, "Loopback Mode\n");
		/* use the same clock when work in loopback */
		qe_setbrg(ut_info->uf_info.rx_clock, 20000000, 1);

		gumr = ioread32be(&priv->uf_regs->gumr);
		gumr |= (UCC_FAST_GUMR_LOOPBACK | UCC_FAST_GUMR_CDS |
			 UCC_FAST_GUMR_TCI);
		gumr &= ~(UCC_FAST_GUMR_CTSP | UCC_FAST_GUMR_RSYN);
		iowrite32be(gumr, &priv->uf_regs->gumr);
	}

	/* Initialize SI */
	if (priv->tsa)
		ucc_tdm_init(priv->utdm, priv->ut_info);

	/* Write to QE CECR, UCCx channel to Stop Transmission */
	cecr_subblock = ucc_fast_get_qe_cr_subblock(uf_info->ucc_num);
	ret = qe_issue_cmd(QE_STOP_TX, cecr_subblock,
			   QE_CR_PROTOCOL_UNSPECIFIED, 0);

	/* Set UPSMR normal mode (need fixed)*/
	iowrite32be(0, &priv->uf_regs->upsmr);

	/* hdlc_bus mode */
	if (priv->hdlc_bus) {
		u32 upsmr;

		dev_info(priv->dev, "HDLC bus Mode\n");
		upsmr = ioread32be(&priv->uf_regs->upsmr);

		/* bus mode and retransmit enable, with collision window
		 * set to 8 bytes
		 */
		upsmr |= UCC_HDLC_UPSMR_RTE | UCC_HDLC_UPSMR_BUS |
				UCC_HDLC_UPSMR_CW8;
		iowrite32be(upsmr, &priv->uf_regs->upsmr);

		/* explicitly disable CDS & CTSP */
		gumr = ioread32be(&priv->uf_regs->gumr);
		gumr &= ~(UCC_FAST_GUMR_CDS | UCC_FAST_GUMR_CTSP);
		/* set automatic sync to explicitly ignore CD signal */
		gumr |= UCC_FAST_GUMR_SYNL_AUTO;
		iowrite32be(gumr, &priv->uf_regs->gumr);
	}

	priv->rx_ring_size = RX_BD_RING_LEN;
	priv->tx_ring_size = TX_BD_RING_LEN;
	/* Alloc Rx BD */
	priv->rx_bd_base = dma_alloc_coherent(priv->dev,
			RX_BD_RING_LEN * sizeof(struct qe_bd),
			&priv->dma_rx_bd, GFP_KERNEL);

	if (!priv->rx_bd_base) {
		dev_err(priv->dev, "Cannot allocate MURAM memory for RxBDs\n");
		ret = -ENOMEM;
		goto free_uccf;
	}

	/* Alloc Tx BD */
	priv->tx_bd_base = dma_alloc_coherent(priv->dev,
			TX_BD_RING_LEN * sizeof(struct qe_bd),
			&priv->dma_tx_bd, GFP_KERNEL);

	if (!priv->tx_bd_base) {
		dev_err(priv->dev, "Cannot allocate MURAM memory for TxBDs\n");
		ret = -ENOMEM;
		goto free_rx_bd;
	}

	/* Alloc parameter ram for ucc hdlc */
	priv->ucc_pram_offset = qe_muram_alloc(sizeof(struct ucc_hdlc_param),
				ALIGNMENT_OF_UCC_HDLC_PRAM);

	if (IS_ERR_VALUE(priv->ucc_pram_offset)) {
		dev_err(priv->dev, "Can not allocate MURAM for hdlc parameter.\n");
		ret = -ENOMEM;
		goto free_tx_bd;
	}

	priv->rx_skbuff = kcalloc(priv->rx_ring_size,
				  sizeof(*priv->rx_skbuff),
				  GFP_KERNEL);
	if (!priv->rx_skbuff)
		goto free_ucc_pram;

	priv->tx_skbuff = kcalloc(priv->tx_ring_size,
				  sizeof(*priv->tx_skbuff),
				  GFP_KERNEL);
	if (!priv->tx_skbuff)
		goto free_rx_skbuff;

	priv->skb_curtx = 0;
	priv->skb_dirtytx = 0;
	priv->curtx_bd = priv->tx_bd_base;
	priv->dirty_tx = priv->tx_bd_base;
	priv->currx_bd = priv->rx_bd_base;
	priv->currx_bdnum = 0;

	/* init parameter base */
	cecr_subblock = ucc_fast_get_qe_cr_subblock(uf_info->ucc_num);
	ret = qe_issue_cmd(QE_ASSIGN_PAGE_TO_DEVICE, cecr_subblock,
			   QE_CR_PROTOCOL_UNSPECIFIED, priv->ucc_pram_offset);

	priv->ucc_pram = (struct ucc_hdlc_param __iomem *)
					qe_muram_addr(priv->ucc_pram_offset);

	/* Zero out parameter ram */
	memset_io(priv->ucc_pram, 0, sizeof(struct ucc_hdlc_param));

	/* Alloc riptr, tiptr */
	riptr = qe_muram_alloc(32, 32);
	if (IS_ERR_VALUE(riptr)) {
		dev_err(priv->dev, "Cannot allocate MURAM mem for Receive internal temp data pointer\n");
		ret = -ENOMEM;
		goto free_tx_skbuff;
	}

	tiptr = qe_muram_alloc(32, 32);
	if (IS_ERR_VALUE(tiptr)) {
		dev_err(priv->dev, "Cannot allocate MURAM mem for Transmit internal temp data pointer\n");
		ret = -ENOMEM;
		goto free_riptr;
	}
	if (riptr != (u16)riptr || tiptr != (u16)tiptr) {
		dev_err(priv->dev, "MURAM allocation out of addressable range\n");
		ret = -ENOMEM;
		goto free_tiptr;
	}

	/* Set RIPTR, TIPTR */
	iowrite16be(riptr, &priv->ucc_pram->riptr);
	iowrite16be(tiptr, &priv->ucc_pram->tiptr);

	/* Set MRBLR */
	iowrite16be(MAX_RX_BUF_LENGTH, &priv->ucc_pram->mrblr);

	/* Set RBASE, TBASE */
	iowrite32be(priv->dma_rx_bd, &priv->ucc_pram->rbase);
	iowrite32be(priv->dma_tx_bd, &priv->ucc_pram->tbase);

	/* Set RSTATE, TSTATE */
	iowrite32be(BMR_GBL | BMR_BIG_ENDIAN, &priv->ucc_pram->rstate);
	iowrite32be(BMR_GBL | BMR_BIG_ENDIAN, &priv->ucc_pram->tstate);

	/* Set C_MASK, C_PRES for 16bit CRC */
	iowrite32be(CRC_16BIT_MASK, &priv->ucc_pram->c_mask);
	iowrite32be(CRC_16BIT_PRES, &priv->ucc_pram->c_pres);

	iowrite16be(MAX_FRAME_LENGTH, &priv->ucc_pram->mflr);
	iowrite16be(DEFAULT_RFTHR, &priv->ucc_pram->rfthr);
	iowrite16be(DEFAULT_RFTHR, &priv->ucc_pram->rfcnt);
	iowrite16be(DEFAULT_ADDR_MASK, &priv->ucc_pram->hmask);
	iowrite16be(DEFAULT_HDLC_ADDR, &priv->ucc_pram->haddr1);
	iowrite16be(DEFAULT_HDLC_ADDR, &priv->ucc_pram->haddr2);
	iowrite16be(DEFAULT_HDLC_ADDR, &priv->ucc_pram->haddr3);
	iowrite16be(DEFAULT_HDLC_ADDR, &priv->ucc_pram->haddr4);

	/* Get BD buffer */
	bd_buffer = dma_zalloc_coherent(priv->dev,
					(RX_BD_RING_LEN + TX_BD_RING_LEN) *
					MAX_RX_BUF_LENGTH,
					&bd_dma_addr, GFP_KERNEL);

	if (!bd_buffer) {
		dev_err(priv->dev, "Could not allocate buffer descriptors\n");
		ret = -ENOMEM;
		goto free_tiptr;
	}

	priv->rx_buffer = bd_buffer;
	priv->tx_buffer = bd_buffer + RX_BD_RING_LEN * MAX_RX_BUF_LENGTH;

	priv->dma_rx_addr = bd_dma_addr;
	priv->dma_tx_addr = bd_dma_addr + RX_BD_RING_LEN * MAX_RX_BUF_LENGTH;

	for (i = 0; i < RX_BD_RING_LEN; i++) {
		if (i < (RX_BD_RING_LEN - 1))
			bd_status = R_E_S | R_I_S;
		else
			bd_status = R_E_S | R_I_S | R_W_S;

		iowrite16be(bd_status, &priv->rx_bd_base[i].status);
		iowrite32be(priv->dma_rx_addr + i * MAX_RX_BUF_LENGTH,
			    &priv->rx_bd_base[i].buf);
	}

	for (i = 0; i < TX_BD_RING_LEN; i++) {
		if (i < (TX_BD_RING_LEN - 1))
			bd_status =  T_I_S | T_TC_S;
		else
			bd_status =  T_I_S | T_TC_S | T_W_S;

		iowrite16be(bd_status, &priv->tx_bd_base[i].status);
		iowrite32be(priv->dma_tx_addr + i * MAX_RX_BUF_LENGTH,
			    &priv->tx_bd_base[i].buf);
	}

	return 0;

free_tiptr:
	qe_muram_free(tiptr);
free_riptr:
	qe_muram_free(riptr);
free_tx_skbuff:
	kfree(priv->tx_skbuff);
free_rx_skbuff:
	kfree(priv->rx_skbuff);
free_ucc_pram:
	qe_muram_free(priv->ucc_pram_offset);
free_tx_bd:
	dma_free_coherent(priv->dev,
			  TX_BD_RING_LEN * sizeof(struct qe_bd),
			  priv->tx_bd_base, priv->dma_tx_bd);
free_rx_bd:
	dma_free_coherent(priv->dev,
			  RX_BD_RING_LEN * sizeof(struct qe_bd),
			  priv->rx_bd_base, priv->dma_rx_bd);
free_uccf:
	ucc_fast_free(priv->uccf);

	return ret;
}

static netdev_tx_t ucc_hdlc_tx(struct sk_buff *skb, struct net_device *dev)
{
	hdlc_device *hdlc = dev_to_hdlc(dev);
	struct ucc_hdlc_private *priv = (struct ucc_hdlc_private *)hdlc->priv;
	struct qe_bd __iomem *bd;
	u16 bd_status;
	unsigned long flags;
	u16 *proto_head;

	switch (dev->type) {
	case ARPHRD_RAWHDLC:
		if (skb_headroom(skb) < HDLC_HEAD_LEN) {
			dev->stats.tx_dropped++;
			dev_kfree_skb(skb);
			netdev_err(dev, "No enough space for hdlc head\n");
			return -ENOMEM;
		}

		skb_push(skb, HDLC_HEAD_LEN);

		proto_head = (u16 *)skb->data;
		*proto_head = htons(DEFAULT_HDLC_HEAD);

		dev->stats.tx_bytes += skb->len;
		break;

	case ARPHRD_PPP:
		proto_head = (u16 *)skb->data;
		if (*proto_head != htons(DEFAULT_PPP_HEAD)) {
			dev->stats.tx_dropped++;
			dev_kfree_skb(skb);
			netdev_err(dev, "Wrong ppp header\n");
			return -ENOMEM;
		}

		dev->stats.tx_bytes += skb->len;
		break;

	default:
		dev->stats.tx_dropped++;
		dev_kfree_skb(skb);
		return -ENOMEM;
	}
	spin_lock_irqsave(&priv->lock, flags);

	/* Start from the next BD that should be filled */
	bd = priv->curtx_bd;
	bd_status = ioread16be(&bd->status);
	/* Save the skb pointer so we can free it later */
	priv->tx_skbuff[priv->skb_curtx] = skb;

	/* Update the current skb pointer (wrapping if this was the last) */
	priv->skb_curtx =
	    (priv->skb_curtx + 1) & TX_RING_MOD_MASK(TX_BD_RING_LEN);

	/* copy skb data to tx buffer for sdma processing */
	memcpy(priv->tx_buffer + (be32_to_cpu(bd->buf) - priv->dma_tx_addr),
	       skb->data, skb->len);

	/* set bd status and length */
	bd_status = (bd_status & T_W_S) | T_R_S | T_I_S | T_L_S | T_TC_S;

	iowrite16be(skb->len, &bd->length);
	iowrite16be(bd_status, &bd->status);

	/* Move to next BD in the ring */
	if (!(bd_status & T_W_S))
		bd += 1;
	else
		bd = priv->tx_bd_base;

	if (bd == priv->dirty_tx) {
		if (!netif_queue_stopped(dev))
			netif_stop_queue(dev);
	}

	priv->curtx_bd = bd;

	spin_unlock_irqrestore(&priv->lock, flags);

	return NETDEV_TX_OK;
}

static int hdlc_tx_done(struct ucc_hdlc_private *priv)
{
	/* Start from the next BD that should be filled */
	struct net_device *dev = priv->ndev;
	struct qe_bd *bd;		/* BD pointer */
	u16 bd_status;

	bd = priv->dirty_tx;
	bd_status = ioread16be(&bd->status);

	/* Normal processing. */
	while ((bd_status & T_R_S) == 0) {
		struct sk_buff *skb;

		/* BD contains already transmitted buffer.   */
		/* Handle the transmitted buffer and release */
		/* the BD to be used with the current frame  */

		skb = priv->tx_skbuff[priv->skb_dirtytx];
		if (!skb)
			break;
		dev->stats.tx_packets++;
		memset(priv->tx_buffer +
		       (be32_to_cpu(bd->buf) - priv->dma_tx_addr),
		       0, skb->len);
		dev_kfree_skb_irq(skb);

		priv->tx_skbuff[priv->skb_dirtytx] = NULL;
		priv->skb_dirtytx =
		    (priv->skb_dirtytx +
		     1) & TX_RING_MOD_MASK(TX_BD_RING_LEN);

		/* We freed a buffer, so now we can restart transmission */
		if (netif_queue_stopped(dev))
			netif_wake_queue(dev);

		/* Advance the confirmation BD pointer */
		if (!(bd_status & T_W_S))
			bd += 1;
		else
			bd = priv->tx_bd_base;
		bd_status = ioread16be(&bd->status);
	}
	priv->dirty_tx = bd;

	return 0;
}

static int hdlc_rx_done(struct ucc_hdlc_private *priv, int rx_work_limit)
{
	struct net_device *dev = priv->ndev;
	struct sk_buff *skb = NULL;
	hdlc_device *hdlc = dev_to_hdlc(dev);
	struct qe_bd *bd;
	u16 bd_status;
	u16 length, howmany = 0;
	u8 *bdbuffer;

	bd = priv->currx_bd;
	bd_status = ioread16be(&bd->status);

	/* while there are received buffers and BD is full (~R_E) */
	while (!((bd_status & (R_E_S)) || (--rx_work_limit < 0))) {
		if (bd_status & R_OV_S)
			dev->stats.rx_over_errors++;
		if (bd_status & R_CR_S) {
			dev->stats.rx_crc_errors++;
			dev->stats.rx_dropped++;
			goto recycle;
		}
		bdbuffer = priv->rx_buffer +
			(priv->currx_bdnum * MAX_RX_BUF_LENGTH);
		length = ioread16be(&bd->length);

		switch (dev->type) {
		case ARPHRD_RAWHDLC:
			bdbuffer += HDLC_HEAD_LEN;
			length -= (HDLC_HEAD_LEN + HDLC_CRC_SIZE);

			skb = dev_alloc_skb(length);
			if (!skb) {
				dev->stats.rx_dropped++;
				return -ENOMEM;
			}

			skb_put(skb, length);
			skb->len = length;
			skb->dev = dev;
			memcpy(skb->data, bdbuffer, length);
			break;

		case ARPHRD_PPP:
			length -= HDLC_CRC_SIZE;

			skb = dev_alloc_skb(length);
			if (!skb) {
				dev->stats.rx_dropped++;
				return -ENOMEM;
			}

			skb_put(skb, length);
			skb->len = length;
			skb->dev = dev;
			memcpy(skb->data, bdbuffer, length);
			break;
		}

		dev->stats.rx_packets++;
		dev->stats.rx_bytes += skb->len;
		howmany++;
		if (hdlc->proto)
			skb->protocol = hdlc_type_trans(skb, dev);
		netif_receive_skb(skb);

recycle:
		iowrite16be(bd_status | R_E_S | R_I_S, &bd->status);

		/* update to point at the next bd */
		if (bd_status & R_W_S) {
			priv->currx_bdnum = 0;
			bd = priv->rx_bd_base;
		} else {
			if (priv->currx_bdnum < (RX_BD_RING_LEN - 1))
				priv->currx_bdnum += 1;
			else
				priv->currx_bdnum = RX_BD_RING_LEN - 1;

			bd += 1;
		}

		bd_status = ioread16be(&bd->status);
	}

	priv->currx_bd = bd;
	return howmany;
}

static int ucc_hdlc_poll(struct napi_struct *napi, int budget)
{
	struct ucc_hdlc_private *priv = container_of(napi,
						     struct ucc_hdlc_private,
						     napi);
	int howmany;

	/* Tx event processing */
	spin_lock(&priv->lock);
	hdlc_tx_done(priv);
	spin_unlock(&priv->lock);

	howmany = 0;
	howmany += hdlc_rx_done(priv, budget - howmany);

	if (howmany < budget) {
		napi_complete_done(napi, howmany);
		qe_setbits32(priv->uccf->p_uccm,
			     (UCCE_HDLC_RX_EVENTS | UCCE_HDLC_TX_EVENTS) << 16);
	}

	return howmany;
}

static irqreturn_t ucc_hdlc_irq_handler(int irq, void *dev_id)
{
	struct ucc_hdlc_private *priv = (struct ucc_hdlc_private *)dev_id;
	struct net_device *dev = priv->ndev;
	struct ucc_fast_private *uccf;
	struct ucc_tdm_info *ut_info;
	u32 ucce;
	u32 uccm;

	ut_info = priv->ut_info;
	uccf = priv->uccf;

	ucce = ioread32be(uccf->p_ucce);
	uccm = ioread32be(uccf->p_uccm);
	ucce &= uccm;
	iowrite32be(ucce, uccf->p_ucce);
	if (!ucce)
		return IRQ_NONE;

	if ((ucce >> 16) & (UCCE_HDLC_RX_EVENTS | UCCE_HDLC_TX_EVENTS)) {
		if (napi_schedule_prep(&priv->napi)) {
			uccm &= ~((UCCE_HDLC_RX_EVENTS | UCCE_HDLC_TX_EVENTS)
				  << 16);
			iowrite32be(uccm, uccf->p_uccm);
			__napi_schedule(&priv->napi);
		}
	}

	/* Errors and other events */
	if (ucce >> 16 & UCC_HDLC_UCCE_BSY)
		dev->stats.rx_errors++;
	if (ucce >> 16 & UCC_HDLC_UCCE_TXE)
		dev->stats.tx_errors++;

	return IRQ_HANDLED;
}

static int uhdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
	const size_t size = sizeof(te1_settings);
	te1_settings line;
	struct ucc_hdlc_private *priv = netdev_priv(dev);

	if (cmd != SIOCWANDEV)
		return hdlc_ioctl(dev, ifr, cmd);

	switch (ifr->ifr_settings.type) {
	case IF_GET_IFACE:
		ifr->ifr_settings.type = IF_IFACE_E1;
		if (ifr->ifr_settings.size < size) {
			ifr->ifr_settings.size = size; /* data size wanted */
			return -ENOBUFS;
		}
		memset(&line, 0, sizeof(line));
		line.clock_type = priv->clocking;

		if (copy_to_user(ifr->ifr_settings.ifs_ifsu.sync, &line, size))
			return -EFAULT;
		return 0;

	default:
		return hdlc_ioctl(dev, ifr, cmd);
	}
}

static int uhdlc_open(struct net_device *dev)
{
	u32 cecr_subblock;
	hdlc_device *hdlc = dev_to_hdlc(dev);
	struct ucc_hdlc_private *priv = hdlc->priv;
	struct ucc_tdm *utdm = priv->utdm;

	if (priv->hdlc_busy != 1) {
		if (request_irq(priv->ut_info->uf_info.irq,
				ucc_hdlc_irq_handler, 0, "hdlc", priv))
			return -ENODEV;

		cecr_subblock = ucc_fast_get_qe_cr_subblock(
					priv->ut_info->uf_info.ucc_num);

		qe_issue_cmd(QE_INIT_TX_RX, cecr_subblock,
			     QE_CR_PROTOCOL_UNSPECIFIED, 0);

		ucc_fast_enable(priv->uccf, COMM_DIR_RX | COMM_DIR_TX);

		/* Enable the TDM port */
		if (priv->tsa)
			utdm->si_regs->siglmr1_h |= (0x1 << utdm->tdm_port);

		priv->hdlc_busy = 1;
		netif_device_attach(priv->ndev);
		napi_enable(&priv->napi);
		netif_start_queue(dev);
		hdlc_open(dev);
	}

	return 0;
}

static void uhdlc_memclean(struct ucc_hdlc_private *priv)
{
	qe_muram_free(priv->ucc_pram->riptr);
	qe_muram_free(priv->ucc_pram->tiptr);

	if (priv->rx_bd_base) {
		dma_free_coherent(priv->dev,
				  RX_BD_RING_LEN * sizeof(struct qe_bd),
				  priv->rx_bd_base, priv->dma_rx_bd);

		priv->rx_bd_base = NULL;
		priv->dma_rx_bd = 0;
	}

	if (priv->tx_bd_base) {
		dma_free_coherent(priv->dev,
				  TX_BD_RING_LEN * sizeof(struct qe_bd),
				  priv->tx_bd_base, priv->dma_tx_bd);

		priv->tx_bd_base = NULL;
		priv->dma_tx_bd = 0;
	}

	if (priv->ucc_pram) {
		qe_muram_free(priv->ucc_pram_offset);
		priv->ucc_pram = NULL;
		priv->ucc_pram_offset = 0;
	 }

	kfree(priv->rx_skbuff);
	priv->rx_skbuff = NULL;

	kfree(priv->tx_skbuff);
	priv->tx_skbuff = NULL;

	if (priv->uf_regs) {
		iounmap(priv->uf_regs);
		priv->uf_regs = NULL;
	}

	if (priv->uccf) {
		ucc_fast_free(priv->uccf);
		priv->uccf = NULL;
	}

	if (priv->rx_buffer) {
		dma_free_coherent(priv->dev,
				  RX_BD_RING_LEN * MAX_RX_BUF_LENGTH,
				  priv->rx_buffer, priv->dma_rx_addr);
		priv->rx_buffer = NULL;
		priv->dma_rx_addr = 0;
	}

	if (priv->tx_buffer) {
		dma_free_coherent(priv->dev,
				  TX_BD_RING_LEN * MAX_RX_BUF_LENGTH,
				  priv->tx_buffer, priv->dma_tx_addr);
		priv->tx_buffer = NULL;
		priv->dma_tx_addr = 0;
	}
}

static int uhdlc_close(struct net_device *dev)
{
	struct ucc_hdlc_private *priv = dev_to_hdlc(dev)->priv;
	struct ucc_tdm *utdm = priv->utdm;
	u32 cecr_subblock;

	napi_disable(&priv->napi);
	cecr_subblock = ucc_fast_get_qe_cr_subblock(
				priv->ut_info->uf_info.ucc_num);

	qe_issue_cmd(QE_GRACEFUL_STOP_TX, cecr_subblock,
		     (u8)QE_CR_PROTOCOL_UNSPECIFIED, 0);
	qe_issue_cmd(QE_CLOSE_RX_BD, cecr_subblock,
		     (u8)QE_CR_PROTOCOL_UNSPECIFIED, 0);

	if (priv->tsa)
		utdm->si_regs->siglmr1_h &= ~(0x1 << utdm->tdm_port);

	ucc_fast_disable(priv->uccf, COMM_DIR_RX | COMM_DIR_TX);

	free_irq(priv->ut_info->uf_info.irq, priv);
	netif_stop_queue(dev);
	priv->hdlc_busy = 0;

	return 0;
}

static int ucc_hdlc_attach(struct net_device *dev, unsigned short encoding,
			   unsigned short parity)
{
	struct ucc_hdlc_private *priv = dev_to_hdlc(dev)->priv;

	if (encoding != ENCODING_NRZ &&
	    encoding != ENCODING_NRZI)
		return -EINVAL;

	if (parity != PARITY_NONE &&
	    parity != PARITY_CRC32_PR1_CCITT &&
	    parity != PARITY_CRC16_PR1_CCITT)
		return -EINVAL;

	priv->encoding = encoding;
	priv->parity = parity;

	return 0;
}

#ifdef CONFIG_PM
static void store_clk_config(struct ucc_hdlc_private *priv)
{
	struct qe_mux *qe_mux_reg = &qe_immr->qmx;

	/* store si clk */
	priv->cmxsi1cr_h = ioread32be(&qe_mux_reg->cmxsi1cr_h);
	priv->cmxsi1cr_l = ioread32be(&qe_mux_reg->cmxsi1cr_l);

	/* store si sync */
	priv->cmxsi1syr = ioread32be(&qe_mux_reg->cmxsi1syr);

	/* store ucc clk */
	memcpy_fromio(priv->cmxucr, qe_mux_reg->cmxucr, 4 * sizeof(u32));
}

static void resume_clk_config(struct ucc_hdlc_private *priv)
{
	struct qe_mux *qe_mux_reg = &qe_immr->qmx;

	memcpy_toio(qe_mux_reg->cmxucr, priv->cmxucr, 4 * sizeof(u32));

	iowrite32be(priv->cmxsi1cr_h, &qe_mux_reg->cmxsi1cr_h);
	iowrite32be(priv->cmxsi1cr_l, &qe_mux_reg->cmxsi1cr_l);

	iowrite32be(priv->cmxsi1syr, &qe_mux_reg->cmxsi1syr);
}

static int uhdlc_suspend(struct device *dev)
{
	struct ucc_hdlc_private *priv = dev_get_drvdata(dev);
	struct ucc_tdm_info *ut_info;
	struct ucc_fast __iomem *uf_regs;

	if (!priv)
		return -EINVAL;

	if (!netif_running(priv->ndev))
		return 0;

	netif_device_detach(priv->ndev);
	napi_disable(&priv->napi);

	ut_info = priv->ut_info;
	uf_regs = priv->uf_regs;

	/* backup gumr guemr*/
	priv->gumr = ioread32be(&uf_regs->gumr);
	priv->guemr = ioread8(&uf_regs->guemr);

	priv->ucc_pram_bak = kmalloc(sizeof(*priv->ucc_pram_bak),
					GFP_KERNEL);
	if (!priv->ucc_pram_bak)
		return -ENOMEM;

	/* backup HDLC parameter */
	memcpy_fromio(priv->ucc_pram_bak, priv->ucc_pram,
		      sizeof(struct ucc_hdlc_param));

	/* store the clk configuration */
	store_clk_config(priv);

	/* save power */
	ucc_fast_disable(priv->uccf, COMM_DIR_RX | COMM_DIR_TX);

	return 0;
}

static int uhdlc_resume(struct device *dev)
{
	struct ucc_hdlc_private *priv = dev_get_drvdata(dev);
	struct ucc_tdm *utdm;
	struct ucc_tdm_info *ut_info;
	struct ucc_fast __iomem *uf_regs;
	struct ucc_fast_private *uccf;
	struct ucc_fast_info *uf_info;
	int ret, i;
	u32 cecr_subblock;
	u16 bd_status;

	if (!priv)
		return -EINVAL;

	if (!netif_running(priv->ndev))
		return 0;

	utdm = priv->utdm;
	ut_info = priv->ut_info;
	uf_info = &ut_info->uf_info;
	uf_regs = priv->uf_regs;
	uccf = priv->uccf;

	/* restore gumr guemr */
	iowrite8(priv->guemr, &uf_regs->guemr);
	iowrite32be(priv->gumr, &uf_regs->gumr);

	/* Set Virtual Fifo registers */
	iowrite16be(uf_info->urfs, &uf_regs->urfs);
	iowrite16be(uf_info->urfet, &uf_regs->urfet);
	iowrite16be(uf_info->urfset, &uf_regs->urfset);
	iowrite16be(uf_info->utfs, &uf_regs->utfs);
	iowrite16be(uf_info->utfet, &uf_regs->utfet);
	iowrite16be(uf_info->utftt, &uf_regs->utftt);
	/* utfb, urfb are offsets from MURAM base */
	iowrite32be(uccf->ucc_fast_tx_virtual_fifo_base_offset, &uf_regs->utfb);
	iowrite32be(uccf->ucc_fast_rx_virtual_fifo_base_offset, &uf_regs->urfb);

	/* Rx Tx and sync clock routing */
	resume_clk_config(priv);

	iowrite32be(uf_info->uccm_mask, &uf_regs->uccm);
	iowrite32be(0xffffffff, &uf_regs->ucce);

	ucc_fast_disable(priv->uccf, COMM_DIR_RX | COMM_DIR_TX);

	/* rebuild SIRAM */
	if (priv->tsa)
		ucc_tdm_init(priv->utdm, priv->ut_info);

	/* Write to QE CECR, UCCx channel to Stop Transmission */
	cecr_subblock = ucc_fast_get_qe_cr_subblock(uf_info->ucc_num);
	ret = qe_issue_cmd(QE_STOP_TX, cecr_subblock,
			   (u8)QE_CR_PROTOCOL_UNSPECIFIED, 0);

	/* Set UPSMR normal mode */
	iowrite32be(0, &uf_regs->upsmr);

	/* init parameter base */
	cecr_subblock = ucc_fast_get_qe_cr_subblock(uf_info->ucc_num);
	ret = qe_issue_cmd(QE_ASSIGN_PAGE_TO_DEVICE, cecr_subblock,
			   QE_CR_PROTOCOL_UNSPECIFIED, priv->ucc_pram_offset);

	priv->ucc_pram = (struct ucc_hdlc_param __iomem *)
				qe_muram_addr(priv->ucc_pram_offset);

	/* restore ucc parameter */
	memcpy_toio(priv->ucc_pram, priv->ucc_pram_bak,
		    sizeof(struct ucc_hdlc_param));
	kfree(priv->ucc_pram_bak);

	/* rebuild BD entry */
	for (i = 0; i < RX_BD_RING_LEN; i++) {
		if (i < (RX_BD_RING_LEN - 1))
			bd_status = R_E_S | R_I_S;
		else
			bd_status = R_E_S | R_I_S | R_W_S;

		iowrite16be(bd_status, &priv->rx_bd_base[i].status);
		iowrite32be(priv->dma_rx_addr + i * MAX_RX_BUF_LENGTH,
			    &priv->rx_bd_base[i].buf);
	}

	for (i = 0; i < TX_BD_RING_LEN; i++) {
		if (i < (TX_BD_RING_LEN - 1))
			bd_status =  T_I_S | T_TC_S;
		else
			bd_status =  T_I_S | T_TC_S | T_W_S;

		iowrite16be(bd_status, &priv->tx_bd_base[i].status);
		iowrite32be(priv->dma_tx_addr + i * MAX_RX_BUF_LENGTH,
			    &priv->tx_bd_base[i].buf);
	}

	/* if hdlc is busy enable TX and RX */
	if (priv->hdlc_busy == 1) {
		cecr_subblock = ucc_fast_get_qe_cr_subblock(
					priv->ut_info->uf_info.ucc_num);

		qe_issue_cmd(QE_INIT_TX_RX, cecr_subblock,
			     (u8)QE_CR_PROTOCOL_UNSPECIFIED, 0);

		ucc_fast_enable(priv->uccf, COMM_DIR_RX | COMM_DIR_TX);

		/* Enable the TDM port */
		if (priv->tsa)
			utdm->si_regs->siglmr1_h |= (0x1 << utdm->tdm_port);
	}

	napi_enable(&priv->napi);
	netif_device_attach(priv->ndev);

	return 0;
}

static const struct dev_pm_ops uhdlc_pm_ops = {
	.suspend = uhdlc_suspend,
	.resume = uhdlc_resume,
	.freeze = uhdlc_suspend,
	.thaw = uhdlc_resume,
};

#define HDLC_PM_OPS (&uhdlc_pm_ops)

#else

#define HDLC_PM_OPS NULL

#endif
static const struct net_device_ops uhdlc_ops = {
	.ndo_open       = uhdlc_open,
	.ndo_stop       = uhdlc_close,
	.ndo_start_xmit = hdlc_start_xmit,
	.ndo_do_ioctl   = uhdlc_ioctl,
};

static int ucc_hdlc_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct ucc_hdlc_private *uhdlc_priv = NULL;
	struct ucc_tdm_info *ut_info;
	struct ucc_tdm *utdm = NULL;
	struct resource res;
	struct net_device *dev;
	hdlc_device *hdlc;
	int ucc_num;
	const char *sprop;
	int ret;
	u32 val;

	ret = of_property_read_u32_index(np, "cell-index", 0, &val);
	if (ret) {
		dev_err(&pdev->dev, "Invalid ucc property\n");
		return -ENODEV;
	}

	ucc_num = val - 1;
	if ((ucc_num > 3) || (ucc_num < 0)) {
		dev_err(&pdev->dev, ": Invalid UCC num\n");
		return -EINVAL;
	}

	memcpy(&utdm_info[ucc_num], &utdm_primary_info,
	       sizeof(utdm_primary_info));

	ut_info = &utdm_info[ucc_num];
	ut_info->uf_info.ucc_num = ucc_num;

	sprop = of_get_property(np, "rx-clock-name", NULL);
	if (sprop) {
		ut_info->uf_info.rx_clock = qe_clock_source(sprop);
		if ((ut_info->uf_info.rx_clock < QE_CLK_NONE) ||
		    (ut_info->uf_info.rx_clock > QE_CLK24)) {
			dev_err(&pdev->dev, "Invalid rx-clock-name property\n");
			return -EINVAL;
		}
	} else {
		dev_err(&pdev->dev, "Invalid rx-clock-name property\n");
		return -EINVAL;
	}

	sprop = of_get_property(np, "tx-clock-name", NULL);
	if (sprop) {
		ut_info->uf_info.tx_clock = qe_clock_source(sprop);
		if ((ut_info->uf_info.tx_clock < QE_CLK_NONE) ||
		    (ut_info->uf_info.tx_clock > QE_CLK24)) {
			dev_err(&pdev->dev, "Invalid tx-clock-name property\n");
			return -EINVAL;
		}
	} else {
		dev_err(&pdev->dev, "Invalid tx-clock-name property\n");
		return -EINVAL;
	}

	ret = of_address_to_resource(np, 0, &res);
	if (ret)
		return -EINVAL;

	ut_info->uf_info.regs = res.start;
	ut_info->uf_info.irq = irq_of_parse_and_map(np, 0);

	uhdlc_priv = kzalloc(sizeof(*uhdlc_priv), GFP_KERNEL);
	if (!uhdlc_priv) {
		return -ENOMEM;
	}

	dev_set_drvdata(&pdev->dev, uhdlc_priv);
	uhdlc_priv->dev = &pdev->dev;
	uhdlc_priv->ut_info = ut_info;

	if (of_get_property(np, "fsl,tdm-interface", NULL))
		uhdlc_priv->tsa = 1;

	if (of_get_property(np, "fsl,ucc-internal-loopback", NULL))
		uhdlc_priv->loopback = 1;

	if (of_get_property(np, "fsl,hdlc-bus", NULL))
		uhdlc_priv->hdlc_bus = 1;

	if (uhdlc_priv->tsa == 1) {
		utdm = kzalloc(sizeof(*utdm), GFP_KERNEL);
		if (!utdm) {
			ret = -ENOMEM;
			dev_err(&pdev->dev, "No mem to alloc ucc tdm data\n");
			goto free_uhdlc_priv;
		}
		uhdlc_priv->utdm = utdm;
		ret = ucc_of_parse_tdm(np, utdm, ut_info);
		if (ret)
			goto free_utdm;
	}

	ret = uhdlc_init(uhdlc_priv);
	if (ret) {
		dev_err(&pdev->dev, "Failed to init uhdlc\n");
		goto free_utdm;
	}

	dev = alloc_hdlcdev(uhdlc_priv);
	if (!dev) {
		ret = -ENOMEM;
		pr_err("ucc_hdlc: unable to allocate memory\n");
		goto undo_uhdlc_init;
	}

	uhdlc_priv->ndev = dev;
	hdlc = dev_to_hdlc(dev);
	dev->tx_queue_len = 16;
	dev->netdev_ops = &uhdlc_ops;
	hdlc->attach = ucc_hdlc_attach;
	hdlc->xmit = ucc_hdlc_tx;
	netif_napi_add(dev, &uhdlc_priv->napi, ucc_hdlc_poll, 32);
	if (register_hdlc_device(dev)) {
		ret = -ENOBUFS;
		pr_err("ucc_hdlc: unable to register hdlc device\n");
		goto free_dev;
	}

	return 0;

free_dev:
	free_netdev(dev);
undo_uhdlc_init:
free_utdm:
	if (uhdlc_priv->tsa)
		kfree(utdm);
free_uhdlc_priv:
	kfree(uhdlc_priv);
	return ret;
}

static int ucc_hdlc_remove(struct platform_device *pdev)
{
	struct ucc_hdlc_private *priv = dev_get_drvdata(&pdev->dev);

	uhdlc_memclean(priv);

	if (priv->utdm->si_regs) {
		iounmap(priv->utdm->si_regs);
		priv->utdm->si_regs = NULL;
	}

	if (priv->utdm->siram) {
		iounmap(priv->utdm->siram);
		priv->utdm->siram = NULL;
	}
	kfree(priv);

	dev_info(&pdev->dev, "UCC based hdlc module removed\n");

	return 0;
}

static const struct of_device_id fsl_ucc_hdlc_of_match[] = {
	{
	.compatible = "fsl,ucc-hdlc",
	},
	{},
};

MODULE_DEVICE_TABLE(of, fsl_ucc_hdlc_of_match);

static struct platform_driver ucc_hdlc_driver = {
	.probe	= ucc_hdlc_probe,
	.remove	= ucc_hdlc_remove,
	.driver	= {
		.name		= DRV_NAME,
		.pm		= HDLC_PM_OPS,
		.of_match_table	= fsl_ucc_hdlc_of_match,
	},
};

module_platform_driver(ucc_hdlc_driver);
MODULE_LICENSE("GPL");
