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