blob: 8e58184194704d0ac41d9f58a99c2aa35b416d5b [file] [log] [blame]
/*
* Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Vineetg: Feb 2009
* -Reworked the API to work with ARC PCI Bridge
*
* vineetg: Feb 2009
* -For AA4 board, kernel to DMA address APIs
*/
/* Some notes on DMA <=> kernel address generation
*
* A simplistic implementation will generate 0 based bus address.
* For e.g. 0x8AAA_0000 becomes 0x0AAA_0000 bus addr
* However this doesnt work with PCI devices behind the PCI Host Bridge on AA4
* which can't allow 0 based addresses. So the API for special case of PCI
* makes corrections
*
* As a small optimisation, if PCI is not enabled we can simply return
* 0 based bus addr hence the CONFIG_xx check for PCI Host Bridge
*/
#ifndef __PLAT_DMA_ADDR_H
#define __PLAT_DMA_ADDR_H
#include <linux/device.h>
static inline unsigned long plat_dma_addr_to_kernel(
struct device *dev, dma_addr_t dma_addr)
{
#ifdef CONFIG_ARC_AHB_PCI_BRIDGE
if (dev && dev->bus && (strncmp(dev->bus->name, "pci", 3) == 0) )
return (unsigned long) dma_addr;
#endif
return dma_addr + PAGE_OFFSET;
}
static inline dma_addr_t plat_kernel_addr_to_dma(struct device *dev, void *ptr)
{
unsigned long addr = (unsigned long)ptr;
/*
* To Catch buggy drivers which can call DMA map API with kernel vaddr
* i.e. for buffers alloc via vmalloc or ioremap which are not gaurnateed
* to be PHY contiguous and hence unfit for DMA anyways.
* On ARC kernel virtual address is 0x7000_0000 to 0x7FFF_FFFF, so
* ideally we want to check this range here, but our implementation is
* better as it checks for even worse user virtual address as well.
*/
BUG_ON(addr < PAGE_OFFSET);
#ifdef CONFIG_ARC_AHB_PCI_BRIDGE
if (dev && dev->bus && (strncmp(dev->bus->name, "pci", 3) == 0) )
return addr;
#endif
return addr - PAGE_OFFSET;
}
#endif