gumstix ethernet smc911x

2 messages Options
Embed this post
Permalink
Harald Roeck

gumstix ethernet smc911x

Reply Threaded More More options
Print post
Permalink
Is it possible do get the new gumstix ethernet module working inside
oklinux? Running linux native we used the smc911x driver. I tried to
port the gumstix smc911x driver to oklinux and got it to compile and
boot (see attached patch file). however, the driver is not getting any
interrupts. I noticed the following warning when oklinux boots:

No IRQF_TRIGGER set_type function for IRQ 66 (iguana)

The eth0 interrupt is registered at IRQ 66, see:
/ # cat /proc/interrupts
 22:        178          iguana  FFUART
 25:          0          iguana  DMA
 27:        757          iguana  ost1
 52:          0          iguana  cell
 66:          0          iguana  eth0

fyi: I'm running OKL4 3.0 on a gumstix verdex with the netwifimicrosd
daughter board.

thanks,
-Harald

[fix-smc911.patch]

diff --git a/linux/kernel-2.6.24-v2/drivers/net/smc911x.c b/linux/kernel-2.6.24-v2/drivers/net/smc911x.c
--- a/linux/kernel-2.6.24-v2/drivers/net/smc911x.c
+++ b/linux/kernel-2.6.24-v2/drivers/net/smc911x.c
@@ -27,32 +27,13 @@
  * History:
  *  04/16/05 Dustin McIntire Initial version
  */
+
 static const char version[] =
  "smc911x.c: v1.0 04-16-2005 by Dustin McIntire <[hidden email]>\n";
 
-/* Debugging options */
-#define ENABLE_SMC_DEBUG_RX 0
-#define ENABLE_SMC_DEBUG_TX 0
-#define ENABLE_SMC_DEBUG_DMA 0
-#define ENABLE_SMC_DEBUG_PKTS 0
-#define ENABLE_SMC_DEBUG_MISC 0
-#define ENABLE_SMC_DEBUG_FUNC 0
-
-#define SMC_DEBUG_RX ((ENABLE_SMC_DEBUG_RX ? 1 : 0) << 0)
-#define SMC_DEBUG_TX ((ENABLE_SMC_DEBUG_TX ? 1 : 0) << 1)
-#define SMC_DEBUG_DMA ((ENABLE_SMC_DEBUG_DMA ? 1 : 0) << 2)
-#define SMC_DEBUG_PKTS ((ENABLE_SMC_DEBUG_PKTS ? 1 : 0) << 3)
-#define SMC_DEBUG_MISC ((ENABLE_SMC_DEBUG_MISC ? 1 : 0) << 4)
-#define SMC_DEBUG_FUNC ((ENABLE_SMC_DEBUG_FUNC ? 1 : 0) << 5)
-
 #ifndef SMC_DEBUG
-#define SMC_DEBUG ( SMC_DEBUG_RX  | \
-   SMC_DEBUG_TX  | \
-   SMC_DEBUG_DMA  | \
-   SMC_DEBUG_PKTS | \
-   SMC_DEBUG_MISC | \
-   SMC_DEBUG_FUNC   \
- )
+#define SMC_DEBUG 0
+#define SMC_DEBUG_PKTS 0
 #endif
 
 #include <linux/init.h>
@@ -76,6 +57,7 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 
+#include <linux/irq.h>
 #include <asm/io.h>
 
 #include "smc911x.h"
@@ -295,14 +277,14 @@
  SMC_SET_AFC_CFG(lp->afc_cfg);
 
 
- /* Set to LED outputs */
- SMC_SET_GPIO_CFG(0x70070000);
+ /* Set to LED outputs and configure EEPROM pins as GP outputs */
+ SMC_SET_GPIO_CFG(GPIO_CFG_LED1_EN_ | GPIO_CFG_LED2_EN_ | 1 << 20);
 
  /*
- * Deassert IRQ for 1*10us for edge type interrupts
+ * Deassert IRQ for 22*10us for edge type interrupts
  * and drive IRQ pin push-pull
  */
- SMC_SET_IRQ_CFG( (1 << 24) | INT_CFG_IRQ_EN_ | INT_CFG_IRQ_TYPE_ );
+ SMC_SET_IRQ_CFG( (22 << 24) | INT_CFG_IRQ_EN_ | INT_CFG_IRQ_TYPE_ );
 
  /* clear anything saved */
  if (lp->pending_tx_skb != NULL) {
@@ -405,7 +387,7 @@
  if (fifo_count <= 4) {
  /* Manually dump the packet data */
  while (fifo_count--)
- SMC_GET_RX_FIFO();
+ (void)SMC_GET_RX_FIFO();
  } else {
  /* Fast forward through the bad packet */
  SMC_SET_RX_DP_CTRL(RX_DP_CTRL_FFWD_BUSY_);
@@ -891,6 +873,7 @@
  unsigned long ioaddr = dev->base_addr;
  unsigned int bmcr;
 
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
  /* Enter Link Disable state */
  SMC_GET_PHY_BMCR(phy, bmcr);
  bmcr |= BMCR_PDOWN;
@@ -916,6 +899,7 @@
 
  if (mii_check_media(&lp->mii, netif_msg_link(lp), init)) {
  /* duplex state has changed */
+ DBG(SMC_DEBUG_MISC, "%s: duplex state has changed\n", dev->name);
  SMC_GET_PHY_BMCR(phyaddr, bmcr);
  SMC_GET_MAC_CR(cr);
  if (lp->mii.full_duplex) {
@@ -951,6 +935,7 @@
  int my_phy_caps; /* My PHY capabilities */
  int my_ad_caps; /* My Advertised capabilities */
  int status;
+ int bmcr;
  unsigned long flags;
 
  DBG(SMC_DEBUG_FUNC, "%s: --> %s()\n", dev->name, __FUNCTION__);
@@ -1024,9 +1009,12 @@
 
  DBG(SMC_DEBUG_MISC, "%s: phy caps=0x%04x\n", dev->name, my_phy_caps);
  DBG(SMC_DEBUG_MISC, "%s: phy advertised caps=0x%04x\n", dev->name, my_ad_caps);
+ DBG(SMC_DEBUG_MISC, "%s: phy advertised readback caps=0x%04x\n", dev->name, status);
 
  /* Restart auto-negotiation process in order to advertise my caps */
- SMC_SET_PHY_BMCR(phyaddr, BMCR_ANENABLE | BMCR_ANRESTART);
+ SMC_GET_PHY_BMCR(phyaddr, bmcr);
+ bmcr |= BMCR_ANENABLE | BMCR_ANRESTART;
+ SMC_SET_PHY_BMCR(phyaddr, bmcr);
 
  smc911x_phy_check_media(dev, 1);
 
@@ -1856,6 +1844,48 @@
  return probe_irq_off(cookie);
 }
 
+static inline unsigned int is_gumstix_oui(u8 *addr)
+{
+ return (addr[0] == 0x00 && addr[1] == 0x15 && addr[2] == 0xC9);
+}
+
+/**
+ * gen_serial_ether_addr - Generate software assigned Ethernet address
+ * based on the system_serial number
+ * @addr: Pointer to a six-byte array containing the Ethernet address
+ *
+ * Generate an Ethernet address (MAC) that is not multicast
+ * and has the local assigned bit set, keyed on the system_serial
+ */
+static inline void gen_serial_ether_addr(u8 *addr)
+{
+#ifdef CONFIG_CELL
+ addr [0] = 0x00;
+ addr [1] = 0x15;
+ addr [2] = 0xC9;
+ addr [3] = 0x83;
+ addr [4] = 0x82;
+ addr [5] = 0x81;
+#else
+ static u8 ether_serial_digit = 0;
+ addr [0] = system_serial_high >> 8;
+ addr [1] = system_serial_high;
+ addr [2] = system_serial_low >> 24;
+ addr [3] = system_serial_low >> 16;
+ addr [4] = system_serial_low >> 8;
+ addr [5] = (system_serial_low & 0xc0) | /* top bits are from system serial */
+ (1 << 4) | /* 2 bits identify interface type 1=ether, 2=usb, 3&4 undef */
+ ((ether_serial_digit++) & 0x0f); /* 15 possible interfaces of each type */
+#endif
+
+ if(!is_gumstix_oui(addr))
+ {
+ addr [0] &= 0xfe; /* clear multicast bit */
+ addr [0] |= 0x02; /* set local assignment bit (IEEE802) */
+ }
+}
+
+
 /*
  * Function: smc911x_probe(unsigned long ioaddr)
  *
@@ -2082,15 +2112,13 @@
 #endif
  printk("\n");
  if (!is_valid_ether_addr(dev->dev_addr)) {
- printk("%s: Invalid ethernet MAC address. Please "
- "set using ifconfig\n", dev->name);
- } else {
- /* Print the Ethernet address */
- printk("%s: Ethernet addr: ", dev->name);
- for (i = 0; i < 5; i++)
- printk("%2.2x:", dev->dev_addr[i]);
- printk("%2.2x\n", dev->dev_addr[5]);
+ gen_serial_ether_addr(dev->dev_addr);
  }
+ /* Print the Ethernet address */
+ printk("%s: Ethernet addr: ", dev->name);
+ for (i = 0; i < 5; i++)
+ printk("%2.2x:", dev->dev_addr[i]);
+ printk("%2.2x\n", dev->dev_addr[5]);
 
  if (lp->phy_type == 0) {
  PRINTK("%s: No PHY found\n", dev->name);
@@ -2265,8 +2293,15 @@
  },
 };
 
+#ifdef CONFIG_ARCH_GUMSTIX
+extern void gumstix_smc911x_load(void);
+#endif
+
 static int __init smc911x_init(void)
 {
+#ifdef CONFIG_ARCH_GUMSTIX
+ gumstix_smc911x_load();
+#endif
  return platform_driver_register(&smc911x_driver);
 }
 
diff --git a/linux/kernel-2.6.24-v2/drivers/net/smc911x.h b/linux/kernel-2.6.24-v2/drivers/net/smc911x.h
--- a/linux/kernel-2.6.24-v2/drivers/net/smc911x.h
+++ b/linux/kernel-2.6.24-v2/drivers/net/smc911x.h
@@ -33,7 +33,9 @@
  * Use the DMA feature on PXA chips
  */
 #ifdef CONFIG_ARCH_PXA
+#if !defined( CONFIG_SMC911X_GUMSTIX ) && !defined( CONFIG_SMC911X_GUMSTIX_MODULE )
   #define SMC_USE_PXA_DMA 1
+#endif
   #define SMC_USE_16BIT 0
   #define SMC_USE_32BIT 1
   #define SMC_IRQ_SENSE IRQF_TRIGGER_FALLING
@@ -52,13 +54,13 @@
 #if SMC_USE_16BIT
 #define SMC_inb(a, r) readb((a) + (r))
 #define SMC_inw(a, r) readw((a) + (r))
-#define SMC_inl(a, r) ((SMC_inw(a, r) & 0xFFFF)+(SMC_inw(a+2, r)<<16))
+#define SMC_inl(a, r) ((SMC_inw(a, r) & 0xFFFF)+(SMC_inw((a)+2, r)<<16))
 #define SMC_outb(v, a, r) writeb(v, (a) + (r))
 #define SMC_outw(v, a, r) writew(v, (a) + (r))
 #define SMC_outl(v, a, r) \
  do{ \
- writel(v & 0xFFFF, (a) + (r)); \
- writel(v >> 16, (a) + (r) + 2); \
+ writel((v) & 0xFFFF, (a) + (r)); \
+ writel((v) >> 16, (a) + (r) + 2); \
  } while (0)
 #define SMC_insl(a, r, p, l) readsw((short*)((a) + (r)), p, l*2)
 #define SMC_outsl(a, r, p, l) writesw((short*)((a) + (r)), p, l*2)
diff --git a/linux/kernel-2.6.24-v2/l4linux_config_gumstix_cell b/linux/kernel-2.6.24-v2/l4linux_config_gumstix_cell
--- a/linux/kernel-2.6.24-v2/l4linux_config_gumstix_cell
+++ b/linux/kernel-2.6.24-v2/l4linux_config_gumstix_cell
@@ -475,10 +475,12 @@
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 # CONFIG_AX88796 is not set
-CONFIG_SMC91X_GUMSTIX=y
-CONFIG_SMC91X=y
+CONFIG_SMC91X_GUMSTIX=n
+CONFIG_SMC91X=n
 # CONFIG_DM9000 is not set
-# CONFIG_SMC911X is not set
+CONFIG_SMC911X=y
+CONFIG_SMC911X_GUMSTIX=y
+
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
diff --git a/linux/kernel-2.6.24-v2/drivers/net/gumstix-smc911x.c b/linux/kernel-2.6.24-v2/drivers/net/gumstix-smc911x.c
new file mode 100644
--- /dev/null
+++ b/linux/kernel-2.6.24-v2/drivers/net/gumstix-smc911x.c
@@ -0,0 +1,209 @@
+/*
+ *  Gumstix SMC911x chip intialization driver
+ *
+ *  Author:     Craig Hughes
+ *  Created:    December 9, 2004
+ *  Copyright:  (C) 2004 Craig Hughes
+ *
+ * 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/module.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/mii.h>
+
+#include <asm/hardware.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/delay.h>
+
+#include <asm/arch/gumstix.h>
+
+#define SMC_DEBUG               9
+#include <asm/io.h>
+#include "smc911x.h"
+
+static struct resource gumstix_smc911x0_resources[] = {
+ [0] = {
+ .name = "smc911x-regs",
+#if defined(CONFIG_CELL)
+ .start  = 0x00000000,
+ .end    = 0x000fffff,
+#else
+ .start  = PXA_CS1_PHYS,
+ .end    = PXA_CS1_PHYS + 0x000fffff,
+#endif
+ .flags  = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start  = GUMSTIX_ETH0_IRQ,
+ .end    = GUMSTIX_ETH0_IRQ,
+ .flags  = IORESOURCE_IRQ,
+ },
+ [2] = {
+               .name   = "smc91x-dma",
+#if defined(CONFIG_CELL)
+               .start  = 0x00000000,
+               .end    = 0x000fffff,
+#else
+               .start  = PXA_CS1_DMA,
+               .end    = PXA_CS1_DMA + 0x000fffff,
+#endif
+               .flags  = IORESOURCE_DMA,
+       },
+};
+
+static struct resource gumstix_smc911x1_resources[] = {
+ [0] = {
+ .name = "smc911x-regs",
+#if defined(CONFIG_CELL)
+ .start = 0x00000000,
+ .end = 0x000fffff,
+#else
+ .start = PXA_CS2_PHYS,
+ .end = PXA_CS2_PHYS + 0x000fffff,
+#endif
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = GUMSTIX_ETH1_IRQ,
+ .end = GUMSTIX_ETH1_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+               .name   = "smc91x-dma",
+#if defined(CONFIG_CELL)
+               .start  = 0x00000000,
+               .end    = 0x000fffff,
+#else
+               .start  = PXA_CS1_DMA,
+               .end    = PXA_CS1_DMA + 0x000fffff,
+#endif
+               .flags  = IORESOURCE_DMA,
+       },
+};
+
+static struct platform_device gumstix_smc911x0_device = {
+ .name           = "smc911x",
+ .id             = 0,
+ .num_resources  = ARRAY_SIZE(gumstix_smc911x0_resources),
+ .resource       = gumstix_smc911x0_resources,
+};
+
+static struct platform_device gumstix_smc911x1_device = {
+ .name           = "smc911x",
+ .id             = 1,
+ .num_resources  = ARRAY_SIZE(gumstix_smc911x1_resources),
+ .resource       = gumstix_smc911x1_resources,
+};
+
+static struct platform_device *smc911x_devices[] = {
+ &gumstix_smc911x0_device,
+ &gumstix_smc911x1_device,
+};
+
+/* First we're going to test if there's a 2nd SMC911x, and if not, then we'll free up those resources and the GPIO lines
+ * that it would otherwise use.  We have no choice but to probe by doing:
+ * Set nCS2 to CS2 mode
+ * Set the reset line to GPIO out mode, and pull it high, then drop it low (to trigger reset)
+ * Read from the memory space to check for the sentinel sequence identifying a likely SMC911x device
+ */
+int __init gumstix_smc911x_init(void)
+{
+ unsigned int val, num_devices=ARRAY_SIZE(smc911x_devices);
+ void *ioaddr;
+ printk("%s\n", __FUNCTION__);
+#if defined(CONFIG_CELL)
+ gumstix_smc911x0_resources[0].start += PXA_CS1_PHYS;
+ printk("start: %lx\n", gumstix_smc911x0_resources[0].start);
+ gumstix_smc911x0_resources[0].end += PXA_CS1_PHYS;
+ gumstix_smc911x1_resources[0].start += PXA_CS2_PHYS;
+ gumstix_smc911x1_resources[0].end += PXA_CS2_PHYS;
+
+ gumstix_smc911x0_resources[2].start += PXA_CS1_DMA;
+ gumstix_smc911x0_resources[2].end += PXA_CS1_DMA;
+ gumstix_smc911x1_resources[2].start += PXA_CS2_DMA;
+ gumstix_smc911x1_resources[2].end += PXA_CS2_DMA;
+#endif
+
+ printk("%s %d\n", __FILE__, __LINE__);
+
+ /* Set up nPWE */
+ pxa_gpio_mode(GPIO49_nPWE_MD);
+
+ pxa_gpio_mode(GPIO78_nCS_2_MD);
+ // If either if statement fails, then we'll drop out and turn_off_eth1,
+ // if both succeed, then we'll skip that and just proceed with 2 cards
+ printk("%s %d\n", __FILE__, __LINE__);
+#if 0 /* do not check for second network interface */
+ if(request_mem_region(gumstix_smc911x1_resources[1].start, SMC911X_IO_EXTENT, "smc911x probe"))
+ {
+ printk("%s %d\n", __FILE__, __LINE__);
+ ioaddr = ioremap(gumstix_smc911x1_resources[1].start, SMC911X_IO_EXTENT);
+ printk("%s %d ioaddr 0x%p\n", __FILE__, __LINE__, ioaddr);
+ val = SMC_GET_PN();
+ printk("%s %d\n", __FILE__, __LINE__);
+ iounmap(ioaddr);
+ printk("%s %d\n", __FILE__, __LINE__);
+ release_mem_region(gumstix_smc911x1_resources[1].start, SMC911X_IO_EXTENT);
+ printk("%s %d\n", __FILE__, __LINE__);
+ if (CHIP_9115 == val ||
+ CHIP_9116 == val ||
+ CHIP_9117 == val ||
+ CHIP_9118 == val ) {
+ goto proceed;
+ }
+ printk("%s %d\n", __FILE__, __LINE__);
+ }
+#endif
+
+ printk("%s %d\n", __FILE__, __LINE__);
+turn_off_eth1:
+ // This is apparently not an SMC911x
+ // So, let's decrement the number of devices to request, and reset the GPIO lines to GPIO IN mode
+ num_devices--;
+ smc911x_devices[1] = NULL;
+ pxa_gpio_mode(78 | GPIO_IN);
+
+ printk("%s %d\n", __FILE__, __LINE__);
+proceed:
+ pxa_gpio_mode(GPIO15_nCS_1_MD);
+
+ if(smc911x_devices[1]) pxa_gpio_mode(GPIO_GUMSTIX_ETH1_RST_MD);
+ pxa_gpio_mode(GPIO_GUMSTIX_ETH0_RST_MD);
+
+ if(smc911x_devices[1]) GPCR(GPIO_GUMSTIX_ETH1_RST) = GPIO_bit(GPIO_GUMSTIX_ETH1_RST);
+ GPCR(GPIO_GUMSTIX_ETH0_RST) = GPIO_bit(GPIO_GUMSTIX_ETH0_RST);
+ msleep(500); // Hold RESET for at least 200µ
+
+ if(smc911x_devices[1]) GPSR(GPIO_GUMSTIX_ETH1_RST) = GPIO_bit(GPIO_GUMSTIX_ETH1_RST);
+ GPSR(GPIO_GUMSTIX_ETH0_RST) = GPIO_bit(GPIO_GUMSTIX_ETH0_RST);
+ msleep(50);
+
+ printk("%s %d\n", __FILE__, __LINE__);
+ return platform_add_devices(smc911x_devices, num_devices);
+}
+
+void __exit gumstix_smc911x_exit(void)
+{
+ if(smc911x_devices[1] != NULL) platform_device_unregister(&gumstix_smc911x1_device);
+ platform_device_unregister(&gumstix_smc911x0_device);
+}
+
+void gumstix_smc911x_load(void) {}
+EXPORT_SYMBOL(gumstix_smc911x_load);
+
+module_init(gumstix_smc911x_init);
+module_exit(gumstix_smc911x_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Craig Hughes <[hidden email]>");
+MODULE_DESCRIPTION("Gumstix board SMC911x chip initialization driver");
+MODULE_VERSION("1:0.1");


_______________________________________________
Developer mailing list
[hidden email]
https://lists.okl4.org/mailman/listinfo/developer
Harald Roeck

Re: gumstix ethernet smc911x

Reply Threaded More More options
Print post
Permalink
got the ethernet driver in wombat working. attached are two patch
files. a patch for OKL4 to get the additional registers of the PXA27x
cpus (i.e. gumstix verdex board). the second patch adds pxa27x support
and the smc911x driver to wombat.

regards,
-Harald

On Wed, Apr 15, 2009 at 3:22 PM, Harald Roeck <[hidden email]> wrote:

> Is it possible do get the new gumstix ethernet module working inside
> oklinux? Running linux native we used the smc911x driver. I tried to
> port the gumstix smc911x driver to oklinux and got it to compile and
> boot (see attached patch file). however, the driver is not getting any
> interrupts. I noticed the following warning when oklinux boots:
>
> No IRQF_TRIGGER set_type function for IRQ 66 (iguana)
>
> The eth0 interrupt is registered at IRQ 66, see:
> / # cat /proc/interrupts
>  22:        178          iguana  FFUART
>  25:          0          iguana  DMA
>  27:        757          iguana  ost1
>  52:          0          iguana  cell
>  66:          0          iguana  eth0
>
> fyi: I'm running OKL4 3.0 on a gumstix verdex with the netwifimicrosd
> daughter board.
>
> thanks,
> -Harald
>

[wombat_pxa270_smc911x.patch]

diff -r 4e814c1899b6 linux/kernel-2.6.24-v2/arch/l4/Kconfig
--- a/linux/kernel-2.6.24-v2/arch/l4/Kconfig Wed Apr 08 15:37:40 2009 +0200
+++ b/linux/kernel-2.6.24-v2/arch/l4/Kconfig Wed Apr 22 20:24:29 2009 +0200
@@ -328,15 +328,12 @@ bool "Generic PXA27x platform"
  select PXA27x
 
 config ARCH_GUMSTIX
-bool "Support for Gumstix platform"
- depends on PXA
+ bool "Gumstix Platform"
  select ARCH_PXA
- select PXA25x
- help
- Support for Gumstix
+
 
 config IBOX
-bool "Support for IBOX platform"
+ bool "Support for IBOX platform"
  depends on PXA
  select ARCH_PXA
  select PXA27x
@@ -350,6 +347,35 @@ bool "Support for PLEB2 platform"
  select PXA25x
  help
  Support for PLEB 2
+
+endchoice
+
+choice
+ depends on ARCH_GUMSTIX
+ prompt "Gumstix Platform Version"
+ default ARCH_GUMSTIX_F
+
+config ARCH_GUMSTIX_F
+ bool "Gumstix-F"
+ select PXA25x
+ help
+  The updated Gumstix basix and connex boards with 60-pin connector, and
+  waysmall systems using these boards, including ws-200ax and ws-400ax.
+
+config ARCH_GUMSTIX_ORIG
+ bool "Support for Gumstix platform"
+ depends on PXA
+ select ARCH_PXA
+ select PXA25x
+ help
+ Support for Gumstix
+
+config ARCH_GUMSTIX_VERDEX
+ bool "Support for Gumstix verdex platform"
+ depends on PXA
+ select PXA27x
+ help
+ Support for Gumstix verdex
 
 endchoice
 
@@ -548,4 +574,5 @@ config EARLY_PRINTK
  help
   Write kernel log output directly to L4 KDB.
 
+#source "drivers/gpio/Kconfig"
 endmenu
diff -r 4e814c1899b6 linux/kernel-2.6.24-v2/arch/l4/kernel/setup.c
--- a/linux/kernel-2.6.24-v2/arch/l4/kernel/setup.c Wed Apr 08 15:37:40 2009 +0200
+++ b/linux/kernel-2.6.24-v2/arch/l4/kernel/setup.c Wed Apr 22 20:24:29 2009 +0200
@@ -10,6 +10,7 @@
 #include <linux/init.h>
 #include <linux/utsname.h>
 #include <linux/console.h>
+#include <linux/module.h>
 #include <asm/page.h>
 #include <asm/tlbflush.h>
 #include <asm/setup.h>
@@ -123,6 +124,7 @@ void okl4_env_lookup_address(const char
  for (i = 0; i < segs->num_segments; i++) {
  if (segs->segments[i].segment == *seg) {
  *addr = segs->segments[i].virt_addr;
+ printk("found address %p for %s\n", addr, name);
  break;
  }
  }
@@ -250,10 +252,12 @@ setup_arch (char **command_line)
 #if defined(CONFIG_ARCH_GUMSTIX)
  {
  extern unsigned long GPIO_BASE, DMAC_BASE;
+ extern unsigned long PXA_CS0_PHYS;
  extern unsigned long PXA_CS1_PHYS, PXA_CS1_DMA;
  extern unsigned long PXA_CS2_PHYS, PXA_CS2_DMA;
  okl4_env_lookup_address("MAIN_GPIO_MEM0", &GPIO_BASE);
  okl4_env_lookup_address("MAIN_DMA_MEM0", &DMAC_BASE);
+ okl4_env_lookup_address("MAIN_CS_MEM0", &PXA_CS0_PHYS);
  okl4_env_lookup_address("MAIN_CS_MEM1", &PXA_CS1_PHYS);
  okl4_env_lookup_address("MAIN_CS_MEM2", &PXA_CS2_PHYS);
 
@@ -273,10 +277,18 @@ unsigned long KMI0_BASE;
 unsigned long KMI0_BASE;
 unsigned long KMI1_BASE;
 unsigned long GPIO_BASE;
+EXPORT_SYMBOL(GPIO_BASE);
 unsigned long DMAC_BASE;
+EXPORT_SYMBOL(DMAC_BASE);
 unsigned long VERSATILE_SYS_BASE;
+unsigned long PXA_CS0_PHYS;
+EXPORT_SYMBOL(PXA_CS0_PHYS);
 unsigned long PXA_CS1_PHYS;
+EXPORT_SYMBOL(PXA_CS1_PHYS);
 unsigned long PXA_CS2_PHYS;
+EXPORT_SYMBOL(PXA_CS2_PHYS);
 unsigned long PXA_CS1_DMA;
+EXPORT_SYMBOL(PXA_CS1_DMA);
 unsigned long PXA_CS2_DMA;
+EXPORT_SYMBOL(PXA_CS2_DMA);
 #endif
diff -r 4e814c1899b6 linux/kernel-2.6.24-v2/arch/l4/kernel/syms.c
--- a/linux/kernel-2.6.24-v2/arch/l4/kernel/syms.c Wed Apr 08 15:37:40 2009 +0200
+++ b/linux/kernel-2.6.24-v2/arch/l4/kernel/syms.c Wed Apr 22 20:24:29 2009 +0200
@@ -1,8 +1,10 @@
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/highmem.h>
+#include <linux/delay.h>
 
 #include <asm/uaccess.h>
+#include <asm/io.h>
 
 #include <l4/ipc.h>
 #include "assert.h"
@@ -47,14 +49,56 @@ EXPORT_SYMBOL(memsection_register_server
 EXPORT_SYMBOL(memsection_register_server);
 #endif
 
+ /* io */
+#ifndef __raw_readsb
+EXPORT_SYMBOL(__raw_readsb);
+#endif
+#ifndef __raw_readsw
+EXPORT_SYMBOL(__raw_readsw);
+#endif
+#ifndef __raw_readsl
+EXPORT_SYMBOL(__raw_readsl);
+#endif
+#ifndef __raw_writesb
+EXPORT_SYMBOL(__raw_writesb);
+#endif
+#ifndef __raw_writesw
+EXPORT_SYMBOL(__raw_writesw);
+#endif
+#ifndef __raw_writesl
+EXPORT_SYMBOL(__raw_writesl);
+#endif
+
 #ifdef CONFIG_AEABI
 /*
  * Needed for modules
  */
 extern void *__aeabi_idivmod;
+EXPORT_SYMBOL(__aeabi_idivmod);
 
-EXPORT_SYMBOL(__aeabi_idivmod);
+extern void *__aeabi_uidivmod;
+EXPORT_SYMBOL(__aeabi_uidivmod);
+
+extern void __aeabi_idiv(void);
+EXPORT_SYMBOL(__aeabi_idiv);
+
+extern void __aeabi_uidiv(void);
+EXPORT_SYMBOL(__aeabi_uidiv);
 #endif
+
+EXPORT_SYMBOL(__udelay);
+EXPORT_SYMBOL(__const_udelay);
+
+ /* bitops */
+EXPORT_SYMBOL(_set_bit_le);
+EXPORT_SYMBOL(_test_and_set_bit_le);
+EXPORT_SYMBOL(_clear_bit_le);
+EXPORT_SYMBOL(_test_and_clear_bit_le);
+EXPORT_SYMBOL(_change_bit_le);
+EXPORT_SYMBOL(_find_first_zero_bit_le);
+EXPORT_SYMBOL(_find_next_zero_bit_le);
+EXPORT_SYMBOL(_find_first_bit_le);
+EXPORT_SYMBOL(_find_next_bit_le);
 
 /*
  * Because we don't use OKL4 libc we need to do this to force
diff -r 4e814c1899b6 linux/kernel-2.6.24-v2/arch/l4/lib/Makefile
--- a/linux/kernel-2.6.24-v2/arch/l4/lib/Makefile Wed Apr 08 15:37:40 2009 +0200
+++ b/linux/kernel-2.6.24-v2/arch/l4/lib/Makefile Wed Apr 22 20:24:29 2009 +0200
@@ -1,3 +1,3 @@ obj-y := assert.o
-obj-y := assert.o
+obj-y := assert.o io-readsb.o
 obj-y += oklibs/
 obj-$(CONFIG_NET) += checksum.o
diff -r 4e814c1899b6 linux/kernel-2.6.24-v2/arch/l4/lib/io-readsb.S
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/linux/kernel-2.6.24-v2/arch/l4/lib/io-readsb.S Wed Apr 22 20:24:29 2009 +0200
@@ -0,0 +1,122 @@
+/*
+ *  linux/arch/arm/lib/io-readsb.S
+ *
+ *  Copyright (C) 1995-2000 Russell King
+ *
+ * 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/linkage.h>
+#include INC_SYSTEM(assembler.h)
+
+.Linsb_align: rsb ip, ip, #4
+ cmp ip, r2
+ movgt ip, r2
+ cmp ip, #2
+ ldrb r3, [r0]
+ strb r3, [r1], #1
+ ldrgeb r3, [r0]
+ strgeb r3, [r1], #1
+ ldrgtb r3, [r0]
+ strgtb r3, [r1], #1
+ subs r2, r2, ip
+ bne .Linsb_aligned
+
+ENTRY(__raw_readsb)
+ teq r2, #0 @ do we have to check for the zero len?
+ moveq pc, lr
+ ands ip, r1, #3
+ bne .Linsb_align
+
+.Linsb_aligned: stmfd sp!, {r4 - r6, lr}
+
+ subs r2, r2, #16
+ bmi .Linsb_no_16
+
+.Linsb_16_lp: ldrb r3, [r0]
+ ldrb r4, [r0]
+ ldrb r5, [r0]
+ mov r3, r3,     put_byte_0
+ ldrb r6, [r0]
+ orr r3, r3, r4, put_byte_1
+ ldrb r4, [r0]
+ orr r3, r3, r5, put_byte_2
+ ldrb r5, [r0]
+ orr r3, r3, r6, put_byte_3
+ ldrb r6, [r0]
+ mov r4, r4,     put_byte_0
+ ldrb ip, [r0]
+ orr r4, r4, r5, put_byte_1
+ ldrb r5, [r0]
+ orr r4, r4, r6, put_byte_2
+ ldrb r6, [r0]
+ orr r4, r4, ip, put_byte_3
+ ldrb ip, [r0]
+ mov r5, r5,     put_byte_0
+ ldrb lr, [r0]
+ orr r5, r5, r6, put_byte_1
+ ldrb r6, [r0]
+ orr r5, r5, ip, put_byte_2
+ ldrb ip, [r0]
+ orr r5, r5, lr, put_byte_3
+ ldrb lr, [r0]
+ mov r6, r6,     put_byte_0
+ orr r6, r6, ip, put_byte_1
+ ldrb ip, [r0]
+ orr r6, r6, lr, put_byte_2
+ orr r6, r6, ip, put_byte_3
+ stmia r1!, {r3 - r6}
+
+ subs r2, r2, #16
+ bpl .Linsb_16_lp
+
+ tst r2, #15
+ ldmeqfd sp!, {r4 - r6, pc}
+
+.Linsb_no_16: tst r2, #8
+ beq .Linsb_no_8
+
+ ldrb r3, [r0]
+ ldrb r4, [r0]
+ ldrb r5, [r0]
+ mov r3, r3,     put_byte_0
+ ldrb r6, [r0]
+ orr r3, r3, r4, put_byte_1
+ ldrb r4, [r0]
+ orr r3, r3, r5, put_byte_2
+ ldrb r5, [r0]
+ orr r3, r3, r6, put_byte_3
+ ldrb r6, [r0]
+ mov r4, r4,     put_byte_0
+ ldrb ip, [r0]
+ orr r4, r4, r5, put_byte_1
+ orr r4, r4, r6, put_byte_2
+ orr r4, r4, ip, put_byte_3
+ stmia r1!, {r3, r4}
+
+.Linsb_no_8: tst r2, #4
+ beq .Linsb_no_4
+
+ ldrb r3, [r0]
+ ldrb r4, [r0]
+ ldrb r5, [r0]
+ ldrb r6, [r0]
+ mov r3, r3,     put_byte_0
+ orr r3, r3, r4, put_byte_1
+ orr r3, r3, r5, put_byte_2
+ orr r3, r3, r6, put_byte_3
+ str r3, [r1], #4
+
+.Linsb_no_4: ands r2, r2, #3
+ ldmeqfd sp!, {r4 - r6, pc}
+
+ cmp r2, #2
+ ldrb r3, [r0]
+ strb r3, [r1], #1
+ ldrgeb r3, [r0]
+ strgeb r3, [r1], #1
+ ldrgtb r3, [r0]
+ strgtb r3, [r1]
+
+ ldmfd sp!, {r4 - r6, pc}
diff -r 4e814c1899b6 linux/kernel-2.6.24-v2/arch/l4/mm/ioremap.c
--- a/linux/kernel-2.6.24-v2/arch/l4/mm/ioremap.c Wed Apr 08 15:37:40 2009 +0200
+++ b/linux/kernel-2.6.24-v2/arch/l4/mm/ioremap.c Wed Apr 22 20:24:29 2009 +0200
@@ -119,6 +119,7 @@ return (void __iomem *) (offset + phys_a
 
  return (void __iomem *) (offset + (char __iomem *)addr);
 }
+EXPORT_SYMBOL(__ioremap);
 
 /*
  * As per ioremap, but ensures that it is uncached.
@@ -217,4 +218,5 @@ void iounmap(volatile void __iomem *addr
 #endif /*CONFIG_CELL*/
  return;
 }
+EXPORT_SYMBOL(iounmap);
 
diff -r 4e814c1899b6 linux/kernel-2.6.24-v2/arch/l4/sys-arm/io.c
--- a/linux/kernel-2.6.24-v2/arch/l4/sys-arm/io.c Wed Apr 08 15:37:40 2009 +0200
+++ b/linux/kernel-2.6.24-v2/arch/l4/sys-arm/io.c Wed Apr 22 20:24:29 2009 +0200
@@ -1,6 +1,7 @@
 #include <l4.h>
 
 
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 
@@ -45,6 +46,7 @@ void _memcpy_fromio(void *to, unsigned l
  from++;
  }
 }
+EXPORT_SYMBOL(_memcpy_fromio);
 
 /*
  * Copy data from "real" memory space to IO memory space.
@@ -60,6 +62,7 @@ void _memcpy_toio(unsigned long to, cons
  to++;
  }
 }
+EXPORT_SYMBOL(_memcpy_toio);
 
 /*
  * "memset" on IO memory space.
diff -r 4e814c1899b6 linux/kernel-2.6.24-v2/arch/l4/sys-arm/mach-pxa/Makefile
--- a/linux/kernel-2.6.24-v2/arch/l4/sys-arm/mach-pxa/Makefile Wed Apr 08 15:37:40 2009 +0200
+++ b/linux/kernel-2.6.24-v2/arch/l4/sys-arm/mach-pxa/Makefile Wed Apr 22 20:24:29 2009 +0200
@@ -2,7 +2,7 @@ obj-$(CONFIG_IGUANA) += generic.o
 obj-$(CONFIG_IGUANA) += generic.o
 obj-$(CONFIG_CELL) += generic.o time.o clock.o dma.o
 
-#obj-$(CONFIG_PXA27x) += pxa27x.o
+obj-$(CONFIG_PXA27x) += pxa27x.o
 obj-$(CONFIG_PXA25x) += pxa25x.o
 
 #obj-$(CONFIG_IBOX) += ibox.o
diff -r 4e814c1899b6 linux/kernel-2.6.24-v2/arch/l4/sys-arm/mach-pxa/pxa27x.c
--- a/linux/kernel-2.6.24-v2/arch/l4/sys-arm/mach-pxa/pxa27x.c Wed Apr 08 15:37:40 2009 +0200
+++ b/linux/kernel-2.6.24-v2/arch/l4/sys-arm/mach-pxa/pxa27x.c Wed Apr 22 20:24:29 2009 +0200
@@ -11,26 +11,35 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <asm/arch/pxa-regs.h>
 #include <linux/init.h>
-#include <linux/pm.h>
+#include <linux/suspend.h>
+#include <linux/platform_device.h>
 
 #include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/irqs.h>
+#include <asm/arch/pxa-regs.h>
+//#include <asm/arch/ohci.h>
+//#include <asm/arch/pm.h>
+#include <asm/arch/dma.h>
 
 #include "generic.h"
+#include "devices.h"
+#include "clock.h"
 
 /* Crystal clock: 13MHz */
 #define BASE_CLK 13000000
+
+#if 0 /*Disable stuff we don't need in OK Linux -cvs*/
 
 /*
  * Get the clock frequency as reflected by CCSR and the turbo flag.
  * We assume these values have been applied via a fcs.
  * If info is not 0 we also display the current settings.
  */
-unsigned int get_clk_frequency_khz( int info)
+unsigned int pxa27x_get_clk_frequency_khz(int info)
 {
  unsigned long ccsr, clkcfg;
  unsigned int l, L, m, M, n2, N, S;
@@ -40,13 +49,8 @@ unsigned int get_clk_frequency_khz( int
  cccr_a = CCCR & (1 << 25);
 
  /* Read clkcfg register: it has turbo, b, half-turbo (and f) */
-
- /* We can't do this because we're at user level in Wombat. I'm just
-   going to fudge it for the moment -- DS*/
- // asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) );
- clkcfg = 0x09;
-
- t  = clkcfg & (1 << 1);
+ asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) );
+ t  = clkcfg & (1 << 0);
  ht = clkcfg & (1 << 2);
  b  = clkcfg & (1 << 3);
 
@@ -78,7 +82,7 @@ unsigned int get_clk_frequency_khz( int
  * Return the current mem clock frequency in units of 10kHz as
  * reflected by CCCR[A], B, and L
  */
-unsigned int get_memclk_frequency_10khz(void)
+unsigned int pxa27x_get_memclk_frequency_10khz(void)
 {
  unsigned long ccsr, clkcfg;
  unsigned int l, L, m, M;
@@ -88,8 +92,7 @@ unsigned int get_memclk_frequency_10khz(
  cccr_a = CCCR & (1 << 25);
 
  /* Read clkcfg register: it has turbo, b, half-turbo (and f) */
- // asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) );
- clkcfg = 0x09;  
+ asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) );
  b = clkcfg & (1 << 3);
 
  l = ccsr & 0x1f;
@@ -104,7 +107,7 @@ unsigned int get_memclk_frequency_10khz(
 /*
  * Return the current LCD clock frequency in units of 10kHz as
  */
-unsigned int get_lcdclk_frequency_10khz(void)
+static unsigned int pxa27x_get_lcdclk_frequency_10khz(void)
 {
  unsigned long ccsr;
  unsigned int l, L, k, K;
@@ -120,6 +123,345 @@ unsigned int get_lcdclk_frequency_10khz(
  return (K / 10000);
 }
 
-EXPORT_SYMBOL(get_clk_frequency_khz);
-EXPORT_SYMBOL(get_memclk_frequency_10khz);
-EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
+static unsigned long clk_pxa27x_lcd_getrate(struct clk *clk)
+{
+ return pxa27x_get_lcdclk_frequency_10khz() * 10000;
+}
+
+static const struct clkops clk_pxa27x_lcd_ops = {
+ .enable = clk_cken_enable,
+ .disable = clk_cken_disable,
+ .getrate = clk_pxa27x_lcd_getrate,
+};
+#endif
+
+#if defined(CONFIG_CELL)
+
+static struct clk pxa27x_clks[] = {
+// INIT_CK("LCDCLK", LCD,    &clk_pxa27x_lcd_ops, &pxa_device_fb.dev),
+// INIT_CK("CAMCLK", CAMERA, &clk_pxa27x_lcd_ops, NULL),
+
+ INIT_CKEN("UARTCLK", FFUART, 14857000, 1, &pxa_device_ffuart.dev),
+// INIT_CKEN("UARTCLK", BTUART, 14857000, 1, &pxa_device_btuart.dev),
+// INIT_CKEN("UARTCLK", STUART, 14857000, 1, NULL),
+
+// INIT_CKEN("I2SCLK",  I2S,  14682000, 0, &pxa_device_i2s.dev),
+// INIT_CKEN("I2CCLK",  I2C,  32842000, 0, &pxa_device_i2c.dev),
+// INIT_CKEN("UDCCLK",  USB,  48000000, 5, &pxa_device_udc.dev),
+// INIT_CKEN("MMCCLK",  MMC,  19500000, 0, &pxa_device_mci.dev),
+// INIT_CKEN("FICPCLK", FICP, 48000000, 0, &pxa_device_ficp.dev),
+
+// INIT_CKEN("USBCLK", USBHOST, 48000000, 0, &pxa27x_device_ohci.dev),
+// INIT_CKEN("I2CCLK", PWRI2C, 13000000, 0, &pxa27x_device_i2c_power.dev),
+// INIT_CKEN("KBDCLK", KEYPAD, 32768, 0, NULL),
+
+ /*
+ INIT_CKEN("PWMCLK",  PWM0, 13000000, 0, NULL),
+ INIT_CKEN("SSPCLK",  SSP1, 13000000, 0, NULL),
+ INIT_CKEN("SSPCLK",  SSP2, 13000000, 0, NULL),
+ INIT_CKEN("SSPCLK",  SSP3, 13000000, 0, NULL),
+ INIT_CKEN("MSLCLK",  MSL,  48000000, 0, NULL),
+ INIT_CKEN("USIMCLK", USIM, 48000000, 0, NULL),
+ INIT_CKEN("MSTKCLK", MEMSTK, 19500000, 0, NULL),
+ INIT_CKEN("IMCLK",   IM,   0, 0, NULL),
+ INIT_CKEN("MEMCLK",  MEMC, 0, 0, NULL),
+ */
+};
+
+#ifdef CONFIG_PM
+
+#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
+#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x]
+
+#define RESTORE_GPLEVEL(n) do { \
+ GPSR##n = sleep_save[SLEEP_SAVE_GPLR##n]; \
+ GPCR##n = ~sleep_save[SLEEP_SAVE_GPLR##n]; \
+} while (0)
+
+/*
+ * List of global PXA peripheral registers to preserve.
+ * More ones like CP and general purpose register values are preserved
+ * with the stack pointer in sleep.S.
+ */
+enum { SLEEP_SAVE_START = 0,
+
+ SLEEP_SAVE_GPLR0, SLEEP_SAVE_GPLR1, SLEEP_SAVE_GPLR2, SLEEP_SAVE_GPLR3,
+ SLEEP_SAVE_GPDR0, SLEEP_SAVE_GPDR1, SLEEP_SAVE_GPDR2, SLEEP_SAVE_GPDR3,
+ SLEEP_SAVE_GRER0, SLEEP_SAVE_GRER1, SLEEP_SAVE_GRER2, SLEEP_SAVE_GRER3,
+ SLEEP_SAVE_GFER0, SLEEP_SAVE_GFER1, SLEEP_SAVE_GFER2, SLEEP_SAVE_GFER3,
+ SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, SLEEP_SAVE_PGSR3,
+
+ SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U,
+ SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR1_U,
+ SLEEP_SAVE_GAFR2_L, SLEEP_SAVE_GAFR2_U,
+ SLEEP_SAVE_GAFR3_L, SLEEP_SAVE_GAFR3_U,
+
+ SLEEP_SAVE_PSTR,
+
+ SLEEP_SAVE_ICMR,
+ SLEEP_SAVE_CKEN,
+
+ SLEEP_SAVE_MDREFR,
+ SLEEP_SAVE_PWER, SLEEP_SAVE_PCFR, SLEEP_SAVE_PRER,
+ SLEEP_SAVE_PFER, SLEEP_SAVE_PKWR,
+
+ SLEEP_SAVE_SIZE
+};
+
+void pxa27x_cpu_pm_save(unsigned long *sleep_save)
+{
+ SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2); SAVE(GPLR3);
+ SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2); SAVE(GPDR3);
+ SAVE(GRER0); SAVE(GRER1); SAVE(GRER2); SAVE(GRER3);
+ SAVE(GFER0); SAVE(GFER1); SAVE(GFER2); SAVE(GFER3);
+ SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); SAVE(PGSR3);
+
+ SAVE(GAFR0_L); SAVE(GAFR0_U);
+ SAVE(GAFR1_L); SAVE(GAFR1_U);
+ SAVE(GAFR2_L); SAVE(GAFR2_U);
+ SAVE(GAFR3_L); SAVE(GAFR3_U);
+
+ SAVE(MDREFR);
+ SAVE(PWER); SAVE(PCFR); SAVE(PRER);
+ SAVE(PFER); SAVE(PKWR);
+
+ SAVE(ICMR); ICMR = 0;
+ SAVE(CKEN);
+ SAVE(PSTR);
+
+ /* Clear GPIO transition detect bits */
+ GEDR0 = GEDR0; GEDR1 = GEDR1; GEDR2 = GEDR2; GEDR3 = GEDR3;
+}
+
+void pxa27x_cpu_pm_restore(unsigned long *sleep_save)
+{
+ /* ensure not to come back here if it wasn't intended */
+ PSPR = 0;
+
+ /* restore registers */
+ RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1);
+ RESTORE_GPLEVEL(2); RESTORE_GPLEVEL(3);
+ RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2); RESTORE(GPDR3);
+ RESTORE(GAFR0_L); RESTORE(GAFR0_U);
+ RESTORE(GAFR1_L); RESTORE(GAFR1_U);
+ RESTORE(GAFR2_L); RESTORE(GAFR2_U);
+ RESTORE(GAFR3_L); RESTORE(GAFR3_U);
+ RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2); RESTORE(GRER3);
+ RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2); RESTORE(GFER3);
+ RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); RESTORE(PGSR3);
+
+ RESTORE(MDREFR);
+ RESTORE(PWER); RESTORE(PCFR); RESTORE(PRER);
+ RESTORE(PFER); RESTORE(PKWR);
+
+ PSSR = PSSR_RDH | PSSR_PH;
+
+ RESTORE(CKEN);
+
+ ICLR = 0;
+ ICCR = 1;
+ RESTORE(ICMR);
+ RESTORE(PSTR);
+}
+
+void pxa27x_cpu_pm_enter(suspend_state_t state)
+{
+ extern void pxa_cpu_standby(void);
+
+ if (state == PM_SUSPEND_STANDBY)
+ CKEN = (1 << CKEN_MEMC) | (1 << CKEN_OSTIMER) |
+ (1 << CKEN_LCD) | (1 << CKEN_PWM0);
+ else
+ CKEN = (1 << CKEN_MEMC) | (1 << CKEN_OSTIMER);
+
+ /* ensure voltage-change sequencer not initiated, which hangs */
+ PCFR &= ~PCFR_FVC;
+
+ /* Clear edge-detect status register. */
+ PEDR = 0xDF12FE1B;
+
+ switch (state) {
+ case PM_SUSPEND_STANDBY:
+ pxa_cpu_standby();
+ break;
+ case PM_SUSPEND_MEM:
+ /* set resume return address */
+ PSPR = virt_to_phys(pxa_cpu_resume);
+ pxa27x_cpu_suspend(PWRMODE_SLEEP);
+ break;
+ }
+}
+
+static int pxa27x_cpu_pm_valid(suspend_state_t state)
+{
+ return state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY;
+}
+
+static struct pxa_cpu_pm_fns pxa27x_cpu_pm_fns = {
+ .save_size = SLEEP_SAVE_SIZE,
+ .save = pxa27x_cpu_pm_save,
+ .restore = pxa27x_cpu_pm_restore,
+ .valid = pxa27x_cpu_pm_valid,
+ .enter = pxa27x_cpu_pm_enter,
+};
+
+static void __init pxa27x_init_pm(void)
+{
+ pxa_cpu_pm_fns = &pxa27x_cpu_pm_fns;
+}
+#endif
+
+#if 0
+/* PXA27x:  Various gpios can issue wakeup events.  This logic only
+ * handles the simple cases, not the WEMUX2 and WEMUX3 options
+ */
+#define PXA27x_GPIO_NOWAKE_MASK \
+        ((1 << 8) | (1 << 7) | (1 << 6) | (1 << 5) | (1 << 2))
+#define WAKEMASK(gpio) \
+        (((gpio) <= 15) \
+                 ? ((1 << (gpio)) & ~PXA27x_GPIO_NOWAKE_MASK) \
+                 : ((gpio == 35) ? (1 << 24) : 0))
+
+static int pxa27x_set_wake(unsigned int irq, unsigned int on)
+{
+ int gpio = IRQ_TO_GPIO(irq);
+ uint32_t mask;
+
+ if ((gpio >= 0 && gpio <= 15) || (gpio == 35)) {
+ if (WAKEMASK(gpio) == 0)
+ return -EINVAL;
+
+ mask = WAKEMASK(gpio);
+
+ if (on) {
+ if (GRER(gpio) | GPIO_bit(gpio))
+ PRER |= mask;
+ else
+ PRER &= ~mask;
+
+ if (GFER(gpio) | GPIO_bit(gpio))
+ PFER |= mask;
+ else
+ PFER &= ~mask;
+ }
+ goto set_pwer;
+ }
+
+ switch (irq) {
+ case IRQ_RTCAlrm:
+ mask = PWER_RTC;
+ break;
+ case IRQ_USB:
+ mask = 1u << 26;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+set_pwer:
+ if (on)
+ PWER |= mask;
+ else
+ PWER &=~mask;
+
+ return 0;
+}
+#endif
+
+void __init pxa27x_init_irq(void)
+{
+// pxa_init_irq_low();
+// pxa_init_irq_high();
+// pxa_init_irq_gpio(128);
+// pxa_init_irq_set_wake(pxa27x_set_wake);
+}
+
+/*
+ * device registration specific to PXA27x.
+ */
+
+#if 0
+static u64 pxa27x_dmamask = 0xffffffffUL;
+
+static struct resource pxa27x_ohci_resources[] = {
+ [0] = {
+ .start  = 0x4C000000,
+ .end    = 0x4C00ff6f,
+ .flags  = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start  = IRQ_USBH1,
+ .end    = IRQ_USBH1,
+ .flags  = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device pxa27x_device_ohci = {
+ .name = "pxa27x-ohci",
+ .id = -1,
+ .dev = {
+ .dma_mask = &pxa27x_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources  = ARRAY_SIZE(pxa27x_ohci_resources),
+ .resource       = pxa27x_ohci_resources,
+};
+
+void __init pxa_set_ohci_info(struct pxaohci_platform_data *info)
+{
+ pxa27x_device_ohci.dev.platform_data = info;
+}
+
+static struct resource i2c_power_resources[] = {
+ {
+ .start = 0x40f00180,
+ .end = 0x40f001a3,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_PWRI2C,
+ .end = IRQ_PWRI2C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device pxa27x_device_i2c_power = {
+ .name = "pxa2xx-i2c",
+ .id = 1,
+ .resource = i2c_power_resources,
+ .num_resources = ARRAY_SIZE(i2c_power_resources),
+};
+#endif
+
+static struct platform_device *devices[] __initdata = {
+// &pxa_device_mci,
+// &pxa_device_udc,
+// &pxa_device_fb,
+ &pxa_device_ffuart,
+// &pxa_device_btuart,
+// &pxa_device_stuart,
+// &pxa_device_i2c,
+// &pxa_device_i2s,
+// &pxa_device_ficp,
+// &pxa_device_rtc,
+// &pxa27x_device_i2c_power,
+// &pxa27x_device_ohci,
+};
+
+static int __init pxa27x_init(void)
+{
+ int ret = 0;
+ if (cpu_is_pxa27x()) {
+ clks_register(pxa27x_clks, ARRAY_SIZE(pxa27x_clks));
+
+ if ((ret = pxa_init_dma(32)))
+ return ret;
+#ifdef CONFIG_PM
+ pxa27x_init_pm();
+#endif
+ ret = platform_add_devices(devices, ARRAY_SIZE(devices));
+ }
+ return ret;
+}
+
+subsys_initcall(pxa27x_init);
+#endif
diff -r 4e814c1899b6 linux/kernel-2.6.24-v2/drivers/net/gumstix-smc911x.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/linux/kernel-2.6.24-v2/drivers/net/gumstix-smc911x.c Wed Apr 22 20:24:29 2009 +0200
@@ -0,0 +1,209 @@
+/*
+ *  Gumstix SMC911x chip intialization driver
+ *
+ *  Author:     Craig Hughes
+ *  Created:    December 9, 2004
+ *  Copyright:  (C) 2004 Craig Hughes
+ *
+ * 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/module.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/mii.h>
+
+#include <asm/hardware.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/delay.h>
+
+#include <asm/arch/gumstix.h>
+
+#define SMC_DEBUG               9
+#include <asm/io.h>
+#include "smc911x.h"
+
+static struct resource gumstix_smc911x0_resources[] = {
+ [0] = {
+ .name = "smc911x-regs",
+#if defined(CONFIG_CELL)
+ .start  = 0x00000000,
+ .end    = 0x000fffff,
+#else
+ .start  = PXA_CS1_PHYS,
+ .end    = PXA_CS1_PHYS + 0x000fffff,
+#endif
+ .flags  = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start  = GUMSTIX_ETH0_IRQ,
+ .end    = GUMSTIX_ETH0_IRQ,
+ .flags  = IORESOURCE_IRQ,
+ },
+ [2] = {
+               .name   = "smc91x-dma",
+#if defined(CONFIG_CELL)
+               .start  = 0x00000000,
+               .end    = 0x000fffff,
+#else
+               .start  = PXA_CS1_DMA,
+               .end    = PXA_CS1_DMA + 0x000fffff,
+#endif
+               .flags  = IORESOURCE_DMA,
+       },
+};
+
+static struct resource gumstix_smc911x1_resources[] = {
+ [0] = {
+ .name = "smc911x-regs",
+#if defined(CONFIG_CELL)
+ .start = 0x00000000,
+ .end = 0x000fffff,
+#else
+ .start = PXA_CS2_PHYS,
+ .end = PXA_CS2_PHYS + 0x000fffff,
+#endif
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = GUMSTIX_ETH1_IRQ,
+ .end = GUMSTIX_ETH1_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+               .name   = "smc91x-dma",
+#if defined(CONFIG_CELL)
+               .start  = 0x00000000,
+               .end    = 0x000fffff,
+#else
+               .start  = PXA_CS1_DMA,
+               .end    = PXA_CS1_DMA + 0x000fffff,
+#endif
+               .flags  = IORESOURCE_DMA,
+       },
+};
+
+static struct platform_device gumstix_smc911x0_device = {
+ .name           = "smc911x",
+ .id             = 0,
+ .num_resources  = ARRAY_SIZE(gumstix_smc911x0_resources),
+ .resource       = gumstix_smc911x0_resources,
+};
+
+static struct platform_device gumstix_smc911x1_device = {
+ .name           = "smc911x",
+ .id             = 1,
+ .num_resources  = ARRAY_SIZE(gumstix_smc911x1_resources),
+ .resource       = gumstix_smc911x1_resources,
+};
+
+static struct platform_device *smc911x_devices[] = {
+ &gumstix_smc911x0_device,
+ &gumstix_smc911x1_device,
+};
+
+/* First we're going to test if there's a 2nd SMC911x, and if not, then we'll free up those resources and the GPIO lines
+ * that it would otherwise use.  We have no choice but to probe by doing:
+ * Set nCS2 to CS2 mode
+ * Set the reset line to GPIO out mode, and pull it high, then drop it low (to trigger reset)
+ * Read from the memory space to check for the sentinel sequence identifying a likely SMC911x device
+ */
+int __init gumstix_smc911x_init(void)
+{
+ unsigned int val, num_devices=ARRAY_SIZE(smc911x_devices);
+ void *ioaddr;
+ printk("%s\n", __FUNCTION__);
+#if defined(CONFIG_CELL)
+ gumstix_smc911x0_resources[0].start += PXA_CS1_PHYS;
+ printk("start: %lx\n", gumstix_smc911x0_resources[0].start);
+ gumstix_smc911x0_resources[0].end += PXA_CS1_PHYS;
+ gumstix_smc911x1_resources[0].start += PXA_CS2_PHYS;
+ gumstix_smc911x1_resources[0].end += PXA_CS2_PHYS;
+
+ gumstix_smc911x0_resources[2].start += PXA_CS1_DMA;
+ gumstix_smc911x0_resources[2].end += PXA_CS1_DMA;
+ gumstix_smc911x1_resources[2].start += PXA_CS2_DMA;
+ gumstix_smc911x1_resources[2].end += PXA_CS2_DMA;
+#endif
+
+ printk("%s %d\n", __FILE__, __LINE__);
+
+ /* Set up nPWE */
+ pxa_gpio_mode(GPIO49_nPWE_MD);
+
+ pxa_gpio_mode(GPIO78_nCS_2_MD);
+ // If either if statement fails, then we'll drop out and turn_off_eth1,
+ // if both succeed, then we'll skip that and just proceed with 2 cards
+ printk("%s %d\n", __FILE__, __LINE__);
+#if 0 /* do not check for second network interface */
+ if(request_mem_region(gumstix_smc911x1_resources[1].start, SMC911X_IO_EXTENT, "smc911x probe"))
+ {
+ printk("%s %d\n", __FILE__, __LINE__);
+ ioaddr = ioremap(gumstix_smc911x1_resources[1].start, SMC911X_IO_EXTENT);
+ printk("%s %d ioaddr 0x%p\n", __FILE__, __LINE__, ioaddr);
+ val = SMC_GET_PN();
+ printk("%s %d\n", __FILE__, __LINE__);
+ iounmap(ioaddr);
+ printk("%s %d\n", __FILE__, __LINE__);
+ release_mem_region(gumstix_smc911x1_resources[1].start, SMC911X_IO_EXTENT);
+ printk("%s %d\n", __FILE__, __LINE__);
+ if (CHIP_9115 == val ||
+ CHIP_9116 == val ||
+ CHIP_9117 == val ||
+ CHIP_9118 == val ) {
+ goto proceed;
+ }
+ printk("%s %d\n", __FILE__, __LINE__);
+ }
+#endif
+
+ printk("%s %d\n", __FILE__, __LINE__);
+turn_off_eth1:
+ // This is apparently not an SMC911x
+ // So, let's decrement the number of devices to request, and reset the GPIO lines to GPIO IN mode
+ num_devices--;
+ smc911x_devices[1] = NULL;
+ pxa_gpio_mode(78 | GPIO_IN);
+
+ printk("%s %d\n", __FILE__, __LINE__);
+proceed:
+ pxa_gpio_mode(GPIO15_nCS_1_MD);
+
+ if(smc911x_devices[1]) pxa_gpio_mode(GPIO_GUMSTIX_ETH1_RST_MD);
+ pxa_gpio_mode(GPIO_GUMSTIX_ETH0_RST_MD);
+
+ if(smc911x_devices[1]) GPCR(GPIO_GUMSTIX_ETH1_RST) = GPIO_bit(GPIO_GUMSTIX_ETH1_RST);
+ GPCR(GPIO_GUMSTIX_ETH0_RST) = GPIO_bit(GPIO_GUMSTIX_ETH0_RST);
+ msleep(500); // Hold RESET for at least 200µ
+
+ if(smc911x_devices[1]) GPSR(GPIO_GUMSTIX_ETH1_RST) = GPIO_bit(GPIO_GUMSTIX_ETH1_RST);
+ GPSR(GPIO_GUMSTIX_ETH0_RST) = GPIO_bit(GPIO_GUMSTIX_ETH0_RST);
+ msleep(50);
+
+ printk("%s %d\n", __FILE__, __LINE__);
+ return platform_add_devices(smc911x_devices, num_devices);
+}
+
+void __exit gumstix_smc911x_exit(void)
+{
+ if(smc911x_devices[1] != NULL) platform_device_unregister(&gumstix_smc911x1_device);
+ platform_device_unregister(&gumstix_smc911x0_device);
+}
+
+void gumstix_smc911x_load(void) {}
+EXPORT_SYMBOL(gumstix_smc911x_load);
+
+module_init(gumstix_smc911x_init);
+module_exit(gumstix_smc911x_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Craig Hughes <[hidden email]>");
+MODULE_DESCRIPTION("Gumstix board SMC911x chip initialization driver");
+MODULE_VERSION("1:0.1");
diff -r 4e814c1899b6 linux/kernel-2.6.24-v2/drivers/net/smc911x.c
--- a/linux/kernel-2.6.24-v2/drivers/net/smc911x.c Wed Apr 08 15:37:40 2009 +0200
+++ b/linux/kernel-2.6.24-v2/drivers/net/smc911x.c Wed Apr 22 20:24:29 2009 +0200
@@ -27,32 +27,13 @@
  * History:
  *  04/16/05 Dustin McIntire Initial version
  */
+
 static const char version[] =
  "smc911x.c: v1.0 04-16-2005 by Dustin McIntire <[hidden email]>\n";
 
-/* Debugging options */
-#define ENABLE_SMC_DEBUG_RX 0
-#define ENABLE_SMC_DEBUG_TX 0
-#define ENABLE_SMC_DEBUG_DMA 0
-#define ENABLE_SMC_DEBUG_PKTS 0
-#define ENABLE_SMC_DEBUG_MISC 0
-#define ENABLE_SMC_DEBUG_FUNC 0
-
-#define SMC_DEBUG_RX ((ENABLE_SMC_DEBUG_RX ? 1 : 0) << 0)
-#define SMC_DEBUG_TX ((ENABLE_SMC_DEBUG_TX ? 1 : 0) << 1)
-#define SMC_DEBUG_DMA ((ENABLE_SMC_DEBUG_DMA ? 1 : 0) << 2)
-#define SMC_DEBUG_PKTS ((ENABLE_SMC_DEBUG_PKTS ? 1 : 0) << 3)
-#define SMC_DEBUG_MISC ((ENABLE_SMC_DEBUG_MISC ? 1 : 0) << 4)
-#define SMC_DEBUG_FUNC ((ENABLE_SMC_DEBUG_FUNC ? 1 : 0) << 5)
-
 #ifndef SMC_DEBUG
-#define SMC_DEBUG ( SMC_DEBUG_RX  | \
-   SMC_DEBUG_TX  | \
-   SMC_DEBUG_DMA  | \
-   SMC_DEBUG_PKTS | \
-   SMC_DEBUG_MISC | \
-   SMC_DEBUG_FUNC   \
- )
+#define SMC_DEBUG 0
+#define SMC_DEBUG_PKTS 0
 #endif
 
 #include <linux/init.h>
@@ -76,6 +57,7 @@ static const char version[] =
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 
+#include <linux/irq.h>
 #include <asm/io.h>
 
 #include "smc911x.h"
@@ -295,14 +277,14 @@ static void smc911x_reset(struct net_dev
  SMC_SET_AFC_CFG(lp->afc_cfg);
 
 
- /* Set to LED outputs */
- SMC_SET_GPIO_CFG(0x70070000);
+ /* Set to LED outputs and configure EEPROM pins as GP outputs */
+ SMC_SET_GPIO_CFG(GPIO_CFG_LED1_EN_ | GPIO_CFG_LED2_EN_ | 1 << 20);
 
  /*
- * Deassert IRQ for 1*10us for edge type interrupts
+ * Deassert IRQ for 22*10us for edge type interrupts
  * and drive IRQ pin push-pull
  */
- SMC_SET_IRQ_CFG( (1 << 24) | INT_CFG_IRQ_EN_ | INT_CFG_IRQ_TYPE_ );
+ SMC_SET_IRQ_CFG( (22 << 24) | INT_CFG_IRQ_EN_ | INT_CFG_IRQ_TYPE_ );
 
  /* clear anything saved */
  if (lp->pending_tx_skb != NULL) {
@@ -405,7 +387,7 @@ static inline void smc911x_drop_pkt(stru
  if (fifo_count <= 4) {
  /* Manually dump the packet data */
  while (fifo_count--)
- SMC_GET_RX_FIFO();
+ (void)SMC_GET_RX_FIFO();
  } else {
  /* Fast forward through the bad packet */
  SMC_SET_RX_DP_CTRL(RX_DP_CTRL_FFWD_BUSY_);
@@ -891,6 +873,7 @@ static void smc911x_phy_powerdown(struct
  unsigned long ioaddr = dev->base_addr;
  unsigned int bmcr;
 
+ DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
  /* Enter Link Disable state */
  SMC_GET_PHY_BMCR(phy, bmcr);
  bmcr |= BMCR_PDOWN;
@@ -916,6 +899,7 @@ static void smc911x_phy_check_media(stru
 
  if (mii_check_media(&lp->mii, netif_msg_link(lp), init)) {
  /* duplex state has changed */
+ DBG(SMC_DEBUG_MISC, "%s: duplex state has changed\n", dev->name);
  SMC_GET_PHY_BMCR(phyaddr, bmcr);
  SMC_GET_MAC_CR(cr);
  if (lp->mii.full_duplex) {
@@ -951,6 +935,7 @@ static void smc911x_phy_configure(struct
  int my_phy_caps; /* My PHY capabilities */
  int my_ad_caps; /* My Advertised capabilities */
  int status;
+ int bmcr;
  unsigned long flags;
 
  DBG(SMC_DEBUG_FUNC, "%s: --> %s()\n", dev->name, __FUNCTION__);
@@ -1024,9 +1009,12 @@ static void smc911x_phy_configure(struct
 
  DBG(SMC_DEBUG_MISC, "%s: phy caps=0x%04x\n", dev->name, my_phy_caps);
  DBG(SMC_DEBUG_MISC, "%s: phy advertised caps=0x%04x\n", dev->name, my_ad_caps);
+ DBG(SMC_DEBUG_MISC, "%s: phy advertised readback caps=0x%04x\n", dev->name, status);
 
  /* Restart auto-negotiation process in order to advertise my caps */
- SMC_SET_PHY_BMCR(phyaddr, BMCR_ANENABLE | BMCR_ANRESTART);
+ SMC_GET_PHY_BMCR(phyaddr, bmcr);
+ bmcr |= BMCR_ANENABLE | BMCR_ANRESTART;
+ SMC_SET_PHY_BMCR(phyaddr, bmcr);
 
  smc911x_phy_check_media(dev, 1);
 
@@ -1856,6 +1844,48 @@ static int __init smc911x_findirq(unsign
  return probe_irq_off(cookie);
 }
 
+static inline unsigned int is_gumstix_oui(u8 *addr)
+{
+ return (addr[0] == 0x00 && addr[1] == 0x15 && addr[2] == 0xC9);
+}
+
+/**
+ * gen_serial_ether_addr - Generate software assigned Ethernet address
+ * based on the system_serial number
+ * @addr: Pointer to a six-byte array containing the Ethernet address
+ *
+ * Generate an Ethernet address (MAC) that is not multicast
+ * and has the local assigned bit set, keyed on the system_serial
+ */
+static inline void gen_serial_ether_addr(u8 *addr)
+{
+#ifdef CONFIG_CELL
+ addr [0] = 0x00;
+ addr [1] = 0x15;
+ addr [2] = 0xC9;
+ addr [3] = 0x83;
+ addr [4] = 0x82;
+ addr [5] = 0x81;
+#else
+ static u8 ether_serial_digit = 0;
+ addr [0] = system_serial_high >> 8;
+ addr [1] = system_serial_high;
+ addr [2] = system_serial_low >> 24;
+ addr [3] = system_serial_low >> 16;
+ addr [4] = system_serial_low >> 8;
+ addr [5] = (system_serial_low & 0xc0) | /* top bits are from system serial */
+ (1 << 4) | /* 2 bits identify interface type 1=ether, 2=usb, 3&4 undef */
+ ((ether_serial_digit++) & 0x0f); /* 15 possible interfaces of each type */
+#endif
+
+ if(!is_gumstix_oui(addr))
+ {
+ addr [0] &= 0xfe; /* clear multicast bit */
+ addr [0] |= 0x02; /* set local assignment bit (IEEE802) */
+ }
+}
+
+
 /*
  * Function: smc911x_probe(unsigned long ioaddr)
  *
@@ -2082,15 +2112,13 @@ static int __init smc911x_probe(struct n
 #endif
  printk("\n");
  if (!is_valid_ether_addr(dev->dev_addr)) {
- printk("%s: Invalid ethernet MAC address. Please "
- "set using ifconfig\n", dev->name);
- } else {
- /* Print the Ethernet address */
- printk("%s: Ethernet addr: ", dev->name);
- for (i = 0; i < 5; i++)
- printk("%2.2x:", dev->dev_addr[i]);
- printk("%2.2x\n", dev->dev_addr[5]);
+ gen_serial_ether_addr(dev->dev_addr);
  }
+ /* Print the Ethernet address */
+ printk("%s: Ethernet addr: ", dev->name);
+ for (i = 0; i < 5; i++)
+ printk("%2.2x:", dev->dev_addr[i]);
+ printk("%2.2x\n", dev->dev_addr[5]);
 
  if (lp->phy_type == 0) {
  PRINTK("%s: No PHY found\n", dev->name);
@@ -2265,8 +2293,15 @@ static struct platform_driver smc911x_dr
  },
 };
 
+#ifdef CONFIG_ARCH_GUMSTIX
+extern void gumstix_smc911x_load(void);
+#endif
+
 static int __init smc911x_init(void)
 {
+#ifdef CONFIG_ARCH_GUMSTIX
+ gumstix_smc911x_load();
+#endif
  return platform_driver_register(&smc911x_driver);
 }
 
diff -r 4e814c1899b6 linux/kernel-2.6.24-v2/drivers/net/smc911x.h
--- a/linux/kernel-2.6.24-v2/drivers/net/smc911x.h Wed Apr 08 15:37:40 2009 +0200
+++ b/linux/kernel-2.6.24-v2/drivers/net/smc911x.h Wed Apr 22 20:24:29 2009 +0200
@@ -33,7 +33,9 @@
  * Use the DMA feature on PXA chips
  */
 #ifdef CONFIG_ARCH_PXA
+#if !defined( CONFIG_SMC911X_GUMSTIX ) && !defined( CONFIG_SMC911X_GUMSTIX_MODULE )
   #define SMC_USE_PXA_DMA 1
+#endif
   #define SMC_USE_16BIT 0
   #define SMC_USE_32BIT 1
   #define SMC_IRQ_SENSE IRQF_TRIGGER_FALLING
@@ -52,13 +54,13 @@
 #if SMC_USE_16BIT
 #define SMC_inb(a, r) readb((a) + (r))
 #define SMC_inw(a, r) readw((a) + (r))
-#define SMC_inl(a, r) ((SMC_inw(a, r) & 0xFFFF)+(SMC_inw(a+2, r)<<16))
+#define SMC_inl(a, r) ((SMC_inw(a, r) & 0xFFFF)+(SMC_inw((a)+2, r)<<16))
 #define SMC_outb(v, a, r) writeb(v, (a) + (r))
 #define SMC_outw(v, a, r) writew(v, (a) + (r))
 #define SMC_outl(v, a, r) \
  do{ \
- writel(v & 0xFFFF, (a) + (r)); \
- writel(v >> 16, (a) + (r) + 2); \
+ writel((v) & 0xFFFF, (a) + (r)); \
+ writel((v) >> 16, (a) + (r) + 2); \
  } while (0)
 #define SMC_insl(a, r, p, l) readsw((short*)((a) + (r)), p, l*2)
 #define SMC_outsl(a, r, p, l) writesw((short*)((a) + (r)), p, l*2)
diff -r 4e814c1899b6 linux/kernel-2.6.24-v2/include/asm-l4/arm/arch-pxa/hardware.h
--- a/linux/kernel-2.6.24-v2/include/asm-l4/arm/arch-pxa/hardware.h Wed Apr 08 15:37:40 2009 +0200
+++ b/linux/kernel-2.6.24-v2/include/asm-l4/arm/arch-pxa/hardware.h Wed Apr 22 20:24:29 2009 +0200
@@ -43,8 +43,9 @@
 #ifdef CONFIG_PXA27x
 #define __cpu_is_pxa27x(id) \
  ({ \
- unsigned int _id = (id) >> 4 & 0xfff; \
- _id == 0x411; \
+ /*unsigned int _id = (id) >> 4 & 0xfff; */ \
+ /*_id == 0x411; */ \
+ 0 == 0; \
  })
 #else
 #define __cpu_is_pxa27x(id) (0)
diff -r 4e814c1899b6 linux/kernel-2.6.24-v2/include/asm-l4/arm/arch-pxa/irqs.h
--- a/linux/kernel-2.6.24-v2/include/asm-l4/arm/arch-pxa/irqs.h Wed Apr 08 15:37:40 2009 +0200
+++ b/linux/kernel-2.6.24-v2/include/asm-l4/arm/arch-pxa/irqs.h Wed Apr 22 20:24:29 2009 +0200
@@ -73,8 +73,12 @@
 #define IRQ_MMC3 PXA_IRQ(55) /* MMC3 Controller (PXA310) */
 #endif
 
-#if defined(CONFIG_CELL) && defined(CONFIG_PXA25x)
+#if defined(CONFIG_CELL)
+#if defined(CONFIG_PXA25x) ||  defined(CONFIG_PXA27x)
 #define PXA_GPIO_IRQ_BASE (32 - 2)
+#else
+#error cpu not supported
+#endif
 #else
 #define PXA_GPIO_IRQ_BASE (64)
 #endif
diff -r 4e814c1899b6 linux/kernel-2.6.24-v2/include/asm-l4/arm/arch-pxa/pxa-regs.h
--- a/linux/kernel-2.6.24-v2/include/asm-l4/arm/arch-pxa/pxa-regs.h Wed Apr 08 15:37:40 2009 +0200
+++ b/linux/kernel-2.6.24-v2/include/asm-l4/arm/arch-pxa/pxa-regs.h Wed Apr 22 20:24:29 2009 +0200
@@ -26,6 +26,8 @@ extern unsigned long DMAC_BASE;
 
 extern unsigned long PXA_CS1_PHYS, PXA_CS1_DMA;
 extern unsigned long PXA_CS2_PHYS, PXA_CS2_DMA;
+extern unsigned long PXA_CS3_PHYS, PXA_CS3_DMA;
+extern unsigned long PXA_CS4_PHYS, PXA_CS4_DMA;
 
 #else
 
@@ -1213,14 +1215,14 @@ extern unsigned long PXA_CS2_PHYS, PXA_C
 #define ICFP2 __REG(0x40D000A8)  /* Interrupt Controller FIQ Pending Register 2 */
 #define ICPR2 __REG(0x40D000AC)  /* Interrupt Controller Pending Register 2 */
 
-#define _GPLR(x) __REG2(0x40E00000, ((x) & 0x60) >> 3)
-#define _GPDR(x) __REG2(0x40E0000C, ((x) & 0x60) >> 3)
-#define _GPSR(x) __REG2(0x40E00018, ((x) & 0x60) >> 3)
-#define _GPCR(x) __REG2(0x40E00024, ((x) & 0x60) >> 3)
-#define _GRER(x) __REG2(0x40E00030, ((x) & 0x60) >> 3)
-#define _GFER(x) __REG2(0x40E0003C, ((x) & 0x60) >> 3)
-#define _GEDR(x) __REG2(0x40E00048, ((x) & 0x60) >> 3)
-#define _GAFR(x) __REG2(0x40E00054, ((x) & 0x70) >> 2)
+#define _GPLR(x) __REG2_GPIO(0x40E00000, ((x) & 0x60) >> 3)
+#define _GPDR(x) __REG2_GPIO(0x40E0000C, ((x) & 0x60) >> 3)
+#define _GPSR(x) __REG2_GPIO(0x40E00018, ((x) & 0x60) >> 3)
+#define _GPCR(x) __REG2_GPIO(0x40E00024, ((x) & 0x60) >> 3)
+#define _GRER(x) __REG2_GPIO(0x40E00030, ((x) & 0x60) >> 3)
+#define _GFER(x) __REG2_GPIO(0x40E0003C, ((x) & 0x60) >> 3)
+#define _GEDR(x) __REG2_GPIO(0x40E00048, ((x) & 0x60) >> 3)
+#define _GAFR(x) __REG2_GPIO(0x40E00054, ((x) & 0x70) >> 2)
 
 #define GPLR(x) (*((((x) & 0x7f) < 96) ? &_GPLR(x) : &GPLR3))
 #define GPDR(x) (*((((x) & 0x7f) < 96) ? &_GPDR(x) : &GPDR3))
@@ -1342,6 +1344,7 @@ extern unsigned long PXA_CS2_PHYS, PXA_C
 #define GPIO77_LCD_ACBIAS 77 /* LCD AC Bias */
 #define GPIO78_nCS_2 78 /* chip select 2 */
 #define GPIO79_nCS_3 79 /* chip select 3 */
+#define GPIO79_pSKTSEL 79 /* Socket Select for Card Space (PXA27x) */
 #define GPIO80_nCS_4 80 /* chip select 4 */
 #define GPIO81_NSCLK 81 /* NSSP clock */
 #define GPIO82_NSFRM 82 /* NSSP Frame */
@@ -1351,6 +1354,7 @@ extern unsigned long PXA_CS2_PHYS, PXA_C
 #define GPIO92_MMCDAT0 92 /* MMC DAT0 (PXA27x) */
 #define GPIO102_nPCE_1 102 /* PCMCIA (PXA27x) */
 #define GPIO104_pSKTSEL 104 /* PCMCIA Socket Select (PXA27x) */
+#define GPIO105_nPCE_2 105 /* Card Enable for Card Space (PXA27x) */
 #define GPIO109_MMCDAT1 109 /* MMC DAT1 (PXA27x) */
 #define GPIO110_MMCDAT2 110 /* MMC DAT2 (PXA27x) */
 #define GPIO110_MMCCS0 110 /* MMC Chip Select 0 (PXA27x) */
@@ -1496,6 +1500,7 @@ extern unsigned long PXA_CS2_PHYS, PXA_C
 #define GPIO92_MMCDAT0_MD (92 | GPIO_ALT_FN_1_OUT)
 #define GPIO102_nPCE_1_MD (102 | GPIO_ALT_FN_1_OUT)
 #define GPIO104_pSKTSEL_MD (104 | GPIO_ALT_FN_1_OUT)
+#define GPIO105_nPCE_2_MD (105 | GPIO_ALT_FN_1_OUT)
 #define GPIO109_MMCDAT1_MD (109 | GPIO_ALT_FN_1_OUT)
 #define GPIO110_MMCDAT2_MD (110 | GPIO_ALT_FN_1_OUT)
 #define GPIO110_MMCCS0_MD (110 | GPIO_ALT_FN_1_OUT)


[okl4_pxa270_platform.patch]

diff -r 4e814c1899b6 platform/pxa/pistachio/include/intctrl.h
--- a/platform/pxa/pistachio/include/intctrl.h Wed Apr 08 15:37:40 2009 +0200
+++ b/platform/pxa/pistachio/include/intctrl.h Wed Apr 22 20:22:40 2009 +0200
@@ -102,9 +102,15 @@
 #define PXA_GRER0       (*(volatile word_t *)(PXA_GPIO + 0x30))   /* GPIO rising edge 0 */
 #define PXA_GRER1       (*(volatile word_t *)(PXA_GPIO + 0x34))   /* GPIO rising edge 1 */
 #define PXA_GRER2       (*(volatile word_t *)(PXA_GPIO + 0x38))   /* GPIO rising edge 2 */
+#if defined(CONFIG_SUBPLAT_PXA270)
+#define PXA_GRER3       (*(volatile word_t *)(PXA_GPIO + 0x130))   /* GPIO rising edge 3 */
+#endif
 
 #define PXA_GFER0       (*(volatile word_t *)(PXA_GPIO + 0x3C))   /* GPIO falling edge 0 */
 #define PXA_GFER1       (*(volatile word_t *)(PXA_GPIO + 0x40))   /* GPIO falling edge 1 */
 #define PXA_GFER2       (*(volatile word_t *)(PXA_GPIO + 0x44))   /* GPIO falling edge 2 */
+#if defined(CONFIG_SUBPLAT_PXA270)
+#define PXA_GFER3       (*(volatile word_t *)(PXA_GPIO + 0x13C))   /* GPIO falling edge 3 */
+#endif
 
 #endif /*__PLATFORM__PXA__INTCTRL_H__ */
diff -r 4e814c1899b6 platform/pxa/pistachio/include/interrupt.h
--- a/platform/pxa/pistachio/include/interrupt.h Wed Apr 08 15:37:40 2009 +0200
+++ b/platform/pxa/pistachio/include/interrupt.h Wed Apr 22 20:22:40 2009 +0200
@@ -70,7 +70,12 @@
 #define PMN0_IRQ_ENABLE   (1UL << 4)
 
 #define PRIMARY_IRQS 32
+#if defined(CONFIG_SUBPLAT_PXA255)
 #define GPIO_IRQS (85 - 2) /* The first two IRQs have level one interrupts */
+#elif defined(CONFIG_SUBPLAT_PXA270)
+#define GPIO_IRQS (121 - 2) /* The first two IRQs have level one interrupts;
+   PXA270 bounds 119; PXA271 and PXA272 bounds all 121 */
+#endif
 #define GPIO_IRQ 10
 #define IRQS (PRIMARY_IRQS + GPIO_IRQS)
 
diff -r 4e814c1899b6 platform/pxa/pistachio/include/timer.h
--- a/platform/pxa/pistachio/include/timer.h Wed Apr 08 15:37:40 2009 +0200
+++ b/platform/pxa/pistachio/include/timer.h Wed Apr 22 20:22:40 2009 +0200
@@ -80,7 +80,7 @@ static const int TIMER_TICK_LENGTH = 500
 #error Invalid sub-architecture
 #endif
 
-#if defined(CONFIG_PXA270)
+#if defined(CONFIG_SUBPLAT_PXA270)
 /* CLKCFG Modes */
 #define CLKCFG_B        (1<<3)  /* Fast Bus Mode        */
 #define CLKCFG_HT       (1<<2)  /* Half Turbo           */
diff -r 4e814c1899b6 platform/pxa/pistachio/src/interrupt.c
--- a/platform/pxa/pistachio/src/interrupt.c Wed Apr 08 15:37:40 2009 +0200
+++ b/platform/pxa/pistachio/src/interrupt.c Wed Apr 22 20:22:40 2009 +0200
@@ -78,7 +78,7 @@ addr_t xscale_int_va;
 addr_t xscale_int_va;
 addr_t xscale_gpio_va;
 
-#if !defined(CONFIG_SUBPLAT_PXA255)
+#if !defined(CONFIG_SUBPLAT_PXA255) && !defined(CONFIG_SUBPLAT_PXA270)
 #error "Unsupported subplatform."
 #endif
 
@@ -107,13 +107,28 @@ soc_unmask_irq(word_t irq)
         /* XXX This is a GPIO IRQ and we should unmask GPIO set */
         XSCALE_INT_ICMR |= (1 << GPIO_IRQ);
 
+ /* XXX unmask falling edge detect too.
+ * smc911x on gumstix uses falling edge interrupts */
         if (idx == 0) {
             PXA_GRER0 = (1UL << gpio);
+            PXA_GFER0 = (1UL << gpio);
         } else if (idx == 1) {
             PXA_GRER1 = (1UL << gpio);
-        } else {
+            PXA_GFER1 = (1UL << gpio);
+        } else
+#if defined(CONFIG_SUBPLAT_PXA270)
+ if (idx == 2)
+#endif
+ {
             PXA_GRER2 = (1UL << gpio);
+            PXA_GFER2 = (1UL << gpio);
         }
+#if defined(CONFIG_SUBPLAT_PXA270)
+ else {
+            PXA_GRER3 = (1UL << gpio);
+            PXA_GFER3 = (1UL << gpio);
+ }
+#endif
     }
 }
 
@@ -147,6 +162,15 @@ pxa_gpio_irq(void)
 
         return 64 + irq - 2;
     }
+
+#if defined(CONFIG_SUBPLAT_PXA270)
+    mask = PXA_GEDR3;
+    if (mask) {
+        irq = msb(mask);
+        PXA_GEDR3 = (1UL << irq);
+        return 96 + irq - 2;
+    }
+#endif
 
     return -1;
 }
diff -r 4e814c1899b6 platform/pxa/tools/machines.py
--- a/platform/pxa/tools/machines.py Wed Apr 08 15:37:40 2009 +0200
+++ b/platform/pxa/tools/machines.py Wed Apr 22 20:22:40 2009 +0200
@@ -77,7 +77,8 @@ class gumstix(pxa):
     cs_driver = "pxa250_cs"
     uart = "FFUART"
     serial_driver = "uart_8250"
-    subplatform = "pxa255"
+#    subplatform = "pxa255"
+    subplatform = "pxa270"
     drivers = [timer_driver] + pxa.drivers
 
     device_core = "gumstix"
@@ -91,10 +92,12 @@ class gumstix(pxa):
     interrupt_rtc = [31]
     memory_irq_controller = [Region(0x40d00000, 0x40d01000, "all", "uncached")]
     memory_gpio = [Region(0x40e00000, 0x40e01000, "all", "uncached")]
-    interrupt_gpio = [8,9] + range(32,32+(85-2))
+    interrupt_gpio = [8,9] + range(32,32+(121 - 2))
     memory_cs = [Region(0x00000000, 0x04000000, "all", "uncached"),
                  Region(0x04000000, 0x08000000, "all", "uncached"),
-                 Region(0x08000000, 0x0c000000, "all", "uncached")]
+                 Region(0x08000000, 0x0c000000, "all", "uncached"),
+                 Region(0x0c000000, 0x10000000, "all", "uncached"),
+                 Region(0x10000000, 0x14000000, "all", "uncached")]
     pmu_irq = [12]
     v2_drivers = [  
                     ("test_device", "vtest", [], [1,3]),


_______________________________________________
Developer mailing list
[hidden email]
https://lists.okl4.org/mailman/listinfo/developer