Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 06/10] net/macb: clean up ring buffer logic
From: Nicolas Ferre @ 2012-10-30 10:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1351591858.git.nicolas.ferre@atmel.com>

From: Havard Skinnemoen <havard@skinnemoen.net>

Instead of masking head and tail every time we increment them, just let them
wrap through UINT_MAX and mask them when subscripting. Add simple accessor
functions to do the subscripting properly to minimize the chances of messing
this up.

This makes the code slightly smaller, and hopefully faster as well.  Also,
doing the ring buffer management this way will simplify things a lot when
making the ring sizes configurable in the future.

Signed-off-by: Havard Skinnemoen <havard@skinnemoen.net>
[nicolas.ferre at atmel.com: split patch in topics, adapt to newer kernel]
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
 drivers/net/ethernet/cadence/macb.c | 168 +++++++++++++++++++++++-------------
 drivers/net/ethernet/cadence/macb.h |  22 +++--
 2 files changed, 122 insertions(+), 68 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index cd6d431..dc03b36 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -31,24 +31,13 @@
 
 #define RX_BUFFER_SIZE		128
 #define RX_RING_SIZE		512
-#define RX_RING_BYTES		(sizeof(struct dma_desc) * RX_RING_SIZE)
+#define RX_RING_BYTES		(sizeof(struct macb_dma_desc) * RX_RING_SIZE)
 
 /* Make the IP header word-aligned (the ethernet header is 14 bytes) */
 #define RX_OFFSET		2
 
 #define TX_RING_SIZE		128
-#define DEF_TX_RING_PENDING	(TX_RING_SIZE - 1)
-#define TX_RING_BYTES		(sizeof(struct dma_desc) * TX_RING_SIZE)
-
-#define TX_RING_GAP(bp)						\
-	(TX_RING_SIZE - (bp)->tx_pending)
-#define TX_BUFFS_AVAIL(bp)					\
-	(((bp)->tx_tail <= (bp)->tx_head) ?			\
-	 (bp)->tx_tail + (bp)->tx_pending - (bp)->tx_head :	\
-	 (bp)->tx_tail - (bp)->tx_head - TX_RING_GAP(bp))
-#define NEXT_TX(n)		(((n) + 1) & (TX_RING_SIZE - 1))
-
-#define NEXT_RX(n)		(((n) + 1) & (RX_RING_SIZE - 1))
+#define TX_RING_BYTES		(sizeof(struct macb_dma_desc) * TX_RING_SIZE)
 
 /* minimum number of free TX descriptors before waking up TX process */
 #define MACB_TX_WAKEUP_THRESH	(TX_RING_SIZE / 4)
@@ -56,6 +45,51 @@
 #define MACB_RX_INT_FLAGS	(MACB_BIT(RCOMP) | MACB_BIT(RXUBR)	\
 				 | MACB_BIT(ISR_ROVR))
 
+/* Ring buffer accessors */
+static unsigned int macb_tx_ring_wrap(unsigned int index)
+{
+	return index & (TX_RING_SIZE - 1);
+}
+
+static unsigned int macb_tx_ring_avail(struct macb *bp)
+{
+	return TX_RING_SIZE - (bp->tx_head - bp->tx_tail);
+}
+
+static struct macb_dma_desc *macb_tx_desc(struct macb *bp, unsigned int index)
+{
+	return &bp->tx_ring[macb_tx_ring_wrap(index)];
+}
+
+static struct macb_tx_skb *macb_tx_skb(struct macb *bp, unsigned int index)
+{
+	return &bp->tx_skb[macb_tx_ring_wrap(index)];
+}
+
+static dma_addr_t macb_tx_dma(struct macb *bp, unsigned int index)
+{
+	dma_addr_t offset;
+
+	offset = macb_tx_ring_wrap(index) * sizeof(struct macb_dma_desc);
+
+	return bp->tx_ring_dma + offset;
+}
+
+static unsigned int macb_rx_ring_wrap(unsigned int index)
+{
+	return index & (RX_RING_SIZE - 1);
+}
+
+static struct macb_dma_desc *macb_rx_desc(struct macb *bp, unsigned int index)
+{
+	return &bp->rx_ring[macb_rx_ring_wrap(index)];
+}
+
+static void *macb_rx_buffer(struct macb *bp, unsigned int index)
+{
+	return bp->rx_buffers + RX_BUFFER_SIZE * macb_rx_ring_wrap(index);
+}
+
 static void __macb_set_hwaddr(struct macb *bp)
 {
 	u32 bottom;
@@ -336,17 +370,18 @@ static void macb_tx(struct macb *bp)
 		bp->tx_ring[TX_RING_SIZE - 1].ctrl |= MACB_BIT(TX_WRAP);
 
 		/* free transmit buffer in upper layer*/
-		for (tail = bp->tx_tail; tail != head; tail = NEXT_TX(tail)) {
-			struct ring_info *rp = &bp->tx_skb[tail];
-			struct sk_buff *skb = rp->skb;
-
-			BUG_ON(skb == NULL);
+		for (tail = bp->tx_tail; tail != head; tail++) {
+			struct macb_tx_skb	*tx_skb;
+			struct sk_buff		*skb;
 
 			rmb();
 
-			dma_unmap_single(&bp->pdev->dev, rp->mapping, skb->len,
-							 DMA_TO_DEVICE);
-			rp->skb = NULL;
+			tx_skb = macb_tx_skb(bp, tail);
+			skb = tx_skb->skb;
+
+			dma_unmap_single(&bp->pdev->dev, tx_skb->mapping,
+						skb->len, DMA_TO_DEVICE);
+			tx_skb->skb = NULL;
 			dev_kfree_skb_irq(skb);
 		}
 
@@ -366,34 +401,38 @@ static void macb_tx(struct macb *bp)
 		return;
 
 	head = bp->tx_head;
-	for (tail = bp->tx_tail; tail != head; tail = NEXT_TX(tail)) {
-		struct ring_info *rp = &bp->tx_skb[tail];
-		struct sk_buff *skb = rp->skb;
-		u32 bufstat;
+	for (tail = bp->tx_tail; tail != head; tail++) {
+		struct macb_tx_skb	*tx_skb;
+		struct sk_buff		*skb;
+		struct macb_dma_desc	*desc;
+		u32			ctrl;
 
-		BUG_ON(skb == NULL);
+		desc = macb_tx_desc(bp, tail);
 
 		/* Make hw descriptor updates visible to CPU */
 		rmb();
 
-		bufstat = bp->tx_ring[tail].ctrl;
+		ctrl = desc->ctrl;
 
-		if (!(bufstat & MACB_BIT(TX_USED)))
+		if (!(ctrl & MACB_BIT(TX_USED)))
 			break;
 
+		tx_skb = macb_tx_skb(bp, tail);
+		skb = tx_skb->skb;
+
 		netdev_vdbg(bp->dev, "skb %u (data %p) TX complete\n",
-			   tail, skb->data);
-		dma_unmap_single(&bp->pdev->dev, rp->mapping, skb->len,
+			macb_tx_ring_wrap(tail), skb->data);
+		dma_unmap_single(&bp->pdev->dev, tx_skb->mapping, skb->len,
 				 DMA_TO_DEVICE);
 		bp->stats.tx_packets++;
 		bp->stats.tx_bytes += skb->len;
-		rp->skb = NULL;
+		tx_skb->skb = NULL;
 		dev_kfree_skb_irq(skb);
 	}
 
 	bp->tx_tail = tail;
-	if (netif_queue_stopped(bp->dev) &&
-	    TX_BUFFS_AVAIL(bp) > MACB_TX_WAKEUP_THRESH)
+	if (netif_queue_stopped(bp->dev)
+			&& macb_tx_ring_avail(bp) > MACB_TX_WAKEUP_THRESH)
 		netif_wake_queue(bp->dev);
 }
 
@@ -404,17 +443,21 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag,
 	unsigned int frag;
 	unsigned int offset = 0;
 	struct sk_buff *skb;
+	struct macb_dma_desc *desc;
 
-	len = MACB_BFEXT(RX_FRMLEN, bp->rx_ring[last_frag].ctrl);
+	desc = macb_rx_desc(bp, last_frag);
+	len = MACB_BFEXT(RX_FRMLEN, desc->ctrl);
 
 	netdev_vdbg(bp->dev, "macb_rx_frame frags %u - %u (len %u)\n",
-		   first_frag, last_frag, len);
+		macb_rx_ring_wrap(first_frag),
+		macb_rx_ring_wrap(last_frag), len);
 
 	skb = netdev_alloc_skb(bp->dev, len + RX_OFFSET);
 	if (!skb) {
 		bp->stats.rx_dropped++;
-		for (frag = first_frag; ; frag = NEXT_RX(frag)) {
-			bp->rx_ring[frag].addr &= ~MACB_BIT(RX_USED);
+		for (frag = first_frag; ; frag++) {
+			desc = macb_rx_desc(bp, frag);
+			desc->addr &= ~MACB_BIT(RX_USED);
 			if (frag == last_frag)
 				break;
 		}
@@ -429,7 +472,7 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag,
 	skb_checksum_none_assert(skb);
 	skb_put(skb, len);
 
-	for (frag = first_frag; ; frag = NEXT_RX(frag)) {
+	for (frag = first_frag; ; frag++) {
 		unsigned int frag_len = RX_BUFFER_SIZE;
 
 		if (offset + frag_len > len) {
@@ -437,11 +480,10 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag,
 			frag_len = len - offset;
 		}
 		skb_copy_to_linear_data_offset(skb, offset,
-					       (bp->rx_buffers +
-					        (RX_BUFFER_SIZE * frag)),
-					       frag_len);
+				macb_rx_buffer(bp, frag), frag_len);
 		offset += RX_BUFFER_SIZE;
-		bp->rx_ring[frag].addr &= ~MACB_BIT(RX_USED);
+		desc = macb_rx_desc(bp, frag);
+		desc->addr &= ~MACB_BIT(RX_USED);
 
 		if (frag == last_frag)
 			break;
@@ -467,8 +509,10 @@ static void discard_partial_frame(struct macb *bp, unsigned int begin,
 {
 	unsigned int frag;
 
-	for (frag = begin; frag != end; frag = NEXT_RX(frag))
-		bp->rx_ring[frag].addr &= ~MACB_BIT(RX_USED);
+	for (frag = begin; frag != end; frag++) {
+		struct macb_dma_desc *desc = macb_rx_desc(bp, frag);
+		desc->addr &= ~MACB_BIT(RX_USED);
+	}
 
 	/* Make descriptor updates visible to hardware */
 	wmb();
@@ -483,17 +527,18 @@ static void discard_partial_frame(struct macb *bp, unsigned int begin,
 static int macb_rx(struct macb *bp, int budget)
 {
 	int received = 0;
-	unsigned int tail = bp->rx_tail;
+	unsigned int tail;
 	int first_frag = -1;
 
-	for (; budget > 0; tail = NEXT_RX(tail)) {
+	for (tail = bp->rx_tail; budget > 0; tail++) {
+		struct macb_dma_desc *desc = macb_rx_desc(bp, tail);
 		u32 addr, ctrl;
 
 		/* Make hw descriptor updates visible to CPU */
 		rmb();
 
-		addr = bp->rx_ring[tail].addr;
-		ctrl = bp->rx_ring[tail].ctrl;
+		addr = desc->addr;
+		ctrl = desc->ctrl;
 
 		if (!(addr & MACB_BIT(RX_USED)))
 			break;
@@ -647,6 +692,8 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	struct macb *bp = netdev_priv(dev);
 	dma_addr_t mapping;
 	unsigned int len, entry;
+	struct macb_dma_desc *desc;
+	struct macb_tx_skb *tx_skb;
 	u32 ctrl;
 	unsigned long flags;
 
@@ -663,7 +710,7 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	spin_lock_irqsave(&bp->lock, flags);
 
 	/* This is a hard error, log it. */
-	if (TX_BUFFS_AVAIL(bp) < 1) {
+	if (macb_tx_ring_avail(bp) < 1) {
 		netif_stop_queue(dev);
 		spin_unlock_irqrestore(&bp->lock, flags);
 		netdev_err(bp->dev, "BUG! Tx Ring full when queue awake!\n");
@@ -672,12 +719,15 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		return NETDEV_TX_BUSY;
 	}
 
-	entry = bp->tx_head;
+	entry = macb_tx_ring_wrap(bp->tx_head);
+	bp->tx_head++;
 	netdev_vdbg(bp->dev, "Allocated ring entry %u\n", entry);
 	mapping = dma_map_single(&bp->pdev->dev, skb->data,
 				 len, DMA_TO_DEVICE);
-	bp->tx_skb[entry].skb = skb;
-	bp->tx_skb[entry].mapping = mapping;
+
+	tx_skb = &bp->tx_skb[entry];
+	tx_skb->skb = skb;
+	tx_skb->mapping = mapping;
 	netdev_vdbg(bp->dev, "Mapped skb data %p to DMA addr %08lx\n",
 		   skb->data, (unsigned long)mapping);
 
@@ -686,20 +736,18 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	if (entry == (TX_RING_SIZE - 1))
 		ctrl |= MACB_BIT(TX_WRAP);
 
-	bp->tx_ring[entry].addr = mapping;
-	bp->tx_ring[entry].ctrl = ctrl;
+	desc = &bp->tx_ring[entry];
+	desc->addr = mapping;
+	desc->ctrl = ctrl;
 
 	/* Make newly initialized descriptor visible to hardware */
 	wmb();
 
-	entry = NEXT_TX(entry);
-	bp->tx_head = entry;
-
 	skb_tx_timestamp(skb);
 
 	macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART));
 
-	if (TX_BUFFS_AVAIL(bp) < 1)
+	if (macb_tx_ring_avail(bp) < 1)
 		netif_stop_queue(dev);
 
 	spin_unlock_irqrestore(&bp->lock, flags);
@@ -735,7 +783,7 @@ static int macb_alloc_consistent(struct macb *bp)
 {
 	int size;
 
-	size = TX_RING_SIZE * sizeof(struct ring_info);
+	size = TX_RING_SIZE * sizeof(struct macb_tx_skb);
 	bp->tx_skb = kmalloc(size, GFP_KERNEL);
 	if (!bp->tx_skb)
 		goto out_err;
@@ -1412,8 +1460,6 @@ static int __init macb_probe(struct platform_device *pdev)
 		macb_or_gem_writel(bp, USRIO, MACB_BIT(MII));
 #endif
 
-	bp->tx_pending = DEF_TX_RING_PENDING;
-
 	err = register_netdev(dev);
 	if (err) {
 		dev_err(&pdev->dev, "Cannot register net device, aborting.\n");
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index 33a050f..024a270 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -362,7 +362,12 @@
 		__v; \
 	})
 
-struct dma_desc {
+/**
+ * struct macb_dma_desc - Hardware DMA descriptor
+ * @addr: DMA address of data buffer
+ * @ctrl: Control and status bits
+ */
+struct macb_dma_desc {
 	u32	addr;
 	u32	ctrl;
 };
@@ -427,7 +432,12 @@ struct dma_desc {
 #define MACB_TX_USED_OFFSET			31
 #define MACB_TX_USED_SIZE			1
 
-struct ring_info {
+/**
+ * struct macb_tx_skb - data about an skb which is being transmitted
+ * @skb: skb currently being transmitted
+ * @mapping: DMA address of the skb's data buffer
+ */
+struct macb_tx_skb {
 	struct sk_buff		*skb;
 	dma_addr_t		mapping;
 };
@@ -512,12 +522,12 @@ struct macb {
 	void __iomem		*regs;
 
 	unsigned int		rx_tail;
-	struct dma_desc		*rx_ring;
+	struct macb_dma_desc	*rx_ring;
 	void			*rx_buffers;
 
 	unsigned int		tx_head, tx_tail;
-	struct dma_desc		*tx_ring;
-	struct ring_info	*tx_skb;
+	struct macb_dma_desc	*tx_ring;
+	struct macb_tx_skb	*tx_skb;
 
 	spinlock_t		lock;
 	struct platform_device	*pdev;
@@ -535,8 +545,6 @@ struct macb {
 	dma_addr_t		tx_ring_dma;
 	dma_addr_t		rx_buffers_dma;
 
-	unsigned int		rx_pending, tx_pending;
-
 	struct mii_bus		*mii_bus;
 	struct phy_device	*phy_dev;
 	unsigned int 		link;
-- 
1.8.0

^ permalink raw reply related

* [PATCH v3 05/10] net/macb: tx status is more than 8 bits now
From: Nicolas Ferre @ 2012-10-30 10:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1351591858.git.nicolas.ferre@atmel.com>

On some revision of GEM, TSR status register has more information.

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
 drivers/net/ethernet/cadence/macb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index 4db52f3..cd6d431 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -314,7 +314,7 @@ static void macb_tx(struct macb *bp)
 	status = macb_readl(bp, TSR);
 	macb_writel(bp, TSR, status);
 
-	netdev_vdbg(bp->dev, "macb_tx status = %02lx\n", (unsigned long)status);
+	netdev_vdbg(bp->dev, "macb_tx status = 0x%03lx\n", (unsigned long)status);
 
 	if (status & (MACB_BIT(UND) | MACB_BIT(TSR_RLE))) {
 		int i;
-- 
1.8.0

^ permalink raw reply related

* [PATCH v3 04/10] net/macb: remove macb_get_drvinfo()
From: Nicolas Ferre @ 2012-10-30 10:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1351591858.git.nicolas.ferre@atmel.com>

This function has little meaning so remove it altogether and
let ethtool core fill in the fields automatically.

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Reviewed-by: Ben Hutchings <bhutchings@solarflare.com>
---
 drivers/net/ethernet/cadence/macb.c | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index b161d73..4db52f3 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -1225,20 +1225,9 @@ static int macb_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 	return phy_ethtool_sset(phydev, cmd);
 }
 
-static void macb_get_drvinfo(struct net_device *dev,
-			     struct ethtool_drvinfo *info)
-{
-	struct macb *bp = netdev_priv(dev);
-
-	strcpy(info->driver, bp->pdev->dev.driver->name);
-	strcpy(info->version, "$Revision: 1.14 $");
-	strcpy(info->bus_info, dev_name(&bp->pdev->dev));
-}
-
 const struct ethtool_ops macb_ethtool_ops = {
 	.get_settings		= macb_get_settings,
 	.set_settings		= macb_set_settings,
-	.get_drvinfo		= macb_get_drvinfo,
 	.get_link		= ethtool_op_get_link,
 	.get_ts_info		= ethtool_op_get_ts_info,
 };
-- 
1.8.0

^ permalink raw reply related

* [PATCH v3 03/10] net/macb: change debugging messages
From: Nicolas Ferre @ 2012-10-30 10:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1351591858.git.nicolas.ferre@atmel.com>

From: Havard Skinnemoen <havard@skinnemoen.net>

Convert some noisy netdev_dbg() statements to netdev_vdbg(). Defining
DEBUG will no longer fill up the logs; VERBOSE_DEBUG still does.
Add one more verbose debug for ISR status.

Signed-off-by: Havard Skinnemoen <havard@skinnemoen.net>
[nicolas.ferre at atmel.com: split patch in topics, add ISR status]
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
 drivers/net/ethernet/cadence/macb.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index e7f554d..b161d73 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -314,7 +314,7 @@ static void macb_tx(struct macb *bp)
 	status = macb_readl(bp, TSR);
 	macb_writel(bp, TSR, status);
 
-	netdev_dbg(bp->dev, "macb_tx status = %02lx\n", (unsigned long)status);
+	netdev_vdbg(bp->dev, "macb_tx status = %02lx\n", (unsigned long)status);
 
 	if (status & (MACB_BIT(UND) | MACB_BIT(TSR_RLE))) {
 		int i;
@@ -381,7 +381,7 @@ static void macb_tx(struct macb *bp)
 		if (!(bufstat & MACB_BIT(TX_USED)))
 			break;
 
-		netdev_dbg(bp->dev, "skb %u (data %p) TX complete\n",
+		netdev_vdbg(bp->dev, "skb %u (data %p) TX complete\n",
 			   tail, skb->data);
 		dma_unmap_single(&bp->pdev->dev, rp->mapping, skb->len,
 				 DMA_TO_DEVICE);
@@ -407,7 +407,7 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag,
 
 	len = MACB_BFEXT(RX_FRMLEN, bp->rx_ring[last_frag].ctrl);
 
-	netdev_dbg(bp->dev, "macb_rx_frame frags %u - %u (len %u)\n",
+	netdev_vdbg(bp->dev, "macb_rx_frame frags %u - %u (len %u)\n",
 		   first_frag, last_frag, len);
 
 	skb = netdev_alloc_skb(bp->dev, len + RX_OFFSET);
@@ -454,7 +454,7 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag,
 
 	bp->stats.rx_packets++;
 	bp->stats.rx_bytes += len;
-	netdev_dbg(bp->dev, "received skb of length %u, csum: %08x\n",
+	netdev_vdbg(bp->dev, "received skb of length %u, csum: %08x\n",
 		   skb->len, skb->csum);
 	netif_receive_skb(skb);
 
@@ -536,7 +536,7 @@ static int macb_poll(struct napi_struct *napi, int budget)
 
 	work_done = 0;
 
-	netdev_dbg(bp->dev, "poll: status = %08lx, budget = %d\n",
+	netdev_vdbg(bp->dev, "poll: status = %08lx, budget = %d\n",
 		   (unsigned long)status, budget);
 
 	work_done = macb_rx(bp, budget);
@@ -575,6 +575,8 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
 			break;
 		}
 
+		netdev_vdbg(bp->dev, "isr = 0x%08lx\n", (unsigned long)status);
+
 		if (status & MACB_RX_INT_FLAGS) {
 			/*
 			 * There's no point taking any more interrupts
@@ -586,7 +588,7 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
 			macb_writel(bp, IDR, MACB_RX_INT_FLAGS);
 
 			if (napi_schedule_prep(&bp->napi)) {
-				netdev_dbg(bp->dev, "scheduling RX softirq\n");
+				netdev_vdbg(bp->dev, "scheduling RX softirq\n");
 				__napi_schedule(&bp->napi);
 			}
 		}
@@ -648,8 +650,8 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	u32 ctrl;
 	unsigned long flags;
 
-#ifdef DEBUG
-	netdev_dbg(bp->dev,
+#if defined(DEBUG) && defined(VERBOSE_DEBUG)
+	netdev_vdbg(bp->dev,
 		   "start_xmit: len %u head %p data %p tail %p end %p\n",
 		   skb->len, skb->head, skb->data,
 		   skb_tail_pointer(skb), skb_end_pointer(skb));
@@ -671,12 +673,12 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	}
 
 	entry = bp->tx_head;
-	netdev_dbg(bp->dev, "Allocated ring entry %u\n", entry);
+	netdev_vdbg(bp->dev, "Allocated ring entry %u\n", entry);
 	mapping = dma_map_single(&bp->pdev->dev, skb->data,
 				 len, DMA_TO_DEVICE);
 	bp->tx_skb[entry].skb = skb;
 	bp->tx_skb[entry].mapping = mapping;
-	netdev_dbg(bp->dev, "Mapped skb data %p to DMA addr %08lx\n",
+	netdev_vdbg(bp->dev, "Mapped skb data %p to DMA addr %08lx\n",
 		   skb->data, (unsigned long)mapping);
 
 	ctrl = MACB_BF(TX_FRMLEN, len);
-- 
1.8.0

^ permalink raw reply related

* [PATCH v3 02/10] net/macb: memory barriers cleanup
From: Nicolas Ferre @ 2012-10-30 10:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1351591858.git.nicolas.ferre@atmel.com>

From: Havard Skinnemoen <havard@skinnemoen.net>

Remove a couple of unneeded barriers and document the remaining ones.

Signed-off-by: Havard Skinnemoen <havard@skinnemoen.net>
[nicolas.ferre at atmel.com: split patch in topics]
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
 drivers/net/ethernet/cadence/macb.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index 0931cb7..e7f554d 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -373,7 +373,9 @@ static void macb_tx(struct macb *bp)
 
 		BUG_ON(skb == NULL);
 
+		/* Make hw descriptor updates visible to CPU */
 		rmb();
+
 		bufstat = bp->tx_ring[tail].ctrl;
 
 		if (!(bufstat & MACB_BIT(TX_USED)))
@@ -416,7 +418,10 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag,
 			if (frag == last_frag)
 				break;
 		}
+
+		/* Make descriptor updates visible to hardware */
 		wmb();
+
 		return 1;
 	}
 
@@ -437,12 +442,14 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag,
 					       frag_len);
 		offset += RX_BUFFER_SIZE;
 		bp->rx_ring[frag].addr &= ~MACB_BIT(RX_USED);
-		wmb();
 
 		if (frag == last_frag)
 			break;
 	}
 
+	/* Make descriptor updates visible to hardware */
+	wmb();
+
 	skb->protocol = eth_type_trans(skb, bp->dev);
 
 	bp->stats.rx_packets++;
@@ -462,6 +469,8 @@ static void discard_partial_frame(struct macb *bp, unsigned int begin,
 
 	for (frag = begin; frag != end; frag = NEXT_RX(frag))
 		bp->rx_ring[frag].addr &= ~MACB_BIT(RX_USED);
+
+	/* Make descriptor updates visible to hardware */
 	wmb();
 
 	/*
@@ -480,7 +489,9 @@ static int macb_rx(struct macb *bp, int budget)
 	for (; budget > 0; tail = NEXT_RX(tail)) {
 		u32 addr, ctrl;
 
+		/* Make hw descriptor updates visible to CPU */
 		rmb();
+
 		addr = bp->rx_ring[tail].addr;
 		ctrl = bp->rx_ring[tail].ctrl;
 
@@ -675,6 +686,8 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	bp->tx_ring[entry].addr = mapping;
 	bp->tx_ring[entry].ctrl = ctrl;
+
+	/* Make newly initialized descriptor visible to hardware */
 	wmb();
 
 	entry = NEXT_TX(entry);
@@ -783,9 +796,6 @@ static void macb_init_rings(struct macb *bp)
 
 static void macb_reset_hw(struct macb *bp)
 {
-	/* Make sure we have the write buffer for ourselves */
-	wmb();
-
 	/*
 	 * Disable RX and TX (XXX: Should we halt the transmission
 	 * more gracefully?)
-- 
1.8.0

^ permalink raw reply related

* [PATCH v3 01/10] net/macb: Add support for Gigabit Ethernet mode
From: Nicolas Ferre @ 2012-10-30 10:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1351591858.git.nicolas.ferre@atmel.com>

From: Patrice Vilchez <patrice.vilchez@atmel.com>

Add Gigabit Ethernet mode to GEM cadence IP and enable RGMII connection.

Signed-off-by: Patrice Vilchez <patrice.vilchez@atmel.com>
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
 drivers/net/ethernet/cadence/macb.c | 15 ++++++++++++---
 drivers/net/ethernet/cadence/macb.h |  4 ++++
 2 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index 6a4f499..0931cb7 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -152,13 +152,17 @@ static void macb_handle_link_change(struct net_device *dev)
 
 			reg = macb_readl(bp, NCFGR);
 			reg &= ~(MACB_BIT(SPD) | MACB_BIT(FD));
+			if (macb_is_gem(bp))
+				reg &= ~GEM_BIT(GBE);
 
 			if (phydev->duplex)
 				reg |= MACB_BIT(FD);
 			if (phydev->speed == SPEED_100)
 				reg |= MACB_BIT(SPD);
+			if (phydev->speed == SPEED_1000)
+				reg |= GEM_BIT(GBE);
 
-			macb_writel(bp, NCFGR, reg);
+			macb_or_gem_writel(bp, NCFGR, reg);
 
 			bp->speed = phydev->speed;
 			bp->duplex = phydev->duplex;
@@ -216,7 +220,10 @@ static int macb_mii_probe(struct net_device *dev)
 	}
 
 	/* mask with MAC supported features */
-	phydev->supported &= PHY_BASIC_FEATURES;
+	if (macb_is_gem(bp))
+		phydev->supported &= PHY_GBIT_FEATURES;
+	else
+		phydev->supported &= PHY_BASIC_FEATURES;
 
 	phydev->advertising = phydev->supported;
 
@@ -1388,7 +1395,9 @@ static int __init macb_probe(struct platform_device *pdev)
 		bp->phy_interface = err;
 	}
 
-	if (bp->phy_interface == PHY_INTERFACE_MODE_RMII)
+	if (bp->phy_interface == PHY_INTERFACE_MODE_RGMII)
+		macb_or_gem_writel(bp, USRIO, GEM_BIT(RGMII));
+	else if (bp->phy_interface == PHY_INTERFACE_MODE_RMII)
 #if defined(CONFIG_ARCH_AT91)
 		macb_or_gem_writel(bp, USRIO, (MACB_BIT(RMII) |
 					       MACB_BIT(CLKEN)));
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index a362751..33a050f 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -149,6 +149,8 @@
 #define MACB_IRXFCS_SIZE			1
 
 /* GEM specific NCFGR bitfields. */
+#define GEM_GBE_OFFSET				10
+#define GEM_GBE_SIZE				1
 #define GEM_CLK_OFFSET				18
 #define GEM_CLK_SIZE				3
 #define GEM_DBW_OFFSET				21
@@ -252,6 +254,8 @@
 /* Bitfields in USRIO (AT91) */
 #define MACB_RMII_OFFSET			0
 #define MACB_RMII_SIZE				1
+#define GEM_RGMII_OFFSET			0	/* GEM gigabit mode */
+#define GEM_RGMII_SIZE				1
 #define MACB_CLKEN_OFFSET			1
 #define MACB_CLKEN_SIZE				1
 
-- 
1.8.0

^ permalink raw reply related

* [PATCH v3 00/10] net/macb: driver enhancement concerning GEM support, ring logic and cleanup
From: Nicolas Ferre @ 2012-10-30 10:17 UTC (permalink / raw)
  To: linux-arm-kernel

This is an enhancement work that began several years ago. I try to catchup with
some performance improvement that has been implemented then by Havard.
The ring index logic and the TX error path modification are the biggest changes
but some cleanup/debugging have been added along the way.
The GEM revision will benefit from the Gigabit support.
Newer pinctrl infrastructure support is added but it is optional.

The series has been tested on several Atmel AT91 SoC with the two MACB/GEM
flavors.

v3: - rebased on net-next to take into account current effor to merge
      at91_ether with macb drivers
    - add additional patch to use the new pinctrl infrastructure
v2: - modify the tx error handling: now uses a workqueue
    - information provided by ethtool -i were not accurate: removed

Havard Skinnemoen (4):
  net/macb: memory barriers cleanup
  net/macb: change debugging messages
  net/macb: clean up ring buffer logic
  net/macb: Offset first RX buffer by two bytes

Jean-Christophe PLAGNIOL-VILLARD (1):
  net/macb: add pinctrl consumer support

Nicolas Ferre (4):
  net/macb: remove macb_get_drvinfo()
  net/macb: tx status is more than 8 bits now
  net/macb: ethtool interface: add register dump feature
  net/macb: better manage tx errors

Patrice Vilchez (1):
  net/macb: Add support for Gigabit Ethernet mode

 drivers/net/ethernet/cadence/macb.c | 446 +++++++++++++++++++++++++-----------
 drivers/net/ethernet/cadence/macb.h |  30 ++-
 2 files changed, 334 insertions(+), 142 deletions(-)

-- 
1.8.0

^ permalink raw reply

* linux-next: manual merge of the clk tree with the arm-soc tree
From: Mike Turquette @ 2012-10-30 10:11 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121030150627.ac1f6a3f75231ea49edf7b98@canb.auug.org.au>

Quoting Stephen Rothwell (2012-10-29 21:06:27)
> Hi Mike,
> 
> Today's linux-next merge of the clk tree got a conflict in
> arch/arm/include/asm/hardware/sp810.h between commit 0891642cf117 ("ARM:
> vexpress: Start using new Versatile Express infrastructure") from the
> arm-soc tree and commit 05e3659135a4 ("clk: Common clocks implementation
> for Versatile Express") from the clk tree.
> 
> I fixed it up (see below) and can carry the fix as necessary (no action
> is required).
> 
> -- 
> Cheers,
> Stephen Rothwell                    sfr at canb.auug.org.au
> 
> diff --cc arch/arm/include/asm/hardware/sp810.h
> index 2cdcf44,afd7e91..0000000
> --- a/arch/arm/include/asm/hardware/sp810.h
> +++ b/arch/arm/include/asm/hardware/sp810.h
> @@@ -50,6 -50,14 +50,8 @@@
>   #define SCPCELLID2            0xFF8
>   #define SCPCELLID3            0xFFC
>   
>  -#define SCCTRL_TIMEREN0SEL_REFCLK     (0 << 15)
>  -#define SCCTRL_TIMEREN0SEL_TIMCLK     (1 << 15)
>  -
>  -#define SCCTRL_TIMEREN1SEL_REFCLK     (0 << 17)
>  -#define SCCTRL_TIMEREN1SEL_TIMCLK     (1 << 17)
>  -
> + #define SCCTRL_TIMERENnSEL_SHIFT(n)   (15 + ((n) * 2))
> + 
>   static inline void sysctl_soft_reset(void __iomem *base)
>   {
>         /* switch to slow mode */

Pawel,

Does this look OK for you?

Thanks,
Mike

^ permalink raw reply

* [PATCH] [RFC] crypto: sha1/arm - fix build with CONFIG_THUMB2_KERNEL
From: Jussi Kivilinna @ 2012-10-30 10:07 UTC (permalink / raw)
  To: linux-arm-kernel

Building cryptodev-2.6 tree with CONFIG_THUMB2_KERNEL=y and
CONFIG_CRYPTO_SHA1_ARM=y give following error:

   AS      arch/arm/crypto/sha1-armv4-large.o
arch/arm/crypto/sha1-armv4-large.S: Assembler messages:
arch/arm/crypto/sha1-armv4-large.S:197: Error: r13 not allowed here --
`teq r14,sp'
arch/arm/crypto/sha1-armv4-large.S:377: Error: r13 not allowed here --
`teq r14,sp'
arch/arm/crypto/sha1-armv4-large.S:469: Error: r13 not allowed here --
`teq r14,sp'

Build can be fixed with adding '.arm' at head of sha1-armv4-large.S.
However I'm not sure if this correct fix as this is my first stab
at arm assembler and I could not get CONFIG_THUMB2_KERNEL boot up
on 'qemu-system-arm -M vexpress-a9' to verify correctness. So this
is only build tested.

Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-crypto at vger.kernel.org
Cc: David McCullough <ucdevel@gmail.com>
---
 arch/arm/crypto/sha1-armv4-large.S |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/crypto/sha1-armv4-large.S b/arch/arm/crypto/sha1-armv4-large.S
index 7050ab1..e8a55eb 100644
--- a/arch/arm/crypto/sha1-armv4-large.S
+++ b/arch/arm/crypto/sha1-armv4-large.S
@@ -53,6 +53,8 @@
 
 .text
 
+.arm
+
 .global	sha1_block_data_order
 .type	sha1_block_data_order,%function
 

^ permalink raw reply related

* [PATCH] arm: dt: tegra: fix length of pad control and mux registers
From: Pritesh Raithatha @ 2012-10-30 10:07 UTC (permalink / raw)
  To: linux-arm-kernel

Cc: <stable@vger.kernel.org>
Signed-off-by: Pritesh Raithatha <praithatha@nvidia.com>
---
 arch/arm/boot/dts/tegra30.dtsi |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index 3e4334d..3f96658 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -73,8 +73,8 @@
 
 	pinmux: pinmux {
 		compatible = "nvidia,tegra30-pinmux";
-		reg = <0x70000868 0xd0    /* Pad control registers */
-		       0x70003000 0x3e0>; /* Mux registers */
+		reg = <0x70000868 0xd4    /* Pad control registers */
+		       0x70003000 0x3e4>; /* Mux registers */
 	};
 
 	serial at 70006000 {
-- 
1.7.1

^ permalink raw reply related

* [PATCH] CLK: clk-twl6040: Initial clock driver for OMAP4+ McPDM fclk clock
From: Mike Turquette @ 2012-10-30 10:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <508F842D.8000407@ti.com>

Quoting P?ter Ujfalusi (2012-10-30 00:39:25)
> Hi Mike,
> 
> On 10/29/2012 06:30 PM, Mike Turquette wrote:
> > Peter,
> > 
> > The patch looks good to me.  To be clear, you wan this to go through
> > clk-next or the mfd tree for avoiding conflicts?
> 
> clk-next is the best place for it I think. The MFD part to register the device
> can still wait till we have ccf support on OMAP4.
>

Cool.  I've taken this into clk-next.

Regards,
Mike
 
> Thank you,
> P?ter

^ permalink raw reply

* [PATCH] ARM: cache-l2x0.c: Apply the workaround to r3p0 only
From: srinidhi kasagar @ 2012-10-30 10:02 UTC (permalink / raw)
  To: linux-arm-kernel

The PL310 bug 753970 should be applied only to r3p0

Signed-off-by: srinidhi kasagar <srinidhi.kasagar@stericsson.com>
---
 arch/arm/mm/cache-l2x0.c |    9 +++++++--
 1 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 2a8e380..7925734 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -311,6 +311,7 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
 	u32 aux;
 	u32 cache_id;
 	u32 way_size = 0;
+	u32 l2x0_revision;
 	int ways;
 	const char *type;
 
@@ -331,8 +332,12 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
 			ways = 8;
 		type = "L310";
 #ifdef CONFIG_PL310_ERRATA_753970
-		/* Unmapped register. */
-		sync_reg_offset = L2X0_DUMMY_REG;
+		 /* FIXME: make sense to have dt support for L2 Erratas? */
+		l2x0_revision = readl_relaxed(l2x0_base + L2X0_CACHE_ID) &
+				L2X0_CACHE_ID_RTL_MASK;
+		if (l2x0_revision == L2X0_CACHE_ID_RTL_R3P0)
+			/* Unmapped register. */
+			sync_reg_offset = L2X0_DUMMY_REG;
 #endif
 		outer_cache.set_debug = pl310_set_debug;
 		break;
-- 
1.7.2.dirty

^ permalink raw reply related

* [PATCH v4] Network driver for the Armada 370 and Armada XP ARM Marvell SoCs
From: Thomas Petazzoni @ 2012-10-30  9:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351245804-31478-1-git-send-email-thomas.petazzoni@free-electrons.com>

Hello,

On Fri, 26 Oct 2012 12:03:20 +0200, Thomas Petazzoni wrote:

> This patch set adds a new network driver for the network unit
> available in the newest Marvell ARM SoCs Armada 370 and Armada XP, as
> well as the necessary Device Tree information to use this driver in
> the two evaluation platforms of those SoCs.

Besides Nobuhiro's small comment on the Device Tree part, are there any
comments on the driver itself, or is the code good to go?

I can send a fifth version with just the fix for Nobuhiro's comment,
but it probably makes sense to take into account a few more comments
(if any) at the same time.

Thanks for your review,

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

^ permalink raw reply

* [RFC PATCH v3 16/16] ARM: dts: add AM33XX SPI support
From: Philip, Avinash @ 2012-10-30  9:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350566815-409-17-git-send-email-mporter@ti.com>

On Mon, Oct 29, 2012 at 14:40:02, Philip, Avinash wrote:
> On Thu, Oct 18, 2012 at 18:56:55, Porter, Matt wrote:
> > Adds AM33XX SPI support for am335x-bone and am335x-evm.

Matt,

Can you build SPI DT patch with DMA support on top of SPI DT patch
I submitted [1]. With the patch [1] SPI can work on PIO mode.
So we can have basic SPI support available in 3.8.

Benoit,
Can you accept the SPI DT patch [1]

In case if you want I will resubmit a patch with subject line modified.

Current subject line
arm/dts: AM33XX: Add SPI device tree data

1. https://patchwork.kernel.org/patch/1470661/

Thanks
Avinash

> > 
> > Signed-off-by: Matt Porter <mporter@ti.com>
> > ---
> >  arch/arm/boot/dts/am335x-bone.dts |   17 +++++++++++++++
> >  arch/arm/boot/dts/am335x-evm.dts  |    9 ++++++++
> >  arch/arm/boot/dts/am33xx.dtsi     |   43 +++++++++++++++++++++++++++++++++++++
> >  3 files changed, 69 insertions(+)
> > 
> > diff --git a/arch/arm/boot/dts/am335x-bone.dts b/arch/arm/boot/dts/am335x-bone.dts
> > index 5510979..23edfd8 100644
> > --- a/arch/arm/boot/dts/am335x-bone.dts
> > +++ b/arch/arm/boot/dts/am335x-bone.dts
> > @@ -18,6 +18,17 @@
> >  		reg = <0x80000000 0x10000000>; /* 256 MB */
> >  	};
> >  
> > +	am3358_pinmux: pinmux at 44e10800 {
> > +		spi1_pins: pinmux_spi1_pins {
> > +			pinctrl-single,pins = <
> > +				0x190 0x13	/* mcasp0_aclkx.spi1_sclk, OUTPUT_PULLUP | MODE3 */
> > +				0x194 0x33	/* mcasp0_fsx.spi1_d0, INPUT_PULLUP | MODE3 */
> > +				0x198 0x13	/* mcasp0_axr0.spi1_d1, OUTPUT_PULLUP | MODE3 */
> > +				0x19c 0x13	/* mcasp0_ahclkr.spi1_cs0, OUTPUT_PULLUP | MODE3 */
> > +			>;
> > +		};
> > +	};
> > +
> 
> Change to am33xx_pinmux.
> 
> >  	ocp {
> >  		uart1: serial at 44e09000 {
> >  			status = "okay";
> > @@ -84,3 +95,9 @@
> >  &mmc1 {
> >  	vmmc-supply = <&ldo3_reg>;
> >  };
> > +
> > +&spi1 {
> > +	status = "okay";
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&spi1_pins>;
> > +};
> > diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
> > index d63fce8..8d5f660 100644
> > --- a/arch/arm/boot/dts/am335x-evm.dts
> > +++ b/arch/arm/boot/dts/am335x-evm.dts
> > @@ -124,3 +124,12 @@
> >  &mmc1 {
> >  	vmmc-supply = <&vmmc_reg>;
> >  };
> > +
> > +&spi0 {
> > +	status = "okay";
> > +	spi-flash at 0 {
> > +		compatible = "spansion,s25fl064k", "m25p80";
> > +		spi-max-frequency = <24000000>;
> > +		reg = <0>;
> > +	};
> > +};
> 
> In AM335x-evm, SPI flash available in profile #2 (am335x evm specific profiles).
> So can you drop this changes as if I understood correctly, am335x-evm.dts will be
> populated for devices present only on profile #0.
> 
> > diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
> > index 26a6af7..063ecea 100644
> > --- a/arch/arm/boot/dts/am33xx.dtsi
> > +++ b/arch/arm/boot/dts/am33xx.dtsi
> > @@ -40,6 +40,15 @@
> >  		};
> >  	};
> >  
> > +	am3358_pinmux: pinmux at 44e10800 {
> > +		compatible = "pinctrl-single";
> > +		reg = <0x44e10800 0x0238>;
> > +		#address-cells = <1>;
> > +		#size-cells = <0>;
> > +		pinctrl-single,register-width = <32>;
> > +		pinctrl-single,function-mask = <0x7f>;
> > +	};
> > +
> 
> Pin ctrl support already submitted
> http://git.kernel.org/?p=linux/kernel/git/bcousson/linux-omap-dt.git;a=commitdiff;h=3e0603e905d9ba662e8c1885ecb1d28bc454e448
> 
> Thanks
> Avinash
> 
> >  	/*
> >  	 * XXX: Use a flat representation of the AM33XX interconnect.
> >  	 * The real AM33XX interconnect network is quite complex.Since
> > @@ -261,6 +270,40 @@
> >  			status = "disabled";
> >  		};
> >  
> > +		spi0: spi at 48030000 {
> > +			compatible = "ti,omap4-mcspi";
> > +			ti,hwmods = "spi0";
> > +			#address-cells = <1>;
> > +			#size-cells = <0>;
> > +			reg = <0x48030000 0x400>;
> > +			interrupt-parent = <&intc>;
> > +			interrupt = <65>;
> > +			dmas = <&edma 16
> > +				&edma 17
> > +				&edma 18
> > +				&edma 19>;
> > +			dma-names = "tx0", "rx0", "tx1", "rx1";
> > +			ti,spi-num-cs = <2>;
> > +			status = "disabled";
> > +		};
> > +
> > +		spi1: spi at 481a0000 {
> > +			compatible = "ti,omap4-mcspi";
> > +			ti,hwmods = "spi1";
> > +			#address-cells = <1>;
> > +			#size-cells = <0>;
> > +			reg = <0x481a0000 0x400>;
> > +			interrupt-parent = <&intc>;
> > +			interrupt = <125>;
> > +			dmas = <&edma 42
> > +				&edma 43
> > +				&edma 44
> > +				&edma 45>;
> > +			dma-names = "tx0", "rx0", "tx1", "rx1";
> > +			ti,spi-num-cs = <2>;
> > +			status = "disabled";
> > +		};
> > +
> >  		wdt2: wdt at 44e35000 {
> >  			compatible = "ti,omap3-wdt";
> >  			ti,hwmods = "wd_timer2";
> > -- 
> > 1.7.9.5
> > 
> > 
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> > 
> 
> 

^ permalink raw reply

* [PATCH] arm/dts: am33xx rtc node
From: Afzal Mohammed @ 2012-10-30  9:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1350643825-9657-1-git-send-email-afzal@ti.com>

Hi Benoit,

On Friday 19 October 2012 04:20 PM, Afzal Mohammed wrote:
> add am33xx rtc node.
>
> Signed-off-by: Afzal Mohammed<afzal@ti.com>
> ---
>
> Based on v3.7-rc1,
> Dependent on series "rtc: omap dt support (for am33xx)",
> (https://lkml.org/lkml/2012/10/19/163)

The dependent series has been merged on -mm tree
and are now present in linux-next.

v2 of this patch has been sent with modification on subject
to follow new convention and removing interrupt parent.

Regards
Afzal

^ permalink raw reply

* [PATCH v2] ARM: dts: am33xx: rtc node
From: Afzal Mohammed @ 2012-10-30  9:34 UTC (permalink / raw)
  To: linux-arm-kernel

Add am33xx rtc node.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
Hi Benoit,

This is based on your for_3.8/dts branch.

This has been tested on Beagle Bone.

Bindings along with driver changes for DT has been picked by Andrew
Morton and is now present in linux-next.

Regards
Afzal

v2
 1. Remove interrupt parent in rtc node.
 2. Modify subject as per new convention.


 arch/arm/boot/dts/am33xx.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index 70d24b8..97a7bd3 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -291,5 +291,13 @@
 			ti,hwmods = "timer7";
 			ti,timer-pwm;
 		};
+
+		rtc at 44e3e000 {
+			compatible = "ti,da830-rtc";
+			reg = <0x44e3e000 0x1000>;
+			interrupts = <75
+				      76>;
+			ti,hwmods = "rtc";
+		};
 	};
 };
-- 
1.7.12

^ permalink raw reply related

* [PATCH 3/4] pinctrl: samsung: Add support for Exynos4x12
From: Linus Walleij @ 2012-10-30  9:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <508E683C.6040807@samsung.com>

On Mon, Oct 29, 2012 at 12:27 PM, Kukjin Kim <kgene.kim@samsung.com> wrote:

> On 10/29/12 19:28, Tomasz Figa wrote:
>> On Monday 29 of October 2012 09:30:26 Kyungmin Park wrote:

>> Since this depends on the patch adding Exynos4x12 dts files
>> ([PATCH] ARM: dts: exynos4: Add support for Exynos4x12 SoCs),
>> which will be going through Kgene's tree and this patch series contains
>> mostly SoC-specific code, maybe this should rather go through Kgene's
>> tree? Or this is not a problem?
>>
> Yeah, I agree with Tomasz's opinion and let me pick this into Samsung tree
> with Linus's ack.

Seems to have worked out well, just one minor conflict in -next
so let's go for this...

Yours,
Linus Walleij

^ permalink raw reply

* [PATCH 4/4] DMA: PL330: add device tree property for DMA_MEMCPY capability
From: Bartlomiej Zolnierkiewicz @ 2012-10-30  9:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CABb+yY1Ztu2n38ObXJq+shOoXw6yk0YK39QUHhDN_pJKziAFQg@mail.gmail.com>


Hi,

On Monday 29 October 2012 22:45:48 Jassi Brar wrote:
> On Mon, Oct 29, 2012 at 10:59 AM, Bartlomiej Zolnierkiewicz
> <b.zolnierkie@samsung.com> wrote:
> > * Add device tree (DT) property ("pl330,dma-memcpy") for DMA_MEMCPY
> >   capability and instead of setting this capability unconditionally
> >   in pl330_probe() do it only when property is present.
> >
> Perhaps we should pass the array of peripheral interfaces via DT, the
> lack of which could imply MEMCPY capability ? (while it works, I doubt
> if pl330 is supposed to have SLAVE and MEMCPY capabilities in any
> instance)

In case of PL330 on EXYNOS4 we have two interfaces with SLAVE capability
and one interface with MEMCPY capability.  Could you please explain more
the idea of passing the array of peripherals through DT so we can detect
which interface has MEMCPY capability?

> That would also be a step towards discarding "struct dma_pl330_platdata".

I don't know if getting rid of "struct dma_pl330_platdata" is possible
but we still need to come up with some way to pass the needed information
through DT.  Do you have an idea how it could be done?

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung Poland R&D Center

^ permalink raw reply

* [PATCH 2/4] ARM: EXYNOS: PL330 MDMA1 fix for revision 0 of Exynos4210 SOC
From: Bartlomiej Zolnierkiewicz @ 2012-10-30  8:56 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <508EBBB6.2090006@samsung.com>


Hi,

On Monday 29 October 2012 18:24:06 Kukjin Kim wrote:
> On 10/29/12 10:59, Bartlomiej Zolnierkiewicz wrote:
> > Commit 8214513 ("ARM: EXYNOS: fix address for EXYNOS4 MDMA1")
> > changed EXYNOS specific setup of PL330 DMA engine to use 'non-secure'
> > mdma1 address instead of 'secure' one (from 0x12840000 to 0x12850000)
> > to fix issue with some Exynos4212 SOCs.  Unfortunately it brakes
> > PL330 setup for revision 0 of Exynos4210 SOC (mdma1 device cannot
> > be found at 'non-secure' address):
> >
> > [    0.566245] dma-pl330 dma-pl330.2: PERIPH_ID 0x0, PCELL_ID 0x0 !
> > [    0.566278] dma-pl330: probe of dma-pl330.2 failed with error -22
> >
> > Fix it by using 'secure' mdma1 address on Exynos4210 revision 0 SOC.
> >
> > Cc: Tomasz Figa<t.figa@samsung.com>
> > Cc: Kukjin Kim<kgene.kim@samsung.com>
> > Signed-off-by: Bartlomiej Zolnierkiewicz<b.zolnierkie@samsung.com>
> > Signed-off-by: Kyungmin Park<kyungmin.park@samsung.com>
> > ---
> >   arch/arm/mach-exynos/dma.c              | 5 ++++-
> >   arch/arm/mach-exynos/include/mach/map.h | 3 ++-
> >   2 files changed, 6 insertions(+), 2 deletions(-)
> 
> [...]
> 
> > +		if (samsung_rev() == EXYNOS4210_REV_0)
> > +			exynos_mdma1_device.res.start = EXYNOS4_PA_S_MDMA1;
> 
> Hi Bart,
> 
> Hmm...above change and adding definition of EXYNOS_PA_S_MDMA1 address 
> can fix the problem you commented on EXYNOS4210 Rev0 without others?...

The problem is affecting only EXYNOS4210 Rev0 and the fix is applied only
for case when soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_0,
or did you mean something else?

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung Poland R&D Center

> Thanks.
> 
> Best regards,
> Kgene.
> --
> Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
> SW Solution Development Team, Samsung Electronics Co., Ltd.

^ permalink raw reply

* OMAP baseline test results for v3.7-rc1
From: Jean Pihet @ 2012-10-30  8:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <alpine.DEB.2.00.1210300416190.12697@utopia.booyaka.com>

Hi Paul,

On Tue, Oct 30, 2012 at 5:16 AM, Paul Walmsley <paul@pwsan.com> wrote:
> Hello Jean,
>
> On Tue, 23 Oct 2012, Jean Pihet wrote:
>
>> Let me try with the same setup as yours (bootloader images,
>> omap2pus_defconfig, angstrom roots).
>
> Had any luck reproducing this one that Aaro & I are seeing?
Unfortunately not. I could not reproduce the issue on my side, using
an ES2.1 Beagleboard with the latest l-o kernel and your bootloader
and rootfs images.
Is there some specific to enable in order to reproduce the issue?

Regards,
Jean

>
>
> - Paul

^ permalink raw reply

* [PATCH 3/4] arm: mvebu: add Ethernet controllers using mvneta driver for Armada 370/XP
From: Thomas Petazzoni @ 2012-10-30  8:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CABMQnVKswTJr9Nd4Etx4Htv0Ckn+pDNqGO8MoPBH-x8y6CwZyA@mail.gmail.com>

Hello,

On Tue, 30 Oct 2012 13:19:15 +0900, Nobuhiro Iwamatsu wrote:

> > diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi
> > index 16cc82c..d484492 100644
> > --- a/arch/arm/boot/dts/armada-370-xp.dtsi
> > +++ b/arch/arm/boot/dts/armada-370-xp.dtsi
> > @@ -68,6 +68,20 @@
> >                         compatible = "marvell,armada-addr-decoding-controller";
> >                         reg = <0xd0020000 0x258>;
> >                 };
> > +
> > +                ethernet at d0070000 {
> > +                               compatible = "marvell,armada-370-neta";
> > +                               reg = <0xd0070000 0x2500>;
> > +                               interrupts = <8>;
> > +                               status = "disabled";
> > +                };
> > +
> > +                ethernet at d0074000 {
> > +                               compatible = "marvell,armada-370-neta";
> > +                               reg = <0xd0074000 0x2500>;
> > +                               interrupts = <10>;
> > +                               status = "disabled";
> > +                };
> 
> Could you fit an indent?

Right, thanks, will fix.

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

^ permalink raw reply

* [PATCH] ARM: Exynos: move interrupt combiner controller driver to drivers/irqchip
From: Thomas Abraham @ 2012-10-30  8:22 UTC (permalink / raw)
  To: linux-arm-kernel

The irqchip support for interrupt combiner controller is moved into
drivers/irqchip directory from arch/arm/mach-exynos/common.c file.

While at it, the use of soc_is_exynos4/5() macro in the combiner controller
driver (used to determine the number of combiners) is removed. Instead, a new
parameter is added to combiner_init function that allows non-dt platform code
to specify the number of combiners available.

Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org>
---
 arch/arm/mach-exynos/common.c           |  210 +------------------------------
 drivers/irqchip/Makefile                |    1 +
 drivers/irqchip/irq-exynos-combiner.c   |  212 +++++++++++++++++++++++++++++++
 include/linux/irqchip/exynos-combiner.h |   18 +++
 4 files changed, 234 insertions(+), 207 deletions(-)
 create mode 100644 drivers/irqchip/irq-exynos-combiner.c
 create mode 100644 include/linux/irqchip/exynos-combiner.h

diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
index 5c75815..56844d1 100644
--- a/arch/arm/mach-exynos/common.c
+++ b/arch/arm/mach-exynos/common.c
@@ -17,11 +17,9 @@
 #include <linux/gpio.h>
 #include <linux/sched.h>
 #include <linux/serial_core.h>
-#include <linux/of.h>
 #include <linux/of_irq.h>
 #include <linux/export.h>
-#include <linux/irqdomain.h>
-#include <linux/of_address.h>
+#include <linux/irqchip/exynos-combiner.h>
 
 #include <asm/proc-fns.h>
 #include <asm/exception.h>
@@ -384,210 +382,7 @@ static void __init exynos5_init_clocks(int xtal)
 	exynos5_setup_clocks();
 }
 
-#define COMBINER_ENABLE_SET	0x0
-#define COMBINER_ENABLE_CLEAR	0x4
-#define COMBINER_INT_STATUS	0xC
-
-static DEFINE_SPINLOCK(irq_controller_lock);
-
-struct combiner_chip_data {
-	unsigned int irq_offset;
-	unsigned int irq_mask;
-	void __iomem *base;
-};
-
-static struct irq_domain *combiner_irq_domain;
-static struct combiner_chip_data combiner_data[MAX_COMBINER_NR];
-
-static inline void __iomem *combiner_base(struct irq_data *data)
-{
-	struct combiner_chip_data *combiner_data =
-		irq_data_get_irq_chip_data(data);
-
-	return combiner_data->base;
-}
-
-static void combiner_mask_irq(struct irq_data *data)
-{
-	u32 mask = 1 << (data->hwirq % 32);
-
-	__raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_CLEAR);
-}
-
-static void combiner_unmask_irq(struct irq_data *data)
-{
-	u32 mask = 1 << (data->hwirq % 32);
-
-	__raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_SET);
-}
-
-static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
-{
-	struct combiner_chip_data *chip_data = irq_get_handler_data(irq);
-	struct irq_chip *chip = irq_get_chip(irq);
-	unsigned int cascade_irq, combiner_irq;
-	unsigned long status;
-
-	chained_irq_enter(chip, desc);
-
-	spin_lock(&irq_controller_lock);
-	status = __raw_readl(chip_data->base + COMBINER_INT_STATUS);
-	spin_unlock(&irq_controller_lock);
-	status &= chip_data->irq_mask;
-
-	if (status == 0)
-		goto out;
-
-	combiner_irq = __ffs(status);
-
-	cascade_irq = combiner_irq + (chip_data->irq_offset & ~31);
-	if (unlikely(cascade_irq >= NR_IRQS))
-		do_bad_IRQ(cascade_irq, desc);
-	else
-		generic_handle_irq(cascade_irq);
-
- out:
-	chained_irq_exit(chip, desc);
-}
-
-static struct irq_chip combiner_chip = {
-	.name		= "COMBINER",
-	.irq_mask	= combiner_mask_irq,
-	.irq_unmask	= combiner_unmask_irq,
-};
-
-static void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq)
-{
-	unsigned int max_nr;
-
-	if (soc_is_exynos5250())
-		max_nr = EXYNOS5_MAX_COMBINER_NR;
-	else
-		max_nr = EXYNOS4_MAX_COMBINER_NR;
-
-	if (combiner_nr >= max_nr)
-		BUG();
-	if (irq_set_handler_data(irq, &combiner_data[combiner_nr]) != 0)
-		BUG();
-	irq_set_chained_handler(irq, combiner_handle_cascade_irq);
-}
-
-static void __init combiner_init_one(unsigned int combiner_nr,
-				     void __iomem *base)
-{
-	combiner_data[combiner_nr].base = base;
-	combiner_data[combiner_nr].irq_offset = irq_find_mapping(
-		combiner_irq_domain, combiner_nr * MAX_IRQ_IN_COMBINER);
-	combiner_data[combiner_nr].irq_mask = 0xff << ((combiner_nr % 4) << 3);
-
-	/* Disable all interrupts */
-	__raw_writel(combiner_data[combiner_nr].irq_mask,
-		     base + COMBINER_ENABLE_CLEAR);
-}
-
 #ifdef CONFIG_OF
-static int combiner_irq_domain_xlate(struct irq_domain *d,
-				     struct device_node *controller,
-				     const u32 *intspec, unsigned int intsize,
-				     unsigned long *out_hwirq,
-				     unsigned int *out_type)
-{
-	if (d->of_node != controller)
-		return -EINVAL;
-
-	if (intsize < 2)
-		return -EINVAL;
-
-	*out_hwirq = intspec[0] * MAX_IRQ_IN_COMBINER + intspec[1];
-	*out_type = 0;
-
-	return 0;
-}
-#else
-static int combiner_irq_domain_xlate(struct irq_domain *d,
-				     struct device_node *controller,
-				     const u32 *intspec, unsigned int intsize,
-				     unsigned long *out_hwirq,
-				     unsigned int *out_type)
-{
-	return -EINVAL;
-}
-#endif
-
-static int combiner_irq_domain_map(struct irq_domain *d, unsigned int irq,
-				   irq_hw_number_t hw)
-{
-	irq_set_chip_and_handler(irq, &combiner_chip, handle_level_irq);
-	irq_set_chip_data(irq, &combiner_data[hw >> 3]);
-	set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
-
-	return 0;
-}
-
-static struct irq_domain_ops combiner_irq_domain_ops = {
-	.xlate	= combiner_irq_domain_xlate,
-	.map	= combiner_irq_domain_map,
-};
-
-static void __init combiner_init(void __iomem *combiner_base,
-				 struct device_node *np)
-{
-	int i, irq, irq_base;
-	unsigned int max_nr, nr_irq;
-
-	if (np) {
-		if (of_property_read_u32(np, "samsung,combiner-nr", &max_nr)) {
-			pr_warning("%s: number of combiners not specified, "
-				"setting default as %d.\n",
-				__func__, EXYNOS4_MAX_COMBINER_NR);
-			max_nr = EXYNOS4_MAX_COMBINER_NR;
-		}
-	} else {
-		max_nr = soc_is_exynos5250() ? EXYNOS5_MAX_COMBINER_NR :
-						EXYNOS4_MAX_COMBINER_NR;
-	}
-	nr_irq = max_nr * MAX_IRQ_IN_COMBINER;
-
-	irq_base = irq_alloc_descs(COMBINER_IRQ(0, 0), 1, nr_irq, 0);
-	if (IS_ERR_VALUE(irq_base)) {
-		irq_base = COMBINER_IRQ(0, 0);
-		pr_warning("%s: irq desc alloc failed. Continuing with %d as linux irq base\n", __func__, irq_base);
-	}
-
-	combiner_irq_domain = irq_domain_add_legacy(np, nr_irq, irq_base, 0,
-				&combiner_irq_domain_ops, &combiner_data);
-	if (WARN_ON(!combiner_irq_domain)) {
-		pr_warning("%s: irq domain init failed\n", __func__);
-		return;
-	}
-
-	for (i = 0; i < max_nr; i++) {
-		combiner_init_one(i, combiner_base + (i >> 2) * 0x10);
-		irq = IRQ_SPI(i);
-#ifdef CONFIG_OF
-		if (np)
-			irq = irq_of_parse_and_map(np, i);
-#endif
-		combiner_cascade_irq(i, irq);
-	}
-}
-
-#ifdef CONFIG_OF
-int __init combiner_of_init(struct device_node *np, struct device_node *parent)
-{
-	void __iomem *combiner_base;
-
-	combiner_base = of_iomap(np, 0);
-	if (!combiner_base) {
-		pr_err("%s: failed to map combiner registers\n", __func__);
-		return -ENXIO;
-	}
-
-	combiner_init(combiner_base, np);
-
-	return 0;
-}
-
 static const struct of_device_id exynos4_dt_irq_match[] = {
 	{ .compatible = "arm,cortex-a9-gic", .data = gic_of_init, },
 	{ .compatible = "samsung,exynos4210-combiner",
@@ -610,7 +405,8 @@ void __init exynos4_init_irq(void)
 #endif
 
 	if (!of_have_populated_dt())
-		combiner_init(S5P_VA_COMBINER_BASE, NULL);
+		combiner_init(S5P_VA_COMBINER_BASE, EXYNOS4_MAX_COMBINER_NR,
+					NULL);
 
 	/*
 	 * The parameters of s5p_init_irq() are for VIC init.
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 054321d..8501eaa 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -1 +1,2 @@
 obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2835.o
+obj-$(CONFIG_ARCH_EXYNOS) += irq-exynos-combiner.o
diff --git a/drivers/irqchip/irq-exynos-combiner.c b/drivers/irqchip/irq-exynos-combiner.c
new file mode 100644
index 0000000..86caa98
--- /dev/null
+++ b/drivers/irqchip/irq-exynos-combiner.c
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * Interrupt combiner controller driver for Samsung Exynos platforms.
+ *
+ * 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.
+ */
+
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/export.h>
+#include <linux/irqdomain.h>
+#include <linux/of_address.h>
+#include <linux/err.h>
+#include <asm/mach/irq.h>
+
+#define COMBINER_ENABLE_SET	0x0
+#define COMBINER_ENABLE_CLEAR	0x4
+#define COMBINER_INT_STATUS	0xC
+
+struct combiner_chip_data {
+	unsigned int irq_offset;
+	unsigned int irq_mask;
+	void __iomem *base;
+};
+
+static DEFINE_SPINLOCK(irq_controller_lock);
+static struct irq_domain *combiner_irq_domain;
+static struct combiner_chip_data combiner_data[MAX_COMBINER_NR];
+
+static inline void __iomem *combiner_base(struct irq_data *data)
+{
+	struct combiner_chip_data *combiner_data =
+		irq_data_get_irq_chip_data(data);
+
+	return combiner_data->base;
+}
+
+static void combiner_mask_irq(struct irq_data *data)
+{
+	u32 mask = 1 << (data->hwirq % 32);
+
+	__raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_CLEAR);
+}
+
+static void combiner_unmask_irq(struct irq_data *data)
+{
+	u32 mask = 1 << (data->hwirq % 32);
+
+	__raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_SET);
+}
+
+static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
+{
+	struct combiner_chip_data *chip_data = irq_get_handler_data(irq);
+	struct irq_chip *chip = irq_get_chip(irq);
+	unsigned int cascade_irq, combiner_irq;
+	unsigned long status;
+
+	chained_irq_enter(chip, desc);
+
+	spin_lock(&irq_controller_lock);
+	status = __raw_readl(chip_data->base + COMBINER_INT_STATUS);
+	spin_unlock(&irq_controller_lock);
+	status &= chip_data->irq_mask;
+
+	if (status == 0)
+		goto out;
+
+	combiner_irq = __ffs(status);
+
+	cascade_irq = combiner_irq + (chip_data->irq_offset & ~31);
+	if (unlikely(cascade_irq >= NR_IRQS))
+		do_bad_IRQ(cascade_irq, desc);
+	else
+		generic_handle_irq(cascade_irq);
+
+ out:
+	chained_irq_exit(chip, desc);
+}
+
+static struct irq_chip combiner_chip = {
+	.name		= "COMBINER",
+	.irq_mask	= combiner_mask_irq,
+	.irq_unmask	= combiner_unmask_irq,
+};
+
+static void __init combiner_cascade_irq(unsigned int combiner_nr,
+						unsigned int irq)
+{
+	if (irq_set_handler_data(irq, &combiner_data[combiner_nr]) != 0)
+		BUG();
+	irq_set_chained_handler(irq, combiner_handle_cascade_irq);
+}
+
+static void __init combiner_init_one(unsigned int combiner_nr,
+				     void __iomem *base)
+{
+	combiner_data[combiner_nr].base = base;
+	combiner_data[combiner_nr].irq_offset = irq_find_mapping(
+		combiner_irq_domain, combiner_nr * MAX_IRQ_IN_COMBINER);
+	combiner_data[combiner_nr].irq_mask = 0xff << ((combiner_nr % 4) << 3);
+
+	/* Disable all interrupts */
+	__raw_writel(combiner_data[combiner_nr].irq_mask,
+		     base + COMBINER_ENABLE_CLEAR);
+}
+
+#ifdef CONFIG_OF
+static int combiner_irq_domain_xlate(struct irq_domain *d,
+				     struct device_node *controller,
+				     const u32 *intspec, unsigned int intsize,
+				     unsigned long *out_hwirq,
+				     unsigned int *out_type)
+{
+	if (d->of_node != controller)
+		return -EINVAL;
+
+	if (intsize < 2)
+		return -EINVAL;
+
+	*out_hwirq = intspec[0] * MAX_IRQ_IN_COMBINER + intspec[1];
+	*out_type = 0;
+
+	return 0;
+}
+#else
+static int combiner_irq_domain_xlate(struct irq_domain *d,
+				     struct device_node *controller,
+				     const u32 *intspec, unsigned int intsize,
+				     unsigned long *out_hwirq,
+				     unsigned int *out_type)
+{
+	return -EINVAL;
+}
+#endif
+
+static int combiner_irq_domain_map(struct irq_domain *d, unsigned int irq,
+				   irq_hw_number_t hw)
+{
+	irq_set_chip_and_handler(irq, &combiner_chip, handle_level_irq);
+	irq_set_chip_data(irq, &combiner_data[hw >> 3]);
+	set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+
+	return 0;
+}
+
+static struct irq_domain_ops combiner_irq_domain_ops = {
+	.xlate	= combiner_irq_domain_xlate,
+	.map	= combiner_irq_domain_map,
+};
+
+void __init combiner_init(void __iomem *combiner_base, unsigned int nr_combiner,
+					struct device_node *np)
+{
+	int i, irq, irq_base;
+	unsigned int nr_irq;
+
+	nr_irq = nr_combiner * MAX_IRQ_IN_COMBINER;
+
+	irq_base = irq_alloc_descs(COMBINER_IRQ(0, 0), 1, nr_irq, 0);
+	if (IS_ERR_VALUE(irq_base)) {
+		irq_base = COMBINER_IRQ(0, 0);
+		pr_warn("%s: irq desc alloc failed. Continuing with %d as "
+				"linux irq base\n", __func__, irq_base);
+	}
+
+	combiner_irq_domain = irq_domain_add_legacy(np, nr_irq, irq_base, 0,
+				&combiner_irq_domain_ops, &combiner_data);
+	if (WARN_ON(!combiner_irq_domain)) {
+		pr_warn("%s: irq domain init failed\n", __func__);
+		return;
+	}
+
+	for (i = 0; i < nr_combiner; i++) {
+		combiner_init_one(i, combiner_base + (i >> 2) * 0x10);
+		irq = IRQ_SPI(i);
+#ifdef CONFIG_OF
+		if (np)
+			irq = irq_of_parse_and_map(np, i);
+#endif
+		combiner_cascade_irq(i, irq);
+	}
+}
+
+#ifdef CONFIG_OF
+int __init combiner_of_init(struct device_node *np, struct device_node *parent)
+{
+	void __iomem *combiner_base;
+	unsigned int nr_combiner;
+
+	combiner_base = of_iomap(np, 0);
+	if (!combiner_base) {
+		pr_err("%s: failed to map combiner registers\n", __func__);
+		return -ENXIO;
+	}
+
+	if (of_property_read_u32(np, "samsung,combiner-nr", &nr_combiner)) {
+			pr_warn("%s: number of combiners not specified, "
+			"setting default as %d.\n",
+			__func__, EXYNOS4_MAX_COMBINER_NR);
+		nr_combiner = EXYNOS4_MAX_COMBINER_NR;
+	}
+
+	combiner_init(combiner_base, nr_combiner, np);
+	return 0;
+}
+#endif
diff --git a/include/linux/irqchip/exynos-combiner.h b/include/linux/irqchip/exynos-combiner.h
new file mode 100644
index 0000000..faa781c
--- /dev/null
+++ b/include/linux/irqchip/exynos-combiner.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_IRQCHIP_EXYNOS_COMBINER_H_
+#define __LINUX_IRQCHIP_EXYNOS_COMBINER_H_
+
+extern void __init combiner_init(void __iomem *combiner_base,
+			unsigned int nr_combiner, struct device_node *np);
+extern int __init combiner_of_init(struct device_node *np,
+			struct device_node *parent);
+
+#endif /* __LINUX_IRQCHIP_EXYNOS_COMBINER_H_ */
-- 
1.6.6.rc2

^ permalink raw reply related

* [PATCH 1/2] arm: bcm2835: move to the multiplatform support
From: Thomas Petazzoni @ 2012-10-30  8:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <508F3BFF.6010305@wwwdotorg.org>

Stephen,

Thanks for taking the time to look at this patch.

On Mon, 29 Oct 2012 20:31:27 -0600, Stephen Warren wrote:

> Since CONFIG_VFP is enabled in bcm2835_defconfig (or in general, could
> be enabled in anyone's .config), I guess that means I can't apply the
> patch yet, because the VFP fix you mention above doesn't seem to have
> been applied anywhere, so applying it would cause bcm2835_defconfig to
> be unbootable. To apply this, I'd need to merge in a branch containing
> the VFP fix first.

I'm pretty sure the VFP fix will land somewhere at some point, we can
wait this moment to merge this multiplatform bcm2835 support patch.

> What branch is this patch series based on? Neither "git am" not "git am
> -3" will apply the series; apparently my repo doesn't have the blobs to
> perform the 3-way merge -3 invokes even though I have a remote for
> linux-next which should pick up most blob sources.

This is my fault, sorry. I based this patch on a branch that contains
the VFP fix + the irqchip changes I've been proposing. I can resend a
new version based on 3.7-rc3, or arm-soc/for-next, at your preference.

> A couple minor comments on the code itself:
> 
> > diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
> 
> > +	config DEBUG_BCM2835_UART
> > +		bool "Kernel low-level debugging messages via BCM2835 UART"
> > +		depends on ARCH_BCM2835
> > +		help
> > +		  Say Y here if you want kernel low-level debugging support
> > +		  on BCM2835 based platforms.
> > +
> 
> Since the SoC has multiple UARTs, does it make sense to rename that
> something like DEBUG_BM2835_PL011_UART?

Agreed.

> > diff --git a/arch/arm/mach-bcm2835/include/mach/debug-macro.S b/arch/arm/include/debug/bcm2835.S
> 
> > -#include <mach/bcm2835_soc.h>
> > +#define BCM2835_DEBUG_PHYS	0x20201000
> > +#define BCM2835_DEBUG_VIRT	0xf0201000
> 
> Especially since I have to wait to apply this anyway, I'd prefer to
> avoid that part of this patch, by calling debug_ll_io_init() from
> bcm2835_map_io(). That patch unfortunately also isn't checked in yet,
> but I'll try to chase it down.

Ok, fine with that. I can respin this multiplatform patch once VFP and
debug_ll_io_init() are available.

Thanks,

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

^ permalink raw reply

* [GIT PULL] Renesas ARM-based SoC defconfig for v3.8
From: Simon Horman @ 2012-10-30  7:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.02.1210221041450.16518@xanadu.home>

On Mon, Oct 22, 2012 at 02:20:31PM -0400, Nicolas Pitre wrote:
> On Mon, 22 Oct 2012, Arnd Bergmann wrote:
> 
> > (adding Nico, who did a lot of the work to get rid of PLAT_PHYS_OFFSET)
> > 
> > On Monday 22 October 2012, Simon Horman wrote:
> > > On Mon, Oct 22, 2012 at 09:33:51AM +0900, Simon Horman wrote:
> > > > On Fri, Oct 19, 2012 at 08:18:50AM +0000, Arnd Bergmann wrote:
> > > > > On Friday 19 October 2012, Simon Horman wrote:
> > > > > > * A more significant problem seems to be the use of CONFIG_MEMORY_START
> > > > > >   to define PLAT_PHYS_OFFSET in arch/arm/mach-shmobile/include/mach/memory.h
> > > > > > 
> > > > > >   I'm not sure that I see an easy way to get around this one.
> > > > > 
> > > > > ARM_PATCH_PHYS_VIRT should take care of this, have you tried it?
> > > 
> > > I believe that this leaves mach-shmobile with three areas
> > > where CONFIG_MEMORY_START/PLAT_PHYS_OFFSET is used.
> > 
> > Hmm, I just noticed that in fact shmobile is the only remaining
> > platform that uses CONFIG_MEMORY_START with a per-board or per-soc
> > setting.
> > 
> > > * arch/arm/mach-shmobile/headsmp.S
> > > 
> > >   This uses PLAT_PHYS_OFFSET.
> > > 
> > >   I believe this can be replaced with a run-time calculation. Though I
> > >   haven't thought about the details yet.
> 
> What about this (untested):

Thanks. I have not managed to successfully test this yet,
but I think something like this is the right direction.
I will try and massage it into a working version.

> 
> diff --git a/arch/arm/mach-shmobile/headsmp.S b/arch/arm/mach-shmobile/headsmp.S
> index b202c12725..9293319fcb 100644
> --- a/arch/arm/mach-shmobile/headsmp.S
> +++ b/arch/arm/mach-shmobile/headsmp.S
> @@ -64,18 +64,23 @@ ENTRY(v7_invalidate_l1)
>  	mov	pc, lr
>  ENDPROC(v7_invalidate_l1)
>  
> -ENTRY(shmobile_invalidate_start)
> +ENTRY(shmobile_secondary_entry)
>  	bl	v7_invalidate_l1
>  	b	secondary_startup
> -ENDPROC(shmobile_invalidate_start)
> +ENDPROC(shmobile_secondary_entry)
>  
>  /*
>   * Reset vector for secondary CPUs.
>   * This will be mapped at address 0 by SBAR register.
>   * We need _long_ jump to the physical address.
> + * the loaded address is initialized to the physical address of
> + * shmobile_secondary_entry
> + * in platform_secondary_init().
>   */
> +	.data
>  	.align  12
> +	.arm
>  ENTRY(shmobile_secondary_vector)
>  	ldr     pc, 1f
> -1:	.long   shmobile_invalidate_start - PAGE_OFFSET + PLAT_PHYS_OFFSET
> +1:	.long   0
>  ENDPROC(shmobile_secondary_vector)
> diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c
> index fde0d23121..356f82da16 100644
> --- a/arch/arm/mach-shmobile/platsmp.c
> +++ b/arch/arm/mach-shmobile/platsmp.c
> @@ -76,8 +76,14 @@ int shmobile_platform_cpu_kill(unsigned int cpu)
>  
>  void __cpuinit platform_secondary_init(unsigned int cpu)
>  {
> +	long shmobile_secondary_address;
> +
>  	trace_hardirqs_off();
>  
> +	shmobile_secondary_address = (long *)(shmobile_secondary_vector) + 1;
> +	*shmobile_secondary_address = virt_to_phys(shmobile_secondary_entry);
> +	__cpuc_flush_dcache_area(shmobile_secondary_address, sizeof(long));
> +
>  	if (is_sh73a0())
>  		sh73a0_secondary_init(cpu);
>  
> 
> > > * arch/arm/boot/compressed/head-shmobile.S
> > > 
> > >   This makes use of CONFIG_MEMORY_START.
> > >   This is only used if CONFIG_ZBOOT_ROM is set.
> > > 
> > >   I'm unsure if this can be replaced with a run-time calculation or not.
> > >   But regardless it is only used if CONFIG_ZBOOT_ROM is set, which is not
> > >   the default at this time.
> 
> This code is meant to be executed from ROM which means a very tailored 
> kernel configuration.  In that case it makes little sense to have 
> CONFIG_ARM_PATCH_PHYS_VIRT nor CONFIG_AUTO_ZRELADDR turned on anyway.

Agreed.

> > Right, you can probably make CONFIG_ZBOOT_ROM_MMCIF and
> > CONFIG_ZBOOT_ROM_SH_MOBILE_SDHI depend on !ARM_PATCH_PHYS_VIRT
> 
> The right dependency would be CONFIG_AUTO_ZRELADDR, not 
> ARM_PATCH_PHYS_VIRT.  The later concerns the final kernel image, not the 
> decompressor.

Thanks.

> > > * arch/arm/mach-shmobile/Makefile.boot
> > > 
> > >  This makes use of CONFIG_MEMORY_START to set zreladdr.
> > > 
> > >  I believe that the solution to this is to make use of CONFIG_AUTO_ZRELADDR.
> > >  However, it is not yet clear to me how that can be used in conjunction
> > >  with a uImage.  As I understand it the boot loader on many of our boards,
> > >  including the Marzen board which is my first target for this work, boot
> > >  uImage imagess.
> > 
> > If this doesn't work, we probably also need to find a solution to
> > build multiple uImage files from the same vmlinux when building a
> > multiplatform kernel.
> 
> The right solution to the U-Boot problem is to remove uImage creation 
> from the kernel entirely.  The U-Boot image format should be created at 
> _installation_ time, not at build time.  The fact that the U-Boot image 
> format is (or was until very recently) inflexible is not Linux's fault.
> 
> If the uImage build target is to remain in the kernel, it should be 
> marked incompatible with a multi-arch config.  There is no point 
> distributing a multi-arch kernel image when wrapped into a uImage 
> format.

I agree with you reasoning, and that in the long term removing uImage as a
target and having an install-time mechanism would be a nice goal. However,
I wonder what the way forward is. Provide install-scripts in the kernel
tree somewhere? Provide information on the start address under
Documentation/ somewhere?

While I am more than happy to help address the issues raised in this
thread, and others that arise. There do seem to be a number of issues
between where we are now and a more generic shmobile_defconfig. I would
like consideration given to allowing the exixting, working, well-maintained,
per-board defconfigs to be updated until these issues have been resolved.

^ permalink raw reply

* [PATCH v3 2/2] [media]: mx2_camera: Fix regression caused by clock conversion
From: Guennadi Liakhovetski @ 2012-10-30  7:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1349791352-9829-1-git-send-email-fabio.estevam@freescale.com>

Hi Fabio

Sorry for a late review, but

On Tue, 9 Oct 2012, Fabio Estevam wrote:

> Since mx27 transitioned to the commmon clock framework in 3.5, the correct way
> to acquire the csi clock is to get csi_ahb and csi_per clocks separately.
> 
> By not doing so the camera sensor does not probe correctly:
> 
> soc-camera-pdrv soc-camera-pdrv.0: Probing soc-camera-pdrv.0
> mx2-camera mx2-camera.0: Camera driver attached to camera 0
> ov2640 0-0030: Product ID error fb:fb
> mx2-camera mx2-camera.0: Camera driver detached from camera 0
> mx2-camera mx2-camera.0: MX2 Camera (CSI) driver probed, clock frequency: 66500000
> 
> Adapt the mx2_camera driver to the new clock framework and make it functional
> again.
> 
> Tested-by: Ga?tan Carlier <gcembed@gmail.com>
> Tested-by: Javier Martin <javier.martin@vista-silicon.com>
> Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
> ---
> Changes since v2:
> - Fix clock error handling code as pointed out by Russell King
> Changes since v1:
> - Rebased against linux-next 20121008.
>  drivers/media/platform/soc_camera/mx2_camera.c |   50 ++++++++++++++++++------
>  1 file changed, 38 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/media/platform/soc_camera/mx2_camera.c b/drivers/media/platform/soc_camera/mx2_camera.c
> index 403d7f1..382b305 100644
> --- a/drivers/media/platform/soc_camera/mx2_camera.c
> +++ b/drivers/media/platform/soc_camera/mx2_camera.c
> @@ -272,7 +272,8 @@ struct mx2_camera_dev {
>  	struct device		*dev;
>  	struct soc_camera_host	soc_host;
>  	struct soc_camera_device *icd;
> -	struct clk		*clk_csi, *clk_emma_ahb, *clk_emma_ipg;
> +	struct clk		*clk_emma_ahb, *clk_emma_ipg;
> +	struct clk		*clk_csi_ahb, *clk_csi_per;
>  
>  	void __iomem		*base_csi, *base_emma;
>  
> @@ -432,7 +433,8 @@ static void mx2_camera_deactivate(struct mx2_camera_dev *pcdev)
>  {
>  	unsigned long flags;
>  
> -	clk_disable_unprepare(pcdev->clk_csi);
> +	clk_disable_unprepare(pcdev->clk_csi_ahb);
> +	clk_disable_unprepare(pcdev->clk_csi_per);
>  	writel(0, pcdev->base_csi + CSICR1);
>  	if (cpu_is_mx27()) {
>  		writel(0, pcdev->base_emma + PRP_CNTL);
> @@ -460,10 +462,14 @@ static int mx2_camera_add_device(struct soc_camera_device *icd)
>  	if (pcdev->icd)
>  		return -EBUSY;
>  
> -	ret = clk_prepare_enable(pcdev->clk_csi);
> +	ret = clk_prepare_enable(pcdev->clk_csi_ahb);
>  	if (ret < 0)
>  		return ret;
>  
> +	ret = clk_prepare_enable(pcdev->clk_csi_per);
> +	if (ret < 0)
> +		goto exit_csi_ahb;
> +
>  	csicr1 = CSICR1_MCLKEN;
>  
>  	if (cpu_is_mx27())
> @@ -480,6 +486,11 @@ static int mx2_camera_add_device(struct soc_camera_device *icd)
>  		 icd->devnum);
>  
>  	return 0;
> +
> +exit_csi_ahb:
> +	clk_disable_unprepare(pcdev->clk_csi_ahb);
> +
> +	return ret;
>  }
>  
>  static void mx2_camera_remove_device(struct soc_camera_device *icd)
> @@ -1725,27 +1736,35 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
>  		goto exit;
>  	}
>  
> -	pcdev->clk_csi = devm_clk_get(&pdev->dev, "ahb");
> -	if (IS_ERR(pcdev->clk_csi)) {
> -		dev_err(&pdev->dev, "Could not get csi clock\n");
> -		err = PTR_ERR(pcdev->clk_csi);
> +	pcdev->clk_csi_ahb = devm_clk_get(&pdev->dev, "ahb");
> +	if (IS_ERR(pcdev->clk_csi_ahb)) {
> +		dev_err(&pdev->dev, "Could not get csi ahb clock\n");
> +		err = PTR_ERR(pcdev->clk_csi_ahb);
>  		goto exit;
>  	}
>  
> +	pcdev->clk_csi_per = devm_clk_get(&pdev->dev, "per");
> +	if (IS_ERR(pcdev->clk_csi_per)) {
> +		dev_err(&pdev->dev, "Could not get csi per clock\n");
> +		err = PTR_ERR(pcdev->clk_csi_per);
> +		goto exit_csi_ahb;
> +	}
> +
>  	pcdev->pdata = pdev->dev.platform_data;
>  	if (pcdev->pdata) {
>  		long rate;
>  
>  		pcdev->platform_flags = pcdev->pdata->flags;
>  
> -		rate = clk_round_rate(pcdev->clk_csi, pcdev->pdata->clk * 2);
> +		rate = clk_round_rate(pcdev->clk_csi_per,
> +						pcdev->pdata->clk * 2);
>  		if (rate <= 0) {
>  			err = -ENODEV;
> -			goto exit;
> +			goto exit_csi_per;
>  		}
> -		err = clk_set_rate(pcdev->clk_csi, rate);
> +		err = clk_set_rate(pcdev->clk_csi_per, rate);
>  		if (err < 0)
> -			goto exit;
> +			goto exit_csi_per;
>  	}
>  
>  	INIT_LIST_HEAD(&pcdev->capture);
> @@ -1801,7 +1820,7 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
>  		goto exit_free_emma;
>  
>  	dev_info(&pdev->dev, "MX2 Camera (CSI) driver probed, clock frequency: %ld\n",
> -			clk_get_rate(pcdev->clk_csi));
> +			clk_get_rate(pcdev->clk_csi_per));
>  
>  	return 0;
>  
> @@ -1812,6 +1831,10 @@ eallocctx:
>  		clk_disable_unprepare(pcdev->clk_emma_ipg);
>  		clk_disable_unprepare(pcdev->clk_emma_ahb);
>  	}
> +exit_csi_per:
> +	clk_disable_unprepare(pcdev->clk_csi_per);
> +exit_csi_ahb:
> +	clk_disable_unprepare(pcdev->clk_csi_ahb);

I don't understand why you need the above two clk_disable_unprepare() - 
you don't seem to clk_enable_prepare() your csi clocks here. Similarly

>  exit:
>  	return err;
>  }
> @@ -1831,6 +1854,9 @@ static int __devexit mx2_camera_remove(struct platform_device *pdev)
>  		clk_disable_unprepare(pcdev->clk_emma_ahb);
>  	}
>  
> +	clk_disable_unprepare(pcdev->clk_csi_per);
> +	clk_disable_unprepare(pcdev->clk_csi_ahb);
> +

I don't think the above two are needed

>  	dev_info(&pdev->dev, "MX2 Camera driver unloaded\n");
>  
>  	return 0;
> -- 
> 1.7.9.5

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ 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