From abf941324fba48a5e08379a702b70a4256809750 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 18 Oct 2004 08:58:43 -0700 Subject: [PATCH] [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: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sh/boards/dreamcast/setup.c | 16 +++++++-- arch/sh/boards/renesas/rts7751r2d/mach.c | 4 ++- arch/sh/cchips/voyagergx/consistent.c | 18 +++++----- arch/sh/drivers/pci/dma-dreamcast.c | 22 ++++++++---- arch/sh/mm/consistent.c | 4 +++ include/asm-sh/dma-mapping.h | 46 ++++++++---------------- include/asm-sh/machvec.h | 2 +- 7 files changed, 61 insertions(+), 51 deletions(-) diff --git a/arch/sh/boards/dreamcast/setup.c b/arch/sh/boards/dreamcast/setup.c index c59d1599b7641..55dece35cde5c 100644 --- a/arch/sh/boards/dreamcast/setup.c +++ b/arch/sh/boards/dreamcast/setup.c @@ -1,15 +1,15 @@ -/* +/* * arch/sh/boards/dreamcast/setup.c * * Hardware support for the Sega Dreamcast. * * Copyright (c) 2001, 2002 M. R. Brown - * Copyright (c) 2002, 2003 Paul Mundt + * Copyright (c) 2002, 2003, 2004 Paul Mundt * * 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 #include #include +#include #include #include @@ -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) diff --git a/arch/sh/boards/renesas/rts7751r2d/mach.c b/arch/sh/boards/renesas/rts7751r2d/mach.c index c1ff45407ab4b..1efc18e786d51 100644 --- a/arch/sh/boards/renesas/rts7751r2d/mach.c +++ b/arch/sh/boards/renesas/rts7751r2d/mach.c @@ -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) diff --git a/arch/sh/cchips/voyagergx/consistent.c b/arch/sh/cchips/voyagergx/consistent.c index 95a309d149b7b..921d12b42f3a3 100644 --- a/arch/sh/cchips/voyagergx/consistent.c +++ b/arch/sh/cchips/voyagergx/consistent.c @@ -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 @@ out: 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); diff --git a/arch/sh/drivers/pci/dma-dreamcast.c b/arch/sh/drivers/pci/dma-dreamcast.c index ff6169720f964..83de7ef4e7df6 100644 --- a/arch/sh/drivers/pci/dma-dreamcast.c +++ b/arch/sh/drivers/pci/dma-dreamcast.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include #include @@ -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; } diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c index 789bacf1a7aa4..1f7af0c73cf45 100644 --- a/arch/sh/mm/consistent.c +++ b/arch/sh/mm/consistent.c @@ -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); + diff --git a/include/asm-sh/dma-mapping.h b/include/asm-sh/dma-mapping.h index 8876ec7b0e4d3..db78317df116e 100644 --- a/include/asm-sh/dma-mapping.h +++ b/include/asm-sh/dma-mapping.h @@ -3,23 +3,17 @@ #include #include +#include #include #include +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); diff --git a/include/asm-sh/machvec.h b/include/asm-sh/machvec.h index 8a2e3dcd17792..5771f4baa4787 100644 --- a/include/asm-sh/machvec.h +++ b/include/asm-sh/machvec.h @@ -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; -- 2.53.0