Commit abf94132 authored by Paul Mundt's avatar Paul Mundt Committed by Linus Torvalds

[PATCH] sh: consistent API cleanup

This gets rid of the hardcoded workarounds for the Dreamcast in the
dma-mapping code, and now wraps into the common consistent_alloc() and
consistent_free() routines if the ones in the machvec aren't interested in
handling it.
Signed-off-by: default avatarPaul Mundt <paul.mundt@nokia.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 83da6494
/*
/*
* arch/sh/boards/dreamcast/setup.c
*
* Hardware support for the Sega Dreamcast.
*
* Copyright (c) 2001, 2002 M. R. Brown <mrbrown@linuxdc.org>
* Copyright (c) 2002, 2003 Paul Mundt <lethal@linux-sh.org>
* Copyright (c) 2002, 2003, 2004 Paul Mundt <lethal@linux-sh.org>
*
* This file is part of the LinuxDC project (www.linuxdc.org)
*
* Released under the terms of the GNU GPL v2.0.
*
*
* This file originally bore the message (with enclosed-$):
* Id: setup_dc.c,v 1.5 2001/05/24 05:09:16 mrbrown Exp
* SEGA Dreamcast support
......@@ -21,6 +21,7 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/device.h>
#include <asm/io.h>
#include <asm/irq.h>
......@@ -34,6 +35,10 @@ extern void (*board_time_init)(void);
extern void aica_time_init(void);
extern int gapspci_init(void);
extern int systemasic_irq_demux(int);
void *dreamcast_consistent_alloc(struct device *, size_t, dma_addr_t *, int);
int dreamcast_consistent_free(struct device *, size_t, void *, dma_addr_t);
const char *get_system_type(void)
{
return "Sega Dreamcast";
......@@ -43,6 +48,11 @@ struct sh_machine_vector mv_dreamcast __initmv = {
.mv_nr_irqs = NR_IRQS,
.mv_irq_demux = systemasic_irq_demux,
#ifdef CONFIG_PCI
.mv_consistent_alloc = dreamcast_consistent_alloc,
.mv_consistent_free = dreamcast_consistent_free,
#endif
};
ALIAS_MV(dreamcast)
......
......@@ -24,7 +24,7 @@ extern void *rts7751r2d_ioremap(unsigned long, unsigned long);
extern int rts7751r2d_irq_demux(int irq);
extern void *voyagergx_consistent_alloc(struct device *, size_t, dma_addr_t *, int);
extern void voyagergx_consistent_free(struct device *, size_t, void *, dma_addr_t);
extern int voyagergx_consistent_free(struct device *, size_t, void *, dma_addr_t);
/*
* The Machine Vector
......@@ -62,7 +62,9 @@ struct sh_machine_vector mv_rts7751r2d __initmv = {
#endif
.mv_irq_demux = rts7751r2d_irq_demux,
#ifdef CONFIG_USB_OHCI_HCD
.mv_consistent_alloc = voyagergx_consistent_alloc,
.mv_consistent_free = voyagergx_consistent_free,
#endif
};
ALIAS_MV(rts7751r2d)
......@@ -49,13 +49,13 @@ void *voyagergx_consistent_alloc(struct device *dev, size_t size,
if (!dev || dev->bus != &sh_bus_types[SH_BUS_VIRT] ||
(dev->bus == &sh_bus_types[SH_BUS_VIRT] &&
shdev->dev_id != SH_DEV_ID_USB_OHCI))
return consistent_alloc(flag, size, handle);
return NULL;
start = OHCI_SRAM_START + OHCI_HCCA_SIZE;
entry = kmalloc(sizeof(struct voya_alloc_entry), GFP_ATOMIC);
if (!entry)
return NULL;
return ERR_PTR(-ENOMEM);
entry->len = (size + 15) & ~15;
......@@ -91,11 +91,11 @@ void *voyagergx_consistent_alloc(struct device *dev, size_t size,
kfree(entry);
spin_unlock_irqrestore(&voya_list_lock, flags);
return NULL;
return ERR_PTR(-EINVAL);
}
void voyagergx_consistent_free(struct device *dev, size_t size,
void *vaddr, dma_addr_t handle)
int voyagergx_consistent_free(struct device *dev, size_t size,
void *vaddr, dma_addr_t handle)
{
struct voya_alloc_entry *entry;
struct sh_dev *shdev = to_sh_dev(dev);
......@@ -103,10 +103,8 @@ void voyagergx_consistent_free(struct device *dev, size_t size,
if (!dev || dev->bus != &sh_bus_types[SH_BUS_VIRT] ||
(dev->bus == &sh_bus_types[SH_BUS_VIRT] &&
shdev->dev_id != SH_DEV_ID_USB_OHCI)) {
consistent_free(vaddr, size);
return;
}
shdev->dev_id != SH_DEV_ID_USB_OHCI))
return -EINVAL;
spin_lock_irqsave(&voya_list_lock, flags);
list_for_each_entry(entry, &voya_alloc_list, list) {
......@@ -119,6 +117,8 @@ void voyagergx_consistent_free(struct device *dev, size_t size,
break;
}
spin_unlock_irqrestore(&voya_list_lock, flags);
return 0;
}
EXPORT_SYMBOL(voyagergx_consistent_alloc);
......
......@@ -23,6 +23,8 @@
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <linux/device.h>
#include <asm/io.h>
#include <asm/irq.h>
......@@ -30,18 +32,21 @@
static int gapspci_dma_used = 0;
void *__pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
dma_addr_t * dma_handle)
void *dreamcast_consistent_alloc(struct device *dev, size_t size,
dma_addr_t *dma_handle, int flag)
{
unsigned long buf;
if (gapspci_dma_used+size > GAPSPCI_DMA_SIZE)
if (dev && dev->bus != &pci_bus_type)
return NULL;
buf = GAPSPCI_DMA_BASE+gapspci_dma_used;
if (gapspci_dma_used + size > GAPSPCI_DMA_SIZE)
return ERR_PTR(-EINVAL);
buf = GAPSPCI_DMA_BASE + gapspci_dma_used;
gapspci_dma_used = PAGE_ALIGN(gapspci_dma_used+size);
*dma_handle = (dma_addr_t)buf;
buf = P2SEGADDR(buf);
......@@ -52,10 +57,15 @@ void *__pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
return (void *)buf;
}
void __pci_free_consistent(struct pci_dev *hwdev, size_t size,
int dreamcast_consistent_free(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle)
{
if (dev && dev->bus != &pci_bus_type)
return -EINVAL;
/* XXX */
gapspci_dma_used = 0;
return 0;
}
......@@ -78,4 +78,8 @@ void consistent_sync(void *vaddr, size_t size, int direction)
BUG();
}
}
EXPORT_SYMBOL(consistent_alloc);
EXPORT_SYMBOL(consistent_free);
EXPORT_SYMBOL(consistent_sync);
......@@ -3,23 +3,17 @@
#include <linux/config.h>
#include <linux/mm.h>
#include <linux/device.h>
#include <asm/scatterlist.h>
#include <asm/io.h>
extern struct bus_type pci_bus_type;
/* arch/sh/mm/consistent.c */
extern void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle);
extern void consistent_free(void *vaddr, size_t size);
extern void consistent_sync(void *vaddr, size_t size, int direction);
#ifdef CONFIG_SH_DREAMCAST
struct pci_dev;
extern struct bus_type pci_bus_type;
extern void *__pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
dma_addr_t *dma_handle);
extern void __pci_free_consistent(struct pci_dev *hwdev, size_t size,
void *vaddr, dma_addr_t dma_handle);
#endif
#define dma_supported(dev, mask) (1)
static inline int dma_set_mask(struct device *dev, u64 mask)
......@@ -35,16 +29,13 @@ static inline int dma_set_mask(struct device *dev, u64 mask)
static inline void *dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, int flag)
{
/*
* Some platforms have special pci_alloc_consistent() implementations,
* in these instances we can't use the generic consistent_alloc().
*/
#ifdef CONFIG_SH_DREAMCAST
if (dev && dev->bus == &pci_bus_type)
return __pci_alloc_consistent(NULL, size, dma_handle);
#endif
if (sh_mv.mv_consistent_alloc)
return sh_mv.mv_consistent_alloc(dev, size, dma_handle, flag);
if (sh_mv.mv_consistent_alloc) {
void *ret;
ret = sh_mv.mv_consistent_alloc(dev, size, dma_handle, flag);
if (ret != NULL)
return ret;
}
return consistent_alloc(flag, size, dma_handle);
}
......@@ -52,19 +43,12 @@ static inline void *dma_alloc_coherent(struct device *dev, size_t size,
static inline void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle)
{
/*
* Same note as above applies to pci_free_consistent()..
*/
#ifdef CONFIG_SH_DREAMCAST
if (dev && dev->bus == &pci_bus_type) {
__pci_free_consistent(NULL, size, vaddr, dma_handle);
return;
}
#endif
if (sh_mv.mv_consistent_free) {
sh_mv.mv_consistent_free(dev, size, vaddr, dma_handle);
return;
int ret;
ret = sh_mv.mv_consistent_free(dev, size, vaddr, dma_handle);
if (ret == 0)
return;
}
consistent_free(vaddr, size);
......
......@@ -65,7 +65,7 @@ struct sh_machine_vector
void (*mv_heartbeat)(void);
void *(*mv_consistent_alloc)(struct device *, size_t, dma_addr_t *, int);
void (*mv_consistent_free)(struct device *, size_t, void *, dma_addr_t);
int (*mv_consistent_free)(struct device *, size_t, void *, dma_addr_t);
};
extern struct sh_machine_vector sh_mv;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment