nslu2-kernel: Removed obsolete 2.6.15 patches.
authorRod Whitby <rod@whitby.id.au>
Sat, 7 Jan 2006 07:23:51 +0000 (07:23 +0000)
committerOpenEmbedded Project <openembedded-devel@lists.openembedded.org>
Sat, 7 Jan 2006 07:23:51 +0000 (07:23 +0000)
packages/linux/nslu2-kernel/2.6.15/20-timer.patch [deleted file]
packages/linux/nslu2-kernel/2.6.15/35-x1205-fix-osc.patch [deleted file]
packages/linux/nslu2-kernel/2.6.15/60-nslu2-rtc.patch [deleted file]
packages/linux/nslu2-kernel/2.6.15/90-ixp4xx-nslu2.patch [deleted file]

diff --git a/packages/linux/nslu2-kernel/2.6.15/20-timer.patch b/packages/linux/nslu2-kernel/2.6.15/20-timer.patch
deleted file mode 100644 (file)
index 3d4a03f..0000000
+++ /dev/null
@@ -1,285 +0,0 @@
---- linux-2.6.15/arch/arm/mach-ixp4xx/common.c 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.15/arch/arm/mach-ixp4xx/common.c 1970-01-01 00:00:00.000000000 +0000
-@@ -239,36 +239,165 @@ void __init ixp4xx_init_irq(void)
-  * IXP4xx timer tick
-  * We use OS timer1 on the CPU for the timer tick and the timestamp 
-  * counter as a source of real clock ticks to account for missed jiffies.
-+ *
-+ * 'CLOCK_TICK_RATE' is the nominal number of internal ticks per second,
-+ * this is significantly greater than the actual number on any ixp4xx
-+ * board.  Neither this nor 'LATCH' are required by this code because
-+ * the only requirement is to generate HZ timer_tick calls per second.
-  *************************************************************************/
-+#if TICK_NSEC * HZ != 1000000000
-+      /* This will cause the jiffies to drift unnecessarily. */
-+#     error CLOCK_TICK_RATE should be a multiple of HZ for this code
-+#endif
-+
-+/* These are the control registers for the interrupt handler, they must
-+ * only be read and written by the interrupt handler and by the init
-+ * method (which sets them to 0).
-+ */
-+static volatile u32 last_timer_time;
-+static volatile int accumulated_error;
-+
-+/* Most ixp4xx boards have 66.6666MHz crystals, so default to this, reset
-+ * this from the board level code if required.  The following variables
-+ * must be *written* only by set_board_tick_rate
-+ */
-+static u32 board_tick_rate;
-+static u32 board_tick_per_1000; /* board_tick_rate/1000 */
-+static u32 timer_count;
-+
-+/* The following symbol may be written to change the current tick rate,
-+ * it is read by the interrupt handler and used to reload the timer.
-+ * The 'real' value (the one in use) is 'board_tick_rate' above.
-+ * NOTE: this can be tweaked to match the actual crystal on a particular
-+ * machine.
-+ */
-+volatile u32 ixp4xx_board_tick_rate = 66666600;
-+EXPORT_SYMBOL(ixp4xx_board_tick_rate);
-+
-+/* The set API may run asynchronously in the presence of interrupts,
-+ * everything it does it is both atomic and complete (notice that it
-+ * doesn't change any of the 'volatile' values).  The mathematics in
-+ * here require the following values.  Changing the board tick rate
-+ * implies an unknown error in the current timestamp tick count.
-+ */
-+#if IXP4XX_OST_RELOAD_MASK != 3 || IXP4XX_OST_ENABLE != 1
-+#     error unexpected value for timer reload mask
-+#endif
-+static void set_board_tick_rate(u32 rate) {
-+      u32 reload;
-+
-+      /* Store the two effectively informational rate values, the
-+       * error calculation is (rate - count*HZ) (above), and rate
-+       * is changed first, this can cause a temporary error which
-+       * will be corrected on the next interrupt.
-+       */
-+      board_tick_rate = rate;
-+      board_tick_per_1000 = (rate+500)/1000;
-+
-+      /* Calculate the correct value to load into the timer countdown
-+       * register, the low two bits must be b01 (to enable the timer).
-+       * Select the top bits to be as close to the desired value as
-+       * possible.
-+       *
-+       * First find the best value, regardless of the low two bits -
-+       * this is the value used in the interrupt calculation even though
-+       * it cannot necessarily be set into the register.
-+       */
-+      timer_count = (rate + (HZ/2))/HZ;
-+
-+      /* Now the timer_ticks are being generated at this rate, calculate
-+       * an appropriate value for the register.  This stores a 30 bit
-+       * value which gives a period of 4*x+1, we want:
-+       *
-+       *   4*x+1 = board_tick_rate/HZ
-+       *
-+       * This needs to be rounded to the closest 4*HZ value:
-+       * 
-+       *   x = ((board_tick_rate-HZ) + (4*HZ)/2) / 4*HZ
-+       *   x = (board_tick_rate+HZ) / (4*HZ);
-+       */
-+      reload = (board_tick_rate + HZ) / HZ;
-+      reload = (reload & ~IXP4XX_OST_RELOAD_MASK) | IXP4XX_OST_ENABLE;
-+      *IXP4XX_OSRT1 = reload;
--static unsigned volatile last_jiffy_time;
-+      /* If the clock is drifing, look in syslog: */
-+      printk(KERN_INFO "IXP4xx: FREQ=%d COUNT=%d\n", rate, reload);
-+}
--#define CLOCK_TICKS_PER_USEC  ((CLOCK_TICK_RATE + USEC_PER_SEC/2) / USEC_PER_SEC)
-+/* This returns the time in timer ticks since the 'last_timer_time'
-+ * recorded above.  Use this to avoid arithmetic errors because of
-+ * the overflow when the timer wraps.
-+ */
-+static inline u32 ixp4xx_timer_delta(void)
-+{
-+      return *IXP4XX_OSTS - last_timer_time;
-+}
- /* IRQs are disabled before entering here from do_gettimeofday() */
- static unsigned long ixp4xx_gettimeoffset(void)
- {
--      u32 elapsed;
--
--      elapsed = *IXP4XX_OSTS - last_jiffy_time;
-+      /* Return the offset of the current time from the last time
-+       * timer tick in microseconds.  This is only used for the
-+       * gettimeofday call.
-+       *
-+       * The result of this API is at most about 20000 (for a 50Hz
-+       * HZ - 20000 uS/tick), the input delta is at most about
-+       * 1.3M - 21 bits.
-+       */
-+      u32 delta = ixp4xx_timer_delta(); /* About 21 bits max */
-+      /* return delta * 1000000 / board_tick_rate; */
-+      return (delta * 1000 + board_tick_per_1000/2) / board_tick_per_1000;
-+}
--      return elapsed / CLOCK_TICKS_PER_USEC;
-+/* This is the correct adjustment to the counter to compensate for an
-+ * error iff timer_count-1 <= exact_count <= timer_count+1
-+ */
-+static inline int adjustment(int error) {
-+      if (error >= HZ)
-+              return 1;
-+      else if (error <= -HZ)
-+              return -1;
-+      return 0;
- }
- static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
- {
-+      u32 rate;
-+      u32 count;
-+      int error;
-+
-       write_seqlock(&xtime_lock);
-       /* Clear Pending Interrupt by writing '1' to it */
-       *IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND;
-+      /* If the board tick rate has been changed update the cached
-+       * value.
-+       */
-+      if (ixp4xx_board_tick_rate != board_tick_rate) {
-+              set_board_tick_rate(ixp4xx_board_tick_rate);
-+              accumulated_error = 0;
-+      }
-+
-       /*
-        * Catch up with the real idea of time
-+       *
-+       * board_tick_rate: actual ixp4xx ticks/second, read-only
-+       * accumulated_error: aggregate error/tick * HZ, read/write
-+       * timer_count: best ixp4xx ticks per timer_tick, read-only
-        */
--      while ((*IXP4XX_OSTS - last_jiffy_time) > LATCH) {
-+      rate = board_tick_rate;
-+      error = accumulated_error;
-+      count = timer_count;
-+      do {
-+              u32 adjusted_count = count + adjustment(error);
-+              if (ixp4xx_timer_delta() < adjusted_count)
-+                      break;
-               timer_tick(regs);
--              last_jiffy_time += LATCH;
--      }
-+              last_timer_time += adjusted_count;
-+              error += rate - adjusted_count*HZ;
-+      } while (1);
-+      accumulated_error = error;
-       write_sequnlock(&xtime_lock);
-@@ -281,17 +410,30 @@ static struct irqaction ixp4xx_timer_irq
-       .handler        = ixp4xx_timer_interrupt,
- };
-+u32 ixp4xx_get_board_tick_rate(void) {
-+      return board_tick_rate;
-+}
-+
-+EXPORT_SYMBOL(ixp4xx_get_board_tick_rate);
-+
-+void ixp4xx_set_board_tick_rate(u32 rate) {
-+      ixp4xx_board_tick_rate = rate;
-+}
-+
-+EXPORT_SYMBOL(ixp4xx_set_board_tick_rate);
-+
- static void __init ixp4xx_timer_init(void)
- {
-       /* Clear Pending Interrupt by writing '1' to it */
-       *IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND;
-       /* Setup the Timer counter value */
--      *IXP4XX_OSRT1 = (LATCH & ~IXP4XX_OST_RELOAD_MASK) | IXP4XX_OST_ENABLE;
-+      set_board_tick_rate(ixp4xx_board_tick_rate);
-       /* Reset time-stamp counter */
-       *IXP4XX_OSTS = 0;
--      last_jiffy_time = 0;
-+      last_timer_time = 0;
-+      accumulated_error = 0;
-       /* Connect the interrupt handler and enable the interrupt */
-       setup_irq(IRQ_IXP4XX_TIMER1, &ixp4xx_timer_irq);
-@@ -337,4 +479,3 @@ void __init ixp4xx_sys_init(void)
-                               ARRAY_SIZE(ixp46x_devices));
-       }
- }
--
---- linux-2.6.15/arch/arm/mach-ixp4xx/nslu2-setup.c    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.15/arch/arm/mach-ixp4xx/nslu2-setup.c    1970-01-01 00:00:00.000000000 +0000
-@@ -119,6 +119,11 @@ static void nslu2_power_off(void)
- static void __init nslu2_init(void)
- {
-+      /* The NSLU2 has a 33MHz crystal on board - 1.01% different
-+       * from the typical value.
-+       */
-+      ixp4xx_set_board_tick_rate(66000000);
-+
-       ixp4xx_sys_init();
-       pm_power_off = nslu2_power_off;
---- linux-2.6.15/drivers/input/misc/nslu2spkr.c        1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.15/drivers/input/misc/nslu2spkr.c        1970-01-01 00:00:00.000000000 +0000
-@@ -51,7 +51,7 @@ static int nslu2_spkr_event(struct input
-       }
-       if (value > 20 && value < 32767)
--              count = (NSLU2_FREQ / (value*4)) - 1;
-+              count = (ixp4xx_get_board_tick_rate() / (value*4)) - 1;
-       spin_lock_irqsave(&beep_lock, flags);
---- linux-2.6.15/include/asm-arm/arch-ixp4xx/nslu2.h   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.15/include/asm-arm/arch-ixp4xx/nslu2.h   1970-01-01 00:00:00.000000000 +0000
-@@ -38,11 +38,6 @@
- #define NSLU2_PCI_INTD_PIN    8
--/* NSLU2 Timer */
--#define NSLU2_FREQ 66000000
--#define NSLU2_CLOCK_TICK_RATE (((NSLU2_FREQ / HZ & ~IXP4XX_OST_RELOAD_MASK) + 1) * HZ)
--#define NSLU2_CLOCK_TICKS_PER_USEC ((NSLU2_CLOCK_TICK_RATE + USEC_PER_SEC/2) / USEC_PER_SEC)
--
- /* GPIO */
- #define NSLU2_GPIO0           0
---- linux-2.6.15/include/asm-arm/arch-ixp4xx/timex.h   1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.15/include/asm-arm/arch-ixp4xx/timex.h   1970-01-01 00:00:00.000000000 +0000
-@@ -6,10 +6,23 @@
- #include <asm/hardware.h>
- /*
-- * We use IXP425 General purpose timer for our timer needs, it runs at 
-- * 66.66... MHz. We do a convulted calculation of CLOCK_TICK_RATE b/c the
-- * timer register ignores the bottom 2 bits of the LATCH value.
-+ * In linux/timex.h 'LATCH' is defined as CLOCK_TICK_RATE/HZ and
-+ * is the number of internal counts per timer interrupt.  Thus
-+ * CLOCK_TICK_RATE is LATCH*HZ.
-+ *
-+ * The actual values of these numbers do not matter, because they
-+ * are only used to calculate ACTHZ (rate/latch as a 24.8 fixed
-+ * point number), so the value here gives a LATCH of 1 and pretty
-+ * much guarantees to flush out any off-by-one errors.
-+ *
-+ * ACTHZ is equal to HZ, because CLOCK_TICK_RATE is a multiple of
-+ * HZ, this is checked in the ixp4xx/common.c code.
-  */
--#define FREQ 66666666
--#define CLOCK_TICK_RATE (((FREQ / HZ & ~IXP4XX_OST_RELOAD_MASK) + 1) * HZ)
-+#define CLOCK_TICK_RATE HZ
-+/* The following allow the exact board tick rate to be set and
-+ * discovered.  The value should be exactly twice the frequency
-+ * (in Hz) of the onboard crystal.
-+ */
-+extern u32 ixp4xx_get_board_tick_rate(void);
-+extern void ixp4xx_set_board_tick_rate(u32 new_rate);
diff --git a/packages/linux/nslu2-kernel/2.6.15/35-x1205-fix-osc.patch b/packages/linux/nslu2-kernel/2.6.15/35-x1205-fix-osc.patch
deleted file mode 100644 (file)
index 44f2636..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
- drivers/i2c/chips/x1205.c |  116 ++++++++++++++++++++++++++++++----------------
- 1 file changed, 76 insertions(+), 40 deletions(-)
-
---- linux-nslu2.orig/drivers/i2c/chips/x1205.c 2005-12-12 18:59:07.000000000 +0100
-+++ linux-nslu2/drivers/i2c/chips/x1205.c      2005-12-13 21:31:32.000000000 +0100
-@@ -22,9 +22,9 @@
- #include <linux/string.h>
- #include <linux/bcd.h>
- #include <linux/rtc.h>
-+#include <linux/delay.h>
--
--#define DRV_VERSION "1.0.0"
-+#define DRV_VERSION "1.0.1"
- /* Addresses to scan: none. This chip is located at
-  * 0x6f and uses a two bytes register addressing.
-@@ -141,35 +141,19 @@ static int x1205_validate_tm(struct rtc_
-  * Epoch is initialized as 2000. Time is set to UTC.
-  */
- static int x1205_get_datetime(struct i2c_client *client, struct rtc_time *tm,
--                              u8 reg_base)
-+                              unsigned char reg_base)
- {
-       unsigned char dt_addr[2] = { 0, reg_base };
--      static unsigned char sr_addr[2] = { 0, X1205_REG_SR };
--      unsigned char buf[8], sr;
-+      unsigned char buf[8];
-       struct i2c_msg msgs[] = {
--              { client->addr, 0, 2, sr_addr },        /* setup read ptr */
--              { client->addr, I2C_M_RD, 1, &sr },     /* read status */
-               { client->addr, 0, 2, dt_addr },        /* setup read ptr */
-               { client->addr, I2C_M_RD, 8, buf },     /* read date */
-       };
--      /* read status register */
--      if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
--              dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
--              return -EIO;
--      }
--
--      /* check for battery failure */
--      if (sr & X1205_SR_RTCF) {
--              dev_warn(&client->dev,
--                      "Clock had a power failure, you must set the date.\n");
--              return -EINVAL;
--      }
--
-       /* read date registers */
--      if ((i2c_transfer(client->adapter, &msgs[2], 2)) != 2) {
-+      if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
-               dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
-               return -EIO;
-       }
-@@ -199,11 +183,28 @@ static int x1205_get_datetime(struct i2c
-       return 0;
- }
-+static int x1205_get_status(struct i2c_client *client, unsigned char *sr)
-+{
-+      static unsigned char sr_addr[2] = { 0, X1205_REG_SR };
-+
-+      struct i2c_msg msgs[] = {
-+              { client->addr, 0, 2, sr_addr },        /* setup read ptr */
-+              { client->addr, I2C_M_RD, 1, sr },      /* read status */
-+      };
-+
-+      /* read status register */
-+      if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
-+              dev_err(&client->dev, "%s: read error\n", __FUNCTION__);
-+              return -EIO;
-+      }
-+
-+      return 0;
-+}
-+
- static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm,
-                               int datetoo, u8 reg_base)
- {
--      int i, err, xfer;
--
-+      int i, xfer;
-       unsigned char buf[8];
-       static const unsigned char wel[3] = { 0, X1205_REG_SR,
-@@ -214,15 +215,10 @@ static int x1205_set_datetime(struct i2c
-       static const unsigned char diswe[3] = { 0, X1205_REG_SR, 0 };
--      /* check if all values in the tm struct are correct */
--      if ((err = x1205_validate_tm(tm)) < 0)
--              return err;
--
--      dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, "
--              "mday=%d, mon=%d, year=%d, wday=%d\n",
-+      dev_dbg(&client->dev,
-+              "%s: secs=%d, mins=%d, hours=%d\n",
-               __FUNCTION__,
--              tm->tm_sec, tm->tm_min, tm->tm_hour,
--              tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
-+              tm->tm_sec, tm->tm_min, tm->tm_hour);
-       buf[CCR_SEC] = BIN2BCD(tm->tm_sec);
-       buf[CCR_MIN] = BIN2BCD(tm->tm_min);
-@@ -232,6 +228,11 @@ static int x1205_set_datetime(struct i2c
-       /* should we also set the date? */
-       if (datetoo) {
-+              dev_dbg(&client->dev,
-+                      "%s: mday=%d, mon=%d, year=%d, wday=%d\n",
-+                      __FUNCTION__,
-+                      tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
-+
-               buf[CCR_MDAY] = BIN2BCD(tm->tm_mday);
-               /* month, 0 - 11 */
-@@ -280,6 +281,22 @@ static int x1205_set_datetime(struct i2c
-       return 0;
- }
-+static int x1205_fix_osc(struct i2c_client *client)
-+{
-+      int err;
-+      struct rtc_time tm;
-+
-+      tm.tm_hour = 0;
-+      tm.tm_min = 0;
-+      tm.tm_sec = 0;
-+
-+      if ((err = x1205_set_datetime(client, &tm, 0, X1205_CCR_BASE)) < 0)
-+              dev_err(&client->dev,
-+                      "unable to restart the clock\n");
-+
-+      return err;
-+}
-+
- static int x1205_get_dtrim(struct i2c_client *client, int *trim)
- {
-       unsigned char dtr;
-@@ -352,14 +369,17 @@ static int x1205_hctosys(struct i2c_clie
-       struct rtc_time tm;
-       struct timespec tv;
-+      unsigned char sr;
-+      if ((err = x1205_get_status(client, &sr)) < 0)
-+              return err;
--      err = x1205_get_datetime(client, &tm, X1205_CCR_BASE);
--      if (err) {
--              dev_err(&client->dev,
--                      "Unable to set the system clock\n");
-+      /* Don't set if we had a power failure */
-+      if (sr & X1205_SR_RTCF)
-+              return -EINVAL;
-+
-+      if ((err = x1205_get_datetime(client, &tm, X1205_CCR_BASE)) < 0)
-               return err;
--      }
-       /* IMPORTANT: the RTC only stores whole seconds. It is arbitrary
-        * whether it stores the most close value or the value with partial
-@@ -506,9 +526,9 @@ static int x1205_attach(struct i2c_adapt
- static int x1205_probe(struct i2c_adapter *adapter, int address, int kind)
- {
--      struct i2c_client *client;
--
-       int err = 0;
-+      unsigned char sr;
-+      struct i2c_client *client;
-       dev_dbg(&adapter->dev, "%s\n", __FUNCTION__);
-@@ -543,9 +563,25 @@ static int x1205_probe(struct i2c_adapte
-       dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
-+      /* Check for power failures and eventualy enable the osc */
-+      if ((err = x1205_get_status(client, &sr)) == 0) {
-+              if (sr & X1205_SR_RTCF) {
-+                      dev_err(&client->dev,
-+                              "power failure detected, "
-+                              "please set the clock\n");
-+                      udelay(50);
-+                      x1205_fix_osc(client);
-+              }
-+      }
-+      else
-+              dev_err(&client->dev, "couldn't read status\n");
-+
-       /* If requested, set the system time */
--      if (hctosys)
--              x1205_hctosys(client);
-+      if (hctosys) {
-+              if ((err = x1205_hctosys(client)) < 0)
-+                      dev_err(&client->dev,
-+                              "unable to set the system clock\n");
-+      }
-       return 0;
diff --git a/packages/linux/nslu2-kernel/2.6.15/60-nslu2-rtc.patch b/packages/linux/nslu2-kernel/2.6.15/60-nslu2-rtc.patch
deleted file mode 100644 (file)
index 9e390c6..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
- arch/arm/mach-ixp4xx/nslu2-setup.c |    5 +++++
- 1 file changed, 5 insertions(+)
-
---- linux-2.6.15/arch/arm/mach-ixp4xx/nslu2-setup.c    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.15/arch/arm/mach-ixp4xx/nslu2-setup.c    1970-01-01 00:00:00.000000000 +0000
-@@ -95,10 +95,15 @@ static struct platform_device nslu2_uart
-       .resource               = nslu2_uart_resources,
- };
-+static struct platform_device nslu2_rtc = {
-+      .name                   = "x1205-rtc",
-+};
-+
- static struct platform_device *nslu2_devices[] __initdata = {
-       &nslu2_i2c_controller,
-       &nslu2_flash,
-       &nslu2_uart,
-+      &nslu2_rtc,
- };
- static void nslu2_power_off(void)
diff --git a/packages/linux/nslu2-kernel/2.6.15/90-ixp4xx-nslu2.patch b/packages/linux/nslu2-kernel/2.6.15/90-ixp4xx-nslu2.patch
deleted file mode 100644 (file)
index c106f7c..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-ixp4xx updates:
-  - Handle reads that don't start on a half-word boundary.
-  - Make it work when CPU is in little-endian mode.
-    
-Signed-off-by: John Bowler <jbowler@acm.org>
-Signed-off-by: Alessandro Zummo <a.zummo@towertech.it>
-Signed-off-by: David Vrabel <dvrabel@arcom.com>
-
-Index: linux-2.6-working/drivers/mtd/maps/ixp4xx.c
-===================================================================
---- linux-2.6-working.orig/drivers/mtd/maps/ixp4xx.c   2005-11-16 15:19:34.000000000 +0000
-+++ linux-2.6-working/drivers/mtd/maps/ixp4xx.c        2005-11-16 16:06:54.000000000 +0000
-@@ -34,10 +34,55 @@
- #include <linux/reboot.h>
-+/*
-+ * Read/write a 16 bit word from flash address 'addr'.
-+ *
-+ * When the cpu is in little-endian mode it swizzles the address lines
-+ * ('address coherency') so we need to undo the swizzling to ensure commands
-+ * and the like end up on the correct flash address.
-+ *
-+ * To further complicate matters, due to the way the expansion bus controller
-+ * handles 32 bit reads, the byte stream ABCD is stored on the flash as:
-+ *     D15    D0
-+ *     +---+---+
-+ *     | A | B | 0
-+ *     +---+---+
-+ *     | C | D | 2
-+ *     +---+---+
-+ * This means that on LE systems each 16 bit word must be swapped. Note that
-+ * this requires CONFIG_MTD_CFI_BE_BYTE_SWAP to be enabled to 'unswap' the CFI
-+ * data and other flash commands which are always in D7-D0.
-+ */
- #ifndef __ARMEB__
-+#ifndef CONFIG_MTD_CFI_BE_BYTE_SWAP
-+#  error CONFIG_MTD_CFI_BE_BYTE_SWAP required
-+#endif
-+
-+static inline u16 flash_read16(void __iomem *addr)
-+{
-+      return be16_to_cpu(__raw_readw((void __iomem *)((unsigned long)addr ^ 0x2)));
-+}
-+
-+static inline void flash_write16(u16 d, void __iomem *addr)
-+{
-+      __raw_writew(cpu_to_be16(d), (void __iomem *)((unsigned long)addr ^ 0x2));
-+}
-+
- #define       BYTE0(h)        ((h) & 0xFF)
- #define       BYTE1(h)        (((h) >> 8) & 0xFF)
-+
- #else
-+
-+static inline u16 flash_read16(const void __iomem *addr)
-+{
-+      return __raw_readw(addr);
-+}
-+
-+static inline void flash_write16(u16 d, void __iomem *addr)
-+{
-+      __raw_writew(d, addr);
-+}
-+
- #define       BYTE0(h)        (((h) >> 8) & 0xFF)
- #define       BYTE1(h)        ((h) & 0xFF)
- #endif
-@@ -45,7 +90,7 @@
- static map_word ixp4xx_read16(struct map_info *map, unsigned long ofs)
- {
-       map_word val;
--      val.x[0] = le16_to_cpu(readw(map->virt + ofs));
-+      val.x[0] = flash_read16(map->virt + ofs);
-       return val;
- }
-@@ -57,19 +102,28 @@
- static void ixp4xx_copy_from(struct map_info *map, void *to,
-                            unsigned long from, ssize_t len)
- {
--      int i;
-       u8 *dest = (u8 *) to;
-       void __iomem *src = map->virt + from;
--      u16 data;
--      for (i = 0; i < (len / 2); i++) {
--              data = le16_to_cpu(readw(src + 2*i));
--              dest[i * 2] = BYTE0(data);
--              dest[i * 2 + 1] = BYTE1(data);
-+      if (len <= 0)
-+              return;
-+
-+      if (from & 1) {
-+              *dest++ = BYTE1(flash_read16(src));
-+                src++;
-+              --len;
-       }
--      if (len & 1)
--              dest[len - 1] = BYTE0(le16_to_cpu(readw(src + 2*i)));
-+      while (len >= 2) {
-+              u16 data = flash_read16(src);
-+              *dest++ = BYTE0(data);
-+              *dest++ = BYTE1(data);
-+              src += 2;
-+              len -= 2;
-+        }
-+
-+      if (len > 0)
-+              *dest++ = BYTE0(flash_read16(src));
- }
- /*
-@@ -79,7 +133,7 @@
- static void ixp4xx_probe_write16(struct map_info *map, map_word d, unsigned long adr)
- {
-       if (!(adr & 1))
--              writew(cpu_to_le16(d.x[0]), map->virt + adr);
-+              flash_write16(d.x[0], map->virt + adr);
- }
- /*
-@@ -87,7 +141,7 @@
-  */
- static void ixp4xx_write16(struct map_info *map, map_word d, unsigned long adr)
- {
--      writew(cpu_to_le16(d.x[0]), map->virt + adr);
-+      flash_write16(d.x[0], map->virt + adr);
- }
- struct ixp4xx_flash_info {