LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 10/21]: powerpc/cell spidernet  fix error interrupt print
From: Linas Vepstas @ 2006-10-10 21:06 UTC (permalink / raw)
  To: akpm; +Cc: jeff, Arnd Bergmann, netdev, James K Lewis, linux-kernel,
	linuxppc-dev
In-Reply-To: <20061010204946.GW4381@austin.ibm.com>



The print message associated with the descriptor chain end interrupt
prints a bogs value. Fix that.

Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
Cc: James K Lewis <jklewis@us.ibm.com>
Cc: Arnd Bergmann <arnd@arndb.de>

----
 drivers/net/spider_net.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: linux-2.6.18-mm2/drivers/net/spider_net.c
===================================================================
--- linux-2.6.18-mm2.orig/drivers/net/spider_net.c	2006-10-10 12:52:42.000000000 -0500
+++ linux-2.6.18-mm2/drivers/net/spider_net.c	2006-10-10 12:58:08.000000000 -0500
@@ -1356,7 +1356,7 @@ spider_net_handle_error_irq(struct spide
 		if (netif_msg_intr(card))
 			pr_err("got descriptor chain end interrupt, "
 			       "restarting DMAC %c.\n",
-			       'D'+i-SPIDER_NET_GDDDCEINT);
+			       'D'-(i-SPIDER_NET_GDDDCEINT)/3);
 		spider_net_refill_rx_chain(card);
 		spider_net_enable_rxdmac(card);
 		show_error = 0;

^ permalink raw reply

* [PATCH 11/21]: powerpc/cell spidernet stop error printing patch.
From: Linas Vepstas @ 2006-10-10 21:08 UTC (permalink / raw)
  To: akpm; +Cc: jeff, Arnd Bergmann, netdev, James K Lewis, linux-kernel,
	linuxppc-dev
In-Reply-To: <20061010204946.GW4381@austin.ibm.com>


Turn off mis-interpretation of the queue-empty interrupt
status bit as an error. 

Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
Signed-off-by: James K Lewis <jklewis@us.ibm.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>

----
 drivers/net/spider_net.c |   13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

Index: linux-2.6.18-mm2/drivers/net/spider_net.c
===================================================================
--- linux-2.6.18-mm2.orig/drivers/net/spider_net.c	2006-10-10 12:58:08.000000000 -0500
+++ linux-2.6.18-mm2/drivers/net/spider_net.c	2006-10-10 13:01:06.000000000 -0500
@@ -1245,12 +1245,15 @@ spider_net_handle_error_irq(struct spide
 	case SPIDER_NET_PHYINT:
 	case SPIDER_NET_GMAC2INT:
 	case SPIDER_NET_GMAC1INT:
-	case SPIDER_NET_GIPSINT:
 	case SPIDER_NET_GFIFOINT:
 	case SPIDER_NET_DMACINT:
 	case SPIDER_NET_GSYSINT:
 		break; */
 
+	case SPIDER_NET_GIPSINT:
+		show_error = 0;
+		break;
+
 	case SPIDER_NET_GPWOPCMPINT:
 		/* PHY write operation completed */
 		show_error = 0;
@@ -1309,9 +1312,10 @@ spider_net_handle_error_irq(struct spide
 	case SPIDER_NET_GDTDCEINT:
 		/* chain end. If a descriptor should be sent, kick off
 		 * tx dma
-		if (card->tx_chain.tail == card->tx_chain.head)
+		if (card->tx_chain.tail != card->tx_chain.head)
 			spider_net_kick_tx_dma(card);
-		show_error = 0; */
+		*/
+		show_error = 0;
 		break;
 
 	/* case SPIDER_NET_G1TMCNTINT: not used. print a message */
@@ -1425,8 +1429,9 @@ spider_net_handle_error_irq(struct spide
 	}
 
 	if ((show_error) && (netif_msg_intr(card)))
-		pr_err("Got error interrupt, GHIINT0STS = 0x%08x, "
+		pr_err("Got error interrupt on %s, GHIINT0STS = 0x%08x, "
 		       "GHIINT1STS = 0x%08x, GHIINT2STS = 0x%08x\n",
+		       card->netdev->name,
 		       status_reg, error_reg1, error_reg2);
 
 	/* clear interrupt sources */

^ permalink raw reply

* [PATCH 12/21]: powerpc/cell spidernet incorrect offset
From: Linas Vepstas @ 2006-10-10 21:09 UTC (permalink / raw)
  To: akpm; +Cc: jeff, Arnd Bergmann, netdev, James K Lewis, linux-kernel,
	linuxppc-dev
In-Reply-To: <20061010204946.GW4381@austin.ibm.com>


Bugfix -- the rx chain is in memory after the tx chain -- 
the offset being used was wrong, resulting in memory corruption
when the size of the rx and tx rings weren't exactly the same.

Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
Cc: James K Lewis <jklewis@us.ibm.com>
Cc: Arnd Bergmann <arnd@arndb.de>

----

 drivers/net/spider_net.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

Index: linux-2.6.18-mm2/drivers/net/spider_net.c
===================================================================
--- linux-2.6.18-mm2.orig/drivers/net/spider_net.c	2006-10-10 13:01:06.000000000 -0500
+++ linux-2.6.18-mm2/drivers/net/spider_net.c	2006-10-10 13:03:11.000000000 -0500
@@ -1628,8 +1628,10 @@ spider_net_open(struct net_device *netde
 	if (spider_net_init_chain(card, &card->tx_chain, card->descr,
 			PCI_DMA_TODEVICE, card->tx_desc))
 		goto alloc_tx_failed;
+
+	/* rx_chain is after tx_chain, so offset is descr + tx_count */
 	if (spider_net_init_chain(card, &card->rx_chain,
-			card->descr + card->rx_desc,
+			card->descr + card->tx_desc,
 			PCI_DMA_FROMDEVICE, card->rx_desc))
 		goto alloc_rx_failed;
 

^ permalink raw reply

* [PATCH 13/21]: powerpc/cell spidernet low watermark patch.
From: Linas Vepstas @ 2006-10-10 21:11 UTC (permalink / raw)
  To: akpm; +Cc: jeff, Arnd Bergmann, netdev, James K Lewis, linux-kernel,
	linuxppc-dev
In-Reply-To: <20061010204946.GW4381@austin.ibm.com>


Implement basic low-watermark support for the transmit queue.
Hardware low-watermarks allow a properly configured kernel
to continously stream data to a device and not have to handle 
any interrupts at all in doing so. Correct zero-interrupt
operation can be actually observed for this driver, when the 
socket buffer is made large enough.

The basic idea of a low-watermark interrupt is as follows.
The device driver queues up a bunch of packets for the hardware
to transmit, and then kicks the hardware to get it started.
As the hardware drains the queue of pending, untransmitted 
packets, the device driver will want to know when the queue
is almost empty, so that it can queue some more packets.

If the queue drains down to the low waterark, then an interrupt
will be generated. However, if the kernel/driver continues 
to add enough packets to keep the queue partially filled,
no interrupt will actually be generated, and the hardware 
can continue streaming packets indefinitely in this mode.

The impelmentation is done by setting the DESCR_TXDESFLG flag 
in one of the packets. When the hardware sees this flag, it will 
interrupt the device driver. Because this flag is on a fixed
packet, rather than at  fixed location in the queue, the
code below needs to move the flag as more packets are
queued up. This implementation attempts to keep the flag 
at about 1/4 from "empty".

Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
Signed-off-by: James K Lewis <jklewis@us.ibm.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>

----
 drivers/net/spider_net.c |   43 +++++++++++++++++++++++++++++++++++++++++++
 drivers/net/spider_net.h |    8 ++++----
 2 files changed, 47 insertions(+), 4 deletions(-)

Index: linux-2.6.18-mm2/drivers/net/spider_net.c
===================================================================
--- linux-2.6.18-mm2.orig/drivers/net/spider_net.c	2006-10-10 13:03:11.000000000 -0500
+++ linux-2.6.18-mm2/drivers/net/spider_net.c	2006-10-10 13:09:27.000000000 -0500
@@ -684,6 +684,7 @@ spider_net_prepare_tx_descr(struct spide
 			break;
 		}
 
+	/* Chain the bus address, so that the DMA engine finds this descr. */
 	descr->prev->next_descr_addr = descr->bus_addr;
 
 	card->netdev->trans_start = jiffies; /* set netdev watchdog timer */
@@ -717,6 +718,41 @@ spider_net_release_tx_descr(struct spide
 	dev_kfree_skb_any(skb);
 }
 
+static void
+spider_net_set_low_watermark(struct spider_net_card *card)
+{
+	int status;
+	int cnt=0;
+	int i;
+	struct spider_net_descr *descr = card->tx_chain.tail;
+
+	/* Measure the length of the queue. */
+	while (descr != card->tx_chain.head) {
+		status = descr->dmac_cmd_status & SPIDER_NET_DESCR_NOT_IN_USE;
+		if (status == SPIDER_NET_DESCR_NOT_IN_USE)
+			break;
+		descr = descr->next;
+		cnt++;
+	}
+
+	/* If TX queue is short, don't even bother with interrupts */
+	if (cnt < card->tx_desc/4)
+		return;
+
+	/* Set low-watermark 3/4th's of the way into the queue. */
+	descr = card->tx_chain.tail;
+	cnt = (cnt*3)/4;
+	for (i=0;i<cnt; i++)
+		descr = descr->next;
+
+	/* Set the new watermark, clear the old watermark */
+	descr->dmac_cmd_status |= SPIDER_NET_DESCR_TXDESFLG;
+	if (card->low_watermark && card->low_watermark != descr)
+		card->low_watermark->dmac_cmd_status =
+		     card->low_watermark->dmac_cmd_status & ~SPIDER_NET_DESCR_TXDESFLG;
+	card->low_watermark = descr;
+}
+
 /**
  * spider_net_release_tx_chain - processes sent tx descriptors
  * @card: adapter structure
@@ -838,6 +874,7 @@ spider_net_xmit(struct sk_buff *skb, str
 		return NETDEV_TX_BUSY;
 	}
 
+	spider_net_set_low_watermark(card);
 	spider_net_kick_tx_dma(card);
 	card->tx_chain.head = card->tx_chain.head->next;
 	spin_unlock_irqrestore(&chain->lock, flags);
@@ -1467,6 +1504,10 @@ spider_net_interrupt(int irq, void *ptr,
 		spider_net_rx_irq_off(card);
 		netif_rx_schedule(netdev);
 	}
+	if (status_reg & SPIDER_NET_TXINT ) {
+		spider_net_cleanup_tx_ring(card);
+		netif_wake_queue(netdev);
+	}
 
 	if (status_reg & SPIDER_NET_ERRINT )
 		spider_net_handle_error_irq(card, status_reg);
@@ -1629,6 +1670,8 @@ spider_net_open(struct net_device *netde
 			PCI_DMA_TODEVICE, card->tx_desc))
 		goto alloc_tx_failed;
 
+	card->low_watermark = NULL;
+
 	/* rx_chain is after tx_chain, so offset is descr + tx_count */
 	if (spider_net_init_chain(card, &card->rx_chain,
 			card->descr + card->tx_desc,
Index: linux-2.6.18-mm2/drivers/net/spider_net.h
===================================================================
--- linux-2.6.18-mm2.orig/drivers/net/spider_net.h	2006-10-10 12:54:06.000000000 -0500
+++ linux-2.6.18-mm2/drivers/net/spider_net.h	2006-10-10 13:09:27.000000000 -0500
@@ -49,7 +49,7 @@ extern char spider_net_driver_name[];
 #define SPIDER_NET_TX_DESCRIPTORS_MIN		16
 #define SPIDER_NET_TX_DESCRIPTORS_MAX		512
 
-#define SPIDER_NET_TX_TIMER			20
+#define SPIDER_NET_TX_TIMER			(HZ/5)
 
 #define SPIDER_NET_RX_CSUM_DEFAULT		1
 
@@ -328,9 +328,7 @@ enum spider_net_int2_status {
 	SPIDER_NET_GRISPDNGINT
 };
 
-#define SPIDER_NET_TXINT	( (1 << SPIDER_NET_GTTEDINT) | \
-				  (1 << SPIDER_NET_GDTDCEINT) | \
-				  (1 << SPIDER_NET_GDTFDCINT) )
+#define SPIDER_NET_TXINT	( (1 << SPIDER_NET_GDTFDCINT) )
 
 /* We rely on flagged descriptor interrupts */
 #define SPIDER_NET_RXINT	( (1 << SPIDER_NET_GDAFDCINT) )
@@ -356,6 +354,7 @@ enum spider_net_int2_status {
 #define SPIDER_NET_DESCR_FORCE_END		0x50000000 /* used in rx and tx */
 #define SPIDER_NET_DESCR_CARDOWNED		0xA0000000 /* used in rx and tx */
 #define SPIDER_NET_DESCR_NOT_IN_USE		0xF0000000
+#define SPIDER_NET_DESCR_TXDESFLG		0x00800000
 
 struct spider_net_descr {
 	/* as defined by the hardware */
@@ -440,6 +439,7 @@ struct spider_net_card {
 
 	struct spider_net_descr_chain tx_chain;
 	struct spider_net_descr_chain rx_chain;
+	struct spider_net_descr *low_watermark;
 
 	struct net_device_stats netdev_stats;
 

^ permalink raw reply

* [PATCH 14/21]: powerpc/cell spidernet NAPI polling info.
From: Linas Vepstas @ 2006-10-10 21:13 UTC (permalink / raw)
  To: akpm; +Cc: jeff, Arnd Bergmann, netdev, James K Lewis, linux-kernel,
	linuxppc-dev
In-Reply-To: <20061010204946.GW4381@austin.ibm.com>


This patch moves transmit queue cleanup code out of the 
interrupt context, and into the NAPI polling routine.

Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Cc: James K Lewis <jklewis@us.ibm.com>

----

 drivers/net/spider_net.c |   16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

Index: linux-2.6.18-mm2/drivers/net/spider_net.c
===================================================================
--- linux-2.6.18-mm2.orig/drivers/net/spider_net.c	2006-10-10 13:09:27.000000000 -0500
+++ linux-2.6.18-mm2/drivers/net/spider_net.c	2006-10-10 13:10:37.000000000 -0500
@@ -715,7 +715,7 @@ spider_net_release_tx_descr(struct spide
 	len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
 	pci_unmap_single(card->pdev, descr->buf_addr, len,
 			PCI_DMA_TODEVICE);
-	dev_kfree_skb_any(skb);
+	dev_kfree_skb(skb);
 }
 
 static void
@@ -885,9 +885,10 @@ spider_net_xmit(struct sk_buff *skb, str
  * spider_net_cleanup_tx_ring - cleans up the TX ring
  * @card: card structure
  *
- * spider_net_cleanup_tx_ring is called by the tx_timer (as we don't use
- * interrupts to cleanup our TX ring) and returns sent packets to the stack
- * by freeing them
+ * spider_net_cleanup_tx_ring is called by either the tx_timer
+ * or from the NAPI polling routine.
+ * This routine releases resources associted with transmitted
+ * packets, including updating the queue tail pointer.
  */
 static void
 spider_net_cleanup_tx_ring(struct spider_net_card *card)
@@ -1092,6 +1093,7 @@ spider_net_poll(struct net_device *netde
 	int packets_to_do, packets_done = 0;
 	int no_more_packets = 0;
 
+	spider_net_cleanup_tx_ring(card);
 	packets_to_do = min(*budget, netdev->quota);
 
 	while (packets_to_do) {
@@ -1504,10 +1506,8 @@ spider_net_interrupt(int irq, void *ptr,
 		spider_net_rx_irq_off(card);
 		netif_rx_schedule(netdev);
 	}
-	if (status_reg & SPIDER_NET_TXINT ) {
-		spider_net_cleanup_tx_ring(card);
-		netif_wake_queue(netdev);
-	}
+	if (status_reg & SPIDER_NET_TXINT)
+		netif_rx_schedule(netdev);
 
 	if (status_reg & SPIDER_NET_ERRINT )
 		spider_net_handle_error_irq(card, status_reg);

^ permalink raw reply

* [PATCH 15/21]: powerpc/cell spidernet refine locking
From: Linas Vepstas @ 2006-10-10 21:14 UTC (permalink / raw)
  To: akpm; +Cc: jeff, Arnd Bergmann, netdev, James K Lewis, linux-kernel,
	linuxppc-dev
In-Reply-To: <20061010204946.GW4381@austin.ibm.com>


The transmit side of the spider ethernet driver currently
places locks around some very large chunks of code. This
results in a fair amount of lock contention is some cases. 
This patch makes the locks much more fine-grained, protecting
only the cirtical sections. One lock is used to protect 
three locations: the queue head and tail pointers, and the 
queue low-watermark location.


Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: James K Lewis <jklewis@us.ibm.com>

----
 drivers/net/spider_net.c |   95 +++++++++++++++++++++--------------------------
 1 file changed, 43 insertions(+), 52 deletions(-)

Index: linux-2.6.18-mm2/drivers/net/spider_net.c
===================================================================
--- linux-2.6.18-mm2.orig/drivers/net/spider_net.c	2006-10-10 13:10:37.000000000 -0500
+++ linux-2.6.18-mm2/drivers/net/spider_net.c	2006-10-10 13:20:08.000000000 -0500
@@ -646,8 +646,9 @@ static int
 spider_net_prepare_tx_descr(struct spider_net_card *card,
 			    struct sk_buff *skb)
 {
-	struct spider_net_descr *descr = card->tx_chain.head;
+	struct spider_net_descr *descr;
 	dma_addr_t buf;
+	unsigned long flags;
 	int length;
 
 	length = skb->len;
@@ -666,6 +667,10 @@ spider_net_prepare_tx_descr(struct spide
 		return -ENOMEM;
 	}
 
+	spin_lock_irqsave(&card->tx_chain.lock, flags);
+	descr = card->tx_chain.head;
+	card->tx_chain.head = descr->next;
+
 	descr->buf_addr = buf;
 	descr->buf_size = length;
 	descr->next_descr_addr = 0;
@@ -674,6 +679,8 @@ spider_net_prepare_tx_descr(struct spide
 
 	descr->dmac_cmd_status =
 			SPIDER_NET_DESCR_CARDOWNED | SPIDER_NET_DMAC_NOCS;
+	spin_unlock_irqrestore(&card->tx_chain.lock, flags);
+
 	if (skb->protocol == htons(ETH_P_IP))
 		switch (skb->nh.iph->protocol) {
 		case IPPROTO_TCP:
@@ -691,42 +698,17 @@ spider_net_prepare_tx_descr(struct spide
 	return 0;
 }
 
-/**
- * spider_net_release_tx_descr - processes a used tx descriptor
- * @card: card structure
- * @descr: descriptor to release
- *
- * releases a used tx descriptor (unmapping, freeing of skb)
- */
-static inline void
-spider_net_release_tx_descr(struct spider_net_card *card)
-{
-	struct spider_net_descr *descr = card->tx_chain.tail;
-	struct sk_buff *skb;
-	unsigned int len;
-
-	card->tx_chain.tail = card->tx_chain.tail->next;
-	descr->dmac_cmd_status |= SPIDER_NET_DESCR_NOT_IN_USE;
-
-	/* unmap the skb */
-	skb = descr->skb;
-	if (!skb)
-		return;
-	len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
-	pci_unmap_single(card->pdev, descr->buf_addr, len,
-			PCI_DMA_TODEVICE);
-	dev_kfree_skb(skb);
-}
-
 static void
 spider_net_set_low_watermark(struct spider_net_card *card)
 {
+	unsigned long flags;
 	int status;
 	int cnt=0;
 	int i;
 	struct spider_net_descr *descr = card->tx_chain.tail;
 
-	/* Measure the length of the queue. */
+	/* Measure the length of the queue. Measurement does not
+	 * need to be precise -- does not need a lock. */
 	while (descr != card->tx_chain.head) {
 		status = descr->dmac_cmd_status & SPIDER_NET_DESCR_NOT_IN_USE;
 		if (status == SPIDER_NET_DESCR_NOT_IN_USE)
@@ -746,11 +728,13 @@ spider_net_set_low_watermark(struct spid
 		descr = descr->next;
 
 	/* Set the new watermark, clear the old watermark */
+	spin_lock_irqsave(&card->tx_chain.lock, flags);
 	descr->dmac_cmd_status |= SPIDER_NET_DESCR_TXDESFLG;
 	if (card->low_watermark && card->low_watermark != descr)
 		card->low_watermark->dmac_cmd_status =
 		     card->low_watermark->dmac_cmd_status & ~SPIDER_NET_DESCR_TXDESFLG;
 	card->low_watermark = descr;
+	spin_unlock_irqrestore(&card->tx_chain.lock, flags);
 }
 
 /**
@@ -769,21 +753,31 @@ static int
 spider_net_release_tx_chain(struct spider_net_card *card, int brutal)
 {
 	struct spider_net_descr_chain *chain = &card->tx_chain;
+	struct spider_net_descr *descr;
+	struct sk_buff *skb;
+	u32 buf_addr;
+	unsigned long flags;
 	int status;
 
 	spider_net_read_reg(card, SPIDER_NET_GDTDMACCNTR);
 
 	while (chain->tail != chain->head) {
-		status = spider_net_get_descr_status(chain->tail);
+		spin_lock_irqsave(&chain->lock, flags);
+		descr = chain->tail;
+
+		status = spider_net_get_descr_status(descr);
 		switch (status) {
 		case SPIDER_NET_DESCR_COMPLETE:
 			card->netdev_stats.tx_packets++;
-			card->netdev_stats.tx_bytes += chain->tail->skb->len;
+			card->netdev_stats.tx_bytes += descr->skb->len;
 			break;
 
 		case SPIDER_NET_DESCR_CARDOWNED:
-			if (!brutal)
+			if (!brutal) {
+				spin_unlock_irqrestore(&chain->lock, flags);
 				return 1;
+			}
+
 			/* fallthrough, if we release the descriptors
 			 * brutally (then we don't care about
 			 * SPIDER_NET_DESCR_CARDOWNED) */
@@ -800,12 +794,25 @@ spider_net_release_tx_chain(struct spide
 
 		default:
 			card->netdev_stats.tx_dropped++;
-			if (!brutal)
+			if (!brutal) {
+				spin_unlock_irqrestore(&chain->lock, flags);
 				return 1;
+			}
 		}
-		spider_net_release_tx_descr(card);
-	}
 
+		chain->tail = descr->next;
+		descr->dmac_cmd_status |= SPIDER_NET_DESCR_NOT_IN_USE;
+		skb = descr->skb;
+		buf_addr = descr->buf_addr;
+		spin_unlock_irqrestore(&chain->lock, flags);
+
+		/* unmap the skb */
+		if (skb) {
+			int len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
+			pci_unmap_single(card->pdev, buf_addr, len, PCI_DMA_TODEVICE);
+			dev_kfree_skb(skb);
+		}
+	}
 	return 0;
 }
 
@@ -857,27 +864,19 @@ spider_net_xmit(struct sk_buff *skb, str
 {
 	struct spider_net_card *card = netdev_priv(netdev);
 	struct spider_net_descr_chain *chain = &card->tx_chain;
-	struct spider_net_descr *descr = chain->head;
-	unsigned long flags;
-
-	spin_lock_irqsave(&chain->lock, flags);
 
 	spider_net_release_tx_chain(card, 0);
 
 	if ((chain->head->next == chain->tail->prev) ||
-	   (spider_net_get_descr_status(descr) != SPIDER_NET_DESCR_NOT_IN_USE) ||
 	   (spider_net_prepare_tx_descr(card, skb) != 0)) {
 
 		card->netdev_stats.tx_dropped++;
-		spin_unlock_irqrestore(&chain->lock, flags);
 		netif_stop_queue(netdev);
 		return NETDEV_TX_BUSY;
 	}
 
 	spider_net_set_low_watermark(card);
 	spider_net_kick_tx_dma(card);
-	card->tx_chain.head = card->tx_chain.head->next;
-	spin_unlock_irqrestore(&chain->lock, flags);
 	return NETDEV_TX_OK;
 }
 
@@ -893,16 +892,11 @@ spider_net_xmit(struct sk_buff *skb, str
 static void
 spider_net_cleanup_tx_ring(struct spider_net_card *card)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(&card->tx_chain.lock, flags);
-
 	if ((spider_net_release_tx_chain(card, 0) != 0) &&
 	    (card->netdev->flags & IFF_UP)) {
 		spider_net_kick_tx_dma(card);
 		netif_wake_queue(card->netdev);
 	}
-	spin_unlock_irqrestore(&card->tx_chain.lock, flags);
 }
 
 /**
@@ -1930,10 +1924,7 @@ spider_net_stop(struct net_device *netde
 	spider_net_disable_rxdmac(card);
 
 	/* release chains */
-	if (spin_trylock(&card->tx_chain.lock)) {
-		spider_net_release_tx_chain(card, 1);
-		spin_unlock(&card->tx_chain.lock);
-	}
+	spider_net_release_tx_chain(card, 1);
 
 	spider_net_free_chain(card, &card->tx_chain);
 	spider_net_free_chain(card, &card->rx_chain);

^ permalink raw reply

* [PATCH 16/21]: powerpc/cell spidernet
From: Linas Vepstas @ 2006-10-10 21:15 UTC (permalink / raw)
  To: akpm; +Cc: jeff, Arnd Bergmann, netdev, James K Lewis, linux-kernel,
	linuxppc-dev
In-Reply-To: <20061010204946.GW4381@austin.ibm.com>


Remove a dummy register read that is not needed.
This reduces CPU usage notably during transmit.

Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: James K Lewis <jklewis@us.ibm.com>

----
 drivers/net/spider_net.c |    2 --
 1 file changed, 2 deletions(-)

Index: linux-2.6.18-mm2/drivers/net/spider_net.c
===================================================================
--- linux-2.6.18-mm2.orig/drivers/net/spider_net.c	2006-10-10 13:20:08.000000000 -0500
+++ linux-2.6.18-mm2/drivers/net/spider_net.c	2006-10-10 13:21:41.000000000 -0500
@@ -759,8 +759,6 @@ spider_net_release_tx_chain(struct spide
 	unsigned long flags;
 	int status;
 
-	spider_net_read_reg(card, SPIDER_NET_GDTDMACCNTR);
-
 	while (chain->tail != chain->head) {
 		spin_lock_irqsave(&chain->lock, flags);
 		descr = chain->tail;

^ permalink raw reply

* [PATCH 17/21]: powerpc/cell spidernet reduce DMA kicking
From: Linas Vepstas @ 2006-10-10 21:18 UTC (permalink / raw)
  To: akpm; +Cc: jeff, Arnd Bergmann, netdev, James K Lewis, linux-kernel,
	linuxppc-dev
In-Reply-To: <20061010204946.GW4381@austin.ibm.com>


The current code attempts to start the TX dma every time a packet
is queued. This is too conservative, and wastes CPU time. This
patch changes behaviour to call the kick-dma function less often, 
only when the tx queue is at risk of emptying.

This reduces cpu usage, improves performance.

Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
Cc: James K Lewis <jklewis@us.ibm.com>
Cc: Arnd Bergmann <arnd@arndb.de>

----
 drivers/net/spider_net.c |   19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

Index: linux-2.6.18-mm2/drivers/net/spider_net.c
===================================================================
--- linux-2.6.18-mm2.orig/drivers/net/spider_net.c	2006-10-10 13:21:41.000000000 -0500
+++ linux-2.6.18-mm2/drivers/net/spider_net.c	2006-10-10 13:28:43.000000000 -0500
@@ -698,7 +698,7 @@ spider_net_prepare_tx_descr(struct spide
 	return 0;
 }
 
-static void
+static int
 spider_net_set_low_watermark(struct spider_net_card *card)
 {
 	unsigned long flags;
@@ -719,7 +719,7 @@ spider_net_set_low_watermark(struct spid
 
 	/* If TX queue is short, don't even bother with interrupts */
 	if (cnt < card->tx_desc/4)
-		return;
+		return cnt;
 
 	/* Set low-watermark 3/4th's of the way into the queue. */
 	descr = card->tx_chain.tail;
@@ -735,6 +735,7 @@ spider_net_set_low_watermark(struct spid
 		     card->low_watermark->dmac_cmd_status & ~SPIDER_NET_DESCR_TXDESFLG;
 	card->low_watermark = descr;
 	spin_unlock_irqrestore(&card->tx_chain.lock, flags);
+	return cnt;
 }
 
 /**
@@ -819,8 +820,12 @@ spider_net_release_tx_chain(struct spide
  * @card: card structure
  * @descr: descriptor address to enable TX processing at
  *
- * spider_net_kick_tx_dma writes the current tx chain head as start address
- * of the tx descriptor chain and enables the transmission DMA engine
+ * This routine will start the transmit DMA running if
+ * it is not already running. This routine ned only be
+ * called when queueing a new packet to an empty tx queue.
+ * Writes the current tx chain head as start address
+ * of the tx descriptor chain and enables the transmission
+ * DMA engine.
  */
 static inline void
 spider_net_kick_tx_dma(struct spider_net_card *card)
@@ -860,6 +865,7 @@ out:
 static int
 spider_net_xmit(struct sk_buff *skb, struct net_device *netdev)
 {
+	int cnt;
 	struct spider_net_card *card = netdev_priv(netdev);
 	struct spider_net_descr_chain *chain = &card->tx_chain;
 
@@ -873,8 +879,9 @@ spider_net_xmit(struct sk_buff *skb, str
 		return NETDEV_TX_BUSY;
 	}
 
-	spider_net_set_low_watermark(card);
-	spider_net_kick_tx_dma(card);
+	cnt = spider_net_set_low_watermark(card);
+	if (cnt < 5)
+		spider_net_kick_tx_dma(card);
 	return NETDEV_TX_OK;
 }
 

^ permalink raw reply

* [PATCH 18/21]: powerpc/cell spidernet variable name change
From: Linas Vepstas @ 2006-10-10 21:19 UTC (permalink / raw)
  To: akpm; +Cc: jeff, Arnd Bergmann, netdev, James K Lewis, linux-kernel,
	linuxppc-dev
In-Reply-To: <20061010204946.GW4381@austin.ibm.com>


Cosmetic patch: give the variable holding the numer of descriptors
a more descriptive name, so to avoid confusion.

Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
Cc: James K Lewis <jklewis@us.ibm.com>
Cc: Arnd Bergmann <arnd@arndb.de>

----

 drivers/net/spider_net.c         |   12 ++++++------
 drivers/net/spider_net.h         |    4 ++--
 drivers/net/spider_net_ethtool.c |    4 ++--
 3 files changed, 10 insertions(+), 10 deletions(-)

Index: linux-2.6.18-mm2/drivers/net/spider_net.c
===================================================================
--- linux-2.6.18-mm2.orig/drivers/net/spider_net.c	2006-10-10 13:28:43.000000000 -0500
+++ linux-2.6.18-mm2/drivers/net/spider_net.c	2006-10-10 13:35:33.000000000 -0500
@@ -718,7 +718,7 @@ spider_net_set_low_watermark(struct spid
 	}
 
 	/* If TX queue is short, don't even bother with interrupts */
-	if (cnt < card->tx_desc/4)
+	if (cnt < card->num_tx_desc/4)
 		return cnt;
 
 	/* Set low-watermark 3/4th's of the way into the queue. */
@@ -1666,15 +1666,15 @@ spider_net_open(struct net_device *netde
 
 	result = -ENOMEM;
 	if (spider_net_init_chain(card, &card->tx_chain, card->descr,
-			PCI_DMA_TODEVICE, card->tx_desc))
+			PCI_DMA_TODEVICE, card->num_tx_desc))
 		goto alloc_tx_failed;
 
 	card->low_watermark = NULL;
 
 	/* rx_chain is after tx_chain, so offset is descr + tx_count */
 	if (spider_net_init_chain(card, &card->rx_chain,
-			card->descr + card->tx_desc,
-			PCI_DMA_FROMDEVICE, card->rx_desc))
+			card->descr + card->num_tx_desc,
+			PCI_DMA_FROMDEVICE, card->num_rx_desc))
 		goto alloc_rx_failed;
 
 	/* allocate rx skbs */
@@ -2060,8 +2060,8 @@ spider_net_setup_netdev(struct spider_ne
 
 	card->options.rx_csum = SPIDER_NET_RX_CSUM_DEFAULT;
 
-	card->tx_desc = tx_descriptors;
-	card->rx_desc = rx_descriptors;
+	card->num_tx_desc = tx_descriptors;
+	card->num_rx_desc = rx_descriptors;
 
 	spider_net_setup_netdev_ops(netdev);
 
Index: linux-2.6.18-mm2/drivers/net/spider_net.h
===================================================================
--- linux-2.6.18-mm2.orig/drivers/net/spider_net.h	2006-10-10 13:09:27.000000000 -0500
+++ linux-2.6.18-mm2/drivers/net/spider_net.h	2006-10-10 13:35:33.000000000 -0500
@@ -455,8 +455,8 @@ struct spider_net_card {
 
 	/* for ethtool */
 	int msg_enable;
-	int rx_desc;
-	int tx_desc;
+	int num_rx_desc;
+	int num_tx_desc;
 	struct spider_net_extra_stats spider_stats;
 
 	struct spider_net_descr descr[0];
Index: linux-2.6.18-mm2/drivers/net/spider_net_ethtool.c
===================================================================
--- linux-2.6.18-mm2.orig/drivers/net/spider_net_ethtool.c	2006-10-10 12:20:05.000000000 -0500
+++ linux-2.6.18-mm2/drivers/net/spider_net_ethtool.c	2006-10-10 13:35:33.000000000 -0500
@@ -158,9 +158,9 @@ spider_net_ethtool_get_ringparam(struct 
 	struct spider_net_card *card = netdev->priv;
 
 	ering->tx_max_pending = SPIDER_NET_TX_DESCRIPTORS_MAX;
-	ering->tx_pending = card->tx_desc;
+	ering->tx_pending = card->num_tx_desc;
 	ering->rx_max_pending = SPIDER_NET_RX_DESCRIPTORS_MAX;
-	ering->rx_pending = card->rx_desc;
+	ering->rx_pending = card->num_rx_desc;
 }
 
 static int spider_net_get_stats_count(struct net_device *netdev)

^ permalink raw reply

* [PATCH 19/21]: powerpc/cell spidernet DMA direction fix
From: Linas Vepstas @ 2006-10-10 21:21 UTC (permalink / raw)
  To: akpm; +Cc: jeff, Arnd Bergmann, netdev, James K Lewis, linux-kernel,
	linuxppc-dev
In-Reply-To: <20061010204946.GW4381@austin.ibm.com>


The ring buffer descriptors are DMA-accessed bidirectionally,
but are not declared in this way.  Fix this.

Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
Cc: James K Lewis <jklewis@us.ibm.com>
Cc: Arnd Bergmann <arnd@arndb.de>

----
 drivers/net/spider_net.c |   26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

Index: linux-2.6.18-mm2/drivers/net/spider_net.c
===================================================================
--- linux-2.6.18-mm2.orig/drivers/net/spider_net.c	2006-10-10 13:35:33.000000000 -0500
+++ linux-2.6.18-mm2/drivers/net/spider_net.c	2006-10-10 13:37:40.000000000 -0500
@@ -301,7 +301,7 @@ static int
 spider_net_init_chain(struct spider_net_card *card,
 		       struct spider_net_descr_chain *chain,
 		       struct spider_net_descr *start_descr,
-		       int direction, int no)
+		       int no)
 {
 	int i;
 	struct spider_net_descr *descr;
@@ -316,7 +316,7 @@ spider_net_init_chain(struct spider_net_
 
 		buf = pci_map_single(card->pdev, descr,
 				     SPIDER_NET_DESCR_SIZE,
-				     direction);
+				     PCI_DMA_BIDIRECTIONAL);
 
 		if (pci_dma_mapping_error(buf))
 			goto iommu_error;
@@ -330,11 +330,6 @@ spider_net_init_chain(struct spider_net_
 	(descr-1)->next = start_descr;
 	start_descr->prev = descr-1;
 
-	descr = start_descr;
-	if (direction == PCI_DMA_FROMDEVICE)
-		for (i=0; i < no; i++, descr++)
-			descr->next_descr_addr = descr->next->bus_addr;
-
 	spin_lock_init(&chain->lock);
 	chain->head = start_descr;
 	chain->tail = start_descr;
@@ -347,7 +342,7 @@ iommu_error:
 		if (descr->bus_addr)
 			pci_unmap_single(card->pdev, descr->bus_addr,
 					 SPIDER_NET_DESCR_SIZE,
-					 direction);
+					 PCI_DMA_BIDIRECTIONAL);
 	return -ENOMEM;
 }
 
@@ -368,7 +363,7 @@ spider_net_free_rx_chain_contents(struct
 			dev_kfree_skb(descr->skb);
 			pci_unmap_single(card->pdev, descr->buf_addr,
 					 SPIDER_NET_MAX_FRAME,
-					 PCI_DMA_FROMDEVICE);
+					 PCI_DMA_BIDIRECTIONAL);
 		}
 		descr = descr->next;
 	}
@@ -1662,21 +1657,26 @@ int
 spider_net_open(struct net_device *netdev)
 {
 	struct spider_net_card *card = netdev_priv(netdev);
-	int result;
+	struct spider_net_descr *descr;
+	int i, result;
 
 	result = -ENOMEM;
 	if (spider_net_init_chain(card, &card->tx_chain, card->descr,
-			PCI_DMA_TODEVICE, card->num_tx_desc))
+	                          card->num_tx_desc))
 		goto alloc_tx_failed;
 
 	card->low_watermark = NULL;
 
 	/* rx_chain is after tx_chain, so offset is descr + tx_count */
 	if (spider_net_init_chain(card, &card->rx_chain,
-			card->descr + card->num_tx_desc,
-			PCI_DMA_FROMDEVICE, card->num_rx_desc))
+	                          card->descr + card->num_tx_desc,
+	                          card->num_rx_desc))
 		goto alloc_rx_failed;
 
+	descr = card->rx_chain.head;
+	for (i=0; i < card->num_rx_desc; i++, descr++)
+		descr->next_descr_addr = descr->next->bus_addr;
+
 	/* allocate rx skbs */
 	if (spider_net_alloc_rx_skbs(card))
 		goto alloc_skbs_failed;

^ permalink raw reply

* [PATCH 20/21]: powerpc/cell spidernet release all descrs
From: Linas Vepstas @ 2006-10-10 21:22 UTC (permalink / raw)
  To: akpm; +Cc: jeff, Arnd Bergmann, netdev, James K Lewis, linux-kernel,
	linuxppc-dev
In-Reply-To: <20061010204946.GW4381@austin.ibm.com>


Bugfix: rx descriptor release function fails to visit
the last entry while walking receive descriptor ring.

Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
Cc: James K Lewis <jklewis@us.ibm.com>
Cc: Arnd Bergmann <arnd@arndb.de>

----
 drivers/net/spider_net.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Index: linux-2.6.18-mm2/drivers/net/spider_net.c
===================================================================
--- linux-2.6.18-mm2.orig/drivers/net/spider_net.c	2006-10-10 13:37:40.000000000 -0500
+++ linux-2.6.18-mm2/drivers/net/spider_net.c	2006-10-10 13:40:56.000000000 -0500
@@ -358,7 +358,7 @@ spider_net_free_rx_chain_contents(struct
 	struct spider_net_descr *descr;
 
 	descr = card->rx_chain.head;
-	while (descr->next != card->rx_chain.head) {
+	do {
 		if (descr->skb) {
 			dev_kfree_skb(descr->skb);
 			pci_unmap_single(card->pdev, descr->buf_addr,
@@ -366,7 +366,7 @@ spider_net_free_rx_chain_contents(struct
 					 PCI_DMA_BIDIRECTIONAL);
 		}
 		descr = descr->next;
-	}
+	} while (descr != card->rx_chain.head);
 }
 
 /**

^ permalink raw reply

* [PATCH 21/21]: powerpc/cell spidernet DMA coalescing
From: Linas Vepstas @ 2006-10-10 21:23 UTC (permalink / raw)
  To: akpm; +Cc: jeff, Arnd Bergmann, netdev, James K Lewis, linux-kernel,
	linuxppc-dev
In-Reply-To: <20061010204946.GW4381@austin.ibm.com>


The current driver code performs 512 DMA mappns of a bunch of 
32-byte structures. This is silly, as they are all in contiguous 
memory. Ths patch changes the code to DMA map the entie area
with just one call.

Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
Cc: James K Lewis <jklewis@us.ibm.com>
Cc: Arnd Bergmann <arnd@arndb.de>

----
 drivers/net/spider_net.c |  107 +++++++++++++++++++++++------------------------
 drivers/net/spider_net.h |   16 ++-----
 2 files changed, 59 insertions(+), 64 deletions(-)

Index: linux-2.6.18-mm2/drivers/net/spider_net.c
===================================================================
--- linux-2.6.18-mm2.orig/drivers/net/spider_net.c	2006-10-10 13:40:56.000000000 -0500
+++ linux-2.6.18-mm2/drivers/net/spider_net.c	2006-10-10 13:42:12.000000000 -0500
@@ -267,25 +267,6 @@ spider_net_get_descr_status(struct spide
 }
 
 /**
- * spider_net_free_chain - free descriptor chain
- * @card: card structure
- * @chain: address of chain
- *
- */
-static void
-spider_net_free_chain(struct spider_net_card *card,
-		      struct spider_net_descr_chain *chain)
-{
-	struct spider_net_descr *descr;
-
-	for (descr = chain->tail; !descr->bus_addr; descr = descr->next) {
-		pci_unmap_single(card->pdev, descr->bus_addr,
-				 SPIDER_NET_DESCR_SIZE, PCI_DMA_BIDIRECTIONAL);
-		descr->bus_addr = 0;
-	}
-}
-
-/**
  * spider_net_init_chain - links descriptor chain
  * @card: card structure
  * @chain: address of chain
@@ -297,15 +278,15 @@ spider_net_free_chain(struct spider_net_
  *
  * returns 0 on success, <0 on failure
  */
-static int
+static void
 spider_net_init_chain(struct spider_net_card *card,
 		       struct spider_net_descr_chain *chain,
 		       struct spider_net_descr *start_descr,
+		       dma_addr_t buf,
 		       int no)
 {
 	int i;
 	struct spider_net_descr *descr;
-	dma_addr_t buf;
 
 	descr = start_descr;
 	memset(descr, 0, sizeof(*descr) * no);
@@ -314,17 +295,12 @@ spider_net_init_chain(struct spider_net_
 	for (i=0; i<no; i++, descr++) {
 		descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE;
 
-		buf = pci_map_single(card->pdev, descr,
-				     SPIDER_NET_DESCR_SIZE,
-				     PCI_DMA_BIDIRECTIONAL);
-
-		if (pci_dma_mapping_error(buf))
-			goto iommu_error;
-
 		descr->bus_addr = buf;
+		descr->next_descr_addr = 0;
 		descr->next = descr + 1;
 		descr->prev = descr - 1;
 
+		buf += sizeof(struct spider_net_descr);
 	}
 	/* do actual circular list */
 	(descr-1)->next = start_descr;
@@ -333,17 +309,6 @@ spider_net_init_chain(struct spider_net_
 	spin_lock_init(&chain->lock);
 	chain->head = start_descr;
 	chain->tail = start_descr;
-
-	return 0;
-
-iommu_error:
-	descr = start_descr;
-	for (i=0; i < no; i++, descr++)
-		if (descr->bus_addr)
-			pci_unmap_single(card->pdev, descr->bus_addr,
-					 SPIDER_NET_DESCR_SIZE,
-					 PCI_DMA_BIDIRECTIONAL);
-	return -ENOMEM;
 }
 
 /**
@@ -1658,24 +1623,32 @@ spider_net_open(struct net_device *netde
 {
 	struct spider_net_card *card = netdev_priv(netdev);
 	struct spider_net_descr *descr;
-	int i, result;
+	int result = -ENOMEM;
 
-	result = -ENOMEM;
-	if (spider_net_init_chain(card, &card->tx_chain, card->descr,
-	                          card->num_tx_desc))
-		goto alloc_tx_failed;
+	card->descr_dma_addr = pci_map_single(card->pdev, card->descr,
+	        (card->num_tx_desc+card->num_rx_desc)*sizeof(struct spider_net_descr),
+				     PCI_DMA_BIDIRECTIONAL);
+	if (pci_dma_mapping_error(card->descr_dma_addr))
+		return -ENOMEM;
+
+	spider_net_init_chain(card, &card->tx_chain, card->descr,
+	                          card->descr_dma_addr,
+	                          card->num_tx_desc);
 
 	card->low_watermark = NULL;
 
 	/* rx_chain is after tx_chain, so offset is descr + tx_count */
-	if (spider_net_init_chain(card, &card->rx_chain,
+	spider_net_init_chain(card, &card->rx_chain,
 	                          card->descr + card->num_tx_desc,
-	                          card->num_rx_desc))
-		goto alloc_rx_failed;
+	                          card->descr_dma_addr
+					+ card->num_tx_desc * sizeof(struct spider_net_descr),
+	                          card->num_rx_desc);
 
 	descr = card->rx_chain.head;
-	for (i=0; i < card->num_rx_desc; i++, descr++)
+	do {
 		descr->next_descr_addr = descr->next->bus_addr;
+		descr = descr->next;
+	} while (descr != card->rx_chain.head);
 
 	/* allocate rx skbs */
 	if (spider_net_alloc_rx_skbs(card))
@@ -1701,10 +1674,21 @@ spider_net_open(struct net_device *netde
 register_int_failed:
 	spider_net_free_rx_chain_contents(card);
 alloc_skbs_failed:
-	spider_net_free_chain(card, &card->rx_chain);
-alloc_rx_failed:
-	spider_net_free_chain(card, &card->tx_chain);
-alloc_tx_failed:
+	descr = card->rx_chain.head;
+	do {
+		descr->bus_addr = 0;
+		descr = descr->next;
+	} while (descr != card->rx_chain.head);
+
+	descr = card->tx_chain.head;
+	do {
+		descr->bus_addr = 0;
+		descr = descr->next;
+	} while (descr != card->tx_chain.head);
+
+	pci_unmap_single(card->pdev, card->descr_dma_addr,
+	   (card->num_tx_desc+card->num_rx_desc)*sizeof(struct spider_net_descr),
+	                 PCI_DMA_BIDIRECTIONAL);
 	return result;
 }
 
@@ -1907,6 +1891,7 @@ int
 spider_net_stop(struct net_device *netdev)
 {
 	struct spider_net_card *card = netdev_priv(netdev);
+	struct spider_net_descr *descr;
 
 	tasklet_kill(&card->rxram_full_tl);
 	netif_poll_disable(netdev);
@@ -1930,9 +1915,23 @@ spider_net_stop(struct net_device *netde
 
 	/* release chains */
 	spider_net_release_tx_chain(card, 1);
+	spider_net_free_rx_chain_contents(card);
+
+	descr = card->rx_chain.head;
+	do {
+		descr->bus_addr = 0;
+		descr = descr->next;
+	} while (descr != card->rx_chain.head);
+
+	descr = card->tx_chain.head;
+	do {
+		descr->bus_addr = 0;
+		descr = descr->next;
+	} while (descr != card->tx_chain.head);
 
-	spider_net_free_chain(card, &card->tx_chain);
-	spider_net_free_chain(card, &card->rx_chain);
+	pci_unmap_single(card->pdev, card->descr_dma_addr,
+	      (card->num_tx_desc+card->num_rx_desc)*sizeof(struct spider_net_descr),
+	                 PCI_DMA_BIDIRECTIONAL);
 
 	return 0;
 }
Index: linux-2.6.18-mm2/drivers/net/spider_net.h
===================================================================
--- linux-2.6.18-mm2.orig/drivers/net/spider_net.h	2006-10-10 13:35:33.000000000 -0500
+++ linux-2.6.18-mm2/drivers/net/spider_net.h	2006-10-10 13:42:12.000000000 -0500
@@ -397,8 +397,6 @@ struct spider_net_descr_chain {
  * 701b8000 would be correct, but every packets gets that flag */
 #define SPIDER_NET_DESTROY_RX_FLAGS	0x700b8000
 
-#define SPIDER_NET_DESCR_SIZE		32
-
 /* this will be bigger some time */
 struct spider_net_options {
 	int rx_csum; /* for rx: if 0 ip_summed=NONE,
@@ -437,28 +435,26 @@ struct spider_net_card {
 
 	void __iomem *regs;
 
+	int num_rx_desc;
+	int num_tx_desc;
 	struct spider_net_descr_chain tx_chain;
 	struct spider_net_descr_chain rx_chain;
 	struct spider_net_descr *low_watermark;
+	dma_addr_t descr_dma_addr;
 
-	struct net_device_stats netdev_stats;
-
-	struct spider_net_options options;
-
-	spinlock_t intmask_lock;
 	struct tasklet_struct rxram_full_tl;
 	struct timer_list tx_timer;
-
 	struct work_struct tx_timeout_task;
 	atomic_t tx_timeout_task_counter;
 	wait_queue_head_t waitq;
 
 	/* for ethtool */
 	int msg_enable;
-	int num_rx_desc;
-	int num_tx_desc;
+	struct net_device_stats netdev_stats;
 	struct spider_net_extra_stats spider_stats;
+	struct spider_net_options options;
 
+	/* Must be last element in the structure */
 	struct spider_net_descr descr[0];
 };
 

^ permalink raw reply

* Re: [PATCH] Xilinx UART Lite 2.6.18 driver
From: Grant Likely @ 2006-10-10 22:04 UTC (permalink / raw)
  To: David Bolcsfoldi; +Cc: linuxppc-embedded
In-Reply-To: <609d5c8e0610101349w64cdd4ecjc5359ad8d1f5d635@mail.gmail.com>

On 10/10/06, David Bolcsfoldi <dbolcsfoldi@gmail.com> wrote:
> Hi,
>
> here's a set of patches that adds support for Xilinx UART lite
> devices. It has been tested on an ML403-FX using xapp902
> (ml403_ppc_plb_temac) using a 2.6.18 kernel and a BusyBox userspace.
>
> This is my first patch for the Linux kernel, so please be gentle :-)

Okay; here goes.  :)

First off; it is easiest to review patches when they are sent inline,
one per email.  When they are attachements, they have to be extracted
and copied back into an email to comment on them.  Also, most of the
patches here are pretty minor.  You can roll all of them up into a
single patch (or two if you want to separate the boot wrapper driver
and the full driver)

Other generic comments:
- Try to keep lines under 80 character long.

xuartlite_tty.c.patch: These changes look pretty good
misc-common.c.patch: ok
virtex.h.patch: ok
xilinx_ml403.c.patch: ok
serial_core.h: ok
virtex.c.patch:
> --- 2.6.18/arch/ppc/platforms/4xx/virtex.c	2006-10-04 14:31:15.000000000 -0700
> +++ patched/arch/ppc/platforms/4xx/virtex.c	2006-10-07 11:21:18.000000000 -0700
> @@ -52,5 +52,10 @@
>  		.id		= 0,
>  		.dev.platform_data = serial_platform_data,
>  	},
> +
> +	[VIRTEX_XUL_UART] = {
> +		.name = "xul_uart",
> +		.id	  = 0,
> +	},
>  };

You need to add a pointer to a table of available UartLites her.
Include base addresses/irq# in the table.  There is no point adding
something to the platform bus if you don't describe the devices that
are available.  Use the .dev.platform_data value.  It's a void*
pointer available for your driver.

xuartlite.c.patch:
> diff -urN 2.6.18/drivers/serial/xuartlite.c patched/drivers/serial/xuartlite.c
> --- 2.6.18/drivers/serial/xuartlite.c	1969-12-31 16:00:00.000000000 -0800
> +++ patched/drivers/serial/xuartlite.c	2006-10-10 11:08:08.000000000 -0700
> @@ -0,0 +1,723 @@

<snip>

> +
> +#include <asm/delay.h>
> +#include <asm/io.h>
> +#include <platforms/4xx/xparameters/xparameters.h>

I'd like to move away from drivers including xparameters.h.  We're
moving towards using the flattened device tree to populate the
platform bus for xilinx devices.  arch/ppc doesn't use the device
tree, but it does populate the platform bus.  Device drivers should
get base addresses, irqs, etc from the platform bus instead of
xparams.

> +
> +#if defined(CONFIG_SERIAL_XUL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
> +#define SUPPORT_SYSRQ
> +#endif
> +
> +#include <linux/serial_core.h>
> +
> +#define SERIAL_XUL_MAJOR	204
> +#define SERIAL_XUL_MINOR	187
Have you added you new major/minor pair to Documentation/devices.txt?

> +
> +/*
> + * Keeps various tidbits about the serial port taken
> + * from xparameters.h
> + * */
> +
> +struct xul_uart_data {
> +	int baud;
> +	int parity;
> +	int bits;
> +	int flow;
> +	int uartclk;
> +	int irq;
> +	int mapbase;
> +	int size;
> +};
> +
> +static struct xul_uart_data xul_data[XPAR_XUARTLITE_NUM_INSTANCES] = {
> +	{
> +		.baud = XPAR_XUL_UART_0_BAUDRATE,
> +#if (XPAR_XUL_UART_0_USE_PARITY != 0)
> +		.parity = 'y',
> +#else
> +		.parity = 'n',
> +#endif /* XPAR_XUL_UART_0_USE_PARITY */
> +		.bits = XPAR_XUL_UART_0_DATA_BITS,		
> +		.flow = 'n',
> +		.uartclk = 100000000 / 16, /* PLB speed / 16 */
> +		.irq = XPAR_INTC_0_XUL_UART_0_VEC_ID,
> +		.mapbase = XPAR_XUL_UART_0_BASEADDR,
> +		.size = (XPAR_XUL_UART_0_HIGHADDR - XPAR_XUL_UART_0_BASEADDR) + 1
> +	}
> +
> +	/* Add next uart here */
> +};

Don't do this stuff here.  Add a table to the platform bus initializer
in virtex.c.

> +
> +static const long ISR_PASS_LIMIT = 255;
> +static struct uart_port xul_uart_ports[XPAR_XUARTLITE_NUM_INSTANCES];
> +
> +#define XUL(port) ((unsigned int)((port)->membase))
> +
> +#define XUL_RX_FIFO_OFFSET              0   /* receive FIFO, read only */
> +#define XUL_TX_FIFO_OFFSET              4   /* transmit FIFO, write only */
> +#define XUL_STATUS_REG_OFFSET           8   /* status register, read only */
> +#define XUL_CONTROL_REG_OFFSET          12  /* control register, write only */
> +
> +#define XUL_CR_ENABLE_INTR              0x10    /* enable interrupt */
> +#define XUL_CR_FIFO_RX_RESET            0x02    /* reset receive FIFO */
> +#define XUL_CR_FIFO_TX_RESET            0x01    /* reset transmit FIFO */
> +
> +#define XUL_SR_PARITY_ERROR             0x80
> +#define XUL_SR_FRAMING_ERROR            0x40
> +#define XUL_SR_OVERRUN_ERROR            0x20
> +#define XUL_SR_TX_FIFO_FULL             0x08    /* transmit FIFO full */
> +#define XUL_SR_TX_FIFO_EMPTY            0x04    /* transmit FIFO empty */
> +#define XUL_SR_RX_FIFO_VALID_DATA       0x01    /* data in receive FIFO */

Break these out into an include file, and share them with
arch/ppc/boot/simple/xuartlite_tty.c

<snip>

> +static void
> +xul_uart_release_port(struct uart_port *port)
> +{
> +	if (port->flags & UPF_IOREMAP) {
> +		iounmap(port->membase);
> +		port->membase = NULL;
> +	}
> +	
> +	release_mem_region(port->mapbase, xul_data[port->line].size);
> +}
> +
> +static int
> +xul_uart_request_port(struct uart_port *port)
> +{
> +	int mem_region;
> +	
> +	if (port->flags & UPF_IOREMAP) {
> +		port->membase = ioremap(port->mapbase, xul_data[port->line].size);
> +	}
> +
> +	if (!port->membase) {
> +		return -EINVAL;
> +	}
> +	
> +	mem_region = request_mem_region(port->mapbase, xul_data[port->line].size, "xul_uart") != NULL ? 0 : -EBUSY;
> +	return 0;
> +}
> +
> +static void
> +xul_uart_config_port(struct uart_port *port, int flags)
> +{
> +	if ( (flags & UART_CONFIG_TYPE) &&
> +	     (xul_uart_request_port(port) == 0) )
> +	     	port->type = PORT_XUL;
> +}
> +
> +static int
> +xul_uart_verify_port(struct uart_port *port, struct serial_struct *ser)
> +{
> +	if ( ser->type != PORT_UNKNOWN && ser->type != PORT_XUL ) {
> +		printk(KERN_WARNING "xul_uart_verify_port(1)\n");
> +		return -EINVAL;
> +	}
> +
> +	if ( (ser->irq != port->irq) ||
> +	     (ser->io_type != SERIAL_IO_MEM) ||
> +	     (ser->baud_base != port->uartclk)  ||
> +	     (ser->iomem_base != (void*)port->mapbase) ||
> +	     (ser->hub6 != 0 ) ) {
> +		printk(KERN_WARNING "xul_uart_verify_port(1)\n");
> +	}
> +		return -EINVAL;
> +
> +	return 0;
> +}

This will always fail w/ -EINVAL.  Check your braces.
Also, merge all these tests into a single if; or break them out into
individual if's.  No need for the half-and-half approach done here.

<snip>

======================================================================== */
> +/* Interrupt handling                                                       */
> +/* ======================================================================== */

<snip>

> +
> +static irqreturn_t
> +xul_uart_int(int irq, void *dev_id, struct pt_regs *regs)
> +{
> +	struct uart_port *port = (struct uart_port *) dev_id;

Cast not needed.

> +	unsigned long pass = ISR_PASS_LIMIT;
> +	unsigned int keepgoing;
> +
> +	if ( irq != port->irq ) {
> +		printk( KERN_WARNING
> +		        "xul_uart_int : " \
> +		        "Received wrong int %d. Waiting for %d\n",
> +		       irq, port->irq);
> +		return IRQ_NONE;
> +	}

No need to check (irq != port->irq).  All those code blocks have been
removed from mainline.

<snip>

======================================================================== */
> +/* Platform Driver                                                          */
> +/* ======================================================================== */
> +
> +static int __devinit
> +xul_uart_probe(struct platform_device *dev)
> +{
> +	/* Probe does nothing */
> +	return 0;
> +}

Gah!  What's the point of registering with the platform bus, if you
don't have a probe() routine!  :)  This is where you should pull the
base addresses and number of devices out of the platform_device
structure and dynamically set up your ports.

<snip>

Cheers,
g.

-- 
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195

^ permalink raw reply

* Re: zImage.prep on 2.6.18 & 2.6.19-rc1-gi5
From: Paul Mackerras @ 2006-10-10 22:56 UTC (permalink / raw)
  To: kth5; +Cc: linuxppc-dev, Benoit Chesneau
In-Reply-To: <452B55EE.2090008@archlinuxppc.org>

Alexander Baldeck writes:

> I've been trying to get an old Motorola Powerstack II working on Linux 
> for the past few days. Everything is working fine except for the fact 
> that I have to use a kernel 2.6.8 or earlier. As I'd like to run newer 
> udevs this is unfortunately an inacceptible state, no uevents and all.

Ah!  A willing victim^H^H^H^H^H^Htester! :)

Could you boot up an old kernel and send me the contents of
/proc/residual, please?

Paul.

^ permalink raw reply

* Re: 2.6.19-rc1: known regressions (v3)
From: Paul Mackerras @ 2006-10-10 22:58 UTC (permalink / raw)
  To: Adrian Bunk
  Cc: alsa-devel, Thierry Vignaud, Torsten Kaiser,
	Linux Kernel Mailing List, linuxppc-dev, Andrew de Quincey,
	Vivek Goyal, Jens Axboe, linux-usb-devel, Steve Fox, lm-sensors,
	art, Mel Gorman, Michael Krufky, Sylvain BERTRAND, jgarzik,
	Prakash Punnoor, fastboot, Olaf Hering, discuss, Trond Myklebust,
	Alex Romosan, Linus Torvalds, Dave Kleikamp, Antonino Daplas,
	v4l-dvb-maintainer, Johannes Berg, perex, linux-pm,
	linux-fbdev-devel, linux-ide, netdev, Greg Kroah-Hartman, ak,
	Sukadev Bhattiprolu, ebiederm, Matthieu Castet, Jean Delvare,
	pavel, Ernst Herzberg, David Hubbard
In-Reply-To: <20061010051019.GB3650@stusta.de>

Adrian Bunk writes:

> Subject    : sleep/wakeup on powerbooks apparently busted
> References : http://lkml.org/lkml/2006/10/5/13
> Submitter  : Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Handled-By : Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Status     : Benjamin will investigate

Should be fixed once Linus pulls the powerpc.git tree.

Paul.

^ permalink raw reply

* Re: BUG() in copy_fdtable() with 64K pages (2.6.19-rc1-mm1)
From: Linas Vepstas @ 2006-10-10 23:05 UTC (permalink / raw)
  To: Vadim Lobanov, Andrew Morton
  Cc: Olof Johansson, Andrew Morton, linux-kernel, linuxppc-dev
In-Reply-To: <200610101331.11842.vlobanov@speakeasy.net>

On Tue, Oct 10, 2006 at 01:31:11PM -0700, Vadim Lobanov wrote:
> On Tuesday 10 October 2006 13:20, Linas Vepstas wrote:
> > On Tue, Oct 10, 2006 at 12:15:19PM -0500, Olof Johansson wrote:
> > > I keep hitting this on -rc1-mm1. The system comes up but I can't login
> > > since login hits it.
> > >
> > > Bisect says that
> > > fdtable-implement-new-pagesize-based-fdtable-allocator.patch is at fault.
> > >
> > > CONFIG_PPC_64K_PAGES=y is required for it to fail, with 4K pages it's
> > > fine.
> > >
> > > (Hardware is a Quad G5, 1GB RAM, g5_defconfig + CONFIG_PPC_64K_PAGES,
> > > defaults on all new options)
> > >
> > > kernel BUG in copy_fdtable at fs/file.c:138!
> >
> > FWIW, I too was hitting this bug, during init:
> >
> > [   41.659823] Freeing unused kernel memory: 320k freed
> > INIT: version 2.86 bootin[   42.509322] kernel BUG in copy_fdtable at
> > fs/file.c:138!
> >
> > and of course systm does not come up.

I forgot to mention my h/w was completely different (a cell)

> I'm digging through this right now, trying to figure out exactly what went 
> wrong (and why some people are seeing this, while others are not). All the 
> code seems correct; another pair of eyes is always welcome though.

The patch that AKPM just posted at

ftp://ftp.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.19-rc1/2.6.19-rc1-mm1/hot-fixes/revert-fdtable-implement-new-pagesize-based-fdtable-allocator.patch

boots for me.

Thanks Andrew!

--linas

^ permalink raw reply

* Re: [PATCH] trivial iomem annotations (arch/powerpc/platfroms/parsemi/pci.c)
From: Michael Buesch @ 2006-10-10 23:16 UTC (permalink / raw)
  To: Al Viro; +Cc: linuxppc-dev, Linus Torvalds, linux-kernel
In-Reply-To: <20061009152309.GQ29920@ftp.linux.org.uk>

On Monday 09 October 2006 17:23, Al Viro wrote:
> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
> ---
>  arch/powerpc/platforms/pasemi/pci.c |   26 +++++++++++++-------------
>  1 files changed, 13 insertions(+), 13 deletions(-)
> 
> diff --git a/arch/powerpc/platforms/pasemi/pci.c b/arch/powerpc/platforms/pasemi/pci.c
> index 4679c52..39020c1 100644
> --- a/arch/powerpc/platforms/pasemi/pci.c
> +++ b/arch/powerpc/platforms/pasemi/pci.c
> @@ -35,17 +35,17 @@ #define PA_PXP_CFA(bus, devfn, off) (((b
>  
>  #define CONFIG_OFFSET_VALID(off) ((off) < 4096)
>  
> -static unsigned long pa_pxp_cfg_addr(struct pci_controller *hose,
> +static void volatile __iomem *pa_pxp_cfg_addr(struct pci_controller *hose,
>  				       u8 bus, u8 devfn, int offset)
>  {
> -	return ((unsigned long)hose->cfg_data) + PA_PXP_CFA(bus, devfn, offset);
> +	return hose->cfg_data + PA_PXP_CFA(bus, devfn, offset);
>  }
>  
>  static int pa_pxp_read_config(struct pci_bus *bus, unsigned int devfn,
>  			      int offset, int len, u32 *val)
>  {
>  	struct pci_controller *hose;
> -	unsigned long addr;
> +	void volatile __iomem *addr;

I think you should drop all these new "volatile"s.

>  	hose = pci_bus_to_host(bus);
>  	if (!hose)
> @@ -62,13 +62,13 @@ static int pa_pxp_read_config(struct pci
>  	 */
>  	switch (len) {
>  	case 1:
> -		*val = in_8((u8 *)addr);
> +		*val = in_8(addr);
>  		break;
>  	case 2:
> -		*val = in_le16((u16 *)addr);
> +		*val = in_le16(addr);
>  		break;
>  	default:
> -		*val = in_le32((u32 *)addr);
> +		*val = in_le32(addr);
>  		break;
>  	}
>  
> @@ -79,7 +79,7 @@ static int pa_pxp_write_config(struct pc
>  			       int offset, int len, u32 val)
>  {
>  	struct pci_controller *hose;
> -	unsigned long addr;
> +	void volatile __iomem *addr;
>  
>  	hose = pci_bus_to_host(bus);
>  	if (!hose)
> @@ -96,16 +96,16 @@ static int pa_pxp_write_config(struct pc
>  	 */
>  	switch (len) {
>  	case 1:
> -		out_8((u8 *)addr, val);
> -		(void) in_8((u8 *)addr);
> +		out_8(addr, val);
> +		(void) in_8(addr);
>  		break;
>  	case 2:
> -		out_le16((u16 *)addr, val);
> -		(void) in_le16((u16 *)addr);
> +		out_le16(addr, val);
> +		(void) in_le16(addr);
>  		break;
>  	default:
> -		out_le32((u32 *)addr, val);
> -		(void) in_le32((u32 *)addr);
> +		out_le32(addr, val);
> +		(void) in_le32(addr);
>  		break;
>  	}
>  	return PCIBIOS_SUCCESSFUL;

-- 
Greetings Michael.

^ permalink raw reply

* Re: [PATCH 21/21]: powerpc/cell spidernet DMA coalescing
From: jschopp @ 2006-10-10 23:20 UTC (permalink / raw)
  To: Linas Vepstas
  Cc: akpm, jeff, Arnd Bergmann, netdev, James K Lewis, linux-kernel,
	linuxppc-dev
In-Reply-To: <20061010212324.GR4381@austin.ibm.com>

Linas Vepstas wrote:
> The current driver code performs 512 DMA mappns of a bunch of 
> 32-byte structures. This is silly, as they are all in contiguous 
> memory. Ths patch changes the code to DMA map the entie area
> with just one call.
> 
> Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
> Cc: James K Lewis <jklewis@us.ibm.com>
> Cc: Arnd Bergmann <arnd@arndb.de>

The others look good, but this one complicates the code and doesn't have any benefit.  20 
for 21 isn't bad.

^ permalink raw reply

* Re: [PATCH 21/21]: powerpc/cell spidernet DMA coalescing
From: Geoff Levand @ 2006-10-11  1:46 UTC (permalink / raw)
  To: jschopp
  Cc: akpm, jeff, Arnd Bergmann, netdev, James K Lewis, linux-kernel,
	linuxppc-dev
In-Reply-To: <452C2AAA.5070001@austin.ibm.com>

jschopp wrote:
> Linas Vepstas wrote:
>> The current driver code performs 512 DMA mappns of a bunch of 
>> 32-byte structures. This is silly, as they are all in contiguous 
>> memory. Ths patch changes the code to DMA map the entie area
>> with just one call.
>> 
>> Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
>> Cc: James K Lewis <jklewis@us.ibm.com>
>> Cc: Arnd Bergmann <arnd@arndb.de>
> 
> The others look good, but this one complicates the code and doesn't have any benefit.  20 
> for 21 isn't bad.

Linas, 

Is the motivation for this change to improve performance by reducing the overhead
of the mapping calls?  If so, there may be some benefit for some systems.  Could
you please elaborate?

-Geoff

^ permalink raw reply

* Re: 2.6.19-rc1: known regressions (v3)
From: Adrian Bunk @ 2006-10-11  3:08 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, pavel, linux-kernel, linux-pm
In-Reply-To: <17708.9637.569670.824121@cargo.ozlabs.ibm.com>

On Wed, Oct 11, 2006 at 08:58:45AM +1000, Paul Mackerras wrote:
> Adrian Bunk writes:
> 
> > Subject    : sleep/wakeup on powerbooks apparently busted
> > References : http://lkml.org/lkml/2006/10/5/13
> > Submitter  : Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > Handled-By : Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > Status     : Benjamin will investigate
> 
> Should be fixed once Linus pulls the powerpc.git tree.

Thanks for the information, I've removed it from the list.

> Paul.

cu
Adrian

-- 

       "Is there not promise of rain?" Ling Tan asked suddenly out
        of the darkness. There had been need of rain for many days.
       "Only a promise," Lao Er said.
                                       Pearl S. Buck - Dragon Seed

^ permalink raw reply

* Re: [PATCH] Add Kconfig dependency !VT for VIOCONS
From: Adrian Bunk @ 2006-10-11  3:56 UTC (permalink / raw)
  To: Randy Dunlap; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <20061010091004.d6d91f8d.rdunlap@xenotime.net>

On Tue, Oct 10, 2006 at 09:10:04AM -0700, Randy Dunlap wrote:
> On Tue, 10 Oct 2006 06:55:34 +0200 Adrian Bunk wrote:
> 
> > On Fri, Oct 06, 2006 at 02:34:37PM -0700, Randy Dunlap wrote:
> > > On Fri, 6 Oct 2006 13:00:07 -0700 Judith Lebzelter wrote:
> > > 
> > > > Actually, this gets rid of the CONFIG_VIOCONS from my .config, but 
> > > > then I get another warning when I build:
> > > > 
> > > > Warning! Found recursive dependency: VT VIOCONS VT
> > > > 
> > > > Can anyone suggest something?
> > > 
> > > I think that your patch is mostly good/correct, but one more line
> > > is needed on the VT side:  a deletion.
> > > 
> > > This works for me:
> > > 
> > > From: Randy Dunlap <rdunlap@xenotime.net>
> > > 
> > > Make allmodconfig .config build successfully by making VIOCONS
> > > available only if VT=n.  VT need not check VIOCONS.
> > > 
> > > Signed-off-by: Randy Dunlap <rdunlap@xenotime.net>
> > > ---
> > >  arch/powerpc/platforms/iseries/Kconfig |    2 +-
> > >  drivers/char/Kconfig                   |    1 -
> > >  2 files changed, 1 insertion(+), 2 deletions(-)
> > > 
> > > --- linux-2619-rc1g2.orig/arch/powerpc/platforms/iseries/Kconfig
> > > +++ linux-2619-rc1g2/arch/powerpc/platforms/iseries/Kconfig
> > > @@ -3,7 +3,7 @@ menu "iSeries device drivers"
> > >  	depends on PPC_ISERIES
> > >  
> > >  config VIOCONS
> > > -	tristate "iSeries Virtual Console Support (Obsolete)"
> > > +	tristate "iSeries Virtual Console Support (Obsolete)" if !VT
> > >  	help
> > >...
> > >  config VT
> > >  	bool "Virtual terminal" if EMBEDDED
> > 
> > With this dependency on EMBEDDED, you could as well simply remove 
> > VIOCONS...
> > 
> > >  	select INPUT
> > > -	default y if !VIOCONS
> > 
> > Removing the "default y" is wrong.
> 
> Oops, yes, agreed.
> 
> I don't see a way (using: make ARCH=powerpc iseries_defconfig,
> which wants to enable VIOCONS) to prevent VT from being enabled
> so that VIOCONS can be enabled.

With iseries_defconfig, CONFIG_VT is not enabled.

> However, since VIOCONS is marked (Obsolete) and since the powerpc
> people don't comment on this patch & problem, maybe Judith is the
> only person who cares.

allmodconfig turns on CONFIG_EMBEDDED.

> ~Randy

cu
Adrian

-- 

       "Is there not promise of rain?" Ling Tan asked suddenly out
        of the darkness. There had been need of rain for many days.
       "Only a promise," Lao Er said.
                                       Pearl S. Buck - Dragon Seed

^ permalink raw reply

* Re: [PATCH] Add Kconfig dependency !VT for VIOCONS
From: Randy Dunlap @ 2006-10-11  4:08 UTC (permalink / raw)
  To: Adrian Bunk; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <20061011035629.GC721@stusta.de>

On Wed, 11 Oct 2006 05:56:29 +0200 Adrian Bunk wrote:

> On Tue, Oct 10, 2006 at 09:10:04AM -0700, Randy Dunlap wrote:
> > On Tue, 10 Oct 2006 06:55:34 +0200 Adrian Bunk wrote:
> > 
> > > On Fri, Oct 06, 2006 at 02:34:37PM -0700, Randy Dunlap wrote:
> > > > On Fri, 6 Oct 2006 13:00:07 -0700 Judith Lebzelter wrote:
> > > > 
> > > > > Actually, this gets rid of the CONFIG_VIOCONS from my .config, but 
> > > > > then I get another warning when I build:
> > > > > 
> > > > > Warning! Found recursive dependency: VT VIOCONS VT
> > > > > 
> > > > > Can anyone suggest something?
> > > > 
> > > > I think that your patch is mostly good/correct, but one more line
> > > > is needed on the VT side:  a deletion.
> > > > 
> > > > This works for me:
> > > > 
> > > > From: Randy Dunlap <rdunlap@xenotime.net>
> > > > 
> > > > Make allmodconfig .config build successfully by making VIOCONS
> > > > available only if VT=n.  VT need not check VIOCONS.
> > > > 
> > > > Signed-off-by: Randy Dunlap <rdunlap@xenotime.net>
> > > > ---
> > > >  arch/powerpc/platforms/iseries/Kconfig |    2 +-
> > > >  drivers/char/Kconfig                   |    1 -
> > > >  2 files changed, 1 insertion(+), 2 deletions(-)
> > > > 
> > > > --- linux-2619-rc1g2.orig/arch/powerpc/platforms/iseries/Kconfig
> > > > +++ linux-2619-rc1g2/arch/powerpc/platforms/iseries/Kconfig
> > > > @@ -3,7 +3,7 @@ menu "iSeries device drivers"
> > > >  	depends on PPC_ISERIES
> > > >  
> > > >  config VIOCONS
> > > > -	tristate "iSeries Virtual Console Support (Obsolete)"
> > > > +	tristate "iSeries Virtual Console Support (Obsolete)" if !VT
> > > >  	help
> > > >...
> > > >  config VT
> > > >  	bool "Virtual terminal" if EMBEDDED
> > > 
> > > With this dependency on EMBEDDED, you could as well simply remove 
> > > VIOCONS...
> > > 
> > > >  	select INPUT
> > > > -	default y if !VIOCONS
> > > 
> > > Removing the "default y" is wrong.
> > 
> > Oops, yes, agreed.
> > 
> > I don't see a way (using: make ARCH=powerpc iseries_defconfig,
> > which wants to enable VIOCONS) to prevent VT from being enabled
> > so that VIOCONS can be enabled.
> 
> With iseries_defconfig, CONFIG_VT is not enabled.
> 
> > However, since VIOCONS is marked (Obsolete) and since the powerpc
> > people don't comment on this patch & problem, maybe Judith is the
> > only person who cares.
> 
> allmodconfig turns on CONFIG_EMBEDDED.

So am I doing this incorrectly?

$ make ARCH=powerpc iseries_defconfig

$editor .config

CONFIG_VT=y
...
#
# iSeries device drivers
#
CONFIG_VIODASD=y
CONFIG_VIOCD=m
CONFIG_VIOTAPE=m
CONFIG_VIOPATH=y


---
~Randy

^ permalink raw reply

* Re: [PATCH] Add Kconfig dependency !VT for VIOCONS
From: Adrian Bunk @ 2006-10-11  4:30 UTC (permalink / raw)
  To: Randy Dunlap; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <20061010210858.f8c85692.rdunlap@xenotime.net>

On Tue, Oct 10, 2006 at 09:08:58PM -0700, Randy Dunlap wrote:
> On Wed, 11 Oct 2006 05:56:29 +0200 Adrian Bunk wrote:
> 
> > On Tue, Oct 10, 2006 at 09:10:04AM -0700, Randy Dunlap wrote:
> > > On Tue, 10 Oct 2006 06:55:34 +0200 Adrian Bunk wrote:
> > > 
> > > > On Fri, Oct 06, 2006 at 02:34:37PM -0700, Randy Dunlap wrote:
> > > > > On Fri, 6 Oct 2006 13:00:07 -0700 Judith Lebzelter wrote:
> > > > > 
> > > > > > Actually, this gets rid of the CONFIG_VIOCONS from my .config, but 
> > > > > > then I get another warning when I build:
> > > > > > 
> > > > > > Warning! Found recursive dependency: VT VIOCONS VT
> > > > > > 
> > > > > > Can anyone suggest something?
> > > > > 
> > > > > I think that your patch is mostly good/correct, but one more line
> > > > > is needed on the VT side:  a deletion.
> > > > > 
> > > > > This works for me:
> > > > > 
> > > > > From: Randy Dunlap <rdunlap@xenotime.net>
> > > > > 
> > > > > Make allmodconfig .config build successfully by making VIOCONS
> > > > > available only if VT=n.  VT need not check VIOCONS.
> > > > > 
> > > > > Signed-off-by: Randy Dunlap <rdunlap@xenotime.net>
> > > > > ---
> > > > >  arch/powerpc/platforms/iseries/Kconfig |    2 +-
> > > > >  drivers/char/Kconfig                   |    1 -
> > > > >  2 files changed, 1 insertion(+), 2 deletions(-)
> > > > > 
> > > > > --- linux-2619-rc1g2.orig/arch/powerpc/platforms/iseries/Kconfig
> > > > > +++ linux-2619-rc1g2/arch/powerpc/platforms/iseries/Kconfig
> > > > > @@ -3,7 +3,7 @@ menu "iSeries device drivers"
> > > > >  	depends on PPC_ISERIES
> > > > >  
> > > > >  config VIOCONS
> > > > > -	tristate "iSeries Virtual Console Support (Obsolete)"
> > > > > +	tristate "iSeries Virtual Console Support (Obsolete)" if !VT
> > > > >  	help
> > > > >...
> > > > >  config VT
> > > > >  	bool "Virtual terminal" if EMBEDDED
> > > > 
> > > > With this dependency on EMBEDDED, you could as well simply remove 
> > > > VIOCONS...
> > > > 
> > > > >  	select INPUT
> > > > > -	default y if !VIOCONS
> > > > 
> > > > Removing the "default y" is wrong.
> > > 
> > > Oops, yes, agreed.
> > > 
> > > I don't see a way (using: make ARCH=powerpc iseries_defconfig,
> > > which wants to enable VIOCONS) to prevent VT from being enabled
> > > so that VIOCONS can be enabled.
> > 
> > With iseries_defconfig, CONFIG_VT is not enabled.
> > 
> > > However, since VIOCONS is marked (Obsolete) and since the powerpc
> > > people don't comment on this patch & problem, maybe Judith is the
> > > only person who cares.
> > 
> > allmodconfig turns on CONFIG_EMBEDDED.
> 
> So am I doing this incorrectly?
> 
> $ make ARCH=powerpc iseries_defconfig
> 
> $editor .config
> 
> CONFIG_VT=y
> ...
> #
> # iSeries device drivers
> #
> CONFIG_VIODASD=y
> CONFIG_VIOCD=m
> CONFIG_VIOTAPE=m
> CONFIG_VIOPATH=y

CONFIG_VIOCONS is not enabled.

> ~Randy

cu
Adrian

-- 

       "Is there not promise of rain?" Ling Tan asked suddenly out
        of the darkness. There had been need of rain for many days.
       "Only a promise," Lao Er said.
                                       Pearl S. Buck - Dragon Seed

^ permalink raw reply

* Re: [PATCH] Add Kconfig dependency !VT for VIOCONS
From: Randy Dunlap @ 2006-10-11  4:35 UTC (permalink / raw)
  To: Adrian Bunk; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <20061011043006.GF721@stusta.de>

On Wed, 11 Oct 2006 06:30:06 +0200 Adrian Bunk wrote:

> On Tue, Oct 10, 2006 at 09:08:58PM -0700, Randy Dunlap wrote:
> > On Wed, 11 Oct 2006 05:56:29 +0200 Adrian Bunk wrote:
> > 
> > > On Tue, Oct 10, 2006 at 09:10:04AM -0700, Randy Dunlap wrote:
> > > > On Tue, 10 Oct 2006 06:55:34 +0200 Adrian Bunk wrote:
> > > > 
> > > > > On Fri, Oct 06, 2006 at 02:34:37PM -0700, Randy Dunlap wrote:
> > > > > > On Fri, 6 Oct 2006 13:00:07 -0700 Judith Lebzelter wrote:
> > > > > > 
> > > > > > > Actually, this gets rid of the CONFIG_VIOCONS from my .config, but 
> > > > > > > then I get another warning when I build:
> > > > > > > 
> > > > > > > Warning! Found recursive dependency: VT VIOCONS VT
> > > > > > > 
> > > > > > > Can anyone suggest something?
> > > > > > 
> > > > > > I think that your patch is mostly good/correct, but one more line
> > > > > > is needed on the VT side:  a deletion.
> > > > > > 
> > > > > > This works for me:
> > > > > > 
> > > > > > From: Randy Dunlap <rdunlap@xenotime.net>
> > > > > > 
> > > > > > Make allmodconfig .config build successfully by making VIOCONS
> > > > > > available only if VT=n.  VT need not check VIOCONS.
> > > > > > 
> > > > > > Signed-off-by: Randy Dunlap <rdunlap@xenotime.net>
> > > > > > ---
> > > > > >  arch/powerpc/platforms/iseries/Kconfig |    2 +-
> > > > > >  drivers/char/Kconfig                   |    1 -
> > > > > >  2 files changed, 1 insertion(+), 2 deletions(-)
> > > > > > 
> > > > > > --- linux-2619-rc1g2.orig/arch/powerpc/platforms/iseries/Kconfig
> > > > > > +++ linux-2619-rc1g2/arch/powerpc/platforms/iseries/Kconfig
> > > > > > @@ -3,7 +3,7 @@ menu "iSeries device drivers"
> > > > > >  	depends on PPC_ISERIES
> > > > > >  
> > > > > >  config VIOCONS
> > > > > > -	tristate "iSeries Virtual Console Support (Obsolete)"
> > > > > > +	tristate "iSeries Virtual Console Support (Obsolete)" if !VT
> > > > > >  	help
> > > > > >...
> > > > > >  config VT
> > > > > >  	bool "Virtual terminal" if EMBEDDED
> > > > > 
> > > > > With this dependency on EMBEDDED, you could as well simply remove 
> > > > > VIOCONS...
> > > > > 
> > > > > >  	select INPUT
> > > > > > -	default y if !VIOCONS
> > > > > 
> > > > > Removing the "default y" is wrong.
> > > > 
> > > > Oops, yes, agreed.
> > > > 
> > > > I don't see a way (using: make ARCH=powerpc iseries_defconfig,
> > > > which wants to enable VIOCONS) to prevent VT from being enabled
> > > > so that VIOCONS can be enabled.
> > > 
> > > With iseries_defconfig, CONFIG_VT is not enabled.
> > > 
> > > > However, since VIOCONS is marked (Obsolete) and since the powerpc
> > > > people don't comment on this patch & problem, maybe Judith is the
> > > > only person who cares.
> > > 
> > > allmodconfig turns on CONFIG_EMBEDDED.
> > 
> > So am I doing this incorrectly?
> > 
> > $ make ARCH=powerpc iseries_defconfig
> > 
> > $editor .config
> > 
> > CONFIG_VT=y
> > ...
> > #
> > # iSeries device drivers
> > #
> > CONFIG_VIODASD=y
> > CONFIG_VIOCD=m
> > CONFIG_VIOTAPE=m
> > CONFIG_VIOPATH=y
> 
> CONFIG_VIOCONS is not enabled.

Yep.  That was with my patch.
But I see what you mean.  Thanks.

---
~Randy

^ permalink raw reply

* [PATCH] powerpc: New DCR access methods
From: Benjamin Herrenschmidt @ 2006-10-11  5:42 UTC (permalink / raw)
  To: linuxppc-dev list; +Cc: cbe-oss-dev@ozlabs.org, Arnd Bergmann

Ѕubject: powerpc: generic DCR access

This patch adds new dcr_map/dcr_read/dcr_write accessors for DCRs that
can be used by drivers to transparently address either native DCRs or
memory mapped DCRs. The implementation for memory mapped DCRs is done
after the binding being currently worked on for SLOF and the Axon
chipset. This patch enables it for the cell native platform

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

Arnd: This will replace powerpc-generic-dcr.diff, though don't put it in
your tree just yet. I'll have other axon related patches including a new
one porting emac over and a new infrastructure for probing OF devices
in the upcoming few days. I'm posting this one early to get comments from
4xx folks.

Eugene: As you can see, the overhead for 4xx is nil. I have a patch hacking
the MAL driver to use those instead of mfdcr/mtdcr. I did it to quicky test
I didn't do anything stupid and it still builds with an ebony_defconfig with
ARCH=ppc. I'll send it separately.

Index: linux-cell/include/asm-powerpc/dcr.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-powerpc/dcr.h	2006-10-11 15:28:41.000000000 +1000
@@ -0,0 +1,40 @@
+/*
+ * (c) Copyright 2006 Benjamin Herrenschmidt, IBM Corp.
+ *                    <benh@kernel.crashing.org>
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   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
+ */
+
+#ifndef _ASM_POWERPC_DCR_H
+#define _ASM_POWERPC_DCR_H
+#ifdef __KERNEL__
+
+#ifdef CONFIG_PPC_DCR_NATIVE
+#include <asm/dcr-native.h>
+#else
+#include <asm/dcr-mmio.h>
+#endif
+
+/*
+ * On CONFIG_PPC_MERGE, we have additional helpers to read the DCR
+ * base from the device-tree
+ */
+#ifdef CONFIG_PPC_MERGE
+extern int dcr_resource_start(struct device_node *np, unsigned int index);
+extern int dcr_resource_len(struct device_node *np, unsigned int index);
+#endif /* CONFIG_PPC_MERGE */
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_DCR_H */
Index: linux-cell/arch/powerpc/Kconfig
===================================================================
--- linux-cell.orig/arch/powerpc/Kconfig	2006-10-11 15:27:03.000000000 +1000
+++ linux-cell/arch/powerpc/Kconfig	2006-10-11 15:29:31.000000000 +1000
@@ -160,9 +160,11 @@ config PPC_86xx
 
 config 40x
 	bool "AMCC 40x"
+	select PPC_DCR_NATIVE
 
 config 44x
 	bool "AMCC 44x"
+	select PPC_DCR_NATIVE
 
 config 8xx
 	bool "Freescale 8xx"
@@ -208,6 +210,19 @@ config PPC_FPU
 	bool
 	default y if PPC64
 
+config PPC_DCR_NATIVE
+	bool
+	default n
+
+config PPC_DCR_MMIO
+	bool
+	default n
+
+config PPC_DCR
+	bool
+	depends on PPC_DCR_NATIVE || PPC_DCR_MMIO
+	default y
+
 config BOOKE
 	bool
 	depends on E200 || E500
@@ -445,6 +460,7 @@ config PPC_CELL
 config PPC_CELL_NATIVE
 	bool
 	select PPC_CELL
+	select PPC_DCR_MMIO
 	default n
 
 config PPC_IBM_CELL_BLADE
Index: linux-cell/include/asm-powerpc/dcr-mmio.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-powerpc/dcr-mmio.h	2006-10-11 15:34:02.000000000 +1000
@@ -0,0 +1,51 @@
+/*
+ * (c) Copyright 2006 Benjamin Herrenschmidt, IBM Corp.
+ *                    <benh@kernel.crashing.org>
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   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
+ */
+
+#ifndef _ASM_POWERPC_DCR_MMIO_H
+#define _ASM_POWERPC_DCR_MMIO_H
+#ifdef __KERNEL__
+
+#include <asm/io.h>
+
+typedef struct { void __iomem *token; unsigned int stride; } dcr_host_t;
+
+#define DCR_MAP_OK(host)	((host).token != NULL)
+
+extern dcr_host_t dcr_map(struct device_node *dev, unsigned int dcr_n,
+			  unsigned int dcr_c);
+extern void dcr_unmap(dcr_host_t host, unsigned int dcr_n, unsigned int dcr_c);
+
+static inline u32 dcr_read(dcr_host_t host, unsigned int dcr_n)
+{
+	return in_be32(host.token + dcr_n * host.stride);
+}
+
+static inline void dcr_write(dcr_host_t host, unsigned int dcr_n, u32 value)
+{
+	out_be32(host.token + dcr_n * host.stride, value);
+}
+
+extern u64 of_translate_dcr_address(struct device_node *dev,
+				    unsigned int dcr_n,
+				    unsigned int *stride);
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_DCR_MMIO_H */
+
+
Index: linux-cell/include/asm-powerpc/dcr-native.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-powerpc/dcr-native.h	2006-10-11 15:28:41.000000000 +1000
@@ -0,0 +1,39 @@
+/*
+ * (c) Copyright 2006 Benjamin Herrenschmidt, IBM Corp.
+ *                    <benh@kernel.crashing.org>
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   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
+ */
+
+#ifndef _ASM_POWERPC_DCR_NATIVE_H
+#define _ASM_POWERPC_DCR_NATIVE_H
+#ifdef __KERNEL__
+
+#include <asm/reg.h>
+
+typedef struct {} dcr_host_t;
+
+#define DCR_MAP_OK(host)	(1)
+
+#define dcr_map(dev, dcr_n, dcr_c)	{}
+#define dcr_unmap(host, dcr_n, dcr_c)	{}
+#define dcr_read(host, dcr_n)		mfdcr(dcr_n)
+#define dcr_write(host, dcr_n, value)	mtdcr(dcr_n, value)
+
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_DCR_NATIVE_H */
+
+
Index: linux-cell/arch/ppc/Kconfig
===================================================================
--- linux-cell.orig/arch/ppc/Kconfig	2006-10-11 15:27:03.000000000 +1000
+++ linux-cell/arch/ppc/Kconfig	2006-10-11 15:28:41.000000000 +1000
@@ -77,9 +77,11 @@ config 6xx
 
 config 40x
 	bool "40x"
+	select PPC_DCR_NATIVE
 
 config 44x
 	bool "44x"
+	select PPC_DCR_NATIVE
 
 config 8xx
 	bool "8xx"
@@ -95,6 +97,15 @@ endchoice
 config PPC_FPU
 	bool
 
+config PPC_DCR_NATIVE
+	bool
+	default n
+
+config PPC_DCR
+	bool
+	depends on PPC_DCR_NATIVE
+	default y
+
 config BOOKE
 	bool
 	depends on E200 || E500
Index: linux-cell/arch/powerpc/kernel/Makefile
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/Makefile	2006-10-11 15:27:03.000000000 +1000
+++ linux-cell/arch/powerpc/kernel/Makefile	2006-10-11 15:28:41.000000000 +1000
@@ -60,6 +60,8 @@ obj-$(CONFIG_BOOTX_TEXT)	+= btext.o
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_KPROBES)		+= kprobes.o
 obj-$(CONFIG_PPC_UDBG_16550)	+= legacy_serial.o udbg_16550.o
+obj-$(CONFIG_PPC_DCR)		+= dcr.o
+
 module-$(CONFIG_PPC64)		+= module_64.o
 obj-$(CONFIG_MODULES)		+= $(module-y)
 
Index: linux-cell/arch/powerpc/kernel/dcr.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/arch/powerpc/kernel/dcr.c	2006-10-11 15:35:34.000000000 +1000
@@ -0,0 +1,120 @@
+/*
+ * (c) Copyright 2006 Benjamin Herrenschmidt, IBM Corp.
+ *                    <benh@kernel.crashing.org>
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   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 <asm/prom.h>
+#include <asm/dcr.h>
+
+int dcr_resource_start(struct device_node *np, unsigned int index)
+{
+	unsigned int ds;
+	const u32 *dr = get_property(np, "dcr-reg", &ds);
+
+	if (dr == NULL || ds & 1 || index >= (ds / 8))
+		return -EINVAL;
+
+	return dr[index * 2];
+}
+
+int dcr_resource_len(struct device_node *np, unsigned int index)
+{
+	unsigned int ds;
+	const u32 *dr = get_property(np, "dcr-reg", &ds);
+
+	if (dr == NULL || ds & 1 || index >= (ds / 8))
+		return -EINVAL;
+
+	return dr[index * 2 + 1];
+}
+
+#ifndef CONFIG_PPC_DCR_NATIVE
+
+static struct device_node * find_dcr_parent(struct device_node * node)
+{
+	struct device_node *par, *tmp;
+	const u32 *p;
+
+	for (par = of_node_get(node); par;) {
+		if (get_property(par, "dcr-controller", NULL))
+		    break;
+		p = get_property(par, "dcr-parent", NULL);
+		tmp = par;
+		if (p == NULL)
+			par = of_get_parent(par);
+		else
+			par = of_find_node_by_phandle(*p);
+		of_node_put(tmp);
+	}
+	return par;
+}
+
+u64 of_translate_dcr_address(struct device_node *dev,
+			     unsigned int dcr_n,
+			     unsigned int *stride)
+{
+	struct device_node *dp;
+	const u32 *p;
+	u64 ret;
+
+	dp = find_dcr_parent(dev);
+	if (dp == NULL)
+		return OF_BAD_ADDR;
+
+	/* Stride is not properly defined yet, default to 0x10 for Axon */
+	p = get_property(dp, "dcr-mmio-stride", NULL);
+	*stride = (p == NULL) ? 0x10 : *p;
+
+	p = get_property(dp, "dcr-mmio-range", NULL);
+	if (p == NULL)
+		return OF_BAD_ADDR;
+
+	/* Maybe could do some better range checking here */
+	ret = of_translate_address(dp, p);
+	if (ret != OF_BAD_ADDR)
+		ret += *stride * dcr_n;
+	return ret;
+}
+
+dcr_host_t dcr_map(struct device_node *dev, unsigned int dcr_n,
+		   unsigned int dcr_c)
+{
+	dcr_host_t ret = { .token = NULL, .stride = 0 };
+	u64 addr;
+
+	addr = of_translate_dcr_address(dev, dcr_n, &ret.stride);
+	if (addr == OF_BAD_ADDR)
+		return ret;
+	ret.token = ioremap(addr, dcr_c * ret.stride);
+	if (ret.token == NULL)
+		return ret;
+	ret.token -= dcr_n * ret.stride;
+	return ret;
+}
+
+void dcr_unmap(dcr_host_t host, unsigned int dcr_n, unsigned int dcr_c)
+{
+	dcr_host_t h = host;
+
+	if (h.token == NULL)
+		return;
+	h.token -= dcr_n * h.stride;
+	iounmap(h.token);
+	h.token = NULL;
+}
+
+#endif /* !defined(CONFIG_PPC_DCR_NATIVE) */

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox