/* jazz_esp.c: ESP front-end for MIPS JAZZ systems.
 *
 * Copyright (C) 2007 Thomas Bogendörfer (tsbogend@alpha.frankende)
 */

#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>

#include <asm/irq.h>
#include <asm/io.h>
#include <asm/dma.h>

#include <asm/jazz.h>
#include <asm/jazzdma.h>

#include <scsi/scsi_host.h>

#include "esp_scsi.h"

#define DRV_MODULE_NAME		"jazz_esp"
#define PFX DRV_MODULE_NAME	": "
#define DRV_VERSION		"1.000"
#define DRV_MODULE_RELDATE	"May 19, 2007"

static void jazz_esp_write8(struct esp *esp, u8 val, unsigned long reg)
{
	*(volatile u8 *)(esp->regs + reg) = val;
}

static u8 jazz_esp_read8(struct esp *esp, unsigned long reg)
{
	return *(volatile u8 *)(esp->regs + reg);
}

static dma_addr_t jazz_esp_map_single(struct esp *esp, void *buf,
				      size_t sz, int dir)
{
	return dma_map_single(esp->dev, buf, sz, dir);
}

static int jazz_esp_map_sg(struct esp *esp, struct scatterlist *sg,
				  int num_sg, int dir)
{
	return dma_map_sg(esp->dev, sg, num_sg, dir);
}

static void jazz_esp_unmap_single(struct esp *esp, dma_addr_t addr,
				  size_t sz, int dir)
{
	dma_unmap_single(esp->dev, addr, sz, dir);
}

static void jazz_esp_unmap_sg(struct esp *esp, struct scatterlist *sg,
			      int num_sg, int dir)
{
	dma_unmap_sg(esp->dev, sg, num_sg, dir);
}

static int jazz_esp_irq_pending(struct esp *esp)
{
	if (jazz_esp_read8(esp, ESP_STATUS) & ESP_STAT_INTR)
		return 1;
	return 0;
}

static void jazz_esp_reset_dma(struct esp *esp)
{
	vdma_disable ((int)esp->dma_regs);
}

static void jazz_esp_dma_drain(struct esp *esp)
{
	/* nothing to do */
}

static void jazz_esp_dma_invalidate(struct esp *esp)
{
	vdma_disable ((int)esp->dma_regs);
}

static void jazz_esp_send_dma_cmd(struct esp *esp, u32 addr, u32 esp_count,
				  u32 dma_count, int write, u8 cmd)
{
	BUG_ON(!(cmd & ESP_CMD_DMA));

	jazz_esp_write8(esp, (esp_count >> 0) & 0xff, ESP_TCLOW);
	jazz_esp_write8(esp, (esp_count >> 8) & 0xff, ESP_TCMED);
	vdma_disable ((int)esp->dma_regs);
	if (write)
		vdma_set_mode ((int)esp->dma_regs, DMA_MODE_READ);
	else
		vdma_set_mode ((int)esp->dma_regs, DMA_MODE_WRITE);

	vdma_set_addr ((int)esp->dma_regs, addr);
	vdma_set_count ((int)esp->dma_regs, dma_count);
	vdma_enable ((int)esp->dma_regs);

	scsi_esp_cmd(esp, cmd);
}

static int jazz_esp_dma_error(struct esp *esp)
{
	u32 enable = vdma_get_enable((int)esp->dma_regs);

	if (enable & (R4030_MEM_INTR|R4030_ADDR_INTR))
		return 1;

	return 0;
}

static const struct esp_driver_ops jazz_esp_ops = {
	.esp_write8	=	jazz_esp_write8,
	.esp_read8	=	jazz_esp_read8,
	.map_single	=	jazz_esp_map_single,
	.map_sg		=	jazz_esp_map_sg,
	.unmap_single	=	jazz_esp_unmap_single,
	.unmap_sg	=	jazz_esp_unmap_sg,
	.irq_pending	=	jazz_esp_irq_pending,
	.reset_dma	=	jazz_esp_reset_dma,
	.dma_drain	=	jazz_esp_dma_drain,
	.dma_invalidate	=	jazz_esp_dma_invalidate,
	.send_dma_cmd	=	jazz_esp_send_dma_cmd,
	.dma_error	=	jazz_esp_dma_error,
};

static int __devinit esp_jazz_probe(struct platform_device *dev)
{
	struct scsi_host_template *tpnt = &scsi_esp_template;
	struct Scsi_Host *host;
	struct esp *esp;
	struct resource *res;
	int err;

	host = scsi_host_alloc(tpnt, sizeof(struct esp));

	err = -ENOMEM;
	if (!host)
		goto fail;

	host->max_id = 8;
	esp = host_to_esp(host);

	esp->host = host;
	esp->dev = dev;
	esp->ops = &jazz_esp_ops;

	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
	if (!res)
		goto fail_unlink;

	esp->regs = (void __iomem *)res->start;
	if (!esp->regs)
		goto fail_unlink;

	res = platform_get_resource(dev, IORESOURCE_MEM, 1);
	if (!res)
		goto fail_unlink;

	esp->dma_regs = (void __iomem *)res->start;

	esp->command_block = dma_alloc_coherent(esp->dev, 16,
						&esp->command_block_dma,
						GFP_KERNEL);
	if (!esp->command_block)
		goto fail_unmap_regs;

	host->irq = platform_get_irq(dev, 0);
	err = request_irq(host->irq, scsi_esp_intr, IRQF_SHARED, "ESP", esp);
	if (err < 0)
		goto fail_unmap_command_block;

	esp->scsi_id = 7;
	esp->host->this_id = esp->scsi_id;
	esp->scsi_id_mask = (1 << esp->scsi_id);
	esp->cfreq = 40000000;

	dev_set_drvdata(&dev->dev, esp);

	err = scsi_esp_register(esp, &dev->dev);
	if (err)
		goto fail_free_irq;

	return 0;

fail_free_irq:
	free_irq(host->irq, esp);
fail_unmap_command_block:
	dma_free_coherent(esp->dev, 16,
			  esp->command_block,
			  esp->command_block_dma);
fail_unmap_regs:
fail_unlink:
	scsi_host_put(host);
fail:
	return err;
}

static int __devexit esp_jazz_remove(struct platform_device *dev)
{
	struct esp *esp = dev_get_drvdata(&dev->dev);
	unsigned int irq = esp->host->irq;

	scsi_esp_unregister(esp);

	free_irq(irq, esp);
	dma_free_coherent(esp->dev, 16,
			  esp->command_block,
			  esp->command_block_dma);

	scsi_host_put(esp->host);

	return 0;
}

static struct platform_driver esp_jazz_driver = {
	.probe		= esp_jazz_probe,
	.remove		= __devexit_p(esp_jazz_remove),
	.driver	= {
		.name	= "jazz_esp",
	},
};

static int __init jazz_esp_init(void)
{
	return platform_driver_register(&esp_jazz_driver);
}

static void __exit jazz_esp_exit(void)
{
	platform_driver_unregister(&esp_jazz_driver);
}

MODULE_DESCRIPTION("JAZZ ESP SCSI driver");
MODULE_AUTHOR("Thomas Bogendoerfer (tsbogend@alpha.franken.de)");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);

module_init(jazz_esp_init);
module_exit(jazz_esp_exit);
