netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCHv3 0/3] Add support for velocity network driver on platform devices
@ 2013-04-29 19:46 Tony Prisk
  2013-04-29 19:46 ` [PATCHv3 1/3] net: velocity: Rename vptr->dev to vptr->netdev Tony Prisk
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Tony Prisk @ 2013-04-29 19:46 UTC (permalink / raw)
  To: Francois Romieu
  Cc: vt8500-wm8505-linux-kernel, linux-arm-kernel, linux-kernel,
	davem, netdev, Tony Prisk

v3 changes:
Rebased against net-next.
Fix errors in pm code.

v2 changes:
Drop patch #1 as requested by David Miller.
Correct the PHYID_ICPLUS_IP101A MII bits - should be ON, rather than OFF.
Read the platform rev_id from the correct register [regs->rev_id]. It's possible
this would work for the PCI version as well and would remove the need for the
'if (pci)' test to set vptr->rev_id.

v1:
The first three patches are general tidyup.

[DROPPED] Patch ## just alphabetizes the #includes to make it easier to read.

Patch #1 replaces vptr->dev with vptr->netdev, in preparation of adding a
struct device *dev in Patch #3

Patch #2 replaces the pci dma functions with the generic versions.

I have build tested these patches but don't have a PCI velocity to run-test it.
I can't see that they should introduce any problems as it is all renames and
function swapping.

Patch #3 adds support for the velocity driver on devicetree platform devices.
Binding document included. This patch is compile-tested for PCI, and boot
tested on a VIA APC8750.

I think it would be pertinent to get some tested-by's for PCI users.

Regards
Tony Prisk

Tony Prisk (3):
  net: velocity: Rename vptr->dev to vptr->netdev
  net: velocity: Convert to generic dma functions
  net: velocity: Add platform device support to VIA velocity driver

 .../devicetree/bindings/net/via-velocity.txt       |   20 +
 drivers/net/ethernet/via/Kconfig                   |    3 +-
 drivers/net/ethernet/via/via-velocity.c            |  563 ++++++++++++++------
 drivers/net/ethernet/via/via-velocity.h            |   35 +-
 4 files changed, 454 insertions(+), 167 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/via-velocity.txt

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCHv3 1/3] net: velocity: Rename vptr->dev to vptr->netdev
  2013-04-29 19:46 [PATCHv3 0/3] Add support for velocity network driver on platform devices Tony Prisk
@ 2013-04-29 19:46 ` Tony Prisk
  2013-04-29 19:46 ` [PATCHv3 2/3] net: velocity: Convert to generic dma functions Tony Prisk
  2013-04-29 19:46 ` [PATCHv3 3/3] net: velocity: Add platform device support to VIA velocity driver Tony Prisk
  2 siblings, 0 replies; 6+ messages in thread
From: Tony Prisk @ 2013-04-29 19:46 UTC (permalink / raw)
  To: Francois Romieu
  Cc: vt8500-wm8505-linux-kernel, linux-arm-kernel, linux-kernel,
	davem, netdev, Tony Prisk

Improve the clarity of the code in preparation for converting the
dma functions to generic versions, which require a struct device *.

This makes it possible to store a 'struct device *dev' in the
velocity_info structure.

Signed-off-by: Tony Prisk <linux@prisktech.co.nz>
---
 drivers/net/ethernet/via/via-velocity.c |   66 +++++++++++++++----------------
 drivers/net/ethernet/via/via-velocity.h |    4 +-
 2 files changed, 35 insertions(+), 35 deletions(-)

diff --git a/drivers/net/ethernet/via/via-velocity.c b/drivers/net/ethernet/via/via-velocity.c
index fb62489..187eef3 100644
--- a/drivers/net/ethernet/via/via-velocity.c
+++ b/drivers/net/ethernet/via/via-velocity.c
@@ -998,9 +998,9 @@ static void velocity_print_link_status(struct velocity_info *vptr)
 {
 
 	if (vptr->mii_status & VELOCITY_LINK_FAIL) {
-		VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: failed to detect cable link\n", vptr->dev->name);
+		VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: failed to detect cable link\n", vptr->netdev->name);
 	} else if (vptr->options.spd_dpx == SPD_DPX_AUTO) {
-		VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link auto-negotiation", vptr->dev->name);
+		VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link auto-negotiation", vptr->netdev->name);
 
 		if (vptr->mii_status & VELOCITY_SPEED_1000)
 			VELOCITY_PRT(MSG_LEVEL_INFO, " speed 1000M bps");
@@ -1014,7 +1014,7 @@ static void velocity_print_link_status(struct velocity_info *vptr)
 		else
 			VELOCITY_PRT(MSG_LEVEL_INFO, " half duplex\n");
 	} else {
-		VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link forced", vptr->dev->name);
+		VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link forced", vptr->netdev->name);
 		switch (vptr->options.spd_dpx) {
 		case SPD_DPX_1000_FULL:
 			VELOCITY_PRT(MSG_LEVEL_INFO, " speed 1000M bps full duplex\n");
@@ -1319,7 +1319,7 @@ static void velocity_init_registers(struct velocity_info *vptr,
 	case VELOCITY_INIT_RESET:
 	case VELOCITY_INIT_WOL:
 
-		netif_stop_queue(vptr->dev);
+		netif_stop_queue(vptr->netdev);
 
 		/*
 		 *	Reset RX to prevent RX pointer not on the 4X location
@@ -1332,7 +1332,7 @@ static void velocity_init_registers(struct velocity_info *vptr,
 		if (velocity_set_media_mode(vptr, mii_status) != VELOCITY_LINK_CHANGE) {
 			velocity_print_link_status(vptr);
 			if (!(vptr->mii_status & VELOCITY_LINK_FAIL))
-				netif_wake_queue(vptr->dev);
+				netif_wake_queue(vptr->netdev);
 		}
 
 		enable_flow_control_ability(vptr);
@@ -1354,7 +1354,7 @@ static void velocity_init_registers(struct velocity_info *vptr,
 
 		mac_eeprom_reload(regs);
 		for (i = 0; i < 6; i++)
-			writeb(vptr->dev->dev_addr[i], &(regs->PAR[i]));
+			writeb(vptr->netdev->dev_addr[i], &(regs->PAR[i]));
 
 		/*
 		 *	clear Pre_ACPI bit.
@@ -1377,7 +1377,7 @@ static void velocity_init_registers(struct velocity_info *vptr,
 		/*
 		 *	Set packet filter: Receive directed and broadcast address
 		 */
-		velocity_set_multi(vptr->dev);
+		velocity_set_multi(vptr->netdev);
 
 		/*
 		 *	Enable MII auto-polling
@@ -1404,14 +1404,14 @@ static void velocity_init_registers(struct velocity_info *vptr,
 		writel((CR0_DPOLL | CR0_TXON | CR0_RXON | CR0_STRT), &regs->CR0Set);
 
 		mii_status = velocity_get_opt_media_mode(vptr);
-		netif_stop_queue(vptr->dev);
+		netif_stop_queue(vptr->netdev);
 
 		mii_init(vptr, mii_status);
 
 		if (velocity_set_media_mode(vptr, mii_status) != VELOCITY_LINK_CHANGE) {
 			velocity_print_link_status(vptr);
 			if (!(vptr->mii_status & VELOCITY_LINK_FAIL))
-				netif_wake_queue(vptr->dev);
+				netif_wake_queue(vptr->netdev);
 		}
 
 		enable_flow_control_ability(vptr);
@@ -1474,7 +1474,7 @@ static int velocity_init_dma_rings(struct velocity_info *vptr)
 				    rx_ring_size, &pool_dma);
 	if (!pool) {
 		dev_err(&pdev->dev, "%s : DMA memory allocation failed.\n",
-			vptr->dev->name);
+			vptr->netdev->name);
 		return -ENOMEM;
 	}
 
@@ -1514,7 +1514,7 @@ static int velocity_alloc_rx_buf(struct velocity_info *vptr, int idx)
 	struct rx_desc *rd = &(vptr->rx.ring[idx]);
 	struct velocity_rd_info *rd_info = &(vptr->rx.info[idx]);
 
-	rd_info->skb = netdev_alloc_skb(vptr->dev, vptr->rx.buf_sz + 64);
+	rd_info->skb = netdev_alloc_skb(vptr->netdev, vptr->rx.buf_sz + 64);
 	if (rd_info->skb == NULL)
 		return -ENOMEM;
 
@@ -1620,7 +1620,7 @@ static int velocity_init_rd_ring(struct velocity_info *vptr)
 
 	if (velocity_rx_refill(vptr) != vptr->options.numrx) {
 		VELOCITY_PRT(MSG_LEVEL_ERR, KERN_ERR
-			"%s: failed to allocate RX buffer.\n", vptr->dev->name);
+			"%s: failed to allocate RX buffer.\n", vptr->netdev->name);
 		velocity_free_rd_ring(vptr);
 		goto out;
 	}
@@ -1809,7 +1809,7 @@ static void velocity_error(struct velocity_info *vptr, int status)
 		printk(KERN_ERR "TD structure error TDindex=%hx\n", readw(&regs->TDIdx[0]));
 		BYTE_REG_BITS_ON(TXESR_TDSTR, &regs->TXESR);
 		writew(TRDCSR_RUN, &regs->TDCSRClr);
-		netif_stop_queue(vptr->dev);
+		netif_stop_queue(vptr->netdev);
 
 		/* FIXME: port over the pci_device_failed code and use it
 		   here */
@@ -1850,10 +1850,10 @@ static void velocity_error(struct velocity_info *vptr, int status)
 
 		if (linked) {
 			vptr->mii_status &= ~VELOCITY_LINK_FAIL;
-			netif_carrier_on(vptr->dev);
+			netif_carrier_on(vptr->netdev);
 		} else {
 			vptr->mii_status |= VELOCITY_LINK_FAIL;
-			netif_carrier_off(vptr->dev);
+			netif_carrier_off(vptr->netdev);
 		}
 
 		velocity_print_link_status(vptr);
@@ -1867,9 +1867,9 @@ static void velocity_error(struct velocity_info *vptr, int status)
 		enable_mii_autopoll(regs);
 
 		if (vptr->mii_status & VELOCITY_LINK_FAIL)
-			netif_stop_queue(vptr->dev);
+			netif_stop_queue(vptr->netdev);
 		else
-			netif_wake_queue(vptr->dev);
+			netif_wake_queue(vptr->netdev);
 
 	}
 	if (status & ISR_MIBFI)
@@ -1894,7 +1894,7 @@ static int velocity_tx_srv(struct velocity_info *vptr)
 	int idx;
 	int works = 0;
 	struct velocity_td_info *tdinfo;
-	struct net_device_stats *stats = &vptr->dev->stats;
+	struct net_device_stats *stats = &vptr->netdev->stats;
 
 	for (qnum = 0; qnum < vptr->tx.numq; qnum++) {
 		for (idx = vptr->tx.tail[qnum]; vptr->tx.used[qnum] > 0;
@@ -1939,9 +1939,9 @@ static int velocity_tx_srv(struct velocity_info *vptr)
 	 *	Look to see if we should kick the transmit network
 	 *	layer for more work.
 	 */
-	if (netif_queue_stopped(vptr->dev) && (full == 0) &&
+	if (netif_queue_stopped(vptr->netdev) && (full == 0) &&
 	    (!(vptr->mii_status & VELOCITY_LINK_FAIL))) {
-		netif_wake_queue(vptr->dev);
+		netif_wake_queue(vptr->netdev);
 	}
 	return works;
 }
@@ -1989,7 +1989,7 @@ static int velocity_rx_copy(struct sk_buff **rx_skb, int pkt_size,
 	if (pkt_size < rx_copybreak) {
 		struct sk_buff *new_skb;
 
-		new_skb = netdev_alloc_skb_ip_align(vptr->dev, pkt_size);
+		new_skb = netdev_alloc_skb_ip_align(vptr->netdev, pkt_size);
 		if (new_skb) {
 			new_skb->ip_summed = rx_skb[0]->ip_summed;
 			skb_copy_from_linear_data(*rx_skb, new_skb->data, pkt_size);
@@ -2030,14 +2030,14 @@ static inline void velocity_iph_realign(struct velocity_info *vptr,
 static int velocity_receive_frame(struct velocity_info *vptr, int idx)
 {
 	void (*pci_action)(struct pci_dev *, dma_addr_t, size_t, int);
-	struct net_device_stats *stats = &vptr->dev->stats;
+	struct net_device_stats *stats = &vptr->netdev->stats;
 	struct velocity_rd_info *rd_info = &(vptr->rx.info[idx]);
 	struct rx_desc *rd = &(vptr->rx.ring[idx]);
 	int pkt_len = le16_to_cpu(rd->rdesc0.len) & 0x3fff;
 	struct sk_buff *skb;
 
 	if (rd->rdesc0.RSR & (RSR_STP | RSR_EDP)) {
-		VELOCITY_PRT(MSG_LEVEL_VERBOSE, KERN_ERR " %s : the received frame span multple RDs.\n", vptr->dev->name);
+		VELOCITY_PRT(MSG_LEVEL_VERBOSE, KERN_ERR " %s : the received frame span multple RDs.\n", vptr->netdev->name);
 		stats->rx_length_errors++;
 		return -EINVAL;
 	}
@@ -2075,7 +2075,7 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx)
 		   PCI_DMA_FROMDEVICE);
 
 	skb_put(skb, pkt_len - 4);
-	skb->protocol = eth_type_trans(skb, vptr->dev);
+	skb->protocol = eth_type_trans(skb, vptr->netdev);
 
 	if (rd->rdesc0.RSR & RSR_DETAG) {
 		u16 vid = swab16(le16_to_cpu(rd->rdesc1.PQTAG));
@@ -2100,7 +2100,7 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx)
  */
 static int velocity_rx_srv(struct velocity_info *vptr, int budget_left)
 {
-	struct net_device_stats *stats = &vptr->dev->stats;
+	struct net_device_stats *stats = &vptr->netdev->stats;
 	int rd_curr = vptr->rx.curr;
 	int works = 0;
 
@@ -2292,7 +2292,7 @@ static int velocity_change_mtu(struct net_device *dev, int new_mtu)
 
 	if ((new_mtu < VELOCITY_MIN_MTU) || new_mtu > (VELOCITY_MAX_MTU)) {
 		VELOCITY_PRT(MSG_LEVEL_ERR, KERN_NOTICE "%s: Invalid MTU.\n",
-				vptr->dev->name);
+				vptr->netdev->name);
 		ret = -EINVAL;
 		goto out_0;
 	}
@@ -2314,7 +2314,7 @@ static int velocity_change_mtu(struct net_device *dev, int new_mtu)
 			goto out_0;
 		}
 
-		tmp_vptr->dev = dev;
+		tmp_vptr->netdev = dev;
 		tmp_vptr->pdev = vptr->pdev;
 		tmp_vptr->options = vptr->options;
 		tmp_vptr->tx.numq = vptr->tx.numq;
@@ -2692,7 +2692,7 @@ static int velocity_get_pci_info(struct velocity_info *vptr,
  */
 static void velocity_print_info(struct velocity_info *vptr)
 {
-	struct net_device *dev = vptr->dev;
+	struct net_device *dev = vptr->netdev;
 
 	printk(KERN_INFO "%s: %s\n", dev->name, get_chip_name(vptr->chip_id));
 	printk(KERN_INFO "%s: Ethernet Address: %pM\n",
@@ -2755,7 +2755,7 @@ static int velocity_found1(struct pci_dev *pdev,
 
 	velocity_init_info(pdev, vptr, info);
 
-	vptr->dev = dev;
+	vptr->netdev = dev;
 
 	ret = pci_enable_device(pdev);
 	if (ret < 0)
@@ -3010,10 +3010,10 @@ static int velocity_suspend(struct pci_dev *pdev, pm_message_t state)
 	struct velocity_info *vptr = netdev_priv(dev);
 	unsigned long flags;
 
-	if (!netif_running(vptr->dev))
+	if (!netif_running(vptr->netdev))
 		return 0;
 
-	netif_device_detach(vptr->dev);
+	netif_device_detach(vptr->netdev);
 
 	spin_lock_irqsave(&vptr->lock, flags);
 	pci_save_state(pdev);
@@ -3078,7 +3078,7 @@ static int velocity_resume(struct pci_dev *pdev)
 	unsigned long flags;
 	int i;
 
-	if (!netif_running(vptr->dev))
+	if (!netif_running(vptr->netdev))
 		return 0;
 
 	pci_set_power_state(pdev, PCI_D0);
@@ -3101,7 +3101,7 @@ static int velocity_resume(struct pci_dev *pdev)
 
 	mac_enable_int(vptr->mac_regs);
 	spin_unlock_irqrestore(&vptr->lock, flags);
-	netif_device_attach(vptr->dev);
+	netif_device_attach(vptr->netdev);
 
 	return 0;
 }
diff --git a/drivers/net/ethernet/via/via-velocity.h b/drivers/net/ethernet/via/via-velocity.h
index 4cb9f13..ff8d7828 100644
--- a/drivers/net/ethernet/via/via-velocity.h
+++ b/drivers/net/ethernet/via/via-velocity.h
@@ -1435,7 +1435,7 @@ struct velocity_opt {
 
 struct velocity_info {
 	struct pci_dev *pdev;
-	struct net_device *dev;
+	struct net_device *netdev;
 
 	unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
 	u8 ip_addr[4];
@@ -1514,7 +1514,7 @@ static inline int velocity_get_ip(struct velocity_info *vptr)
 	int res = -ENOENT;
 
 	rcu_read_lock();
-	in_dev = __in_dev_get_rcu(vptr->dev);
+	in_dev = __in_dev_get_rcu(vptr->netdev);
 	if (in_dev != NULL) {
 		ifa = (struct in_ifaddr *) in_dev->ifa_list;
 		if (ifa != NULL) {
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCHv3 2/3] net: velocity: Convert to generic dma functions
  2013-04-29 19:46 [PATCHv3 0/3] Add support for velocity network driver on platform devices Tony Prisk
  2013-04-29 19:46 ` [PATCHv3 1/3] net: velocity: Rename vptr->dev to vptr->netdev Tony Prisk
@ 2013-04-29 19:46 ` Tony Prisk
  2013-04-29 19:46 ` [PATCHv3 3/3] net: velocity: Add platform device support to VIA velocity driver Tony Prisk
  2 siblings, 0 replies; 6+ messages in thread
From: Tony Prisk @ 2013-04-29 19:46 UTC (permalink / raw)
  To: Francois Romieu
  Cc: vt8500-wm8505-linux-kernel, linux-arm-kernel, linux-kernel,
	davem, netdev, Tony Prisk

Remove the pci_* dma functions and replace with the more generic
versions.

In preparation of adding platform support, a new struct device *dev
is added to struct velocity_info which can be used by both the pci
and platform code.

Signed-off-by: Tony Prisk <linux@prisktech.co.nz>
---
 drivers/net/ethernet/via/via-velocity.c |   51 +++++++++++++++----------------
 drivers/net/ethernet/via/via-velocity.h |    1 +
 2 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/drivers/net/ethernet/via/via-velocity.c b/drivers/net/ethernet/via/via-velocity.c
index 187eef3..5996cee 100644
--- a/drivers/net/ethernet/via/via-velocity.c
+++ b/drivers/net/ethernet/via/via-velocity.c
@@ -46,6 +46,7 @@
 #include <linux/types.h>
 #include <linux/bitops.h>
 #include <linux/init.h>
+#include <linux/dma-mapping.h>
 #include <linux/mm.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
@@ -1459,7 +1460,6 @@ static int velocity_init_dma_rings(struct velocity_info *vptr)
 	struct velocity_opt *opt = &vptr->options;
 	const unsigned int rx_ring_size = opt->numrx * sizeof(struct rx_desc);
 	const unsigned int tx_ring_size = opt->numtx * sizeof(struct tx_desc);
-	struct pci_dev *pdev = vptr->pdev;
 	dma_addr_t pool_dma;
 	void *pool;
 	unsigned int i;
@@ -1467,13 +1467,13 @@ static int velocity_init_dma_rings(struct velocity_info *vptr)
 	/*
 	 * Allocate all RD/TD rings a single pool.
 	 *
-	 * pci_alloc_consistent() fulfills the requirement for 64 bytes
+	 * dma_alloc_coherent() fulfills the requirement for 64 bytes
 	 * alignment
 	 */
-	pool = pci_alloc_consistent(pdev, tx_ring_size * vptr->tx.numq +
-				    rx_ring_size, &pool_dma);
+	pool = dma_alloc_coherent(vptr->dev, tx_ring_size * vptr->tx.numq +
+				    rx_ring_size, &pool_dma, GFP_ATOMIC);
 	if (!pool) {
-		dev_err(&pdev->dev, "%s : DMA memory allocation failed.\n",
+		dev_err(vptr->dev, "%s : DMA memory allocation failed.\n",
 			vptr->netdev->name);
 		return -ENOMEM;
 	}
@@ -1524,8 +1524,8 @@ static int velocity_alloc_rx_buf(struct velocity_info *vptr, int idx)
 	 */
 	skb_reserve(rd_info->skb,
 			64 - ((unsigned long) rd_info->skb->data & 63));
-	rd_info->skb_dma = pci_map_single(vptr->pdev, rd_info->skb->data,
-					vptr->rx.buf_sz, PCI_DMA_FROMDEVICE);
+	rd_info->skb_dma = dma_map_single(vptr->dev, rd_info->skb->data,
+					vptr->rx.buf_sz, DMA_FROM_DEVICE);
 
 	/*
 	 *	Fill in the descriptor to match
@@ -1588,8 +1588,8 @@ static void velocity_free_rd_ring(struct velocity_info *vptr)
 
 		if (!rd_info->skb)
 			continue;
-		pci_unmap_single(vptr->pdev, rd_info->skb_dma, vptr->rx.buf_sz,
-				 PCI_DMA_FROMDEVICE);
+		dma_unmap_single(vptr->dev, rd_info->skb_dma, vptr->rx.buf_sz,
+				 DMA_FROM_DEVICE);
 		rd_info->skb_dma = 0;
 
 		dev_kfree_skb(rd_info->skb);
@@ -1670,7 +1670,7 @@ static void velocity_free_dma_rings(struct velocity_info *vptr)
 	const int size = vptr->options.numrx * sizeof(struct rx_desc) +
 		vptr->options.numtx * sizeof(struct tx_desc) * vptr->tx.numq;
 
-	pci_free_consistent(vptr->pdev, size, vptr->rx.ring, vptr->rx.pool_dma);
+	dma_free_coherent(vptr->dev, size, vptr->rx.ring, vptr->rx.pool_dma);
 }
 
 static int velocity_init_rings(struct velocity_info *vptr, int mtu)
@@ -1727,8 +1727,8 @@ static void velocity_free_tx_buf(struct velocity_info *vptr,
 				pktlen = max_t(size_t, pktlen,
 						td->td_buf[i].size & ~TD_QUEUE);
 
-			pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i],
-					le16_to_cpu(pktlen), PCI_DMA_TODEVICE);
+			dma_unmap_single(vptr->dev, tdinfo->skb_dma[i],
+					le16_to_cpu(pktlen), DMA_TO_DEVICE);
 		}
 	}
 	dev_kfree_skb_irq(skb);
@@ -1750,8 +1750,8 @@ static void velocity_free_td_ring_entry(struct velocity_info *vptr,
 	if (td_info->skb) {
 		for (i = 0; i < td_info->nskb_dma; i++) {
 			if (td_info->skb_dma[i]) {
-				pci_unmap_single(vptr->pdev, td_info->skb_dma[i],
-					td_info->skb->len, PCI_DMA_TODEVICE);
+				dma_unmap_single(vptr->dev, td_info->skb_dma[i],
+					td_info->skb->len, DMA_TO_DEVICE);
 				td_info->skb_dma[i] = 0;
 			}
 		}
@@ -2029,7 +2029,6 @@ static inline void velocity_iph_realign(struct velocity_info *vptr,
  */
 static int velocity_receive_frame(struct velocity_info *vptr, int idx)
 {
-	void (*pci_action)(struct pci_dev *, dma_addr_t, size_t, int);
 	struct net_device_stats *stats = &vptr->netdev->stats;
 	struct velocity_rd_info *rd_info = &(vptr->rx.info[idx]);
 	struct rx_desc *rd = &(vptr->rx.ring[idx]);
@@ -2047,8 +2046,8 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx)
 
 	skb = rd_info->skb;
 
-	pci_dma_sync_single_for_cpu(vptr->pdev, rd_info->skb_dma,
-				    vptr->rx.buf_sz, PCI_DMA_FROMDEVICE);
+	dma_sync_single_for_cpu(vptr->dev, rd_info->skb_dma,
+				    vptr->rx.buf_sz, DMA_FROM_DEVICE);
 
 	/*
 	 *	Drop frame not meeting IEEE 802.3
@@ -2061,19 +2060,18 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx)
 		}
 	}
 
-	pci_action = pci_dma_sync_single_for_device;
-
 	velocity_rx_csum(rd, skb);
 
 	if (velocity_rx_copy(&skb, pkt_len, vptr) < 0) {
 		velocity_iph_realign(vptr, skb, pkt_len);
-		pci_action = pci_unmap_single;
 		rd_info->skb = NULL;
+		dma_unmap_single(vptr->dev, rd_info->skb_dma, vptr->rx.buf_sz,
+				 DMA_FROM_DEVICE);
+	} else {
+		dma_sync_single_for_device(vptr->dev, rd_info->skb_dma,
+					   vptr->rx.buf_sz, DMA_FROM_DEVICE);
 	}
 
-	pci_action(vptr->pdev, rd_info->skb_dma, vptr->rx.buf_sz,
-		   PCI_DMA_FROMDEVICE);
-
 	skb_put(skb, pkt_len - 4);
 	skb->protocol = eth_type_trans(skb, vptr->netdev);
 
@@ -2550,7 +2548,8 @@ static netdev_tx_t velocity_xmit(struct sk_buff *skb,
 	 *	add it to the transmit ring.
 	 */
 	tdinfo->skb = skb;
-	tdinfo->skb_dma[0] = pci_map_single(vptr->pdev, skb->data, pktlen, PCI_DMA_TODEVICE);
+	tdinfo->skb_dma[0] = dma_map_single(vptr->dev, skb->data, pktlen,
+								DMA_TO_DEVICE);
 	td_ptr->tdesc0.len = cpu_to_le16(pktlen);
 	td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
 	td_ptr->td_buf[0].pa_high = 0;
@@ -2560,7 +2559,7 @@ static netdev_tx_t velocity_xmit(struct sk_buff *skb,
 	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
 		const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
-		tdinfo->skb_dma[i + 1] = skb_frag_dma_map(&vptr->pdev->dev,
+		tdinfo->skb_dma[i + 1] = skb_frag_dma_map(vptr->dev,
 							  frag, 0,
 							  skb_frag_size(frag),
 							  DMA_TO_DEVICE);
@@ -2637,6 +2636,7 @@ static void velocity_init_info(struct pci_dev *pdev, struct velocity_info *vptr,
 {
 	memset(vptr, 0, sizeof(struct velocity_info));
 
+	vptr->dev = &pdev->dev;
 	vptr->pdev = pdev;
 	vptr->chip_id = info->chip_id;
 	vptr->tx.numq = info->txqueue;
@@ -2744,7 +2744,6 @@ static int velocity_found1(struct pci_dev *pdev,
 	SET_NETDEV_DEV(dev, &pdev->dev);
 	vptr = netdev_priv(dev);
 
-
 	if (first) {
 		printk(KERN_INFO "%s Ver. %s\n",
 			VELOCITY_FULL_DRV_NAM, VELOCITY_VERSION);
diff --git a/drivers/net/ethernet/via/via-velocity.h b/drivers/net/ethernet/via/via-velocity.h
index ff8d7828..c38bbae 100644
--- a/drivers/net/ethernet/via/via-velocity.h
+++ b/drivers/net/ethernet/via/via-velocity.h
@@ -1434,6 +1434,7 @@ struct velocity_opt {
 #define GET_RD_BY_IDX(vptr, idx)   (vptr->rd_ring[idx])
 
 struct velocity_info {
+	struct device *dev;
 	struct pci_dev *pdev;
 	struct net_device *netdev;
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCHv3 3/3] net: velocity: Add platform device support to VIA velocity driver
  2013-04-29 19:46 [PATCHv3 0/3] Add support for velocity network driver on platform devices Tony Prisk
  2013-04-29 19:46 ` [PATCHv3 1/3] net: velocity: Rename vptr->dev to vptr->netdev Tony Prisk
  2013-04-29 19:46 ` [PATCHv3 2/3] net: velocity: Convert to generic dma functions Tony Prisk
@ 2013-04-29 19:46 ` Tony Prisk
  2013-04-29 23:04   ` Francois Romieu
  2 siblings, 1 reply; 6+ messages in thread
From: Tony Prisk @ 2013-04-29 19:46 UTC (permalink / raw)
  To: Francois Romieu
  Cc: vt8500-wm8505-linux-kernel, linux-arm-kernel, linux-kernel,
	davem, netdev, Tony Prisk

Add support for the VIA Velocity network driver to be bound to a
OF created platform device.

Signed-off-by: Tony Prisk <linux@prisktech.co.nz>
---
 .../devicetree/bindings/net/via-velocity.txt       |   20 +
 drivers/net/ethernet/via/Kconfig                   |    3 +-
 drivers/net/ethernet/via/via-velocity.c            |  452 +++++++++++++++-----
 drivers/net/ethernet/via/via-velocity.h            |   30 +-
 4 files changed, 396 insertions(+), 109 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/via-velocity.txt

diff --git a/Documentation/devicetree/bindings/net/via-velocity.txt b/Documentation/devicetree/bindings/net/via-velocity.txt
new file mode 100644
index 0000000..b3db469
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/via-velocity.txt
@@ -0,0 +1,20 @@
+* VIA Velocity 10/100/1000 Network Controller
+
+Required properties:
+- compatible : Should be "via,velocity-vt6110"
+- reg : Address and length of the io space
+- interrupts : Should contain the controller interrupt line
+
+Optional properties:
+- no-eeprom : PCI network cards use an external EEPROM to store data. Embedded
+	devices quite often set this data in uboot and do not provide an eeprom.
+	Specify this option if you have no external eeprom.
+
+Examples:
+
+eth0@d8004000 {
+	compatible = "via,velocity-vt6110";
+	reg = <0xd8004000 0x400>;
+	interrupts = <10>;
+	no-eeprom;
+};
diff --git a/drivers/net/ethernet/via/Kconfig b/drivers/net/ethernet/via/Kconfig
index 68a9ba6..6a87097 100644
--- a/drivers/net/ethernet/via/Kconfig
+++ b/drivers/net/ethernet/via/Kconfig
@@ -5,7 +5,6 @@
 config NET_VENDOR_VIA
 	bool "VIA devices"
 	default y
-	depends on PCI
 	---help---
 	  If you have a network (Ethernet) card belonging to this class, say Y
 	  and read the Ethernet-HOWTO, available from
@@ -45,7 +44,7 @@ config VIA_RHINE_MMIO
 
 config VIA_VELOCITY
 	tristate "VIA Velocity support"
-	depends on PCI
+	depends on (PCI || USE_OF)
 	select CRC32
 	select CRC_CCITT
 	select NET_CORE
diff --git a/drivers/net/ethernet/via/via-velocity.c b/drivers/net/ethernet/via/via-velocity.c
index 5996cee..3a87f13 100644
--- a/drivers/net/ethernet/via/via-velocity.c
+++ b/drivers/net/ethernet/via/via-velocity.c
@@ -65,7 +65,11 @@
 #include <linux/if.h>
 #include <linux/uaccess.h>
 #include <linux/proc_fs.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
 #include <linux/inetdevice.h>
+#include <linux/platform_device.h>
 #include <linux/reboot.h>
 #include <linux/ethtool.h>
 #include <linux/mii.h>
@@ -84,6 +88,16 @@
 static int velocity_nics;
 static int msglevel = MSG_LEVEL_INFO;
 
+static void velocity_set_power_state(struct velocity_info *vptr, char state)
+{
+	void *addr = vptr->mac_regs;
+
+	if (vptr->bustype == BUS_PCI)
+		pci_set_power_state(vptr->pdev, state);
+	else
+		writeb(state, addr + 0x154);
+}
+
 /**
  *	mac_get_cam_mask	-	Read a CAM mask
  *	@regs: register block for this velocity
@@ -362,12 +376,24 @@ static struct velocity_info_tbl chip_info_table[] = {
  *	Describe the PCI device identifiers that we support in this
  *	device driver. Used for hotplug autoloading.
  */
-static DEFINE_PCI_DEVICE_TABLE(velocity_id_table) = {
+#ifdef CONFIG_PCI
+static DEFINE_PCI_DEVICE_TABLE(velocity_pci_id_table) = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_612X) },
 	{ }
 };
 
-MODULE_DEVICE_TABLE(pci, velocity_id_table);
+MODULE_DEVICE_TABLE(pci, velocity_pci_id_table);
+#endif
+
+/**
+ *	Describe the OF device identifiers that we support in this
+ *	device driver. Used for devicetree nodes.
+ */
+static struct of_device_id velocity_of_ids[] = {
+	{ .compatible = "via,velocity-vt6110", .data = &chip_info_table[0] },
+	{ /* Sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, velocity_of_ids);
 
 /**
  *	get_chip_name	- 	identifier to name
@@ -386,29 +412,6 @@ static const char *get_chip_name(enum chip_type chip_id)
 }
 
 /**
- *	velocity_remove1	-	device unplug
- *	@pdev: PCI device being removed
- *
- *	Device unload callback. Called on an unplug or on module
- *	unload for each active device that is present. Disconnects
- *	the device from the network layer and frees all the resources
- */
-static void velocity_remove1(struct pci_dev *pdev)
-{
-	struct net_device *dev = pci_get_drvdata(pdev);
-	struct velocity_info *vptr = netdev_priv(dev);
-
-	unregister_netdev(dev);
-	iounmap(vptr->mac_regs);
-	pci_release_regions(pdev);
-	pci_disable_device(pdev);
-	pci_set_drvdata(pdev, NULL);
-	free_netdev(dev);
-
-	velocity_nics--;
-}
-
-/**
  *	velocity_set_int_opt	-	parser for integer options
  *	@opt: pointer to option value
  *	@val: value the user requested (or -1 for default)
@@ -1181,6 +1184,14 @@ static void mii_init(struct velocity_info *vptr, u32 mii_status)
 	u16 BMCR;
 
 	switch (PHYID_GET_PHY_ID(vptr->phy_id)) {
+	case PHYID_ICPLUS_IP101A:
+		MII_REG_BITS_ON((ADVERTISE_PAUSE_ASYM | ADVERTISE_PAUSE_CAP), MII_ADVERTISE, vptr->mac_regs);
+		if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
+			MII_REG_BITS_ON(TCSR_ECHODIS, MII_SREVISION, vptr->mac_regs);
+		else
+			MII_REG_BITS_OFF(TCSR_ECHODIS, MII_SREVISION, vptr->mac_regs);
+		MII_REG_BITS_ON(PLED_LALBE, MII_TPISTATUS, vptr->mac_regs);
+		break;
 	case PHYID_CICADA_CS8201:
 		/*
 		 *	Reset to hardware default
@@ -1353,9 +1364,12 @@ static void velocity_init_registers(struct velocity_info *vptr,
 		velocity_soft_reset(vptr);
 		mdelay(5);
 
-		mac_eeprom_reload(regs);
-		for (i = 0; i < 6; i++)
-			writeb(vptr->netdev->dev_addr[i], &(regs->PAR[i]));
+		if (!vptr->no_eeprom) {
+			mac_eeprom_reload(regs);
+			for (i = 0; i < 6; i++)
+				writeb(vptr->netdev->dev_addr[i],
+							&(regs->PAR[i]));
+		}
 
 		/*
 		 *	clear Pre_ACPI bit.
@@ -2233,15 +2247,15 @@ static int velocity_open(struct net_device *dev)
 		goto out;
 
 	/* Ensure chip is running */
-	pci_set_power_state(vptr->pdev, PCI_D0);
+	velocity_set_power_state(vptr, PCI_D0);
 
 	velocity_init_registers(vptr, VELOCITY_INIT_COLD);
 
-	ret = request_irq(vptr->pdev->irq, velocity_intr, IRQF_SHARED,
+	ret = request_irq(dev->irq, velocity_intr, IRQF_SHARED,
 			  dev->name, dev);
 	if (ret < 0) {
 		/* Power down the chip */
-		pci_set_power_state(vptr->pdev, PCI_D3hot);
+		velocity_set_power_state(vptr, PCI_D3hot);
 		velocity_free_rings(vptr);
 		goto out;
 	}
@@ -2413,7 +2427,7 @@ static int velocity_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 	   saving then we need to bring the device back up to talk to it */
 
 	if (!netif_running(dev))
-		pci_set_power_state(vptr->pdev, PCI_D0);
+		velocity_set_power_state(vptr, PCI_D0);
 
 	switch (cmd) {
 	case SIOCGMIIPHY:	/* Get address of MII PHY in use. */
@@ -2426,7 +2440,7 @@ static int velocity_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 		ret = -EOPNOTSUPP;
 	}
 	if (!netif_running(dev))
-		pci_set_power_state(vptr->pdev, PCI_D3hot);
+		velocity_set_power_state(vptr, PCI_D3hot);
 
 
 	return ret;
@@ -2492,7 +2506,7 @@ static int velocity_close(struct net_device *dev)
 	if (vptr->flags & VELOCITY_FLAGS_WOL_ENABLED)
 		velocity_get_ip(vptr);
 
-	free_irq(vptr->pdev->irq, dev);
+	free_irq(dev->irq, dev);
 
 	velocity_free_rings(vptr);
 
@@ -2631,13 +2645,25 @@ static const struct net_device_ops velocity_netdev_ops = {
  *	Set up the initial velocity_info struct for the device that has been
  *	discovered.
  */
-static void velocity_init_info(struct pci_dev *pdev, struct velocity_info *vptr,
-			       const struct velocity_info_tbl *info)
+static void velocity_init_info(void *pdev,
+				struct velocity_info *vptr,
+				const struct velocity_info_tbl *info,
+				enum velocity_bus_type bustype)
 {
+	struct pci_dev *pci_dev;
+	struct platform_device *platform_dev;
+
 	memset(vptr, 0, sizeof(struct velocity_info));
 
-	vptr->dev = &pdev->dev;
-	vptr->pdev = pdev;
+	if (bustype == BUS_PCI) {
+		pci_dev = pdev;
+		vptr->pdev = pci_dev;
+		vptr->dev = &pci_dev->dev;
+	} else {
+		platform_dev = pdev;
+		vptr->dev = &platform_dev->dev;
+	}
+
 	vptr->chip_id = info->chip_id;
 	vptr->tx.numq = info->txqueue;
 	vptr->multicast_limit = MCAM_SIZE;
@@ -2655,8 +2681,6 @@ static void velocity_init_info(struct pci_dev *pdev, struct velocity_info *vptr,
 static int velocity_get_pci_info(struct velocity_info *vptr,
 				 struct pci_dev *pdev)
 {
-	vptr->rev_id = pdev->revision;
-
 	pci_set_master(pdev);
 
 	vptr->ioaddr = pci_resource_start(pdev, 0);
@@ -2678,12 +2702,45 @@ static int velocity_get_pci_info(struct velocity_info *vptr,
 		dev_err(&pdev->dev, "region #1 is too small.\n");
 		return -EINVAL;
 	}
+
 	vptr->pdev = pdev;
 
 	return 0;
 }
 
 /**
+ *	velocity_get_platform_info - retrieve platform info for device
+ *	@vptr: velocity device
+ *	@pdev: platform device it matches
+ *
+ *	Retrieve the Platform configuration data that interests us
+ */
+static int velocity_get_platform_info(struct velocity_info *vptr,
+					struct platform_device *pdev)
+{
+	int ret;
+	struct resource res;
+
+	if (of_get_property(pdev->dev.of_node, "no-eeprom", NULL))
+		vptr->no_eeprom = 1;
+
+	ret = of_address_to_resource(pdev->dev.of_node, 0, &res);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to find memory address\n");
+		return ret;
+	}
+
+	vptr->memaddr = res.start;
+
+	if (resource_size(&res) < VELOCITY_IO_SIZE) {
+		dev_err(&pdev->dev, "memory region is too small.\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
  *	velocity_print_info	-	per driver data
  *	@vptr: velocity
  *
@@ -2707,42 +2764,59 @@ static u32 velocity_get_link(struct net_device *dev)
 }
 
 /**
- *	velocity_found1		-	set up discovered velocity card
+ *	velocity_probe - set up discovered velocity device
  *	@pdev: PCI device
  *	@ent: PCI device table entry that matched
+ *	@bustype: bus that device is connected to
  *
  *	Configure a discovered adapter from scratch. Return a negative
  *	errno error code on failure paths.
  */
-static int velocity_found1(struct pci_dev *pdev,
-			   const struct pci_device_id *ent)
+static int velocity_probe(void *pdev,
+			   const struct pci_device_id *ent,
+			   enum velocity_bus_type bustype)
 {
 	static int first = 1;
-	struct net_device *dev;
+	struct pci_dev *pci_dev = NULL;
+	struct platform_device *platform_dev = NULL;
+	struct net_device *netdev;
+	struct device *dev;
+	const struct of_device_id *of_id;
 	int i;
 	const char *drv_string;
-	const struct velocity_info_tbl *info = &chip_info_table[ent->driver_data];
+	const struct velocity_info_tbl *info;
 	struct velocity_info *vptr;
 	struct mac_regs __iomem *regs;
+	int pci = (bustype == BUS_PCI) ? 1 : 0;
 	int ret = -ENOMEM;
 
+	if (pci) {
+		pci_dev = pdev;
+		dev = &pci_dev->dev;
+		info = &chip_info_table[ent->driver_data];
+	} else {
+		platform_dev = pdev;
+		dev = &platform_dev->dev;
+		of_id = of_match_device(velocity_of_ids, dev);
+		info = of_id->data;
+	}
+
 	/* FIXME: this driver, like almost all other ethernet drivers,
 	 * can support more than MAX_UNITS.
 	 */
 	if (velocity_nics >= MAX_UNITS) {
-		dev_notice(&pdev->dev, "already found %d NICs.\n",
-			   velocity_nics);
+		dev_notice(dev, "already found %d NICs.\n", velocity_nics);
 		return -ENODEV;
 	}
 
-	dev = alloc_etherdev(sizeof(struct velocity_info));
-	if (!dev)
+	netdev = alloc_etherdev(sizeof(struct velocity_info));
+	if (!netdev)
 		goto out;
 
 	/* Chain it all together */
 
-	SET_NETDEV_DEV(dev, &pdev->dev);
-	vptr = netdev_priv(dev);
+	SET_NETDEV_DEV(netdev, dev);
+	vptr = netdev_priv(netdev);
 
 	if (first) {
 		printk(KERN_INFO "%s Ver. %s\n",
@@ -2752,26 +2826,42 @@ static int velocity_found1(struct pci_dev *pdev,
 		first = 0;
 	}
 
-	velocity_init_info(pdev, vptr, info);
-
-	vptr->netdev = dev;
+	velocity_init_info(pdev, vptr, info, bustype);
+	vptr->bustype = bustype;
+	vptr->netdev = netdev;
 
-	ret = pci_enable_device(pdev);
-	if (ret < 0)
-		goto err_free_dev;
+	if (pci) {
+		ret = pci_enable_device(pci_dev);
+		if (ret < 0)
+			goto err_free_dev;
+		netdev->irq = pci_dev->irq;
+	} else {
+		netdev->irq =
+			irq_of_parse_and_map(platform_dev->dev.of_node, 0);
 
-	ret = velocity_get_pci_info(vptr, pdev);
-	if (ret < 0) {
-		/* error message already printed */
-		goto err_disable;
+		if (!netdev->irq) {
+			ret = -EINVAL;
+			goto err_free_dev;
+		}
 	}
 
-	ret = pci_request_regions(pdev, VELOCITY_NAME);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "No PCI resources.\n");
-		goto err_disable;
+	if (pci) {
+		ret = velocity_get_pci_info(vptr, pci_dev);
+		if (ret < 0)
+			goto err_disable;
+
+		ret = pci_request_regions(pci_dev, VELOCITY_NAME);
+		if (ret < 0) {
+			dev_err(dev, "No PCI resources.\n");
+			goto err_disable;
+		}
+	} else {
+		ret = velocity_get_platform_info(vptr, platform_dev);
+		if (ret < 0)
+			goto err_disable;
 	}
 
+
 	regs = ioremap(vptr->memaddr, VELOCITY_IO_SIZE);
 	if (regs == NULL) {
 		ret = -EIO;
@@ -2780,13 +2870,18 @@ static int velocity_found1(struct pci_dev *pdev,
 
 	vptr->mac_regs = regs;
 
+	if (pci)
+		vptr->rev_id = pci_dev->revision;
+	else
+		vptr->rev_id = readb(&regs->rev_id);
+
 	mac_wol_reset(regs);
 
 	for (i = 0; i < 6; i++)
-		dev->dev_addr[i] = readb(&regs->PAR[i]);
+		netdev->dev_addr[i] = readb(&regs->PAR[i]);
 
 
-	drv_string = dev_driver_string(&pdev->dev);
+	drv_string = dev_driver_string(dev);
 
 	velocity_get_options(&vptr->options, velocity_nics, drv_string);
 
@@ -2807,30 +2902,34 @@ static int velocity_found1(struct pci_dev *pdev,
 
 	vptr->phy_id = MII_GET_PHY_ID(vptr->mac_regs);
 
-	dev->netdev_ops = &velocity_netdev_ops;
-	dev->ethtool_ops = &velocity_ethtool_ops;
-	netif_napi_add(dev, &vptr->napi, velocity_poll, VELOCITY_NAPI_WEIGHT);
+	netdev->netdev_ops = &velocity_netdev_ops;
+	netdev->ethtool_ops = &velocity_ethtool_ops;
+	netif_napi_add(netdev, &vptr->napi, velocity_poll, VELOCITY_NAPI_WEIGHT);
 
-	dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
+	netdev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
 			   NETIF_F_HW_VLAN_CTAG_TX;
-	dev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_FILTER |
-			 NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_IP_CSUM;
+	netdev->features |= NETIF_F_HW_VLAN_CTAG_TX |
+			NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_RX |
+			NETIF_F_IP_CSUM;
 
-	ret = register_netdev(dev);
+	ret = register_netdev(netdev);
 	if (ret < 0)
 		goto err_iounmap;
 
-	if (!velocity_get_link(dev)) {
-		netif_carrier_off(dev);
+	if (!velocity_get_link(netdev)) {
+		netif_carrier_off(netdev);
 		vptr->mii_status |= VELOCITY_LINK_FAIL;
 	}
 
 	velocity_print_info(vptr);
-	pci_set_drvdata(pdev, dev);
+	if (pci)
+		pci_set_drvdata(pci_dev, netdev);
+	else
+		platform_set_drvdata(platform_dev, netdev);
 
 	/* and leave the chip powered down */
 
-	pci_set_power_state(pdev, PCI_D3hot);
+	velocity_set_power_state(vptr, PCI_D3hot);
 	velocity_nics++;
 out:
 	return ret;
@@ -2838,14 +2937,79 @@ out:
 err_iounmap:
 	iounmap(regs);
 err_release_res:
-	pci_release_regions(pdev);
+	if (pci)
+		pci_release_regions(pci_dev);
 err_disable:
-	pci_disable_device(pdev);
+	if (pci)
+		pci_disable_device(pci_dev);
 err_free_dev:
-	free_netdev(dev);
+	free_netdev(netdev);
 	goto out;
 }
 
+/**
+ *	velocity_remove	- device unplug
+ *	@pdev: PCI device being removed
+ *	@bustype: bus that device is connected to
+ *
+ *	Device unload callback. Called on an unplug or on module
+ *	unload for each active device that is present. Disconnects
+ *	the device from the network layer and frees all the resources
+ */
+static int velocity_remove(void *pdev, enum velocity_bus_type bustype)
+{
+	struct net_device *netdev;
+	struct velocity_info *vptr;
+	int pci = (bustype == BUS_PCI) ? 1 : 0;
+
+	if (pci)
+		netdev = pci_get_drvdata(pdev);
+	else
+		netdev = platform_get_drvdata(pdev);
+
+	vptr = netdev_priv(netdev);
+
+	unregister_netdev(netdev);
+	iounmap(vptr->mac_regs);
+
+	if (pci) {
+		pci_release_regions(pdev);
+		pci_disable_device(pdev);
+		pci_set_drvdata(pdev, NULL);
+	} else {
+		platform_set_drvdata(pdev, NULL);
+	}
+
+	free_netdev(netdev);
+
+	velocity_nics--;
+
+	return 0;
+}
+
+#ifdef CONFIG_PCI
+static int velocity_pci_probe(struct pci_dev *pdev,
+			   const struct pci_device_id *ent)
+{
+	return velocity_probe(pdev, ent, BUS_PCI);
+}
+
+static void velocity_pci_remove(struct pci_dev *pdev)
+{
+	velocity_remove(pdev, BUS_PCI);
+}
+#endif
+
+static int velocity_platform_probe(struct platform_device *pdev)
+{
+	return velocity_probe(pdev, NULL, BUS_PLATFORM);
+}
+
+static int velocity_platform_remove(struct platform_device *pdev)
+{
+	return velocity_remove(pdev, BUS_PLATFORM);
+}
+
 #ifdef CONFIG_PM
 /**
  *	wol_calc_crc		-	WOL CRC
@@ -3003,11 +3167,20 @@ static void velocity_save_context(struct velocity_info *vptr, struct velocity_co
 
 }
 
-static int velocity_suspend(struct pci_dev *pdev, pm_message_t state)
+static int velocity_suspend(void *pdev, pm_message_t state,
+					enum velocity_bus_type bustype)
 {
-	struct net_device *dev = pci_get_drvdata(pdev);
-	struct velocity_info *vptr = netdev_priv(dev);
+	struct net_device *netdev;
+	struct velocity_info *vptr;
 	unsigned long flags;
+	int pci = (bustype == BUS_PCI) ? 1 : 0;
+
+	if (pci)
+		netdev = pci_get_drvdata(pdev);
+	else
+		netdev = platform_get_drvdata(pdev);
+
+	vptr = netdev_priv(netdev);
 
 	if (!netif_running(vptr->netdev))
 		return 0;
@@ -3015,20 +3188,24 @@ static int velocity_suspend(struct pci_dev *pdev, pm_message_t state)
 	netif_device_detach(vptr->netdev);
 
 	spin_lock_irqsave(&vptr->lock, flags);
-	pci_save_state(pdev);
+	if (pci)
+		pci_save_state(pdev);
 
 	if (vptr->flags & VELOCITY_FLAGS_WOL_ENABLED) {
 		velocity_get_ip(vptr);
 		velocity_save_context(vptr, &vptr->context);
 		velocity_shutdown(vptr);
 		velocity_set_wol(vptr);
-		pci_enable_wake(pdev, PCI_D3hot, 1);
-		pci_set_power_state(pdev, PCI_D3hot);
+		if (pci)
+			pci_enable_wake(pdev, PCI_D3hot, 1);
+		velocity_set_power_state(vptr, PCI_D3hot);
 	} else {
 		velocity_save_context(vptr, &vptr->context);
 		velocity_shutdown(vptr);
-		pci_disable_device(pdev);
-		pci_set_power_state(pdev, pci_choose_state(pdev, state));
+		if (pci)
+			pci_disable_device(pdev);
+		velocity_set_power_state(vptr,
+					 velocity_choose_state(pdev, state));
 	}
 
 	spin_unlock_irqrestore(&vptr->lock, flags);
@@ -3070,19 +3247,30 @@ static void velocity_restore_context(struct velocity_info *vptr, struct velocity
 		writeb(*((u8 *) (context->mac_reg + i)), ptr + i);
 }
 
-static int velocity_resume(struct pci_dev *pdev)
+static int velocity_resume(void *pdev, enum velocity_bus_type bustype)
 {
-	struct net_device *dev = pci_get_drvdata(pdev);
-	struct velocity_info *vptr = netdev_priv(dev);
+	struct net_device *netdev;
+	struct velocity_info *vptr;
 	unsigned long flags;
+	int pci = (bustype == BUS_PCI) ? 1 : 0;
 	int i;
 
+	if (pci)
+		netdev = pci_get_drvdata(pdev);
+	else
+		netdev = platform_get_drvdata(pdev);
+
+	vptr = netdev_priv(netdev);
+
 	if (!netif_running(vptr->netdev))
 		return 0;
 
-	pci_set_power_state(pdev, PCI_D0);
-	pci_enable_wake(pdev, 0, 0);
-	pci_restore_state(pdev);
+	velocity_set_power_state(vptr, PCI_D0);
+
+	if (pci) {
+		pci_enable_wake(pdev, 0, 0);
+		pci_restore_state(pdev);
+	}
 
 	mac_wol_reset(vptr->mac_regs);
 
@@ -3104,23 +3292,62 @@ static int velocity_resume(struct pci_dev *pdev)
 
 	return 0;
 }
+
+#ifdef CONFIG_PCI
+static int velocity_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	return velocity_suspend(pdev, state, BUS_PCI);
+}
+
+static int velocity_pci_resume(struct pci_dev *pdev)
+{
+	return velocity_resume(pdev, BUS_PCI);
+}
 #endif
 
+static int velocity_platform_suspend(struct platform_device *pdev,
+				      pm_message_t state)
+{
+	return velocity_suspend(pdev, state, BUS_PLATFORM);
+}
+
+static int velocity_platform_resume(struct platform_device *pdev)
+{
+	return velocity_resume(pdev, BUS_PLATFORM);
+}
+
+#endif	/* !CONFIG_PM */
+
 /*
  *	Definition for our device driver. The PCI layer interface
  *	uses this to handle all our card discover and plugging
  */
-static struct pci_driver velocity_driver = {
+#ifdef CONFIG_PCI
+static struct pci_driver velocity_pci_driver = {
 	.name		= VELOCITY_NAME,
-	.id_table	= velocity_id_table,
-	.probe		= velocity_found1,
-	.remove		= velocity_remove1,
+	.id_table	= velocity_pci_id_table,
+	.probe		= velocity_pci_probe,
+	.remove		= velocity_pci_remove,
 #ifdef CONFIG_PM
-	.suspend	= velocity_suspend,
-	.resume		= velocity_resume,
+	.suspend	= velocity_pci_suspend,
+	.resume		= velocity_pci_resume,
 #endif
 };
+#endif
 
+static struct platform_driver velocity_platform_driver = {
+	.probe		= velocity_platform_probe,
+	.remove		= velocity_platform_remove,
+#ifdef CONFIG_PM
+	.suspend	= velocity_platform_suspend,
+	.resume		= velocity_platform_resume,
+#endif
+	.driver = {
+		.name = "via-velocity",
+		.owner = THIS_MODULE,
+		.of_match_table = velocity_of_ids,
+	},
+};
 
 /**
  *	velocity_ethtool_up	-	pre hook for ethtool
@@ -3133,7 +3360,7 @@ static int velocity_ethtool_up(struct net_device *dev)
 {
 	struct velocity_info *vptr = netdev_priv(dev);
 	if (!netif_running(dev))
-		pci_set_power_state(vptr->pdev, PCI_D0);
+		velocity_set_power_state(vptr, PCI_D0);
 	return 0;
 }
 
@@ -3148,7 +3375,7 @@ static void velocity_ethtool_down(struct net_device *dev)
 {
 	struct velocity_info *vptr = netdev_priv(dev);
 	if (!netif_running(dev))
-		pci_set_power_state(vptr->pdev, PCI_D3hot);
+		velocity_set_power_state(vptr, PCI_D3hot);
 }
 
 static int velocity_get_settings(struct net_device *dev,
@@ -3270,7 +3497,11 @@ static void velocity_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo
 	struct velocity_info *vptr = netdev_priv(dev);
 	strlcpy(info->driver, VELOCITY_NAME, sizeof(info->driver));
 	strlcpy(info->version, VELOCITY_VERSION, sizeof(info->version));
-	strlcpy(info->bus_info, pci_name(vptr->pdev), sizeof(info->bus_info));
+	if (vptr->bustype == BUS_PCI)
+		strlcpy(info->bus_info, pci_name(vptr->pdev),
+						sizeof(info->bus_info));
+	else
+		strlcpy(info->bus_info, "platform", sizeof(info->bus_info));
 }
 
 static void velocity_ethtool_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
@@ -3563,9 +3794,15 @@ static int __init velocity_init_module(void)
 	int ret;
 
 	velocity_register_notifier();
-	ret = pci_register_driver(&velocity_driver);
+#ifdef CONFIG_PCI
+	ret = pci_register_driver(&velocity_pci_driver);
 	if (ret < 0)
 		velocity_unregister_notifier();
+#endif
+	ret = platform_driver_register(&velocity_platform_driver);
+	if (ret < 0)
+		velocity_unregister_notifier();
+
 	return ret;
 }
 
@@ -3580,7 +3817,10 @@ static int __init velocity_init_module(void)
 static void __exit velocity_cleanup_module(void)
 {
 	velocity_unregister_notifier();
-	pci_unregister_driver(&velocity_driver);
+#ifdef CONFIG_PCI
+	pci_unregister_driver(&velocity_pci_driver);
+#endif
+	platform_driver_unregister(&velocity_platform_driver);
 }
 
 module_init(velocity_init_module);
diff --git a/drivers/net/ethernet/via/via-velocity.h b/drivers/net/ethernet/via/via-velocity.h
index c38bbae..7468765 100644
--- a/drivers/net/ethernet/via/via-velocity.h
+++ b/drivers/net/ethernet/via/via-velocity.h
@@ -1265,7 +1265,7 @@ struct velocity_context {
 #define PHYID_VT3216_64BIT  0x000FC600UL
 #define PHYID_MARVELL_1000  0x01410C50UL
 #define PHYID_MARVELL_1000S 0x01410C40UL
-
+#define PHYID_ICPLUS_IP101A 0x02430C54UL
 #define PHYID_REV_ID_MASK   0x0000000FUL
 
 #define PHYID_GET_PHY_ID(i)         ((i) & ~PHYID_REV_ID_MASK)
@@ -1433,10 +1433,38 @@ struct velocity_opt {
 
 #define GET_RD_BY_IDX(vptr, idx)   (vptr->rd_ring[idx])
 
+static inline char velocity_choose_state(struct device *dev,
+					   pm_message_t state)
+
+{
+	switch (state.event) {
+	case PM_EVENT_ON:
+		return PCI_D0;
+	case PM_EVENT_FREEZE:
+	case PM_EVENT_PRETHAW:
+		/* REVISIT both freeze and pre-thaw "should" use D0 */
+	case PM_EVENT_SUSPEND:
+	case PM_EVENT_HIBERNATE:
+		return PCI_D3hot;
+	default:
+		dev_info(dev, "unrecognized suspend event %d\n", state.event);
+		BUG();
+	}
+
+	return PCI_D0;
+}
+
+enum velocity_bus_type {
+	BUS_PCI,
+	BUS_PLATFORM,
+};
+
 struct velocity_info {
 	struct device *dev;
 	struct pci_dev *pdev;
 	struct net_device *netdev;
+	enum velocity_bus_type bustype;
+	int no_eeprom;
 
 	unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
 	u8 ip_addr[4];
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCHv3 3/3] net: velocity: Add platform device support to VIA velocity driver
  2013-04-29 19:46 ` [PATCHv3 3/3] net: velocity: Add platform device support to VIA velocity driver Tony Prisk
@ 2013-04-29 23:04   ` Francois Romieu
  2013-05-02 17:19     ` Russell King - ARM Linux
  0 siblings, 1 reply; 6+ messages in thread
From: Francois Romieu @ 2013-04-29 23:04 UTC (permalink / raw)
  To: Tony Prisk
  Cc: vt8500-wm8505-linux-kernel, netdev, linux-kernel,
	linux-arm-kernel, davem

Tony Prisk <linux@prisktech.co.nz> :
[...]
> +static int velocity_remove(void *pdev, enum velocity_bus_type bustype)
> +{
> +	struct net_device *netdev;
> +	struct velocity_info *vptr;
> +	int pci = (bustype == BUS_PCI) ? 1 : 0;
> +
> +	if (pci)
> +		netdev = pci_get_drvdata(pdev);
> +	else
> +		netdev = platform_get_drvdata(pdev);

The caller knows how to retrieve the net_device pointer, whence
the struct velocity_info pointer, whence any bustype dependent
function pointer to alleviate the "if (pci)" and CONFIG stuff.

If you are not convinced, please consider turning the void *
into an union *.

-- 
Ueimor

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCHv3 3/3] net: velocity: Add platform device support to VIA velocity driver
  2013-04-29 23:04   ` Francois Romieu
@ 2013-05-02 17:19     ` Russell King - ARM Linux
  0 siblings, 0 replies; 6+ messages in thread
From: Russell King - ARM Linux @ 2013-05-02 17:19 UTC (permalink / raw)
  To: Francois Romieu
  Cc: Tony Prisk, vt8500-wm8505-linux-kernel, netdev, linux-kernel,
	linux-arm-kernel, davem

On Tue, Apr 30, 2013 at 01:04:50AM +0200, Francois Romieu wrote:
> Tony Prisk <linux@prisktech.co.nz> :
> [...]
> > +static int velocity_remove(void *pdev, enum velocity_bus_type bustype)
> > +{
> > +	struct net_device *netdev;
> > +	struct velocity_info *vptr;
> > +	int pci = (bustype == BUS_PCI) ? 1 : 0;
> > +
> > +	if (pci)
> > +		netdev = pci_get_drvdata(pdev);
> > +	else
> > +		netdev = platform_get_drvdata(pdev);
> 
> The caller knows how to retrieve the net_device pointer, whence
> the struct velocity_info pointer, whence any bustype dependent
> function pointer to alleviate the "if (pci)" and CONFIG stuff.
> 
> If you are not convinced, please consider turning the void *
> into an union *.

The other thing here is that you can just pass a struct device into
these and retrieve the same driver data via:

	netdev = dev_get_drvdata(dev);

as:

static inline void *platform_get_drvdata(const struct platform_device *pdev)
{
        return dev_get_drvdata(&pdev->dev);
}

static inline void *pci_get_drvdata(struct pci_dev *pdev)
{
        return dev_get_drvdata(&pdev->dev);
}

So there's no need for void * or union nonsense.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2013-05-02 17:20 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-04-29 19:46 [PATCHv3 0/3] Add support for velocity network driver on platform devices Tony Prisk
2013-04-29 19:46 ` [PATCHv3 1/3] net: velocity: Rename vptr->dev to vptr->netdev Tony Prisk
2013-04-29 19:46 ` [PATCHv3 2/3] net: velocity: Convert to generic dma functions Tony Prisk
2013-04-29 19:46 ` [PATCHv3 3/3] net: velocity: Add platform device support to VIA velocity driver Tony Prisk
2013-04-29 23:04   ` Francois Romieu
2013-05-02 17:19     ` Russell King - ARM Linux

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).