/*
 * Copyright © 2009 - Maxim Levitsky
 * driver for Ricoh xD readers
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/jiffies.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <asm/byteorder.h>
#include <linux/sched.h>
#include "sm_common.h"
#include "r852.h"


static bool r852_enable_dma = 1;
module_param(r852_enable_dma, bool, S_IRUGO);
MODULE_PARM_DESC(r852_enable_dma, "Enable usage of the DMA (default)");

static int debug;
module_param(debug, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug level (0-2)");

/* read register */
static inline uint8_t r852_read_reg(struct r852_device *dev, int address)
{
	uint8_t reg = readb(dev->mmio + address);
	return reg;
}

/* write register */
static inline void r852_write_reg(struct r852_device *dev,
						int address, uint8_t value)
{
	writeb(value, dev->mmio + address);
	mmiowb();
}


/* read dword sized register */
static inline uint32_t r852_read_reg_dword(struct r852_device *dev, int address)
{
	uint32_t reg = le32_to_cpu(readl(dev->mmio + address));
	return reg;
}

/* write dword sized register */
static inline void r852_write_reg_dword(struct r852_device *dev,
							int address, uint32_t value)
{
	writel(cpu_to_le32(value), dev->mmio + address);
	mmiowb();
}

/* returns pointer to our private structure */
static inline struct r852_device *r852_get_dev(struct mtd_info *mtd)
{
	struct nand_chip *chip = mtd->priv;
	return chip->priv;
}


/* check if controller supports dma */
static void r852_dma_test(struct r852_device *dev)
{
	dev->dma_usable = (r852_read_reg(dev, R852_DMA_CAP) &
		(R852_DMA1 | R852_DMA2)) == (R852_DMA1 | R852_DMA2);

	if (!dev->dma_usable)
		message("Non dma capable device detected, dma disabled");

	if (!r852_enable_dma) {
		message("disabling dma on user request");
		dev->dma_usable = 0;
	}
}

/*
 * Enable dma. Enables ether first or second stage of the DMA,
 * Expects dev->dma_dir and dev->dma_state be set
 */
static void r852_dma_enable(struct r852_device *dev)
{
	uint8_t dma_reg, dma_irq_reg;

	/* Set up dma settings */
	dma_reg = r852_read_reg_dword(dev, R852_DMA_SETTINGS);
	dma_reg &= ~(R852_DMA_READ | R852_DMA_INTERNAL | R852_DMA_MEMORY);

	if (dev->dma_dir)
		dma_reg |= R852_DMA_READ;

	if (dev->dma_state == DMA_INTERNAL) {
		dma_reg |= R852_DMA_INTERNAL;
		/* Precaution to make sure HW doesn't write */
			/* to random kernel memory */
		r852_write_reg_dword(dev, R852_DMA_ADDR,
			cpu_to_le32(dev->phys_bounce_buffer));
	} else {
		dma_reg |= R852_DMA_MEMORY;
		r852_write_reg_dword(dev, R852_DMA_ADDR,
			cpu_to_le32(dev->phys_dma_addr));
	}

	/* Precaution: make sure write reached the device */
	r852_read_reg_dword(dev, R852_DMA_ADDR);

	r852_write_reg_dword(dev, R852_DMA_SETTINGS, dma_reg);

	/* Set dma irq */
	dma_irq_reg = r852_read_reg_dword(dev, R852_DMA_IRQ_ENABLE);
	r852_write_reg_dword(dev, R852_DMA_IRQ_ENABLE,
		dma_irq_reg |
		R852_DMA_IRQ_INTERNAL |
		R852_DMA_IRQ_ERROR |
		R852_DMA_IRQ_MEMORY);
}

/*
 * Disable dma, called from the interrupt handler, which specifies
 * success of the operation via 'error' argument
 */
static void r852_dma_done(struct r852_device *dev, int error)
{
	WARN_ON(dev->dma_stage == 0);

	r852_write_reg_dword(dev, R852_DMA_IRQ_STA,
			r852_read_reg_dword(dev, R852_DMA_IRQ_STA));

	r852_write_reg_dword(dev, R852_DMA_SETTINGS, 0);
	r852_write_reg_dword(dev, R852_DMA_IRQ_ENABLE, 0);

	/* Precaution to make sure HW doesn't write to random kernel memory */
	r852_write_reg_dword(dev, R852_DMA_ADDR,
		cpu_to_le32(dev->phys_bounce_buffer));
	r852_read_reg_dword(dev, R852_DMA_ADDR);

	dev->dma_error = error;
	dev->dma_stage = 0;

	if (dev->phys_dma_addr && dev->phys_dma_addr != dev->phys_bounce_buffer)
		pci_unmap_single(dev->pci_dev, dev->phys_dma_addr, R852_DMA_LEN,
			dev->dma_dir ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
}

/*
 * Wait, till dma is done, which includes both phases of it
 */
static int r852_dma_wait(struct r852_device *dev)
{
	long timeout = wait_for_completion_timeout(&dev->dma_done,
				msecs_to_jiffies(1000));
	if (!timeout) {
		dbg("timeout waiting for DMA interrupt");
		return -ETIMEDOUT;
	}

	return 0;
}

/*
 * Read/Write one page using dma. Only pages can be read (512 bytes)
*/
static void r852_do_dma(struct r852_device *dev, uint8_t *buf, int do_read)
{
	int bounce = 0;
	unsigned long flags;
	int error;

	dev->dma_error = 0;

	/* Set dma direction */
	dev->dma_dir = do_read;
	dev->dma_stage = 1;
	INIT_COMPLETION(dev->dma_done);

	dbg_verbose("doing dma %s ", do_read ? "read" : "write");

	/* Set initial dma state: for reading first fill on board buffer,
	  from device, for writes first fill the buffer  from memory*/
	dev->dma_state = do_read ? DMA_INTERNAL : DMA_MEMORY;

	/* if incoming buffer is not page aligned, we should do bounce */
	if ((unsigned long)buf & (R852_DMA_LEN-1))
		bounce = 1;

	if (!bounce) {
		dev->phys_dma_addr = pci_map_single(dev->pci_dev, (void *)buf,
			R852_DMA_LEN,
			(do_read ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE));

		if (pci_dma_mapping_error(dev->pci_dev, dev->phys_dma_addr))
			bounce = 1;
	}

	if (bounce) {
		dbg_verbose("dma: using bounce buffer");
		dev->phys_dma_addr = dev->phys_bounce_buffer;
		if (!do_read)
			memcpy(dev->bounce_buffer, buf, R852_DMA_LEN);
	}

	/* Enable DMA */
	spin_lock_irqsave(&dev->irqlock, flags);
	r852_dma_enable(dev);
	spin_unlock_irqrestore(&dev->irqlock, flags);

	/* Wait till complete */
	error = r852_dma_wait(dev);

	if (error) {
		r852_dma_done(dev, error);
		return;
	}

	if (do_read && bounce)
		memcpy((void *)buf, dev->bounce_buffer, R852_DMA_LEN);
}

/*
 * Program data lines of the nand chip to send data to it
 */
void r852_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
{
	struct r852_device *dev = r852_get_dev(mtd);
	uint32_t reg;

	/* Don't allow any access to hardware if we suspect card removal */
	if (dev->card_unstable)
		return;

	/* Special case for whole sector read */
	if (len == R852_DMA_LEN && dev->dma_usable) {
		r852_do_dma(dev, (uint8_t *)buf, 0);
		return;
	}

	/* write DWORD chinks - faster */
	while (len) {
		reg = buf[0] | buf[1] << 8 | buf[2] << 16 | buf[3] << 24;
		r852_write_reg_dword(dev, R852_DATALINE, reg);
		buf += 4;
		len -= 4;

	}

	/* write rest */
	while (len)
		r852_write_reg(dev, R852_DATALINE, *buf++);
}

/*
 * Read data lines of the nand chip to retrieve data
 */
void r852_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
{
	struct r852_device *dev = r852_get_dev(mtd);
	uint32_t reg;

	if (dev->card_unstable) {
		/* since we can't signal error here, at least, return
			predictable buffer */
		memset(buf, 0, len);
		return;
	}

	/* special case for whole sector read */
	if (len == R852_DMA_LEN && dev->dma_usable) {
		r852_do_dma(dev, buf, 1);
		return;
	}

	/* read in dword sized chunks */
	while (len >= 4) {

		reg = r852_read_reg_dword(dev, R852_DATALINE);
		*buf++ = reg & 0xFF;
		*buf++ = (reg >> 8) & 0xFF;
		*buf++ = (reg >> 16) & 0xFF;
		*buf++ = (reg >> 24) & 0xFF;
		len -= 4;
	}

	/* read the reset by bytes */
	while (len--)
		*buf++ = r852_read_reg(dev, R852_DATALINE);
}

/*
 * Read one byte from nand chip
 */
static uint8_t r852_read_byte(struct mtd_info *mtd)
{
	struct r852_device *dev = r852_get_dev(mtd);

	/* Same problem as in r852_read_buf.... */
	if (dev->card_unstable)
		return 0;

	return r852_read_reg(dev, R852_DATALINE);
}


/*
 * Readback the buffer to verify it
 */
int r852_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
{
	struct r852_device *dev = r852_get_dev(mtd);

	/* We can't be sure about anything here... */
	if (dev->card_unstable)
		return -1;

	/* This will never happen, unless you wired up a nand chip
		with > 512 bytes page size to the reader */
	if (len > SM_SECTOR_SIZE)
		return 0;

	r852_read_buf(mtd, dev->tmp_buffer, len);
	return memcmp(buf, dev->tmp_buffer, len);
}

/*
 * Control several chip lines & send commands
 */
void r852_cmdctl(struct mtd_info *mtd, int dat, unsigned int ctrl)
{
	struct r852_device *dev = r852_get_dev(mtd);

	if (dev->card_unstable)
		return;

	if (ctrl & NAND_CTRL_CHANGE) {

		dev->ctlreg &= ~(R852_CTL_DATA | R852_CTL_COMMAND |
				 R852_CTL_ON | R852_CTL_CARDENABLE);

		if (ctrl & NAND_ALE)
			dev->ctlreg |= R852_CTL_DATA;

		if (ctrl & NAND_CLE)
			dev->ctlreg |= R852_CTL_COMMAND;

		if (ctrl & NAND_NCE)
			dev->ctlreg |= (R852_CTL_CARDENABLE | R852_CTL_ON);
		else
			dev->ctlreg &= ~R852_CTL_WRITE;

		/* when write is stareted, enable write access */
		if (dat == NAND_CMD_ERASE1)
			dev->ctlreg |= R852_CTL_WRITE;

		r852_write_reg(dev, R852_CTL, dev->ctlreg);
	}

	 /* HACK: NAND_CMD_SEQIN is called without NAND_CTRL_CHANGE, but we need
		to set write mode */
	if (dat == NAND_CMD_SEQIN && (dev->ctlreg & R852_CTL_COMMAND)) {
		dev->ctlreg |= R852_CTL_WRITE;
		r852_write_reg(dev, R852_CTL, dev->ctlreg);
	}

	if (dat != NAND_CMD_NONE)
		r852_write_reg(dev, R852_DATALINE, dat);
}

/*
 * Wait till card is ready.
 * based on nand_wait, but returns errors on DMA error
 */
int r852_wait(struct mtd_info *mtd, struct nand_chip *chip)
{
	struct r852_device *dev = chip->priv;

	unsigned long timeout;
	int status;

	timeout = jiffies + (chip->state == FL_ERASING ?
		msecs_to_jiffies(400) : msecs_to_jiffies(20));

	while (time_before(jiffies, timeout))
		if (chip->dev_ready(mtd))
			break;

	chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
	status = (int)chip->read_byte(mtd);

	/* Unfortunelly, no way to send detailed error status... */
	if (dev->dma_error) {
		status |= NAND_STATUS_FAIL;
		dev->dma_error = 0;
	}
	return status;
}

/*
 * Check if card is ready
 */

int r852_ready(struct mtd_info *mtd)
{
	struct r852_device *dev = r852_get_dev(mtd);
	return !(r852_read_reg(dev, R852_CARD_STA) & R852_CARD_STA_BUSY);
}


/*
 * Set ECC engine mode
*/

void r852_ecc_hwctl(struct mtd_info *mtd, int mode)
{
	struct r852_device *dev = r852_get_dev(mtd);

	if (dev->card_unstable)
		return;

	switch (mode) {
	case NAND_ECC_READ:
	case NAND_ECC_WRITE:
		/* enable ecc generation/check*/
		dev->ctlreg |= R852_CTL_ECC_ENABLE;

		/* flush ecc buffer */
		r852_write_reg(dev, R852_CTL,
			dev->ctlreg | R852_CTL_ECC_ACCESS);

		r852_read_reg_dword(dev, R852_DATALINE);
		r852_write_reg(dev, R852_CTL, dev->ctlreg);
		return;

	case NAND_ECC_READSYN:
		/* disable ecc generation */
		dev->ctlreg &= ~R852_CTL_ECC_ENABLE;
		r852_write_reg(dev, R852_CTL, dev->ctlreg);
	}
}

/*
 * Calculate ECC, only used for writes
 */

int r852_ecc_calculate(struct mtd_info *mtd, const uint8_t *dat,
							uint8_t *ecc_code)
{
	struct r852_device *dev = r852_get_dev(mtd);
	struct sm_oob *oob = (struct sm_oob *)ecc_code;
	uint32_t ecc1, ecc2;

	if (dev->card_unstable)
		return 0;

	dev->ctlreg &= ~R852_CTL_ECC_ENABLE;
	r852_write_reg(dev, R852_CTL, dev->ctlreg | R852_CTL_ECC_ACCESS);

	ecc1 = r852_read_reg_dword(dev, R852_DATALINE);
	ecc2 = r852_read_reg_dword(dev, R852_DATALINE);

	oob->ecc1[0] = (ecc1) & 0xFF;
	oob->ecc1[1] = (ecc1 >> 8) & 0xFF;
	oob->ecc1[2] = (ecc1 >> 16) & 0xFF;

	oob->ecc2[0] = (ecc2) & 0xFF;
	oob->ecc2[1] = (ecc2 >> 8) & 0xFF;
	oob->ecc2[2] = (ecc2 >> 16) & 0xFF;

	r852_write_reg(dev, R852_CTL, dev->ctlreg);
	return 0;
}

/*
 * Correct the data using ECC, hw did almost everything for us
 */

int r852_ecc_correct(struct mtd_info *mtd, uint8_t *dat,
				uint8_t *read_ecc, uint8_t *calc_ecc)
{
	uint16_t ecc_reg;
	uint8_t ecc_status, err_byte;
	int i, error = 0;

	struct r852_device *dev = r852_get_dev(mtd);

	if (dev->card_unstable)
		return 0;

	if (dev->dma_error) {
		dev->dma_error = 0;
		return -1;
	}

	r852_write_reg(dev, R852_CTL, dev->ctlreg | R852_CTL_ECC_ACCESS);
	ecc_reg = r852_read_reg_dword(dev, R852_DATALINE);
	r852_write_reg(dev, R852_CTL, dev->ctlreg);

	for (i = 0 ; i <= 1 ; i++) {

		ecc_status = (ecc_reg >> 8) & 0xFF;

		/* ecc uncorrectable error */
		if (ecc_status & R852_ECC_FAIL) {
			dbg("ecc: unrecoverable error, in half %d", i);
			error = -1;
			goto exit;
		}

		/* correctable error */
		if (ecc_status & R852_ECC_CORRECTABLE) {

			err_byte = ecc_reg & 0xFF;
			dbg("ecc: recoverable error, "
				"in half %d, byte %d, bit %d", i,
				err_byte, ecc_status & R852_ECC_ERR_BIT_MSK);

			dat[err_byte] ^=
				1 << (ecc_status & R852_ECC_ERR_BIT_MSK);
			error++;
		}

		dat += 256;
		ecc_reg >>= 16;
	}
exit:
	return error;
}

/*
 * This is copy of nand_read_oob_std
 * nand_read_oob_syndrome assumes we can send column address - we can't
 */
static int r852_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
			     int page, int sndcmd)
{
	if (sndcmd) {
		chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
		sndcmd = 0;
	}
	chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
	return sndcmd;
}

/*
 * Start the nand engine
 */

void r852_engine_enable(struct r852_device *dev)
{
	if (r852_read_reg_dword(dev, R852_HW) & R852_HW_UNKNOWN) {
		r852_write_reg(dev, R852_CTL, R852_CTL_RESET | R852_CTL_ON);
		r852_write_reg_dword(dev, R852_HW, R852_HW_ENABLED);
	} else {
		r852_write_reg_dword(dev, R852_HW, R852_HW_ENABLED);
		r852_write_reg(dev, R852_CTL, R852_CTL_RESET | R852_CTL_ON);
	}
	msleep(300);
	r852_write_reg(dev, R852_CTL, 0);
}


/*
 * Stop the nand engine
 */

void r852_engine_disable(struct r852_device *dev)
{
	r852_write_reg_dword(dev, R852_HW, 0);
	r852_write_reg(dev, R852_CTL, R852_CTL_RESET);
}

/*
 * Test if card is present
 */

void r852_card_update_present(struct r852_device *dev)
{
	unsigned long flags;
	uint8_t reg;

	spin_lock_irqsave(&dev->irqlock, flags);
	reg = r852_read_reg(dev, R852_CARD_STA);
	dev->card_detected = !!(reg & R852_CARD_STA_PRESENT);
	spin_unlock_irqrestore(&dev->irqlock, flags);
}

/*
 * Update card detection IRQ state according to current card state
 * which is read in r852_card_update_present
 */
void r852_update_card_detect(struct r852_device *dev)
{
	int card_detect_reg = r852_read_reg(dev, R852_CARD_IRQ_ENABLE);
	dev->card_unstable = 0;

	card_detect_reg &= ~(R852_CARD_IRQ_REMOVE | R852_CARD_IRQ_INSERT);
	card_detect_reg |= R852_CARD_IRQ_GENABLE;

	card_detect_reg |= dev->card_detected ?
		R852_CARD_IRQ_REMOVE : R852_CARD_IRQ_INSERT;

	r852_write_reg(dev, R852_CARD_IRQ_ENABLE, card_detect_reg);
}

ssize_t r852_media_type_show(struct device *sys_dev,
		struct device_attribute *attr, char *buf)
{
	struct mtd_info *mtd = container_of(sys_dev, struct mtd_info, dev);
	struct r852_device *dev = r852_get_dev(mtd);
	char *data = dev->sm ? "smartmedia" : "xd";

	strcpy(buf, data);
	return strlen(data);
}

DEVICE_ATTR(media_type, S_IRUGO, r852_media_type_show, NULL);


/* Detect properties of card in slot */
void r852_update_media_status(struct r852_device *dev)
{
	uint8_t reg;
	unsigned long flags;
	int readonly;

	spin_lock_irqsave(&dev->irqlock, flags);
	if (!dev->card_detected) {
		message("card removed");
		spin_unlock_irqrestore(&dev->irqlock, flags);
		return ;
	}

	readonly  = r852_read_reg(dev, R852_CARD_STA) & R852_CARD_STA_RO;
	reg = r852_read_reg(dev, R852_DMA_CAP);
	dev->sm = (reg & (R852_DMA1 | R852_DMA2)) && (reg & R852_SMBIT);

	message("detected %s %s card in slot",
		dev->sm ? "SmartMedia" : "xD",
		readonly ? "readonly" : "writeable");

	dev->readonly = readonly;
	spin_unlock_irqrestore(&dev->irqlock, flags);
}

/*
 * Register the nand device
 * Called when the card is detected
 */
int r852_register_nand_device(struct r852_device *dev)
{
	dev->mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL);

	if (!dev->mtd)
		goto error1;

	WARN_ON(dev->card_registred);

	dev->mtd->owner = THIS_MODULE;
	dev->mtd->priv = dev->chip;
	dev->mtd->dev.parent = &dev->pci_dev->dev;

	if (dev->readonly)
		dev->chip->options |= NAND_ROM;

	r852_engine_enable(dev);

	if (sm_register_device(dev->mtd, dev->sm))
		goto error2;

	if (device_create_file(&dev->mtd->dev, &dev_attr_media_type))
		message("can't create media type sysfs attribute");

	dev->card_registred = 1;
	return 0;
error2:
	kfree(dev->mtd);
error1:
	/* Force card redetect */
	dev->card_detected = 0;
	return -1;
}

/*
 * Unregister the card
 */

void r852_unregister_nand_device(struct r852_device *dev)
{
	if (!dev->card_registred)
		return;

	device_remove_file(&dev->mtd->dev, &dev_attr_media_type);
	nand_release(dev->mtd);
	r852_engine_disable(dev);
	dev->card_registred = 0;
	kfree(dev->mtd);
	dev->mtd = NULL;
}

/* Card state updater */
void r852_card_detect_work(struct work_struct *work)
{
	struct r852_device *dev =
		container_of(work, struct r852_device, card_detect_work.work);

	r852_card_update_present(dev);
	r852_update_card_detect(dev);
	dev->card_unstable = 0;

	/* False alarm */
	if (dev->card_detected == dev->card_registred)
		goto exit;

	/* Read media properties */
	r852_update_media_status(dev);

	/* Register the card */
	if (dev->card_detected)
		r852_register_nand_device(dev);
	else
		r852_unregister_nand_device(dev);
exit:
	r852_update_card_detect(dev);
}

/* Ack + disable IRQ generation */
static void r852_disable_irqs(struct r852_device *dev)
{
	uint8_t reg;
	reg = r852_read_reg(dev, R852_CARD_IRQ_ENABLE);
	r852_write_reg(dev, R852_CARD_IRQ_ENABLE, reg & ~R852_CARD_IRQ_MASK);

	reg = r852_read_reg_dword(dev, R852_DMA_IRQ_ENABLE);
	r852_write_reg_dword(dev, R852_DMA_IRQ_ENABLE,
					reg & ~R852_DMA_IRQ_MASK);

	r852_write_reg(dev, R852_CARD_IRQ_STA, R852_CARD_IRQ_MASK);
	r852_write_reg_dword(dev, R852_DMA_IRQ_STA, R852_DMA_IRQ_MASK);
}

/* Interrupt handler */
static irqreturn_t r852_irq(int irq, void *data)
{
	struct r852_device *dev = (struct r852_device *)data;

	uint8_t card_status, dma_status;
	unsigned long flags;
	irqreturn_t ret = IRQ_NONE;

	spin_lock_irqsave(&dev->irqlock, flags);

	/* handle card detection interrupts first */
	card_status = r852_read_reg(dev, R852_CARD_IRQ_STA);
	r852_write_reg(dev, R852_CARD_IRQ_STA, card_status);

	if (card_status & (R852_CARD_IRQ_INSERT|R852_CARD_IRQ_REMOVE)) {

		ret = IRQ_HANDLED;
		dev->card_detected = !!(card_status & R852_CARD_IRQ_INSERT);

		/* we shouldn't receive any interrupts if we wait for card
			to settle */
		WARN_ON(dev->card_unstable);

		/* disable irqs while card is unstable */
		/* this will timeout DMA if active, but better that garbage */
		r852_disable_irqs(dev);

		if (dev->card_unstable)
			goto out;

		/* let, card state to settle a bit, and then do the work */
		dev->card_unstable = 1;
		queue_delayed_work(dev->card_workqueue,
			&dev->card_detect_work, msecs_to_jiffies(100));
		goto out;
	}


	/* Handle dma interrupts */
	dma_status = r852_read_reg_dword(dev, R852_DMA_IRQ_STA);
	r852_write_reg_dword(dev, R852_DMA_IRQ_STA, dma_status);

	if (dma_status & R852_DMA_IRQ_MASK) {

		ret = IRQ_HANDLED;

		if (dma_status & R852_DMA_IRQ_ERROR) {
			dbg("received dma error IRQ");
			r852_dma_done(dev, -EIO);
			complete(&dev->dma_done);
			goto out;
		}

		/* received DMA interrupt out of nowhere? */
		WARN_ON_ONCE(dev->dma_stage == 0);

		if (dev->dma_stage == 0)
			goto out;

		/* done device access */
		if (dev->dma_state == DMA_INTERNAL &&
				(dma_status & R852_DMA_IRQ_INTERNAL)) {

			dev->dma_state = DMA_MEMORY;
			dev->dma_stage++;
		}

		/* done memory DMA */
		if (dev->dma_state == DMA_MEMORY &&
				(dma_status & R852_DMA_IRQ_MEMORY)) {
			dev->dma_state = DMA_INTERNAL;
			dev->dma_stage++;
		}

		/* Enable 2nd half of dma dance */
		if (dev->dma_stage == 2)
			r852_dma_enable(dev);

		/* Operation done */
		if (dev->dma_stage == 3) {
			r852_dma_done(dev, 0);
			complete(&dev->dma_done);
		}
		goto out;
	}

	/* Handle unknown interrupts */
	if (dma_status)
		dbg("bad dma IRQ status = %x", dma_status);

	if (card_status & ~R852_CARD_STA_CD)
		dbg("strange card status = %x", card_status);

out:
	spin_unlock_irqrestore(&dev->irqlock, flags);
	return ret;
}

int  r852_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
{
	int error;
	struct nand_chip *chip;
	struct r852_device *dev;

	/* pci initialization */
	error = pci_enable_device(pci_dev);

	if (error)
		goto error1;

	pci_set_master(pci_dev);

	error = pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32));
	if (error)
		goto error2;

	error = pci_request_regions(pci_dev, DRV_NAME);

	if (error)
		goto error3;

	error = -ENOMEM;

	/* init nand chip, but register it only on card insert */
	chip = kzalloc(sizeof(struct nand_chip), GFP_KERNEL);

	if (!chip)
		goto error4;

	/* commands */
	chip->cmd_ctrl = r852_cmdctl;
	chip->waitfunc = r852_wait;
	chip->dev_ready = r852_ready;

	/* I/O */
	chip->read_byte = r852_read_byte;
	chip->read_buf = r852_read_buf;
	chip->write_buf = r852_write_buf;
	chip->verify_buf = r852_verify_buf;

	/* ecc */
	chip->ecc.mode = NAND_ECC_HW_SYNDROME;
	chip->ecc.size = R852_DMA_LEN;
	chip->ecc.bytes = SM_OOB_SIZE;
	chip->ecc.strength = 2;
	chip->ecc.hwctl = r852_ecc_hwctl;
	chip->ecc.calculate = r852_ecc_calculate;
	chip->ecc.correct = r852_ecc_correct;

	/* TODO: hack */
	chip->ecc.read_oob = r852_read_oob;

	/* init our device structure */
	dev = kzalloc(sizeof(struct r852_device), GFP_KERNEL);

	if (!dev)
		goto error5;

	chip->priv = dev;
	dev->chip = chip;
	dev->pci_dev = pci_dev;
	pci_set_drvdata(pci_dev, dev);

	dev->bounce_buffer = pci_alloc_consistent(pci_dev, R852_DMA_LEN,
		&dev->phys_bounce_buffer);

	if (!dev->bounce_buffer)
		goto error6;


	error = -ENODEV;
	dev->mmio = pci_ioremap_bar(pci_dev, 0);

	if (!dev->mmio)
		goto error7;

	error = -ENOMEM;
	dev->tmp_buffer = kzalloc(SM_SECTOR_SIZE, GFP_KERNEL);

	if (!dev->tmp_buffer)
		goto error8;

	init_completion(&dev->dma_done);

	dev->card_workqueue = create_freezable_workqueue(DRV_NAME);

	if (!dev->card_workqueue)
		goto error9;

	INIT_DELAYED_WORK(&dev->card_detect_work, r852_card_detect_work);

	/* shutdown everything - precation */
	r852_engine_disable(dev);
	r852_disable_irqs(dev);

	r852_dma_test(dev);

	dev->irq = pci_dev->irq;
	spin_lock_init(&dev->irqlock);

	dev->card_detected = 0;
	r852_card_update_present(dev);

	/*register irq handler*/
	error = -ENODEV;
	if (request_irq(pci_dev->irq, &r852_irq, IRQF_SHARED,
			  DRV_NAME, dev))
		goto error10;

	/* kick initial present test */
	queue_delayed_work(dev->card_workqueue,
		&dev->card_detect_work, 0);


	printk(KERN_NOTICE DRV_NAME ": driver loaded successfully\n");
	return 0;

error10:
	destroy_workqueue(dev->card_workqueue);
error9:
	kfree(dev->tmp_buffer);
error8:
	pci_iounmap(pci_dev, dev->mmio);
error7:
	pci_free_consistent(pci_dev, R852_DMA_LEN,
		dev->bounce_buffer, dev->phys_bounce_buffer);
error6:
	kfree(dev);
error5:
	kfree(chip);
error4:
	pci_release_regions(pci_dev);
error3:
error2:
	pci_disable_device(pci_dev);
error1:
	return error;
}

void r852_remove(struct pci_dev *pci_dev)
{
	struct r852_device *dev = pci_get_drvdata(pci_dev);

	/* Stop detect workqueue -
		we are going to unregister the device anyway*/
	cancel_delayed_work_sync(&dev->card_detect_work);
	destroy_workqueue(dev->card_workqueue);

	/* Unregister the device, this might make more IO */
	r852_unregister_nand_device(dev);

	/* Stop interrupts */
	r852_disable_irqs(dev);
	synchronize_irq(dev->irq);
	free_irq(dev->irq, dev);

	/* Cleanup */
	kfree(dev->tmp_buffer);
	pci_iounmap(pci_dev, dev->mmio);
	pci_free_consistent(pci_dev, R852_DMA_LEN,
		dev->bounce_buffer, dev->phys_bounce_buffer);

	kfree(dev->chip);
	kfree(dev);

	/* Shutdown the PCI device */
	pci_release_regions(pci_dev);
	pci_disable_device(pci_dev);
}

void r852_shutdown(struct pci_dev *pci_dev)
{
	struct r852_device *dev = pci_get_drvdata(pci_dev);

	cancel_delayed_work_sync(&dev->card_detect_work);
	r852_disable_irqs(dev);
	synchronize_irq(dev->irq);
	pci_disable_device(pci_dev);
}

#ifdef CONFIG_PM
static int r852_suspend(struct device *device)
{
	struct r852_device *dev = pci_get_drvdata(to_pci_dev(device));

	if (dev->ctlreg & R852_CTL_CARDENABLE)
		return -EBUSY;

	/* First make sure the detect work is gone */
	cancel_delayed_work_sync(&dev->card_detect_work);

	/* Turn off the interrupts and stop the device */
	r852_disable_irqs(dev);
	r852_engine_disable(dev);

	/* If card was pulled off just during the suspend, which is very
		unlikely, we will remove it on resume, it too late now
		anyway... */
	dev->card_unstable = 0;
	return 0;
}

static int r852_resume(struct device *device)
{
	struct r852_device *dev = pci_get_drvdata(to_pci_dev(device));

	r852_disable_irqs(dev);
	r852_card_update_present(dev);
	r852_engine_disable(dev);


	/* If card status changed, just do the work */
	if (dev->card_detected != dev->card_registred) {
		dbg("card was %s during low power state",
			dev->card_detected ? "added" : "removed");

		queue_delayed_work(dev->card_workqueue,
		&dev->card_detect_work, msecs_to_jiffies(1000));
		return 0;
	}

	/* Otherwise, initialize the card */
	if (dev->card_registred) {
		r852_engine_enable(dev);
		dev->chip->select_chip(dev->mtd, 0);
		dev->chip->cmdfunc(dev->mtd, NAND_CMD_RESET, -1, -1);
		dev->chip->select_chip(dev->mtd, -1);
	}

	/* Program card detection IRQ */
	r852_update_card_detect(dev);
	return 0;
}
#else
#define r852_suspend	NULL
#define r852_resume	NULL
#endif

static const struct pci_device_id r852_pci_id_tbl[] = {

	{ PCI_VDEVICE(RICOH, 0x0852), },
	{ },
};

MODULE_DEVICE_TABLE(pci, r852_pci_id_tbl);

static SIMPLE_DEV_PM_OPS(r852_pm_ops, r852_suspend, r852_resume);

static struct pci_driver r852_pci_driver = {
	.name		= DRV_NAME,
	.id_table	= r852_pci_id_tbl,
	.probe		= r852_probe,
	.remove		= r852_remove,
	.shutdown	= r852_shutdown,
	.driver.pm	= &r852_pm_ops,
};

static __init int r852_module_init(void)
{
	return pci_register_driver(&r852_pci_driver);
}

static void __exit r852_module_exit(void)
{
	pci_unregister_driver(&r852_pci_driver);
}

module_init(r852_module_init);
module_exit(r852_module_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Maxim Levitsky <maximlevitsky@gmail.com>");
MODULE_DESCRIPTION("Ricoh 85xx xD/smartmedia card reader driver");
