// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright © 2009 - Maxim Levitsky
* driver for Ricoh xD readers
*/
#define DRV_NAME "r852"
#define pr_fmt(fmt) DRV_NAME ": " fmt
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/jiffies.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <asm/byteorder.h>
#include <linux/sched.h>
#include "sm_common.h"
#include "r852.h"
static bool r852_enable_dma = 1;
module_param(r852_enable_dma, bool, S_IRUGO);
MODULE_PARM_DESC(r852_enable_dma, "Enable usage of the DMA (default)");
static int debug;
module_param(debug, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug level (0-2)");
/* read register */
static inline uint8_t r852_read_reg(struct r852_device *dev, int address)
{
uint8_t reg = readb(dev->mmio + address);
return reg;
}
/* write register */
static inline void r852_write_reg(struct r852_device *dev,
int address, uint8_t value)
{
writeb(value, dev->mmio + address);
}
/* read dword sized register */
static inline uint32_t r852_read_reg_dword(struct r852_device *dev, int address)
{
uint32_t reg = le32_to_cpu(readl(dev->mmio + address));
return reg;
}
/* write dword sized register */
static inline void r852_write_reg_dword(struct r852_device *dev,
int address, uint32_t value)
{
writel(cpu_to_le32(value), dev->mmio + address);
}
/* returns pointer to our private structure */
static inline struct r852_device *r852_get_dev(struct mtd_info *mtd)
{
struct nand_chip *chip = mtd_to_nand(mtd);
return nand_get_controller_data(chip);
}
/* check if controller supports dma */
static void r852_dma_test(struct r852_device *dev)
{
dev->dma_usable = (r852_read_reg(dev, R852_DMA_CAP) &
(R852_DMA1 | R852_DMA2)) == (R852_DMA1 | R852_DMA2);
if (!dev->dma_usable)
message("Non dma capable device detected, dma disabled");
if (!r852_enable_dma) {
message("disabling dma on user request");
dev->dma_usable = 0;
}
}
/*
* Enable dma. Enables ether first or second stage of the DMA,
* Expects dev->dma_dir and dev->dma_state be set
*/
static void r852_dma_enable(struct r852_device *dev)
{
uint8_t dma_reg, dma_irq_reg;
/* Set up dma settings */
dma_reg = r852_read_reg_dword(dev, R852_DMA_SETTINGS);
dma_reg &= ~(R852_DMA_READ | R852_DMA_INTERNAL | R852_DMA_MEMORY);
if (dev->dma_dir)
dma_reg |= R852_DMA_READ;
if (dev->dma_state == DMA_INTERNAL) {
dma_reg |= R852_DMA_INTERNAL;
/* Precaution to make sure HW doesn't write */
/* to random kernel memory */
r852_write_reg_dword(dev, R852_DMA_ADDR,
cpu_to_le32(dev->phys_bounce_buffer));
} else {
dma_reg |= R852_DMA_MEMORY;
r852_write_reg_dword(dev, R852_DMA_ADDR,
cpu_to_le32(dev->phys_dma_addr));
}
/* Precaution: make sure write reached the device */
r852_read_reg_dword(dev, R852_DMA_ADDR);
r852_write_reg_dword(dev, R852_DMA_SETTINGS, dma_reg);
/* Set dma irq */
dma_irq_reg = r852_read_reg_dword(dev, R852_DMA_IRQ_ENABLE);
r852_write_reg_dword(dev, R852_DMA_IRQ_ENABLE,
dma_irq_reg |
R852_DMA_IRQ_INTERNAL |
R852_DMA_IRQ_ERROR |
R852_DMA_IRQ_MEMORY);
}
/*
* Disable dma, called from the interrupt handler, which specifies
* success of the operation via 'error' argument
*/
static void r852_dma_done(struct r852_device *dev, int error)
{
WARN_ON(dev->dma_stage == 0);
r852_write_reg_dword(dev, R852_DMA_IRQ_STA,
r852_read_reg_dword(dev, R852_DMA_IRQ_STA));
r852_write_reg_dword(dev, R852_DMA_SETTINGS, 0);
r852_write_reg_dword(dev, R852_DMA_IRQ_ENABLE, 0);
/* Precaution to make sure HW doesn't write to random kernel memory */
r852_write_reg_dword(dev, R852_DMA_ADDR,
cpu_to_le32(dev->phys_bounce_buffer));
r852_read_reg_dword(dev, R852_DMA_ADDR);
dev->dma_error = error;
dev->dma_stage = 0;
if (dev->phys_dma_addr && dev->phys_dma_addr != dev->phys_bounce_buffer)
dma_unmap_single(&dev->pci_dev->dev, dev->phys_dma_addr,
R852_DMA_LEN,
dev->dma_dir ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
}
/*
* Wait, till dma is done, which includes both phases of it
*/
static int r852_dma_wait(struct r852_device *dev)
{
long timeout = wait_for_completion_timeout(&dev->dma_done,
msecs_to_jiffies(1000));
if (!timeout) {
dbg("timeout waiting for DMA interrupt");
return -ETIMEDOUT;
}
return 0;
}
/*
* Read/Write one page using dma. Only pages can be read (512 bytes)
*/
static void r852_do_dma(struct r852_device *dev