All of lore.kernel.org
 help / color / mirror / Atom feed
From: Olof Johansson <olof@lixom.net>
To: jgarzik@pobox.com
Cc: linuxppc-dev@ozlabs.org, netdev@vger.kernel.org
Subject: [PATCH] [3/12] pasemi: DMA engine management library
Date: Wed, 28 Nov 2007 20:56:20 -0600	[thread overview]
Message-ID: <20071129025620.GD17215@lixom.net> (raw)
In-Reply-To: <20071129025410.GA17215@lixom.net>

pasemi: DMA engine management library

Introduce a DMA management library to manage the various DMA resources
on the PA Semi SoCs. Since several drivers need to allocate these shared
resources, provide some abstractions as well as allocation/free functions
for channels, etc.


Signed-off-by: Olof Johansson <olof@lixom.net>

---
 arch/powerpc/platforms/pasemi/Makefile  |    2 
 arch/powerpc/platforms/pasemi/dma_lib.c |  487 ++++++++++++++++++++++++++++++++
 arch/powerpc/platforms/pasemi/pasemi.h  |    1 
 include/asm-powerpc/pasemi_dma.h        |   76 ++++
 4 files changed, 565 insertions(+), 1 deletion(-)

Index: k.org/arch/powerpc/platforms/pasemi/Makefile
===================================================================
--- k.org.orig/arch/powerpc/platforms/pasemi/Makefile
+++ k.org/arch/powerpc/platforms/pasemi/Makefile
@@ -1,4 +1,4 @@
-obj-y	+= setup.o pci.o time.o idle.o powersave.o iommu.o
+obj-y	+= setup.o pci.o time.o idle.o powersave.o iommu.o dma_lib.o
 obj-$(CONFIG_PPC_PASEMI_MDIO)	+= gpio_mdio.o
 obj-$(CONFIG_ELECTRA_IDE) += electra_ide.o
 obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += cpufreq.o
Index: k.org/arch/powerpc/platforms/pasemi/dma_lib.c
===================================================================
--- /dev/null
+++ k.org/arch/powerpc/platforms/pasemi/dma_lib.c
@@ -0,0 +1,487 @@
+/*
+ * Copyright (C) 2006-2007 PA Semi, Inc
+ *
+ * Common functions for DMA access on PA Semi PWRficient
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/of.h>
+
+#include <asm/pasemi_dma.h>
+
+#define MAX_TXCH 64
+#define MAX_RXCH 64
+
+static struct pasdma_status *dma_status;
+
+static void __iomem *iob_regs;
+static void __iomem *mac_regs[6];
+static void __iomem *dma_regs;
+
+static int base_hw_irq;
+
+static int num_txch, num_rxch;
+
+static struct pci_dev *dma_pdev;
+
+/* Bitmaps to handle allocation of channels */
+
+static DECLARE_BITMAP(txch_free, MAX_TXCH);
+static DECLARE_BITMAP(rxch_free, MAX_RXCH);
+
+/* pasemi_read_iob_reg - read IOB register
+ * @reg: Register to read (offset into PCI CFG space)
+ */
+unsigned int pasemi_read_iob_reg(unsigned int reg)
+{
+	return in_le32(iob_regs+reg);
+}
+EXPORT_SYMBOL(pasemi_read_iob_reg);
+
+/* pasemi_write_iob_reg - write IOB register
+ * @reg: Register to write to (offset into PCI CFG space)
+ * @val: Value to write
+ */
+void pasemi_write_iob_reg(unsigned int reg, unsigned int val)
+{
+	out_le32(iob_regs+reg, val);
+}
+EXPORT_SYMBOL(pasemi_write_iob_reg);
+
+/* pasemi_read_mac_reg - read MAC register
+ * @intf: MAC interface
+ * @reg: Register to read (offset into PCI CFG space)
+ */
+unsigned int pasemi_read_mac_reg(int intf, unsigned int reg)
+{
+	return in_le32(mac_regs[intf]+reg);
+}
+EXPORT_SYMBOL(pasemi_read_mac_reg);
+
+/* pasemi_write_mac_reg - write MAC register
+ * @intf: MAC interface
+ * @reg: Register to write to (offset into PCI CFG space)
+ * @val: Value to write
+ */
+void pasemi_write_mac_reg(int intf, unsigned int reg, unsigned int val)
+{
+	out_le32(mac_regs[intf]+reg, val);
+}
+EXPORT_SYMBOL(pasemi_write_mac_reg);
+
+/* pasemi_read_dma_reg - read DMA register
+ * @reg: Register to read (offset into PCI CFG space)
+ */
+unsigned int pasemi_read_dma_reg(unsigned int reg)
+{
+	return in_le32(dma_regs+reg);
+}
+EXPORT_SYMBOL(pasemi_read_dma_reg);
+
+/* pasemi_write_dma_reg - write DMA register
+ * @reg: Register to write to (offset into PCI CFG space)
+ * @val: Value to write
+ */
+void pasemi_write_dma_reg(unsigned int reg, unsigned int val)
+{
+	out_le32(dma_regs+reg, val);
+}
+EXPORT_SYMBOL(pasemi_write_dma_reg);
+
+static int pasemi_alloc_tx_chan(enum pasemi_dmachan_type type)
+{
+	int bit;
+	int start, limit;
+
+	switch (type & (TXCHAN_EVT0|TXCHAN_EVT1)) {
+	case TXCHAN_EVT0:
+		start = 0;
+		limit = 10;
+		break;
+	case TXCHAN_EVT1:
+		start = 10;
+		limit = MAX_TXCH;
+		break;
+	default:
+		start = 0;
+		limit = MAX_TXCH;
+		break;
+	}
+retry:
+	bit = find_next_bit(txch_free, MAX_TXCH, start);
+	if (bit >= limit)
+		return -ENOSPC;
+	if (!test_and_clear_bit(bit, txch_free))
+		goto retry;
+
+	return bit;
+}
+
+static void pasemi_free_tx_chan(int chan)
+{
+	BUG_ON(test_bit(chan, txch_free));
+	set_bit(chan, txch_free);
+}
+
+static int pasemi_alloc_rx_chan(void)
+{
+	int bit;
+retry:
+	bit = find_first_bit(rxch_free, MAX_RXCH);
+	if (bit >= MAX_TXCH)
+		return -ENOSPC;
+	if (!test_and_clear_bit(bit, rxch_free))
+		goto retry;
+
+	return bit;
+}
+
+static void pasemi_free_rx_chan(int chan)
+{
+	BUG_ON(test_bit(chan, rxch_free));
+	set_bit(chan, rxch_free);
+}
+
+/* pasemi_dma_alloc_chan - Allocate a DMA channel
+ * @type: Type of channel to allocate
+ * @total_size: Total size of structure to allocate (to allow for more
+ *		room behind the structure to be used by the client)
+ * @offset: Offset in bytes from start of the total structure to the beginning
+ *	    of struct pasemi_dmachan. Needed when struct pasemi_dmachan is
+ *	    not the first member of the client structure.
+ *
+ * pasemi_dma_alloc_chan allocates a DMA channel for use by a client. The
+ * type argument specifies whether it's a RX or TX channel, and in the case
+ * of TX channels which group it needs to belong to (if any).
+ *
+ * Returns a pointer to the total structure allocated on success, NULL
+ * on failure.
+ */
+void *pasemi_dma_alloc_chan(enum pasemi_dmachan_type type,
+			    int total_size, int offset)
+{
+	void *buf;
+	struct pasemi_dmachan *chan;
+	int chno;
+
+	BUG_ON(total_size < sizeof(struct pasemi_dmachan));
+
+	buf = kzalloc(total_size, GFP_KERNEL);
+
+	if (!buf)
+		return NULL;
+	chan = buf + offset;
+
+	chan->priv = buf;
+
+	switch (type & (TXCHAN|RXCHAN)) {
+	case RXCHAN:
+		chno = pasemi_alloc_rx_chan();
+		chan->chno = chno;
+		chan->irq = irq_create_mapping(NULL,
+					       base_hw_irq + num_txch + chno);
+		chan->status = &dma_status->rx_sta[chno];
+		break;
+	case TXCHAN:
+		chno = pasemi_alloc_tx_chan(type);
+		chan->chno = chno;
+		chan->irq = irq_create_mapping(NULL, base_hw_irq + chno);
+		chan->status = &dma_status->tx_sta[chno];
+		break;
+	}
+
+	chan->chan_type = type;
+
+	return chan;
+}
+EXPORT_SYMBOL(pasemi_dma_alloc_chan);
+
+/* pasemi_dma_free_chan - Free a previously allocated channel
+ * @chan: Channel to free
+ *
+ * Frees a previously allocated channel. It will also deallocate any
+ * descriptor ring associated with the channel, if allocated.
+ */
+void pasemi_dma_free_chan(struct pasemi_dmachan *chan)
+{
+	if (chan->ring_virt)
+		pasemi_dma_free_ring(chan);
+
+	switch (chan->chan_type & (RXCHAN|TXCHAN)) {
+	case RXCHAN:
+		pasemi_free_rx_chan(chan->chno);
+		break;
+	case TXCHAN:
+		pasemi_free_tx_chan(chan->chno);
+		break;
+	}
+
+	kfree(chan->priv);
+}
+EXPORT_SYMBOL(pasemi_dma_free_chan);
+
+/* pasemi_dma_alloc_ring - Allocate descriptor ring for a channel
+ * @chan: Channel for which to allocate
+ * @ring_size: Ring size in 64-bit (8-byte) words
+ *
+ * Allocate a descriptor ring for a channel. Returns 0 on success, errno
+ * on failure. The passed in struct pasemi_dmachan is updated with the
+ * virtual and DMA addresses of the ring.
+ */
+int pasemi_dma_alloc_ring(struct pasemi_dmachan *chan, int ring_size)
+{
+	BUG_ON(chan->ring_virt);
+
+	chan->ring_size = ring_size;
+
+	chan->ring_virt = dma_alloc_coherent(&dma_pdev->dev,
+					     ring_size * sizeof(u64),
+					     &chan->ring_dma, GFP_KERNEL);
+
+	if (!chan->ring_virt)
+		return -ENOMEM;
+
+	memset(chan->ring_virt, 0, ring_size * sizeof(u64));
+
+	return 0;
+}
+EXPORT_SYMBOL(pasemi_dma_alloc_ring);
+
+/* pasemi_dma_free_ring - Free an allocated descriptor ring for a channel
+ * @chan: Channel for which to free the descriptor ring
+ *
+ * Frees a previously allocated descriptor ring for a channel.
+ */
+void pasemi_dma_free_ring(struct pasemi_dmachan *chan)
+{
+	BUG_ON(!chan->ring_virt);
+
+	dma_free_coherent(&dma_pdev->dev, chan->ring_size * sizeof(u64),
+			  chan->ring_virt, chan->ring_dma);
+	chan->ring_virt = NULL;
+	chan->ring_size = 0;
+	chan->ring_dma = 0;
+}
+EXPORT_SYMBOL(pasemi_dma_free_ring);
+
+/* pasemi_dma_start_chan - Start a DMA channel
+ * @chan: Channel to start
+ * @cmdsta: Additional CCMDSTA/TCMDSTA bits to write
+ *
+ * Enables (starts) a DMA channel with optional additional arguments.
+ */
+void pasemi_dma_start_chan(const struct pasemi_dmachan *chan, const u32 cmdsta)
+{
+	if (chan->chan_type == RXCHAN)
+		pasemi_write_dma_reg(PAS_DMA_RXCHAN_CCMDSTA(chan->chno),
+				     cmdsta | PAS_DMA_RXCHAN_CCMDSTA_EN);
+	else
+		pasemi_write_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(chan->chno),
+				     cmdsta | PAS_DMA_TXCHAN_TCMDSTA_EN);
+}
+EXPORT_SYMBOL(pasemi_dma_start_chan);
+
+/* pasemi_dma_stop_chan - Stop a DMA channel
+ * @chan: Channel to stop
+ *
+ * Stops (disables) a DMA channel. This is done by setting the ST bit in the
+ * CMDSTA register and waiting on the ACT (active) bit to clear, then
+ * finally disabling the whole channel.
+ *
+ * This function will only try for a short while for the channel to stop, if
+ * it doesn't it will return failure.
+ *
+ * Returns 1 on success, 0 on failure.
+ */
+#define MAX_RETRIES 5000
+int pasemi_dma_stop_chan(const struct pasemi_dmachan *chan)
+{
+	int reg, retries;
+	u32 sta;
+
+	if (chan->chan_type == RXCHAN) {
+		reg = PAS_DMA_RXCHAN_CCMDSTA(chan->chno);
+		pasemi_write_dma_reg(reg, PAS_DMA_RXCHAN_CCMDSTA_ST);
+		for (retries = 0; retries < MAX_RETRIES; retries++) {
+			sta = pasemi_read_dma_reg(reg);
+			if (!(sta & PAS_DMA_RXCHAN_CCMDSTA_ACT)) {
+				pasemi_write_dma_reg(reg, 0);
+				return 1;
+			}
+			cond_resched();
+		}
+	} else {
+		reg = PAS_DMA_TXCHAN_TCMDSTA(chan->chno);
+		pasemi_write_dma_reg(reg, PAS_DMA_TXCHAN_TCMDSTA_ST);
+		for (retries = 0; retries < MAX_RETRIES; retries++) {
+			sta = pasemi_read_dma_reg(reg);
+			if (!(sta & PAS_DMA_TXCHAN_TCMDSTA_ACT)) {
+				pasemi_write_dma_reg(reg, 0);
+				return 1;
+			}
+			cond_resched();
+		}
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(pasemi_dma_stop_chan);
+
+/* pasemi_dma_alloc_buf - Allocate a buffer to use for DMA
+ * @chan: Channel to allocate for
+ * @size: Size of buffer in bytes
+ * @handle: DMA handle
+ *
+ * Allocate a buffer to be used by the DMA engine for read/write,
+ * similar to dma_alloc_coherent().
+ *
+ * Returns the virtual address of the buffer, or NULL in case of failure.
+ */
+void *pasemi_dma_alloc_buf(struct pasemi_dmachan *chan, int size,
+			   dma_addr_t *handle)
+{
+	return dma_alloc_coherent(&dma_pdev->dev, size, handle, GFP_KERNEL);
+}
+EXPORT_SYMBOL(pasemi_dma_alloc_buf);
+
+/* pasemi_dma_free_buf - Free a buffer used for DMA
+ * @chan: Channel the buffer was allocated for
+ * @size: Size of buffer in bytes
+ * @handle: DMA handle
+ *
+ * Frees a previously allocated buffer.
+ */
+void pasemi_dma_free_buf(struct pasemi_dmachan *chan, int size,
+			 dma_addr_t *handle)
+{
+	dma_free_coherent(&dma_pdev->dev, size, handle, GFP_KERNEL);
+}
+EXPORT_SYMBOL(pasemi_dma_free_buf);
+
+static void *map_onedev(struct pci_dev *p, int index)
+{
+	struct device_node *dn;
+	void __iomem *ret;
+
+	dn = pci_device_to_OF_node(p);
+	if (!dn)
+		goto fallback;
+
+	ret = of_iomap(dn, index);
+	if (!ret)
+		goto fallback;
+
+	return ret;
+fallback:
+	/* This is hardcoded and ugly, but we have some firmware versions
+	 * that don't provide the register space in the device tree. Luckily
+	 * they are at well-known locations so we can just do the math here.
+	 */
+	return ioremap(0xe0000000 + (p->devfn << 12), 0x2000);
+}
+
+/* pasemi_dma_init - Initialize the PA Semi DMA library
+ *
+ * This function initializes the DMA library. It must be called before
+ * any other function in the library.
+ *
+ * Returns 0 on success, errno on failure.
+ */
+int pasemi_dma_init(void)
+{
+	static spinlock_t init_lock = SPIN_LOCK_UNLOCKED;
+	struct pci_dev *iob_pdev;
+	struct pci_dev *pdev;
+	struct resource res;
+	struct device_node *dn;
+	int i, intf, err = 0;
+	u32 tmp;
+
+	if (!machine_is(pasemi))
+		return -ENODEV;
+
+	spin_lock(&init_lock);
+
+	/* Make sure we haven't already initialized */
+	if (dma_pdev)
+		goto out;
+
+	iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL);
+	if (!iob_pdev) {
+		BUG();
+		printk(KERN_WARNING "Can't find I/O Bridge\n");
+		err = -ENODEV;
+		goto out;
+	}
+	iob_regs = map_onedev(iob_pdev, 0);
+
+	dma_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa007, NULL);
+	if (!dma_pdev) {
+		BUG();
+		printk(KERN_WARNING "Can't find DMA controller\n");
+		err = -ENODEV;
+		goto out;
+	}
+	dma_regs = map_onedev(dma_pdev, 0);
+	base_hw_irq = virq_to_hw(dma_pdev->irq);
+
+	pci_read_config_dword(dma_pdev, PAS_DMA_CAP_TXCH, &tmp);
+	num_txch = (tmp & PAS_DMA_CAP_TXCH_TCHN_M) >> PAS_DMA_CAP_TXCH_TCHN_S;
+
+	pci_read_config_dword(dma_pdev, PAS_DMA_CAP_RXCH, &tmp);
+	num_rxch = (tmp & PAS_DMA_CAP_RXCH_RCHN_M) >> PAS_DMA_CAP_RXCH_RCHN_S;
+
+	intf = 0;
+	for (pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa006, NULL);
+	     pdev;
+	     pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa006, pdev))
+		mac_regs[intf++] = map_onedev(pdev, 0);
+
+	pci_dev_put(pdev);
+
+	for (pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa005, NULL);
+	     pdev;
+	     pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa005, pdev))
+		mac_regs[intf++] = map_onedev(pdev, 0);
+
+	pci_dev_put(pdev);
+
+	dn = pci_device_to_OF_node(iob_pdev);
+	if (dn)
+		err = of_address_to_resource(dn, 1, &res);
+	if (!dn || err) {
+		/* Fallback for old firmware */
+		res.start = 0xfd800000;
+		res.end = res.start + 0x1000;
+	}
+	dma_status = __ioremap(res.start, res.end-res.start, 0);
+	pci_dev_put(iob_pdev);
+
+	for (i = 0; i < MAX_TXCH; i++)
+		__set_bit(i, txch_free);
+
+	for (i = 0; i < MAX_RXCH; i++)
+		__set_bit(i, rxch_free);
+
+	printk(KERN_INFO "PA Semi PWRficient DMA library initialized "
+		"(%d tx, %d rx channels)\n", num_txch, num_rxch);
+
+out:
+	spin_unlock(&init_lock);
+	return err;
+}
Index: k.org/arch/powerpc/platforms/pasemi/pasemi.h
===================================================================
--- k.org.orig/arch/powerpc/platforms/pasemi/pasemi.h
+++ k.org/arch/powerpc/platforms/pasemi/pasemi.h
@@ -9,6 +9,7 @@ extern void __devinit pas_pci_dma_dev_se
 extern void __iomem *pasemi_pci_getcfgaddr(struct pci_dev *dev, int offset);
 
 extern void __init alloc_iobmap_l2(void);
+extern void __init pasemi_map_registers(void);
 
 /* Power savings modes, implemented in asm */
 extern void idle_spin(void);
Index: k.org/include/asm-powerpc/pasemi_dma.h
===================================================================
--- k.org.orig/include/asm-powerpc/pasemi_dma.h
+++ k.org/include/asm-powerpc/pasemi_dma.h
@@ -33,11 +33,27 @@ struct pasdma_status {
  * device. Use the normal PCI config access functions for them.
  */
 enum {
+	PAS_DMA_CAP_TXCH  = 0x44,	/* Transmit Channel Info      */
+	PAS_DMA_CAP_RXCH  = 0x48,	/* Transmit Channel Info      */
+	PAS_DMA_CAP_IFI	  = 0x4c,	/* Interface Info	      */
 	PAS_DMA_COM_TXCMD = 0x100,	/* Transmit Command Register  */
 	PAS_DMA_COM_TXSTA = 0x104,	/* Transmit Status Register   */
 	PAS_DMA_COM_RXCMD = 0x108,	/* Receive Command Register   */
 	PAS_DMA_COM_RXSTA = 0x10c,	/* Receive Status Register    */
 };
+
+
+#define PAS_DMA_CAP_TXCH_TCHN_M	0x00ff0000 /* # of TX channels */
+#define PAS_DMA_CAP_TXCH_TCHN_S	16
+
+#define PAS_DMA_CAP_RXCH_RCHN_M	0x00ff0000 /* # of RX channels */
+#define PAS_DMA_CAP_RXCH_RCHN_S	16
+
+#define PAS_DMA_CAP_IFI_IOFF_M	0xff000000 /* Cfg reg for intf pointers */
+#define PAS_DMA_CAP_IFI_IOFF_S	24
+#define PAS_DMA_CAP_IFI_NIN_M	0x00ff0000 /* # of interfaces */
+#define PAS_DMA_CAP_IFI_NIN_S	16
+
 #define PAS_DMA_COM_TXCMD_EN	0x00000001 /* enable */
 #define PAS_DMA_COM_TXSTA_ACT	0x00000001 /* active */
 #define PAS_DMA_COM_RXCMD_EN	0x00000001 /* enable */
@@ -388,4 +404,64 @@ enum {
 				 CTRL_CMD_REG_M)
 
 
+
+/* Prototypes for the shared DMA functions in the platform code. */
+
+/* DMA TX Channel type. Right now only limitations used are event types 0/1,
+ * for event-triggered DMA transactions.
+ */
+
+enum pasemi_dmachan_type {
+	RXCHAN = 0,		/* Any RX chan */
+	TXCHAN = 1,		/* Any TX chan */
+	TXCHAN_EVT0 = 0x1001,	/* TX chan in event class 0 (chan 0-9) */
+	TXCHAN_EVT1 = 0x2001,	/* TX chan in event class 1 (chan 10-19) */
+};
+
+struct pasemi_dmachan {
+	int		 chno;		/* Channel number */
+	enum pasemi_dmachan_type chan_type;	/* TX / RX */
+	u64		*status;	/* Ptr to cacheable status */
+	int		 irq;		/* IRQ used by channel */
+	unsigned int	 ring_size;	/* size of allocated ring */
+	dma_addr_t	 ring_dma;	/* DMA address for ring */
+	u64		*ring_virt;	/* Virt address for ring */
+	void		*priv;		/* Ptr to start of client struct */
+};
+
+/* Read/write the different registers in the I/O Bridge, Ethernet
+ * and DMA Controller
+ */
+extern unsigned int pasemi_read_iob_reg(unsigned int reg);
+extern void pasemi_write_iob_reg(unsigned int reg, unsigned int val);
+
+extern unsigned int pasemi_read_mac_reg(int intf, unsigned int reg);
+extern void pasemi_write_mac_reg(int intf, unsigned int reg, unsigned int val);
+
+extern unsigned int pasemi_read_dma_reg(unsigned int reg);
+extern void pasemi_write_dma_reg(unsigned int reg, unsigned int val);
+
+/* Channel management routines */
+
+extern void *pasemi_dma_alloc_chan(enum pasemi_dmachan_type type,
+				   int total_size, int offset);
+extern void pasemi_dma_free_chan(struct pasemi_dmachan *chan);
+
+extern void pasemi_dma_start_chan(const struct pasemi_dmachan *chan,
+				  const u32 cmdsta);
+extern int pasemi_dma_stop_chan(const struct pasemi_dmachan *chan);
+
+/* Common routines to allocate rings and buffers */
+
+extern int pasemi_dma_alloc_ring(struct pasemi_dmachan *chan, int ring_size);
+extern void pasemi_dma_free_ring(struct pasemi_dmachan *chan);
+
+extern void *pasemi_dma_alloc_buf(struct pasemi_dmachan *chan, int size,
+				  dma_addr_t *handle);
+extern void pasemi_dma_free_buf(struct pasemi_dmachan *chan, int size,
+				dma_addr_t *handle);
+
+/* Initialize the library, must be called before any other functions */
+extern int pasemi_dma_init(void);
+
 #endif /* ASM_PASEMI_DMA_H */

  parent reply	other threads:[~2007-11-29  2:53 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-11-29  2:54 [PATCH] [0/12] pasemi_mac updates for 2.6.25 + DMA channel management library Olof Johansson
2007-11-29  2:54 ` [PATCH] [1/12] pasemi_mac: RX/TX ring management cleanup Olof Johansson
2007-12-01 21:54   ` Jeff Garzik
2007-11-29  2:56 ` [PATCH] [2/12] pasemi_mac: Move register definitions to include/asm-powerpc Olof Johansson
2007-11-29  2:56 ` Olof Johansson [this message]
2007-11-29  2:56 ` [PATCH] [4/12] pasemi_mac: Convert to new dma library Olof Johansson
2007-11-29  2:56 ` [PATCH] [5/12] pasemi_mac: performance tweaks Olof Johansson
2007-11-29  2:56 ` [PATCH] [6/12] pasemi_mac: Fix TX cleaning Olof Johansson
2007-11-29  2:57 ` [PATCH] [7/12] pasemi_mac: Improve RX interrupt mitigation Olof Johansson
2007-11-29  2:57 ` [PATCH] [8/12] pasemi_mac: Software-based LRO support Olof Johansson
2007-11-29  2:57 ` [PATCH] [9/12] pasemi_mac: SKB unmap optimization Olof Johansson
2007-11-29  2:57 ` [PATCH] [10/12] pasemi_mac: Remove SKB copy/recycle logic Olof Johansson
2007-11-29  2:58 ` [PATCH] [11/12] pasemi_mac: Print warning when not attaching to a PHY Olof Johansson
2007-11-29  2:58 ` [PATCH] [12/12] pasemi_mac: Don't enable RX/TX without a link (if possible) Olof Johansson
2007-11-29  2:59 ` [PATCH] [0/12] pasemi_mac updates for 2.6.25 + DMA channel management library Olof Johansson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20071129025620.GD17215@lixom.net \
    --to=olof@lixom.net \
    --cc=jgarzik@pobox.com \
    --cc=linuxppc-dev@ozlabs.org \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.