Thread (4 messages) 4 messages, 4 authors, 2012-01-17
STALE5307d

[PATCH V3 1/4] CS89x0 : add platform driver support

From: Russell King - ARM Linux <hidden>
Date: 2012-01-16 11:09:07
Also in: netdev

On Sat, Jan 14, 2012 at 08:56:36PM +0100, Jaccon Bastiaansen wrote:
The CS89x0 ethernet controller is used on a number of evaluation
boards, such as the MX31ADS. The current driver has memory address and
IRQ settings for each board on which this controller is used. Driver
updates are therefore required to support other boards that also use
the CS89x0. To avoid these driver updates, a better mechanism
(platform driver support) is added to communicate the board dependent
settings to the driver.
Please check your changes with sparse and checkpatch.
quoted hunk ↗ jump to hunk
@@ -236,6 +243,11 @@ struct net_local {
 	unsigned char *end_dma_buff;	/* points to the end of the buffer */
 	unsigned char *rx_dma_ptr;	/* points to the next packet  */
 #endif
+#ifdef CONFIG_CS89x0_PLATFORM
+	void *virt_addr;	/* Virtual address for accessing the CS89x0. */
	void __iomem *virt_addr;
+#ifdef CONFIG_CS89x0_PLATFORM
+static int __init cs89x0_platform_probe(struct platform_device *pdev)
+{
+	struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
+	struct net_local *lp = netdev_priv(dev);
+	struct resource *mem_res;
+	int err;
+
+	if (!dev)
+		return -ENODEV;
Wouldn't -ENOMEM be better?  Also, organise this as:

	struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
	struct net_local *lp;

	if (!dev)
		return -ENOMEM;

	lp = netdev_priv(dev);

because you don't shouldn't how netdev_priv() works, or whether it
dereferences a pointer within the net_device.  (How netdev_priv()
works is not something that should concern you as a driver writer -
it's there to hide the details, which may change over time.)
+
+	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	dev->irq = platform_get_irq(pdev, 0);
+	if (mem_res == NULL || dev->irq <= 0) {
+		dev_warn(&dev->dev, "memory/interrupt resource missing.\n");
+		err = -ENOENT;
Other patches return -ENXIO for this.
+		goto free;
+	}
+
+	lp->phys_addr = mem_res->start;
+	lp->size = mem_res->end - mem_res->start + 1;
lp->size = resource_size(mem_res);
+	if (!request_mem_region(lp->phys_addr, lp->size, DRV_NAME)) {
+		dev_warn(&dev->dev, "request_mem_region() failed.\n");
+		err = -ENOMEM;
If the region is busy, then this fails.  It's return value should therefore
be -EBUSY.
+		goto free;
+	}
+
+	lp->virt_addr = ioremap(lp->phys_addr, lp->size);
+	if (!lp->virt_addr) {
+		dev_warn(&dev->dev, "ioremap() failed.\n");
+		err = -ENOMEM;
+		goto release;
+	}
+
+	err = cs89x0_probe1(dev, (int)lp->virt_addr, 0);
Have you checked whether this causes a compiler warning?  Normally if you
cast a pointer to 'int', it'll complain about a narrowing cast.

There are architectures Linux supports where int is 32-bit and a pointer
is 64-bit, so this won't work.  It needs the 'port' type changed to
something which pointers can be casted (I suggest unsigned long, as we
do elsewhere.)
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help