File Index
Files and directories
Sign in
FILE

dma-pvr2.c

File preview with syntax highlighting.

linux-6.19.14/arch/sh/drivers/dma/dma-pvr2.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * arch/sh/drivers/dma/dma-pvr2.c
  4 *
  5 * NEC PowerVR 2 (Dreamcast) DMA support
  6 *
  7 * Copyright (C) 2003, 2004  Paul Mundt
  8 */
  9#include <linux/init.h>
 10#include <linux/kernel.h>
 11#include <linux/module.h>
 12#include <linux/interrupt.h>
 13#include <mach/sysasic.h>
 14#include <mach/dma.h>
 15#include <asm/dma.h>
 16#include <asm/io.h>
 17
 18static unsigned int xfer_complete;
 19static int count;
 20
 21static irqreturn_t pvr2_dma_interrupt(int irq, void *dev_id)
 22{
 23	if (get_dma_residue(PVR2_CASCADE_CHAN)) {
 24		printk(KERN_WARNING "DMA: SH DMAC did not complete transfer "
 25		       "on channel %d, waiting..\n", PVR2_CASCADE_CHAN);
 26		dma_wait_for_completion(PVR2_CASCADE_CHAN);
 27	}
 28
 29	if (count++ < 10)
 30		pr_debug("Got a pvr2 dma interrupt for channel %d\n",
 31			 irq - HW_EVENT_PVR2_DMA);
 32
 33	xfer_complete = 1;
 34
 35	return IRQ_HANDLED;
 36}
 37
 38static int pvr2_request_dma(struct dma_channel *chan)
 39{
 40	if (__raw_readl(PVR2_DMA_MODE) != 0)
 41		return -EBUSY;
 42
 43	__raw_writel(0, PVR2_DMA_LMMODE0);
 44
 45	return 0;
 46}
 47
 48static int pvr2_get_dma_residue(struct dma_channel *chan)
 49{
 50	return xfer_complete == 0;
 51}
 52
 53static int pvr2_xfer_dma(struct dma_channel *chan)
 54{
 55	if (chan->sar || !chan->dar)
 56		return -EINVAL;
 57
 58	xfer_complete = 0;
 59
 60	__raw_writel(chan->dar, PVR2_DMA_ADDR);
 61	__raw_writel(chan->count, PVR2_DMA_COUNT);
 62	__raw_writel(chan->mode & DMA_MODE_MASK, PVR2_DMA_MODE);
 63
 64	return 0;
 65}
 66
 67static struct dma_ops pvr2_dma_ops = {
 68	.request	= pvr2_request_dma,
 69	.get_residue	= pvr2_get_dma_residue,
 70	.xfer		= pvr2_xfer_dma,
 71};
 72
 73static struct dma_info pvr2_dma_info = {
 74	.name		= "pvr2_dmac",
 75	.nr_channels	= 1,
 76	.ops		= &pvr2_dma_ops,
 77	.flags		= DMAC_CHANNELS_TEI_CAPABLE,
 78};
 79
 80static int __init pvr2_dma_init(void)
 81{
 82	if (request_irq(HW_EVENT_PVR2_DMA, pvr2_dma_interrupt, 0,
 83			"pvr2 DMA handler", NULL))
 84		pr_err("Failed to register pvr2 DMA handler interrupt\n");
 85	request_dma(PVR2_CASCADE_CHAN, "pvr2 cascade");
 86
 87	return register_dmac(&pvr2_dma_info);
 88}
 89
 90static void __exit pvr2_dma_exit(void)
 91{
 92	free_dma(PVR2_CASCADE_CHAN);
 93	free_irq(HW_EVENT_PVR2_DMA, 0);
 94	unregister_dmac(&pvr2_dma_info);
 95}
 96
 97subsys_initcall(pvr2_dma_init);
 98module_exit(pvr2_dma_exit);
 99
100MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>");
101MODULE_DESCRIPTION("NEC PowerVR 2 DMA driver");
102MODULE_LICENSE("GPL v2");
~/ Read-only file preview.