Greetings to all.
Can anyone give me pointers where I can find patch for supporting MPC8280 processor for Linuxppc Kernel 2.4.20(has support for MPC8260)? The help would be highly appreciated. With Best Regards, C.R.Srivatsan -----Original Message----- From: [EMAIL PROTECTED] [mailto:linuxppc-embedded-bounces at ozlabs.org] On Behalf Of linuxppc-embedded-request at ozlabs.org Sent: Thursday, December 09, 2004 10:26 AM To: linuxppc-embedded at ozlabs.org Subject: Linuxppc-embedded Digest, Vol 4, Issue 13 Send Linuxppc-embedded mailing list submissions to linuxppc-embedded at ozlabs.org To subscribe or unsubscribe via the World Wide Web, visit https://ozlabs.org/mailman/listinfo/linuxppc-embedded or, via email, send a message with subject or body 'help' to linuxppc-embedded-request at ozlabs.org You can reach the person managing the list at linuxppc-embedded-owner at ozlabs.org When replying, please edit your Subject line so it is more specific than "Re: Contents of Linuxppc-embedded digest..." Today's Topics: 1. Linux PCI support on Ocotea (Chris Love) 2. Re: Linux PCI support on Ocotea (Matt Porter) 3. Re: Linux PCI support on Ocotea (Chris Love) 4. [RFC][PPC32] platform device / driver model usage (Kumar Gala) ---------------------------------------------------------------------- Message: 1 Date: Wed, 08 Dec 2004 17:10:54 -0800 From: Chris Love <[EMAIL PROTECTED]> Subject: Linux PCI support on Ocotea To: linuxppc-embedded at ozlabs.org Message-ID: <41B7A61E.9000602 at ccpu.com> Content-Type: text/plain; charset=us-ascii; format=flowed Hi folks, We have an Ocotea reference board (PPC 440GX) w/256M and have tried running both stable 2.4.26 and 2.6.10-rc3 kernels from penguinppc.org. For now the bootloader is still PIBS, though we'll get U-Boot installed shortly. As a first experiment we've tried installing a legacy card with an Intel 82559 device on it. The warning seen from pci_setup_device() suggests that PCI config space wasn't read cleanly: a header type of 0x7f is encountered. Nothing shows up under /proc/bus/pci. The card we'd actually like to install has a transparent bridge (Intel 21152) and other devices behind the bridge. Both cards are PCI-33 versus PCI-X. To ask some really stupid questions first: what is the state of PCI support with linux on this board? Have others tried to do something like this with 33/66 Mhz PCI devices or am I in uncharted waters? Of the PCI #defines in platforms/ocotea.h I can correlate most with data from the user's manual, but not the following: #define OCOTEA_PCI_LOWER_IO 0x00000000 #define OCOTEA_PCI_UPPER_IO 0x0000ffff #define OCOTEA_PCI_LOWER_MEM 0x80000000 #define OCOTEA_PCI_UPPER_MEM 0xffffefff Is there some documentation I'm missing on these values? Thanks in advance for any suggestions, Chris -- Chris Love // Continuous Computing Corporation love at ccpu.com // http://www.ccpu.com ------------------------------ Message: 2 Date: Wed, 8 Dec 2004 18:49:58 -0700 From: Matt Porter <[EMAIL PROTECTED]> Subject: Re: Linux PCI support on Ocotea To: Chris Love <love at ccpu.com> Cc: linuxppc-embedded at ozlabs.org Message-ID: <20041208184958.A22430 at home.com> Content-Type: text/plain; charset=us-ascii On Wed, Dec 08, 2004 at 05:10:54PM -0800, Chris Love wrote: > Hi folks, > > We have an Ocotea reference board (PPC 440GX) w/256M and have > tried running both stable 2.4.26 and 2.6.10-rc3 kernels from > penguinppc.org. For now the bootloader is still PIBS, though > we'll get U-Boot installed shortly. > > As a first experiment we've tried installing a legacy card > with an Intel 82559 device on it. The warning seen from > pci_setup_device() suggests that PCI config space wasn't > read cleanly: a header type of 0x7f is encountered. Nothing > shows up under /proc/bus/pci. The card we'd actually like to > install has a transparent bridge (Intel 21152) and other devices > behind the bridge. Both cards are PCI-33 versus PCI-X. Sounds like something is wrong with your hardware configuration. > To ask some really stupid questions first: what is the state of > PCI support with linux on this board? Have others tried to do > something like this with 33/66 Mhz PCI devices or am I in > uncharted waters? No, this works fine for many other people, so don't get too worried. Do verify that you have jumpered for 33Mhz operation since you are using a 33Mhz device. PIBS should warn you about this and advise to make the change, but maybe you have a different version than I've seen. What rev. ocotea board and version of PIBS do you have? > Of the PCI #defines in platforms/ocotea.h I can correlate most > with data from the user's manual, but not the following: > > #define OCOTEA_PCI_LOWER_IO 0x00000000 > #define OCOTEA_PCI_UPPER_IO 0x0000ffff > #define OCOTEA_PCI_LOWER_MEM 0x80000000 > #define OCOTEA_PCI_UPPER_MEM 0xffffefff > > Is there some documentation I'm missing on these values? The code is self-documenting as they say. :) These are the address ranges used by the pci_auto code to assign base addresses to each BAR that is encountered. -Matt ------------------------------ Message: 3 Date: Wed, 08 Dec 2004 18:20:29 -0800 From: Chris Love <[EMAIL PROTECTED]> Subject: Re: Linux PCI support on Ocotea To: Matt Porter <mporter at kernel.crashing.org> Cc: linuxppc-embedded at ozlabs.org Message-ID: <41B7B66D.2000409 at ccpu.com> Content-Type: text/plain; charset=us-ascii; format=flowed Matt Porter wrote: > On Wed, Dec 08, 2004 at 05:10:54PM -0800, Chris Love wrote: > >>Hi folks, >> >>We have an Ocotea reference board (PPC 440GX) w/256M and have >>tried running both stable 2.4.26 and 2.6.10-rc3 kernels from >>penguinppc.org. For now the bootloader is still PIBS, though >>we'll get U-Boot installed shortly. >> >>As a first experiment we've tried installing a legacy card >>with an Intel 82559 device on it. The warning seen from >>pci_setup_device() suggests that PCI config space wasn't >>read cleanly: a header type of 0x7f is encountered. Nothing >>shows up under /proc/bus/pci. The card we'd actually like to >>install has a transparent bridge (Intel 21152) and other devices >>behind the bridge. Both cards are PCI-33 versus PCI-X. > > > Sounds like something is wrong with your hardware configuration. > > >>To ask some really stupid questions first: what is the state of >>PCI support with linux on this board? Have others tried to do >>something like this with 33/66 Mhz PCI devices or am I in >>uncharted waters? > > > No, this works fine for many other people, so don't get too worried. > Do verify that you have jumpered for 33Mhz operation since you > are using a 33Mhz device. PIBS should warn you about this and > advise to make the change, but maybe you have a different > version than I've seen. What rev. ocotea board and version of > PIBS do you have? Hi Matt, PIBS version text is "Version 1.80 JUNE/17/2004". Ocotea rev appears to be rev 5. Changing the settings for the U80 switches did the trick, at least as far as silencing the PIBS warning and enumerating the bus by Linux. Thanks for the suggestion; this was lurking on the board schematics. Chris -- Chris Love // Continuous Computing Corporation love at ccpu.com // http://www.ccpu.com ------------------------------ Message: 4 Date: Wed, 8 Dec 2004 22:56:03 -0600 (CST) From: Kumar Gala <[EMAIL PROTECTED]> Subject: [RFC][PPC32] platform device / driver model usage To: linux-kernel at vger.kernel.org Cc: linuxppc-embedded at ozlabs.org Message-ID: <Pine.LNX.4.61.0412082233440.14848 at blarg.somerset.sps.mot.com> Content-Type: TEXT/PLAIN; charset=US-ASCII Moves the MPC85xx to using the driver model instead of OCP for driver/device binding. Transitioned the gianfar ethernet driver over as an example, this currently only works on the MPC8540ADS with TSEC1. The patch is a work in progress to get feedback on. This is based on patches from Jason McMullan at TimeSys. I wanted to get feedback on the addition of a flags field to struct platform_device. Also, if there was any issue with the addition of include/linux/fsl_devices.h. Other comments are welcome. thanks - kumar diff -Nru a/arch/ppc/platforms/85xx/Makefile b/arch/ppc/platforms/85xx/Makefile --- a/arch/ppc/platforms/85xx/Makefile 2004-12-08 22:22:37 -06:00 +++ b/arch/ppc/platforms/85xx/Makefile 2004-12-08 22:22:37 -06:00 @@ -1,6 +1,7 @@ # # Makefile for the PowerPC 85xx linux kernel. # +obj-$(CONFIG_85xx) += mpc85xx.o obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads_common.o mpc8540_ads.o obj-$(CONFIG_MPC8555_CDS) += mpc85xx_cds_common.o diff -Nru a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c --- a/arch/ppc/platforms/85xx/mpc8540_ads.c 2004-12-08 22:22:37 -06:00 +++ b/arch/ppc/platforms/85xx/mpc8540_ads.c 2004-12-08 22:22:37 -06:00 @@ -32,6 +32,7 @@ #include <linux/serial_core.h> #include <linux/initrd.h> #include <linux/module.h> +#include <linux/fsl_devices.h> #include <asm/system.h> #include <asm/pgtable.h> @@ -54,6 +55,14 @@ #include <syslib/ppc85xx_common.h> #include <syslib/ppc85xx_setup.h> +struct gianfar_platform_data mpc85xx_gianfar1_def = { + .flags = GFAR_HAS_PHY_INTR, + .interruptPHY = MPC85xx_IRQ_EXT5, + .phyid = 0, + .phydevice = "fsl-gianfar1", + .phyregidx = 1, +}; + struct ocp_gfar_data mpc85xx_tsec1_def = { .interruptTransmit = MPC85xx_IRQ_TSEC1_TX, .interruptError = MPC85xx_IRQ_TSEC1_ERROR, @@ -147,6 +156,8 @@ einfo = (struct ocp_gfar_data *) def->additions; memcpy(einfo->mac_addr, binfo->bi_enet2addr, 6); } + + memcpy(mpc85xx_gianfar1_def.mac_addr, binfo->bi_enetaddr, 6); #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start) diff -Nru a/arch/ppc/platforms/85xx/mpc85xx.c b/arch/ppc/platforms/85xx/mpc85xx.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/arch/ppc/platforms/85xx/mpc85xx.c 2004-12-08 22:22:37 -06:00 @@ -0,0 +1,243 @@ +/* + * arch/ppc/platforms/85xx/mpc85xx.c + * + * MPC85xx Device descriptions + * + * Maintainer: Kumar Gala <kumar.gala at freescale.com> + * + * Copyright 2004 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/device.h> +#include <linux/fsl_devices.h> +#include <asm/mpc85xx.h> + +/* These should be defined in platform code */ +extern struct gianfar_platform_data mpc85xx_gianfar1_def; + +/* We use offsets for IORESOURCE_MEM since we do not know at compile time + * what CCSRBAR is, platform code should fix this up in + * setup_arch + * + */ + +static struct platform_device m_dev[] = { + [MPC85xx_TSEC1] = { + .name = "fsl-gianfar", + .id = 1, + .flags = GIANFAR_HAS_GIGABIT | GIANFAR_HAS_MULTI_INTR | GIANFAR_HAS_RMON | GIANFAR_HAS_COALESCE, + .num_resources = 4, + .dev.platform_data = &mpc85xx_gianfar1_def, + .resource = (struct resource[]) { + { + .start = MPC85xx_ENET1_OFFSET, + .end = MPC85xx_ENET1_OFFSET + MPC85xx_ENET1_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "tx", + .start = MPC85xx_IRQ_TSEC1_TX, + .end = MPC85xx_IRQ_TSEC1_TX, + .flags = IORESOURCE_IRQ, + }, + { + .name = "rx", + .start = MPC85xx_IRQ_TSEC1_RX, + .end = MPC85xx_IRQ_TSEC1_RX, + .flags = IORESOURCE_IRQ, + }, + { + .name = "error", + .start = MPC85xx_IRQ_TSEC1_ERROR, + .end = MPC85xx_IRQ_TSEC1_ERROR, + .flags = IORESOURCE_IRQ, + }, + }, + }, + [MPC85xx_TSEC2] = { + .name = "fsl-gianfar", + .id = 2, + .flags = GIANFAR_HAS_GIGABIT | GIANFAR_HAS_MULTI_INTR | GIANFAR_HAS_RMON | GIANFAR_HAS_COALESCE, + .num_resources = 4, + .resource = (struct resource[]) { + { + .start = MPC85xx_ENET2_OFFSET, + .end = MPC85xx_ENET2_OFFSET + MPC85xx_ENET2_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "tx", + .start = MPC85xx_IRQ_TSEC2_TX, + .end = MPC85xx_IRQ_TSEC2_TX, + .flags = IORESOURCE_IRQ, + }, + { + .name = "rx", + .start = MPC85xx_IRQ_TSEC2_RX, + .end = MPC85xx_IRQ_TSEC2_RX, + .flags = IORESOURCE_IRQ, + }, + { + .name = "error", + .start = MPC85xx_IRQ_TSEC2_ERROR, + .end = MPC85xx_IRQ_TSEC2_ERROR, + .flags = IORESOURCE_IRQ, + }, + }, + }, + [MPC85xx_FEC] = { + .name = "fsl-gianfar", + .id = 3, + .num_resources = 2, + .resource = (struct resource[]) { + { + .start = MPC85xx_ENET3_OFFSET, + .end = MPC85xx_ENET3_OFFSET + MPC85xx_ENET3_SIZE - 1, + .flags = IORESOURCE_MEM, + + }, + { + .start = MPC85xx_IRQ_TSEC1_TX, + .end = MPC85xx_IRQ_TSEC1_TX, + .flags = IORESOURCE_IRQ, + }, + }, + }, + [MPC85xx_IIC1] = { + .name = "fsl-i2c", + .id = 1, + .flags = FSL_I2C_SEPARATE_DFSRR, + .num_resources = 2, + .resource = (struct resource[]) { + { + .start = MPC85xx_IIC1_OFFSET, + .end = MPC85xx_IIC1_OFFSET + MPC85xx_IIC1_SIZE - 1, + .flags = IORESOURCE_MEM, + + }, + { + .start = MPC85xx_IRQ_IIC1, + .end = MPC85xx_IRQ_IIC1, + .flags = IORESOURCE_IRQ, + }, + }, + }, + [MPC85xx_DMA0] = { + .name = "fsl-dma", + .id = 0, + .num_resources = 2, + .resource = (struct resource[]) { + { + .start = MPC85xx_DMA0_OFFSET, + .end = MPC85xx_DMA0_OFFSET + MPC85xx_DMA0_SIZE - 1, + .flags = IORESOURCE_MEM, + + }, + { + .start = MPC85xx_IRQ_DMA0, + .end = MPC85xx_IRQ_DMA0, + .flags = IORESOURCE_IRQ, + }, + }, + }, + [MPC85xx_DMA1] = { + .name = "fsl-dma", + .id = 1, + .num_resources = 2, + .resource = (struct resource[]) { + { + .start = MPC85xx_DMA1_OFFSET, + .end = MPC85xx_DMA1_OFFSET + MPC85xx_DMA1_SIZE - 1, + .flags = IORESOURCE_MEM, + + }, + { + .start = MPC85xx_IRQ_DMA1, + .end = MPC85xx_IRQ_DMA1, + .flags = IORESOURCE_IRQ, + }, + }, + }, + [MPC85xx_DMA2] = { + .name = "fsl-dma", + .id = 2, + .num_resources = 2, + .resource = (struct resource[]) { + { + .start = MPC85xx_DMA2_OFFSET, + .end = MPC85xx_DMA2_OFFSET + MPC85xx_DMA2_SIZE - 1, + .flags = IORESOURCE_MEM, + + }, + { + .start = MPC85xx_IRQ_DMA2, + .end = MPC85xx_IRQ_DMA2, + .flags = IORESOURCE_IRQ, + }, + }, + }, + [MPC85xx_DMA3] = { + .name = "fsl-dma", + .id = 3, + .num_resources = 2, + .resource = (struct resource[]) { + { + .start = MPC85xx_DMA3_OFFSET, + .end = MPC85xx_DMA3_OFFSET + MPC85xx_DMA3_SIZE - 1, + .flags = IORESOURCE_MEM, + + }, + { + .start = MPC85xx_IRQ_DMA3, + .end = MPC85xx_IRQ_DMA3, + .flags = IORESOURCE_IRQ, + }, + }, + }, + +}; + +static int +mpc85xx_update_paddr(struct device *dev, void *arg) +{ + phys_addr_t ccsrbar; + struct platform_device *pdev = to_platform_device(dev); + struct resource * r; + + /* xxx - this only gets ioresource_mem 0 */ + if (arg) { + ccsrbar = *(phys_addr_t *)arg; + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + r->start += ccsrbar; + r->end += ccsrbar; + } + return 0; +} + +static int __init mach_mpc85xx_init(void) +{ + phys_addr_t ccsr = CCSRBAR; + platform_device_register(&m_dev[MPC85xx_TSEC1]); +#if 0 + platform_device_register(&m_dev[MPC85xx_TSEC2]); + platform_device_register(&m_dev[MPC85xx_FEC]); +#endif + platform_device_register(&m_dev[MPC85xx_IIC1]); + platform_device_register(&m_dev[MPC85xx_DMA0]); + platform_device_register(&m_dev[MPC85xx_DMA1]); + platform_device_register(&m_dev[MPC85xx_DMA2]); + platform_device_register(&m_dev[MPC85xx_DMA3]); + + bus_for_each_dev(&platform_bus_type, NULL, &ccsr, mpc85xx_update_paddr); + return 0; +} + +subsys_initcall(mach_mpc85xx_init); + diff -Nru a/drivers/base/platform.c b/drivers/base/platform.c --- a/drivers/base/platform.c 2004-12-08 22:22:37 -06:00 +++ b/drivers/base/platform.c 2004-12-08 22:22:37 -06:00 @@ -58,6 +58,42 @@ } /** + * platform_get_resource_byname - get a resource for a device by name + * @dev: platform device + * @type: resource type + * @name: resource name + */ +struct resource * +platform_get_resource_byname(struct platform_device *dev, unsigned int type, + char * name) +{ + int i; + + for (i = 0; i < dev->num_resources; i++) { + struct resource *r = &dev->resource[i]; + + if ((r->flags & (IORESOURCE_IO|IORESOURCE_MEM| + IORESOURCE_IRQ|IORESOURCE_DMA)) + == type) + if (!strcmp(r->name, name)) + return r; + } + return NULL; +} + +/** + * platform_get_irq - get an IRQ for a device + * @dev: platform device + * @name: IRQ name + */ +int platform_get_irq_byname(struct platform_device *dev, char * name) +{ + struct resource *r = platform_get_resource_byname(dev, IORESOURCE_IRQ, name); + + return r ? r->start : 0; +} + +/** * platform_add_devices - add a numbers of platform devices * @devs: array of platform devices to add * @num: number of platform devices in array @@ -103,7 +139,8 @@ for (i = 0; i < pdev->num_resources; i++) { struct resource *p, *r = &pdev->resource[i]; - r->name = pdev->dev.bus_id; + if (r->name == NULL) + r->name = pdev->dev.bus_id; p = NULL; if (r->flags & IORESOURCE_MEM) @@ -308,3 +345,5 @@ EXPORT_SYMBOL_GPL(platform_device_unregister); EXPORT_SYMBOL_GPL(platform_get_irq); EXPORT_SYMBOL_GPL(platform_get_resource); +EXPORT_SYMBOL_GPL(platform_get_irq_byname); +EXPORT_SYMBOL_GPL(platform_get_resource_byname); diff -Nru a/drivers/net/gianfar.c b/drivers/net/gianfar.c --- a/drivers/net/gianfar.c 2004-12-08 22:22:37 -06:00 +++ b/drivers/net/gianfar.c 2004-12-08 22:22:37 -06:00 @@ -85,6 +85,7 @@ #include <linux/skbuff.h> #include <linux/spinlock.h> #include <linux/mm.h> +#include <linux/device.h> #include <asm/io.h> #include <asm/irq.h> @@ -93,6 +94,7 @@ #include <linux/version.h> #include <linux/dma-mapping.h> #include <linux/crc32.h> +#include <linux/fsl_devices.h> #include "gianfar.h" #include "gianfar_phy.h" @@ -130,8 +132,12 @@ static void adjust_link(struct net_device *dev); static void init_registers(struct net_device *dev); static int init_phy(struct net_device *dev); +#if 0 static int gfar_probe(struct ocp_device *ocpdev); static void gfar_remove(struct ocp_device *ocpdev); +#endif +static int gfar_probe(struct device *device); +static int gfar_remove(struct device *device); void free_skb_resources(struct gfar_private *priv); static void gfar_set_multi(struct net_device *dev); static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr); @@ -148,6 +154,7 @@ MODULE_DESCRIPTION("Gianfar Ethernet Driver"); MODULE_LICENSE("GPL"); +#if 0 /* Called by the ocp code to initialize device data structures * required for bringing up the device * returns 0 on success */ @@ -196,7 +203,7 @@ priv = netdev_priv(dev); /* Set the info in the priv to the current info */ - priv->einfo = einfo; + priv->einfo = pdev; /* get a pointer to the register memory */ priv->regs = (struct gfar *) @@ -343,6 +350,223 @@ iounmap((void *) priv->phyregs); free_netdev(dev); } +#endif + +static int gfar_probe(struct device *device) +{ + u32 tempval; + struct platform_device *mdiodev; + struct net_device *dev = NULL; + struct gfar_private *priv = NULL; + struct platform_device *pdev = to_platform_device(device); + struct gianfar_platform_data *pdinfo; + struct resource *r; + int idx; + int err = 0; + int dev_ethtool_ops = 0; + + pdinfo = (struct gianfar_platform_data *) pdev->dev.platform_data; + + if (pdinfo == NULL) { + printk(KERN_ERR "gfar %d: Missing additional data!\n", + pdev->id); + + return -ENODEV; + } + + /* get a pointer to the register memory which can + * configure the PHYs. If it's different from this set, + * get the device which has those regs */ + if ((pdinfo->phyregidx >= 0) && + (pdinfo->phyregidx != pdev->id)) { + + /* xxx - broken, gregkh tells me device_find has locking issues */ + /* only enable the 1st TSEC for now */ + struct device *d = device_find(pdinfo->phydevice, &platform_bus_type); + + mdiodev = to_platform_device(d); + + /* If the device which holds the MDIO regs isn't + * up, wait for it to come up */ + if (mdiodev == NULL) + return -EAGAIN; + } else { + mdiodev = pdev; + } + + /* Create an ethernet device instance */ + dev = alloc_etherdev(sizeof (*priv)); + + if (dev == NULL) + return -ENOMEM; + + priv = netdev_priv(dev); + + /* fill out IRQ fields */ + + if (pdev->flags & GFAR_HAS_MULTI_INTR) { + priv->interruptTransmit = platform_get_irq_byname(pdev, "tx"); + priv->interruptReceive = platform_get_irq_byname(pdev, "rx"); + priv->interruptError = platform_get_irq_byname(pdev, "error"); + } else { + priv->interruptTransmit = platform_get_irq(pdev, 0); + } + + /* Set the info in the priv to the current info */ + priv->einfo = pdev; + priv->pdinfo = pdinfo; + + /* get a pointer to the register memory */ + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + priv->regs = (struct gfar *) + ioremap(r->start, sizeof (struct gfar)); + + if (priv->regs == NULL) { + err = -ENOMEM; + goto regs_fail; + } + + /* Set the PHY base address */ + r = platform_get_resource(mdiodev, IORESOURCE_MEM, 0); + priv->phyregs = (struct gfar *) + ioremap(r->start, sizeof (struct gfar)); + + if (priv->phyregs == NULL) { + err = -ENOMEM; + goto phy_regs_fail; + } + + spin_lock_init(&priv->lock); + + dev_set_drvdata(device, dev); + + /* Stop the DMA engine now, in case it was running before */ + /* (The firmware could have used it, and left it running). */ + /* To do this, we write Graceful Receive Stop and Graceful */ + /* Transmit Stop, and then wait until the corresponding bits */ + /* in IEVENT indicate the stops have completed. */ + tempval = gfar_read(&priv->regs->dmactrl); + tempval &= ~(DMACTRL_GRS | DMACTRL_GTS); + gfar_write(&priv->regs->dmactrl, tempval); + + tempval = gfar_read(&priv->regs->dmactrl); + tempval |= (DMACTRL_GRS | DMACTRL_GTS); + gfar_write(&priv->regs->dmactrl, tempval); + + while (!(gfar_read(&priv->regs->ievent) & (IEVENT_GRSC | IEVENT_GTSC))) + cpu_relax(); + + /* Reset MAC layer */ + gfar_write(&priv->regs->maccfg1, MACCFG1_SOFT_RESET); + + tempval = (MACCFG1_TX_FLOW | MACCFG1_RX_FLOW); + gfar_write(&priv->regs->maccfg1, tempval); + + /* Initialize MACCFG2. */ + gfar_write(&priv->regs->maccfg2, MACCFG2_INIT_SETTINGS); + + /* Initialize ECNTRL */ + gfar_write(&priv->regs->ecntrl, ECNTRL_INIT_SETTINGS); + + /* Copy the station address into the dev structure, */ + memcpy(dev->dev_addr, pdinfo->mac_addr, MAC_ADDR_LEN); + + /* Set the dev->base_addr to the gfar reg region */ + dev->base_addr = (unsigned long) (priv->regs); + + SET_MODULE_OWNER(dev); + SET_NETDEV_DEV(dev, device); + + /* Fill in the dev structure */ + dev->open = gfar_enet_open; + dev->hard_start_xmit = gfar_start_xmit; + dev->tx_timeout = gfar_timeout; + dev->watchdog_timeo = TX_TIMEOUT; +#ifdef CONFIG_GFAR_NAPI + dev->poll = gfar_poll; + dev->weight = GFAR_DEV_WEIGHT; +#endif + dev->stop = gfar_close; + dev->get_stats = gfar_get_stats; + dev->change_mtu = gfar_change_mtu; + dev->mtu = 1500; + dev->set_multicast_list = gfar_set_multi; + + /* Index into the array of possible ethtool + * ops to catch all 4 possibilities */ + if((priv->einfo->flags & GFAR_HAS_RMON) == 0) + dev_ethtool_ops += 1; + + if((priv->einfo->flags & GFAR_HAS_COALESCE) == 0) + dev_ethtool_ops += 2; + + dev->ethtool_ops = gfar_op_array[dev_ethtool_ops]; + + priv->rx_buffer_size = DEFAULT_RX_BUFFER_SIZE; +#ifdef CONFIG_GFAR_BUFSTASH + priv->rx_stash_size = STASH_LENGTH; +#endif + priv->tx_ring_size = DEFAULT_TX_RING_SIZE; + priv->rx_ring_size = DEFAULT_RX_RING_SIZE; + + priv->txcoalescing = DEFAULT_TX_COALESCE; + priv->txcount = DEFAULT_TXCOUNT; + priv->txtime = DEFAULT_TXTIME; + priv->rxcoalescing = DEFAULT_RX_COALESCE; + priv->rxcount = DEFAULT_RXCOUNT; + priv->rxtime = DEFAULT_RXTIME; + + err = register_netdev(dev); + + if (err) { + printk(KERN_ERR "%s: Cannot register net device, aborting.\n", + dev->name); + goto register_fail; + } + + /* Print out the device info */ + printk(KERN_INFO DEVICE_NAME, dev->name); + for (idx = 0; idx < 6; idx++) + printk("%2.2x%c", dev->dev_addr[idx], idx == 5 ? ' ' : ':'); + printk("\n"); + + /* Even more device info helps when determining which kernel */ + /* provided which set of benchmarks. Since this is global for all */ + /* devices, we only print it once */ +#ifdef CONFIG_GFAR_NAPI + printk(KERN_INFO "%s: Running with NAPI enabled\n", dev->name); +#else + printk(KERN_INFO "%s: Running with NAPI disabled\n", dev->name); +#endif + printk(KERN_INFO "%s: %d/%d RX/TX BD ring size\n", + dev->name, priv->rx_ring_size, priv->tx_ring_size); + + return 0; + +register_fail: + iounmap((void *) priv->phyregs); +phy_regs_fail: + iounmap((void *) priv->regs); +regs_fail: + free_netdev(dev); + return -ENOMEM; + return 0; +} + +static int gfar_remove(struct device *device) +{ + struct net_device *dev = dev_get_drvdata(device); + struct gfar_private *priv = netdev_priv(dev); + + dev_set_drvdata(device, NULL); + + iounmap((void *) priv->regs); + iounmap((void *) priv->phyregs); + free_netdev(dev); + + return 0; +} + /* Configure the PHY for dev. * returns 0 if success. -1 if failure @@ -381,7 +605,7 @@ ADVERTISED_1000baseT_Full); mii_info->autoneg = 1; - mii_info->mii_id = priv->einfo->phyid; + mii_info->mii_id = priv->pdinfo->phyid; mii_info->dev = dev; @@ -549,15 +773,15 @@ /* Free the IRQs */ if (priv->einfo->flags & GFAR_HAS_MULTI_INTR) { - free_irq(priv->einfo->interruptError, dev); - free_irq(priv->einfo->interruptTransmit, dev); - free_irq(priv->einfo->interruptReceive, dev); + free_irq(priv->interruptError, dev); + free_irq(priv->interruptTransmit, dev); + free_irq(priv->interruptReceive, dev); } else { - free_irq(priv->einfo->interruptTransmit, dev); + free_irq(priv->interruptTransmit, dev); } if (priv->einfo->flags & GFAR_HAS_PHY_INTR) { - free_irq(priv->einfo->interruptPHY, dev); + free_irq(priv->pdinfo->interruptPHY, dev); } else { del_timer_sync(&priv->phy_info_timer); } @@ -730,38 +954,38 @@ if (priv->einfo->flags & GFAR_HAS_MULTI_INTR) { /* Install our interrupt handlers for Error, * Transmit, and Receive */ - if (request_irq(priv->einfo->interruptError, gfar_error, + if (request_irq(priv->interruptError, gfar_error, 0, "enet_error", dev) < 0) { printk(KERN_ERR "%s: Can't get IRQ %d\n", - dev->name, priv->einfo->interruptError); + dev->name, priv->interruptError); err = -1; goto err_irq_fail; } - if (request_irq(priv->einfo->interruptTransmit, gfar_transmit, + if (request_irq(priv->interruptTransmit, gfar_transmit, 0, "enet_tx", dev) < 0) { printk(KERN_ERR "%s: Can't get IRQ %d\n", - dev->name, priv->einfo->interruptTransmit); + dev->name, priv->interruptTransmit); err = -1; goto tx_irq_fail; } - if (request_irq(priv->einfo->interruptReceive, gfar_receive, + if (request_irq(priv->interruptReceive, gfar_receive, 0, "enet_rx", dev) < 0) { printk(KERN_ERR "%s: Can't get IRQ %d (receive0)\n", - dev->name, priv->einfo->interruptReceive); + dev->name, priv->interruptReceive); err = -1; goto rx_irq_fail; } } else { - if (request_irq(priv->einfo->interruptTransmit, gfar_interrupt, + if (request_irq(priv->interruptTransmit, gfar_interrupt, 0, "gfar_interrupt", dev) < 0) { printk(KERN_ERR "%s: Can't get IRQ %d\n", - dev->name, priv->einfo->interruptError); + dev->name, priv->interruptError); err = -1; goto err_irq_fail; @@ -815,9 +1039,9 @@ return 0; rx_irq_fail: - free_irq(priv->einfo->interruptTransmit, dev); + free_irq(priv->interruptTransmit, dev); tx_irq_fail: - free_irq(priv->einfo->interruptError, dev); + free_irq(priv->interruptError, dev); err_irq_fail: rx_skb_fail: free_skb_resources(priv); @@ -1548,14 +1772,14 @@ /* Grab the PHY interrupt, if necessary/possible */ if (priv->einfo->flags & GFAR_HAS_PHY_INTR) { - if (request_irq(priv->einfo->interruptPHY, + if (request_irq(priv->pdinfo->interruptPHY, phy_interrupt, SA_SHIRQ, "phy_interrupt", mii_info->dev) < 0) { printk(KERN_ERR "%s: Can't get IRQ %d (PHY)\n", mii_info->dev->name, - priv->einfo->interruptPHY); + priv->pdinfo->interruptPHY); } else { mii_configure_phy_interrupt(priv->mii_info, MII_INTERRUPT_ENABLED); @@ -1828,6 +2052,7 @@ return IRQ_HANDLED; } +#if 0 /* Structure for a device driver */ static struct ocp_device_id gfar_ids[] = { {.vendor = OCP_ANY_ID,.function = OCP_FUNC_GFAR}, @@ -1862,3 +2087,26 @@ module_init(gfar_init); module_exit(gfar_exit); +#endif + +/* Structure for a device driver */ +static struct device_driver gfar_driver = { + .name = "fsl-gianfar", + .bus = &platform_bus_type, + .probe = gfar_probe, + .remove = gfar_remove, +}; + +static int __init gfar_init(void) +{ + return driver_register(&gfar_driver); +} + +static void __exit gfar_exit(void) +{ + driver_unregister(&gfar_driver); +} + +module_init(gfar_init); +module_exit(gfar_exit); + diff -Nru a/drivers/net/gianfar.h b/drivers/net/gianfar.h --- a/drivers/net/gianfar.h 2004-12-08 22:22:37 -06:00 +++ b/drivers/net/gianfar.h 2004-12-08 22:22:37 -06:00 @@ -510,7 +510,11 @@ unsigned int rxclean; /* Info structure initialized by board setup code */ - struct ocp_gfar_data *einfo; + unsigned int interruptTransmit; + unsigned int interruptReceive; + unsigned int interruptError; + struct platform_device *einfo; + struct gianfar_platform_data *pdinfo; struct gfar_mii_info *mii_info; int oldspeed; diff -Nru a/include/asm-ppc/mpc85xx.h b/include/asm-ppc/mpc85xx.h --- a/include/asm-ppc/mpc85xx.h 2004-12-08 22:22:37 -06:00 +++ b/include/asm-ppc/mpc85xx.h 2004-12-08 22:22:37 -06:00 @@ -103,6 +103,14 @@ #define MPC85xx_CPM_SIZE (0x40000) #define MPC85xx_DMA_OFFSET (0x21000) #define MPC85xx_DMA_SIZE (0x01000) +#define MPC85xx_DMA0_OFFSET (0x21100) +#define MPC85xx_DMA0_SIZE (0x00080) +#define MPC85xx_DMA1_OFFSET (0x21180) +#define MPC85xx_DMA1_SIZE (0x00080) +#define MPC85xx_DMA2_OFFSET (0x21200) +#define MPC85xx_DMA2_SIZE (0x00080) +#define MPC85xx_DMA3_OFFSET (0x21280) +#define MPC85xx_DMA3_SIZE (0x00080) #define MPC85xx_ENET1_OFFSET (0x24000) #define MPC85xx_ENET1_SIZE (0x01000) #define MPC85xx_ENET2_OFFSET (0x25000) @@ -138,6 +146,17 @@ #else #define CCSRBAR BOARD_CCSRBAR #endif + +enum mpc85xx_devices { + MPC85xx_TSEC1, + MPC85xx_TSEC2, + MPC85xx_FEC, + MPC85xx_IIC1, + MPC85xx_DMA0, + MPC85xx_DMA1, + MPC85xx_DMA2, + MPC85xx_DMA3, +}; #endif /* CONFIG_85xx */ #endif /* __ASM_MPC85xx_H__ */ diff -Nru a/include/linux/device.h b/include/linux/device.h --- a/include/linux/device.h 2004-12-08 22:22:37 -06:00 +++ b/include/linux/device.h 2004-12-08 22:22:37 -06:00 @@ -370,6 +370,7 @@ struct device dev; u32 num_resources; struct resource * resource; + u32 flags; }; #define to_platform_device(x) container_of((x), struct platform_device, dev) @@ -382,6 +383,8 @@ extern struct resource *platform_get_resource(struct platform_device *, unsigned int, unsigned int); extern int platform_get_irq(struct platform_device *, unsigned int); +extern struct resource *platform_get_resource_byname(struct platform_device *, unsigned int, char *); +extern int platform_get_irq_byname(struct platform_device *, char *); extern int platform_add_devices(struct platform_device **, int); extern struct platform_device *platform_device_register_simple(char *, unsigned int, struct resource *, unsigned int); diff -Nru a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/include/linux/fsl_devices.h 2004-12-08 22:22:37 -06:00 @@ -0,0 +1,48 @@ +/* + * include/linux/fsl_devices.h + * + * Definitions for any platform device related flags or structures for + * Freescale processor devices + * + * Maintainer: Kumar Gala (kumar.gala at freescale.com) + * + * Copyright 2004 Freescale Semiconductor, Inc + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifdef __KERNEL__ +#ifndef _FSL_DEVICE_H_ +#define _FSL_DEVICE_H_ + +/* A table of information for supporting the Gianfar Ethernet Controller + * This helps identify which enet controller we are dealing with, + * and what type of enet controller it is + */ +struct gianfar_platform_data { + u32 flags; + u32 phyid; + uint interruptPHY; + uint phyregidx; + char * phydevice; + unsigned char mac_addr[6]; +}; + +/* Flags related to gianfar device features */ +#define GIANFAR_HAS_GIGABIT 0x00000001 +#define GIANFAR_HAS_COALESCE 0x00000002 +#define GIANFAR_HAS_RMON 0x00000004 +#define GIANFAR_HAS_MULTI_INTR 0x00000008 + +/* Flags in gianfar_platform_data */ +#define GIANFAR_PDATA_HAS_PHY_INTR 0x00000001 /* if not set use a timer */ + +/* Flags related to I2C device features */ +#define FSL_I2C_SEPARATE_DFSRR 0x00000001 +#define FSL_I2C_CLOCK_5200 0x00000002 + +#endif /* _FSL_DEVICE_H_ */ +#endif /* __KERNEL__ */ ------------------------------ _______________________________________________ Linuxppc-embedded mailing list Linuxppc-embedded at ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-embedded End of Linuxppc-embedded Digest, Vol 4, Issue 13 ************************************************ ********************************DISCLAIMER********************************** This e-mail and any attachment is for authorised use by the intended recipient(s) only. It may contain proprietary material, confidential information and/or be subject to legal privilege of Deccanet Designs Ltd. If you have received this message in error, please notify the originator immediately. If you are not the intended recipient, you are notified that you are strictly prohibited from retaining, using, copying, altering or disclosing the contents of this message. ****************************************************************************