/*
 * File:         drivers/ata/pata_bf54x.c
 * Author:       Sonic Zhang <sonic.zhang@analog.com>
 *
 * Created:
 * Description:  PATA Driver for blackfin 54x
 *
 * Modified:
 *               Copyright 2007 Analog Devices Inc.
 *
 * Bugs:         Enter bugs at http://blackfin.uclinux.org/
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see the file COPYING, or write
 * to the Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
#include <linux/platform_device.h>
#include <asm/dma.h>
#include <asm/gpio.h>
#include <asm/portmux.h>

#define DRV_NAME		"pata-bf54x"
#define DRV_VERSION		"0.9"

#define ATA_REG_CTRL		0x0E
#define ATA_REG_ALTSTATUS	ATA_REG_CTRL

/* These are the offset of the controller's registers */
#define ATAPI_OFFSET_CONTROL		0x00
#define ATAPI_OFFSET_STATUS		0x04
#define ATAPI_OFFSET_DEV_ADDR		0x08
#define ATAPI_OFFSET_DEV_TXBUF		0x0c
#define ATAPI_OFFSET_DEV_RXBUF		0x10
#define ATAPI_OFFSET_INT_MASK		0x14
#define ATAPI_OFFSET_INT_STATUS		0x18
#define ATAPI_OFFSET_XFER_LEN		0x1c
#define ATAPI_OFFSET_LINE_STATUS	0x20
#define ATAPI_OFFSET_SM_STATE		0x24
#define ATAPI_OFFSET_TERMINATE		0x28
#define ATAPI_OFFSET_PIO_TFRCNT		0x2c
#define ATAPI_OFFSET_DMA_TFRCNT		0x30
#define ATAPI_OFFSET_UMAIN_TFRCNT	0x34
#define ATAPI_OFFSET_UDMAOUT_TFRCNT	0x38
#define ATAPI_OFFSET_REG_TIM_0		0x40
#define ATAPI_OFFSET_PIO_TIM_0		0x44
#define ATAPI_OFFSET_PIO_TIM_1		0x48
#define ATAPI_OFFSET_MULTI_TIM_0	0x50
#define ATAPI_OFFSET_MULTI_TIM_1	0x54
#define ATAPI_OFFSET_MULTI_TIM_2	0x58
#define ATAPI_OFFSET_ULTRA_TIM_0	0x60
#define ATAPI_OFFSET_ULTRA_TIM_1	0x64
#define ATAPI_OFFSET_ULTRA_TIM_2	0x68
#define ATAPI_OFFSET_ULTRA_TIM_3	0x6c


#define ATAPI_GET_CONTROL(base)\
	bfin_read16(base + ATAPI_OFFSET_CONTROL)
#define ATAPI_SET_CONTROL(base, val)\
	bfin_write16(base + ATAPI_OFFSET_CONTROL, val)
#define ATAPI_GET_STATUS(base)\
	bfin_read16(base + ATAPI_OFFSET_STATUS)
#define ATAPI_GET_DEV_ADDR(base)\
	bfin_read16(base + ATAPI_OFFSET_DEV_ADDR)
#define ATAPI_SET_DEV_ADDR(base, val)\
	bfin_write16(base + ATAPI_OFFSET_DEV_ADDR, val)
#define ATAPI_GET_DEV_TXBUF(base)\
	bfin_read16(base + ATAPI_OFFSET_DEV_TXBUF)
#define ATAPI_SET_DEV_TXBUF(base, val)\
	bfin_write16(base + ATAPI_OFFSET_DEV_TXBUF, val)
#define ATAPI_GET_DEV_RXBUF(base)\
	bfin_read16(base + ATAPI_OFFSET_DEV_RXBUF)
#define ATAPI_SET_DEV_RXBUF(base, val)\
	bfin_write16(base + ATAPI_OFFSET_DEV_RXBUF, val)
#define ATAPI_GET_INT_MASK(base)\
	bfin_read16(base + ATAPI_OFFSET_INT_MASK)
#define ATAPI_SET_INT_MASK(base, val)\
	bfin_write16(base + ATAPI_OFFSET_INT_MASK, val)
#define ATAPI_GET_INT_STATUS(base)\
	bfin_read16(base + ATAPI_OFFSET_INT_STATUS)
#define ATAPI_SET_INT_STATUS(base, val)\
	bfin_write16(base + ATAPI_OFFSET_INT_STATUS, val)
#define ATAPI_GET_XFER_LEN(base)\
	bfin_read16(base + ATAPI_OFFSET_XFER_LEN)
#define ATAPI_SET_XFER_LEN(base, val)\
	bfin_write16(base + ATAPI_OFFSET_XFER_LEN, val)
#define ATAPI_GET_LINE_STATUS(base)\
	bfin_read16(base + ATAPI_OFFSET_LINE_STATUS)
#define ATAPI_GET_SM_STATE(base)\
	bfin_read16(base + ATAPI_OFFSET_SM_STATE)
#define ATAPI_GET_TERMINATE(base)\
	bfin_read16(base + ATAPI_OFFSET_TERMINATE)
#define ATAPI_SET_TERMINATE(base, val)\
	bfin_write16(base + ATAPI_OFFSET_TERMINATE, val)
#define ATAPI_GET_PIO_TFRCNT(base)\
	bfin_read16(base + ATAPI_OFFSET_PIO_TFRCNT)
#define ATAPI_GET_DMA_TFRCNT(base)\
	bfin_read16(base + ATAPI_OFFSET_DMA_TFRCNT)
#define ATAPI_GET_UMAIN_TFRCNT(base)\
	bfin_read16(base + ATAPI_OFFSET_UMAIN_TFRCNT)
#define ATAPI_GET_UDMAOUT_TFRCNT(base)\
	bfin_read16(base + ATAPI_OFFSET_UDMAOUT_TFRCNT)
#define ATAPI_GET_REG_TIM_0(base)\
	bfin_read16(base + ATAPI_OFFSET_REG_TIM_0)
#define ATAPI_SET_REG_TIM_0(base, val)\
	bfin_write16(base + ATAPI_OFFSET_REG_TIM_0, val)
#define ATAPI_GET_PIO_TIM_0(base)\
	bfin_read16(base + ATAPI_OFFSET_PIO_TIM_0)
#define ATAPI_SET_PIO_TIM_0(base, val)\
	bfin_write16(base + ATAPI_OFFSET_PIO_TIM_0, val)
#define ATAPI_GET_PIO_TIM_1(base)\
	bfin_read16(base + ATAPI_OFFSET_PIO_TIM_1)
#define ATAPI_SET_PIO_TIM_1(base, val)\
	bfin_write16(base + ATAPI_OFFSET_PIO_TIM_1, val)
#define ATAPI_GET_MULTI_TIM_0(base)\
	bfin_read16(base + ATAPI_OFFSET_MULTI_TIM_0)
#define ATAPI_SET_MULTI_TIM_0(base, val)\
	bfin_write16(base + ATAPI_OFFSET_MULTI_TIM_0, val)
#define ATAPI_GET_MULTI_TIM_1(base)\
	bfin_read16(base + ATAPI_OFFSET_MULTI_TIM_1)
#define ATAPI_SET_MULTI_TIM_1(base, val)\
	bfin_write16(base + ATAPI_OFFSET_MULTI_TIM_1, val)
#define ATAPI_GET_MULTI_TIM_2(base)\
	bfin_read16(base + ATAPI_OFFSET_MULTI_TIM_2)
#define ATAPI_SET_MULTI_TIM_2(base, val)\
	bfin_write16(base + ATAPI_OFFSET_MULTI_TIM_2, val)
#define ATAPI_GET_ULTRA_TIM_0(base)\
	bfin_read16(base + ATAPI_OFFSET_ULTRA_TIM_0)
#define ATAPI_SET_ULTRA_TIM_0(base, val)\
	bfin_write16(base + ATAPI_OFFSET_ULTRA_TIM_0, val)
#define ATAPI_GET_ULTRA_TIM_1(base)\
	bfin_read16(base + ATAPI_OFFSET_ULTRA_TIM_1)
#define ATAPI_SET_ULTRA_TIM_1(base, val)\
	bfin_write16(base + ATAPI_OFFSET_ULTRA_TIM_1, val)
#define ATAPI_GET_ULTRA_TIM_2(base)\
	bfin_read16(base + ATAPI_OFFSET_ULTRA_TIM_2)
#define ATAPI_SET_ULTRA_TIM_2(base, val)\
	bfin_write16(base + ATAPI_OFFSET_ULTRA_TIM_2, val)
#define ATAPI_GET_ULTRA_TIM_3(base)\
	bfin_read16(base + ATAPI_OFFSET_ULTRA_TIM_3)
#define ATAPI_SET_ULTRA_TIM_3(base, val)\
	bfin_write16(base + ATAPI_OFFSET_ULTRA_TIM_3, val)

/**
 * PIO Mode - Frequency compatibility
 */
/* mode: 0         1         2         3         4 */
static const u32 pio_fsclk[] =
{ 33333333, 33333333, 33333333, 33333333, 33333333 };

/**
 * MDMA Mode - Frequency compatibility
 */
/*               mode:      0         1         2        */
static const u32 mdma_fsclk[] = { 33333333, 33333333, 33333333 };

/**
 * UDMA Mode - Frequency compatibility
 *
 * UDMA5 - 100 MB/s   - SCLK  = 133 MHz
 * UDMA4 - 66 MB/s    - SCLK >=  80 MHz
 * UDMA3 - 44.4 MB/s  - SCLK >=  50 MHz
 * UDMA2 - 33 MB/s    - SCLK >=  40 MHz
 */
/* mode: 0         1         2         3         4          5 */
static const u32 udma_fsclk[] =
{ 33333333, 33333333, 40000000, 50000000, 80000000, 133333333 };

/**
 * Register transfer timing table
 */
/*               mode:       0    1    2    3    4    */
/* Cycle Time                     */
static const u32 reg_t0min[]   = { 600, 383, 330, 180, 120 };
/* DIOR/DIOW to end cycle         */
static const u32 reg_t2min[]   = { 290, 290, 290, 70,  25  };
/* DIOR/DIOW asserted pulse width */
static const u32 reg_teocmin[] = { 290, 290, 290, 80,  70  };

/**
 * PIO timing table
 */
/*               mode:       0    1    2    3    4    */
/* Cycle Time                     */
static const u32 pio_t0min[]   = { 600, 383, 240, 180, 120 };
/* Address valid to DIOR/DIORW    */
static const u32 pio_t1min[]   = { 70,  50,  30,  30,  25  };
/* DIOR/DIOW to end cycle         */
static const u32 pio_t2min[]   = { 165, 125, 100, 80,  70  };
/* DIOR/DIOW asserted pulse width */
static const u32 pio_teocmin[] = { 165, 125, 100, 70,  25  };
/* DIOW data hold                 */
static const u32 pio_t4min[]   = { 30,  20,  15,  10,  10  };

/* ******************************************************************
 * Multiword DMA timing table
 * ******************************************************************
 */
/*               mode:       0   1    2        */
/* Cycle Time                     */
static const u32 mdma_t0min[]  = { 480, 150, 120 };
/* DIOR/DIOW asserted pulse width */
static const u32 mdma_tdmin[]  = { 215, 80,  70  };
/* DMACK to read data released    */
static const u32 mdma_thmin[]  = { 20,  15,  10  };
/* DIOR/DIOW to DMACK hold        */
static const u32 mdma_tjmin[]  = { 20,  5,   5   };
/* DIOR negated pulse width       */
static const u32 mdma_tkrmin[] = { 50,  50,  25  };
/* DIOR negated pulse width       */
static const u32 mdma_tkwmin[] = { 215, 50,  25  };
/* CS[1:0] valid to DIOR/DIOW     */
static const u32 mdma_tmmin[]  = { 50,  30,  25  };
/* DMACK to read data released    */
static const u32 mdma_tzmax[]  = { 20,  25,  25  };

/**
 * Ultra DMA timing table
 */
/*               mode:         0    1    2    3    4    5       */
static const u32 udma_tcycmin[]  = { 112, 73,  54,  39,  25,  17 };
static const u32 udma_tdvsmin[]  = { 70,  48,  31,  20,  7,   5  };
static const u32 udma_tenvmax[]  = { 70,  70,  70,  55,  55,  50 };
static const u32 udma_trpmin[]   = { 160, 125, 100, 100, 100, 85 };
static const u32 udma_tmin[]     = { 5,   5,   5,   5,   3,   3  };


static const u32 udma_tmlimin = 20;
static const u32 udma_tzahmin = 20;
static const u32 udma_tenvmin = 20;
static const u32 udma_tackmin = 20;
static const u32 udma_tssmin = 50;

/**
 *
 *	Function:       num_clocks_min
 *
 *	Description:
 *	calculate number of SCLK cycles to meet minimum timing
 */
static unsigned short num_clocks_min(unsigned long tmin,
				unsigned long fsclk)
{
	unsigned long tmp ;
	unsigned short result;

	tmp = tmin * (fsclk/1000/1000) / 1000;
	result = (unsigned short)tmp;
	if ((tmp*1000*1000) < (tmin*(fsclk/1000))) {
		result++;
	}

	return result;
}

/**
 *	bfin_set_piomode - Initialize host controller PATA PIO timings
 *	@ap: Port whose timings we are configuring
 *	@adev: um
 *
 *	Set PIO mode for device.
 *
 *	LOCKING:
 *	None (inherited from caller).
 */

static void bfin_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
	int mode = adev->pio_mode - XFER_PIO_0;
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
	unsigned int fsclk = get_sclk();
	unsigned short teoc_reg, t2_reg, teoc_pio;
	unsigned short t4_reg, t2_pio, t1_reg;
	unsigned short n0, n6, t6min = 5;

	/* the most restrictive timing value is t6 and tc, the DIOW - data hold
	* If one SCLK pulse is longer than this minimum value then register
	* transfers cannot be supported at this frequency.
	*/
	n6 = num_clocks_min(t6min, fsclk);
	if (mode >= 0 && mode <= 4 && n6 >= 1) {
		pr_debug("set piomode: mode=%d, fsclk=%ud\n", mode, fsclk);
		/* calculate the timing values for register transfers. */
		while (mode > 0 && pio_fsclk[mode] > fsclk)
			mode--;

		/* DIOR/DIOW to end cycle time */
		t2_reg = num_clocks_min(reg_t2min[mode], fsclk);
		/* DIOR/DIOW asserted pulse width */
		teoc_reg = num_clocks_min(reg_teocmin[mode], fsclk);
		/* Cycle Time */
		n0  = num_clocks_min(reg_t0min[mode], fsclk);

		/* increase t2 until we meed the minimum cycle length */
		if (t2_reg + teoc_reg < n0)
			t2_reg = n0 - teoc_reg;

		/* calculate the timing values for pio transfers. */

		/* DIOR/DIOW to end cycle time */
		t2_pio = num_clocks_min(pio_t2min[mode], fsclk);
		/* DIOR/DIOW asserted pulse width */
		teoc_pio = num_clocks_min(pio_teocmin[mode], fsclk);
		/* Cycle Time */
		n0  = num_clocks_min(pio_t0min[mode], fsclk);

		/* increase t2 until we meed the minimum cycle length */
		if (t2_pio + teoc_pio < n0)
			t2_pio = n0 - teoc_pio;

		/* Address valid to DIOR/DIORW */
		t1_reg = num_clocks_min(pio_t1min[mode], fsclk);

		/* DIOW data hold */
		t4_reg = num_clocks_min(pio_t4min[mode], fsclk);

		ATAPI_SET_REG_TIM_0(base, (teoc_reg<<8 | t2_reg));
		ATAPI_SET_PIO_TIM_0(base, (t4_reg<<12 | t2_pio<<4 | t1_reg));
		ATAPI_SET_PIO_TIM_1(base, teoc_pio);
		if (mode > 2) {
			ATAPI_SET_CONTROL(base,
				ATAPI_GET_CONTROL(base) | IORDY_EN);
		} else {
			ATAPI_SET_CONTROL(base,
				ATAPI_GET_CONTROL(base) & ~IORDY_EN);
		}

		/* Disable host ATAPI PIO interrupts */
		ATAPI_SET_INT_MASK(base, ATAPI_GET_INT_MASK(base)
			& ~(PIO_DONE_MASK | HOST_TERM_XFER_MASK));
		SSYNC();
	}
}

/**
 *	bfin_set_dmamode - Initialize host controller PATA DMA timings
 *	@ap: Port whose timings we are configuring
 *	@adev: um
 *	@udma: udma mode, 0 - 6
 *
 *	Set UDMA mode for device.
 *
 *	LOCKING:
 *	None (inherited from caller).
 */

static void bfin_set_dmamode(struct ata_port *ap, struct ata_device *adev)
{
	int mode;
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
	unsigned long fsclk = get_sclk();
	unsigned short tenv, tack, tcyc_tdvs, tdvs, tmli, tss, trp, tzah;
	unsigned short tm, td, tkr, tkw, teoc, th;
	unsigned short n0, nf, tfmin = 5;
	unsigned short nmin, tcyc;

	mode = adev->dma_mode - XFER_UDMA_0;
	if (mode >= 0 && mode <= 5) {
		pr_debug("set udmamode: mode=%d\n", mode);
		/* the most restrictive timing value is t6 and tc,
		 * the DIOW - data hold. If one SCLK pulse is longer
		 * than this minimum value then register
		 * transfers cannot be supported at this frequency.
		 */
		while (mode > 0 && udma_fsclk[mode] > fsclk)
			mode--;

		nmin = num_clocks_min(udma_tmin[mode], fsclk);
		if (nmin >= 1) {
			/* calculate the timing values for Ultra DMA. */
			tdvs = num_clocks_min(udma_tdvsmin[mode], fsclk);
			tcyc = num_clocks_min(udma_tcycmin[mode], fsclk);
			tcyc_tdvs = 2;

			/* increase tcyc - tdvs (tcyc_tdvs) until we meed
			 * the minimum cycle length
			 */
			if (tdvs + tcyc_tdvs < tcyc)
				tcyc_tdvs = tcyc - tdvs;

			/* Mow assign the values required for the timing
			 * registers
			 */
			if (tcyc_tdvs < 2)
				tcyc_tdvs = 2;

			if (tdvs < 2)
				tdvs = 2;

			tack = num_clocks_min(udma_tackmin, fsclk);
			tss = num_clocks_min(udma_tssmin, fsclk);
			tmli = num_clocks_min(udma_tmlimin, fsclk);
			tzah = num_clocks_min(udma_tzahmin, fsclk);
			trp = num_clocks_min(udma_trpmin[mode], fsclk);
			tenv = num_clocks_min(udma_tenvmin, fsclk);
			if (tenv <= udma_tenvmax[mode]) {
				ATAPI_SET_ULTRA_TIM_0(base, (tenv<<8 | tack));
				ATAPI_SET_ULTRA_TIM_1(base,
					(tcyc_tdvs<<8 | tdvs));
				ATAPI_SET_ULTRA_TIM_2(base, (tmli<<8 | tss));
				ATAPI_SET_ULTRA_TIM_3(base, (trp<<8 | tzah));

				/* Enable host ATAPI Untra DMA interrupts */
				ATAPI_SET_INT_MASK(base,
					ATAPI_GET_INT_MASK(base)
					| UDMAIN_DONE_MASK
					| UDMAOUT_DONE_MASK
					| UDMAIN_TERM_MASK
					| UDMAOUT_TERM_MASK);
			}
		}
	}

	mode = adev->dma_mode - XFER_MW_DMA_0;
	if (mode >= 0 && mode <= 2) {
		pr_debug("set mdmamode: mode=%d\n", mode);
		/* the most restrictive timing value is tf, the DMACK to
		 * read data released. If one SCLK pulse is longer than
		 * this maximum value then the MDMA mode
		 * cannot be supported at this frequency.
		 */
		while (mode > 0 && mdma_fsclk[mode] > fsclk)
			mode--;

		nf = num_clocks_min(tfmin, fsclk);
		if (nf >= 1) {
			/* calculate the timing values for Multi-word DMA. */

			/* DIOR/DIOW asserted pulse width */
			td = num_clocks_min(mdma_tdmin[mode], fsclk);

			/* DIOR negated pulse width */
			tkw = num_clocks_min(mdma_tkwmin[mode], fsclk);

			/* Cycle Time */
			n0  = num_clocks_min(mdma_t0min[mode], fsclk);

			/* increase tk until we meed the minimum cycle length */
			if (tkw + td < n0)
				tkw = n0 - td;

			/* DIOR negated pulse width - read */
			tkr = num_clocks_min(mdma_tkrmin[mode], fsclk);
			/* CS{1:0] valid to DIOR/DIOW */
			tm = num_clocks_min(mdma_tmmin[mode], fsclk);
			/* DIOR/DIOW to DMACK hold */
			teoc = num_clocks_min(mdma_tjmin[mode], fsclk);
			/* DIOW Data hold */
			th = num_clocks_min(mdma_thmin[mode], fsclk);

			ATAPI_SET_MULTI_TIM_0(base, (tm<<8 | td));
			ATAPI_SET_MULTI_TIM_1(base, (tkr<<8 | tkw));
			ATAPI_SET_MULTI_TIM_2(base, (teoc<<8 | th));

			/* Enable host ATAPI Multi DMA interrupts */
			ATAPI_SET_INT_MASK(base, ATAPI_GET_INT_MASK(base)
				| MULTI_DONE_MASK | MULTI_TERM_MASK);
			SSYNC();
		}
	}
	return;
}

/**
 *
 *    Function:       wait_complete
 *
 *    Description:    Waits the interrupt from device
 *
 */
static inline void wait_complete(void __iomem *base, unsigned short mask)
{
	unsigned short status;
	unsigned int i = 0;

#define PATA_BF54X_WAIT_TIMEOUT		10000

	for (i = 0; i < PATA_BF54X_WAIT_TIMEOUT; i++) {
		status = ATAPI_GET_INT_STATUS(base) & mask;
		if (status)
			break;
	}

	ATAPI_SET_INT_STATUS(base, mask);
}

/**
 *
 *    Function:       write_atapi_register
 *
 *    Description:    Writes to ATA Device Resgister
 *
 */

static void write_atapi_register(void __iomem *base,
		unsigned long ata_reg, unsigned short value)
{
	/* Program the ATA_DEV_TXBUF register with write data (to be
	 * written into the device).
	 */
	ATAPI_SET_DEV_TXBUF(base, value);

	/* Program the ATA_DEV_ADDR register with address of the
	 * device register (0x01 to 0x0F).
	 */
	ATAPI_SET_DEV_ADDR(base, ata_reg);

	/* Program the ATA_CTRL register with dir set to write (1)
	 */
	ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) | XFER_DIR));

	/* ensure PIO DMA is not set */
	ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) & ~PIO_USE_DMA));

	/* and start the transfer */
	ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) | PIO_START));

	/* Wait for the interrupt to indicate the end of the transfer.
	 * (We need to wait on and clear rhe ATA_DEV_INT interrupt status)
	 */
	wait_complete(base, PIO_DONE_INT);
}

/**
 *
 *	Function:       read_atapi_register
 *
 *Description:    Reads from ATA Device Resgister
 *
 */

static unsigned short read_atapi_register(void __iomem *base,
		unsigned long ata_reg)
{
	/* Program the ATA_DEV_ADDR register with address of the
	 * device register (0x01 to 0x0F).
	 */
	ATAPI_SET_DEV_ADDR(base, ata_reg);

	/* Program the ATA_CTRL register with dir set to read (0) and
	 */
	ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) & ~XFER_DIR));

	/* ensure PIO DMA is not set */
	ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) & ~PIO_USE_DMA));

	/* and start the transfer */
	ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) | PIO_START));

	/* Wait for the interrupt to indicate the end of the transfer.
	 * (PIO_DONE interrupt is set and it doesn't seem to matter
	 * that we don't clear it)
	 */
	wait_complete(base, PIO_DONE_INT);

	/* Read the ATA_DEV_RXBUF register with write data (to be
	 * written into the device).
	 */
	return ATAPI_GET_DEV_RXBUF(base);
}

/**
 *
 *    Function:       write_atapi_register_data
 *
 *    Description:    Writes to ATA Device Resgister
 *
 */

static void write_atapi_data(void __iomem *base,
		int len, unsigned short *buf)
{
	int i;

	/* Set transfer length to 1 */
	ATAPI_SET_XFER_LEN(base, 1);

	/* Program the ATA_DEV_ADDR register with address of the
	 * ATA_REG_DATA
	 */
	ATAPI_SET_DEV_ADDR(base, ATA_REG_DATA);

	/* Program the ATA_CTRL register with dir set to write (1)
	 */
	ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) | XFER_DIR));

	/* ensure PIO DMA is not set */
	ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) & ~PIO_USE_DMA));

	for (i = 0; i < len; i++) {
		/* Program the ATA_DEV_TXBUF register with write data (to be
		 * written into the device).
		 */
		ATAPI_SET_DEV_TXBUF(base, buf[i]);

		/* and start the transfer */
		ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) | PIO_START));

		/* Wait for the interrupt to indicate the end of the transfer.
		 * (We need to wait on and clear rhe ATA_DEV_INT
		 * interrupt status)
		 */
		wait_complete(base, PIO_DONE_INT);
	}
}

/**
 *
 *	Function:       read_atapi_register_data
 *
 *	Description:    Reads from ATA Device Resgister
 *
 */

static void read_atapi_data(void __iomem *base,
		int len, unsigned short *buf)
{
	int i;

	/* Set transfer length to 1 */
	ATAPI_SET_XFER_LEN(base, 1);

	/* Program the ATA_DEV_ADDR register with address of the
	 * ATA_REG_DATA
	 */
	ATAPI_SET_DEV_ADDR(base, ATA_REG_DATA);

	/* Program the ATA_CTRL register with dir set to read (0) and
	 */
	ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) & ~XFER_DIR));

	/* ensure PIO DMA is not set */
	ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) & ~PIO_USE_DMA));

	for (i = 0; i < len; i++) {
		/* and start the transfer */
		ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base) | PIO_START));

		/* Wait for the interrupt to indicate the end of the transfer.
		 * (PIO_DONE interrupt is set and it doesn't seem to matter
		 * that we don't clear it)
		 */
		wait_complete(base, PIO_DONE_INT);

		/* Read the ATA_DEV_RXBUF register with write data (to be
		 * written into the device).
		 */
		buf[i] = ATAPI_GET_DEV_RXBUF(base);
	}
}

/**
 *	bfin_tf_load - send taskfile registers to host controller
 *	@ap: Port to which output is sent
 *	@tf: ATA taskfile register set
 *
 *	Note: Original code is ata_tf_load().
 */

static void bfin_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
{
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
	unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;

	if (tf->ctl != ap->last_ctl) {
		write_atapi_register(base, ATA_REG_CTRL, tf->ctl);
		ap->last_ctl = tf->ctl;
		ata_wait_idle(ap);
	}

	if (is_addr) {
		if (tf->flags & ATA_TFLAG_LBA48) {
			write_atapi_register(base, ATA_REG_FEATURE,
						tf->hob_feature);
			write_atapi_register(base, ATA_REG_NSECT,
						tf->hob_nsect);
			write_atapi_register(base, ATA_REG_LBAL, tf->hob_lbal);
			write_atapi_register(base, ATA_REG_LBAM, tf->hob_lbam);
			write_atapi_register(base, ATA_REG_LBAH, tf->hob_lbah);
			pr_debug("hob: feat 0x%X nsect 0x%X, lba 0x%X "
				 "0x%X 0x%X\n",
				tf->hob_feature,
				tf->hob_nsect,
				tf->hob_lbal,
				tf->hob_lbam,
				tf->hob_lbah);
		}

		write_atapi_register(base, ATA_REG_FEATURE, tf->feature);
		write_atapi_register(base, ATA_REG_NSECT, tf->nsect);
		write_atapi_register(base, ATA_REG_LBAL, tf->lbal);
		write_atapi_register(base, ATA_REG_LBAM, tf->lbam);
		write_atapi_register(base, ATA_REG_LBAH, tf->lbah);
		pr_debug("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n",
			tf->feature,
			tf->nsect,
			tf->lbal,
			tf->lbam,
			tf->lbah);
	}

	if (tf->flags & ATA_TFLAG_DEVICE) {
		write_atapi_register(base, ATA_REG_DEVICE, tf->device);
		pr_debug("device 0x%X\n", tf->device);
	}

	ata_wait_idle(ap);
}

/**
 *	bfin_check_status - Read device status reg & clear interrupt
 *	@ap: port where the device is
 *
 *	Note: Original code is ata_check_status().
 */

static u8 bfin_check_status(struct ata_port *ap)
{
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
	return read_atapi_register(base, ATA_REG_STATUS);
}

/**
 *	bfin_tf_read - input device's ATA taskfile shadow registers
 *	@ap: Port from which input is read
 *	@tf: ATA taskfile register set for storing input
 *
 *	Note: Original code is ata_tf_read().
 */

static void bfin_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
{
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;

	tf->command = bfin_check_status(ap);
	tf->feature = read_atapi_register(base, ATA_REG_ERR);
	tf->nsect = read_atapi_register(base, ATA_REG_NSECT);
	tf->lbal = read_atapi_register(base, ATA_REG_LBAL);
	tf->lbam = read_atapi_register(base, ATA_REG_LBAM);
	tf->lbah = read_atapi_register(base, ATA_REG_LBAH);
	tf->device = read_atapi_register(base, ATA_REG_DEVICE);

	if (tf->flags & ATA_TFLAG_LBA48) {
		write_atapi_register(base, ATA_REG_CTRL, tf->ctl | ATA_HOB);
		tf->hob_feature = read_atapi_register(base, ATA_REG_ERR);
		tf->hob_nsect = read_atapi_register(base, ATA_REG_NSECT);
		tf->hob_lbal = read_atapi_register(base, ATA_REG_LBAL);
		tf->hob_lbam = read_atapi_register(base, ATA_REG_LBAM);
		tf->hob_lbah = read_atapi_register(base, ATA_REG_LBAH);
	}
}

/**
 *	bfin_exec_command - issue ATA command to host controller
 *	@ap: port to which command is being issued
 *	@tf: ATA taskfile register set
 *
 *	Note: Original code is ata_exec_command().
 */

static void bfin_exec_command(struct ata_port *ap,
			      const struct ata_taskfile *tf)
{
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
	pr_debug("ata%u: cmd 0x%X\n", ap->print_id, tf->command);

	write_atapi_register(base, ATA_REG_CMD, tf->command);
	ata_pause(ap);
}

/**
 *	bfin_check_altstatus - Read device alternate status reg
 *	@ap: port where the device is
 */

static u8 bfin_check_altstatus(struct ata_port *ap)
{
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
	return read_atapi_register(base, ATA_REG_ALTSTATUS);
}

/**
 *	bfin_std_dev_select - Select device 0/1 on ATA bus
 *	@ap: ATA channel to manipulate
 *	@device: ATA device (numbered from zero) to select
 *
 *	Note: Original code is ata_std_dev_select().
 */

static void bfin_std_dev_select(struct ata_port *ap, unsigned int device)
{
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
	u8 tmp;

	if (device == 0)
		tmp = ATA_DEVICE_OBS;
	else
		tmp = ATA_DEVICE_OBS | ATA_DEV1;

	write_atapi_register(base, ATA_REG_DEVICE, tmp);
	ata_pause(ap);
}

/**
 *	bfin_bmdma_setup - Set up IDE DMA transaction
 *	@qc: Info associated with this ATA transaction.
 *
 *	Note: Original code is ata_bmdma_setup().
 */

static void bfin_bmdma_setup(struct ata_queued_cmd *qc)
{
	unsigned short config = WDSIZE_16;
	struct scatterlist *sg;

	pr_debug("in atapi dma setup\n");
	/* Program the ATA_CTRL register with dir */
	if (qc->tf.flags & ATA_TFLAG_WRITE) {
		/* fill the ATAPI DMA controller */
		set_dma_config(CH_ATAPI_TX, config);
		set_dma_x_modify(CH_ATAPI_TX, 2);
		ata_for_each_sg(sg, qc) {
			set_dma_start_addr(CH_ATAPI_TX, sg_dma_address(sg));
			set_dma_x_count(CH_ATAPI_TX, sg_dma_len(sg) >> 1);
		}
	} else {
		config |= WNR;
		/* fill the ATAPI DMA controller */
		set_dma_config(CH_ATAPI_RX, config);
		set_dma_x_modify(CH_ATAPI_RX, 2);
		ata_for_each_sg(sg, qc) {
			set_dma_start_addr(CH_ATAPI_RX, sg_dma_address(sg));
			set_dma_x_count(CH_ATAPI_RX, sg_dma_len(sg) >> 1);
		}
	}
}

/**
 *	bfin_bmdma_start - Start an IDE DMA transaction
 *	@qc: Info associated with this ATA transaction.
 *
 *	Note: Original code is ata_bmdma_start().
 */

static void bfin_bmdma_start(struct ata_queued_cmd *qc)
{
	struct ata_port *ap = qc->ap;
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
	struct scatterlist *sg;

	pr_debug("in atapi dma start\n");
	if (!(ap->udma_mask || ap->mwdma_mask))
		return;

	/* start ATAPI DMA controller*/
	if (qc->tf.flags & ATA_TFLAG_WRITE) {
		/*
		 * On blackfin arch, uncacheable memory is not
		 * allocated with flag GFP_DMA. DMA buffer from
		 * common kenel code should be flushed if WB
		 * data cache is enabled. Otherwise, this loop
		 * is an empty loop and optimized out.
		 */
		ata_for_each_sg(sg, qc) {
			flush_dcache_range(sg_dma_address(sg),
				sg_dma_address(sg) + sg_dma_len(sg));
		}
		enable_dma(CH_ATAPI_TX);
		pr_debug("enable udma write\n");

		/* Send ATA DMA write command */
		bfin_exec_command(ap, &qc->tf);

		/* set ATA DMA write direction */
		ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base)
			| XFER_DIR));
	} else {
		enable_dma(CH_ATAPI_RX);
		pr_debug("enable udma read\n");

		/* Send ATA DMA read command */
		bfin_exec_command(ap, &qc->tf);

		/* set ATA DMA read direction */
		ATAPI_SET_CONTROL(base, (ATAPI_GET_CONTROL(base)
			& ~XFER_DIR));
	}

	/* Reset all transfer count */
	ATAPI_SET_CONTROL(base, ATAPI_GET_CONTROL(base) | TFRCNT_RST);

		/* Set transfer length to buffer len */
	ata_for_each_sg(sg, qc) {
		ATAPI_SET_XFER_LEN(base, (sg_dma_len(sg) >> 1));
	}

	/* Enable ATA DMA operation*/
	if (ap->udma_mask)
		ATAPI_SET_CONTROL(base, ATAPI_GET_CONTROL(base)
			| ULTRA_START);
	else
		ATAPI_SET_CONTROL(base, ATAPI_GET_CONTROL(base)
			| MULTI_START);
}

/**
 *	bfin_bmdma_stop - Stop IDE DMA transfer
 *	@qc: Command we are ending DMA for
 */

static void bfin_bmdma_stop(struct ata_queued_cmd *qc)
{
	struct ata_port *ap = qc->ap;
	struct scatterlist *sg;

	pr_debug("in atapi dma stop\n");
	if (!(ap->udma_mask || ap->mwdma_mask))
		return;

	/* stop ATAPI DMA controller*/
	if (qc->tf.flags & ATA_TFLAG_WRITE)
		disable_dma(CH_ATAPI_TX);
	else {
		disable_dma(CH_ATAPI_RX);
		if (ap->hsm_task_state & HSM_ST_LAST) {
			/*
			 * On blackfin arch, uncacheable memory is not
			 * allocated with flag GFP_DMA. DMA buffer from
			 * common kenel code should be invalidated if
			 * data cache is enabled. Otherwise, this loop
			 * is an empty loop and optimized out.
			 */
			ata_for_each_sg(sg, qc) {
				invalidate_dcache_range(
					sg_dma_address(sg),
					sg_dma_address(sg)
					+ sg_dma_len(sg));
			}
		}
	}
}

/**
 *	bfin_devchk - PATA device presence detection
 *	@ap: ATA channel to examine
 *	@device: Device to examine (starting at zero)
 *
 *	Note: Original code is ata_devchk().
 */

static unsigned int bfin_devchk(struct ata_port *ap,
				unsigned int device)
{
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
	u8 nsect, lbal;

	bfin_std_dev_select(ap, device);

	write_atapi_register(base, ATA_REG_NSECT, 0x55);
	write_atapi_register(base, ATA_REG_LBAL, 0xaa);

	write_atapi_register(base, ATA_REG_NSECT, 0xaa);
	write_atapi_register(base, ATA_REG_LBAL, 0x55);

	write_atapi_register(base, ATA_REG_NSECT, 0x55);
	write_atapi_register(base, ATA_REG_LBAL, 0xaa);

	nsect = read_atapi_register(base, ATA_REG_NSECT);
	lbal = read_atapi_register(base, ATA_REG_LBAL);

	if ((nsect == 0x55) && (lbal == 0xaa))
		return 1;	/* we found a device */

	return 0;		/* nothing found */
}

/**
 *	bfin_bus_post_reset - PATA device post reset
 *
 *	Note: Original code is ata_bus_post_reset().
 */

static void bfin_bus_post_reset(struct ata_port *ap, unsigned int devmask)
{
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
	unsigned int dev0 = devmask & (1 << 0);
	unsigned int dev1 = devmask & (1 << 1);
	unsigned long timeout;

	/* if device 0 was found in ata_devchk, wait for its
	 * BSY bit to clear
	 */
	if (dev0)
		ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);

	/* if device 1 was found in ata_devchk, wait for
	 * register access, then wait for BSY to clear
	 */
	timeout = jiffies + ATA_TMOUT_BOOT;
	while (dev1) {
		u8 nsect, lbal;

		bfin_std_dev_select(ap, 1);
		nsect = read_atapi_register(base, ATA_REG_NSECT);
		lbal = read_atapi_register(base, ATA_REG_LBAL);
		if ((nsect == 1) && (lbal == 1))
			break;
		if (time_after(jiffies, timeout)) {
			dev1 = 0;
			break;
		}
		msleep(50);	/* give drive a breather */
	}
	if (dev1)
		ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);

	/* is all this really necessary? */
	bfin_std_dev_select(ap, 0);
	if (dev1)
		bfin_std_dev_select(ap, 1);
	if (dev0)
		bfin_std_dev_select(ap, 0);
}

/**
 *	bfin_bus_softreset - PATA device software reset
 *
 *	Note: Original code is ata_bus_softreset().
 */

static unsigned int bfin_bus_softreset(struct ata_port *ap,
				       unsigned int devmask)
{
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;

	/* software reset.  causes dev0 to be selected */
	write_atapi_register(base, ATA_REG_CTRL, ap->ctl);
	udelay(20);
	write_atapi_register(base, ATA_REG_CTRL, ap->ctl | ATA_SRST);
	udelay(20);
	write_atapi_register(base, ATA_REG_CTRL, ap->ctl);

	/* spec mandates ">= 2ms" before checking status.
	 * We wait 150ms, because that was the magic delay used for
	 * ATAPI devices in Hale Landis's ATADRVR, for the period of time
	 * between when the ATA command register is written, and then
	 * status is checked.  Because waiting for "a while" before
	 * checking status is fine, post SRST, we perform this magic
	 * delay here as well.
	 *
	 * Old drivers/ide uses the 2mS rule and then waits for ready
	 */
	msleep(150);

	/* Before we perform post reset processing we want to see if
	 * the bus shows 0xFF because the odd clown forgets the D7
	 * pulldown resistor.
	 */
	if (bfin_check_status(ap) == 0xFF)
		return 0;

	bfin_bus_post_reset(ap, devmask);

	return 0;
}

/**
 *	bfin_std_softreset - reset host port via ATA SRST
 *	@ap: port to reset
 *	@classes: resulting classes of attached devices
 *
 *	Note: Original code is ata_std_softreset().
 */

static int bfin_std_softreset(struct ata_link *link, unsigned int *classes,
		unsigned long deadline)
{
	struct ata_port *ap = link->ap;
	unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
	unsigned int devmask = 0, err_mask;
	u8 err;

	if (ata_link_offline(link)) {
		classes[0] = ATA_DEV_NONE;
		goto out;
	}

	/* determine if device 0/1 are present */
	if (bfin_devchk(ap, 0))
		devmask |= (1 << 0);
	if (slave_possible && bfin_devchk(ap, 1))
		devmask |= (1 << 1);

	/* select device 0 again */
	bfin_std_dev_select(ap, 0);

	/* issue bus reset */
	err_mask = bfin_bus_softreset(ap, devmask);
	if (err_mask) {
		ata_port_printk(ap, KERN_ERR, "SRST failed (err_mask=0x%x)\n",
				err_mask);
		return -EIO;
	}

	/* determine by signature whether we have ATA or ATAPI devices */
	classes[0] = ata_dev_try_classify(&ap->link.device[0],
				devmask & (1 << 0), &err);
	if (slave_possible && err != 0x81)
		classes[1] = ata_dev_try_classify(&ap->link.device[1],
					devmask & (1 << 1), &err);

 out:
	return 0;
}

/**
 *	bfin_bmdma_status - Read IDE DMA status
 *	@ap: Port associated with this ATA transaction.
 */

static unsigned char bfin_bmdma_status(struct ata_port *ap)
{
	unsigned char host_stat = 0;
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
	unsigned short int_status = ATAPI_GET_INT_STATUS(base);

	if (ATAPI_GET_STATUS(base) & (MULTI_XFER_ON|ULTRA_XFER_ON)) {
		host_stat |= ATA_DMA_ACTIVE;
	}
	if (int_status & (MULTI_DONE_INT|UDMAIN_DONE_INT|UDMAOUT_DONE_INT)) {
		host_stat |= ATA_DMA_INTR;
	}
	if (int_status & (MULTI_TERM_INT|UDMAIN_TERM_INT|UDMAOUT_TERM_INT)) {
		host_stat |= ATA_DMA_ERR;
	}

	return host_stat;
}

/**
 *	bfin_data_xfer - Transfer data by PIO
 *	@adev: device for this I/O
 *	@buf: data buffer
 *	@buflen: buffer length
 *	@write_data: read/write
 *
 *	Note: Original code is ata_data_xfer().
 */

static void bfin_data_xfer(struct ata_device *adev, unsigned char *buf,
			   unsigned int buflen, int write_data)
{
	struct ata_port *ap = adev->link->ap;
	unsigned int words = buflen >> 1;
	unsigned short *buf16 = (u16 *) buf;
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;

	/* Transfer multiple of 2 bytes */
	if (write_data) {
		write_atapi_data(base, words, buf16);
	} else {
		read_atapi_data(base, words, buf16);
	}

	/* Transfer trailing 1 byte, if any. */
	if (unlikely(buflen & 0x01)) {
		unsigned short align_buf[1] = { 0 };
		unsigned char *trailing_buf = buf + buflen - 1;

		if (write_data) {
			memcpy(align_buf, trailing_buf, 1);
			write_atapi_data(base, 1, align_buf);
		} else {
			read_atapi_data(base, 1, align_buf);
			memcpy(trailing_buf, align_buf, 1);
		}
	}
}

/**
 *	bfin_irq_clear - Clear ATAPI interrupt.
 *	@ap: Port associated with this ATA transaction.
 *
 *	Note: Original code is ata_bmdma_irq_clear().
 */

static void bfin_irq_clear(struct ata_port *ap)
{
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;

	pr_debug("in atapi irq clear\n");

	ATAPI_SET_INT_STATUS(base, ATAPI_GET_INT_STATUS(base)|ATAPI_DEV_INT
		| MULTI_DONE_INT | UDMAIN_DONE_INT | UDMAOUT_DONE_INT
		| MULTI_TERM_INT | UDMAIN_TERM_INT | UDMAOUT_TERM_INT);
}

/**
 *	bfin_irq_on - Enable interrupts on a port.
 *	@ap: Port on which interrupts are enabled.
 *
 *	Note: Original code is ata_irq_on().
 */

static unsigned char bfin_irq_on(struct ata_port *ap)
{
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
	u8 tmp;

	pr_debug("in atapi irq on\n");
	ap->ctl &= ~ATA_NIEN;
	ap->last_ctl = ap->ctl;

	write_atapi_register(base, ATA_REG_CTRL, ap->ctl);
	tmp = ata_wait_idle(ap);

	bfin_irq_clear(ap);

	return tmp;
}

/**
 *	bfin_bmdma_freeze - Freeze DMA controller port
 *	@ap: port to freeze
 *
 *	Note: Original code is ata_bmdma_freeze().
 */

static void bfin_bmdma_freeze(struct ata_port *ap)
{
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;

	pr_debug("in atapi dma freeze\n");
	ap->ctl |= ATA_NIEN;
	ap->last_ctl = ap->ctl;

	write_atapi_register(base, ATA_REG_CTRL, ap->ctl);

	/* Under certain circumstances, some controllers raise IRQ on
	 * ATA_NIEN manipulation.  Also, many controllers fail to mask
	 * previously pending IRQ on ATA_NIEN assertion.  Clear it.
	 */
	ata_chk_status(ap);

	bfin_irq_clear(ap);
}

/**
 *	bfin_bmdma_thaw - Thaw DMA controller port
 *	@ap: port to thaw
 *
 *	Note: Original code is ata_bmdma_thaw().
 */

void bfin_bmdma_thaw(struct ata_port *ap)
{
	bfin_check_status(ap);
	bfin_irq_clear(ap);
	bfin_irq_on(ap);
}

/**
 *	bfin_std_postreset - standard postreset callback
 *	@ap: the target ata_port
 *	@classes: classes of attached devices
 *
 *	Note: Original code is ata_std_postreset().
 */

static void bfin_std_postreset(struct ata_link *link, unsigned int *classes)
{
	struct ata_port *ap = link->ap;
	void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;

	/* re-enable interrupts */
	bfin_irq_on(ap);

	/* is double-select really necessary? */
	if (classes[0] != ATA_DEV_NONE)
		bfin_std_dev_select(ap, 1);
	if (classes[1] != ATA_DEV_NONE)
		bfin_std_dev_select(ap, 0);

	/* bail out if no device is present */
	if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) {
		return;
	}

	/* set up device control */
	write_atapi_register(base, ATA_REG_CTRL, ap->ctl);
}

/**
 *	bfin_error_handler - Stock error handler for DMA controller
 *	@ap: port to handle error for
 */

static void bfin_error_handler(struct ata_port *ap)
{
	ata_bmdma_drive_eh(ap, ata_std_prereset, bfin_std_softreset, NULL,
			   bfin_std_postreset);
}

static void bfin_port_stop(struct ata_port *ap)
{
	pr_debug("in atapi port stop\n");
	if (ap->udma_mask != 0 || ap->mwdma_mask != 0) {
		free_dma(CH_ATAPI_RX);
		free_dma(CH_ATAPI_TX);
	}
}

static int bfin_port_start(struct ata_port *ap)
{
	pr_debug("in atapi port start\n");
	if (!(ap->udma_mask || ap->mwdma_mask))
		return 0;

	if (request_dma(CH_ATAPI_RX, "BFIN ATAPI RX DMA") >= 0) {
		if (request_dma(CH_ATAPI_TX,
			"BFIN ATAPI TX DMA") >= 0)
			return 0;

		free_dma(CH_ATAPI_RX);
	}

	ap->udma_mask = 0;
	ap->mwdma_mask = 0;
	dev_err(ap->dev, "Unable to request ATAPI DMA!"
		" Continue in PIO mode.\n");

	return 0;
}

static struct scsi_host_template bfin_sht = {
	.module			= THIS_MODULE,
	.name			= DRV_NAME,
	.ioctl			= ata_scsi_ioctl,
	.queuecommand		= ata_scsi_queuecmd,
	.can_queue		= ATA_DEF_QUEUE,
	.this_id		= ATA_SHT_THIS_ID,
	.sg_tablesize		= SG_NONE,
	.cmd_per_lun		= ATA_SHT_CMD_PER_LUN,
	.emulated		= ATA_SHT_EMULATED,
	.use_clustering		= ATA_SHT_USE_CLUSTERING,
	.proc_name		= DRV_NAME,
	.dma_boundary		= ATA_DMA_BOUNDARY,
	.slave_configure	= ata_scsi_slave_config,
	.slave_destroy		= ata_scsi_slave_destroy,
	.bios_param		= ata_std_bios_param,
#ifdef CONFIG_PM
	.resume			= ata_scsi_device_resume,
	.suspend		= ata_scsi_device_suspend,
#endif
};

static const struct ata_port_operations bfin_pata_ops = {
	.set_piomode		= bfin_set_piomode,
	.set_dmamode		= bfin_set_dmamode,

	.tf_load		= bfin_tf_load,
	.tf_read		= bfin_tf_read,
	.exec_command		= bfin_exec_command,
	.check_status		= bfin_check_status,
	.check_altstatus	= bfin_check_altstatus,
	.dev_select		= bfin_std_dev_select,

	.bmdma_setup		= bfin_bmdma_setup,
	.bmdma_start		= bfin_bmdma_start,
	.bmdma_stop		= bfin_bmdma_stop,
	.bmdma_status		= bfin_bmdma_status,
	.data_xfer		= bfin_data_xfer,

	.qc_prep		= ata_noop_qc_prep,
	.qc_issue		= ata_qc_issue_prot,

	.freeze			= bfin_bmdma_freeze,
	.thaw			= bfin_bmdma_thaw,
	.error_handler		= bfin_error_handler,
	.post_internal_cmd	= bfin_bmdma_stop,

	.irq_handler		= ata_interrupt,
	.irq_clear		= bfin_irq_clear,
	.irq_on			= bfin_irq_on,

	.port_start		= bfin_port_start,
	.port_stop		= bfin_port_stop,
};

static struct ata_port_info bfin_port_info[] = {
	{
		.sht		= &bfin_sht,
		.flags		= ATA_FLAG_SLAVE_POSS
				| ATA_FLAG_MMIO
				| ATA_FLAG_NO_LEGACY,
		.pio_mask	= 0x1f,	/* pio0-4 */
		.mwdma_mask	= 0,
		.udma_mask	= 0,
		.port_ops	= &bfin_pata_ops,
	},
};

/**
 *	bfin_reset_controller - initialize BF54x ATAPI controller.
 */

static int bfin_reset_controller(struct ata_host *host)
{
	void __iomem *base = (void __iomem *)host->ports[0]->ioaddr.ctl_addr;
	int count;
	unsigned short status;

	/* Disable all ATAPI interrupts */
	ATAPI_SET_INT_MASK(base, 0);
	SSYNC();

	/* Assert the RESET signal 25us*/
	ATAPI_SET_CONTROL(base, ATAPI_GET_CONTROL(base) | DEV_RST);
	udelay(30);

	/* Negate the RESET signal for 2ms*/
	ATAPI_SET_CONTROL(base, ATAPI_GET_CONTROL(base) & ~DEV_RST);
	msleep(2);

	/* Wait on Busy flag to clear */
	count = 10000000;
	do {
		status = read_atapi_register(base, ATA_REG_STATUS);
	} while (count-- && (status & ATA_BUSY));

	/* Enable only ATAPI Device interrupt */
	ATAPI_SET_INT_MASK(base, 1);
	SSYNC();

	return (!count);
}

/**
 *	atapi_io_port - define atapi peripheral port pins.
 */
static unsigned short atapi_io_port[] = {
	P_ATAPI_RESET,
	P_ATAPI_DIOR,
	P_ATAPI_DIOW,
	P_ATAPI_CS0,
	P_ATAPI_CS1,
	P_ATAPI_DMACK,
	P_ATAPI_DMARQ,
	P_ATAPI_INTRQ,
	P_ATAPI_IORDY,
	0
};

/**
 *	bfin_atapi_probe	-	attach a bfin atapi interface
 *	@pdev: platform device
 *
 *	Register a bfin atapi interface.
 *
 *
 *	Platform devices are expected to contain 2 resources per port:
 *
 *		- I/O Base (IORESOURCE_IO)
 *		- IRQ	   (IORESOURCE_IRQ)
 *
 */
static int __devinit bfin_atapi_probe(struct platform_device *pdev)
{
	int board_idx = 0;
	struct resource *res;
	struct ata_host *host;
	unsigned int fsclk = get_sclk();
	int udma_mode = 5;
	const struct ata_port_info *ppi[] =
		{ &bfin_port_info[board_idx], NULL };

	/*
	 * Simple resource validation ..
	 */
	if (unlikely(pdev->num_resources != 2)) {
		dev_err(&pdev->dev, "invalid number of resources\n");
		return -EINVAL;
	}

	/*
	 * Get the register base first
	 */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL)
		return -EINVAL;

	while (bfin_port_info[board_idx].udma_mask>0 && udma_fsclk[udma_mode] > fsclk) {
		udma_mode--;
		bfin_port_info[board_idx].udma_mask >>= 1;
	}

	/*
	 * Now that that's out of the way, wire up the port..
	 */
	host = ata_host_alloc_pinfo(&pdev->dev, ppi, 1);
	if (!host)
		return -ENOMEM;

	host->ports[0]->ioaddr.ctl_addr = (void *)res->start;

	if (peripheral_request_list(atapi_io_port, "atapi-io-port")) {
		dev_err(&pdev->dev, "Requesting Peripherals faild\n");
		return -EFAULT;
	}

	if (bfin_reset_controller(host)) {
		peripheral_free_list(atapi_io_port);
		dev_err(&pdev->dev, "Fail to reset ATAPI device\n");
		return -EFAULT;
	}

	if (ata_host_activate(host, platform_get_irq(pdev, 0),
		ata_interrupt, IRQF_SHARED, &bfin_sht) != 0) {
		peripheral_free_list(atapi_io_port);
		dev_err(&pdev->dev, "Fail to attach ATAPI device\n");
		return -ENODEV;
	}

	return 0;
}

/**
 *	bfin_atapi_remove	-	unplug a bfin atapi interface
 *	@pdev: platform device
 *
 *	A bfin atapi device has been unplugged. Perform the needed
 *	cleanup. Also called on module unload for any active devices.
 */
static int __devexit bfin_atapi_remove(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct ata_host *host = dev_get_drvdata(dev);

	ata_host_detach(host);

	peripheral_free_list(atapi_io_port);

	return 0;
}

#ifdef CONFIG_PM
int bfin_atapi_suspend(struct platform_device *pdev, pm_message_t state)
{
	return 0;
}

int bfin_atapi_resume(struct platform_device *pdev)
{
	return 0;
}
#endif

static struct platform_driver bfin_atapi_driver = {
	.probe			= bfin_atapi_probe,
	.remove			= __devexit_p(bfin_atapi_remove),
	.driver = {
		.name		= DRV_NAME,
		.owner		= THIS_MODULE,
#ifdef CONFIG_PM
		.suspend	= bfin_atapi_suspend,
		.resume		= bfin_atapi_resume,
#endif
	},
};

#define ATAPI_MODE_SIZE		10
static char bfin_atapi_mode[ATAPI_MODE_SIZE];

static int __init bfin_atapi_init(void)
{
	pr_info("register bfin atapi driver\n");

	switch(bfin_atapi_mode[0]) {
	case 'p':
	case 'P':
		break;
	case 'm':
	case 'M':
		bfin_port_info[0].mwdma_mask = ATA_MWDMA2;
		break;
	default:
		bfin_port_info[0].udma_mask = ATA_UDMA5;
	};

	return platform_driver_register(&bfin_atapi_driver);
}

static void __exit bfin_atapi_exit(void)
{
	platform_driver_unregister(&bfin_atapi_driver);
}

module_init(bfin_atapi_init);
module_exit(bfin_atapi_exit);
/*
 * ATAPI mode:
 * pio/PIO
 * udma/UDMA (default)
 * mwdma/MWDMA
 */
module_param_string(bfin_atapi_mode, bfin_atapi_mode, ATAPI_MODE_SIZE, 0);

MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
MODULE_DESCRIPTION("PATA driver for blackfin 54x ATAPI controller");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
