19263412501022fecef844907129ee2513b5a89deMaxim Levitsky/*
29263412501022fecef844907129ee2513b5a89deMaxim Levitsky * Copyright (C) 2010 - Maxim Levitsky
39263412501022fecef844907129ee2513b5a89deMaxim Levitsky * driver for Ricoh memstick readers
49263412501022fecef844907129ee2513b5a89deMaxim Levitsky *
59263412501022fecef844907129ee2513b5a89deMaxim Levitsky * This program is free software; you can redistribute it and/or modify
69263412501022fecef844907129ee2513b5a89deMaxim Levitsky * it under the terms of the GNU General Public License version 2 as
79263412501022fecef844907129ee2513b5a89deMaxim Levitsky * published by the Free Software Foundation.
89263412501022fecef844907129ee2513b5a89deMaxim Levitsky */
99263412501022fecef844907129ee2513b5a89deMaxim Levitsky
109263412501022fecef844907129ee2513b5a89deMaxim Levitsky#include <linux/kernel.h>
119263412501022fecef844907129ee2513b5a89deMaxim Levitsky#include <linux/module.h>
129263412501022fecef844907129ee2513b5a89deMaxim Levitsky#include <linux/freezer.h>
139263412501022fecef844907129ee2513b5a89deMaxim Levitsky#include <linux/jiffies.h>
149263412501022fecef844907129ee2513b5a89deMaxim Levitsky#include <linux/interrupt.h>
159263412501022fecef844907129ee2513b5a89deMaxim Levitsky#include <linux/pci.h>
169263412501022fecef844907129ee2513b5a89deMaxim Levitsky#include <linux/pci_ids.h>
179263412501022fecef844907129ee2513b5a89deMaxim Levitsky#include <linux/delay.h>
189263412501022fecef844907129ee2513b5a89deMaxim Levitsky#include <linux/slab.h>
199263412501022fecef844907129ee2513b5a89deMaxim Levitsky#include <linux/kthread.h>
209263412501022fecef844907129ee2513b5a89deMaxim Levitsky#include <linux/sched.h>
219263412501022fecef844907129ee2513b5a89deMaxim Levitsky#include <linux/highmem.h>
229263412501022fecef844907129ee2513b5a89deMaxim Levitsky#include <asm/byteorder.h>
239263412501022fecef844907129ee2513b5a89deMaxim Levitsky#include <linux/swab.h>
249263412501022fecef844907129ee2513b5a89deMaxim Levitsky#include "r592.h"
259263412501022fecef844907129ee2513b5a89deMaxim Levitsky
2690ab5ee94171b3e28de6bb42ee30b527014e0be7Rusty Russellstatic bool r592_enable_dma = 1;
279263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic int debug;
289263412501022fecef844907129ee2513b5a89deMaxim Levitsky
299263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic const char *tpc_names[] = {
309263412501022fecef844907129ee2513b5a89deMaxim Levitsky	"MS_TPC_READ_MG_STATUS",
319263412501022fecef844907129ee2513b5a89deMaxim Levitsky	"MS_TPC_READ_LONG_DATA",
329263412501022fecef844907129ee2513b5a89deMaxim Levitsky	"MS_TPC_READ_SHORT_DATA",
339263412501022fecef844907129ee2513b5a89deMaxim Levitsky	"MS_TPC_READ_REG",
349263412501022fecef844907129ee2513b5a89deMaxim Levitsky	"MS_TPC_READ_QUAD_DATA",
359263412501022fecef844907129ee2513b5a89deMaxim Levitsky	"INVALID",
369263412501022fecef844907129ee2513b5a89deMaxim Levitsky	"MS_TPC_GET_INT",
379263412501022fecef844907129ee2513b5a89deMaxim Levitsky	"MS_TPC_SET_RW_REG_ADRS",
389263412501022fecef844907129ee2513b5a89deMaxim Levitsky	"MS_TPC_EX_SET_CMD",
399263412501022fecef844907129ee2513b5a89deMaxim Levitsky	"MS_TPC_WRITE_QUAD_DATA",
409263412501022fecef844907129ee2513b5a89deMaxim Levitsky	"MS_TPC_WRITE_REG",
419263412501022fecef844907129ee2513b5a89deMaxim Levitsky	"MS_TPC_WRITE_SHORT_DATA",
429263412501022fecef844907129ee2513b5a89deMaxim Levitsky	"MS_TPC_WRITE_LONG_DATA",
439263412501022fecef844907129ee2513b5a89deMaxim Levitsky	"MS_TPC_SET_CMD",
449263412501022fecef844907129ee2513b5a89deMaxim Levitsky};
459263412501022fecef844907129ee2513b5a89deMaxim Levitsky
469263412501022fecef844907129ee2513b5a89deMaxim Levitsky/**
479263412501022fecef844907129ee2513b5a89deMaxim Levitsky * memstick_debug_get_tpc_name - debug helper that returns string for
489263412501022fecef844907129ee2513b5a89deMaxim Levitsky * a TPC number
499263412501022fecef844907129ee2513b5a89deMaxim Levitsky */
509263412501022fecef844907129ee2513b5a89deMaxim Levitskyconst char *memstick_debug_get_tpc_name(int tpc)
519263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
529263412501022fecef844907129ee2513b5a89deMaxim Levitsky	return tpc_names[tpc-1];
539263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
549263412501022fecef844907129ee2513b5a89deMaxim LevitskyEXPORT_SYMBOL(memstick_debug_get_tpc_name);
559263412501022fecef844907129ee2513b5a89deMaxim Levitsky
569263412501022fecef844907129ee2513b5a89deMaxim Levitsky
579263412501022fecef844907129ee2513b5a89deMaxim Levitsky/* Read a register*/
589263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic inline u32 r592_read_reg(struct r592_device *dev, int address)
599263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
609263412501022fecef844907129ee2513b5a89deMaxim Levitsky	u32 value = readl(dev->mmio + address);
619263412501022fecef844907129ee2513b5a89deMaxim Levitsky	dbg_reg("reg #%02d == 0x%08x", address, value);
629263412501022fecef844907129ee2513b5a89deMaxim Levitsky	return value;
639263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
649263412501022fecef844907129ee2513b5a89deMaxim Levitsky
659263412501022fecef844907129ee2513b5a89deMaxim Levitsky/* Write a register */
669263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic inline void r592_write_reg(struct r592_device *dev,
679263412501022fecef844907129ee2513b5a89deMaxim Levitsky							int address, u32 value)
689263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
699263412501022fecef844907129ee2513b5a89deMaxim Levitsky	dbg_reg("reg #%02d <- 0x%08x", address, value);
709263412501022fecef844907129ee2513b5a89deMaxim Levitsky	writel(value, dev->mmio + address);
719263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
729263412501022fecef844907129ee2513b5a89deMaxim Levitsky
739263412501022fecef844907129ee2513b5a89deMaxim Levitsky/* Reads a big endian DWORD register */
749263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic inline u32 r592_read_reg_raw_be(struct r592_device *dev, int address)
759263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
769263412501022fecef844907129ee2513b5a89deMaxim Levitsky	u32 value = __raw_readl(dev->mmio + address);
779263412501022fecef844907129ee2513b5a89deMaxim Levitsky	dbg_reg("reg #%02d == 0x%08x", address, value);
789263412501022fecef844907129ee2513b5a89deMaxim Levitsky	return be32_to_cpu(value);
799263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
809263412501022fecef844907129ee2513b5a89deMaxim Levitsky
819263412501022fecef844907129ee2513b5a89deMaxim Levitsky/* Writes a big endian DWORD register */
829263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic inline void r592_write_reg_raw_be(struct r592_device *dev,
839263412501022fecef844907129ee2513b5a89deMaxim Levitsky							int address, u32 value)
849263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
859263412501022fecef844907129ee2513b5a89deMaxim Levitsky	dbg_reg("reg #%02d <- 0x%08x", address, value);
869263412501022fecef844907129ee2513b5a89deMaxim Levitsky	__raw_writel(cpu_to_be32(value), dev->mmio + address);
879263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
889263412501022fecef844907129ee2513b5a89deMaxim Levitsky
899263412501022fecef844907129ee2513b5a89deMaxim Levitsky/* Set specific bits in a register (little endian) */
909263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic inline void r592_set_reg_mask(struct r592_device *dev,
919263412501022fecef844907129ee2513b5a89deMaxim Levitsky							int address, u32 mask)
929263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
939263412501022fecef844907129ee2513b5a89deMaxim Levitsky	u32 reg = readl(dev->mmio + address);
949263412501022fecef844907129ee2513b5a89deMaxim Levitsky	dbg_reg("reg #%02d |= 0x%08x (old =0x%08x)", address, mask, reg);
959263412501022fecef844907129ee2513b5a89deMaxim Levitsky	writel(reg | mask , dev->mmio + address);
969263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
979263412501022fecef844907129ee2513b5a89deMaxim Levitsky
989263412501022fecef844907129ee2513b5a89deMaxim Levitsky/* Clear specific bits in a register (little endian) */
999263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic inline void r592_clear_reg_mask(struct r592_device *dev,
1009263412501022fecef844907129ee2513b5a89deMaxim Levitsky						int address, u32 mask)
1019263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
1029263412501022fecef844907129ee2513b5a89deMaxim Levitsky	u32 reg = readl(dev->mmio + address);
1039263412501022fecef844907129ee2513b5a89deMaxim Levitsky	dbg_reg("reg #%02d &= 0x%08x (old = 0x%08x, mask = 0x%08x)",
1049263412501022fecef844907129ee2513b5a89deMaxim Levitsky						address, ~mask, reg, mask);
1059263412501022fecef844907129ee2513b5a89deMaxim Levitsky	writel(reg & ~mask, dev->mmio + address);
1069263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
1079263412501022fecef844907129ee2513b5a89deMaxim Levitsky
1089263412501022fecef844907129ee2513b5a89deMaxim Levitsky
1099263412501022fecef844907129ee2513b5a89deMaxim Levitsky/* Wait for status bits while checking for errors */
1109263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic int r592_wait_status(struct r592_device *dev, u32 mask, u32 wanted_mask)
1119263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
1129263412501022fecef844907129ee2513b5a89deMaxim Levitsky	unsigned long timeout = jiffies + msecs_to_jiffies(1000);
1139263412501022fecef844907129ee2513b5a89deMaxim Levitsky	u32 reg = r592_read_reg(dev, R592_STATUS);
1149263412501022fecef844907129ee2513b5a89deMaxim Levitsky
1159263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if ((reg & mask) == wanted_mask)
1169263412501022fecef844907129ee2513b5a89deMaxim Levitsky		return 0;
1179263412501022fecef844907129ee2513b5a89deMaxim Levitsky
1189263412501022fecef844907129ee2513b5a89deMaxim Levitsky	while (time_before(jiffies, timeout)) {
1199263412501022fecef844907129ee2513b5a89deMaxim Levitsky
1209263412501022fecef844907129ee2513b5a89deMaxim Levitsky		reg = r592_read_reg(dev, R592_STATUS);
1219263412501022fecef844907129ee2513b5a89deMaxim Levitsky
1229263412501022fecef844907129ee2513b5a89deMaxim Levitsky		if ((reg & mask) == wanted_mask)
1239263412501022fecef844907129ee2513b5a89deMaxim Levitsky			return 0;
1249263412501022fecef844907129ee2513b5a89deMaxim Levitsky
1259263412501022fecef844907129ee2513b5a89deMaxim Levitsky		if (reg & (R592_STATUS_SEND_ERR | R592_STATUS_RECV_ERR))
1269263412501022fecef844907129ee2513b5a89deMaxim Levitsky			return -EIO;
1279263412501022fecef844907129ee2513b5a89deMaxim Levitsky
1289263412501022fecef844907129ee2513b5a89deMaxim Levitsky		cpu_relax();
1299263412501022fecef844907129ee2513b5a89deMaxim Levitsky	}
1309263412501022fecef844907129ee2513b5a89deMaxim Levitsky	return -ETIME;
1319263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
1329263412501022fecef844907129ee2513b5a89deMaxim Levitsky
1339263412501022fecef844907129ee2513b5a89deMaxim Levitsky
1349263412501022fecef844907129ee2513b5a89deMaxim Levitsky/* Enable/disable device */
1359263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic int r592_enable_device(struct r592_device *dev, bool enable)
1369263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
1379263412501022fecef844907129ee2513b5a89deMaxim Levitsky	dbg("%sabling the device", enable ? "en" : "dis");
1389263412501022fecef844907129ee2513b5a89deMaxim Levitsky
1399263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (enable) {
1409263412501022fecef844907129ee2513b5a89deMaxim Levitsky
1419263412501022fecef844907129ee2513b5a89deMaxim Levitsky		/* Power up the card */
1429263412501022fecef844907129ee2513b5a89deMaxim Levitsky		r592_write_reg(dev, R592_POWER, R592_POWER_0 | R592_POWER_1);
1439263412501022fecef844907129ee2513b5a89deMaxim Levitsky
1449263412501022fecef844907129ee2513b5a89deMaxim Levitsky		/* Perform a reset */
1459263412501022fecef844907129ee2513b5a89deMaxim Levitsky		r592_set_reg_mask(dev, R592_IO, R592_IO_RESET);
1469263412501022fecef844907129ee2513b5a89deMaxim Levitsky
1479263412501022fecef844907129ee2513b5a89deMaxim Levitsky		msleep(100);
1489263412501022fecef844907129ee2513b5a89deMaxim Levitsky	} else
1499263412501022fecef844907129ee2513b5a89deMaxim Levitsky		/* Power down the card */
1509263412501022fecef844907129ee2513b5a89deMaxim Levitsky		r592_write_reg(dev, R592_POWER, 0);
1519263412501022fecef844907129ee2513b5a89deMaxim Levitsky
1529263412501022fecef844907129ee2513b5a89deMaxim Levitsky	return 0;
1539263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
1549263412501022fecef844907129ee2513b5a89deMaxim Levitsky
1559263412501022fecef844907129ee2513b5a89deMaxim Levitsky/* Set serial/parallel mode */
1569263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic int r592_set_mode(struct r592_device *dev, bool parallel_mode)
1579263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
1589263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (!parallel_mode) {
1599263412501022fecef844907129ee2513b5a89deMaxim Levitsky		dbg("switching to serial mode");
1609263412501022fecef844907129ee2513b5a89deMaxim Levitsky
1619263412501022fecef844907129ee2513b5a89deMaxim Levitsky		/* Set serial mode */
1629263412501022fecef844907129ee2513b5a89deMaxim Levitsky		r592_write_reg(dev, R592_IO_MODE, R592_IO_MODE_SERIAL);
1639263412501022fecef844907129ee2513b5a89deMaxim Levitsky
1649263412501022fecef844907129ee2513b5a89deMaxim Levitsky		r592_clear_reg_mask(dev, R592_POWER, R592_POWER_20);
1659263412501022fecef844907129ee2513b5a89deMaxim Levitsky
1669263412501022fecef844907129ee2513b5a89deMaxim Levitsky	} else {
1679263412501022fecef844907129ee2513b5a89deMaxim Levitsky		dbg("switching to parallel mode");
1689263412501022fecef844907129ee2513b5a89deMaxim Levitsky
1699263412501022fecef844907129ee2513b5a89deMaxim Levitsky		/* This setting should be set _before_ switch TPC */
1709263412501022fecef844907129ee2513b5a89deMaxim Levitsky		r592_set_reg_mask(dev, R592_POWER, R592_POWER_20);
1719263412501022fecef844907129ee2513b5a89deMaxim Levitsky
1729263412501022fecef844907129ee2513b5a89deMaxim Levitsky		r592_clear_reg_mask(dev, R592_IO,
1739263412501022fecef844907129ee2513b5a89deMaxim Levitsky			R592_IO_SERIAL1 | R592_IO_SERIAL2);
1749263412501022fecef844907129ee2513b5a89deMaxim Levitsky
1759263412501022fecef844907129ee2513b5a89deMaxim Levitsky		/* Set the parallel mode now */
1769263412501022fecef844907129ee2513b5a89deMaxim Levitsky		r592_write_reg(dev, R592_IO_MODE, R592_IO_MODE_PARALLEL);
1779263412501022fecef844907129ee2513b5a89deMaxim Levitsky	}
1789263412501022fecef844907129ee2513b5a89deMaxim Levitsky
1799263412501022fecef844907129ee2513b5a89deMaxim Levitsky	dev->parallel_mode = parallel_mode;
1809263412501022fecef844907129ee2513b5a89deMaxim Levitsky	return 0;
1819263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
1829263412501022fecef844907129ee2513b5a89deMaxim Levitsky
1839263412501022fecef844907129ee2513b5a89deMaxim Levitsky/* Perform a controller reset without powering down the card */
1849263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic void r592_host_reset(struct r592_device *dev)
1859263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
1869263412501022fecef844907129ee2513b5a89deMaxim Levitsky	r592_set_reg_mask(dev, R592_IO, R592_IO_RESET);
1879263412501022fecef844907129ee2513b5a89deMaxim Levitsky	msleep(100);
1889263412501022fecef844907129ee2513b5a89deMaxim Levitsky	r592_set_mode(dev, dev->parallel_mode);
1899263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
1909263412501022fecef844907129ee2513b5a89deMaxim Levitsky
1919263412501022fecef844907129ee2513b5a89deMaxim Levitsky/* Disable all hardware interrupts */
1929263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic void r592_clear_interrupts(struct r592_device *dev)
1939263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
1949263412501022fecef844907129ee2513b5a89deMaxim Levitsky	/* Disable & ACK all interrupts */
1959263412501022fecef844907129ee2513b5a89deMaxim Levitsky	r592_clear_reg_mask(dev, R592_REG_MSC, IRQ_ALL_ACK_MASK);
1969263412501022fecef844907129ee2513b5a89deMaxim Levitsky	r592_clear_reg_mask(dev, R592_REG_MSC, IRQ_ALL_EN_MASK);
1979263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
1989263412501022fecef844907129ee2513b5a89deMaxim Levitsky
1999263412501022fecef844907129ee2513b5a89deMaxim Levitsky/* Tests if there is an CRC error */
2009263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic int r592_test_io_error(struct r592_device *dev)
2019263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
2029263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (!(r592_read_reg(dev, R592_STATUS) &
2039263412501022fecef844907129ee2513b5a89deMaxim Levitsky		(R592_STATUS_SEND_ERR | R592_STATUS_RECV_ERR)))
2049263412501022fecef844907129ee2513b5a89deMaxim Levitsky		return 0;
2059263412501022fecef844907129ee2513b5a89deMaxim Levitsky
2069263412501022fecef844907129ee2513b5a89deMaxim Levitsky	return -EIO;
2079263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
2089263412501022fecef844907129ee2513b5a89deMaxim Levitsky
2099263412501022fecef844907129ee2513b5a89deMaxim Levitsky/* Ensure that FIFO is ready for use */
2109263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic int r592_test_fifo_empty(struct r592_device *dev)
2119263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
2129263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (r592_read_reg(dev, R592_REG_MSC) & R592_REG_MSC_FIFO_EMPTY)
2139263412501022fecef844907129ee2513b5a89deMaxim Levitsky		return 0;
2149263412501022fecef844907129ee2513b5a89deMaxim Levitsky
2159263412501022fecef844907129ee2513b5a89deMaxim Levitsky	dbg("FIFO not ready, trying to reset the device");
2169263412501022fecef844907129ee2513b5a89deMaxim Levitsky	r592_host_reset(dev);
2179263412501022fecef844907129ee2513b5a89deMaxim Levitsky
2189263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (r592_read_reg(dev, R592_REG_MSC) & R592_REG_MSC_FIFO_EMPTY)
2199263412501022fecef844907129ee2513b5a89deMaxim Levitsky		return 0;
2209263412501022fecef844907129ee2513b5a89deMaxim Levitsky
2219263412501022fecef844907129ee2513b5a89deMaxim Levitsky	message("FIFO still not ready, giving up");
2229263412501022fecef844907129ee2513b5a89deMaxim Levitsky	return -EIO;
2239263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
2249263412501022fecef844907129ee2513b5a89deMaxim Levitsky
2259263412501022fecef844907129ee2513b5a89deMaxim Levitsky/* Activates the DMA transfer from to FIFO */
2269263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic void r592_start_dma(struct r592_device *dev, bool is_write)
2279263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
2289263412501022fecef844907129ee2513b5a89deMaxim Levitsky	unsigned long flags;
2299263412501022fecef844907129ee2513b5a89deMaxim Levitsky	u32 reg;
2309263412501022fecef844907129ee2513b5a89deMaxim Levitsky	spin_lock_irqsave(&dev->irq_lock, flags);
2319263412501022fecef844907129ee2513b5a89deMaxim Levitsky
2329263412501022fecef844907129ee2513b5a89deMaxim Levitsky	/* Ack interrupts (just in case) + enable them */
2339263412501022fecef844907129ee2513b5a89deMaxim Levitsky	r592_clear_reg_mask(dev, R592_REG_MSC, DMA_IRQ_ACK_MASK);
2349263412501022fecef844907129ee2513b5a89deMaxim Levitsky	r592_set_reg_mask(dev, R592_REG_MSC, DMA_IRQ_EN_MASK);
2359263412501022fecef844907129ee2513b5a89deMaxim Levitsky
2369263412501022fecef844907129ee2513b5a89deMaxim Levitsky	/* Set DMA address */
2379263412501022fecef844907129ee2513b5a89deMaxim Levitsky	r592_write_reg(dev, R592_FIFO_DMA, sg_dma_address(&dev->req->sg));
2389263412501022fecef844907129ee2513b5a89deMaxim Levitsky
2399263412501022fecef844907129ee2513b5a89deMaxim Levitsky	/* Enable the DMA */
2409263412501022fecef844907129ee2513b5a89deMaxim Levitsky	reg = r592_read_reg(dev, R592_FIFO_DMA_SETTINGS);
2419263412501022fecef844907129ee2513b5a89deMaxim Levitsky	reg |= R592_FIFO_DMA_SETTINGS_EN;
2429263412501022fecef844907129ee2513b5a89deMaxim Levitsky
2439263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (!is_write)
2449263412501022fecef844907129ee2513b5a89deMaxim Levitsky		reg |= R592_FIFO_DMA_SETTINGS_DIR;
2459263412501022fecef844907129ee2513b5a89deMaxim Levitsky	else
2469263412501022fecef844907129ee2513b5a89deMaxim Levitsky		reg &= ~R592_FIFO_DMA_SETTINGS_DIR;
2479263412501022fecef844907129ee2513b5a89deMaxim Levitsky	r592_write_reg(dev, R592_FIFO_DMA_SETTINGS, reg);
2489263412501022fecef844907129ee2513b5a89deMaxim Levitsky
2499263412501022fecef844907129ee2513b5a89deMaxim Levitsky	spin_unlock_irqrestore(&dev->irq_lock, flags);
2509263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
2519263412501022fecef844907129ee2513b5a89deMaxim Levitsky
2529263412501022fecef844907129ee2513b5a89deMaxim Levitsky/* Cleanups DMA related settings */
2539263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic void r592_stop_dma(struct r592_device *dev, int error)
2549263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
2559263412501022fecef844907129ee2513b5a89deMaxim Levitsky	r592_clear_reg_mask(dev, R592_FIFO_DMA_SETTINGS,
2569263412501022fecef844907129ee2513b5a89deMaxim Levitsky		R592_FIFO_DMA_SETTINGS_EN);
2579263412501022fecef844907129ee2513b5a89deMaxim Levitsky
2589263412501022fecef844907129ee2513b5a89deMaxim Levitsky	/* This is only a precation */
2599263412501022fecef844907129ee2513b5a89deMaxim Levitsky	r592_write_reg(dev, R592_FIFO_DMA,
2609263412501022fecef844907129ee2513b5a89deMaxim Levitsky			dev->dummy_dma_page_physical_address);
2619263412501022fecef844907129ee2513b5a89deMaxim Levitsky
2629263412501022fecef844907129ee2513b5a89deMaxim Levitsky	r592_clear_reg_mask(dev, R592_REG_MSC, DMA_IRQ_EN_MASK);
2639263412501022fecef844907129ee2513b5a89deMaxim Levitsky	r592_clear_reg_mask(dev, R592_REG_MSC, DMA_IRQ_ACK_MASK);
2649263412501022fecef844907129ee2513b5a89deMaxim Levitsky	dev->dma_error = error;
2659263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
2669263412501022fecef844907129ee2513b5a89deMaxim Levitsky
2679263412501022fecef844907129ee2513b5a89deMaxim Levitsky/* Test if hardware supports DMA */
2689263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic void r592_check_dma(struct r592_device *dev)
2699263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
2705ede9ddfba424b5dad96e7ccd55607875a64ff6cStephen Rothwell	dev->dma_capable = r592_enable_dma &&
2719263412501022fecef844907129ee2513b5a89deMaxim Levitsky		(r592_read_reg(dev, R592_FIFO_DMA_SETTINGS) &
2729263412501022fecef844907129ee2513b5a89deMaxim Levitsky			R592_FIFO_DMA_SETTINGS_CAP);
2739263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
2749263412501022fecef844907129ee2513b5a89deMaxim Levitsky
2759263412501022fecef844907129ee2513b5a89deMaxim Levitsky/* Transfers fifo contents in/out using DMA */
2769263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic int r592_transfer_fifo_dma(struct r592_device *dev)
2779263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
2789263412501022fecef844907129ee2513b5a89deMaxim Levitsky	int len, sg_count;
2799263412501022fecef844907129ee2513b5a89deMaxim Levitsky	bool is_write;
2809263412501022fecef844907129ee2513b5a89deMaxim Levitsky
2819263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (!dev->dma_capable || !dev->req->long_data)
2829263412501022fecef844907129ee2513b5a89deMaxim Levitsky		return -EINVAL;
2839263412501022fecef844907129ee2513b5a89deMaxim Levitsky
2849263412501022fecef844907129ee2513b5a89deMaxim Levitsky	len = dev->req->sg.length;
2859263412501022fecef844907129ee2513b5a89deMaxim Levitsky	is_write = dev->req->data_dir == WRITE;
2869263412501022fecef844907129ee2513b5a89deMaxim Levitsky
2879263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (len != R592_LFIFO_SIZE)
2889263412501022fecef844907129ee2513b5a89deMaxim Levitsky		return -EINVAL;
2899263412501022fecef844907129ee2513b5a89deMaxim Levitsky
2909263412501022fecef844907129ee2513b5a89deMaxim Levitsky	dbg_verbose("doing dma transfer");
2919263412501022fecef844907129ee2513b5a89deMaxim Levitsky
2929263412501022fecef844907129ee2513b5a89deMaxim Levitsky	dev->dma_error = 0;
2939263412501022fecef844907129ee2513b5a89deMaxim Levitsky	INIT_COMPLETION(dev->dma_done);
2949263412501022fecef844907129ee2513b5a89deMaxim Levitsky
2959263412501022fecef844907129ee2513b5a89deMaxim Levitsky	/* TODO: hidden assumption about nenth beeing always 1 */
2969263412501022fecef844907129ee2513b5a89deMaxim Levitsky	sg_count = dma_map_sg(&dev->pci_dev->dev, &dev->req->sg, 1, is_write ?
2979263412501022fecef844907129ee2513b5a89deMaxim Levitsky		PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
2989263412501022fecef844907129ee2513b5a89deMaxim Levitsky
2999263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (sg_count != 1 ||
3009263412501022fecef844907129ee2513b5a89deMaxim Levitsky			(sg_dma_len(&dev->req->sg) < dev->req->sg.length)) {
3019263412501022fecef844907129ee2513b5a89deMaxim Levitsky		message("problem in dma_map_sg");
3029263412501022fecef844907129ee2513b5a89deMaxim Levitsky		return -EIO;
3039263412501022fecef844907129ee2513b5a89deMaxim Levitsky	}
3049263412501022fecef844907129ee2513b5a89deMaxim Levitsky
3059263412501022fecef844907129ee2513b5a89deMaxim Levitsky	r592_start_dma(dev, is_write);
3069263412501022fecef844907129ee2513b5a89deMaxim Levitsky
3079263412501022fecef844907129ee2513b5a89deMaxim Levitsky	/* Wait for DMA completion */
3089263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (!wait_for_completion_timeout(
3099263412501022fecef844907129ee2513b5a89deMaxim Levitsky			&dev->dma_done, msecs_to_jiffies(1000))) {
3109263412501022fecef844907129ee2513b5a89deMaxim Levitsky		message("DMA timeout");
3119263412501022fecef844907129ee2513b5a89deMaxim Levitsky		r592_stop_dma(dev, -ETIMEDOUT);
3129263412501022fecef844907129ee2513b5a89deMaxim Levitsky	}
3139263412501022fecef844907129ee2513b5a89deMaxim Levitsky
3149263412501022fecef844907129ee2513b5a89deMaxim Levitsky	dma_unmap_sg(&dev->pci_dev->dev, &dev->req->sg, 1, is_write ?
3159263412501022fecef844907129ee2513b5a89deMaxim Levitsky		PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
3169263412501022fecef844907129ee2513b5a89deMaxim Levitsky
3179263412501022fecef844907129ee2513b5a89deMaxim Levitsky
3189263412501022fecef844907129ee2513b5a89deMaxim Levitsky	return dev->dma_error;
3199263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
3209263412501022fecef844907129ee2513b5a89deMaxim Levitsky
3219263412501022fecef844907129ee2513b5a89deMaxim Levitsky/*
3229263412501022fecef844907129ee2513b5a89deMaxim Levitsky * Writes the FIFO in 4 byte chunks.
3239263412501022fecef844907129ee2513b5a89deMaxim Levitsky * If length isn't 4 byte aligned, rest of the data if put to a fifo
3249263412501022fecef844907129ee2513b5a89deMaxim Levitsky * to be written later
3259263412501022fecef844907129ee2513b5a89deMaxim Levitsky * Use r592_flush_fifo_write to flush that fifo when writing for the
3269263412501022fecef844907129ee2513b5a89deMaxim Levitsky * last time
3279263412501022fecef844907129ee2513b5a89deMaxim Levitsky */
3289263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic void r592_write_fifo_pio(struct r592_device *dev,
3299263412501022fecef844907129ee2513b5a89deMaxim Levitsky					unsigned char *buffer, int len)
3309263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
3319263412501022fecef844907129ee2513b5a89deMaxim Levitsky	/* flush spill from former write */
3329263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (!kfifo_is_empty(&dev->pio_fifo)) {
3339263412501022fecef844907129ee2513b5a89deMaxim Levitsky
3349263412501022fecef844907129ee2513b5a89deMaxim Levitsky		u8 tmp[4] = {0};
3359263412501022fecef844907129ee2513b5a89deMaxim Levitsky		int copy_len = kfifo_in(&dev->pio_fifo, buffer, len);
3369263412501022fecef844907129ee2513b5a89deMaxim Levitsky
3379263412501022fecef844907129ee2513b5a89deMaxim Levitsky		if (!kfifo_is_full(&dev->pio_fifo))
3389263412501022fecef844907129ee2513b5a89deMaxim Levitsky			return;
3399263412501022fecef844907129ee2513b5a89deMaxim Levitsky		len -= copy_len;
3409263412501022fecef844907129ee2513b5a89deMaxim Levitsky		buffer += copy_len;
3419263412501022fecef844907129ee2513b5a89deMaxim Levitsky
3429263412501022fecef844907129ee2513b5a89deMaxim Levitsky		copy_len = kfifo_out(&dev->pio_fifo, tmp, 4);
3439263412501022fecef844907129ee2513b5a89deMaxim Levitsky		WARN_ON(copy_len != 4);
3449263412501022fecef844907129ee2513b5a89deMaxim Levitsky		r592_write_reg_raw_be(dev, R592_FIFO_PIO, *(u32 *)tmp);
3459263412501022fecef844907129ee2513b5a89deMaxim Levitsky	}
3469263412501022fecef844907129ee2513b5a89deMaxim Levitsky
3479263412501022fecef844907129ee2513b5a89deMaxim Levitsky	WARN_ON(!kfifo_is_empty(&dev->pio_fifo));
3489263412501022fecef844907129ee2513b5a89deMaxim Levitsky
3499263412501022fecef844907129ee2513b5a89deMaxim Levitsky	/* write full dwords */
3509263412501022fecef844907129ee2513b5a89deMaxim Levitsky	while (len >= 4) {
3519263412501022fecef844907129ee2513b5a89deMaxim Levitsky		r592_write_reg_raw_be(dev, R592_FIFO_PIO, *(u32 *)buffer);
3529263412501022fecef844907129ee2513b5a89deMaxim Levitsky		buffer += 4;
3539263412501022fecef844907129ee2513b5a89deMaxim Levitsky		len -= 4;
3549263412501022fecef844907129ee2513b5a89deMaxim Levitsky	}
3559263412501022fecef844907129ee2513b5a89deMaxim Levitsky
3569263412501022fecef844907129ee2513b5a89deMaxim Levitsky	/* put remaining bytes to the spill */
3579263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (len)
3589263412501022fecef844907129ee2513b5a89deMaxim Levitsky		kfifo_in(&dev->pio_fifo, buffer, len);
3599263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
3609263412501022fecef844907129ee2513b5a89deMaxim Levitsky
3619263412501022fecef844907129ee2513b5a89deMaxim Levitsky/* Flushes the temporary FIFO used to make aligned DWORD writes */
3629263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic void r592_flush_fifo_write(struct r592_device *dev)
3639263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
3649263412501022fecef844907129ee2513b5a89deMaxim Levitsky	u8 buffer[4] = { 0 };
3659263412501022fecef844907129ee2513b5a89deMaxim Levitsky	int len;
3669263412501022fecef844907129ee2513b5a89deMaxim Levitsky
3679263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (kfifo_is_empty(&dev->pio_fifo))
3689263412501022fecef844907129ee2513b5a89deMaxim Levitsky		return;
3699263412501022fecef844907129ee2513b5a89deMaxim Levitsky
3709263412501022fecef844907129ee2513b5a89deMaxim Levitsky	len = kfifo_out(&dev->pio_fifo, buffer, 4);
3719263412501022fecef844907129ee2513b5a89deMaxim Levitsky	r592_write_reg_raw_be(dev, R592_FIFO_PIO, *(u32 *)buffer);
3729263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
3739263412501022fecef844907129ee2513b5a89deMaxim Levitsky
3749263412501022fecef844907129ee2513b5a89deMaxim Levitsky/*
3759263412501022fecef844907129ee2513b5a89deMaxim Levitsky * Read a fifo in 4 bytes chunks.
3769263412501022fecef844907129ee2513b5a89deMaxim Levitsky * If input doesn't fit the buffer, it places bytes of last dword in spill
3779263412501022fecef844907129ee2513b5a89deMaxim Levitsky * buffer, so that they don't get lost on last read, just throw these away.
3789263412501022fecef844907129ee2513b5a89deMaxim Levitsky */
3799263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic void r592_read_fifo_pio(struct r592_device *dev,
3809263412501022fecef844907129ee2513b5a89deMaxim Levitsky						unsigned char *buffer, int len)
3819263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
3829263412501022fecef844907129ee2513b5a89deMaxim Levitsky	u8 tmp[4];
3839263412501022fecef844907129ee2513b5a89deMaxim Levitsky
3849263412501022fecef844907129ee2513b5a89deMaxim Levitsky	/* Read from last spill */
3859263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (!kfifo_is_empty(&dev->pio_fifo)) {
3869263412501022fecef844907129ee2513b5a89deMaxim Levitsky		int bytes_copied =
3879263412501022fecef844907129ee2513b5a89deMaxim Levitsky			kfifo_out(&dev->pio_fifo, buffer, min(4, len));
3889263412501022fecef844907129ee2513b5a89deMaxim Levitsky		buffer += bytes_copied;
3899263412501022fecef844907129ee2513b5a89deMaxim Levitsky		len -= bytes_copied;
3909263412501022fecef844907129ee2513b5a89deMaxim Levitsky
3919263412501022fecef844907129ee2513b5a89deMaxim Levitsky		if (!kfifo_is_empty(&dev->pio_fifo))
3929263412501022fecef844907129ee2513b5a89deMaxim Levitsky			return;
3939263412501022fecef844907129ee2513b5a89deMaxim Levitsky	}
3949263412501022fecef844907129ee2513b5a89deMaxim Levitsky
3959263412501022fecef844907129ee2513b5a89deMaxim Levitsky	/* Reads dwords from FIFO */
3969263412501022fecef844907129ee2513b5a89deMaxim Levitsky	while (len >= 4) {
3979263412501022fecef844907129ee2513b5a89deMaxim Levitsky		*(u32 *)buffer = r592_read_reg_raw_be(dev, R592_FIFO_PIO);
3989263412501022fecef844907129ee2513b5a89deMaxim Levitsky		buffer += 4;
3999263412501022fecef844907129ee2513b5a89deMaxim Levitsky		len -= 4;
4009263412501022fecef844907129ee2513b5a89deMaxim Levitsky	}
4019263412501022fecef844907129ee2513b5a89deMaxim Levitsky
4029263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (len) {
4039263412501022fecef844907129ee2513b5a89deMaxim Levitsky		*(u32 *)tmp = r592_read_reg_raw_be(dev, R592_FIFO_PIO);
4049263412501022fecef844907129ee2513b5a89deMaxim Levitsky		kfifo_in(&dev->pio_fifo, tmp, 4);
4059263412501022fecef844907129ee2513b5a89deMaxim Levitsky		len -= kfifo_out(&dev->pio_fifo, buffer, len);
4069263412501022fecef844907129ee2513b5a89deMaxim Levitsky	}
4079263412501022fecef844907129ee2513b5a89deMaxim Levitsky
4089263412501022fecef844907129ee2513b5a89deMaxim Levitsky	WARN_ON(len);
4099263412501022fecef844907129ee2513b5a89deMaxim Levitsky	return;
4109263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
4119263412501022fecef844907129ee2513b5a89deMaxim Levitsky
4129263412501022fecef844907129ee2513b5a89deMaxim Levitsky/* Transfers actual data using PIO. */
4139263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic int r592_transfer_fifo_pio(struct r592_device *dev)
4149263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
4159263412501022fecef844907129ee2513b5a89deMaxim Levitsky	unsigned long flags;
4169263412501022fecef844907129ee2513b5a89deMaxim Levitsky
4179263412501022fecef844907129ee2513b5a89deMaxim Levitsky	bool is_write = dev->req->tpc >= MS_TPC_SET_RW_REG_ADRS;
4189263412501022fecef844907129ee2513b5a89deMaxim Levitsky	struct sg_mapping_iter miter;
4199263412501022fecef844907129ee2513b5a89deMaxim Levitsky
4209263412501022fecef844907129ee2513b5a89deMaxim Levitsky	kfifo_reset(&dev->pio_fifo);
4219263412501022fecef844907129ee2513b5a89deMaxim Levitsky
4229263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (!dev->req->long_data) {
4239263412501022fecef844907129ee2513b5a89deMaxim Levitsky		if (is_write) {
4249263412501022fecef844907129ee2513b5a89deMaxim Levitsky			r592_write_fifo_pio(dev, dev->req->data,
4259263412501022fecef844907129ee2513b5a89deMaxim Levitsky							dev->req->data_len);
4269263412501022fecef844907129ee2513b5a89deMaxim Levitsky			r592_flush_fifo_write(dev);
4279263412501022fecef844907129ee2513b5a89deMaxim Levitsky		} else
4289263412501022fecef844907129ee2513b5a89deMaxim Levitsky			r592_read_fifo_pio(dev, dev->req->data,
4299263412501022fecef844907129ee2513b5a89deMaxim Levitsky							dev->req->data_len);
4309263412501022fecef844907129ee2513b5a89deMaxim Levitsky		return 0;
4319263412501022fecef844907129ee2513b5a89deMaxim Levitsky	}
4329263412501022fecef844907129ee2513b5a89deMaxim Levitsky
4339263412501022fecef844907129ee2513b5a89deMaxim Levitsky	local_irq_save(flags);
4349263412501022fecef844907129ee2513b5a89deMaxim Levitsky	sg_miter_start(&miter, &dev->req->sg, 1, SG_MITER_ATOMIC |
4359263412501022fecef844907129ee2513b5a89deMaxim Levitsky		(is_write ? SG_MITER_FROM_SG : SG_MITER_TO_SG));
4369263412501022fecef844907129ee2513b5a89deMaxim Levitsky
4379263412501022fecef844907129ee2513b5a89deMaxim Levitsky	/* Do the transfer fifo<->memory*/
4389263412501022fecef844907129ee2513b5a89deMaxim Levitsky	while (sg_miter_next(&miter))
4399263412501022fecef844907129ee2513b5a89deMaxim Levitsky		if (is_write)
4409263412501022fecef844907129ee2513b5a89deMaxim Levitsky			r592_write_fifo_pio(dev, miter.addr, miter.length);
4419263412501022fecef844907129ee2513b5a89deMaxim Levitsky		else
4429263412501022fecef844907129ee2513b5a89deMaxim Levitsky			r592_read_fifo_pio(dev, miter.addr, miter.length);
4439263412501022fecef844907129ee2513b5a89deMaxim Levitsky
4449263412501022fecef844907129ee2513b5a89deMaxim Levitsky
4459263412501022fecef844907129ee2513b5a89deMaxim Levitsky	/* Write last few non aligned bytes*/
4469263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (is_write)
4479263412501022fecef844907129ee2513b5a89deMaxim Levitsky		r592_flush_fifo_write(dev);
4489263412501022fecef844907129ee2513b5a89deMaxim Levitsky
4499263412501022fecef844907129ee2513b5a89deMaxim Levitsky	sg_miter_stop(&miter);
4509263412501022fecef844907129ee2513b5a89deMaxim Levitsky	local_irq_restore(flags);
4519263412501022fecef844907129ee2513b5a89deMaxim Levitsky	return 0;
4529263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
4539263412501022fecef844907129ee2513b5a89deMaxim Levitsky
4549263412501022fecef844907129ee2513b5a89deMaxim Levitsky/* Executes one TPC (data is read/written from small or large fifo) */
4559263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic void r592_execute_tpc(struct r592_device *dev)
4569263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
4579263412501022fecef844907129ee2513b5a89deMaxim Levitsky	bool is_write = dev->req->tpc >= MS_TPC_SET_RW_REG_ADRS;
4589263412501022fecef844907129ee2513b5a89deMaxim Levitsky	int len, error;
4599263412501022fecef844907129ee2513b5a89deMaxim Levitsky	u32 status, reg;
4609263412501022fecef844907129ee2513b5a89deMaxim Levitsky
4619263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (!dev->req) {
4629263412501022fecef844907129ee2513b5a89deMaxim Levitsky		message("BUG: tpc execution without request!");
4639263412501022fecef844907129ee2513b5a89deMaxim Levitsky		return;
4649263412501022fecef844907129ee2513b5a89deMaxim Levitsky	}
4659263412501022fecef844907129ee2513b5a89deMaxim Levitsky
4669263412501022fecef844907129ee2513b5a89deMaxim Levitsky	len = dev->req->long_data ?
4679263412501022fecef844907129ee2513b5a89deMaxim Levitsky		dev->req->sg.length : dev->req->data_len;
4689263412501022fecef844907129ee2513b5a89deMaxim Levitsky
4699263412501022fecef844907129ee2513b5a89deMaxim Levitsky	/* Ensure that FIFO can hold the input data */
4709263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (len > R592_LFIFO_SIZE) {
4719263412501022fecef844907129ee2513b5a89deMaxim Levitsky		message("IO: hardware doesn't support TPCs longer that 512");
4729263412501022fecef844907129ee2513b5a89deMaxim Levitsky		error = -ENOSYS;
4739263412501022fecef844907129ee2513b5a89deMaxim Levitsky		goto out;
4749263412501022fecef844907129ee2513b5a89deMaxim Levitsky	}
4759263412501022fecef844907129ee2513b5a89deMaxim Levitsky
4769263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (!(r592_read_reg(dev, R592_REG_MSC) & R592_REG_MSC_PRSNT)) {
4779263412501022fecef844907129ee2513b5a89deMaxim Levitsky		dbg("IO: refusing to send TPC because card is absent");
4789263412501022fecef844907129ee2513b5a89deMaxim Levitsky		error = -ENODEV;
4799263412501022fecef844907129ee2513b5a89deMaxim Levitsky		goto out;
4809263412501022fecef844907129ee2513b5a89deMaxim Levitsky	}
4819263412501022fecef844907129ee2513b5a89deMaxim Levitsky
4829263412501022fecef844907129ee2513b5a89deMaxim Levitsky	dbg("IO: executing %s LEN=%d",
4839263412501022fecef844907129ee2513b5a89deMaxim Levitsky			memstick_debug_get_tpc_name(dev->req->tpc), len);
4849263412501022fecef844907129ee2513b5a89deMaxim Levitsky
4859263412501022fecef844907129ee2513b5a89deMaxim Levitsky	/* Set IO direction */
4869263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (is_write)
4879263412501022fecef844907129ee2513b5a89deMaxim Levitsky		r592_set_reg_mask(dev, R592_IO, R592_IO_DIRECTION);
4889263412501022fecef844907129ee2513b5a89deMaxim Levitsky	else
4899263412501022fecef844907129ee2513b5a89deMaxim Levitsky		r592_clear_reg_mask(dev, R592_IO, R592_IO_DIRECTION);
4909263412501022fecef844907129ee2513b5a89deMaxim Levitsky
4919263412501022fecef844907129ee2513b5a89deMaxim Levitsky
4929263412501022fecef844907129ee2513b5a89deMaxim Levitsky	error = r592_test_fifo_empty(dev);
4939263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (error)
4949263412501022fecef844907129ee2513b5a89deMaxim Levitsky		goto out;
4959263412501022fecef844907129ee2513b5a89deMaxim Levitsky
4969263412501022fecef844907129ee2513b5a89deMaxim Levitsky	/* Transfer write data */
4979263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (is_write) {
4989263412501022fecef844907129ee2513b5a89deMaxim Levitsky		error = r592_transfer_fifo_dma(dev);
4999263412501022fecef844907129ee2513b5a89deMaxim Levitsky		if (error == -EINVAL)
5009263412501022fecef844907129ee2513b5a89deMaxim Levitsky			error = r592_transfer_fifo_pio(dev);
5019263412501022fecef844907129ee2513b5a89deMaxim Levitsky	}
5029263412501022fecef844907129ee2513b5a89deMaxim Levitsky
5039263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (error)
5049263412501022fecef844907129ee2513b5a89deMaxim Levitsky		goto out;
5059263412501022fecef844907129ee2513b5a89deMaxim Levitsky
5069263412501022fecef844907129ee2513b5a89deMaxim Levitsky	/* Trigger the TPC */
5079263412501022fecef844907129ee2513b5a89deMaxim Levitsky	reg = (len << R592_TPC_EXEC_LEN_SHIFT) |
5089263412501022fecef844907129ee2513b5a89deMaxim Levitsky		(dev->req->tpc << R592_TPC_EXEC_TPC_SHIFT) |
5099263412501022fecef844907129ee2513b5a89deMaxim Levitsky			R592_TPC_EXEC_BIG_FIFO;
5109263412501022fecef844907129ee2513b5a89deMaxim Levitsky
5119263412501022fecef844907129ee2513b5a89deMaxim Levitsky	r592_write_reg(dev, R592_TPC_EXEC, reg);
5129263412501022fecef844907129ee2513b5a89deMaxim Levitsky
5139263412501022fecef844907129ee2513b5a89deMaxim Levitsky	/* Wait for TPC completion */
5149263412501022fecef844907129ee2513b5a89deMaxim Levitsky	status = R592_STATUS_RDY;
5159263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (dev->req->need_card_int)
5169263412501022fecef844907129ee2513b5a89deMaxim Levitsky		status |= R592_STATUS_CED;
5179263412501022fecef844907129ee2513b5a89deMaxim Levitsky
5189263412501022fecef844907129ee2513b5a89deMaxim Levitsky	error = r592_wait_status(dev, status, status);
5199263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (error) {
5209263412501022fecef844907129ee2513b5a89deMaxim Levitsky		message("card didn't respond");
5219263412501022fecef844907129ee2513b5a89deMaxim Levitsky		goto out;
5229263412501022fecef844907129ee2513b5a89deMaxim Levitsky	}
5239263412501022fecef844907129ee2513b5a89deMaxim Levitsky
5249263412501022fecef844907129ee2513b5a89deMaxim Levitsky	/* Test IO errors */
5259263412501022fecef844907129ee2513b5a89deMaxim Levitsky	error = r592_test_io_error(dev);
5269263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (error) {
5279263412501022fecef844907129ee2513b5a89deMaxim Levitsky		dbg("IO error");
5289263412501022fecef844907129ee2513b5a89deMaxim Levitsky		goto out;
5299263412501022fecef844907129ee2513b5a89deMaxim Levitsky	}
5309263412501022fecef844907129ee2513b5a89deMaxim Levitsky
5319263412501022fecef844907129ee2513b5a89deMaxim Levitsky	/* Read data from FIFO */
5329263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (!is_write) {
5339263412501022fecef844907129ee2513b5a89deMaxim Levitsky		error = r592_transfer_fifo_dma(dev);
5349263412501022fecef844907129ee2513b5a89deMaxim Levitsky		if (error == -EINVAL)
5359263412501022fecef844907129ee2513b5a89deMaxim Levitsky			error = r592_transfer_fifo_pio(dev);
5369263412501022fecef844907129ee2513b5a89deMaxim Levitsky	}
5379263412501022fecef844907129ee2513b5a89deMaxim Levitsky
5389263412501022fecef844907129ee2513b5a89deMaxim Levitsky	/* read INT reg. This can be shortened with shifts, but that way
5399263412501022fecef844907129ee2513b5a89deMaxim Levitsky		its more readable */
5409263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (dev->parallel_mode && dev->req->need_card_int) {
5419263412501022fecef844907129ee2513b5a89deMaxim Levitsky
5429263412501022fecef844907129ee2513b5a89deMaxim Levitsky		dev->req->int_reg = 0;
5439263412501022fecef844907129ee2513b5a89deMaxim Levitsky		status = r592_read_reg(dev, R592_STATUS);
5449263412501022fecef844907129ee2513b5a89deMaxim Levitsky
5459263412501022fecef844907129ee2513b5a89deMaxim Levitsky		if (status & R592_STATUS_P_CMDNACK)
5469263412501022fecef844907129ee2513b5a89deMaxim Levitsky			dev->req->int_reg |= MEMSTICK_INT_CMDNAK;
5479263412501022fecef844907129ee2513b5a89deMaxim Levitsky		if (status & R592_STATUS_P_BREQ)
5489263412501022fecef844907129ee2513b5a89deMaxim Levitsky			dev->req->int_reg |= MEMSTICK_INT_BREQ;
5499263412501022fecef844907129ee2513b5a89deMaxim Levitsky		if (status & R592_STATUS_P_INTERR)
5509263412501022fecef844907129ee2513b5a89deMaxim Levitsky			dev->req->int_reg |= MEMSTICK_INT_ERR;
5519263412501022fecef844907129ee2513b5a89deMaxim Levitsky		if (status & R592_STATUS_P_CED)
5529263412501022fecef844907129ee2513b5a89deMaxim Levitsky			dev->req->int_reg |= MEMSTICK_INT_CED;
5539263412501022fecef844907129ee2513b5a89deMaxim Levitsky	}
5549263412501022fecef844907129ee2513b5a89deMaxim Levitsky
5559263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (error)
5569263412501022fecef844907129ee2513b5a89deMaxim Levitsky		dbg("FIFO read error");
5579263412501022fecef844907129ee2513b5a89deMaxim Levitskyout:
5589263412501022fecef844907129ee2513b5a89deMaxim Levitsky	dev->req->error = error;
5599263412501022fecef844907129ee2513b5a89deMaxim Levitsky	r592_clear_reg_mask(dev, R592_REG_MSC, R592_REG_MSC_LED);
5609263412501022fecef844907129ee2513b5a89deMaxim Levitsky	return;
5619263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
5629263412501022fecef844907129ee2513b5a89deMaxim Levitsky
5639263412501022fecef844907129ee2513b5a89deMaxim Levitsky/* Main request processing thread */
5649263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic int r592_process_thread(void *data)
5659263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
5669263412501022fecef844907129ee2513b5a89deMaxim Levitsky	int error;
5679263412501022fecef844907129ee2513b5a89deMaxim Levitsky	struct r592_device *dev = (struct r592_device *)data;
5689263412501022fecef844907129ee2513b5a89deMaxim Levitsky	unsigned long flags;
5699263412501022fecef844907129ee2513b5a89deMaxim Levitsky
5709263412501022fecef844907129ee2513b5a89deMaxim Levitsky	while (!kthread_should_stop()) {
5719263412501022fecef844907129ee2513b5a89deMaxim Levitsky		spin_lock_irqsave(&dev->io_thread_lock, flags);
5729263412501022fecef844907129ee2513b5a89deMaxim Levitsky		set_current_state(TASK_INTERRUPTIBLE);
5739263412501022fecef844907129ee2513b5a89deMaxim Levitsky		error = memstick_next_req(dev->host, &dev->req);
5749263412501022fecef844907129ee2513b5a89deMaxim Levitsky		spin_unlock_irqrestore(&dev->io_thread_lock, flags);
5759263412501022fecef844907129ee2513b5a89deMaxim Levitsky
5769263412501022fecef844907129ee2513b5a89deMaxim Levitsky		if (error) {
5779263412501022fecef844907129ee2513b5a89deMaxim Levitsky			if (error == -ENXIO || error == -EAGAIN) {
5789263412501022fecef844907129ee2513b5a89deMaxim Levitsky				dbg_verbose("IO: done IO, sleeping");
5799263412501022fecef844907129ee2513b5a89deMaxim Levitsky			} else {
5809263412501022fecef844907129ee2513b5a89deMaxim Levitsky				dbg("IO: unknown error from "
5819263412501022fecef844907129ee2513b5a89deMaxim Levitsky					"memstick_next_req %d", error);
5829263412501022fecef844907129ee2513b5a89deMaxim Levitsky			}
5839263412501022fecef844907129ee2513b5a89deMaxim Levitsky
5849263412501022fecef844907129ee2513b5a89deMaxim Levitsky			if (kthread_should_stop())
5859263412501022fecef844907129ee2513b5a89deMaxim Levitsky				set_current_state(TASK_RUNNING);
5869263412501022fecef844907129ee2513b5a89deMaxim Levitsky
5879263412501022fecef844907129ee2513b5a89deMaxim Levitsky			schedule();
5889263412501022fecef844907129ee2513b5a89deMaxim Levitsky		} else {
5899263412501022fecef844907129ee2513b5a89deMaxim Levitsky			set_current_state(TASK_RUNNING);
5909263412501022fecef844907129ee2513b5a89deMaxim Levitsky			r592_execute_tpc(dev);
5919263412501022fecef844907129ee2513b5a89deMaxim Levitsky		}
5929263412501022fecef844907129ee2513b5a89deMaxim Levitsky	}
5939263412501022fecef844907129ee2513b5a89deMaxim Levitsky	return 0;
5949263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
5959263412501022fecef844907129ee2513b5a89deMaxim Levitsky
5969263412501022fecef844907129ee2513b5a89deMaxim Levitsky/* Reprogram chip to detect change in card state */
5979263412501022fecef844907129ee2513b5a89deMaxim Levitsky/* eg, if card is detected, arm it to detect removal, and vice versa */
5989263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic void r592_update_card_detect(struct r592_device *dev)
5999263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
6009263412501022fecef844907129ee2513b5a89deMaxim Levitsky	u32 reg = r592_read_reg(dev, R592_REG_MSC);
6019263412501022fecef844907129ee2513b5a89deMaxim Levitsky	bool card_detected = reg & R592_REG_MSC_PRSNT;
6029263412501022fecef844907129ee2513b5a89deMaxim Levitsky
6039263412501022fecef844907129ee2513b5a89deMaxim Levitsky	dbg("update card detect. card state: %s", card_detected ?
6049263412501022fecef844907129ee2513b5a89deMaxim Levitsky		"present" : "absent");
6059263412501022fecef844907129ee2513b5a89deMaxim Levitsky
6069263412501022fecef844907129ee2513b5a89deMaxim Levitsky	reg &= ~((R592_REG_MSC_IRQ_REMOVE | R592_REG_MSC_IRQ_INSERT) << 16);
6079263412501022fecef844907129ee2513b5a89deMaxim Levitsky
6089263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (card_detected)
6099263412501022fecef844907129ee2513b5a89deMaxim Levitsky		reg |= (R592_REG_MSC_IRQ_REMOVE << 16);
6109263412501022fecef844907129ee2513b5a89deMaxim Levitsky	else
6119263412501022fecef844907129ee2513b5a89deMaxim Levitsky		reg |= (R592_REG_MSC_IRQ_INSERT << 16);
6129263412501022fecef844907129ee2513b5a89deMaxim Levitsky
6139263412501022fecef844907129ee2513b5a89deMaxim Levitsky	r592_write_reg(dev, R592_REG_MSC, reg);
6149263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
6159263412501022fecef844907129ee2513b5a89deMaxim Levitsky
6169263412501022fecef844907129ee2513b5a89deMaxim Levitsky/* Timer routine that fires 1 second after last card detection event, */
6179263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic void r592_detect_timer(long unsigned int data)
6189263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
6199263412501022fecef844907129ee2513b5a89deMaxim Levitsky	struct r592_device *dev = (struct r592_device *)data;
6209263412501022fecef844907129ee2513b5a89deMaxim Levitsky	r592_update_card_detect(dev);
6219263412501022fecef844907129ee2513b5a89deMaxim Levitsky	memstick_detect_change(dev->host);
6229263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
6239263412501022fecef844907129ee2513b5a89deMaxim Levitsky
6249263412501022fecef844907129ee2513b5a89deMaxim Levitsky/* Interrupt handler */
6259263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic irqreturn_t r592_irq(int irq, void *data)
6269263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
6279263412501022fecef844907129ee2513b5a89deMaxim Levitsky	struct r592_device *dev = (struct r592_device *)data;
6289263412501022fecef844907129ee2513b5a89deMaxim Levitsky	irqreturn_t ret = IRQ_NONE;
6299263412501022fecef844907129ee2513b5a89deMaxim Levitsky	u32 reg;
6309263412501022fecef844907129ee2513b5a89deMaxim Levitsky	u16 irq_enable, irq_status;
6319263412501022fecef844907129ee2513b5a89deMaxim Levitsky	unsigned long flags;
6329263412501022fecef844907129ee2513b5a89deMaxim Levitsky	int error;
6339263412501022fecef844907129ee2513b5a89deMaxim Levitsky
6349263412501022fecef844907129ee2513b5a89deMaxim Levitsky	spin_lock_irqsave(&dev->irq_lock, flags);
6359263412501022fecef844907129ee2513b5a89deMaxim Levitsky
6369263412501022fecef844907129ee2513b5a89deMaxim Levitsky	reg = r592_read_reg(dev, R592_REG_MSC);
6379263412501022fecef844907129ee2513b5a89deMaxim Levitsky	irq_enable = reg >> 16;
6389263412501022fecef844907129ee2513b5a89deMaxim Levitsky	irq_status = reg & 0xFFFF;
6399263412501022fecef844907129ee2513b5a89deMaxim Levitsky
6409263412501022fecef844907129ee2513b5a89deMaxim Levitsky	/* Ack the interrupts */
6419263412501022fecef844907129ee2513b5a89deMaxim Levitsky	reg &= ~irq_status;
6429263412501022fecef844907129ee2513b5a89deMaxim Levitsky	r592_write_reg(dev, R592_REG_MSC, reg);
6439263412501022fecef844907129ee2513b5a89deMaxim Levitsky
6449263412501022fecef844907129ee2513b5a89deMaxim Levitsky	/* Get the IRQ status minus bits that aren't enabled */
6459263412501022fecef844907129ee2513b5a89deMaxim Levitsky	irq_status &= (irq_enable);
6469263412501022fecef844907129ee2513b5a89deMaxim Levitsky
6479263412501022fecef844907129ee2513b5a89deMaxim Levitsky	/* Due to limitation of memstick core, we don't look at bits that
6489263412501022fecef844907129ee2513b5a89deMaxim Levitsky		indicate that card was removed/inserted and/or present */
6499263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (irq_status & (R592_REG_MSC_IRQ_INSERT | R592_REG_MSC_IRQ_REMOVE)) {
6509263412501022fecef844907129ee2513b5a89deMaxim Levitsky
6519263412501022fecef844907129ee2513b5a89deMaxim Levitsky		bool card_was_added = irq_status & R592_REG_MSC_IRQ_INSERT;
6529263412501022fecef844907129ee2513b5a89deMaxim Levitsky		ret = IRQ_HANDLED;
6539263412501022fecef844907129ee2513b5a89deMaxim Levitsky
6549263412501022fecef844907129ee2513b5a89deMaxim Levitsky		message("IRQ: card %s", card_was_added ? "added" : "removed");
6559263412501022fecef844907129ee2513b5a89deMaxim Levitsky
6569263412501022fecef844907129ee2513b5a89deMaxim Levitsky		mod_timer(&dev->detect_timer,
6579263412501022fecef844907129ee2513b5a89deMaxim Levitsky			jiffies + msecs_to_jiffies(card_was_added ? 500 : 50));
6589263412501022fecef844907129ee2513b5a89deMaxim Levitsky	}
6599263412501022fecef844907129ee2513b5a89deMaxim Levitsky
6609263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (irq_status &
6619263412501022fecef844907129ee2513b5a89deMaxim Levitsky		(R592_REG_MSC_FIFO_DMA_DONE | R592_REG_MSC_FIFO_DMA_ERR)) {
6629263412501022fecef844907129ee2513b5a89deMaxim Levitsky		ret = IRQ_HANDLED;
6639263412501022fecef844907129ee2513b5a89deMaxim Levitsky
6649263412501022fecef844907129ee2513b5a89deMaxim Levitsky		if (irq_status & R592_REG_MSC_FIFO_DMA_ERR) {
6659263412501022fecef844907129ee2513b5a89deMaxim Levitsky			message("IRQ: DMA error");
6669263412501022fecef844907129ee2513b5a89deMaxim Levitsky			error = -EIO;
6679263412501022fecef844907129ee2513b5a89deMaxim Levitsky		} else {
6689263412501022fecef844907129ee2513b5a89deMaxim Levitsky			dbg_verbose("IRQ: dma done");
6699263412501022fecef844907129ee2513b5a89deMaxim Levitsky			error = 0;
6709263412501022fecef844907129ee2513b5a89deMaxim Levitsky		}
6719263412501022fecef844907129ee2513b5a89deMaxim Levitsky
6729263412501022fecef844907129ee2513b5a89deMaxim Levitsky		r592_stop_dma(dev, error);
6739263412501022fecef844907129ee2513b5a89deMaxim Levitsky		complete(&dev->dma_done);
6749263412501022fecef844907129ee2513b5a89deMaxim Levitsky	}
6759263412501022fecef844907129ee2513b5a89deMaxim Levitsky
6769263412501022fecef844907129ee2513b5a89deMaxim Levitsky	spin_unlock_irqrestore(&dev->irq_lock, flags);
6779263412501022fecef844907129ee2513b5a89deMaxim Levitsky	return ret;
6789263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
6799263412501022fecef844907129ee2513b5a89deMaxim Levitsky
6809263412501022fecef844907129ee2513b5a89deMaxim Levitsky/* External inteface: set settings */
6819263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic int r592_set_param(struct memstick_host *host,
6829263412501022fecef844907129ee2513b5a89deMaxim Levitsky			enum memstick_param param, int value)
6839263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
6849263412501022fecef844907129ee2513b5a89deMaxim Levitsky	struct r592_device *dev = memstick_priv(host);
6859263412501022fecef844907129ee2513b5a89deMaxim Levitsky
6869263412501022fecef844907129ee2513b5a89deMaxim Levitsky	switch (param) {
6879263412501022fecef844907129ee2513b5a89deMaxim Levitsky	case MEMSTICK_POWER:
6889263412501022fecef844907129ee2513b5a89deMaxim Levitsky		switch (value) {
6899263412501022fecef844907129ee2513b5a89deMaxim Levitsky		case MEMSTICK_POWER_ON:
6909263412501022fecef844907129ee2513b5a89deMaxim Levitsky			return r592_enable_device(dev, true);
6919263412501022fecef844907129ee2513b5a89deMaxim Levitsky		case MEMSTICK_POWER_OFF:
6929263412501022fecef844907129ee2513b5a89deMaxim Levitsky			return r592_enable_device(dev, false);
6939263412501022fecef844907129ee2513b5a89deMaxim Levitsky		default:
6949263412501022fecef844907129ee2513b5a89deMaxim Levitsky			return -EINVAL;
6959263412501022fecef844907129ee2513b5a89deMaxim Levitsky		}
6969263412501022fecef844907129ee2513b5a89deMaxim Levitsky	case MEMSTICK_INTERFACE:
6979263412501022fecef844907129ee2513b5a89deMaxim Levitsky		switch (value) {
6989263412501022fecef844907129ee2513b5a89deMaxim Levitsky		case MEMSTICK_SERIAL:
6999263412501022fecef844907129ee2513b5a89deMaxim Levitsky			return r592_set_mode(dev, 0);
7009263412501022fecef844907129ee2513b5a89deMaxim Levitsky		case MEMSTICK_PAR4:
7019263412501022fecef844907129ee2513b5a89deMaxim Levitsky			return r592_set_mode(dev, 1);
7029263412501022fecef844907129ee2513b5a89deMaxim Levitsky		default:
7039263412501022fecef844907129ee2513b5a89deMaxim Levitsky			return -EINVAL;
7049263412501022fecef844907129ee2513b5a89deMaxim Levitsky		}
7059263412501022fecef844907129ee2513b5a89deMaxim Levitsky	default:
7069263412501022fecef844907129ee2513b5a89deMaxim Levitsky		return -EINVAL;
7079263412501022fecef844907129ee2513b5a89deMaxim Levitsky	}
7089263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
7099263412501022fecef844907129ee2513b5a89deMaxim Levitsky
7109263412501022fecef844907129ee2513b5a89deMaxim Levitsky/* External interface: submit requests */
7119263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic void r592_submit_req(struct memstick_host *host)
7129263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
7139263412501022fecef844907129ee2513b5a89deMaxim Levitsky	struct r592_device *dev = memstick_priv(host);
7149263412501022fecef844907129ee2513b5a89deMaxim Levitsky	unsigned long flags;
7159263412501022fecef844907129ee2513b5a89deMaxim Levitsky
7169263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (dev->req)
7179263412501022fecef844907129ee2513b5a89deMaxim Levitsky		return;
7189263412501022fecef844907129ee2513b5a89deMaxim Levitsky
7199263412501022fecef844907129ee2513b5a89deMaxim Levitsky	spin_lock_irqsave(&dev->io_thread_lock, flags);
7209263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (wake_up_process(dev->io_thread))
7219263412501022fecef844907129ee2513b5a89deMaxim Levitsky		dbg_verbose("IO thread woken to process requests");
7229263412501022fecef844907129ee2513b5a89deMaxim Levitsky	spin_unlock_irqrestore(&dev->io_thread_lock, flags);
7239263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
7249263412501022fecef844907129ee2513b5a89deMaxim Levitsky
7259263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic const struct pci_device_id r592_pci_id_tbl[] = {
7269263412501022fecef844907129ee2513b5a89deMaxim Levitsky
7279263412501022fecef844907129ee2513b5a89deMaxim Levitsky	{ PCI_VDEVICE(RICOH, 0x0592), },
7289263412501022fecef844907129ee2513b5a89deMaxim Levitsky	{ },
7299263412501022fecef844907129ee2513b5a89deMaxim Levitsky};
7309263412501022fecef844907129ee2513b5a89deMaxim Levitsky
7319263412501022fecef844907129ee2513b5a89deMaxim Levitsky/* Main entry */
7329263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic int r592_probe(struct pci_dev *pdev, const struct pci_device_id *id)
7339263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
7349263412501022fecef844907129ee2513b5a89deMaxim Levitsky	int error = -ENOMEM;
7359263412501022fecef844907129ee2513b5a89deMaxim Levitsky	struct memstick_host *host;
7369263412501022fecef844907129ee2513b5a89deMaxim Levitsky	struct r592_device *dev;
7379263412501022fecef844907129ee2513b5a89deMaxim Levitsky
7389263412501022fecef844907129ee2513b5a89deMaxim Levitsky	/* Allocate memory */
7399263412501022fecef844907129ee2513b5a89deMaxim Levitsky	host = memstick_alloc_host(sizeof(struct r592_device), &pdev->dev);
7409263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (!host)
7419263412501022fecef844907129ee2513b5a89deMaxim Levitsky		goto error1;
7429263412501022fecef844907129ee2513b5a89deMaxim Levitsky
7439263412501022fecef844907129ee2513b5a89deMaxim Levitsky	dev = memstick_priv(host);
7449263412501022fecef844907129ee2513b5a89deMaxim Levitsky	dev->host = host;
7459263412501022fecef844907129ee2513b5a89deMaxim Levitsky	dev->pci_dev = pdev;
7469263412501022fecef844907129ee2513b5a89deMaxim Levitsky	pci_set_drvdata(pdev, dev);
7479263412501022fecef844907129ee2513b5a89deMaxim Levitsky
7489263412501022fecef844907129ee2513b5a89deMaxim Levitsky	/* pci initialization */
7499263412501022fecef844907129ee2513b5a89deMaxim Levitsky	error = pci_enable_device(pdev);
7509263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (error)
7519263412501022fecef844907129ee2513b5a89deMaxim Levitsky		goto error2;
7529263412501022fecef844907129ee2513b5a89deMaxim Levitsky
7539263412501022fecef844907129ee2513b5a89deMaxim Levitsky	pci_set_master(pdev);
7549263412501022fecef844907129ee2513b5a89deMaxim Levitsky	error = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
7559263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (error)
7569263412501022fecef844907129ee2513b5a89deMaxim Levitsky		goto error3;
7579263412501022fecef844907129ee2513b5a89deMaxim Levitsky
7589263412501022fecef844907129ee2513b5a89deMaxim Levitsky	error = pci_request_regions(pdev, DRV_NAME);
7599263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (error)
7609263412501022fecef844907129ee2513b5a89deMaxim Levitsky		goto error3;
7619263412501022fecef844907129ee2513b5a89deMaxim Levitsky
7629263412501022fecef844907129ee2513b5a89deMaxim Levitsky	dev->mmio = pci_ioremap_bar(pdev, 0);
7639263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (!dev->mmio)
7649263412501022fecef844907129ee2513b5a89deMaxim Levitsky		goto error4;
7659263412501022fecef844907129ee2513b5a89deMaxim Levitsky
7669263412501022fecef844907129ee2513b5a89deMaxim Levitsky	dev->irq = pdev->irq;
7679263412501022fecef844907129ee2513b5a89deMaxim Levitsky	spin_lock_init(&dev->irq_lock);
7689263412501022fecef844907129ee2513b5a89deMaxim Levitsky	spin_lock_init(&dev->io_thread_lock);
7699263412501022fecef844907129ee2513b5a89deMaxim Levitsky	init_completion(&dev->dma_done);
7709263412501022fecef844907129ee2513b5a89deMaxim Levitsky	INIT_KFIFO(dev->pio_fifo);
7719263412501022fecef844907129ee2513b5a89deMaxim Levitsky	setup_timer(&dev->detect_timer,
7729263412501022fecef844907129ee2513b5a89deMaxim Levitsky		r592_detect_timer, (long unsigned int)dev);
7739263412501022fecef844907129ee2513b5a89deMaxim Levitsky
7749263412501022fecef844907129ee2513b5a89deMaxim Levitsky	/* Host initialization */
7759263412501022fecef844907129ee2513b5a89deMaxim Levitsky	host->caps = MEMSTICK_CAP_PAR4;
7769263412501022fecef844907129ee2513b5a89deMaxim Levitsky	host->request = r592_submit_req;
7779263412501022fecef844907129ee2513b5a89deMaxim Levitsky	host->set_param = r592_set_param;
7789263412501022fecef844907129ee2513b5a89deMaxim Levitsky	r592_check_dma(dev);
7799263412501022fecef844907129ee2513b5a89deMaxim Levitsky
7809263412501022fecef844907129ee2513b5a89deMaxim Levitsky	dev->io_thread = kthread_run(r592_process_thread, dev, "r592_io");
7819263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (IS_ERR(dev->io_thread)) {
7829263412501022fecef844907129ee2513b5a89deMaxim Levitsky		error = PTR_ERR(dev->io_thread);
7839263412501022fecef844907129ee2513b5a89deMaxim Levitsky		goto error5;
7849263412501022fecef844907129ee2513b5a89deMaxim Levitsky	}
7859263412501022fecef844907129ee2513b5a89deMaxim Levitsky
7869263412501022fecef844907129ee2513b5a89deMaxim Levitsky	/* This is just a precation, so don't fail */
7879263412501022fecef844907129ee2513b5a89deMaxim Levitsky	dev->dummy_dma_page = pci_alloc_consistent(pdev, PAGE_SIZE,
7889263412501022fecef844907129ee2513b5a89deMaxim Levitsky		&dev->dummy_dma_page_physical_address);
7899263412501022fecef844907129ee2513b5a89deMaxim Levitsky	r592_stop_dma(dev , 0);
7909263412501022fecef844907129ee2513b5a89deMaxim Levitsky
7919263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (request_irq(dev->irq, &r592_irq, IRQF_SHARED,
7929263412501022fecef844907129ee2513b5a89deMaxim Levitsky			  DRV_NAME, dev))
7939263412501022fecef844907129ee2513b5a89deMaxim Levitsky		goto error6;
7949263412501022fecef844907129ee2513b5a89deMaxim Levitsky
7959263412501022fecef844907129ee2513b5a89deMaxim Levitsky	r592_update_card_detect(dev);
7969263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (memstick_add_host(host))
7979263412501022fecef844907129ee2513b5a89deMaxim Levitsky		goto error7;
7989263412501022fecef844907129ee2513b5a89deMaxim Levitsky
79925985edcedea6396277003854657b5f3cb31a628Lucas De Marchi	message("driver successfully loaded");
8009263412501022fecef844907129ee2513b5a89deMaxim Levitsky	return 0;
8019263412501022fecef844907129ee2513b5a89deMaxim Levitskyerror7:
8029263412501022fecef844907129ee2513b5a89deMaxim Levitsky	free_irq(dev->irq, dev);
8039263412501022fecef844907129ee2513b5a89deMaxim Levitskyerror6:
8049263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (dev->dummy_dma_page)
8059263412501022fecef844907129ee2513b5a89deMaxim Levitsky		pci_free_consistent(pdev, PAGE_SIZE, dev->dummy_dma_page,
8069263412501022fecef844907129ee2513b5a89deMaxim Levitsky			dev->dummy_dma_page_physical_address);
8079263412501022fecef844907129ee2513b5a89deMaxim Levitsky
8089263412501022fecef844907129ee2513b5a89deMaxim Levitsky	kthread_stop(dev->io_thread);
8099263412501022fecef844907129ee2513b5a89deMaxim Levitskyerror5:
8109263412501022fecef844907129ee2513b5a89deMaxim Levitsky	iounmap(dev->mmio);
8119263412501022fecef844907129ee2513b5a89deMaxim Levitskyerror4:
8129263412501022fecef844907129ee2513b5a89deMaxim Levitsky	pci_release_regions(pdev);
8139263412501022fecef844907129ee2513b5a89deMaxim Levitskyerror3:
8149263412501022fecef844907129ee2513b5a89deMaxim Levitsky	pci_disable_device(pdev);
8159263412501022fecef844907129ee2513b5a89deMaxim Levitskyerror2:
8169263412501022fecef844907129ee2513b5a89deMaxim Levitsky	memstick_free_host(host);
8179263412501022fecef844907129ee2513b5a89deMaxim Levitskyerror1:
8189263412501022fecef844907129ee2513b5a89deMaxim Levitsky	return error;
8199263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
8209263412501022fecef844907129ee2513b5a89deMaxim Levitsky
8219263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic void r592_remove(struct pci_dev *pdev)
8229263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
8239263412501022fecef844907129ee2513b5a89deMaxim Levitsky	int error = 0;
8249263412501022fecef844907129ee2513b5a89deMaxim Levitsky	struct r592_device *dev = pci_get_drvdata(pdev);
8259263412501022fecef844907129ee2513b5a89deMaxim Levitsky
8269263412501022fecef844907129ee2513b5a89deMaxim Levitsky	/* Stop the processing thread.
8279263412501022fecef844907129ee2513b5a89deMaxim Levitsky	That ensures that we won't take any more requests */
8289263412501022fecef844907129ee2513b5a89deMaxim Levitsky	kthread_stop(dev->io_thread);
8299263412501022fecef844907129ee2513b5a89deMaxim Levitsky
8309263412501022fecef844907129ee2513b5a89deMaxim Levitsky	r592_enable_device(dev, false);
8319263412501022fecef844907129ee2513b5a89deMaxim Levitsky
8329263412501022fecef844907129ee2513b5a89deMaxim Levitsky	while (!error && dev->req) {
8339263412501022fecef844907129ee2513b5a89deMaxim Levitsky		dev->req->error = -ETIME;
8349263412501022fecef844907129ee2513b5a89deMaxim Levitsky		error = memstick_next_req(dev->host, &dev->req);
8359263412501022fecef844907129ee2513b5a89deMaxim Levitsky	}
8369263412501022fecef844907129ee2513b5a89deMaxim Levitsky	memstick_remove_host(dev->host);
8379263412501022fecef844907129ee2513b5a89deMaxim Levitsky
8389263412501022fecef844907129ee2513b5a89deMaxim Levitsky	free_irq(dev->irq, dev);
8399263412501022fecef844907129ee2513b5a89deMaxim Levitsky	iounmap(dev->mmio);
8409263412501022fecef844907129ee2513b5a89deMaxim Levitsky	pci_release_regions(pdev);
8419263412501022fecef844907129ee2513b5a89deMaxim Levitsky	pci_disable_device(pdev);
8429263412501022fecef844907129ee2513b5a89deMaxim Levitsky	memstick_free_host(dev->host);
8439263412501022fecef844907129ee2513b5a89deMaxim Levitsky
8449263412501022fecef844907129ee2513b5a89deMaxim Levitsky	if (dev->dummy_dma_page)
8459263412501022fecef844907129ee2513b5a89deMaxim Levitsky		pci_free_consistent(pdev, PAGE_SIZE, dev->dummy_dma_page,
8469263412501022fecef844907129ee2513b5a89deMaxim Levitsky			dev->dummy_dma_page_physical_address);
8479263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
8489263412501022fecef844907129ee2513b5a89deMaxim Levitsky
8499263412501022fecef844907129ee2513b5a89deMaxim Levitsky#ifdef CONFIG_PM
8509263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic int r592_suspend(struct device *core_dev)
8519263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
8529263412501022fecef844907129ee2513b5a89deMaxim Levitsky	struct pci_dev *pdev = to_pci_dev(core_dev);
8539263412501022fecef844907129ee2513b5a89deMaxim Levitsky	struct r592_device *dev = pci_get_drvdata(pdev);
8549263412501022fecef844907129ee2513b5a89deMaxim Levitsky
8559263412501022fecef844907129ee2513b5a89deMaxim Levitsky	r592_clear_interrupts(dev);
8569263412501022fecef844907129ee2513b5a89deMaxim Levitsky	memstick_suspend_host(dev->host);
8579263412501022fecef844907129ee2513b5a89deMaxim Levitsky	del_timer_sync(&dev->detect_timer);
8589263412501022fecef844907129ee2513b5a89deMaxim Levitsky	return 0;
8599263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
8609263412501022fecef844907129ee2513b5a89deMaxim Levitsky
8619263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic int r592_resume(struct device *core_dev)
8629263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
8639263412501022fecef844907129ee2513b5a89deMaxim Levitsky	struct pci_dev *pdev = to_pci_dev(core_dev);
8649263412501022fecef844907129ee2513b5a89deMaxim Levitsky	struct r592_device *dev = pci_get_drvdata(pdev);
8659263412501022fecef844907129ee2513b5a89deMaxim Levitsky
8669263412501022fecef844907129ee2513b5a89deMaxim Levitsky	r592_clear_interrupts(dev);
8679263412501022fecef844907129ee2513b5a89deMaxim Levitsky	r592_enable_device(dev, false);
8689263412501022fecef844907129ee2513b5a89deMaxim Levitsky	memstick_resume_host(dev->host);
8699263412501022fecef844907129ee2513b5a89deMaxim Levitsky	r592_update_card_detect(dev);
8709263412501022fecef844907129ee2513b5a89deMaxim Levitsky	return 0;
8719263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
8729263412501022fecef844907129ee2513b5a89deMaxim Levitsky
8739263412501022fecef844907129ee2513b5a89deMaxim LevitskySIMPLE_DEV_PM_OPS(r592_pm_ops, r592_suspend, r592_resume);
8749263412501022fecef844907129ee2513b5a89deMaxim Levitsky#endif
8759263412501022fecef844907129ee2513b5a89deMaxim Levitsky
8769263412501022fecef844907129ee2513b5a89deMaxim LevitskyMODULE_DEVICE_TABLE(pci, r592_pci_id_tbl);
8779263412501022fecef844907129ee2513b5a89deMaxim Levitsky
8789263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic struct pci_driver r852_pci_driver = {
8799263412501022fecef844907129ee2513b5a89deMaxim Levitsky	.name		= DRV_NAME,
8809263412501022fecef844907129ee2513b5a89deMaxim Levitsky	.id_table	= r592_pci_id_tbl,
8819263412501022fecef844907129ee2513b5a89deMaxim Levitsky	.probe		= r592_probe,
8829263412501022fecef844907129ee2513b5a89deMaxim Levitsky	.remove		= r592_remove,
8839263412501022fecef844907129ee2513b5a89deMaxim Levitsky#ifdef CONFIG_PM
8849263412501022fecef844907129ee2513b5a89deMaxim Levitsky	.driver.pm	= &r592_pm_ops,
8859263412501022fecef844907129ee2513b5a89deMaxim Levitsky#endif
8869263412501022fecef844907129ee2513b5a89deMaxim Levitsky};
8879263412501022fecef844907129ee2513b5a89deMaxim Levitsky
8889263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic __init int r592_module_init(void)
8899263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
8909263412501022fecef844907129ee2513b5a89deMaxim Levitsky	return pci_register_driver(&r852_pci_driver);
8919263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
8929263412501022fecef844907129ee2513b5a89deMaxim Levitsky
8939263412501022fecef844907129ee2513b5a89deMaxim Levitskystatic void __exit r592_module_exit(void)
8949263412501022fecef844907129ee2513b5a89deMaxim Levitsky{
8959263412501022fecef844907129ee2513b5a89deMaxim Levitsky	pci_unregister_driver(&r852_pci_driver);
8969263412501022fecef844907129ee2513b5a89deMaxim Levitsky}
8979263412501022fecef844907129ee2513b5a89deMaxim Levitsky
8989263412501022fecef844907129ee2513b5a89deMaxim Levitskymodule_init(r592_module_init);
8999263412501022fecef844907129ee2513b5a89deMaxim Levitskymodule_exit(r592_module_exit);
9009263412501022fecef844907129ee2513b5a89deMaxim Levitsky
9015ede9ddfba424b5dad96e7ccd55607875a64ff6cStephen Rothwellmodule_param_named(enable_dma, r592_enable_dma, bool, S_IRUGO);
9029263412501022fecef844907129ee2513b5a89deMaxim LevitskyMODULE_PARM_DESC(enable_dma, "Enable usage of the DMA (default)");
9039263412501022fecef844907129ee2513b5a89deMaxim Levitskymodule_param(debug, int, S_IRUGO | S_IWUSR);
9049263412501022fecef844907129ee2513b5a89deMaxim LevitskyMODULE_PARM_DESC(debug, "Debug level (0-3)");
9059263412501022fecef844907129ee2513b5a89deMaxim Levitsky
9069263412501022fecef844907129ee2513b5a89deMaxim LevitskyMODULE_LICENSE("GPL");
9079263412501022fecef844907129ee2513b5a89deMaxim LevitskyMODULE_AUTHOR("Maxim Levitsky <maximlevitsky@gmail.com>");
9089263412501022fecef844907129ee2513b5a89deMaxim LevitskyMODULE_DESCRIPTION("Ricoh R5C592 Memstick/Memstick PRO card reader driver");
909