]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge current mainline tree into linux-omap tree
authorTony Lindgren <tony@atomide.com>
Fri, 3 Apr 2009 00:10:56 +0000 (17:10 -0700)
committerTony Lindgren <tony@atomide.com>
Fri, 3 Apr 2009 00:10:56 +0000 (17:10 -0700)
Merge branches 'master' and 'linus'

Conflicts:
arch/arm/configs/omap_3430sdp_defconfig
arch/arm/configs/rx51_defconfig
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/board-2430sdp.c
arch/arm/mach-omap2/board-3430sdp.c
arch/arm/mach-omap2/board-apollon.c
arch/arm/mach-omap2/board-h4.c
arch/arm/mach-omap2/board-ldp.c
arch/arm/mach-omap2/board-omap3beagle.c
arch/arm/mach-omap2/board-omap3pandora.c
arch/arm/mach-omap2/board-overo.c
arch/arm/mach-omap2/board-rx51-peripherals.c
arch/arm/mach-omap2/board-rx51.c
arch/arm/mach-omap2/mmc-twl4030.c
arch/arm/mach-omap2/mmc-twl4030.h
arch/arm/mach-omap2/usb-musb.c
arch/arm/plat-omap/dma.c
arch/arm/plat-omap/include/mach/board-nokia.h
arch/arm/plat-omap/include/mach/irqs.h
arch/arm/plat-omap/include/mach/usb.h
drivers/Makefile
drivers/i2c/chips/Kconfig
drivers/video/omap/omapfb_main.c
net/ipv4/netfilter/Makefile

41 files changed:
1  2 
Makefile
arch/arm/Kconfig
arch/arm/include/asm/setup.h
arch/arm/mach-omap1/Kconfig
arch/arm/mach-omap2/Kconfig
arch/arm/plat-omap/gpio.c
arch/arm/plat-omap/include/mach/irqs.h
arch/arm/plat-omap/sram.c
drivers/Makefile
drivers/char/hw_random/omap-rng.c
drivers/crypto/Kconfig
drivers/crypto/Makefile
drivers/hwmon/Kconfig
drivers/hwmon/Makefile
drivers/i2c/busses/i2c-omap.c
drivers/i2c/chips/Kconfig
drivers/i2c/chips/Makefile
drivers/input/keyboard/Kconfig
drivers/input/keyboard/lm8323.c
drivers/input/keyboard/tsc2301_kp.c
drivers/input/touchscreen/tsc2005.c
drivers/input/touchscreen/tsc2301_ts.c
drivers/leds/Kconfig
drivers/misc/Kconfig
drivers/misc/Makefile
drivers/mmc/host/omap.c
drivers/mmc/host/omap_hsmmc.c
drivers/mtd/maps/Kconfig
drivers/mtd/maps/Makefile
drivers/mtd/nand/Kconfig
drivers/mtd/nand/omap-nand-flash.c
drivers/mtd/nand/omap2.c
drivers/net/smc91x.c
drivers/spi/omap2_mcspi.c
drivers/usb/Kconfig
drivers/usb/host/Kconfig
drivers/usb/host/ehci-hcd.c
drivers/video/omap/omapfb_main.c
include/linux/connector.h
net/ipv4/netfilter/Kconfig
net/ipv4/netfilter/Makefile

diff --combined Makefile
index cf782ca3b6cadc7c567884b896ba091713734b05,c6307b6d069f8ec9a969ca6ad617245b95486d94..a04da9376d1d849add2337e671faa74422ab5567
+++ b/Makefile
@@@ -16,9 -16,6 +16,9 @@@ NAME = Temporary Tasmanian Devi
  # o  print "Entering directory ...";
  MAKEFLAGS += -rR --no-print-directory
  
 +# Add custom flags here to avoid conflict with updates
 +EXTRAVERSION := $(EXTRAVERSION)-omap1
 +
  # We are using a recursive build, so we need to do a little thinking
  # to get the ordering right.
  #
@@@ -174,8 -171,6 +174,8 @@@ SUBARCH := $(shell uname -m | sed -e s/
                                  -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
                                  -e s/sh.*/sh/ )
  
 +SUBARCH := arm
 +
  # Cross compiling and selecting different set of gcc/bin-utils
  # ---------------------------------------------------------------------------
  #
  # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
  export KBUILD_BUILDHOST := $(SUBARCH)
  ARCH          ?= $(SUBARCH)
 -CROSS_COMPILE ?=
 +CROSS_COMPILE ?= arm-linux-
  
  # Architecture as present in compile.h
  UTS_MACHINE   := $(ARCH)
@@@ -538,8 -533,9 +538,9 @@@ KBUILD_CFLAGS += $(call cc-option,-Wfra
  endif
  
  # Force gcc to behave correct even for buggy distributions
- # Arch Makefiles may override this setting
+ ifndef CONFIG_CC_STACKPROTECTOR
  KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector)
+ endif
  
  ifdef CONFIG_FRAME_POINTER
  KBUILD_CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls
diff --combined arch/arm/Kconfig
index e7fb2016a1a803715eec1607360d3d78af44a7fa,e02b893fb9097f4fd97508a10ebc7b9e5c05f8ef..fd5663bf4b35d2dd2258e30c34fcf09c394a8b22
@@@ -241,6 -241,7 +241,7 @@@ config ARCH_VERSATIL
  config ARCH_AT91
        bool "Atmel AT91"
        select GENERIC_GPIO
+       select ARCH_REQUIRE_GPIOLIB
        select HAVE_CLK
        help
          This enables support for systems based on the Atmel AT91RM9200,
@@@ -275,6 -276,14 +276,14 @@@ config ARCH_EP93X
        help
          This enables support for the Cirrus EP93xx series of CPUs.
  
+ config ARCH_GEMINI
+       bool "Cortina Systems Gemini"
+       select CPU_FA526
+       select GENERIC_GPIO
+       select ARCH_REQUIRE_GPIOLIB
+       help
+         Support for the Cortina Systems Gemini family SoCs
  config ARCH_FOOTBRIDGE
        bool "FootBridge"
        select CPU_SA110
@@@ -477,12 -486,29 +486,29 @@@ config ARCH_PX
        select HAVE_CLK
        select COMMON_CLKDEV
        select ARCH_REQUIRE_GPIOLIB
+       select HAVE_CLK
+       select COMMON_CLKDEV
        select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
        select TICK_ONESHOT
+       select PLAT_PXA
        help
          Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
  
+ config ARCH_MMP
+       bool "Marvell PXA168/910"
+       depends on MMU
+       select GENERIC_GPIO
+       select ARCH_REQUIRE_GPIOLIB
+       select HAVE_CLK
+       select COMMON_CLKDEV
+       select GENERIC_TIME
+       select GENERIC_CLOCKEVENTS
+       select TICK_ONESHOT
+       select PLAT_PXA
+       help
+         Support for Marvell's PXA168/910 processor line.
  config ARCH_RPC
        bool "RiscPC"
        select ARCH_ACORN
@@@ -598,6 -624,8 +624,8 @@@ source "arch/arm/mach-ep93xx/Kconfig
  
  source "arch/arm/mach-footbridge/Kconfig"
  
+ source "arch/arm/mach-gemini/Kconfig"
  source "arch/arm/mach-integrator/Kconfig"
  
  source "arch/arm/mach-iop32x/Kconfig"
@@@ -617,6 -645,9 +645,9 @@@ source "arch/arm/mach-loki/Kconfig
  source "arch/arm/mach-mv78xx0/Kconfig"
  
  source "arch/arm/mach-pxa/Kconfig"
+ source "arch/arm/plat-pxa/Kconfig"
+ source "arch/arm/mach-mmp/Kconfig"
  
  source "arch/arm/mach-sa1100/Kconfig"
  
@@@ -686,12 -717,15 +717,15 @@@ config PLAT_IO
  config PLAT_ORION
        bool
  
+ config PLAT_PXA
+       bool
  source arch/arm/mm/Kconfig
  
  config IWMMXT
        bool "Enable iWMMXt support"
-       depends on CPU_XSCALE || CPU_XSC3
-       default y if PXA27x || PXA3xx
+       depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK
+       default y if PXA27x || PXA3xx || ARCH_MMP
        help
          Enable support for iWMMXt context switching at run time if
          running on a CPU that supports it.
@@@ -915,6 -949,23 +949,23 @@@ config NODES_SHIF
        default "2"
        depends on NEED_MULTIPLE_NODES
  
+ config HIGHMEM
+       bool "High Memory Support (EXPERIMENTAL)"
+       depends on MMU && EXPERIMENTAL
+       help
+         The address space of ARM processors is only 4 Gigabytes large
+         and it has to accommodate user address space, kernel address
+         space as well as some memory mapped IO. That means that, if you
+         have a large amount of physical memory and/or IO, not all of the
+         memory can be "permanently mapped" by the kernel. The physical
+         memory that is not permanently mapped is called "high memory".
+         Depending on the selected kernel/user memory split, minimum
+         vmalloc space and actual amount of RAM, you may not need this
+         option which should result in a slightly faster kernel.
+         If unsure, say n.
  source "mm/Kconfig"
  
  config LEDS
@@@ -1092,7 -1143,7 +1143,7 @@@ source "drivers/cpufreq/Kconfig
  
  config CPU_FREQ_SA1100
        bool
-       depends on CPU_FREQ && (SA1100_H3100 || SA1100_H3600 || SA1100_H3800 || SA1100_LART || SA1100_PLEB || SA1100_BADGE4 || SA1100_HACKKIT)
+       depends on CPU_FREQ && (SA1100_H3100 || SA1100_H3600 || SA1100_LART || SA1100_PLEB || SA1100_BADGE4 || SA1100_HACKKIT)
        default y
  
  config CPU_FREQ_SA1110
@@@ -1327,10 -1378,6 +1378,10 @@@ source "drivers/uio/Kconfig
  
  source "drivers/staging/Kconfig"
  
 +if ARCH_OMAP
 +source "drivers/cbus/Kconfig"
 +endif
 +
  endmenu
  
  source "fs/Kconfig"
index 7ffbb29a0e9dc3e03e8ee1a5b53042e366ce6a59,ee1304f22f944c3104d28d44c1b0eeb05957eb22..2e0b9e04f12e85176aeb38b84baf3a6e84a08b60
@@@ -14,7 -14,7 +14,7 @@@
  #ifndef __ASMARM_SETUP_H
  #define __ASMARM_SETUP_H
  
- #include <asm/types.h>
+ #include <linux/types.h>
  
  #define COMMAND_LINE_SIZE 1024
  
@@@ -136,13 -136,6 +136,13 @@@ struct tag_acorn 
        __u8 adfsdrives;
  };
  
 +/* TI OMAP specific information */
 +#define ATAG_BOARD       0x414f4d50
 +
 +struct tag_omap {
 +      u8 data[0];
 +};
 +
  /* footbridge memory clock, see arch/arm/mach-footbridge/arch.c */
  #define ATAG_MEMCLK   0x41000402
  
@@@ -168,11 -161,6 +168,11 @@@ struct tag 
                 */
                struct tag_acorn        acorn;
  
 +              /*
 +               * OMAP specific
 +                 */
 +                struct tag_omap         omap;
 +
                /*
                 * DC21285 specific
                 */
index a95a2f30ed8b97934f4932ab2750c3ecd8ffa891,3f325d3718a9909a1e4c8edce9b34d4b115ce4fe..a51c730da64aa90294833747fd8cebe5615ac6e2
@@@ -7,6 -7,11 +7,11 @@@ config ARCH_OMAP73
        select CPU_ARM926T
        select ARCH_OMAP_OTG
  
+ config ARCH_OMAP850
+       depends on ARCH_OMAP1
+       bool "OMAP850 Based System"
+       select CPU_ARM926T
  config ARCH_OMAP15XX
        depends on ARCH_OMAP1
        default y
@@@ -41,10 -46,17 +46,16 @@@ config MACH_OMAP_H
  config MACH_OMAP_H3
        bool "TI H3 Support"
        depends on ARCH_OMAP1 && ARCH_OMAP16XX
 -#     select GPIOEXPANDER_OMAP
        help
          TI OMAP 1710 H3 board support. Say Y here if you have such
          a board.
  
+ config MACH_OMAP_HTCWIZARD
+       bool "HTC Wizard"
+       depends on ARCH_OMAP850
+       help
+         HTC Wizard smartphone support (AKA QTEK 9100, ...)
  config MACH_OMAP_OSK
        bool "TI OSK Support"
        depends on ARCH_OMAP1 && ARCH_OMAP16XX
@@@ -162,7 -174,7 +173,7 @@@ config OMAP_ARM_216MH
  
  config OMAP_ARM_195MHZ
        bool "OMAP ARM 195 MHz CPU"
-       depends on ARCH_OMAP1 && ARCH_OMAP730
+       depends on ARCH_OMAP1 && (ARCH_OMAP730 || ARCH_OMAP850)
        help
            Enable 195MHz clock for OMAP CPU. If unsure, say N.
  
@@@ -174,13 -186,13 +185,13 @@@ config OMAP_ARM_192MH
  
  config OMAP_ARM_182MHZ
        bool "OMAP ARM 182 MHz CPU"
-       depends on ARCH_OMAP1 && ARCH_OMAP730
+       depends on ARCH_OMAP1 && (ARCH_OMAP730 || ARCH_OMAP850)
        help
            Enable 182MHz clock for OMAP CPU. If unsure, say N.
  
  config OMAP_ARM_168MHZ
        bool "OMAP ARM 168 MHz CPU"
-       depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730)
+       depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850)
        help
            Enable 168MHz clock for OMAP CPU. If unsure, say N.
  
@@@ -192,20 -204,20 +203,20 @@@ config OMAP_ARM_150MH
  
  config OMAP_ARM_120MHZ
        bool "OMAP ARM 120 MHz CPU"
-       depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730)
+       depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850)
        help
            Enable 120MHz clock for OMAP CPU. If unsure, say N.
  
  config OMAP_ARM_60MHZ
        bool "OMAP ARM 60 MHz CPU"
-       depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730)
+       depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850)
          default y
        help
            Enable 60MHz clock for OMAP CPU. If unsure, say Y.
  
  config OMAP_ARM_30MHZ
        bool "OMAP ARM 30 MHz CPU"
-       depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730)
+       depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850)
        help
            Enable 30MHz clock for OMAP CPU. If unsure, say N.
  
index 8fa650d35365267585e2883f3ef9dd87e13447f2,64ab386a65c775ff7553d24b65ab8c4928d64210..3a2214cb37aba18fb5f4964223d79693902b1029
@@@ -10,13 -10,10 +10,13 @@@ config ARCH_OMAP242
        depends on ARCH_OMAP24XX
        select OMAP_DM_TIMER
        select ARCH_OMAP_OTG
 +      select CPU_V6
  
  config ARCH_OMAP2430
        bool "OMAP2430 support"
        depends on ARCH_OMAP24XX
 +      select ARCH_OMAP_OTG
 +      select CPU_V6
  
  config ARCH_OMAP34XX
        bool "OMAP34xx Based System"
@@@ -26,7 -23,6 +26,7 @@@ config ARCH_OMAP343
        bool "OMAP3430 support"
        depends on ARCH_OMAP3 && ARCH_OMAP34XX
        select ARCH_OMAP_OTG
 +      select CPU_V7
  
  comment "OMAP Board Type"
        depends on ARCH_OMAP2 || ARCH_OMAP3
@@@ -35,98 -31,25 +35,98 @@@ config MACH_OMAP_GENERI
        bool "Generic OMAP board"
        depends on ARCH_OMAP2 && ARCH_OMAP24XX
  
 +config MACH_NOKIA_N800
 +      bool "Nokia N800"
 +      depends on ARCH_OMAP2420
 +      select VIDEO_TCM825X if VIDEO_OMAP2 && VIDEO_HELPER_CHIPS_AUTO
 +      select CBUS if VIDEO_TCM825X
 +      select CBUS_RETU if VIDEO_TCM825X
 +      select MENELAUS if VIDEO_TCM825X
 +      select OMAP_GPIO_SWITCH
 +
 +config MACH_NOKIA_N810
 +      bool "Nokia N810"
 +      depends on MACH_NOKIA_N800
 +
 +config MACH_NOKIA_N810_WIMAX
 +      bool "Nokia N810 WiMAX"
 +      depends on MACH_NOKIA_N800
 +      select MACH_NOKIA_N810
 +
 +config MACH_NOKIA_RX51
 +      bool "Nokia RX-51 board"
 +      depends on ARCH_OMAP3 && ARCH_OMAP34XX
 +
 +config MACH_OMAP2_TUSB6010
 +      bool
 +      depends on ARCH_OMAP2 && ARCH_OMAP2420
 +      default y if MACH_NOKIA_N800
 +
  config MACH_OMAP_H4
        bool "OMAP 2420 H4 board"
 -      depends on ARCH_OMAP2 && ARCH_OMAP24XX
 +      depends on ARCH_OMAP2 && ARCH_OMAP2420
        select OMAP_DEBUG_DEVICES
  
 +config MACH_OMAP_H4_TUSB
 +      bool "TUSB 6010 EVM board"
 +      depends on MACH_OMAP_H4
 +      select MACH_OMAP2_TUSB6010
 +      help
 +        Set this if you've got a TUSB6010 high speed USB board.
 +        You may need to consult the schematics for your revisions
 +        of the Menelaus and TUSB boards, and make changes to be
 +        sure this is set up properly for your board stack.
 +
 +        Be sure to select OTG mode operation, not host-only or
 +        peripheral-only.
 +
 +config MACH_OMAP_H4_OTG
 +      bool "Use USB OTG connector, not device connector (S1.10)"
 +      depends on MACH_OMAP_H4
 +      help
 +        Set this if you've set S1.10 (on the mainboard) to use the
 +        Mini-AB (OTG) connector and OTG transceiver with the USB0
 +        port, instead of the Mini-B ("download") connector with its
 +        non-OTG transceiver.
 +
 +        Note that the "download" connector can be used to bootstrap
 +        the system from the OMAP mask ROM.  Also, since this is a
 +        development platform, you can also force the OTG port into
 +        a non-OTG operational mode.
 +
 +config MACH_OMAP2_H4_USB1
 +      bool "Use USB1 port, not UART2 (S3.3)"
 +      depends on MACH_OMAP_H4
 +      help
 +        Set this if you've set SW3.3 (on the CPU card) so that the
 +        expansion connectors receive USB1 signals instead of UART2.
 +
  config MACH_OMAP_APOLLON
        bool "OMAP 2420 Apollon board"
 -      depends on ARCH_OMAP2 && ARCH_OMAP24XX
 +      depends on ARCH_OMAP2 && ARCH_OMAP2420
  
  config MACH_OMAP_2430SDP
        bool "OMAP 2430 SDP board"
 +      depends on ARCH_OMAP2 && ARCH_OMAP2430
 +
 +config MACH_OMAP_LDP
 +      bool "OMAP3 LDP board"
 +      depends on ARCH_OMAP3 && ARCH_OMAP34XX
 +
 +config MACH_OMAP2EVM 
 +      bool "OMAP 2530 EVM board"
        depends on ARCH_OMAP2 && ARCH_OMAP24XX
  
 -config MACH_OMAP3_BEAGLE
 -      bool "OMAP3 BEAGLE board"
 +config MACH_OMAP_3430SDP
 +      bool "OMAP 3430 SDP board"
        depends on ARCH_OMAP3 && ARCH_OMAP34XX
  
 -config MACH_OMAP_LDP
 -      bool "OMAP3 LDP board"
 +config MACH_OMAP3EVM
 +      bool "OMAP 3530 EVM board"
 +      depends on ARCH_OMAP3 && ARCH_OMAP34XX
 +
 +config MACH_OMAP3_BEAGLE
 +      bool "OMAP3 BEAGLE board"
        depends on ARCH_OMAP3 && ARCH_OMAP34XX
  
  config MACH_OVERO
  config MACH_OMAP3_PANDORA
        bool "OMAP3 Pandora"
        depends on ARCH_OMAP3 && ARCH_OMAP34XX
+ config MACH_OMAP_3430SDP
+       bool "OMAP 3430 SDP board"
+       depends on ARCH_OMAP3 && ARCH_OMAP34XX
+ config MACH_NOKIA_RX51
+       bool "Nokia RX-51 board"
+       depends on ARCH_OMAP3 && ARCH_OMAP34XX
index 798a8cd811a946e03cfaff6190f1c08a95653654,d3fa41e3d8c5a79235eb687dc4dc9ae92f330b77..210a1c04555488cf9d4d39856557b9caac029b53
  #define OMAP730_GPIO_INT_MASK         0x10
  #define OMAP730_GPIO_INT_STATUS               0x14
  
+ /*
+  * OMAP850 specific GPIO registers
+  */
+ #define OMAP850_GPIO1_BASE            IO_ADDRESS(0xfffbc000)
+ #define OMAP850_GPIO2_BASE            IO_ADDRESS(0xfffbc800)
+ #define OMAP850_GPIO3_BASE            IO_ADDRESS(0xfffbd000)
+ #define OMAP850_GPIO4_BASE            IO_ADDRESS(0xfffbd800)
+ #define OMAP850_GPIO5_BASE            IO_ADDRESS(0xfffbe000)
+ #define OMAP850_GPIO6_BASE            IO_ADDRESS(0xfffbe800)
+ #define OMAP850_GPIO_DATA_INPUT               0x00
+ #define OMAP850_GPIO_DATA_OUTPUT      0x04
+ #define OMAP850_GPIO_DIR_CONTROL      0x08
+ #define OMAP850_GPIO_INT_CONTROL      0x0c
+ #define OMAP850_GPIO_INT_MASK         0x10
+ #define OMAP850_GPIO_INT_STATUS               0x14
  /*
   * omap24xx specific GPIO registers
   */
@@@ -159,7 -175,8 +175,8 @@@ struct gpio_bank 
  #define METHOD_GPIO_1510      1
  #define METHOD_GPIO_1610      2
  #define METHOD_GPIO_730               3
- #define METHOD_GPIO_24XX      4
+ #define METHOD_GPIO_850               4
+ #define METHOD_GPIO_24XX      5
  
  #ifdef CONFIG_ARCH_OMAP16XX
  static struct gpio_bank gpio_bank_1610[5] = {
@@@ -190,6 -207,19 +207,19 @@@ static struct gpio_bank gpio_bank_730[7
  };
  #endif
  
+ #ifdef CONFIG_ARCH_OMAP850
+ static struct gpio_bank gpio_bank_850[7] = {
+       { OMAP_MPUIO_BASE,     INT_850_MPUIO,       IH_MPUIO_BASE,      METHOD_MPUIO },
+       { OMAP850_GPIO1_BASE,  INT_850_GPIO_BANK1,  IH_GPIO_BASE,       METHOD_GPIO_850 },
+       { OMAP850_GPIO2_BASE,  INT_850_GPIO_BANK2,  IH_GPIO_BASE + 32,  METHOD_GPIO_850 },
+       { OMAP850_GPIO3_BASE,  INT_850_GPIO_BANK3,  IH_GPIO_BASE + 64,  METHOD_GPIO_850 },
+       { OMAP850_GPIO4_BASE,  INT_850_GPIO_BANK4,  IH_GPIO_BASE + 96,  METHOD_GPIO_850 },
+       { OMAP850_GPIO5_BASE,  INT_850_GPIO_BANK5,  IH_GPIO_BASE + 128, METHOD_GPIO_850 },
+       { OMAP850_GPIO6_BASE,  INT_850_GPIO_BANK6,  IH_GPIO_BASE + 160, METHOD_GPIO_850 },
+ };
+ #endif
  #ifdef CONFIG_ARCH_OMAP24XX
  
  static struct gpio_bank gpio_bank_242x[4] = {
@@@ -236,7 -266,7 +266,7 @@@ static inline struct gpio_bank *get_gpi
                        return &gpio_bank[0];
                return &gpio_bank[1 + (gpio >> 4)];
        }
-       if (cpu_is_omap730()) {
+       if (cpu_is_omap7xx()) {
                if (OMAP_GPIO_IS_MPUIO(gpio))
                        return &gpio_bank[0];
                return &gpio_bank[1 + (gpio >> 5)];
  
  static inline int get_gpio_index(int gpio)
  {
-       if (cpu_is_omap730())
+       if (cpu_is_omap7xx())
                return gpio & 0x1f;
        if (cpu_is_omap24xx())
                return gpio & 0x1f;
@@@ -273,7 -303,7 +303,7 @@@ static inline int gpio_valid(int gpio
                return 0;
        if ((cpu_is_omap16xx()) && gpio < 64)
                return 0;
-       if (cpu_is_omap730() && gpio < 192)
+       if (cpu_is_omap7xx() && gpio < 192)
                return 0;
        if (cpu_is_omap24xx() && gpio < 128)
                return 0;
@@@ -318,6 -348,11 +348,11 @@@ static void _set_gpio_direction(struct 
                reg += OMAP730_GPIO_DIR_CONTROL;
                break;
  #endif
+ #ifdef CONFIG_ARCH_OMAP850
+       case METHOD_GPIO_850:
+               reg += OMAP850_GPIO_DIR_CONTROL;
+               break;
+ #endif
  #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
        case METHOD_GPIO_24XX:
                reg += OMAP24XX_GPIO_OE;
@@@ -380,6 -415,16 +415,16 @@@ static void _set_gpio_dataout(struct gp
                        l &= ~(1 << gpio);
                break;
  #endif
+ #ifdef CONFIG_ARCH_OMAP850
+       case METHOD_GPIO_850:
+               reg += OMAP850_GPIO_DATA_OUTPUT;
+               l = __raw_readl(reg);
+               if (enable)
+                       l |= 1 << gpio;
+               else
+                       l &= ~(1 << gpio);
+               break;
+ #endif
  #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
        case METHOD_GPIO_24XX:
                if (enable)
@@@ -426,6 -471,11 +471,11 @@@ static int __omap_get_gpio_datain(int g
                reg += OMAP730_GPIO_DATA_INPUT;
                break;
  #endif
+ #ifdef CONFIG_ARCH_OMAP850
+       case METHOD_GPIO_850:
+               reg += OMAP850_GPIO_DATA_INPUT;
+               break;
+ #endif
  #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
        case METHOD_GPIO_24XX:
                reg += OMAP24XX_GPIO_DATAIN;
@@@ -598,6 -648,18 +648,18 @@@ static int _set_gpio_triggering(struct 
                        goto bad;
                break;
  #endif
+ #ifdef CONFIG_ARCH_OMAP850
+       case METHOD_GPIO_850:
+               reg += OMAP850_GPIO_INT_CONTROL;
+               l = __raw_readl(reg);
+               if (trigger & IRQ_TYPE_EDGE_RISING)
+                       l |= 1 << gpio;
+               else if (trigger & IRQ_TYPE_EDGE_FALLING)
+                       l &= ~(1 << gpio);
+               else
+                       goto bad;
+               break;
+ #endif
  #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
        case METHOD_GPIO_24XX:
                set_24xx_gpio_triggering(bank, gpio, trigger);
@@@ -678,6 -740,11 +740,11 @@@ static void _clear_gpio_irqbank(struct 
                reg += OMAP730_GPIO_INT_STATUS;
                break;
  #endif
+ #ifdef CONFIG_ARCH_OMAP850
+       case METHOD_GPIO_850:
+               reg += OMAP850_GPIO_INT_STATUS;
+               break;
+ #endif
  #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
        case METHOD_GPIO_24XX:
                reg += OMAP24XX_GPIO_IRQSTATUS1;
@@@ -736,6 -803,13 +803,13 @@@ static u32 _get_gpio_irqbank_mask(struc
                inv = 1;
                break;
  #endif
+ #ifdef CONFIG_ARCH_OMAP850
+       case METHOD_GPIO_850:
+               reg += OMAP850_GPIO_INT_MASK;
+               mask = 0xffffffff;
+               inv = 1;
+               break;
+ #endif
  #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
        case METHOD_GPIO_24XX:
                reg += OMAP24XX_GPIO_IRQENABLE1;
@@@ -799,6 -873,16 +873,16 @@@ static void _enable_gpio_irqbank(struc
                        l |= gpio_mask;
                break;
  #endif
+ #ifdef CONFIG_ARCH_OMAP850
+       case METHOD_GPIO_850:
+               reg += OMAP850_GPIO_INT_MASK;
+               l = __raw_readl(reg);
+               if (enable)
+                       l &= ~(gpio_mask);
+               else
+                       l |= gpio_mask;
+               break;
+ #endif
  #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
        case METHOD_GPIO_24XX:
                if (enable)
@@@ -837,10 -921,13 +921,10 @@@ static int _set_gpio_wakeup(struct gpio
        case METHOD_MPUIO:
        case METHOD_GPIO_1610:
                spin_lock_irqsave(&bank->lock, flags);
 -              if (enable) {
 +              if (enable)
                        bank->suspend_wakeup |= (1 << gpio);
 -                      enable_irq_wake(bank->irq);
 -              } else {
 -                      disable_irq_wake(bank->irq);
 +              else
                        bank->suspend_wakeup &= ~(1 << gpio);
 -              }
                spin_unlock_irqrestore(&bank->lock, flags);
                return 0;
  #endif
                        return -EINVAL;
                }
                spin_lock_irqsave(&bank->lock, flags);
 -              if (enable) {
 +              if (enable)
                        bank->suspend_wakeup |= (1 << gpio);
 -                      enable_irq_wake(bank->irq);
 -              } else {
 -                      disable_irq_wake(bank->irq);
 +              else
                        bank->suspend_wakeup &= ~(1 << gpio);
 -              }
                spin_unlock_irqrestore(&bank->lock, flags);
                return 0;
  #endif
@@@ -977,6 -1067,10 +1061,10 @@@ static void gpio_irq_handler(unsigned i
        if (bank->method == METHOD_GPIO_730)
                isr_reg = bank->base + OMAP730_GPIO_INT_STATUS;
  #endif
+ #ifdef CONFIG_ARCH_OMAP850
+       if (bank->method == METHOD_GPIO_850)
+               isr_reg = bank->base + OMAP850_GPIO_INT_STATUS;
+ #endif
  #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
        if (bank->method == METHOD_GPIO_24XX)
                isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1;
@@@ -1366,6 -1460,13 +1454,13 @@@ static int __init _omap_gpio_init(void
                gpio_bank = gpio_bank_730;
        }
  #endif
+ #ifdef CONFIG_ARCH_OMAP850
+       if (cpu_is_omap850()) {
+               printk(KERN_INFO "OMAP850 GPIO hardware\n");
+               gpio_bank_count = 7;
+               gpio_bank = gpio_bank_850;
+       }
+ #endif
  
  #ifdef CONFIG_ARCH_OMAP24XX
        if (cpu_is_omap242x()) {
                        __raw_writew(0xffff, bank->base + OMAP1610_GPIO_IRQSTATUS1);
                        __raw_writew(0x0014, bank->base + OMAP1610_GPIO_SYSCONFIG);
                }
-               if (cpu_is_omap730() && bank->method == METHOD_GPIO_730) {
+               if (cpu_is_omap7xx() && bank->method == METHOD_GPIO_730) {
                        __raw_writel(0xffffffff, bank->base + OMAP730_GPIO_INT_MASK);
                        __raw_writel(0x00000000, bank->base + OMAP730_GPIO_INT_STATUS);
  
@@@ -1737,6 -1838,9 +1832,9 @@@ static int gpio_is_input(struct gpio_ba
        case METHOD_GPIO_730:
                reg += OMAP730_GPIO_DIR_CONTROL;
                break;
+       case METHOD_GPIO_850:
+               reg += OMAP850_GPIO_DIR_CONTROL;
+               break;
        case METHOD_GPIO_24XX:
                reg += OMAP24XX_GPIO_OE;
                break;
@@@ -1756,7 -1860,8 +1854,8 @@@ static int dbg_gpio_show(struct seq_fil
  
                if (bank_is_mpuio(bank))
                        gpio = OMAP_MPUIO(0);
-               else if (cpu_class_is_omap2() || cpu_is_omap730())
+               else if (cpu_class_is_omap2() || cpu_is_omap730() ||
+                               cpu_is_omap850())
                        bankwidth = 32;
  
                for (j = 0; j < bankwidth; j++, gpio++, mask <<= 1) {
index d12c39fd76c022913bca32c1b3ed30ffdc09310e,7f57ee66f364dd0ad65092f58d62066c95a3604d..9499a0520e0f5554de292d4cef2e757fd0b4d22e
  #define INT_730_GPIO_BANK6    18
  #define INT_730_SPGIO_WR      29
  
+ /*
+  * OMAP-850 specific IRQ numbers for interrupt handler 1
+  */
+ #define INT_850_IH2_FIQ               0
+ #define INT_850_IH2_IRQ               1
+ #define INT_850_USB_NON_ISO   2
+ #define INT_850_USB_ISO               3
+ #define INT_850_ICR           4
+ #define INT_850_EAC           5
+ #define INT_850_GPIO_BANK1    6
+ #define INT_850_GPIO_BANK2    7
+ #define INT_850_GPIO_BANK3    8
+ #define INT_850_McBSP2TX      10
+ #define INT_850_McBSP2RX      11
+ #define INT_850_McBSP2RX_OVF  12
+ #define INT_850_LCD_LINE      14
+ #define INT_850_GSM_PROTECT   15
+ #define INT_850_TIMER3                16
+ #define INT_850_GPIO_BANK5    17
+ #define INT_850_GPIO_BANK6    18
+ #define INT_850_SPGIO_WR      29
  /*
   * IRQ numbers for interrupt handler 2
   *
  #define INT_730_DMA_CH15      (62 + IH2_BASE)
  #define INT_730_NAND          (63 + IH2_BASE)
  
+ /*
+  * OMAP-850 specific IRQ numbers for interrupt handler 2
+  */
+ #define INT_850_HW_ERRORS     (0 + IH2_BASE)
+ #define INT_850_NFIQ_PWR_FAIL (1 + IH2_BASE)
+ #define INT_850_CFCD          (2 + IH2_BASE)
+ #define INT_850_CFIREQ                (3 + IH2_BASE)
+ #define INT_850_I2C           (4 + IH2_BASE)
+ #define INT_850_PCC           (5 + IH2_BASE)
+ #define INT_850_MPU_EXT_NIRQ  (6 + IH2_BASE)
+ #define INT_850_SPI_100K_1    (7 + IH2_BASE)
+ #define INT_850_SYREN_SPI     (8 + IH2_BASE)
+ #define INT_850_VLYNQ         (9 + IH2_BASE)
+ #define INT_850_GPIO_BANK4    (10 + IH2_BASE)
+ #define INT_850_McBSP1TX      (11 + IH2_BASE)
+ #define INT_850_McBSP1RX      (12 + IH2_BASE)
+ #define INT_850_McBSP1RX_OF   (13 + IH2_BASE)
+ #define INT_850_UART_MODEM_IRDA_2 (14 + IH2_BASE)
+ #define INT_850_UART_MODEM_1  (15 + IH2_BASE)
+ #define INT_850_MCSI          (16 + IH2_BASE)
+ #define INT_850_uWireTX               (17 + IH2_BASE)
+ #define INT_850_uWireRX               (18 + IH2_BASE)
+ #define INT_850_SMC_CD                (19 + IH2_BASE)
+ #define INT_850_SMC_IREQ      (20 + IH2_BASE)
+ #define INT_850_HDQ_1WIRE     (21 + IH2_BASE)
+ #define INT_850_TIMER32K      (22 + IH2_BASE)
+ #define INT_850_MMC_SDIO      (23 + IH2_BASE)
+ #define INT_850_UPLD          (24 + IH2_BASE)
+ #define INT_850_USB_HHC_1     (27 + IH2_BASE)
+ #define INT_850_USB_HHC_2     (28 + IH2_BASE)
+ #define INT_850_USB_GENI      (29 + IH2_BASE)
+ #define INT_850_USB_OTG               (30 + IH2_BASE)
+ #define INT_850_CAMERA_IF     (31 + IH2_BASE)
+ #define INT_850_RNG           (32 + IH2_BASE)
+ #define INT_850_DUAL_MODE_TIMER (33 + IH2_BASE)
+ #define INT_850_DBB_RF_EN     (34 + IH2_BASE)
+ #define INT_850_MPUIO_KEYPAD  (35 + IH2_BASE)
+ #define INT_850_SHA1_MD5      (36 + IH2_BASE)
+ #define INT_850_SPI_100K_2    (37 + IH2_BASE)
+ #define INT_850_RNG_IDLE      (38 + IH2_BASE)
+ #define INT_850_MPUIO         (39 + IH2_BASE)
+ #define INT_850_LLPC_LCD_CTRL_CAN_BE_OFF      (40 + IH2_BASE)
+ #define INT_850_LLPC_OE_FALLING (41 + IH2_BASE)
+ #define INT_850_LLPC_OE_RISING        (42 + IH2_BASE)
+ #define INT_850_LLPC_VSYNC    (43 + IH2_BASE)
+ #define INT_850_WAKE_UP_REQ   (46 + IH2_BASE)
+ #define INT_850_DMA_CH6               (53 + IH2_BASE)
+ #define INT_850_DMA_CH7               (54 + IH2_BASE)
+ #define INT_850_DMA_CH8               (55 + IH2_BASE)
+ #define INT_850_DMA_CH9               (56 + IH2_BASE)
+ #define INT_850_DMA_CH10      (57 + IH2_BASE)
+ #define INT_850_DMA_CH11      (58 + IH2_BASE)
+ #define INT_850_DMA_CH12      (59 + IH2_BASE)
+ #define INT_850_DMA_CH13      (60 + IH2_BASE)
+ #define INT_850_DMA_CH14      (61 + IH2_BASE)
+ #define INT_850_DMA_CH15      (62 + IH2_BASE)
+ #define INT_850_NAND          (63 + IH2_BASE)
  #define INT_24XX_SYS_NIRQ     7
  #define INT_24XX_SDMA_IRQ0    12
  #define INT_24XX_SDMA_IRQ1    13
  #define INT_34XX_MMC3_IRQ     94
  #define INT_34XX_GPT12_IRQ    95
  
- /* Max. 128 level 2 IRQs (OMAP1610), 192 GPIOs (OMAP730) and
 -#define       INT_34XX_BENCH_MPU_EMUL 3
 -
+ /* Max. 128 level 2 IRQs (OMAP1610), 192 GPIOs (OMAP730/850) and
   * 16 MPUIO lines */
  #define OMAP_MAX_GPIO_LINES   192
  #define IH_GPIO_BASE          (128 + IH2_BASE)
  
  #ifndef __ASSEMBLY__
  extern void omap_init_irq(void);
 +extern int omap_irq_pending(void);
  #endif
  
  #include <mach/hardware.h>
index 9242fe5b95a49809563dcc749e0c01e37596ca98,fa5297d643d3f545d181551bdee853a2a0938251..e1e637f222c6673fb102c588eb0ef6616ba36462
@@@ -38,8 -38,8 +38,8 @@@
  #define OMAP1_SRAM_VA         VMALLOC_END
  #define OMAP2_SRAM_PA         0x40200000
  #define OMAP2_SRAM_PUB_PA     0x4020f800
 -#define OMAP2_SRAM_VA         VMALLOC_END
 -#define OMAP2_SRAM_PUB_VA     (VMALLOC_END + 0x800)
 +#define OMAP2_SRAM_VA         0xe3000000
 +#define OMAP2_SRAM_PUB_VA     (OMAP2_SRAM_VA + 0x800)
  #define OMAP3_SRAM_PA           0x40200000
  #define OMAP3_SRAM_VA           0xd7000000
  #define OMAP3_SRAM_PUB_PA       0x40208000
@@@ -148,7 -148,7 +148,7 @@@ void __init omap_detect_sram(void
                omap_sram_base = OMAP1_SRAM_VA;
                omap_sram_start = OMAP1_SRAM_PA;
  
-               if (cpu_is_omap730())
+               if (cpu_is_omap7xx())
                        omap_sram_size = 0x32000;       /* 200K */
                else if (cpu_is_omap15xx())
                        omap_sram_size = 0x30000;       /* 192K */
@@@ -359,14 -359,14 +359,14 @@@ static u32 (*_omap3_sram_configure_core
                                              u32 m2);
  u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl, u32 sdrc_actim_ctrla,
                              u32 sdrc_actim_ctrlb, u32 m2)
 -{
 + {
        if (!_omap3_sram_configure_core_dpll)
                omap_sram_error();
  
        return _omap3_sram_configure_core_dpll(sdrc_rfr_ctrl,
                                               sdrc_actim_ctrla,
                                               sdrc_actim_ctrlb, m2);
 -}
 + }
  
  /* REVISIT: Should this be same as omap34xx_sram_init() after off-idle? */
  void restore_sram_functions(void)
                               omap3_sram_configure_core_dpll_sz);
  }
  
 -int __init omap34xx_sram_init(void)
 +int __init omap3_sram_init(void)
  {
        _omap3_sram_configure_core_dpll =
                omap_sram_push(omap3_sram_configure_core_dpll,
        return 0;
  }
  #else
 -static inline int omap34xx_sram_init(void)
 +static inline int omap3_sram_init(void)
  {
        return 0;
  }
@@@ -405,7 -405,7 +405,7 @@@ int __init omap_sram_init(void
        else if (cpu_is_omap2430())
                omap243x_sram_init();
        else if (cpu_is_omap34xx())
 -              omap34xx_sram_init();
 +              omap3_sram_init();
  
        return 0;
  }
diff --combined drivers/Makefile
index fec4d8e2170719a51b03be06640664e70c955928,2618a6169a1304379a8644725f0663aee3ac7fd9..3db0a27a914a64cfcc1dffa3040b47af2946fca3
@@@ -34,20 -34,16 +34,21 @@@ obj-$(CONFIG_CONNECTOR)            += connector
  obj-$(CONFIG_FB_I810)           += video/i810/
  obj-$(CONFIG_FB_INTEL)          += video/intelfb/
  
 +# we also need input/serio early so serio bus is initialized by the time
 +# serial drivers start registering their serio ports
 +obj-$(CONFIG_SERIO)           += input/serio/
  obj-y                         += serial/
  obj-$(CONFIG_PARPORT)         += parport/
- obj-y                         += base/ block/ misc/ mfd/ net/ media/
+ obj-y                         += base/ block/ misc/ mfd/ media/
 +obj-y                         += i2c/
 +obj-y                         += cbus/
  obj-$(CONFIG_NUBUS)           += nubus/
- obj-$(CONFIG_ATM)             += atm/
  obj-y                         += macintosh/
  obj-$(CONFIG_IDE)             += ide/
  obj-$(CONFIG_SCSI)            += scsi/
  obj-$(CONFIG_ATA)             += ata/
+ obj-y                         += net/
+ obj-$(CONFIG_ATM)             += atm/
  obj-$(CONFIG_FUSION)          += message/
  obj-$(CONFIG_FIREWIRE)                += firewire/
  obj-y                         += ieee1394/
@@@ -70,10 -66,12 +71,10 @@@ obj-$(CONFIG_USB)          += usb
  obj-$(CONFIG_USB_MUSB_HDRC)   += usb/musb/
  obj-$(CONFIG_PCI)             += usb/
  obj-$(CONFIG_USB_GADGET)      += usb/gadget/
 -obj-$(CONFIG_SERIO)           += input/serio/
  obj-$(CONFIG_GAMEPORT)                += input/gameport/
  obj-$(CONFIG_INPUT)           += input/
  obj-$(CONFIG_I2O)             += message/
  obj-$(CONFIG_RTC_LIB)         += rtc/
 -obj-y                         += i2c/
  obj-$(CONFIG_W1)              += w1/
  obj-$(CONFIG_POWER_SUPPLY)    += power/
  obj-$(CONFIG_HWMON)           += hwmon/
index 5bced87d823d151c1ddefab7de69d1447a2b2453,538313f9e7ac6f8b45731b6ee49be2e8af0e0f8a..de201faa9df71640998b83500f07e190f5e1b97f
@@@ -102,7 -102,7 +102,7 @@@ static int __init omap_rng_probe(struc
                return -EBUSY;
  
        if (cpu_is_omap24xx()) {
-               rng_ick = clk_get(&pdev->dev, "rng_ick");
+               rng_ick = clk_get(&pdev->dev, "ick");
                if (IS_ERR(rng_ick)) {
                        dev_err(&pdev->dev, "Could not get rng_ick\n");
                        ret = PTR_ERR(rng_ick);
@@@ -205,6 -205,7 +205,6 @@@ static struct platform_driver omap_rng_
                .name           = "omap_rng",
                .owner          = THIS_MODULE,
        },
 -      .probe          = omap_rng_probe,
        .remove         = __exit_p(omap_rng_remove),
        .suspend        = omap_rng_suspend,
        .resume         = omap_rng_resume
@@@ -215,7 -216,7 +215,7 @@@ static int __init omap_rng_init(void
        if (!cpu_is_omap16xx() && !cpu_is_omap24xx())
                return -ENODEV;
  
 -      return platform_driver_register(&omap_rng_driver);
 +      return platform_driver_probe(&omap_rng_driver, omap_rng_probe);
  }
  
  static void __exit omap_rng_exit(void)
diff --combined drivers/crypto/Kconfig
index 7fb9494e4d80d5757b4f6185795fa647c0fad104,01afd758072f8242f550fc70b30b9c124aa8fa2b..f43cdd664258410b708541aa8d8383efcccfbd21
@@@ -83,17 -83,10 +83,17 @@@ config ZCRYPT_MONOLITHI
          that contains all parts of the crypto device driver (ap bus,
          request router and all the card drivers).
  
 +config OMAP_SHA1_MD5
 +      tristate "Support for OMAP SHA1/MD5 hw engine"
 +      depends on ARCH_OMAP24XX && CRYPTO_SHA1 && CRYPTO_MD5
 +      help
 +        OMAP processors have SHA1/MD5 module accelerator. Select this if you
 +        want to use the OMAP module for SHA1/MD5 algorithms.
 +
  config CRYPTO_SHA1_S390
        tristate "SHA1 digest algorithm"
        depends on S390
-       select CRYPTO_ALGAPI
+       select CRYPTO_HASH
        help
          This is the s390 hardware accelerated implementation of the
          SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
  config CRYPTO_SHA256_S390
        tristate "SHA256 digest algorithm"
        depends on S390
-       select CRYPTO_ALGAPI
+       select CRYPTO_HASH
        help
          This is the s390 hardware accelerated implementation of the
          SHA256 secure hash standard (DFIPS 180-2).
  config CRYPTO_SHA512_S390
        tristate "SHA384 and SHA512 digest algorithm"
        depends on S390
-       select CRYPTO_ALGAPI
+       select CRYPTO_HASH
        help
          This is the s390 hardware accelerated implementation of the
          SHA512 secure hash standard.
@@@ -207,4 -200,13 +207,13 @@@ config CRYPTO_DEV_IXP4X
        help
          Driver for the IXP4xx NPE crypto engine.
  
+ config CRYPTO_DEV_PPC4XX
+       tristate "Driver AMCC PPC4xx crypto accelerator"
+       depends on PPC && 4xx
+       select CRYPTO_HASH
+       select CRYPTO_ALGAPI
+       select CRYPTO_BLKCIPHER
+       help
+         This option allows you to have support for AMCC crypto acceleration.
  endif # CRYPTO_HW
diff --combined drivers/crypto/Makefile
index 5da41a156fc7871d6a399d6eb90a00ff754de51a,9bf4a2bc88461efdcbaca356a39728d84a9ca420..e6095f0f1778211b9bfa8434914898a90cd3b7dd
@@@ -1,7 -1,7 +1,8 @@@
  obj-$(CONFIG_CRYPTO_DEV_PADLOCK_AES) += padlock-aes.o
  obj-$(CONFIG_CRYPTO_DEV_PADLOCK_SHA) += padlock-sha.o
  obj-$(CONFIG_CRYPTO_DEV_GEODE) += geode-aes.o
 +obj-$(CONFIG_OMAP_SHA1_MD5) += omap-sha1-md5.o
  obj-$(CONFIG_CRYPTO_DEV_HIFN_795X) += hifn_795x.o
  obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o
  obj-$(CONFIG_CRYPTO_DEV_IXP4XX) += ixp4xx_crypto.o
+ obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += amcc/
diff --combined drivers/hwmon/Kconfig
index d65f6f93109d46cfce9ec7df83197557fa7729af,ce52bf2f235ed541660fe4a76d728272203ea816..d2b0eea3455189d5e451ccd95df8bafd8307d12c
@@@ -343,12 -343,13 +343,13 @@@ config SENSORS_FSCPO
          will be called fscpos.
  
  config SENSORS_FSCHMD
-       tristate "FSC Poseidon, Scylla, Hermes, Heimdall and Heracles"
+       tristate "Fujitsu Siemens Computers sensor chips"
        depends on X86 && I2C
        help
-         If you say yes here you get support for various Fujitsu Siemens
-         Computers sensor chips, including support for the integrated
-         watchdog.
+         If you say yes here you get support for the following Fujitsu
+         Siemens Computers (FSC) sensor chips: Poseidon, Scylla, Hermes,
+         Heimdall, Heracles, Hades and Syleus including support for the
+         integrated watchdog.
  
          This is a merged driver for FSC sensor chips replacing the fscpos,
          fscscy and fscher drivers and adding support for several other FSC
@@@ -570,6 -571,17 +571,17 @@@ config SENSORS_LM9
          This driver can also be built as a module.  If so, the module
          will be called lm93.
  
+ config SENSORS_LTC4215
+       tristate "Linear Technology LTC4215"
+       depends on I2C && EXPERIMENTAL
+       default n
+       help
+         If you say yes here you get support for Linear Technology LTC4215
+         Hot Swap Controller I2C interface.
+         This driver can also be built as a module. If so, the module will
+         be called ltc4215.
  config SENSORS_LTC4245
        tristate "Linear Technology LTC4245"
        depends on I2C && EXPERIMENTAL
          This driver can also be built as a module. If so, the module will
          be called ltc4245.
  
+ config SENSORS_LM95241
+       tristate "National Semiconductor LM95241 sensor chip"
+       depends on I2C
+       help
+         If you say yes here you get support for LM95241 sensor chip.
+         This driver can also be built as a module.  If so, the module
+         will be called lm95241.
  config SENSORS_MAX1111
        tristate "Maxim MAX1111 Multichannel, Serial 8-bit ADC chip"
        depends on SPI_MASTER
@@@ -635,6 -656,20 +656,20 @@@ config SENSORS_PC8742
          This driver can also be built as a module.  If so, the module
          will be called pc87427.
  
+ config SENSORS_PCF8591
+       tristate "Philips PCF8591 ADC/DAC"
+       depends on I2C
+       default n
+       help
+         If you say yes here you get support for Philips PCF8591 4-channel
+         ADC, 1-channel DAC chips.
+         This driver can also be built as a module.  If so, the module
+         will be called pcf8591.
+         These devices are hard to detect and rarely found on mainstream
+         hardware.  If unsure, say N.
  config SENSORS_SIS5595
        tristate "Silicon Integrated Systems Corp. SiS5595"
        depends on PCI
@@@ -827,7 -862,7 +862,7 @@@ config SENSORS_W83627H
          will be called w83627hf.
  
  config SENSORS_W83627EHF
-       tristate "Winbond W83627EHF/DHG"
+       tristate "Winbond W83627EHF/EHG/DHG, W83667HG"
        select HWMON_VID
        help
          If you say yes here you get support for the hardware
          chip suited for specific Intel processors that use PECI such as
          the Core 2 Duo.
  
+         This driver also supports the W83667HG chip.
          This driver can also be built as a module.  If so, the module
          will be called w83627ehf.
  
@@@ -895,6 -932,22 +932,22 @@@ config SENSORS_LIS3LV02
          Say Y here if you have an applicable laptop and want to experience
          the awesome power of lis3lv02d.
  
+ config SENSORS_LIS3_SPI
+       tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer (SPI)"
+       depends on !ACPI && SPI_MASTER && INPUT
+       default n
+       help
+         This driver provides support for the LIS3LV02Dx accelerometer connected
+         via SPI. The accelerometer data is readable via
+         /sys/devices/platform/lis3lv02d.
+         This driver also provides an absolute input class device, allowing
+         the laptop to act as a pinball machine-esque joystick.
+         This driver can also be built as modules.  If so, the core module
+         will be called lis3lv02d and a specific module for the SPI transport
+         is called lis3lv02d_spi.
  config SENSORS_APPLESMC
        tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)"
        depends on INPUT && X86
          Say Y here if you have an applicable laptop and want to experience
          the awesome power of applesmc.
  
 +config SENSORS_TSC210X
 +      tristate "TI TSC210x battery & temperature sensors"
 +      depends on HWMON && SPI_MASTER
 +      select SPI_TSC210X
 +      help
 +        Say Y if your board has a TSC210x chip and you want to
 +        have its battery state, auxiliary input and/or temperature
 +        sensors exported through hwmon.
 +
 +        This driver can also be built as a module.  In this case
 +        the module will be called tsc210x_sensors.
 +
 +config SENSORS_OMAP34XX
 +      tristate "TI OMAP34xx internal temperature sensor"
 +      depends on ARCH_OMAP3 && HIGH_RES_TIMERS
 +
  config HWMON_DEBUG_CHIP
        bool "Hardware Monitoring Chip debugging messages"
        default n
diff --combined drivers/hwmon/Makefile
index ad4fc07310dfc881255bd50d71a91bafaea9f138,3a6b1f06f8f4a50bd7440da3e7dbc34a0aee7567..a4a6320dcb2657fbbf522556ecbc771a57fe355e
@@@ -52,6 -52,7 +52,7 @@@ obj-$(CONFIG_SENSORS_IBMPEX)  += ibmpex.
  obj-$(CONFIG_SENSORS_IT87)    += it87.o
  obj-$(CONFIG_SENSORS_K8TEMP)  += k8temp.o
  obj-$(CONFIG_SENSORS_LIS3LV02D) += lis3lv02d.o hp_accel.o
+ obj-$(CONFIG_SENSORS_LIS3_SPI)        += lis3lv02d.o lis3lv02d_spi.o
  obj-$(CONFIG_SENSORS_LM63)    += lm63.o
  obj-$(CONFIG_SENSORS_LM70)    += lm70.o
  obj-$(CONFIG_SENSORS_LM75)    += lm75.o
@@@ -64,12 -65,15 +65,15 @@@ obj-$(CONFIG_SENSORS_LM87) += lm87.
  obj-$(CONFIG_SENSORS_LM90)    += lm90.o
  obj-$(CONFIG_SENSORS_LM92)    += lm92.o
  obj-$(CONFIG_SENSORS_LM93)    += lm93.o
+ obj-$(CONFIG_SENSORS_LM95241) += lm95241.o
+ obj-$(CONFIG_SENSORS_LTC4215) += ltc4215.o
  obj-$(CONFIG_SENSORS_LTC4245) += ltc4245.o
  obj-$(CONFIG_SENSORS_MAX1111) += max1111.o
  obj-$(CONFIG_SENSORS_MAX1619) += max1619.o
  obj-$(CONFIG_SENSORS_MAX6650) += max6650.o
  obj-$(CONFIG_SENSORS_PC87360) += pc87360.o
  obj-$(CONFIG_SENSORS_PC87427) += pc87427.o
+ obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o
  obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o
  obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o
  obj-$(CONFIG_SENSORS_SMSC47M1)        += smsc47m1.o
@@@ -80,9 -84,7 +84,9 @@@ obj-$(CONFIG_SENSORS_VT1211)  += vt1211.
  obj-$(CONFIG_SENSORS_VT8231)  += vt8231.o
  obj-$(CONFIG_SENSORS_W83627EHF)       += w83627ehf.o
  obj-$(CONFIG_SENSORS_W83L785TS)       += w83l785ts.o
 +obj-$(CONFIG_SENSORS_TSC210X) += tsc210x_sensors.o
  obj-$(CONFIG_SENSORS_W83L786NG)       += w83l786ng.o
 +obj-$(CONFIG_SENSORS_OMAP34XX)  += omap34xx_temp.o
  
  ifeq ($(CONFIG_HWMON_DEBUG_CHIP),y)
  EXTRA_CFLAGS += -DDEBUG
index 0c3ed419c69a731dd44ecdf58900f333e30d0e1a,ece0125a1ee520710f1e4ac18cd7b8eea83f0422..9919c086ff5d8188edb034ec2b578bf8bce64932
@@@ -193,22 -193,24 +193,24 @@@ static inline u16 omap_i2c_read_reg(str
  
  static int __init omap_i2c_get_clocks(struct omap_i2c_dev *dev)
  {
-       if (cpu_is_omap16xx() || cpu_class_is_omap2()) {
-               dev->iclk = clk_get(dev->dev, "i2c_ick");
-               if (IS_ERR(dev->iclk)) {
-                       dev->iclk = NULL;
-                       return -ENODEV;
-               }
+       int ret;
+       dev->iclk = clk_get(dev->dev, "ick");
+       if (IS_ERR(dev->iclk)) {
+               ret = PTR_ERR(dev->iclk);
+               dev->iclk = NULL;
+               return ret;
        }
  
-       dev->fclk = clk_get(dev->dev, "i2c_fck");
+       dev->fclk = clk_get(dev->dev, "fck");
        if (IS_ERR(dev->fclk)) {
+               ret = PTR_ERR(dev->fclk);
                if (dev->iclk != NULL) {
                        clk_put(dev->iclk);
                        dev->iclk = NULL;
                }
                dev->fclk = NULL;
-               return -ENODEV;
+               return ret;
        }
  
        return 0;
@@@ -218,18 -220,15 +220,15 @@@ static void omap_i2c_put_clocks(struct 
  {
        clk_put(dev->fclk);
        dev->fclk = NULL;
-       if (dev->iclk != NULL) {
-               clk_put(dev->iclk);
-               dev->iclk = NULL;
-       }
+       clk_put(dev->iclk);
+       dev->iclk = NULL;
  }
  
  static void omap_i2c_unidle(struct omap_i2c_dev *dev)
  {
        WARN_ON(!dev->idle);
  
-       if (dev->iclk != NULL)
-               clk_enable(dev->iclk);
+       clk_enable(dev->iclk);
        clk_enable(dev->fclk);
        dev->idle = 0;
        if (dev->iestate)
@@@ -254,8 -253,7 +253,7 @@@ static void omap_i2c_idle(struct omap_i
        }
        dev->idle = 1;
        clk_disable(dev->fclk);
-       if (dev->iclk != NULL)
-               clk_disable(dev->iclk);
+       clk_disable(dev->iclk);
  }
  
  static int omap_i2c_init(struct omap_i2c_dev *dev)
        omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
  
        if (cpu_class_is_omap1()) {
-               struct clk *armxor_ck;
-               armxor_ck = clk_get(NULL, "armxor_ck");
-               if (IS_ERR(armxor_ck))
-                       dev_warn(dev->dev, "Could not get armxor_ck\n");
-               else {
-                       fclk_rate = clk_get_rate(armxor_ck);
-                       clk_put(armxor_ck);
-               }
+               /*
+                * The I2C functional clock is the armxor_ck, so there's
+                * no need to get "armxor_ck" separately.  Now, if OMAP2420
+                * always returns 12MHz for the functional clock, we can
+                * do this bit unconditionally.
+                */
+               fclk_rate = clk_get_rate(dev->fclk);
                /* TRM for 5912 says the I2C clock must be prescaled to be
                 * between 7 - 12 MHz. The XOR input clock is typically
                 * 12, 13 or 19.2 MHz. So we should have code that produces:
@@@ -675,9 -672,8 +672,9 @@@ omap_i2c_isr(int this_irq, void *dev_id
                                if (stat & OMAP_I2C_STAT_RRDY)
                                        num_bytes = dev->fifo_size;
                                else
 -                                      num_bytes = omap_i2c_read_reg(dev,
 -                                                      OMAP_I2C_BUFSTAT_REG);
 +                                      num_bytes = (omap_i2c_read_reg(dev,
 +                                                      OMAP_I2C_BUFSTAT_REG)
 +                                                      >> 8) & 0x3F;
                        }
                        while (num_bytes) {
                                num_bytes--;
                                if (stat & OMAP_I2C_STAT_XRDY)
                                        num_bytes = dev->fifo_size;
                                else
 -                                      num_bytes = omap_i2c_read_reg(dev,
 -                                                      OMAP_I2C_BUFSTAT_REG);
 +                                      num_bytes = (omap_i2c_read_reg(dev,
 +                                                      OMAP_I2C_BUFSTAT_REG))
 +                                                      & 0x3F;
                        }
                        while (num_bytes) {
                                num_bytes--;
index bf7bd1b9109e2b03d8bb3d268908ddbbe548b513,8f8c81eb0aee750006a7949ed530d10a4257503c..a01f40778ae61d57bd3c61cb0122e57d8c58ce39
@@@ -64,44 -64,6 +64,31 @@@ config SENSORS_PCA953
          This driver is deprecated and will be dropped soon. Use
          drivers/gpio/pca953x.c instead.
  
- config SENSORS_PCF8591
-       tristate "Philips PCF8591"
-       depends on EXPERIMENTAL
-       default n
-       help
-         If you say yes here you get support for Philips PCF8591 chips.
-         This driver can also be built as a module.  If so, the module
-         will be called pcf8591.
-         These devices are hard to detect and rarely found on mainstream
-         hardware.  If unsure, say N.
 +config TWL4030_MADC
 +      tristate "TWL4030 MADC Driver"
 +      depends on TWL4030_CORE
 +      help
 +        The TWL4030 Monitoring ADC driver enables the host
 +        processor to monitor analog signals using analog-to-digital
 +        conversions on the input source. TWL4030 MADC provides the
 +        following features:
 +         - Single 10-bit ADC with successive approximation register (SAR) conversion;
 +         - Analog multiplexer for 16 inputs;
 +         - Seven (of the 16) inputs are freely available;
 +         - Battery voltage monitoring;
 +         - Concurrent conversion request management;
 +         - Interrupt signal to Primary Interrupt Handler;
 +         - Averaging feature;
 +         - Selective enable/disable of the averaging feature.
 +
 +        Say 'y' here to statically link this module into the kernel or 'm'
 +        to build it as a dinamically loadable module. The module will be
 +        called twl4030-madc.ko
 +
 +config TWL4030_POWEROFF
 +      tristate "TWL4030 device poweroff"
 +      depends on TWL4030_CORE
 +
  config SENSORS_MAX6875
        tristate "Maxim MAX6875 Power supply supervisor"
        depends on EXPERIMENTAL
@@@ -127,24 -89,4 +114,24 @@@ config SENSORS_TSL255
          This driver can also be built as a module.  If so, the module
          will be called tsl2550.
  
 +config SENSORS_TSL2563
 +       tristate "Taos TSL2563 ambient light sensor"
 +       depends on I2C && HWMON
 +       help
 +         If you say yes here you get support for the Taos TSL2563
 +         ambient light sensor.
 +
 +         This driver can also be built as a module.  If so, the module
 +         will be called tsl2563.
 +
 +config MENELAUS
 +      bool "TWL92330/Menelaus PM chip"
 +      depends on I2C=y && ARCH_OMAP24XX
 +      help
 +        If you say yes here you get support for the Texas Instruments
 +        TWL92330/Menelaus Power Management chip. This include voltage
 +        regulators, Dual slot memory card tranceivers, real-time clock
 +        and other features that are often used in portable devices like
 +        cell phones and PDAs.
 +
  endmenu
index 8da23eeebe581d8e8ce81df797b16d0d20d7f549,55a37603718332dcceab0ef5c90f38a6cb054a8e..0f8a24539a9854a6d3534c40f7074283a2ad7c62
@@@ -15,12 -15,9 +15,11 @@@ obj-$(CONFIG_SENSORS_MAX6875)       += max687
  obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o
  obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o
  obj-$(CONFIG_PCF8575)         += pcf8575.o
- obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o
  obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o
 +obj-$(CONFIG_TWL4030_POWEROFF)        += twl4030-poweroff.o
 +obj-$(CONFIG_TWL4030_MADC)    += twl4030-madc.o
 +obj-$(CONFIG_RTC_X1205_I2C)   += x1205.o
  
  ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
  EXTRA_CFLAGS += -DDEBUG
  endif
 -
index 2c5b7bc08ad36916a0469e36ba2fc1ce210a543b,ea2638b4198226dfc7d2d69c87a387eea1df1df6..0c20376a2ed466e714f0e77a798a0a175e84e44f
@@@ -13,11 -13,11 +13,11 @@@ menuconfig INPUT_KEYBOAR
  if INPUT_KEYBOARD
  
  config KEYBOARD_ATKBD
-       tristate "AT keyboard" if EMBEDDED || !X86_PC
+       tristate "AT keyboard" if EMBEDDED || !X86
        default y
        select SERIO
        select SERIO_LIBPS2
-       select SERIO_I8042 if X86_PC
+       select SERIO_I8042 if X86
        select SERIO_GSCPS2 if GSC
        help
          Say Y here if you want to use a standard AT or PS/2 keyboard. Usually
@@@ -259,41 -259,6 +259,41 @@@ config KEYBOARD_OMA
          To compile this driver as a module, choose M here: the
          module will be called omap-keypad.
  
 +config KEYBOARD_TWL4030
 +      tristate "TI TWL4030/TWL5030/TPS659x0 keypad support"
 +      depends on TWL4030_CORE
 +      help
 +        Say Y here if your board use the keypad controller on
 +        TWL4030 family chips.  It's safe to say enable this
 +        even on boards that don't use the keypad controller.
 +
 +        To compile this driver as a module, choose M here: the
 +        module will be called twl4030_keypad.
 +
 +config OMAP_PS2
 +      tristate "TI OMAP Innovator 1510 PS/2 keyboard & mouse support"
 +      depends on ARCH_OMAP15XX && MACH_OMAP_INNOVATOR
 +      help
 +        Say Y here if you want to use the OMAP Innovator 1510 PS/2
 +        keyboard and mouse.
 +
 +        To compile this driver as a module, choose M here: the
 +        module will be called innovator_ps2.
 +
 +config KEYBOARD_TSC2301
 +      tristate "TSC2301 keypad support"
 +      depends on SPI_TSC2301
 +      help
 +        Say Y here for if you are using the keypad features of TSC2301.
 +
 +config KEYBOARD_LM8323
 +      tristate "LM8323 keypad chip"
 +      depends on I2C
 +      depends on LEDS
 +      help
 +        If you say yes here you get support for the National Semiconductor
 +        LM8323 keypad controller.
 +
  config KEYBOARD_PXA27x
        tristate "PXA27x/PXA3xx keypad support"
        depends on PXA27x || PXA3xx
index a796680b785ac87e786d719d0f6d803f53081f29,0000000000000000000000000000000000000000..a95ea0333007ec2d2a14fed7ee600e8ac83e408b
mode 100644,000000..100644
--- /dev/null
@@@ -1,928 -1,0 +1,928 @@@
-       snprintf(lm->phys, sizeof(lm->phys), "%s/input-kp", client->dev.bus_id);
 +/*
 + * drivers/i2c/chips/lm8323.c
 + *
 + * Copyright (C) 2007-2009 Nokia Corporation
 + *
 + * Written by Daniel Stone <daniel.stone@nokia.com>
 + *            Timo O. Karjalainen <timo.o.karjalainen@nokia.com>
 + *
 + * Updated by Felipe Balbi <felipe.balbi@nokia.com>
 + *
 + * 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 (version 2 of the License only).
 + *
 + * This program is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 + * GNU General Public License for more details.
 + *
 + * You should have received a copy of the GNU General Public License
 + * along with this program; if not, write to the Free Software
 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 + */
 +
 +#include <linux/module.h>
 +#include <linux/i2c.h>
 +#include <linux/interrupt.h>
 +#include <linux/sched.h>
 +#include <linux/mutex.h>
 +#include <linux/delay.h>
 +#include <linux/input.h>
 +#include <linux/leds.h>
 +#include <linux/i2c/lm8323.h>
 +
 +/* Commands to send to the chip. */
 +#define LM8323_CMD_READ_ID            0x80 /* Read chip ID. */
 +#define LM8323_CMD_WRITE_CFG          0x81 /* Set configuration item. */
 +#define LM8323_CMD_READ_INT           0x82 /* Get interrupt status. */
 +#define LM8323_CMD_RESET              0x83 /* Reset, same as external one */
 +#define LM8323_CMD_WRITE_PORT_SEL     0x85 /* Set GPIO in/out. */
 +#define LM8323_CMD_WRITE_PORT_STATE   0x86 /* Set GPIO pullup. */
 +#define LM8323_CMD_READ_PORT_SEL      0x87 /* Get GPIO in/out. */
 +#define LM8323_CMD_READ_PORT_STATE    0x88 /* Get GPIO pullup. */
 +#define LM8323_CMD_READ_FIFO          0x89 /* Read byte from FIFO. */
 +#define LM8323_CMD_RPT_READ_FIFO      0x8a /* Read FIFO (no increment). */
 +#define LM8323_CMD_SET_ACTIVE         0x8b /* Set active time. */
 +#define LM8323_CMD_READ_ERR           0x8c /* Get error status. */
 +#define LM8323_CMD_READ_ROTATOR               0x8e /* Read rotator status. */
 +#define LM8323_CMD_SET_DEBOUNCE               0x8f /* Set debouncing time. */
 +#define LM8323_CMD_SET_KEY_SIZE               0x90 /* Set keypad size. */
 +#define LM8323_CMD_READ_KEY_SIZE      0x91 /* Get keypad size. */
 +#define LM8323_CMD_READ_CFG           0x92 /* Get configuration item. */
 +#define LM8323_CMD_WRITE_CLOCK                0x93 /* Set clock config. */
 +#define LM8323_CMD_READ_CLOCK         0x94 /* Get clock config. */
 +#define LM8323_CMD_PWM_WRITE          0x95 /* Write PWM script. */
 +#define LM8323_CMD_START_PWM          0x96 /* Start PWM engine. */
 +#define LM8323_CMD_STOP_PWM           0x97 /* Stop PWM engine. */
 +
 +/* Interrupt status. */
 +#define INT_KEYPAD                    0x01 /* Key event. */
 +#define INT_ROTATOR                   0x02 /* Rotator event. */
 +#define INT_ERROR                     0x08 /* Error: use CMD_READ_ERR. */
 +#define INT_NOINIT                    0x10 /* Lost configuration. */
 +#define INT_PWM1                      0x20 /* PWM1 stopped. */
 +#define INT_PWM2                      0x40 /* PWM2 stopped. */
 +#define INT_PWM3                      0x80 /* PWM3 stopped. */
 +
 +/* Errors (signalled by INT_ERROR, read with CMD_READ_ERR). */
 +#define ERR_BADPAR                    0x01 /* Bad parameter. */
 +#define ERR_CMDUNK                    0x02 /* Unknown command. */
 +#define ERR_KEYOVR                    0x04 /* Too many keys pressed. */
 +#define ERR_FIFOOVER                  0x40 /* FIFO overflow. */
 +
 +/* Configuration keys (CMD_{WRITE,READ}_CFG). */
 +#define CFG_MUX1SEL                   0x01 /* Select MUX1_OUT input. */
 +#define CFG_MUX1EN                    0x02 /* Enable MUX1_OUT. */
 +#define CFG_MUX2SEL                   0x04 /* Select MUX2_OUT input. */
 +#define CFG_MUX2EN                    0x08 /* Enable MUX2_OUT. */
 +#define CFG_PSIZE                     0x20 /* Package size (must be 0). */
 +#define CFG_ROTEN                     0x40 /* Enable rotator. */
 +
 +/* Clock settings (CMD_{WRITE,READ}_CLOCK). */
 +#define CLK_RCPWM_INTERNAL            0x00
 +#define CLK_RCPWM_EXTERNAL            0x03
 +#define CLK_SLOWCLKEN                 0x08 /* Enable 32.768kHz clock. */
 +#define CLK_SLOWCLKOUT                        0x40 /* Enable slow pulse output. */
 +
 +/* The possible addresses corresponding to CONFIG1 and CONFIG2 pin wirings. */
 +#define LM8323_I2C_ADDR00             (0x84 >> 1)     /* 1000 010x */
 +#define LM8323_I2C_ADDR01             (0x86 >> 1)     /* 1000 011x */
 +#define LM8323_I2C_ADDR10             (0x88 >> 1)     /* 1000 100x */
 +#define LM8323_I2C_ADDR11             (0x8A >> 1)     /* 1000 101x */
 +
 +/* Key event fifo length */
 +#define LM8323_FIFO_LEN                       15
 +
 +/* Commands for PWM engine; feed in with PWM_WRITE. */
 +/* Load ramp counter from duty cycle field (range 0 - 0xff). */
 +#define PWM_SET(v)                    (0x4000 | ((v) & 0xff))
 +/* Go to start of script. */
 +#define PWM_GOTOSTART                 0x0000
 +/*
 + * Stop engine (generates interrupt).  If reset is 1, clear the program
 + * counter, else leave it.
 + */
 +#define PWM_END(reset)                        (0xc000 | (!!(reset) << 11))
 +/*
 + * Ramp.  If s is 1, divide clock by 512, else divide clock by 16.
 + * Take t clock scales (up to 63) per step, for n steps (up to 126).
 + * If u is set, ramp up, else ramp down.
 + */
 +#define PWM_RAMP(s, t, n, u)          ((!!(s) << 14) | ((t) & 0x3f) << 8 | \
 +                                       ((n) & 0x7f) | ((u) ? 0 : 0x80))
 +/*
 + * Loop (i.e. jump back to pos) for a given number of iterations (up to 63).
 + * If cnt is zero, execute until PWM_END is encountered.
 + */
 +#define PWM_LOOP(cnt, pos)            (0xa000 | (((cnt) & 0x3f) << 7) | \
 +                                       ((pos) & 0x3f))
 +/*
 + * Wait for trigger.  Argument is a mask of channels, shifted by the channel
 + * number, e.g. 0xa for channels 3 and 1.  Note that channels are numbered
 + * from 1, not 0.
 + */
 +#define PWM_WAIT_TRIG(chans)          (0xe000 | (((chans) & 0x7) << 6))
 +/* Send trigger.  Argument is same as PWM_WAIT_TRIG. */
 +#define PWM_SEND_TRIG(chans)          (0xe000 | ((chans) & 0x7))
 +
 +struct lm8323_pwm {
 +      int                     id;
 +      int                     enabled;
 +      int                     fade_time;
 +      int                     brightness;
 +      int                     desired_brightness;
 +      int                     running;
 +      /* pwm lock */
 +      struct mutex            lock;
 +      struct work_struct      work;
 +      struct led_classdev     cdev;
 +};
 +
 +struct lm8323_chip {
 +      /* device lock */
 +      struct mutex            lock;
 +      struct i2c_client       *client;
 +      struct work_struct      work;
 +      struct input_dev        *idev;
 +      unsigned                kp_enabled:1;
 +      unsigned                pm_suspend:1;
 +      unsigned                keys_down;
 +      char                    phys[32];
 +      s16                     keymap[LM8323_KEYMAP_SIZE];
 +      int                     size_x;
 +      int                     size_y;
 +      int                     debounce_time;
 +      int                     active_time;
 +      struct lm8323_pwm       pwm1;
 +      struct lm8323_pwm       pwm2;
 +      struct lm8323_pwm       pwm3;
 +};
 +
 +#define client_to_lm8323(c)   container_of(c, struct lm8323_chip, client)
 +#define dev_to_lm8323(d)      container_of(d, struct lm8323_chip, client->dev)
 +#define work_to_lm8323(w)     container_of(w, struct lm8323_chip, work)
 +#define cdev_to_pwm(c)                container_of(c, struct lm8323_pwm, cdev)
 +#define work_to_pwm(w)                container_of(w, struct lm8323_pwm, work)
 +
 +static struct lm8323_chip *pwm_to_lm8323(struct lm8323_pwm *pwm)
 +{
 +      switch (pwm->id) {
 +      case 1:
 +              return container_of(pwm, struct lm8323_chip, pwm1);
 +      case 2:
 +              return container_of(pwm, struct lm8323_chip, pwm2);
 +      case 3:
 +              return container_of(pwm, struct lm8323_chip, pwm3);
 +      default:
 +              return NULL;
 +      }
 +}
 +
 +#define LM8323_MAX_DATA 8
 +
 +/*
 + * To write, we just access the chip's address in write mode, and dump the
 + * command and data out on the bus.  The command byte and data are taken as
 + * sequential u8s out of varargs, to a maximum of LM8323_MAX_DATA.
 + */
 +static int lm8323_write(struct lm8323_chip *lm, int len, ...)
 +{
 +      int ret, i;
 +      va_list ap;
 +      u8 data[LM8323_MAX_DATA];
 +
 +      va_start(ap, len);
 +
 +      if (unlikely(len > LM8323_MAX_DATA)) {
 +              dev_err(&lm->client->dev, "tried to send %d bytes\n", len);
 +              va_end(ap);
 +              return 0;
 +      }
 +
 +      for (i = 0; i < len; i++)
 +              data[i] = va_arg(ap, int);
 +
 +      va_end(ap);
 +
 +      /*
 +       * If the host is asleep while we send the data, we can get a NACK
 +       * back while it wakes up, so try again, once.
 +       */
 +      ret = i2c_master_send(lm->client, data, len);
 +      if (unlikely(ret == -EREMOTEIO))
 +              ret = i2c_master_send(lm->client, data, len);
 +      if (unlikely(ret != len))
 +              dev_err(&lm->client->dev, "sent %d bytes of %d total\n",
 +                      len, ret);
 +
 +      return ret;
 +}
 +
 +/*
 + * To read, we first send the command byte to the chip and end the transaction,
 + * then access the chip in read mode, at which point it will send the data.
 + */
 +static int lm8323_read(struct lm8323_chip *lm, u8 cmd, u8 *buf, int len)
 +{
 +      int ret;
 +
 +      /*
 +       * If the host is asleep while we send the byte, we can get a NACK
 +       * back while it wakes up, so try again, once.
 +       */
 +      ret = i2c_master_send(lm->client, &cmd, 1);
 +      if (unlikely(ret == -EREMOTEIO))
 +              ret = i2c_master_send(lm->client, &cmd, 1);
 +      if (unlikely(ret != 1)) {
 +              dev_err(&lm->client->dev, "sending read cmd 0x%02x failed\n",
 +                      cmd);
 +              return 0;
 +      }
 +
 +      ret = i2c_master_recv(lm->client, buf, len);
 +      if (unlikely(ret != len))
 +              dev_err(&lm->client->dev, "wanted %d bytes, got %d\n",
 +                      len, ret);
 +
 +      return ret;
 +}
 +
 +/*
 + * Set the chip active time (idle time before it enters halt).
 + */
 +static void lm8323_set_active_time(struct lm8323_chip *lm, int time)
 +{
 +      lm8323_write(lm, 2, LM8323_CMD_SET_ACTIVE, time >> 2);
 +}
 +
 +/*
 + * The signals are AT-style: the low 7 bits are the keycode, and the top
 + * bit indicates the state (1 for down, 0 for up).
 + */
 +static inline u8 lm8323_whichkey(u8 event)
 +{
 +      return event & 0x7f;
 +}
 +
 +static inline int lm8323_ispress(u8 event)
 +{
 +      return (event & 0x80) ? 1 : 0;
 +}
 +
 +static void process_keys(struct lm8323_chip *lm)
 +{
 +      u8 event;
 +      u8 key_fifo[LM8323_FIFO_LEN + 1];
 +      int old_keys_down = lm->keys_down;
 +      int ret;
 +      int i = 0;
 +
 +      /*
 +       * Read all key events from the FIFO at once. Next READ_FIFO clears the
 +       * FIFO even if we didn't read all events previously.
 +       */
 +      ret = lm8323_read(lm, LM8323_CMD_READ_FIFO, key_fifo, LM8323_FIFO_LEN);
 +
 +      if (ret < 0) {
 +              dev_err(&lm->client->dev, "Failed reading fifo \n");
 +              return;
 +      }
 +      key_fifo[ret] = 0;
 +
 +      while ((event = key_fifo[i])) {
 +              u8 key = lm8323_whichkey(event);
 +              int isdown = lm8323_ispress(event);
 +              s16 keycode = lm->keymap[key];
 +
 +              if (likely(keycode > 0)) {
 +                      dev_vdbg(&lm->client->dev, "key 0x%02x %s\n", key,
 +                            isdown ? "down" : "up");
 +                      if (likely(lm->kp_enabled)) {
 +                              input_report_key(lm->idev, keycode, isdown);
 +                              input_sync(lm->idev);
 +                      }
 +                      if (isdown)
 +                              lm->keys_down++;
 +                      else
 +                              lm->keys_down--;
 +              } else {
 +                      dev_err(&lm->client->dev, "keycode 0x%02x not mapped "
 +                              "to any key\n", key);
 +              }
 +              i++;
 +      }
 +
 +      /*
 +       * Errata: We need to ensure that the chip never enters halt mode
 +       * during a keypress, so set active time to 0.  When it's released,
 +       * we can enter halt again, so set the active time back to normal.
 +       */
 +      if (!old_keys_down && lm->keys_down)
 +              lm8323_set_active_time(lm, 0);
 +      if (old_keys_down && !lm->keys_down)
 +              lm8323_set_active_time(lm, lm->active_time);
 +}
 +
 +static void lm8323_process_error(struct lm8323_chip *lm)
 +{
 +      u8 error;
 +
 +      if (lm8323_read(lm, LM8323_CMD_READ_ERR, &error, 1) == 1) {
 +              if (error & ERR_FIFOOVER)
 +                      dev_vdbg(&lm->client->dev, "fifo overflow!\n");
 +              if (error & ERR_KEYOVR)
 +                      dev_vdbg(&lm->client->dev,
 +                                      "more than two keys pressed\n");
 +              if (error & ERR_CMDUNK)
 +                      dev_vdbg(&lm->client->dev,
 +                                      "unknown command submitted\n");
 +              if (error & ERR_BADPAR)
 +                      dev_vdbg(&lm->client->dev, "bad command parameter\n");
 +      }
 +}
 +
 +static void lm8323_reset(struct lm8323_chip *lm)
 +{
 +      /* The docs say we must pass 0xAA as the data byte. */
 +      lm8323_write(lm, 2, LM8323_CMD_RESET, 0xAA);
 +}
 +
 +static int lm8323_configure(struct lm8323_chip *lm)
 +{
 +      int keysize = (lm->size_x << 4) | lm->size_y;
 +      int clock = (CLK_SLOWCLKEN | CLK_RCPWM_EXTERNAL);
 +      int debounce = lm->debounce_time >> 2;
 +      int active = lm->active_time >> 2;
 +
 +      /*
 +       * Active time must be greater than the debounce time: if it's
 +       * a close-run thing, give ourselves a 12ms buffer.
 +       */
 +      if (debounce >= active)
 +              active = debounce + 3;
 +
 +      lm8323_write(lm, 2, LM8323_CMD_WRITE_CFG, 0);
 +      lm8323_write(lm, 2, LM8323_CMD_WRITE_CLOCK, clock);
 +      lm8323_write(lm, 2, LM8323_CMD_SET_KEY_SIZE, keysize);
 +      lm8323_set_active_time(lm, lm->active_time);
 +      lm8323_write(lm, 2, LM8323_CMD_SET_DEBOUNCE, debounce);
 +      lm8323_write(lm, 3, LM8323_CMD_WRITE_PORT_STATE, 0xff, 0xff);
 +      lm8323_write(lm, 3, LM8323_CMD_WRITE_PORT_SEL, 0, 0);
 +
 +      /*
 +       * Not much we can do about errors at this point, so just hope
 +       * for the best.
 +       */
 +
 +      return 0;
 +}
 +
 +static void pwm_done(struct lm8323_pwm *pwm)
 +{
 +      mutex_lock(&pwm->lock);
 +      pwm->running = 0;
 +      if (pwm->desired_brightness != pwm->brightness)
 +              schedule_work(&pwm->work);
 +      mutex_unlock(&pwm->lock);
 +}
 +
 +/*
 + * Bottom half: handle the interrupt by posting key events, or dealing with
 + * errors appropriately.
 + */
 +static void lm8323_work(struct work_struct *work)
 +{
 +      struct lm8323_chip *lm = work_to_lm8323(work);
 +      u8 ints;
 +
 +      mutex_lock(&lm->lock);
 +
 +      while ((lm8323_read(lm, LM8323_CMD_READ_INT, &ints, 1) == 1) && ints) {
 +              if (likely(ints & INT_KEYPAD))
 +                      process_keys(lm);
 +              if (ints & INT_ROTATOR) {
 +                      /* We don't currently support the rotator. */
 +                      dev_vdbg(&lm->client->dev, "rotator fired\n");
 +              }
 +              if (ints & INT_ERROR) {
 +                      dev_vdbg(&lm->client->dev, "error!\n");
 +                      lm8323_process_error(lm);
 +              }
 +              if (ints & INT_NOINIT) {
 +                      dev_err(&lm->client->dev, "chip lost config; "
 +                                                "reinitialising\n");
 +                      lm8323_configure(lm);
 +              }
 +              if (ints & INT_PWM1) {
 +                      dev_vdbg(&lm->client->dev, "pwm1 engine completed\n");
 +                      pwm_done(&lm->pwm1);
 +              }
 +              if (ints & INT_PWM2) {
 +                      dev_vdbg(&lm->client->dev, "pwm2 engine completed\n");
 +                      pwm_done(&lm->pwm2);
 +              }
 +              if (ints & INT_PWM3) {
 +                      dev_vdbg(&lm->client->dev, "pwm3 engine completed\n");
 +                      pwm_done(&lm->pwm3);
 +              }
 +      }
 +
 +      mutex_unlock(&lm->lock);
 +}
 +
 +/*
 + * We cannot use I2C in interrupt context, so we just schedule work.
 + */
 +static irqreturn_t lm8323_irq(int irq, void *data)
 +{
 +      struct lm8323_chip *lm = data;
 +
 +      schedule_work(&lm->work);
 +
 +      return IRQ_HANDLED;
 +}
 +
 +/*
 + * Read the chip ID.
 + */
 +static int lm8323_read_id(struct lm8323_chip *lm, u8 *buf)
 +{
 +      int bytes;
 +
 +      bytes = lm8323_read(lm, LM8323_CMD_READ_ID, buf, 2);
 +      if (unlikely(bytes != 2))
 +              return -EIO;
 +
 +      return 0;
 +}
 +
 +static void lm8323_write_pwm_one(struct lm8323_pwm *pwm, int pos, u16 cmd)
 +{
 +      struct lm8323_chip *lm = pwm_to_lm8323(pwm);
 +
 +      lm8323_write(lm, 4, LM8323_CMD_PWM_WRITE, (pos << 2) | pwm->id,
 +                   (cmd & 0xff00) >> 8, cmd & 0x00ff);
 +}
 +
 +/*
 + * Write a script into a given PWM engine, concluding with PWM_END.
 + * If 'kill' is nonzero, the engine will be shut down at the end
 + * of the script, producing a zero output. Otherwise the engine
 + * will be kept running at the final PWM level indefinitely.
 + */
 +static void lm8323_write_pwm(struct lm8323_pwm *pwm, int kill,
 +                           int len, const u16 *cmds)
 +{
 +      struct lm8323_chip *lm = pwm_to_lm8323(pwm);
 +      int i;
 +
 +      for (i = 0; i < len; i++)
 +              lm8323_write_pwm_one(pwm, i, cmds[i]);
 +
 +      lm8323_write_pwm_one(pwm, i++, PWM_END(kill));
 +      lm8323_write(lm, 2, LM8323_CMD_START_PWM, pwm->id);
 +      pwm->running = 1;
 +}
 +
 +static void lm8323_pwm_work(struct work_struct *work)
 +{
 +      struct lm8323_pwm *pwm = work_to_pwm(work);
 +      int div512, perstep, steps, hz, up, kill;
 +      u16 pwm_cmds[3];
 +      int num_cmds = 0;
 +
 +      mutex_lock(&pwm->lock);
 +
 +      /*
 +       * Do nothing if we're already at the requested level,
 +       * or previous setting is not yet complete. In the latter
 +       * case we will be called again when the previous PWM script
 +       * finishes.
 +       */
 +      if (pwm->running || pwm->desired_brightness == pwm->brightness) {
 +              mutex_unlock(&pwm->lock);
 +              return;
 +      }
 +
 +      kill = (pwm->desired_brightness == 0);
 +      up = (pwm->desired_brightness > pwm->brightness);
 +      steps = abs(pwm->desired_brightness - pwm->brightness);
 +
 +      /*
 +       * Convert time (in ms) into a divisor (512 or 16 on a refclk of
 +       * 32768Hz), and number of ticks per step.
 +       */
 +      if ((pwm->fade_time / steps) > (32768 / 512)) {
 +              div512 = 1;
 +              hz = 32768 / 512;
 +      } else {
 +              div512 = 0;
 +              hz = 32768 / 16;
 +      }
 +
 +      perstep = (hz * pwm->fade_time) / (steps * 1000);
 +
 +      if (perstep == 0)
 +              perstep = 1;
 +      else if (perstep > 63)
 +              perstep = 63;
 +
 +      while (steps) {
 +              int s;
 +
 +              s = min(126, steps);
 +              pwm_cmds[num_cmds++] = PWM_RAMP(div512, perstep, s, up);
 +              steps -= s;
 +      }
 +
 +      lm8323_write_pwm(pwm, kill, num_cmds, pwm_cmds);
 +
 +      pwm->brightness = pwm->desired_brightness;
 +      mutex_unlock(&pwm->lock);
 +}
 +
 +static void lm8323_pwm_set_brightness(struct led_classdev *led_cdev,
 +                                    enum led_brightness brightness)
 +{
 +      struct lm8323_pwm *pwm = cdev_to_pwm(led_cdev);
 +      struct lm8323_chip *lm = pwm_to_lm8323(pwm);
 +
 +      mutex_lock(&pwm->lock);
 +      pwm->desired_brightness = brightness;
 +      mutex_unlock(&pwm->lock);
 +
 +      if (in_interrupt()) {
 +              schedule_work(&pwm->work);
 +      } else {
 +              /*
 +               * Schedule PWM work as usual unless we are going into suspend
 +               */
 +              mutex_lock(&lm->lock);
 +              if (likely(!lm->pm_suspend))
 +                      schedule_work(&pwm->work);
 +              else
 +                      lm8323_pwm_work(&pwm->work);
 +              mutex_unlock(&lm->lock);
 +      }
 +}
 +
 +static ssize_t lm8323_pwm_show_time(struct device *dev,
 +              struct device_attribute *attr, char *buf)
 +{
 +      struct led_classdev *led_cdev = dev_get_drvdata(dev);
 +      struct lm8323_pwm *pwm = cdev_to_pwm(led_cdev);
 +
 +      return sprintf(buf, "%d\n", pwm->fade_time);
 +}
 +
 +static ssize_t lm8323_pwm_store_time(struct device *dev,
 +              struct device_attribute *attr, const char *buf, size_t len)
 +{
 +      struct led_classdev *led_cdev = dev_get_drvdata(dev);
 +      struct lm8323_pwm *pwm = cdev_to_pwm(led_cdev);
 +      int ret;
 +      int time;
 +
 +      ret = strict_strtoul(buf, 10, &time);
 +      /* Numbers only, please. */
 +      if (ret)
 +              return -EINVAL;
 +
 +      pwm->fade_time = time;
 +
 +      return strlen(buf);
 +}
 +static DEVICE_ATTR(time, 0644, lm8323_pwm_show_time, lm8323_pwm_store_time);
 +
 +static int init_pwm(struct lm8323_chip *lm, int id, struct device *dev,
 +                  const char *name)
 +{
 +      struct lm8323_pwm *pwm = NULL;
 +
 +      BUG_ON(id > 3);
 +
 +      switch (id) {
 +      case 1:
 +              pwm = &lm->pwm1;
 +              break;
 +      case 2:
 +              pwm = &lm->pwm2;
 +              break;
 +      case 3:
 +              pwm = &lm->pwm3;
 +              break;
 +      }
 +
 +      pwm->id = id;
 +      pwm->fade_time = 0;
 +      pwm->brightness = 0;
 +      pwm->desired_brightness = 0;
 +      pwm->running = 0;
 +      mutex_init(&pwm->lock);
 +      if (name) {
 +              pwm->cdev.name = name;
 +              pwm->cdev.brightness_set = lm8323_pwm_set_brightness;
 +              if (led_classdev_register(dev, &pwm->cdev) < 0) {
 +                      dev_err(dev, "couldn't register PWM %d\n", id);
 +                      return -1;
 +              }
 +              if (device_create_file(pwm->cdev.dev,
 +                                           &dev_attr_time) < 0) {
 +                      dev_err(dev, "couldn't register time attribute\n");
 +                      led_classdev_unregister(&pwm->cdev);
 +                      return -1;
 +              }
 +              INIT_WORK(&pwm->work, lm8323_pwm_work);
 +              pwm->enabled = 1;
 +      } else {
 +              pwm->enabled = 0;
 +      }
 +
 +      return 0;
 +}
 +
 +static struct i2c_driver lm8323_i2c_driver;
 +
 +static ssize_t lm8323_show_disable(struct device *dev,
 +                                 struct device_attribute *attr, char *buf)
 +{
 +      struct lm8323_chip *lm = dev_get_drvdata(dev);
 +
 +      return sprintf(buf, "%u\n", !lm->kp_enabled);
 +}
 +
 +static ssize_t lm8323_set_disable(struct device *dev,
 +                                struct device_attribute *attr,
 +                                const char *buf, size_t count)
 +{
 +      struct lm8323_chip *lm = dev_get_drvdata(dev);
 +      int ret;
 +      int i;
 +
 +      ret = strict_strtoul(buf, 10, &i);
 +
 +      mutex_lock(&lm->lock);
 +      lm->kp_enabled = !i;
 +      mutex_unlock(&lm->lock);
 +
 +      return count;
 +}
 +static DEVICE_ATTR(disable_kp, 0644, lm8323_show_disable, lm8323_set_disable);
 +
 +static int lm8323_probe(struct i2c_client *client,
 +              const struct i2c_device_id *id)
 +{
 +      struct lm8323_platform_data *pdata;
 +      struct input_dev *idev;
 +      struct lm8323_chip *lm;
 +      int i, err = 0;
 +      unsigned long tmo;
 +      u8 data[2];
 +
 +      lm = kzalloc(sizeof *lm, GFP_KERNEL);
 +      if (!lm)
 +              return -ENOMEM;
 +
 +      i2c_set_clientdata(client, lm);
 +      lm->client = client;
 +      pdata = client->dev.platform_data;
 +      if (!pdata || !pdata->size_x || !pdata->size_y) {
 +              dev_err(&client->dev, "missing platform_data\n");
 +              err = -EINVAL;
 +              goto fail2;
 +      }
 +
 +      lm->size_x = pdata->size_x;
 +      if (lm->size_x > 8) {
 +              dev_err(&client->dev, "invalid x size %d specified\n",
 +                              lm->size_x);
 +              err = -EINVAL;
 +              goto fail2;
 +      }
 +
 +      lm->size_y = pdata->size_y;
 +      if (lm->size_y > 12) {
 +              dev_err(&client->dev, "invalid y size %d specified\n",
 +                              lm->size_y);
 +              err = -EINVAL;
 +              goto fail2;
 +      }
 +
 +      dev_vdbg(&client->dev, "Keypad size: %d x %d\n",
 +                      lm->size_x, lm->size_y);
 +
 +      lm->debounce_time = pdata->debounce_time;
 +      lm->active_time = pdata->active_time;
 +
 +      lm8323_reset(lm);
 +
 +      /* Nothing's set up to service the IRQ yet, so just spin for max.
 +       * 100ms until we can configure. */
 +      tmo = jiffies + msecs_to_jiffies(100);
 +      while (lm8323_read(lm, LM8323_CMD_READ_INT, data, 1) == 1) {
 +              if (data[0] & INT_NOINIT)
 +                      break;
 +
 +              if (time_after(jiffies, tmo)) {
 +                      dev_err(&client->dev,
 +                                      "timeout waiting for initialisation\n");
 +                      break;
 +              }
 +
 +              msleep(1);
 +      }
 +      lm8323_configure(lm);
 +
 +      /* If a true probe check the device */
 +      if (lm8323_read_id(lm, data) != 0) {
 +              dev_err(&client->dev, "device not found\n");
 +              err = -ENODEV;
 +              goto fail2;
 +      }
 +
 +      if (init_pwm(lm, 1, &client->dev, pdata->pwm1_name) < 0)
 +              goto fail3;
 +      if (init_pwm(lm, 2, &client->dev, pdata->pwm2_name) < 0)
 +              goto fail4;
 +      if (init_pwm(lm, 3, &client->dev, pdata->pwm3_name) < 0)
 +              goto fail5;
 +
 +      mutex_init(&lm->lock);
 +      INIT_WORK(&lm->work, lm8323_work);
 +
 +      err = request_irq(client->irq, lm8323_irq,
 +                        IRQF_TRIGGER_FALLING | IRQF_DISABLED,
 +                        "lm8323", lm);
 +      if (err) {
 +              dev_err(&client->dev, "could not get IRQ %d\n", client->irq);
 +              goto fail6;
 +      }
 +
 +      device_init_wakeup(&client->dev, 1);
 +      enable_irq_wake(client->irq);
 +
 +      lm->kp_enabled = 1;
 +      err = device_create_file(&client->dev, &dev_attr_disable_kp);
 +      if (err < 0)
 +              goto fail7;
 +
 +      idev = input_allocate_device();
 +      if (!idev) {
 +              err = -ENOMEM;
 +              goto fail8;
 +      }
 +
 +      if (pdata->name)
 +              idev->name = pdata->name;
 +      else
 +              idev->name = "LM8323 keypad";
++      snprintf(lm->phys, sizeof(lm->phys), "%s/input-kp", dev_name(&client->dev));
 +      idev->phys = lm->phys;
 +
 +      lm->keys_down = 0;
 +      idev->evbit[0] = BIT(EV_KEY);
 +      for (i = 0; i < LM8323_KEYMAP_SIZE; i++) {
 +              if (pdata->keymap[i] > 0)
 +                      __set_bit(pdata->keymap[i], idev->keybit);
 +
 +              lm->keymap[i] = pdata->keymap[i];
 +      }
 +
 +      if (pdata->repeat)
 +              __set_bit(EV_REP, idev->evbit);
 +
 +      lm->idev = idev;
 +      err = input_register_device(idev);
 +      if (err) {
 +              dev_dbg(&client->dev, "error registering input device\n");
 +              goto fail8;
 +      }
 +
 +      return 0;
 +
 +fail8:
 +      device_remove_file(&client->dev, &dev_attr_disable_kp);
 +fail7:
 +      free_irq(client->irq, lm);
 +fail6:
 +      if (lm->pwm3.enabled)
 +              led_classdev_unregister(&lm->pwm3.cdev);
 +fail5:
 +      if (lm->pwm2.enabled)
 +              led_classdev_unregister(&lm->pwm2.cdev);
 +fail4:
 +      if (lm->pwm1.enabled)
 +              led_classdev_unregister(&lm->pwm1.cdev);
 +fail3:
 +fail2:
 +      kfree(lm);
 +      return err;
 +}
 +
 +static int lm8323_remove(struct i2c_client *client)
 +{
 +      struct lm8323_chip *lm = i2c_get_clientdata(client);
 +
 +      disable_irq_wake(client->irq);
 +      free_irq(client->irq, lm);
 +      cancel_work_sync(&lm->work);
 +      input_unregister_device(lm->idev);
 +      device_remove_file(&lm->client->dev, &dev_attr_disable_kp);
 +      if (lm->pwm3.enabled)
 +              led_classdev_unregister(&lm->pwm3.cdev);
 +      if (lm->pwm2.enabled)
 +              led_classdev_unregister(&lm->pwm2.cdev);
 +      if (lm->pwm1.enabled)
 +              led_classdev_unregister(&lm->pwm1.cdev);
 +      kfree(lm);
 +
 +      return 0;
 +}
 +
 +#ifdef CONFIG_PM
 +/*
 + * We don't need to explicitly suspend the chip, as it already switches off
 + * when there's no activity.
 + */
 +static int lm8323_suspend(struct i2c_client *client, pm_message_t mesg)
 +{
 +      struct lm8323_chip *lm = i2c_get_clientdata(client);
 +
 +      set_irq_wake(client->irq, 0);
 +      disable_irq(client->irq);
 +
 +      mutex_lock(&lm->lock);
 +      lm->pm_suspend = 1;
 +      mutex_unlock(&lm->lock);
 +
 +      if (lm->pwm1.enabled)
 +              led_classdev_suspend(&lm->pwm1.cdev);
 +      if (lm->pwm2.enabled)
 +              led_classdev_suspend(&lm->pwm2.cdev);
 +      if (lm->pwm3.enabled)
 +              led_classdev_suspend(&lm->pwm3.cdev);
 +
 +      return 0;
 +}
 +
 +static int lm8323_resume(struct i2c_client *client)
 +{
 +      struct lm8323_chip *lm = i2c_get_clientdata(client);
 +
 +      mutex_lock(&lm->lock);
 +      lm->pm_suspend = 0;
 +      mutex_unlock(&lm->lock);
 +
 +      if (lm->pwm1.enabled)
 +              led_classdev_resume(&lm->pwm1.cdev);
 +      if (lm->pwm2.enabled)
 +              led_classdev_resume(&lm->pwm2.cdev);
 +      if (lm->pwm3.enabled)
 +              led_classdev_resume(&lm->pwm3.cdev);
 +
 +      enable_irq(client->irq);
 +      set_irq_wake(client->irq, 1);
 +
 +      return 0;
 +}
 +#else
 +#define lm8323_suspend        NULL
 +#define lm8323_resume NULL
 +#endif
 +
 +static const struct i2c_device_id lm8323_id[] = {
 +      { "lm8323", 0 },
 +      { }
 +};
 +
 +static struct i2c_driver lm8323_i2c_driver = {
 +      .driver = {
 +              .name    = "lm8323",
 +      },
 +      .probe          = lm8323_probe,
 +      .remove         = lm8323_remove,
 +      .suspend        = lm8323_suspend,
 +      .resume         = lm8323_resume,
 +      .id_table       = lm8323_id,
 +};
 +MODULE_DEVICE_TABLE(i2c, lm8323_id);
 +
 +static int __init lm8323_init(void)
 +{
 +      return i2c_add_driver(&lm8323_i2c_driver);
 +}
 +module_init(lm8323_init);
 +
 +static void __exit lm8323_exit(void)
 +{
 +      i2c_del_driver(&lm8323_i2c_driver);
 +}
 +module_exit(lm8323_exit);
 +
 +MODULE_AUTHOR("Timo O. Karjalainen <timo.o.karjalainen@nokia.com>");
 +MODULE_AUTHOR("Daniel Stone");
 +MODULE_AUTHOR("Felipe Balbi <felipe.balbi@nokia.com>");
 +MODULE_DESCRIPTION("LM8323 keypad driver");
 +MODULE_LICENSE("GPL");
 +
index a974a5fdc2e67a17f7efde09bb7e7b0b2c2779c3,0000000000000000000000000000000000000000..0f2cb7f5a10e69c9a4a2caad0cf75c768031f766
mode 100644,000000..100644
--- /dev/null
@@@ -1,475 -1,0 +1,475 @@@
-       snprintf(kp->phys, sizeof(kp->phys), "%s/input-kp", tsc->spi->dev.bus_id);
 +/*
 + * TSC2301 keypad driver
 + *
 + * Copyright (C) 2005-2006 Nokia Corporation
 + *
 + * Written by Jarkko Oikarinen
 + * Rewritten by Juha Yrjola <juha.yrjola@nokia.com>
 + *
 + * 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.
 + *
 + * This program is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 + * GNU General Public License for more details.
 + *
 + * You should have received a copy of the GNU General Public License
 + * along with this program; if not, write to the Free Software
 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 + *
 + */
 +
 +#include <linux/kernel.h>
 +#include <linux/module.h>
 +#include <linux/input.h>
 +#include <linux/interrupt.h>
 +#include <linux/irq.h>
 +#include <linux/delay.h>
 +#include <linux/spi/spi.h>
 +
 +#include <linux/spi/tsc2301.h>
 +
 +#define TSC2301_KEYBOARD_PRODUCT_ID      0x0051
 +#define TSC2301_KEYBOARD_PRODUCT_VERSION 0x0001
 +#define TSC2301_DEBOUNCE_TIME_2MS        0x0000
 +#define TSC2301_DEBOUNCE_TIME_10MS       0x0800
 +#define TSC2301_DEBOUNCE_TIME_20MS       0x1000
 +#define TSC2301_DEBOUNCE_TIME_50MS       0x1800
 +#define TSC2301_DEBOUNCE_TIME_60MS       0x2000
 +#define TSC2301_DEBOUNCE_TIME_80MS       0x2800
 +#define TSC2301_DEBOUNCE_TIME_100MS      0x3000
 +#define TSC2301_DEBOUNCE_TIME_120MS      0x3800
 +
 +#define TSC2301_DEBOUNCE_TIME         TSC2301_DEBOUNCE_TIME_20MS
 +
 +#define TSC2301_RELEASE_TIMEOUT               50
 +
 +struct tsc2301_kp {
 +      struct input_dev        *idev;
 +      char                    phys[32];
 +      spinlock_t              lock;
 +      struct mutex            mutex;
 +      struct timer_list       timer;
 +      u16                     keys_pressed;
 +      unsigned                pending:1;
 +      unsigned                user_disabled:1;
 +      unsigned                disable_depth;
 +
 +      struct spi_transfer     read_xfer[4];
 +      struct spi_message      read_msg;
 +
 +      u16                     data;
 +      u16                     mask;
 +
 +      int                     irq;
 +      s16                     keymap[16];
 +};
 +
 +static inline int tsc2301_kp_disabled(struct tsc2301 *tsc)
 +{
 +      return tsc->kp->disable_depth != 0;
 +}
 +
 +static void tsc2301_kp_send_key_events(struct tsc2301 *tsc,
 +                                     u16 prev_state,
 +                                     u16 new_state)
 +{
 +      struct tsc2301_kp *kp = tsc->kp;
 +      u16 common, released, pressed;
 +      int i;
 +
 +      common = prev_state & new_state;
 +      released = common ^ prev_state;
 +      pressed = common ^ new_state;
 +      if (!released && !pressed)
 +              return;
 +      for (i = 0; i < 16 && (released || pressed); i++) {
 +              if (released & 1) {
 +                      dev_dbg(&tsc->spi->dev, "key %d released\n", i);
 +                      input_report_key(kp->idev, kp->keymap[i], 0);
 +              }
 +              released >>= 1;
 +              if (pressed & 1) {
 +                      dev_dbg(&tsc->spi->dev, "key %d pressed\n", i);
 +                      input_report_key(kp->idev, kp->keymap[i], 1);
 +              }
 +              pressed >>= 1;
 +      }
 +      input_sync(kp->idev);
 +}
 +
 +static inline void _filter_out(struct tsc2301 *tsc, u16 prev_state,
 +                             u16 *new_state, int row1, int row2, u8 rect_pat)
 +{
 +      u16 mask;
 +
 +      mask = (rect_pat << (row1 * 4)) | (rect_pat << (row2 * 4));
 +      mask &= ~prev_state;
 +      *new_state &= ~mask;
 +      dev_dbg(&tsc->spi->dev, "filtering ghost keys %02x\n", mask);
 +}
 +
 +static void tsc2301_filter_ghost_keys(struct tsc2301 *tsc, u16 prev_state,
 +                                    u16 *new_state)
 +{
 +      int row1, row2;
 +      u16 key_map;
 +      u16 row1_map;
 +      static const u8 rect_pat[] = {
 +              0x3, 0x5, 0x9, 0x6, 0xa, 0xc, 0,
 +      };
 +
 +      key_map = *new_state;
 +      for (row1 = 0; row1 < 4; row1++) {
 +              row1_map = (key_map >> (row1 * 4)) & 0xf;
 +              if (!row1_map)
 +                      continue;
 +              for (row2 = row1 + 1; row2 < 4; row2++) {
 +                      u16 rect_map = (key_map >> (row2 * 4)) & 0xf;
 +                      const u8 *rp;
 +
 +                      rect_map &= row1_map;
 +                      if (!rect_map)
 +                              continue;
 +                      for (rp = rect_pat; *rp; rp++)
 +                              if ((rect_map & *rp) == *rp)
 +                                      _filter_out(tsc, prev_state, new_state,
 +                                                  row1, row2, *rp);
 +              }
 +      }
 +}
 +
 +static void tsc2301_kp_timer(unsigned long arg)
 +{
 +      struct tsc2301 *tsc = (void *) arg;
 +      struct tsc2301_kp *kp = tsc->kp;
 +      unsigned long flags;
 +
 +      tsc2301_kp_send_key_events(tsc, kp->keys_pressed, 0);
 +      spin_lock_irqsave(&kp->lock, flags);
 +      kp->keys_pressed = 0;
 +      spin_unlock_irqrestore(&kp->lock, flags);
 +}
 +
 +static void tsc2301_kp_rx(void *arg)
 +{
 +      struct tsc2301 *tsc = arg;
 +      struct tsc2301_kp *kp = tsc->kp;
 +      unsigned long flags;
 +      u16 kp_data;
 +
 +      kp_data = kp->data;
 +      dev_dbg(&tsc->spi->dev, "KP data %04x\n", kp_data);
 +
 +      tsc2301_filter_ghost_keys(tsc, kp->keys_pressed, &kp_data);
 +      tsc2301_kp_send_key_events(tsc, kp->keys_pressed, kp_data);
 +      spin_lock_irqsave(&kp->lock, flags);
 +      kp->keys_pressed = kp_data;
 +      kp->pending = 0;
 +      spin_unlock_irqrestore(&kp->lock, flags);
 +}
 +
 +static irqreturn_t tsc2301_kp_irq_handler(int irq, void *dev_id)
 +{
 +      struct tsc2301 *tsc = dev_id;
 +      struct tsc2301_kp *kp = tsc->kp;
 +      unsigned long flags;
 +      int r;
 +
 +      spin_lock_irqsave(&kp->lock, flags);
 +      if (tsc2301_kp_disabled(tsc)) {
 +              spin_unlock_irqrestore(&kp->lock, flags);
 +              return IRQ_HANDLED;
 +      }
 +      kp->pending = 1;
 +      spin_unlock_irqrestore(&kp->lock, flags);
 +      mod_timer(&kp->timer,
 +               jiffies + msecs_to_jiffies(TSC2301_RELEASE_TIMEOUT));
 +      r = spi_async(tsc->spi, &tsc->kp->read_msg);
 +      if (r)
 +              dev_err(&tsc->spi->dev, "kp: spi_async() failed");
 +      return IRQ_HANDLED;
 +}
 +
 +static void tsc2301_kp_start_scan(struct tsc2301 *tsc)
 +{
 +      tsc2301_write_reg(tsc, TSC2301_REG_KPMASK, tsc->kp->mask);
 +      tsc2301_write_reg(tsc, TSC2301_REG_KEY, TSC2301_DEBOUNCE_TIME);
 +}
 +
 +static void tsc2301_kp_stop_scan(struct tsc2301 *tsc)
 +{
 +      tsc2301_write_reg(tsc, TSC2301_REG_KEY, 1 << 14);
 +}
 +
 +/* Must be called with the mutex held */
 +static void tsc2301_kp_enable(struct tsc2301 *tsc)
 +{
 +      struct tsc2301_kp *kp = tsc->kp;
 +      unsigned long flags;
 +
 +      spin_lock_irqsave(&kp->lock, flags);
 +      BUG_ON(!tsc2301_kp_disabled(tsc));
 +      if (--kp->disable_depth != 0) {
 +              spin_unlock_irqrestore(&kp->lock, flags);
 +              return;
 +      }
 +      spin_unlock_irqrestore(&kp->lock, flags);
 +
 +      set_irq_type(kp->irq, IRQ_TYPE_EDGE_FALLING);
 +      tsc2301_kp_start_scan(tsc);
 +      enable_irq(kp->irq);
 +}
 +
 +/* Must be called with the mutex held */
 +static int tsc2301_kp_disable(struct tsc2301 *tsc, int release_keys)
 +{
 +      struct tsc2301_kp *kp = tsc->kp;
 +      unsigned long flags;
 +
 +      spin_lock_irqsave(&kp->lock, flags);
 +      if (kp->disable_depth++ != 0) {
 +              spin_unlock_irqrestore(&kp->lock, flags);
 +              goto out;
 +      }
 +      disable_irq_nosync(kp->irq);
 +      set_irq_type(kp->irq, IRQ_TYPE_NONE);
 +      spin_unlock_irqrestore(&kp->lock, flags);
 +
 +      while (kp->pending) {
 +              msleep(1);
 +      }
 +
 +      tsc2301_kp_stop_scan(tsc);
 +out:
 +      if (!release_keys)
 +              del_timer(&kp->timer); /* let timeout release keys */
 +
 +      return 0;
 +}
 +
 +/* The following workaround is needed for a HW bug triggered by the
 + * following:
 + * 1. keep any key pressed
 + * 2. disable keypad
 + * 3. release all keys
 + * 4. reenable keypad
 + * 5. disable touch screen controller
 + *
 + * After this the keypad scanner will get stuck in busy state and won't
 + * report any interrupts for further keypresses. One way to recover is to
 + * restart the keypad scanner whenever we enable / disable the
 + * touchscreen controller.
 + */
 +void tsc2301_kp_restart(struct tsc2301 *tsc)
 +{
 +      if (!tsc2301_kp_disabled(tsc)) {
 +              tsc2301_kp_start_scan(tsc);
 +      }
 +}
 +
 +static ssize_t tsc2301_kp_disable_show(struct device *dev,
 +                                     struct device_attribute *attr, char *buf)
 +{
 +      struct tsc2301          *tsc = dev_get_drvdata(dev);
 +
 +      return sprintf(buf, "%u\n", tsc2301_kp_disabled(tsc) ? 1 : 0);
 +}
 +
 +static ssize_t tsc2301_kp_disable_store(struct device *dev,
 +                                      struct device_attribute *attr,
 +                                      const char *buf, size_t count)
 +{
 +      struct tsc2301          *tsc = dev_get_drvdata(dev);
 +      struct tsc2301_kp       *kp = tsc->kp;
 +      char *endp;
 +      int i;
 +
 +      i = simple_strtoul(buf, &endp, 10);
 +      i = i ? 1 : 0;
 +
 +      mutex_lock(&kp->mutex);
 +      if (i == kp->user_disabled) {
 +              mutex_unlock(&kp->mutex);
 +              return count;
 +      }
 +      kp->user_disabled = i;
 +
 +      if (i)
 +              tsc2301_kp_disable(tsc, 1);
 +      else
 +              tsc2301_kp_enable(tsc);
 +      mutex_unlock(&kp->mutex);
 +
 +      return count;
 +}
 +
 +static DEVICE_ATTR(disable_kp, 0664, tsc2301_kp_disable_show,
 +                 tsc2301_kp_disable_store);
 +
 +static const u16 tsc2301_kp_read_data = 0x8000 | TSC2301_REG_KPDATA;
 +
 +static void tsc2301_kp_setup_spi_xfer(struct tsc2301 *tsc)
 +{
 +      struct tsc2301_kp *kp = tsc->kp;
 +      struct spi_message *m = &kp->read_msg;
 +      struct spi_transfer *x = &kp->read_xfer[0];
 +
 +      spi_message_init(&kp->read_msg);
 +
 +      x->tx_buf = &tsc2301_kp_read_data;
 +      x->len = 2;
 +      spi_message_add_tail(x, m);
 +      x++;
 +
 +      x->rx_buf = &kp->data;
 +      x->len = 2;
 +      spi_message_add_tail(x, m);
 +
 +      m->complete = tsc2301_kp_rx;
 +      m->context = tsc;
 +}
 +
 +#ifdef CONFIG_PM
 +int tsc2301_kp_suspend(struct tsc2301 *tsc)
 +{
 +      struct tsc2301_kp *kp = tsc->kp;
 +
 +      mutex_lock(&kp->mutex);
 +      tsc2301_kp_disable(tsc, 1);
 +      mutex_unlock(&kp->mutex);
 +      return 0;
 +}
 +
 +void tsc2301_kp_resume(struct tsc2301 *tsc)
 +{
 +      struct tsc2301_kp *kp = tsc->kp;
 +
 +      mutex_lock(&kp->mutex);
 +      tsc2301_kp_enable(tsc);
 +      mutex_unlock(&kp->mutex);
 +}
 +#endif
 +
 +int __devinit tsc2301_kp_init(struct tsc2301 *tsc,
 +                            struct tsc2301_platform_data *pdata)
 +{
 +      struct input_dev *idev;
 +      struct tsc2301_kp *kp;
 +      int r, i;
 +      u16 mask;
 +
 +      if (pdata->keyb_int < 0) {
 +              dev_err(&tsc->spi->dev, "need kbirq");
 +              return -EINVAL;
 +      }
 +
 +      kp = kzalloc(sizeof(*kp), GFP_KERNEL);
 +      if (kp == NULL)
 +              return -ENOMEM;
 +      tsc->kp = kp;
 +
 +      kp->irq = pdata->keyb_int;
 +      spin_lock_init(&kp->lock);
 +      mutex_init(&kp->mutex);
 +
 +      init_timer(&kp->timer);
 +      kp->timer.data = (unsigned long) tsc;
 +      kp->timer.function = tsc2301_kp_timer;
 +
 +      idev = input_allocate_device();
 +      if (idev == NULL) {
 +              r = -ENOMEM;
 +              goto err1;
 +      }
 +      if (pdata->keyb_name)
 +              idev->name = pdata->keyb_name;
 +      else
 +              idev->name = "TSC2301 keypad";
++      snprintf(kp->phys, sizeof(kp->phys), "%s/input-kp", dev_name(&tsc->spi->dev));
 +      idev->phys = kp->phys;
 +
 +      mask = 0;
 +      idev->evbit[0] = BIT(EV_KEY);
 +      for (i = 0; i < 16; i++) {
 +              if (pdata->keymap[i] > 0) {
 +                      set_bit(pdata->keymap[i], idev->keybit);
 +                      kp->keymap[i] = pdata->keymap[i];
 +              } else {
 +                      kp->keymap[i] = -1;
 +                      mask |= 1 << i;
 +              }
 +      }
 +
 +      if (pdata->kp_rep)
 +              set_bit(EV_REP, idev->evbit);
 +
 +      kp->idev = idev;
 +
 +      tsc2301_kp_setup_spi_xfer(tsc);
 +
 +      r = device_create_file(&tsc->spi->dev, &dev_attr_disable_kp);
 +      if (r < 0)
 +              goto err2;
 +
 +      tsc2301_kp_start_scan(tsc);
 +
 +      /* IRQ mode 0 is faulty, it can cause the KBIRQ to get stuck.
 +       * Mode 2 deasserts the IRQ at:
 +       * - HW or SW reset
 +       * - Setting SCS flag in REG_KEY register
 +       * - Releasing all keys
 +       * - Reading the REG_KPDATA
 +       */
 +      tsc2301_write_kbc(tsc, 2);
 +
 +      tsc2301_write_reg(tsc, TSC2301_REG_KPMASK, mask);
 +      kp->mask = mask;
 +
 +      set_irq_type(kp->irq, IRQ_TYPE_EDGE_FALLING);
 +
 +      r = request_irq(kp->irq, tsc2301_kp_irq_handler, IRQF_SAMPLE_RANDOM,
 +                      "tsc2301-kp", tsc);
 +      if (r < 0) {
 +              dev_err(&tsc->spi->dev, "unable to get kbirq IRQ");
 +              goto err3;
 +      }
 +      set_irq_wake(kp->irq, 1);
 +
 +      /* We need to read the register once..? */
 +      tsc2301_read_reg(tsc, TSC2301_REG_KPDATA);
 +
 +      r = input_register_device(idev);
 +      if (r < 0) {
 +              dev_err(&tsc->spi->dev, "can't register keypad device\n");
 +              goto err4;
 +      }
 +
 +      return 0;
 +
 +err4:
 +      free_irq(kp->irq, tsc);
 +err3:
 +      tsc2301_kp_stop_scan(tsc);
 +      device_remove_file(&tsc->spi->dev, &dev_attr_disable_kp);
 +err2:
 +      input_free_device(kp->idev);
 +err1:
 +      kfree(kp);
 +      return r;
 +}
 +
 +void __devexit tsc2301_kp_exit(struct tsc2301 *tsc)
 +{
 +      struct tsc2301_kp *kp = tsc->kp;
 +
 +      tsc2301_kp_disable(tsc, 1);
 +      input_unregister_device(kp->idev);
 +      free_irq(kp->irq, tsc);
 +      device_remove_file(&tsc->spi->dev, &dev_attr_disable_kp);
 +
 +      kfree(kp);
 +}
index 03c3a102dd61f7e6c844b1d5cd54bc20c3896975,0000000000000000000000000000000000000000..ec4c9e7a736753a7070af69cbddcbd551d0a0f1d
mode 100644,000000..100644
--- /dev/null
@@@ -1,728 -1,0 +1,728 @@@
-                ts->spi->dev.bus_id);
 +/*
 + * TSC2005 touchscreen driver
 + *
 + * Copyright (C) 2006-2008 Nokia Corporation
 + *
 + * Author: Lauri Leukkunen <lauri.leukkunen@nokia.com>
 + * based on TSC2301 driver by Klaus K. Pedersen <klaus.k.pedersen@nokia.com>
 + *
 + * 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.
 + *
 + * This program is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 + * GNU General Public License for more details.
 + *
 + * You should have received a copy of the GNU General Public License
 + * along with this program; if not, write to the Free Software
 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 + *
 + */
 +
 +#include <linux/kernel.h>
 +#include <linux/module.h>
 +#include <linux/input.h>
 +#include <linux/interrupt.h>
 +#include <linux/delay.h>
 +#include <linux/gpio.h>
 +#include <linux/spi/spi.h>
 +
 +#include <linux/spi/tsc2005.h>
 +
 +/**
 + * The touchscreen interface operates as follows:
 + *
 + * Initialize:
 + *    Request access to GPIO103 (DAV)
 + *    tsc2005_dav_irq_handler will trigger when DAV line goes down
 + *
 + *  1) Pen is pressed against touchscreeen
 + *  2) TSC2005 performs AD conversion
 + *  3) After the conversion is done TSC2005 drives DAV line down
 + *  4) GPIO IRQ is received and tsc2005_dav_irq_handler is called
 + *  5) tsc2005_ts_irq_handler queues up an spi transfer to fetch
 + *     the x, y, z1, z2 values
 + *  6) tsc2005_ts_rx() reports coordinates to input layer and
 + *     sets up tsc2005_ts_timer() to be called after TSC2005_TS_SCAN_TIME
 + *  7)  When the penup_timer expires, there have not been DAV interrupts
 + *     during the last 20ms which means the pen has been lifted.
 + */
 +
 +#define TSC2005_VDD_LOWER_27
 +
 +#ifdef TSC2005_VDD_LOWER_27
 +#define TSC2005_HZ     (10000000)
 +#else
 +#define TSC2005_HZ     (25000000)
 +#endif
 +
 +#define TSC2005_CMD   (0x80)
 +#define TSC2005_REG   (0x00)
 +
 +#define TSC2005_CMD_STOP      (1)
 +#define TSC2005_CMD_10BIT     (0 << 2)
 +#define TSC2005_CMD_12BIT     (1 << 2)
 +
 +#define TSC2005_CMD_SCAN_XYZZ (0 << 3)
 +#define TSC2005_CMD_SCAN_XY   (1 << 3)
 +#define TSC2005_CMD_SCAN_X    (2 << 3)
 +#define TSC2005_CMD_SCAN_Y    (3 << 3)
 +#define TSC2005_CMD_SCAN_ZZ   (4 << 3)
 +#define TSC2005_CMD_AUX_SINGLE        (5 << 3)
 +#define TSC2005_CMD_TEMP1     (6 << 3)
 +#define TSC2005_CMD_TEMP2     (7 << 3)
 +#define TSC2005_CMD_AUX_CONT  (8 << 3)
 +#define TSC2005_CMD_TEST_X_CONN       (9 << 3)
 +#define TSC2005_CMD_TEST_Y_CONN       (10 << 3)
 +/* command 11 reserved */
 +#define TSC2005_CMD_TEST_SHORT        (12 << 3)
 +#define TSC2005_CMD_DRIVE_XX  (13 << 3)
 +#define TSC2005_CMD_DRIVE_YY  (14 << 3)
 +#define TSC2005_CMD_DRIVE_YX  (15 << 3)
 +
 +#define TSC2005_REG_X         (0 << 3)
 +#define TSC2005_REG_Y         (1 << 3)
 +#define TSC2005_REG_Z1                (2 << 3)
 +#define TSC2005_REG_Z2                (3 << 3)
 +#define TSC2005_REG_AUX               (4 << 3)
 +#define TSC2005_REG_TEMP1     (5 << 3)
 +#define TSC2005_REG_TEMP2     (6 << 3)
 +#define TSC2005_REG_STATUS    (7 << 3)
 +#define TSC2005_REG_AUX_HIGH  (8 << 3)
 +#define TSC2005_REG_AUX_LOW   (9 << 3)
 +#define TSC2005_REG_TEMP_HIGH (10 << 3)
 +#define TSC2005_REG_TEMP_LOW  (11 << 3)
 +#define TSC2005_REG_CFR0      (12 << 3)
 +#define TSC2005_REG_CFR1      (13 << 3)
 +#define TSC2005_REG_CFR2      (14 << 3)
 +#define TSC2005_REG_FUNCTION  (15 << 3)
 +
 +#define TSC2005_REG_PND0      (1 << 1)
 +#define TSC2005_REG_READ      (0x01)
 +#define TSC2005_REG_WRITE     (0x00)
 +
 +
 +#define TSC2005_CFR0_LONGSAMPLING     (1)
 +#define TSC2005_CFR0_DETECTINWAIT     (1 << 1)
 +#define TSC2005_CFR0_SENSETIME_32US   (0)
 +#define TSC2005_CFR0_SENSETIME_96US   (1 << 2)
 +#define TSC2005_CFR0_SENSETIME_544US  (1 << 3)
 +#define TSC2005_CFR0_SENSETIME_2080US (1 << 4)
 +#define TSC2005_CFR0_SENSETIME_2656US (0x001C)
 +#define TSC2005_CFR0_PRECHARGE_20US   (0x0000)
 +#define TSC2005_CFR0_PRECHARGE_84US   (0x0020)
 +#define TSC2005_CFR0_PRECHARGE_276US  (0x0040)
 +#define TSC2005_CFR0_PRECHARGE_1044US (0x0080)
 +#define TSC2005_CFR0_PRECHARGE_1364US (0x00E0)
 +#define TSC2005_CFR0_STABTIME_0US     (0x0000)
 +#define TSC2005_CFR0_STABTIME_100US   (0x0100)
 +#define TSC2005_CFR0_STABTIME_500US   (0x0200)
 +#define TSC2005_CFR0_STABTIME_1MS     (0x0300)
 +#define TSC2005_CFR0_STABTIME_5MS     (0x0400)
 +#define TSC2005_CFR0_STABTIME_100MS   (0x0700)
 +#define TSC2005_CFR0_CLOCK_4MHZ               (0x0000)
 +#define TSC2005_CFR0_CLOCK_2MHZ               (0x0800)
 +#define TSC2005_CFR0_CLOCK_1MHZ               (0x1000)
 +#define TSC2005_CFR0_RESOLUTION12     (0x2000)
 +#define TSC2005_CFR0_STATUS           (0x4000)
 +#define TSC2005_CFR0_PENMODE          (0x8000)
 +
 +#define TSC2005_CFR0_INITVALUE        (TSC2005_CFR0_STABTIME_1MS  |   \
 +                               TSC2005_CFR0_CLOCK_1MHZ    |   \
 +                               TSC2005_CFR0_RESOLUTION12  |   \
 +                               TSC2005_CFR0_PRECHARGE_276US | \
 +                               TSC2005_CFR0_PENMODE)
 +
 +#define TSC2005_CFR1_BATCHDELAY_0MS   (0x0000)
 +#define TSC2005_CFR1_BATCHDELAY_1MS   (0x0001)
 +#define TSC2005_CFR1_BATCHDELAY_2MS   (0x0002)
 +#define TSC2005_CFR1_BATCHDELAY_4MS   (0x0003)
 +#define TSC2005_CFR1_BATCHDELAY_10MS  (0x0004)
 +#define TSC2005_CFR1_BATCHDELAY_20MS  (0x0005)
 +#define TSC2005_CFR1_BATCHDELAY_40MS  (0x0006)
 +#define TSC2005_CFR1_BATCHDELAY_100MS (0x0007)
 +
 +#define TSC2005_CFR1_INITVALUE        (TSC2005_CFR1_BATCHDELAY_2MS)
 +
 +#define TSC2005_CFR2_MAVE_TEMP        (0x0001)
 +#define TSC2005_CFR2_MAVE_AUX (0x0002)
 +#define TSC2005_CFR2_MAVE_Z   (0x0004)
 +#define TSC2005_CFR2_MAVE_Y   (0x0008)
 +#define TSC2005_CFR2_MAVE_X   (0x0010)
 +#define TSC2005_CFR2_AVG_1    (0x0000)
 +#define TSC2005_CFR2_AVG_3    (0x0400)
 +#define TSC2005_CFR2_AVG_7    (0x0800)
 +#define TSC2005_CFR2_MEDIUM_1 (0x0000)
 +#define TSC2005_CFR2_MEDIUM_3 (0x1000)
 +#define TSC2005_CFR2_MEDIUM_7 (0x2000)
 +#define TSC2005_CFR2_MEDIUM_15        (0x3000)
 +
 +#define TSC2005_CFR2_IRQ_DAV  (0x4000)
 +#define TSC2005_CFR2_IRQ_PEN  (0x8000)
 +#define TSC2005_CFR2_IRQ_PENDAV       (0x0000)
 +
 +#define TSC2005_CFR2_INITVALUE        (TSC2005_CFR2_IRQ_DAV   |       \
 +                               TSC2005_CFR2_MAVE_X    |       \
 +                               TSC2005_CFR2_MAVE_Y    |       \
 +                               TSC2005_CFR2_MAVE_Z    |       \
 +                               TSC2005_CFR2_MEDIUM_15 |       \
 +                               TSC2005_CFR2_AVG_7)
 +
 +#define MAX_12BIT                                     ((1 << 12) - 1)
 +#define TS_SAMPLES                                    4
 +#define TS_RECT_SIZE                                  8
 +#define TSC2005_TS_PENUP_TIME                         20
 +
 +static const u32 tsc2005_read_reg[] = {
 +      (TSC2005_REG | TSC2005_REG_X | TSC2005_REG_READ) << 16,
 +      (TSC2005_REG | TSC2005_REG_Y | TSC2005_REG_READ) << 16,
 +      (TSC2005_REG | TSC2005_REG_Z1 | TSC2005_REG_READ) << 16,
 +      (TSC2005_REG | TSC2005_REG_Z2 | TSC2005_REG_READ) << 16,
 +};
 +#define NUM_READ_REGS (sizeof(tsc2005_read_reg)/sizeof(tsc2005_read_reg[0]))
 +
 +struct tsc2005 {
 +      struct spi_device       *spi;
 +
 +      struct input_dev        *idev;
 +      char                    phys[32];
 +      struct timer_list       penup_timer;
 +      spinlock_t              lock;
 +      struct mutex            mutex;
 +
 +      struct spi_message      read_msg;
 +      struct spi_transfer     read_xfer[NUM_READ_REGS];
 +      u32                     data[NUM_READ_REGS];
 +
 +      /* previous x,y,z */
 +      int                     x;
 +      int                     y;
 +      int                     p;
 +      /* average accumulators for each component */
 +      int                     sample_cnt;
 +      int                     avg_x;
 +      int                     avg_y;
 +      int                     avg_z1;
 +      int                     avg_z2;
 +      /* configuration */
 +      int                     x_plate_ohm;
 +      int                     hw_avg_max;
 +      int                     stab_time;
 +      int                     p_max;
 +      int                     touch_pressure;
 +      int                     irq;
 +      s16                     dav_gpio;
 +      /* status */
 +      u8                      sample_sent;
 +      u8                      pen_down;
 +      u8                      disabled;
 +      u8                      disable_depth;
 +      u8                      spi_active;
 +};
 +
 +static void tsc2005_cmd(struct tsc2005 *ts, u8 cmd)
 +{
 +      u16 data = TSC2005_CMD | TSC2005_CMD_12BIT | cmd;
 +      struct spi_message msg;
 +      struct spi_transfer xfer = { 0 };
 +
 +      xfer.tx_buf = &data;
 +      xfer.rx_buf = NULL;
 +      xfer.len = 1;
 +      xfer.bits_per_word = 8;
 +
 +      spi_message_init(&msg);
 +      spi_message_add_tail(&xfer, &msg);
 +      spi_sync(ts->spi, &msg);
 +}
 +
 +static void tsc2005_write(struct tsc2005 *ts, u8 reg, u16 value)
 +{
 +      u32 tx;
 +      struct spi_message msg;
 +      struct spi_transfer xfer = { 0 };
 +
 +      tx = (TSC2005_REG | reg | TSC2005_REG_PND0 |
 +             TSC2005_REG_WRITE) << 16;
 +      tx |= value;
 +
 +      xfer.tx_buf = &tx;
 +      xfer.rx_buf = NULL;
 +      xfer.len = 4;
 +      xfer.bits_per_word = 24;
 +
 +      spi_message_init(&msg);
 +      spi_message_add_tail(&xfer, &msg);
 +      spi_sync(ts->spi, &msg);
 +}
 +
 +static void tsc2005_ts_update_pen_state(struct tsc2005 *ts,
 +                                      int x, int y, int pressure)
 +{
 +      if (pressure) {
 +              input_report_abs(ts->idev, ABS_X, x);
 +              input_report_abs(ts->idev, ABS_Y, y);
 +              input_report_abs(ts->idev, ABS_PRESSURE, pressure);
 +              if (!ts->pen_down) {
 +                      input_report_key(ts->idev, BTN_TOUCH, 1);
 +                      ts->pen_down = 1;
 +              }
 +      } else {
 +              input_report_abs(ts->idev, ABS_PRESSURE, 0);
 +              if (ts->pen_down) {
 +                      input_report_key(ts->idev, BTN_TOUCH, 0);
 +                      ts->pen_down = 0;
 +              }
 +      }
 +
 +      input_sync(ts->idev);
 +}
 +
 +/*
 + * This function is called by the SPI framework after the coordinates
 + * have been read from TSC2005
 + */
 +static void tsc2005_ts_rx(void *arg)
 +{
 +      struct tsc2005 *ts = arg;
 +      unsigned long flags;
 +      int inside_rect, pressure_limit;
 +      int x, y, z1, z2, pressure;
 +
 +      spin_lock_irqsave(&ts->lock, flags);
 +
 +      x = ts->data[0];
 +      y = ts->data[1];
 +      z1 = ts->data[2];
 +      z2 = ts->data[3];
 +
 +      /* validate pressure and position */
 +      if (x > MAX_12BIT || y > MAX_12BIT)
 +              goto out;
 +
 +      /* skip coords if the pressure-components are out of range */
 +      if (z1 < 100 || z2 > 4000)
 +              goto out;
 +
 +      /* don't run average on the "pen down" event */
 +      if (ts->sample_sent) {
 +              ts->avg_x += x;
 +              ts->avg_y += y;
 +              ts->avg_z1 += z1;
 +              ts->avg_z2 += z2;
 +
 +              if (++ts->sample_cnt < TS_SAMPLES)
 +                      goto out;
 +
 +              x = ts->avg_x / TS_SAMPLES;
 +              y = ts->avg_y / TS_SAMPLES;
 +              z1 = ts->avg_z1 / TS_SAMPLES;
 +              z2 = ts->avg_z2 / TS_SAMPLES;
 +      }
 +
 +      ts->sample_cnt = 0;
 +      ts->avg_x = 0;
 +      ts->avg_y = 0;
 +      ts->avg_z1 = 0;
 +      ts->avg_z2 = 0;
 +
 +      if (z1) {
 +              pressure = x * (z2 - z1) / z1;
 +              pressure = pressure * ts->x_plate_ohm / 4096;
 +      } else
 +              goto out;
 +
 +      pressure_limit = ts->sample_sent? ts->p_max: ts->touch_pressure;
 +      if (pressure > pressure_limit)
 +              goto out;
 +
 +      /* discard the event if it still is within the previous rect - unless
 +       * if the pressure is harder, but then use previous x,y position */
 +      inside_rect = (ts->sample_sent &&
 +              x > (int)ts->x - TS_RECT_SIZE &&
 +              x < (int)ts->x + TS_RECT_SIZE &&
 +              y > (int)ts->y - TS_RECT_SIZE &&
 +              y < (int)ts->y + TS_RECT_SIZE);
 +      if (inside_rect)
 +              x = ts->x, y = ts->y;
 +
 +      if (!inside_rect || pressure < ts->p) {
 +              tsc2005_ts_update_pen_state(ts, x, y, pressure);
 +              ts->sample_sent = 1;
 +              ts->x = x;
 +              ts->y = y;
 +              ts->p = pressure;
 +      }
 +out:
 +      ts->spi_active = 0;
 +      spin_unlock_irqrestore(&ts->lock, flags);
 +
 +      /* kick pen up timer - to make sure it expires again(!) */
 +      if (ts->sample_sent)
 +              mod_timer(&ts->penup_timer,
 +                        jiffies + msecs_to_jiffies(TSC2005_TS_PENUP_TIME));
 +}
 +
 +static void tsc2005_ts_penup_timer_handler(unsigned long data)
 +{
 +      struct tsc2005 *ts = (struct tsc2005 *)data;
 +
 +      if (ts->sample_sent) {
 +              tsc2005_ts_update_pen_state(ts, 0, 0, 0);
 +              ts->sample_sent = 0;
 +      }
 +}
 +
 +/*
 + * This interrupt is called when pen is down and coordinates are
 + * available. That is indicated by a falling edge on DAV line.
 + */
 +static irqreturn_t tsc2005_ts_irq_handler(int irq, void *dev_id)
 +{
 +      struct tsc2005 *ts = dev_id;
 +      int r;
 +
 +      if (ts->spi_active)
 +              return IRQ_HANDLED;
 +
 +      ts->spi_active = 1;
 +      r = spi_async(ts->spi, &ts->read_msg);
 +      if (r)
 +              dev_err(&ts->spi->dev, "ts: spi_async() failed");
 +
 +      /* kick pen up timer */
 +      mod_timer(&ts->penup_timer,
 +                jiffies + msecs_to_jiffies(TSC2005_TS_PENUP_TIME));
 +
 +      return IRQ_HANDLED;
 +}
 +
 +static void tsc2005_ts_setup_spi_xfer(struct tsc2005 *ts)
 +{
 +      struct spi_message *m = &ts->read_msg;
 +      struct spi_transfer *x = &ts->read_xfer[0];
 +      int i;
 +
 +      spi_message_init(m);
 +
 +      for (i = 0; i < NUM_READ_REGS; i++, x++) {
 +              x->tx_buf = &tsc2005_read_reg[i];
 +              x->rx_buf = &ts->data[i];
 +              x->len = 4;
 +              x->bits_per_word = 24;
 +              x->cs_change = i < (NUM_READ_REGS - 1);
 +              spi_message_add_tail(x, m);
 +      }
 +
 +      m->complete = tsc2005_ts_rx;
 +      m->context = ts;
 +}
 +
 +static ssize_t tsc2005_ts_pen_down_show(struct device *dev,
 +                                      struct device_attribute *attr,
 +                                      char *buf)
 +{
 +      struct tsc2005 *tsc = dev_get_drvdata(dev);
 +
 +      return sprintf(buf, "%u\n", tsc->pen_down);
 +}
 +
 +static DEVICE_ATTR(pen_down, S_IRUGO, tsc2005_ts_pen_down_show, NULL);
 +
 +static int tsc2005_configure(struct tsc2005 *tsc, int flags)
 +{
 +      tsc2005_write(tsc, TSC2005_REG_CFR0, TSC2005_CFR0_INITVALUE);
 +      tsc2005_write(tsc, TSC2005_REG_CFR1, TSC2005_CFR1_INITVALUE);
 +      tsc2005_write(tsc, TSC2005_REG_CFR2, TSC2005_CFR2_INITVALUE);
 +      tsc2005_cmd(tsc, flags);
 +
 +      return 0;
 +}
 +
 +static void tsc2005_start_scan(struct tsc2005 *tsc)
 +{
 +      tsc2005_configure(tsc, TSC2005_CMD_SCAN_XYZZ);
 +}
 +
 +static void tsc2005_stop_scan(struct tsc2005 *tsc)
 +{
 +      tsc2005_cmd(tsc, TSC2005_CMD_STOP);
 +}
 +
 +/* Must be called with mutex held */
 +static void tsc2005_disable(struct tsc2005 *ts)
 +{
 +      if (ts->disable_depth++ != 0)
 +              return;
 +
 +      disable_irq(ts->irq);
 +
 +      /* wait until penup timer expire normally */
 +      do {
 +              msleep(4);
 +      } while (ts->sample_sent);
 +
 +      tsc2005_stop_scan(ts);
 +}
 +
 +static void tsc2005_enable(struct tsc2005 *ts)
 +{
 +      if (--ts->disable_depth != 0)
 +              return;
 +
 +      enable_irq(ts->irq);
 +
 +      tsc2005_start_scan(ts);
 +}
 +
 +static ssize_t tsc2005_disable_show(struct device *dev,
 +                                  struct device_attribute *attr, char *buf)
 +{
 +      struct tsc2005 *ts = dev_get_drvdata(dev);
 +
 +      return sprintf(buf, "%u\n", ts->disabled);
 +}
 +
 +static ssize_t tsc2005_disable_store(struct device *dev,
 +                                   struct device_attribute *attr,
 +                                   const char *buf, size_t count)
 +{
 +      struct tsc2005          *tsc = dev_get_drvdata(dev);
 +      unsigned long res;
 +      int i;
 +
 +      i = strict_strtoul(buf, 10, &res);
 +      i = i ? 1 : 0;
 +
 +      mutex_lock(&tsc->mutex);
 +      if (i == tsc->disabled)
 +              goto out;
 +      tsc->disabled = i;
 +
 +      if (i)
 +              tsc2005_disable(tsc);
 +      else
 +              tsc2005_enable(tsc);
 +out:
 +      mutex_unlock(&tsc->mutex);
 +      return count;
 +}
 +
 +static DEVICE_ATTR(disable_ts, 0664, tsc2005_disable_show,
 +                 tsc2005_disable_store);
 +
 +
 +static int __devinit tsc2005_ts_init(struct tsc2005 *ts,
 +                                   struct tsc2005_platform_data *pdata)
 +{
 +      struct input_dev *idev;
 +      int dav_gpio, r;
 +      int x_max, y_max;
 +      int x_fudge, y_fudge, p_fudge;
 +
 +      if (pdata->dav_gpio < 0) {
 +              dev_err(&ts->spi->dev, "need DAV GPIO");
 +              return -EINVAL;
 +      }
 +      dav_gpio = pdata->dav_gpio;
 +      ts->dav_gpio = dav_gpio;
 +      dev_dbg(&ts->spi->dev, "TSC2005: DAV GPIO = %d\n", dav_gpio);
 +
 +      r = gpio_request(dav_gpio, "TSC2005 dav");
 +      if (r < 0) {
 +              dev_err(&ts->spi->dev, "unable to get DAV GPIO");
 +              goto err1;
 +      }
 +      gpio_direction_input(dav_gpio);
 +      ts->irq = gpio_to_irq(dav_gpio);
 +      dev_dbg(&ts->spi->dev, "TSC2005: DAV IRQ = %d\n", ts->irq);
 +
 +      init_timer(&ts->penup_timer);
 +      setup_timer(&ts->penup_timer, tsc2005_ts_penup_timer_handler,
 +                      (unsigned long)ts);
 +
 +      spin_lock_init(&ts->lock);
 +      mutex_init(&ts->mutex);
 +
 +      ts->x_plate_ohm         = pdata->ts_x_plate_ohm ? : 280;
 +      ts->hw_avg_max          = pdata->ts_hw_avg;
 +      ts->stab_time           = pdata->ts_stab_time;
 +      x_max                   = pdata->ts_x_max ? : 4096;
 +      x_fudge                 = pdata->ts_x_fudge ? : 4;
 +      y_max                   = pdata->ts_y_max ? : 4096;
 +      y_fudge                 = pdata->ts_y_fudge ? : 8;
 +      ts->p_max               = pdata->ts_pressure_max ? : MAX_12BIT;
 +      ts->touch_pressure      = pdata->ts_touch_pressure ? : ts->p_max;
 +      p_fudge                 = pdata->ts_pressure_fudge ? : 2;
 +
 +      idev = input_allocate_device();
 +      if (idev == NULL) {
 +              r = -ENOMEM;
 +              goto err2;
 +      }
 +
 +      idev->name = "TSC2005 touchscreen";
 +      snprintf(ts->phys, sizeof(ts->phys), "%s/input-ts",
++               dev_name(&ts->spi->dev));
 +      idev->phys = ts->phys;
 +
 +      idev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
 +      idev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
 +      ts->idev = idev;
 +
 +      tsc2005_ts_setup_spi_xfer(ts);
 +
 +      input_set_abs_params(idev, ABS_X, 0, x_max, x_fudge, 0);
 +      input_set_abs_params(idev, ABS_Y, 0, y_max, y_fudge, 0);
 +      input_set_abs_params(idev, ABS_PRESSURE, 0, ts->p_max, p_fudge, 0);
 +
 +      tsc2005_start_scan(ts);
 +
 +      r = request_irq(ts->irq, tsc2005_ts_irq_handler,
 +                      IRQF_TRIGGER_FALLING | IRQF_DISABLED |
 +                      IRQF_SAMPLE_RANDOM, "tsc2005", ts);
 +      if (r < 0) {
 +              dev_err(&ts->spi->dev, "unable to get DAV IRQ");
 +              goto err3;
 +      }
 +
 +      set_irq_wake(ts->irq, 1);
 +
 +      r = input_register_device(idev);
 +      if (r < 0) {
 +              dev_err(&ts->spi->dev, "can't register touchscreen device\n");
 +              goto err4;
 +      }
 +
 +      /* We can tolerate these failing */
 +      if (device_create_file(&ts->spi->dev, &dev_attr_pen_down));
 +      if (device_create_file(&ts->spi->dev, &dev_attr_disable_ts));
 +
 +      return 0;
 +err4:
 +      free_irq(ts->irq, ts);
 +err3:
 +      tsc2005_stop_scan(ts);
 +      input_free_device(idev);
 +err2:
 +      gpio_free(dav_gpio);
 +err1:
 +      return r;
 +}
 +
 +static int __devinit tsc2005_probe(struct spi_device *spi)
 +{
 +      struct tsc2005                  *tsc;
 +      struct tsc2005_platform_data    *pdata = spi->dev.platform_data;
 +      int r;
 +
 +      if (!pdata) {
 +              dev_dbg(&spi->dev, "no platform data?\n");
 +              return -ENODEV;
 +      }
 +
 +      tsc = kzalloc(sizeof(*tsc), GFP_KERNEL);
 +      if (tsc == NULL)
 +              return -ENOMEM;
 +
 +      dev_set_drvdata(&spi->dev, tsc);
 +      tsc->spi = spi;
 +      spi->dev.power.power_state = PMSG_ON;
 +
 +      spi->mode = SPI_MODE_0;
 +      spi->bits_per_word = 8;
 +      /* The max speed might've been defined by the board-specific
 +       * struct */
 +      if (!spi->max_speed_hz)
 +              spi->max_speed_hz = TSC2005_HZ;
 +
 +      spi_setup(spi);
 +
 +      r = tsc2005_ts_init(tsc, pdata);
 +      if (r)
 +              goto err1;
 +
 +      return 0;
 +
 +err1:
 +      kfree(tsc);
 +      return r;
 +}
 +
 +static int __devexit tsc2005_remove(struct spi_device *spi)
 +{
 +      struct tsc2005 *ts = dev_get_drvdata(&spi->dev);
 +
 +      mutex_lock(&ts->mutex);
 +      tsc2005_disable(ts);
 +      mutex_unlock(&ts->mutex);
 +
 +      device_remove_file(&ts->spi->dev, &dev_attr_disable_ts);
 +      device_remove_file(&ts->spi->dev, &dev_attr_pen_down);
 +
 +      free_irq(ts->irq, ts);
 +      input_unregister_device(ts->idev);
 +
 +      gpio_free(ts->dav_gpio);
 +      kfree(ts);
 +
 +      return 0;
 +}
 +
 +#ifdef CONFIG_PM
 +static int tsc2005_suspend(struct spi_device *spi, pm_message_t mesg)
 +{
 +      struct tsc2005 *ts = dev_get_drvdata(&spi->dev);
 +
 +      mutex_lock(&ts->mutex);
 +      tsc2005_disable(ts);
 +      mutex_unlock(&ts->mutex);
 +
 +      return 0;
 +}
 +
 +static int tsc2005_resume(struct spi_device *spi)
 +{
 +      struct tsc2005 *ts = dev_get_drvdata(&spi->dev);
 +
 +      mutex_lock(&ts->mutex);
 +      tsc2005_enable(ts);
 +      mutex_unlock(&ts->mutex);
 +
 +      return 0;
 +}
 +#endif
 +
 +static struct spi_driver tsc2005_driver = {
 +      .driver = {
 +              .name = "tsc2005",
 +              .owner = THIS_MODULE,
 +      },
 +#ifdef CONFIG_PM
 +      .suspend = tsc2005_suspend,
 +      .resume = tsc2005_resume,
 +#endif
 +      .probe = tsc2005_probe,
 +      .remove = __devexit_p(tsc2005_remove),
 +};
 +
 +static int __init tsc2005_init(void)
 +{
 +      printk(KERN_INFO "TSC2005 driver initializing\n");
 +
 +      return spi_register_driver(&tsc2005_driver);
 +}
 +module_init(tsc2005_init);
 +
 +static void __exit tsc2005_exit(void)
 +{
 +      spi_unregister_driver(&tsc2005_driver);
 +}
 +module_exit(tsc2005_exit);
 +
 +MODULE_AUTHOR("Lauri Leukkunen <lauri.leukkunen@nokia.com>");
 +MODULE_LICENSE("GPL");
 +MODULE_ALIAS("platform:tsc2005");
index 6462cc2bf398447e67f60d821401fc85dd025ef8,0000000000000000000000000000000000000000..a157b48dd0b8638a9187ed950be8403a12242d84
mode 100644,000000..100644
--- /dev/null
@@@ -1,676 -1,0 +1,676 @@@
-                "%s/input-ts", tsc->spi->dev.bus_id);
 +/*
 + * TSC2301 touchscreen driver
 + *
 + * Copyright (C) 2005-2008 Nokia Corporation
 + *
 + * Written by Jarkko Oikarinen, Imre Deak and Juha Yrjola
 + *
 + * 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.
 + *
 + * This program is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 + * GNU General Public License for more details.
 + *
 + * You should have received a copy of the GNU General Public License
 + * along with this program; if not, write to the Free Software
 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 + *
 + */
 +
 +#include <linux/kernel.h>
 +#include <linux/module.h>
 +#include <linux/input.h>
 +#include <linux/interrupt.h>
 +#include <linux/delay.h>
 +#include <linux/spi/spi.h>
 +
 +#include <linux/spi/tsc2301.h>
 +
 +/**
 + * The touchscreen interface operates as follows:
 + *
 + * Initialize:
 + *    Request access to GPIO103 (DAV)
 + *    tsc2301_ts_irq_handler will trigger when DAV line goes down
 + *
 + *  1) Pen is pressed against touchscreeen
 + *  2) TSC2301 performs AD conversion
 + *  3) After the conversion is done TSC2301 drives DAV line down
 + *  4) GPIO IRQ is received and tsc2301_ts_irq_handler is called
 + *  5) tsc2301_ts_irq_handler queues up an spi transfer to fetch
 + *     the x, y, z1, z2 values
 + *  6) SPI framework calls tsc2301_ts_rx after the coordinates are read
 + *  7) When the penup_timer expires, there have not been DAV interrupts
 + *     during the last 20ms which means the pen has been lifted.
 + */
 +
 +
 +#define TSC2301_TOUCHSCREEN_PRODUCT_ID                0x0052
 +#define TSC2301_TOUCHSCREEN_PRODUCT_VERSION           0x0001
 +
 +#define TSC2301_TS_PENUP_TIME                         20
 +
 +#define TSC2301_ADCREG_CONVERSION_CTRL_BY_TSC2301     0x8000
 +#define TSC2301_ADCREG_CONVERSION_CTRL_BY_HOST                0x0000
 +
 +#define TSC2301_ADCREG_FUNCTION_NONE                  0x0000
 +#define TSC2301_ADCREG_FUNCTION_XY                    0x0400
 +#define TSC2301_ADCREG_FUNCTION_XYZ                   0x0800
 +#define TSC2301_ADCREG_FUNCTION_X                     0x0C00
 +#define TSC2301_ADCREG_FUNCTION_Y                     0x1000
 +#define TSC2301_ADCREG_FUNCTION_Z                     0x1400
 +#define TSC2301_ADCREG_FUNCTION_DAT1                  0x1800
 +#define TSC2301_ADCREG_FUNCTION_DAT2                  0x1C00
 +#define TSC2301_ADCREG_FUNCTION_AUX1                  0x2000
 +#define TSC2301_ADCREG_FUNCTION_AUX2                  0x2400
 +#define TSC2301_ADCREG_FUNCTION_TEMP                  0x2800
 +
 +#define TSC2301_ADCREG_RESOLUTION_8BIT                        0x0100
 +#define TSC2301_ADCREG_RESOLUTION_10BIT                       0x0200
 +#define TSC2301_ADCREG_RESOLUTION_12BIT                       0x0300
 +
 +#define TSC2301_ADCREG_AVERAGING_NONE                 0x0000
 +#define TSC2301_ADCREG_AVERAGING_4AVG                 0x0040
 +#define TSC2301_ADCREG_AVERAGING_8AVG                 0x0080
 +#define TSC2301_ADCREG_AVERAGING_16AVG                        0x00C0
 +
 +#define TSC2301_ADCREG_CLOCK_8MHZ                     0x0000
 +#define TSC2301_ADCREG_CLOCK_4MHZ                     0x0010
 +#define TSC2301_ADCREG_CLOCK_2MHZ                     0x0020
 +#define TSC2301_ADCREG_CLOCK_1MHZ                     0x0030
 +
 +#define TSC2301_ADCREG_VOLTAGE_STAB_0US                       0x0000
 +#define TSC2301_ADCREG_VOLTAGE_STAB_100US             0x0002
 +#define TSC2301_ADCREG_VOLTAGE_STAB_500US             0x0004
 +#define TSC2301_ADCREG_VOLTAGE_STAB_1MS                       0x0006
 +#define TSC2301_ADCREG_VOLTAGE_STAB_5MS                       0x0008
 +#define TSC2301_ADCREG_VOLTAGE_STAB_10MS              0x000A
 +#define TSC2301_ADCREG_VOLTAGE_STAB_50MS              0x000C
 +#define TSC2301_ADCREG_VOLTAGE_STAB_100MS             0x000E
 +
 +#define TSC2301_ADCREG_STOP_CONVERSION                        0x4000
 +
 +#define MAX_12BIT                                     ((1 << 12) - 1)
 +
 +#define TS_RECT_SIZE                                  8
 +#define TSF_MIN_Z1                                    100
 +#define TSF_MAX_Z2                                    4000
 +
 +#define TSF_SAMPLES                                   4
 +
 +struct ts_filter {
 +      int                     sample_cnt;
 +
 +      int                     avg_x;
 +      int                     avg_y;
 +      int                     avg_z1;
 +      int                     avg_z2;
 +};
 +
 +struct ts_coords {
 +      u16                     x;
 +      u16                     y;
 +      u16                     z1;
 +      u16                     z2;
 +};
 +
 +struct tsc2301_ts {
 +      struct input_dev        *idev;
 +      char                    phys[32];
 +      struct timer_list       penup_timer;
 +      struct mutex            mutex;
 +
 +      struct spi_transfer     read_xfer[2];
 +      struct spi_message      read_msg;
 +      struct ts_coords        *coords;
 +
 +      struct ts_filter        filter;
 +
 +      int                     hw_avg_max;
 +      u16                     x;
 +      u16                     y;
 +      u16                     p;
 +
 +      u16                     x_plate_ohm;
 +      int                     stab_time;
 +      int                     max_pressure;
 +      int                     touch_pressure;
 +
 +      u8                      event_sent;
 +      u8                      pen_down;
 +      u8                      disabled;
 +      u8                      disable_depth;
 +
 +      int                     hw_flags;
 +      int                     irq;
 +};
 +
 +
 +static const u16 tsc2301_ts_read_data = 0x8000 | TSC2301_REG_X;
 +
 +static int tsc2301_ts_check_config(struct tsc2301_ts *ts, int *hw_flags)
 +{
 +      int flags;
 +
 +      flags = 0;
 +      switch (ts->hw_avg_max) {
 +      case 0:
 +              flags |= TSC2301_ADCREG_AVERAGING_NONE;
 +              break;
 +      case 4:
 +              flags |= TSC2301_ADCREG_AVERAGING_4AVG;
 +              break;
 +      case 8:
 +              flags |= TSC2301_ADCREG_AVERAGING_8AVG;
 +              break;
 +      case 16:
 +              flags |= TSC2301_ADCREG_AVERAGING_16AVG;
 +              break;
 +      default:
 +              return -EINVAL;
 +      }
 +
 +      switch (ts->stab_time) {
 +      case 0:
 +              flags |= TSC2301_ADCREG_VOLTAGE_STAB_0US;
 +              break;
 +      case 100:
 +              flags |= TSC2301_ADCREG_VOLTAGE_STAB_100US;
 +              break;
 +      case 500:
 +              flags |= TSC2301_ADCREG_VOLTAGE_STAB_500US;
 +              break;
 +      case 1000:
 +              flags |= TSC2301_ADCREG_VOLTAGE_STAB_1MS;
 +              break;
 +      case 5000:
 +              flags |= TSC2301_ADCREG_VOLTAGE_STAB_5MS;
 +              break;
 +      case 10000:
 +              flags |= TSC2301_ADCREG_VOLTAGE_STAB_10MS;
 +              break;
 +      case 50000:
 +              flags |= TSC2301_ADCREG_VOLTAGE_STAB_50MS;
 +              break;
 +      case 100000:
 +              flags |= TSC2301_ADCREG_VOLTAGE_STAB_100MS;
 +              break;
 +      default:
 +              return -EINVAL;
 +      }
 +
 +      *hw_flags = flags;
 +      return 0;
 +}
 +
 +/*
 + * This odd three-time initialization is to work around a bug in TSC2301.
 + * See TSC2301 errata for details.
 + */
 +static int tsc2301_ts_configure(struct tsc2301 *tsc, int flags)
 +{
 +      struct spi_transfer xfer[5];
 +      struct spi_transfer *x;
 +      struct spi_message m;
 +      int i;
 +      u16 val1, val2, val3;
 +      u16 data[10];
 +
 +      val1 = TSC2301_ADCREG_CONVERSION_CTRL_BY_HOST |
 +              TSC2301_ADCREG_STOP_CONVERSION |
 +              TSC2301_ADCREG_FUNCTION_NONE |
 +              TSC2301_ADCREG_RESOLUTION_12BIT |
 +              TSC2301_ADCREG_AVERAGING_NONE |
 +              TSC2301_ADCREG_CLOCK_2MHZ |
 +              TSC2301_ADCREG_VOLTAGE_STAB_100MS;
 +
 +      val2 = TSC2301_ADCREG_CONVERSION_CTRL_BY_HOST |
 +              TSC2301_ADCREG_FUNCTION_XYZ |
 +              TSC2301_ADCREG_RESOLUTION_12BIT |
 +              TSC2301_ADCREG_AVERAGING_16AVG |
 +              TSC2301_ADCREG_CLOCK_1MHZ |
 +              TSC2301_ADCREG_VOLTAGE_STAB_100MS;
 +
 +      /* Averaging and voltage stabilization settings in flags */
 +      val3 = TSC2301_ADCREG_CONVERSION_CTRL_BY_TSC2301 |
 +              TSC2301_ADCREG_FUNCTION_XYZ |
 +              TSC2301_ADCREG_RESOLUTION_12BIT |
 +              TSC2301_ADCREG_CLOCK_2MHZ |
 +              flags;
 +
 +      /* Now we prepare the command for transferring */
 +      data[0] = TSC2301_REG_ADC;
 +      data[1] = val1;
 +      data[2] = TSC2301_REG_ADC;
 +      data[3] = val2;
 +      data[4] = TSC2301_REG_ADC;
 +      data[5] = val3;
 +      data[6] = TSC2301_REG_REF;
 +      data[7] = 1 << 4 | 1 << 2 | 1; /* intref, 100uS settl, 2.5V ref */
 +      data[8] = TSC2301_REG_CONFIG;
 +      data[9] = 3 << 3 | 2 << 0; /* 340uS pre-chrg, 544us delay */
 +
 +      spi_message_init(&m);
 +      m.spi = tsc->spi;
 +
 +      memset(xfer, 0, sizeof(xfer));
 +      x = &xfer[0];
 +
 +      for (i = 0; i < 10; i += 2) {
 +              x->tx_buf = &data[i];
 +              x->len = 4;
 +              if (i != 8)
 +                      x->cs_change = 1;
 +              spi_message_add_tail(x, &m);
 +              x++;
 +      }
 +      spi_sync(m.spi, &m);
 +
 +      return 0;
 +}
 +
 +static void tsc2301_ts_start_scan(struct tsc2301 *tsc)
 +{
 +      tsc2301_ts_configure(tsc, tsc->ts->hw_flags);
 +      tsc2301_kp_restart(tsc);
 +}
 +
 +static void tsc2301_ts_stop_scan(struct tsc2301 *tsc)
 +{
 +      tsc2301_write_reg(tsc, TSC2301_REG_ADC, TSC2301_ADCREG_STOP_CONVERSION);
 +      tsc2301_kp_restart(tsc);
 +}
 +
 +static void update_pen_state(struct tsc2301_ts *ts, int x, int y, int pressure)
 +{
 +      if (pressure) {
 +              input_report_abs(ts->idev, ABS_X, x);
 +              input_report_abs(ts->idev, ABS_Y, y);
 +              input_report_abs(ts->idev, ABS_PRESSURE, pressure);
 +              if (!ts->pen_down)
 +                      input_report_key(ts->idev, BTN_TOUCH, 1);
 +              ts->pen_down = 1;
 +      } else {
 +              input_report_abs(ts->idev, ABS_PRESSURE, 0);
 +              if (ts->pen_down)
 +                      input_report_key(ts->idev, BTN_TOUCH, 0);
 +              ts->pen_down = 0;
 +      }
 +
 +      input_sync(ts->idev);
 +
 +#ifdef VERBOSE
 +      dev_dbg(&tsc->spi->dev, "x %4d y %4d p %4d\n", x, y, pressure);
 +#endif
 +}
 +
 +static int filter(struct tsc2301_ts *ts, int x, int y, int z1, int z2)
 +{
 +      int inside_rect, pressure_limit, Rt;
 +      struct ts_filter *tsf = &ts->filter;
 +
 +      /* validate pressure and position */
 +      if (x > MAX_12BIT || y > MAX_12BIT)
 +              return 0;
 +
 +      /* skip coords if the pressure-components are out of range */
 +      if (z1 < TSF_MIN_Z1 || z2 > TSF_MAX_Z2)
 +              return 0;
 +
 +      /* Use the x,y,z1,z2 directly on the first "pen down" event */
 +      if (ts->event_sent) {
 +              tsf->avg_x  += x;
 +              tsf->avg_y  += y;
 +              tsf->avg_z1 += z1;
 +              tsf->avg_z2 += z2;
 +
 +              if (++tsf->sample_cnt < TSF_SAMPLES)
 +                      return 0;
 +              x = tsf->avg_x / TSF_SAMPLES;
 +              y = tsf->avg_y / TSF_SAMPLES;
 +              z1 = tsf->avg_z1 / TSF_SAMPLES;
 +              z2 = tsf->avg_z2 / TSF_SAMPLES;
 +      }
 +      tsf->sample_cnt = 0;
 +      tsf->avg_x  = 0;
 +      tsf->avg_y  = 0;
 +      tsf->avg_z1 = 0;
 +      tsf->avg_z2 = 0;
 +
 +      pressure_limit = ts->event_sent? ts->max_pressure: ts->touch_pressure;
 +
 +      /* z1 is always at least 100: */
 +      Rt = x * (z2 - z1) / z1;
 +      Rt = Rt * ts->x_plate_ohm / 4096;
 +      if (Rt > pressure_limit)
 +              return 0;
 +
 +      /* discard the event if it still is within the previous rect - unless
 +       * if the pressure is harder, but then use previous x,y position */
 +      inside_rect = (
 +          x > (int)ts->x - TS_RECT_SIZE && x < (int)ts->x + TS_RECT_SIZE &&
 +          y > (int)ts->y - TS_RECT_SIZE && y < (int)ts->y + TS_RECT_SIZE);
 +
 +      if (!ts->event_sent || !inside_rect) {
 +              ts->x = x;
 +              ts->y = y;
 +              ts->p = Rt;
 +              return 1;
 +      } else if (Rt < ts->p) {
 +              ts->p = Rt;
 +              return 1;
 +      }
 +      return 0;
 +}
 +
 +/*
 + * This procedure is called by the SPI framework after the coordinates
 + * have been read from TSC2301
 + */
 +static void tsc2301_ts_rx(void *arg)
 +{
 +      struct tsc2301 *tsc = arg;
 +      struct tsc2301_ts *ts = tsc->ts;
 +      int send_event;
 +      int x, y, z1, z2;
 +
 +      x  = ts->coords->x;
 +      y  = ts->coords->y;
 +      z1 = ts->coords->z1;
 +      z2 = ts->coords->z2;
 +
 +      send_event = filter(ts, x, y, z1, z2);
 +      if (send_event) {
 +              update_pen_state(ts, ts->x, ts->y, ts->p);
 +              ts->event_sent = 1;
 +      }
 +
 +      mod_timer(&ts->penup_timer,
 +                jiffies + msecs_to_jiffies(TSC2301_TS_PENUP_TIME));
 +}
 +
 +/*
 + * Timer is called TSC2301_TS_PENUP_TIME after pen is up
 + */
 +static void tsc2301_ts_timer_handler(unsigned long data)
 +{
 +      struct tsc2301 *tsc = (struct tsc2301 *)data;
 +      struct tsc2301_ts *ts = tsc->ts;
 +
 +      if (ts->event_sent) {
 +              ts->event_sent = 0;
 +              update_pen_state(ts, 0, 0, 0);
 +      }
 +}
 +
 +/*
 + * This interrupt is called when pen is down and coordinates are
 + * available. That is indicated by a falling edge on DEV line.
 + */
 +static irqreturn_t tsc2301_ts_irq_handler(int irq, void *dev_id)
 +{
 +      struct tsc2301 *tsc = dev_id;
 +      struct tsc2301_ts *ts = tsc->ts;
 +      int r;
 +
 +      r = spi_async(tsc->spi, &ts->read_msg);
 +      if (r)
 +              dev_err(&tsc->spi->dev, "ts: spi_async() failed");
 +
 +      mod_timer(&ts->penup_timer,
 +                jiffies + msecs_to_jiffies(TSC2301_TS_PENUP_TIME));
 +
 +      return IRQ_HANDLED;
 +}
 +
 +static void tsc2301_ts_disable(struct tsc2301 *tsc)
 +{
 +      struct tsc2301_ts *ts = tsc->ts;
 +
 +      if (ts->disable_depth++ != 0)
 +              return;
 +
 +      disable_irq(ts->irq);
 +
 +      /* wait until penup timer expire normally */
 +      do {
 +              msleep(1);
 +      } while (ts->event_sent);
 +
 +      tsc2301_ts_stop_scan(tsc);
 +}
 +
 +static void tsc2301_ts_enable(struct tsc2301 *tsc)
 +{
 +      struct tsc2301_ts *ts = tsc->ts;
 +
 +      if (--ts->disable_depth != 0)
 +              return;
 +
 +      enable_irq(ts->irq);
 +
 +      tsc2301_ts_start_scan(tsc);
 +}
 +
 +#ifdef CONFIG_PM
 +int tsc2301_ts_suspend(struct tsc2301 *tsc)
 +{
 +      struct tsc2301_ts *ts = tsc->ts;
 +
 +      mutex_lock(&ts->mutex);
 +      tsc2301_ts_disable(tsc);
 +      mutex_unlock(&ts->mutex);
 +
 +      return 0;
 +}
 +
 +void tsc2301_ts_resume(struct tsc2301 *tsc)
 +{
 +      struct tsc2301_ts *ts = tsc->ts;
 +
 +      mutex_lock(&ts->mutex);
 +      tsc2301_ts_enable(tsc);
 +      mutex_unlock(&ts->mutex);
 +}
 +#endif
 +
 +static void tsc2301_ts_setup_spi_xfer(struct tsc2301 *tsc)
 +{
 +      struct tsc2301_ts *ts = tsc->ts;
 +      struct spi_message *m = &ts->read_msg;
 +      struct spi_transfer *x = &ts->read_xfer[0];
 +
 +      spi_message_init(m);
 +
 +      x->tx_buf = &tsc2301_ts_read_data;
 +      x->len = 2;
 +      spi_message_add_tail(x, m);
 +
 +      x++;
 +      x->rx_buf = ts->coords;
 +      x->len = 8;
 +      spi_message_add_tail(x, m);
 +
 +      m->complete = tsc2301_ts_rx;
 +      m->context = tsc;
 +}
 +
 +static ssize_t tsc2301_ts_pen_down_show(struct device *dev,
 +                                      struct device_attribute *attr,
 +                                      char *buf)
 +{
 +      struct tsc2301 *tsc = dev_get_drvdata(dev);
 +
 +      return sprintf(buf, "%u\n", tsc->ts->pen_down);
 +}
 +
 +static DEVICE_ATTR(pen_down, S_IRUGO, tsc2301_ts_pen_down_show, NULL);
 +
 +static ssize_t tsc2301_ts_disable_show(struct device *dev,
 +                                     struct device_attribute *attr, char *buf)
 +{
 +      struct tsc2301          *tsc = dev_get_drvdata(dev);
 +      struct tsc2301_ts       *ts = tsc->ts;
 +
 +      return sprintf(buf, "%u\n", ts->disabled);
 +}
 +
 +static ssize_t tsc2301_ts_disable_store(struct device *dev,
 +                                      struct device_attribute *attr,
 +                                      const char *buf, size_t count)
 +{
 +      struct tsc2301          *tsc = dev_get_drvdata(dev);
 +      struct tsc2301_ts       *ts = tsc->ts;
 +      char *endp;
 +      int i;
 +
 +      i = simple_strtoul(buf, &endp, 10);
 +      i = i ? 1 : 0;
 +      mutex_lock(&ts->mutex);
 +      if (i == ts->disabled) goto out;
 +      ts->disabled = i;
 +
 +      if (i)
 +              tsc2301_ts_disable(tsc);
 +      else
 +              tsc2301_ts_enable(tsc);
 +out:
 +      mutex_unlock(&ts->mutex);
 +      return count;
 +}
 +
 +static DEVICE_ATTR(disable_ts, 0664, tsc2301_ts_disable_show,
 +                 tsc2301_ts_disable_store);
 +
 +int __devinit tsc2301_ts_init(struct tsc2301 *tsc,
 +                            struct tsc2301_platform_data *pdata)
 +{
 +      struct tsc2301_ts *ts;
 +      struct input_dev *idev;
 +      int r;
 +      int x_max, y_max;
 +      int x_fudge, y_fudge, p_fudge;
 +
 +      if (pdata->dav_int <= 0) {
 +              dev_err(&tsc->spi->dev, "need DAV IRQ");
 +              return -EINVAL;
 +      }
 +
 +      ts = kzalloc(sizeof(*ts), GFP_KERNEL);
 +      if (ts == NULL)
 +              return -ENOMEM;
 +      tsc->ts = ts;
 +
 +      ts->coords = kzalloc(sizeof(*ts->coords), GFP_KERNEL);
 +      if (ts->coords == NULL) {
 +              kfree(ts);
 +              return -ENOMEM;
 +      }
 +
 +      ts->irq = pdata->dav_int;
 +
 +      init_timer(&ts->penup_timer);
 +      setup_timer(&ts->penup_timer, tsc2301_ts_timer_handler,
 +                      (unsigned long)tsc);
 +
 +      mutex_init(&ts->mutex);
 +
 +      ts->x_plate_ohm = pdata->ts_x_plate_ohm ? : 280;
 +      ts->hw_avg_max  = pdata->ts_hw_avg;
 +      ts->max_pressure = pdata->ts_max_pressure ? : MAX_12BIT;
 +      ts->touch_pressure = pdata->ts_touch_pressure ? : ts->max_pressure;
 +      ts->stab_time   = pdata->ts_stab_time;
 +
 +      x_max           = pdata->ts_x_max ? : 4096;
 +      y_max           = pdata->ts_y_max ? : 4096;
 +      x_fudge         = pdata->ts_x_fudge ? : 4;
 +      y_fudge         = pdata->ts_y_fudge ? : 8;
 +      p_fudge         = pdata->ts_pressure_fudge ? : 2;
 +
 +      if ((r = tsc2301_ts_check_config(ts, &ts->hw_flags))) {
 +              dev_err(&tsc->spi->dev, "invalid configuration\n");
 +              goto err2;
 +      }
 +
 +      idev = input_allocate_device();
 +      if (idev == NULL) {
 +              r = -ENOMEM;
 +              goto err2;
 +      }
 +      idev->name = "TSC2301 touchscreen";
 +      snprintf(ts->phys, sizeof(ts->phys),
++               "%s/input-ts", dev_name(&tsc->spi->dev));
 +      idev->phys = ts->phys;
 +      idev->dev.parent = &tsc->spi->dev;
 +
 +      idev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
 +      idev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
 +      ts->idev = idev;
 +
 +      tsc2301_ts_setup_spi_xfer(tsc);
 +
 +      /* These parameters should perhaps be configurable? */
 +      input_set_abs_params(idev, ABS_X, 0, x_max, x_fudge, 0);
 +      input_set_abs_params(idev, ABS_Y, 0, y_max, y_fudge, 0);
 +      input_set_abs_params(idev, ABS_PRESSURE, 0, ts->max_pressure,
 +                           p_fudge, 0);
 +
 +      tsc2301_ts_start_scan(tsc);
 +
 +      r = request_irq(ts->irq, tsc2301_ts_irq_handler,
 +                      IRQF_SAMPLE_RANDOM | IRQF_TRIGGER_FALLING,
 +                      "tsc2301-ts", tsc);
 +      if (r < 0) {
 +              dev_err(&tsc->spi->dev, "unable to get DAV IRQ");
 +              goto err3;
 +      }
 +      set_irq_wake(ts->irq, 1);
 +
 +      if (device_create_file(&tsc->spi->dev, &dev_attr_pen_down) < 0)
 +              goto err4;
 +      if (device_create_file(&tsc->spi->dev, &dev_attr_disable_ts) < 0)
 +              goto err5;
 +
 +      r = input_register_device(idev);
 +      if (r < 0) {
 +              dev_err(&tsc->spi->dev, "can't register touchscreen device\n");
 +              goto err6;
 +      }
 +
 +      return 0;
 +err6:
 +      device_remove_file(&tsc->spi->dev, &dev_attr_disable_ts);
 +err5:
 +      device_remove_file(&tsc->spi->dev, &dev_attr_pen_down);
 +err4:
 +      free_irq(ts->irq, tsc);
 +err3:
 +      tsc2301_ts_stop_scan(tsc);
 +      input_free_device(idev);
 +err2:
 +      kfree(ts->coords);
 +      kfree(ts);
 +      return r;
 +}
 +
 +void __devexit tsc2301_ts_exit(struct tsc2301 *tsc)
 +{
 +      struct tsc2301_ts *ts = tsc->ts;
 +
 +      tsc2301_ts_disable(tsc);
 +
 +      device_remove_file(&tsc->spi->dev, &dev_attr_disable_ts);
 +      device_remove_file(&tsc->spi->dev, &dev_attr_pen_down);
 +
 +      free_irq(ts->irq, tsc);
 +      input_unregister_device(ts->idev);
 +
 +      kfree(ts->coords);
 +      kfree(ts);
 +}
 +MODULE_AUTHOR("Jarkko Oikarinen <jarkko.oikarinen@nokia.com>");
 +MODULE_LICENSE("GPL");
diff --combined drivers/leds/Kconfig
index 8d0f37e8a5c62e86249ae7d3418d822c19ee405c,556aeca0d860c835c9467bbfa9578bd61d0292dc..5c34aef3e9a2f029ce13fb1c6699c2489c023b36
@@@ -63,26 -63,11 +63,26 @@@ config LEDS_WRA
        help
          This option enables support for the PCEngines WRAP programmable LEDs.
  
 -config LEDS_ALIX2
 -      tristate "LED Support for ALIX.2 and ALIX.3 series"
 -      depends on LEDS_CLASS && X86 && EXPERIMENTAL
 +config LEDS_OMAP_DEBUG
 +      boolean "LED Support for OMAP debug board LEDs"
 +      depends on LEDS_CLASS=y && ARCH_OMAP
        help
 -        This option enables support for the PCEngines ALIX.2 and ALIX.3 LEDs.
 +        Enables support for the LEDs on the debug board used with OMAP
 +        reference boards like H2/H3/H4 and Perseus2.  Up to six of these
 +        may be claimed by the original ARM debug LED API.
 +
 +config LEDS_OMAP
 +      tristate "LED Support for OMAP GPIO LEDs"
 +      depends on LEDS_CLASS && ARCH_OMAP
 +      help
 +        This option enables support for the LEDs on OMAP processors.
 +
 +config LEDS_OMAP_PWM
 +      tristate "LED Support for OMAP PWM-controlled LEDs"
 +      depends on LEDS_CLASS && ARCH_OMAP && OMAP_DM_TIMER
 +      help
 +        This options enables support for LEDs connected to GPIO lines
 +        controlled by a PWM timer on OMAP CPUs.
  
  config LEDS_H1940
        tristate "LED Support for iPAQ H1940 device"
@@@ -98,7 -83,7 +98,7 @@@ config LEDS_COBALT_QUB
  
  config LEDS_COBALT_RAQ
        bool "LED Support for the Cobalt Raq series"
 -      depends on LEDS_CLASS=y && MIPS_COBALT
 +      depends on LEDS_CLASS && MIPS_COBALT
        select LEDS_TRIGGERS
        help
          This option enables support for the Cobalt Raq series LEDs.
@@@ -134,16 -119,6 +134,16 @@@ config LEDS_GPI
          outputs. To be useful the particular board must have LEDs
          and they must be connected to the GPIO lines.
  
 +config LEDS_LP5521
 +      tristate "LED Support for the LP5521 LEDs"
 +      depends on LEDS_CLASS && I2C
 +      help
 +        If you say 'Y' here you get support for the National Semiconductor
 +        LP5521 LED driver used in n8x0 boards.
 +
 +        This driver can be built as a module by choosing 'M'. The module
 +        will be called leds-lp5521.
 +
  config LEDS_CLEVO_MAIL
        tristate "Mail LED on Clevo notebook (EXPERIMENTAL)"
        depends on LEDS_CLASS && X86 && SERIO_I8042 && DMI && EXPERIMENTAL
@@@ -182,6 -157,13 +182,6 @@@ config LEDS_PCA955
          LED driver chips accessed via the I2C bus.  Supported
          devices include PCA9550, PCA9551, PCA9552, and PCA9553.
  
 -config LEDS_WM8350
 -      tristate "LED Support for WM8350 AudioPlus PMIC"
 -      depends on LEDS_CLASS && MFD_WM8350
 -      help
 -        This option enables support for LEDs driven by the Wolfson
 -        Microelectronics WM8350 AudioPlus PMIC.
 -
  config LEDS_DA903X
        tristate "LED Support for DA9030/DA9034 PMIC"
        depends on LEDS_CLASS && PMIC_DA903X
@@@ -241,4 -223,7 +241,7 @@@ config LEDS_TRIGGER_DEFAULT_O
          This allows LEDs to be initialised in the ON state.
          If unsure, say Y.
  
+ comment "iptables trigger is under Netfilter config (LED target)"
+       depends on LEDS_TRIGGERS
  endif # NEW_LEDS
diff --combined drivers/misc/Kconfig
index 3c74d733ee39414bc1f3eff8b35d52754f134173,5f3bff43462188a3e70513355854a8478af57d22..4a022dad4b4f0ece88a2a44a5bb91859f080a7ea
@@@ -150,20 -150,6 +150,20 @@@ config ATMEL_SS
  
          If unsure, say N.
  
 +config OMAP_STI
 +      bool "Serial Trace Interface support"
 +      depends on ARCH_OMAP16XX || ARCH_OMAP24XX || ARCH_OMAP34XX
 +      default n
 +      help
 +        Serial Trace Interface. The protocols suported for OMAP1/2/3 are
 +        STI/CSTI/XTIv2 correspondingly.
 +
 +config OMAP_STI_CONSOLE
 +      bool "STI console support"
 +      depends on OMAP_STI
 +      help
 +        This enables a console driver by way of STI/XTI.
 +
  config ENCLOSURE_SERVICES
        tristate "Enclosure Services"
        default n
  config SGI_XP
        tristate "Support communication between SGI SSIs"
        depends on NET
-       depends on (IA64_GENERIC || IA64_SGI_SN2 || IA64_SGI_UV || X86_64) && SMP
+       depends on (IA64_GENERIC || IA64_SGI_SN2 || IA64_SGI_UV || X86_UV) && SMP
        select IA64_UNCACHED_ALLOCATOR if IA64_GENERIC || IA64_SGI_SN2
        select GENERIC_ALLOCATOR if IA64_GENERIC || IA64_SGI_SN2
        select SGI_GRU if (IA64_GENERIC || IA64_SGI_UV || X86_64) && SMP
@@@ -203,7 -189,7 +203,7 @@@ config HP_IL
  
  config SGI_GRU
        tristate "SGI GRU driver"
-       depends on (X86_64 || IA64_SGI_UV || IA64_GENERIC) && SMP
+       depends on (X86_UV || IA64_SGI_UV || IA64_GENERIC) && SMP
        default n
        select MMU_NOTIFIER
        ---help---
@@@ -237,6 -223,16 +237,16 @@@ config DELL_LAPTO
        This driver adds support for rfkill and backlight control to Dell
        laptops.
  
+ config ISL29003
+       tristate "Intersil ISL29003 ambient light sensor"
+       depends on I2C && SYSFS
+       help
+         If you say yes here you get support for the Intersil ISL29003
+         ambient light sensor.
+         This driver can also be built as a module.  If so, the module
+         will be called isl29003.
  source "drivers/misc/c2port/Kconfig"
  source "drivers/misc/eeprom/Kconfig"
  
diff --combined drivers/misc/Makefile
index b162e23af35c1339ee1608bff98feede664737db,7871f05dcb9b8d29804dbe7e68743c01369937da..8143c4d157a522c4357cba37fe3a26b84d69a75e
@@@ -13,11 -13,11 +13,12 @@@ obj-$(CONFIG_TIFM_CORE)            += tifm_
  obj-$(CONFIG_TIFM_7XX1)               += tifm_7xx1.o
  obj-$(CONFIG_PHANTOM)         += phantom.o
  obj-$(CONFIG_SGI_IOC4)                += ioc4.o
 +obj-$(CONFIG_OMAP_STI)                += sti/
  obj-$(CONFIG_ENCLOSURE_SERVICES) += enclosure.o
  obj-$(CONFIG_KGDB_TESTS)      += kgdbts.o
  obj-$(CONFIG_SGI_XP)          += sgi-xp/
  obj-$(CONFIG_SGI_GRU)         += sgi-gru/
  obj-$(CONFIG_HP_ILO)          += hpilo.o
+ obj-$(CONFIG_ISL29003)                += isl29003.o
  obj-$(CONFIG_C2PORT)          += c2port/
  obj-y                         += eeprom/
diff --combined drivers/mmc/host/omap.c
index d8b32a6aa9345837434ed08f67d993eb21f765ed,5570849188cc806032cab4791ab3ce10706a51f2..bfa25c01c8722f17684520b1ab3adfee9bdef193
@@@ -157,6 -157,8 +157,6 @@@ struct mmc_omap_host 
        struct timer_list       dma_timer;
        unsigned                dma_len;
  
 -      short                   power_pin;
 -
        struct mmc_omap_slot    *slots[OMAP_MMC_MAX_SLOTS];
        struct mmc_omap_slot    *current_slot;
        spinlock_t              slot_lock;
@@@ -1458,18 -1460,12 +1458,12 @@@ static int __init mmc_omap_probe(struc
        if (!host->virt_base)
                goto err_ioremap;
  
-       if (cpu_is_omap24xx()) {
-               host->iclk = clk_get(&pdev->dev, "mmc_ick");
-               if (IS_ERR(host->iclk))
-                       goto err_free_mmc_host;
-               clk_enable(host->iclk);
-       }
-       if (!cpu_is_omap24xx())
-               host->fclk = clk_get(&pdev->dev, "mmc_ck");
-       else
-               host->fclk = clk_get(&pdev->dev, "mmc_fck");
+       host->iclk = clk_get(&pdev->dev, "ick");
+       if (IS_ERR(host->iclk))
+               goto err_free_mmc_host;
+       clk_enable(host->iclk);
  
+       host->fclk = clk_get(&pdev->dev, "fck");
        if (IS_ERR(host->fclk)) {
                ret = PTR_ERR(host->fclk);
                goto err_free_iclk;
@@@ -1534,10 -1530,10 +1528,10 @@@ static int mmc_omap_remove(struct platf
        if (host->pdata->cleanup)
                host->pdata->cleanup(&pdev->dev);
  
-       if (host->iclk && !IS_ERR(host->iclk))
-               clk_put(host->iclk);
-       if (host->fclk && !IS_ERR(host->fclk))
-               clk_put(host->fclk);
+       mmc_omap_fclk_enable(host, 0);
+       clk_put(host->fclk);
+       clk_disable(host->iclk);
+       clk_put(host->iclk);
  
        iounmap(host->virt_base);
        release_mem_region(pdev->resource[0].start,
index 8c570bff7d1705e63be602dd983c41e99c7a4ff6,3916a5618e288e4cd5680a1127ce025efcc8b387..9b82096b433cefd40131e0d65cf62cbbe4b69f02
@@@ -956,13 -956,13 +956,13 @@@ static int __init omap_mmc_probe(struc
  
        sema_init(&host->sem, 1);
  
-       host->iclk = clk_get(&pdev->dev, "mmchs_ick");
+       host->iclk = clk_get(&pdev->dev, "ick");
        if (IS_ERR(host->iclk)) {
                ret = PTR_ERR(host->iclk);
                host->iclk = NULL;
                goto err1;
        }
-       host->fclk = clk_get(&pdev->dev, "mmchs_fck");
+       host->fclk = clk_get(&pdev->dev, "fck");
        if (IS_ERR(host->fclk)) {
                ret = PTR_ERR(host->fclk);
                host->fclk = NULL;
        mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
        mmc->max_seg_size = mmc->max_req_size;
  
 -      mmc->ocr_avail = mmc_slot(host).ocr_mask;
        mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED;
  
        if (pdata->slots[host->slot_id].wires >= 4)
                goto err_irq;
        }
  
 +      /* initialize power supplies, gpios, etc */
        if (pdata->init != NULL) {
                if (pdata->init(&pdev->dev) != 0) {
 -                      dev_dbg(mmc_dev(host->mmc),
 -                              "Unable to configure MMC IRQs\n");
 +                      dev_dbg(mmc_dev(host->mmc), "late init error\n");
                        goto err_irq_cd_init;
                }
        }
 +      mmc->ocr_avail = mmc_slot(host).ocr_mask;
  
        /* Request IRQ for card detect */
        if ((mmc_slot(host).card_detect_irq) && (mmc_slot(host).card_detect)) {
diff --combined drivers/mtd/maps/Kconfig
index f96e408a0b08f9fa3ad338112eaf0ed258174b24,729f899a5cd5d71725ab137715d2c5b1c8a45789..d071eabdabaf8ccfd2b2bd112b0d6e7a5e698036
@@@ -445,13 -445,6 +445,13 @@@ config MTD_CEIV
          PhotoMax Digital Picture Frame.
          If you have such a device, say 'Y'.
  
 +config MTD_NOR_TOTO
 +      tristate "NOR Flash device on TOTO board"
 +      depends on ARCH_OMAP && OMAP_TOTO
 +      help
 +        This enables access to the NOR flash on the Texas Instruments
 +        TOTO board.
 +
  config MTD_H720X
        tristate "Hynix evaluation board mappings"
        depends on MTD_CFI && ( ARCH_H7201 || ARCH_H7202 )
@@@ -558,5 -551,15 +558,15 @@@ config MTD_PLATRA
  
          This selection automatically selects the map_ram driver.
  
- endmenu
+ config MTD_VMU
+       tristate "Map driver for Dreamcast VMU"
+       depends on MAPLE
+       help
+         This driver enables access to the Dreamcast Visual Memory Unit (VMU).
+         Most Dreamcast users will want to say Y here.
  
+         To build this as a module select M here, the module will be called
+         vmu-flash.
+ endmenu
index b2582506cde97627a680776dd2c9d0bcf56b6075,26b28a7a90b5e19a57baf21502d2dd94fdc349a7..d70822def7924d63238ca01f6a58fc9fbd06f651
@@@ -52,7 -52,6 +52,7 @@@ obj-$(CONFIG_MTD_NETtel)      += nettel.
  obj-$(CONFIG_MTD_SCB2_FLASH)  += scb2_flash.o
  obj-$(CONFIG_MTD_H720X)               += h720x-flash.o
  obj-$(CONFIG_MTD_SBC8240)     += sbc8240.o
 +obj-$(CONFIG_MTD_NOR_TOTO)    += omap-toto-flash.o
  obj-$(CONFIG_MTD_IXP4XX)      += ixp4xx.o
  obj-$(CONFIG_MTD_IXP2000)     += ixp2000.o
  obj-$(CONFIG_MTD_WRSBC8260)   += wr_sbc82xx_flash.o
@@@ -62,3 -61,4 +62,4 @@@ obj-$(CONFIG_MTD_PLATRAM)     += plat-ram.
  obj-$(CONFIG_MTD_OMAP_NOR)    += omap_nor.o
  obj-$(CONFIG_MTD_INTEL_VR_NOR)        += intel_vr_nor.o
  obj-$(CONFIG_MTD_BFIN_ASYNC)  += bfin-async-flash.o
+ obj-$(CONFIG_MTD_VMU)         += vmu-flash.o
diff --combined drivers/mtd/nand/Kconfig
index 08e168f84bd17c40ead70576fc2cbfd9e6d4c4be,2ff88791cebc359aae7b830a18cf5b9679ec15b4..53635b95e5aa9082b8cd32f31c1dbdc1c616daa4
@@@ -74,31 -74,6 +74,31 @@@ config MTD_NAND_AMS_DELT
        help
          Support for NAND flash on Amstrad E3 (Delta).
  
 +config MTD_NAND_OMAP2
 +      tristate "NAND Flash device on OMAP2 and OMAP3"
 +      depends on ARM && MTD_NAND && (ARCH_OMAP2 || ARCH_OMAP3)
 +      help
 +          Support for NAND flash on Texas Instruments OMAP2 and OMAP3 platforms.
 +
 +config MTD_NAND_OMAP
 +      tristate "NAND Flash device on OMAP H3/H2/P2 boards"
 +      depends on ARM && ARCH_OMAP1 && MTD_NAND && (MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_PERSEUS2)
 +      help
 +        Support for NAND flash on Texas Instruments H3/H2/P2 platforms.
 +
 +config MTD_NAND_OMAP_HW
 +      bool "OMAP HW NAND Flash controller support"
 +        depends on ARM && ARCH_OMAP16XX && MTD_NAND
 +
 +      help
 +        Driver for TI OMAP16xx hardware NAND flash controller.
 +
 +config MTD_NAND_TOTO
 +      tristate "NAND Flash device on TOTO board"
 +      depends on ARCH_OMAP && BROKEN
 +      help
 +        Support for NAND flash on Texas Instruments Toto platform.
 +
  config MTD_NAND_TS7250
        tristate "NAND Flash device on TS-7250 board"
        depends on MACH_TS72XX
@@@ -298,7 -273,7 +298,7 @@@ config MTD_NAND_CAF
  
  config MTD_NAND_CS553X
        tristate "NAND support for CS5535/CS5536 (AMD Geode companion chip)"
-       depends on X86_32 && (X86_PC || X86_GENERICARCH)
+       depends on X86_32
        help
          The CS553x companion chips for the AMD Geode processor
          include NAND flash controllers with built-in hardware ECC
index 6b8fb44573d4ae748e56457e01785730a6c153f2,0000000000000000000000000000000000000000..5263b19c81728ca13f00e63d9e3f29cd3d0fc5d1
mode 100644,000000..100644
--- /dev/null
@@@ -1,184 -1,0 +1,184 @@@
-       info->mtd.name = pdev->dev.bus_id;
 +/*
 + * drivers/mtd/nand/omap-nand-flash.c
 + *
 + * Copyright (c) 2004 Texas Instruments, Jian Zhang <jzhang@ti.com>
 + * Copyright (c) 2004 David Brownell
 + *
 + * 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/init.h>
 +#include <linux/ioport.h>
 +#include <linux/delay.h>
 +#include <linux/kernel.h>
 +#include <linux/module.h>
 +#include <linux/platform_device.h>
 +#include <linux/types.h>
 +#include <linux/mtd/mtd.h>
 +#include <linux/mtd/nand.h>
 +#include <linux/mtd/partitions.h>
 +
 +#include <asm/io.h>
 +#include <mach/hardware.h>
 +#include <asm/mach-types.h>
 +#include <asm/mach/flash.h>
 +#include <mach/tc.h>
 +
 +#include <mach/nand.h>
 +
 +#define       DRIVER_NAME     "omapnand"
 +
 +#ifdef CONFIG_MTD_PARTITIONS
 +static const char *part_probes[] = { "cmdlinepart", NULL };
 +#endif
 +
 +struct omap_nand_info {
 +      struct omap_nand_platform_data *pdata;
 +      struct mtd_partition    *parts;
 +      struct mtd_info         mtd;
 +      struct nand_chip        nand;
 +};
 +
 +/*
 + *    hardware specific access to control-lines
 + *    NOTE:  boards may use different bits for these!!
 + *
 + *    ctrl:
 + *    NAND_NCE: bit 0 - don't care
 + *    NAND_CLE: bit 1 -> bit 1  (0x0002)
 + *    NAND_ALE: bit 2 -> bit 2  (0x0004)
 + */
 +
 +static void omap_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
 +{
 +      struct nand_chip *chip = mtd->priv;
 +      unsigned long mask;
 +
 +      if (cmd == NAND_CMD_NONE)
 +              return;
 +
 +      mask = (ctrl & NAND_CLE) ? 0x02 : 0;
 +      if (ctrl & NAND_ALE)
 +              mask |= 0x04;
 +      writeb(cmd, (unsigned long)chip->IO_ADDR_W | mask);
 +}
 +
 +static int omap_nand_dev_ready(struct mtd_info *mtd)
 +{
 +      struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, mtd);
 +
 +      return info->pdata->dev_ready(info->pdata);
 +}
 +
 +static int __devinit omap_nand_probe(struct platform_device *pdev)
 +{
 +      struct omap_nand_info           *info;
 +      struct omap_nand_platform_data  *pdata = pdev->dev.platform_data;
 +      struct resource                 *res = pdev->resource;
 +      unsigned long                   size = res->end - res->start + 1;
 +      int                             err;
 +
 +      info = kzalloc(sizeof(struct omap_nand_info), GFP_KERNEL);
 +      if (!info)
 +              return -ENOMEM;
 +
 +      if (!request_mem_region(res->start, size, pdev->dev.driver->name)) {
 +              err = -EBUSY;
 +              goto out_free_info;
 +      }
 +
 +      info->nand.IO_ADDR_R = ioremap(res->start, size);
 +      if (!info->nand.IO_ADDR_R) {
 +              err = -ENOMEM;
 +              goto out_release_mem_region;
 +      }
 +      info->nand.IO_ADDR_W = info->nand.IO_ADDR_R;
 +      info->nand.cmd_ctrl = omap_nand_hwcontrol;
 +      info->nand.ecc.mode = NAND_ECC_SOFT;
 +      info->nand.options = pdata->options;
 +      if (pdata->dev_ready)
 +              info->nand.dev_ready = omap_nand_dev_ready;
 +      else
 +              info->nand.chip_delay = 20;
 +
++      info->mtd.name = dev_name(&pdev->dev);
 +      info->mtd.priv = &info->nand;
 +
 +      info->pdata = pdata;
 +
 +      /* DIP switches on H2 and some other boards change between 8 and 16 bit
 +       * bus widths for flash.  Try the other width if the first try fails.
 +       */
 +      if (nand_scan(&info->mtd, 1)) {
 +              info->nand.options ^= NAND_BUSWIDTH_16;
 +              if (nand_scan(&info->mtd, 1)) {
 +                      err = -ENXIO;
 +                      goto out_iounmap;
 +              }
 +      }
 +      info->mtd.owner = THIS_MODULE;
 +
 +#ifdef CONFIG_MTD_PARTITIONS
 +      err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0);
 +      if (err > 0)
 +              add_mtd_partitions(&info->mtd, info->parts, err);
 +      else if (err < 0 && pdata->parts)
 +              add_mtd_partitions(&info->mtd, pdata->parts, pdata->nr_parts);
 +      else
 +#endif
 +              add_mtd_device(&info->mtd);
 +
 +      platform_set_drvdata(pdev, info);
 +
 +      return 0;
 +
 +out_iounmap:
 +      iounmap(info->nand.IO_ADDR_R);
 +out_release_mem_region:
 +      release_mem_region(res->start, size);
 +out_free_info:
 +      kfree(info);
 +
 +      return err;
 +}
 +
 +static int omap_nand_remove(struct platform_device *pdev)
 +{
 +      struct omap_nand_info *info = platform_get_drvdata(pdev);
 +
 +      platform_set_drvdata(pdev, NULL);
 +      /* Release NAND device, its internal structures and partitions */
 +      nand_release(&info->mtd);
 +      iounmap(info->nand.IO_ADDR_R);
 +      kfree(info);
 +      return 0;
 +}
 +
 +static struct platform_driver omap_nand_driver = {
 +      .probe          = omap_nand_probe,
 +      .remove         = omap_nand_remove,
 +      .driver         = {
 +              .name   = DRIVER_NAME,
 +      },
 +};
 +MODULE_ALIAS(DRIVER_NAME);
 +
 +static int __init omap_nand_init(void)
 +{
 +      return platform_driver_register(&omap_nand_driver);
 +}
 +
 +static void __exit omap_nand_exit(void)
 +{
 +      platform_driver_unregister(&omap_nand_driver);
 +}
 +
 +module_init(omap_nand_init);
 +module_exit(omap_nand_exit);
 +
 +MODULE_LICENSE("GPL");
 +MODULE_AUTHOR("Jian Zhang <jzhang@ti.com> (and others)");
 +MODULE_DESCRIPTION("Glue layer for NAND flash on TI OMAP boards");
 +
diff --combined drivers/mtd/nand/omap2.c
index 55ba7462cbc9a0563734fade6f9cc669493f0501,0000000000000000000000000000000000000000..516da8f755ae2e6d972aac95582fc5532cea5f08
mode 100644,000000..100644
--- /dev/null
@@@ -1,755 -1,0 +1,755 @@@
-       info->mtd.name          = pdev->dev.bus_id;
 +/*
 + * drivers/mtd/nand/omap2.c
 + *
 + * Copyright (c) 2004 Texas Instruments, Jian Zhang <jzhang@ti.com>
 + * Copyright (c) 2004 Micron Technology Inc.
 + * Copyright (c) 2004 David Brownell
 + *
 + * 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/platform_device.h>
 +#include <linux/dma-mapping.h>
 +#include <linux/delay.h>
 +#include <linux/mtd/mtd.h>
 +#include <linux/mtd/nand.h>
 +#include <linux/mtd/partitions.h>
 +#include <linux/io.h>
 +
 +#include <asm/dma.h>
 +
 +#include <mach/gpmc.h>
 +#include <mach/nand.h>
 +
 +#define GPMC_IRQ_STATUS               0x18
 +#define GPMC_ECC_CONFIG               0x1F4
 +#define GPMC_ECC_CONTROL      0x1F8
 +#define GPMC_ECC_SIZE_CONFIG  0x1FC
 +#define GPMC_ECC1_RESULT      0x200
 +
 +#define       DRIVER_NAME     "omap2-nand"
 +#define       NAND_IO_SIZE    SZ_4K
 +
 +#define       NAND_WP_ON      1
 +#define       NAND_WP_OFF     0
 +#define NAND_WP_BIT   0x00000010
 +#define WR_RD_PIN_MONITORING  0x00600000
 +
 +#define       GPMC_BUF_FULL   0x00000001
 +#define       GPMC_BUF_EMPTY  0x00000000
 +
 +#define NAND_Ecc_P1e          (1 << 0)
 +#define NAND_Ecc_P2e          (1 << 1)
 +#define NAND_Ecc_P4e          (1 << 2)
 +#define NAND_Ecc_P8e          (1 << 3)
 +#define NAND_Ecc_P16e         (1 << 4)
 +#define NAND_Ecc_P32e         (1 << 5)
 +#define NAND_Ecc_P64e         (1 << 6)
 +#define NAND_Ecc_P128e                (1 << 7)
 +#define NAND_Ecc_P256e                (1 << 8)
 +#define NAND_Ecc_P512e                (1 << 9)
 +#define NAND_Ecc_P1024e               (1 << 10)
 +#define NAND_Ecc_P2048e               (1 << 11)
 +
 +#define NAND_Ecc_P1o          (1 << 16)
 +#define NAND_Ecc_P2o          (1 << 17)
 +#define NAND_Ecc_P4o          (1 << 18)
 +#define NAND_Ecc_P8o          (1 << 19)
 +#define NAND_Ecc_P16o         (1 << 20)
 +#define NAND_Ecc_P32o         (1 << 21)
 +#define NAND_Ecc_P64o         (1 << 22)
 +#define NAND_Ecc_P128o                (1 << 23)
 +#define NAND_Ecc_P256o                (1 << 24)
 +#define NAND_Ecc_P512o                (1 << 25)
 +#define NAND_Ecc_P1024o               (1 << 26)
 +#define NAND_Ecc_P2048o               (1 << 27)
 +
 +#define TF(value)     (value ? 1 : 0)
 +
 +#define P2048e(a)     (TF(a & NAND_Ecc_P2048e)        << 0)
 +#define P2048o(a)     (TF(a & NAND_Ecc_P2048o)        << 1)
 +#define P1e(a)                (TF(a & NAND_Ecc_P1e)           << 2)
 +#define P1o(a)                (TF(a & NAND_Ecc_P1o)           << 3)
 +#define P2e(a)                (TF(a & NAND_Ecc_P2e)           << 4)
 +#define P2o(a)                (TF(a & NAND_Ecc_P2o)           << 5)
 +#define P4e(a)                (TF(a & NAND_Ecc_P4e)           << 6)
 +#define P4o(a)                (TF(a & NAND_Ecc_P4o)           << 7)
 +
 +#define P8e(a)                (TF(a & NAND_Ecc_P8e)           << 0)
 +#define P8o(a)                (TF(a & NAND_Ecc_P8o)           << 1)
 +#define P16e(a)               (TF(a & NAND_Ecc_P16e)          << 2)
 +#define P16o(a)               (TF(a & NAND_Ecc_P16o)          << 3)
 +#define P32e(a)               (TF(a & NAND_Ecc_P32e)          << 4)
 +#define P32o(a)               (TF(a & NAND_Ecc_P32o)          << 5)
 +#define P64e(a)               (TF(a & NAND_Ecc_P64e)          << 6)
 +#define P64o(a)               (TF(a & NAND_Ecc_P64o)          << 7)
 +
 +#define P128e(a)      (TF(a & NAND_Ecc_P128e)         << 0)
 +#define P128o(a)      (TF(a & NAND_Ecc_P128o)         << 1)
 +#define P256e(a)      (TF(a & NAND_Ecc_P256e)         << 2)
 +#define P256o(a)      (TF(a & NAND_Ecc_P256o)         << 3)
 +#define P512e(a)      (TF(a & NAND_Ecc_P512e)         << 4)
 +#define P512o(a)      (TF(a & NAND_Ecc_P512o)         << 5)
 +#define P1024e(a)     (TF(a & NAND_Ecc_P1024e)        << 6)
 +#define P1024o(a)     (TF(a & NAND_Ecc_P1024o)        << 7)
 +
 +#define P8e_s(a)      (TF(a & NAND_Ecc_P8e)           << 0)
 +#define P8o_s(a)      (TF(a & NAND_Ecc_P8o)           << 1)
 +#define P16e_s(a)     (TF(a & NAND_Ecc_P16e)          << 2)
 +#define P16o_s(a)     (TF(a & NAND_Ecc_P16o)          << 3)
 +#define P1e_s(a)      (TF(a & NAND_Ecc_P1e)           << 4)
 +#define P1o_s(a)      (TF(a & NAND_Ecc_P1o)           << 5)
 +#define P2e_s(a)      (TF(a & NAND_Ecc_P2e)           << 6)
 +#define P2o_s(a)      (TF(a & NAND_Ecc_P2o)           << 7)
 +
 +#define P4e_s(a)      (TF(a & NAND_Ecc_P4e)           << 0)
 +#define P4o_s(a)      (TF(a & NAND_Ecc_P4o)           << 1)
 +
 +#ifdef CONFIG_MTD_PARTITIONS
 +static const char *part_probes[] = { "cmdlinepart", NULL };
 +#endif
 +
 +struct omap_nand_info {
 +      struct nand_hw_control          controller;
 +      struct omap_nand_platform_data  *pdata;
 +      struct mtd_info                 mtd;
 +      struct mtd_partition            *parts;
 +      struct nand_chip                nand;
 +      struct platform_device          *pdev;
 +
 +      int                             gpmc_cs;
 +      unsigned long                   phys_base;
 +      void __iomem                    *gpmc_cs_baseaddr;
 +      void __iomem                    *gpmc_baseaddr;
 +};
 +
 +/*
 + * omap_nand_wp - This function enable or disable the Write Protect feature on
 + * NAND device
 + * @mtd: MTD device structure
 + * @mode: WP ON/OFF
 + */
 +static void omap_nand_wp(struct mtd_info *mtd, int mode)
 +{
 +      struct omap_nand_info *info = container_of(mtd,
 +                                              struct omap_nand_info, mtd);
 +
 +      unsigned long config = __raw_readl(info->gpmc_baseaddr + GPMC_CONFIG);
 +
 +      if (mode)
 +              config &= ~(NAND_WP_BIT);       /* WP is ON */
 +      else
 +              config |= (NAND_WP_BIT);        /* WP is OFF */
 +
 +      __raw_writel(config, (info->gpmc_baseaddr + GPMC_CONFIG));
 +}
 +
 +/*
 + * hardware specific access to control-lines
 + * NOTE: boards may use different bits for these!!
 + *
 + * ctrl:
 + * NAND_NCE: bit 0 - don't care
 + * NAND_CLE: bit 1 -> Command Latch
 + * NAND_ALE: bit 2 -> Address Latch
 + */
 +static void omap_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
 +{
 +      struct omap_nand_info *info = container_of(mtd,
 +                                      struct omap_nand_info, mtd);
 +      switch (ctrl) {
 +      case NAND_CTRL_CHANGE | NAND_CTRL_CLE:
 +              info->nand.IO_ADDR_W = info->gpmc_cs_baseaddr +
 +                                              GPMC_CS_NAND_COMMAND;
 +              info->nand.IO_ADDR_R = info->gpmc_cs_baseaddr +
 +                                              GPMC_CS_NAND_DATA;
 +              break;
 +
 +      case NAND_CTRL_CHANGE | NAND_CTRL_ALE:
 +              info->nand.IO_ADDR_W = info->gpmc_cs_baseaddr +
 +                                              GPMC_CS_NAND_ADDRESS;
 +              info->nand.IO_ADDR_R = info->gpmc_cs_baseaddr +
 +                                              GPMC_CS_NAND_DATA;
 +              break;
 +
 +      case NAND_CTRL_CHANGE | NAND_NCE:
 +              info->nand.IO_ADDR_W = info->gpmc_cs_baseaddr +
 +                                              GPMC_CS_NAND_DATA;
 +              info->nand.IO_ADDR_R = info->gpmc_cs_baseaddr +
 +                                              GPMC_CS_NAND_DATA;
 +              break;
 +      }
 +
 +      if (cmd != NAND_CMD_NONE)
 +              __raw_writeb(cmd, info->nand.IO_ADDR_W);
 +}
 +
 +/*
 + * omap_read_buf16 - read data from NAND controller into buffer
 + * @mtd: MTD device structure
 + * @buf: buffer to store date
 + * @len: number of bytes to read
 + */
 +static void omap_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
 +{
 +      struct nand_chip *nand = mtd->priv;
 +
 +      __raw_readsw(nand->IO_ADDR_R, buf, len / 2);
 +}
 +
 +/*
 + * omap_write_buf16 - write buffer to NAND controller
 + * @mtd: MTD device structure
 + * @buf: data buffer
 + * @len: number of bytes to write
 + */
 +static void omap_write_buf16(struct mtd_info *mtd, const u_char * buf, int len)
 +{
 +      struct omap_nand_info *info = container_of(mtd,
 +                                              struct omap_nand_info, mtd);
 +      u16 *p = (u16 *) buf;
 +
 +      /* FIXME try bursts of writesw() or DMA ... */
 +      len >>= 1;
 +
 +      while (len--) {
 +              writew(*p++, info->nand.IO_ADDR_W);
 +
 +              while (GPMC_BUF_EMPTY == (readl(info->gpmc_baseaddr +
 +                                              GPMC_STATUS) & GPMC_BUF_FULL));
 +      }
 +}
 +/*
 + * omap_verify_buf - Verify chip data against buffer
 + * @mtd: MTD device structure
 + * @buf: buffer containing the data to compare
 + * @len: number of bytes to compare
 + */
 +static int omap_verify_buf(struct mtd_info *mtd, const u_char * buf, int len)
 +{
 +      struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 +                                                      mtd);
 +      u16 *p = (u16 *) buf;
 +
 +      len >>= 1;
 +
 +      while (len--) {
 +
 +              if (*p++ != cpu_to_le16(readw(info->nand.IO_ADDR_R)))
 +                      return -EFAULT;
 +      }
 +
 +      return 0;
 +}
 +
 +#ifdef CONFIG_MTD_NAND_OMAP_HWECC
 +/*
 + * omap_hwecc_init-Initialize the Hardware ECC for NAND flash in GPMC controller
 + * @mtd: MTD device structure
 + */
 +static void omap_hwecc_init(struct mtd_info *mtd)
 +{
 +      struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 +                                                      mtd);
 +      register struct nand_chip *chip = mtd->priv;
 +      unsigned long val = 0x0;
 +
 +      /* Read from ECC Control Register */
 +      val = __raw_readl(info->gpmc_baseaddr + GPMC_ECC_CONTROL);
 +      /* Clear all ECC | Enable Reg1 */
 +      val = ((0x00000001<<8) | 0x00000001);
 +      __raw_writel(val, info->gpmc_baseaddr + GPMC_ECC_CONTROL);
 +
 +      /* Read from ECC Size Config Register */
 +      val = __raw_readl(info->gpmc_baseaddr + GPMC_ECC_SIZE_CONFIG);
 +      /* ECCSIZE1=512 | Select eccResultsize[0-3] */
 +      val = ((((chip->ecc.size >> 1) - 1) << 22) | (0x0000000F));
 +      __raw_writel(val, info->gpmc_baseaddr + GPMC_ECC_SIZE_CONFIG);
 +}
 +
 +/*
 + * gen_true_ecc - This function will generate true ECC value, which can be used
 + * when correcting data read from NAND flash memory core
 + * @ecc_buf: buffer to store ecc code
 + */
 +static void gen_true_ecc(u8 *ecc_buf)
 +{
 +      u32 tmp = ecc_buf[0] | (ecc_buf[1] << 16) |
 +              ((ecc_buf[2] & 0xF0) << 20) | ((ecc_buf[2] & 0x0F) << 8);
 +
 +      ecc_buf[0] = ~(P64o(tmp) | P64e(tmp) | P32o(tmp) | P32e(tmp) |
 +                      P16o(tmp) | P16e(tmp) | P8o(tmp) | P8e(tmp));
 +      ecc_buf[1] = ~(P1024o(tmp) | P1024e(tmp) | P512o(tmp) | P512e(tmp) |
 +                      P256o(tmp) | P256e(tmp) | P128o(tmp) | P128e(tmp));
 +      ecc_buf[2] = ~(P4o(tmp) | P4e(tmp) | P2o(tmp) | P2e(tmp) | P1o(tmp) |
 +                      P1e(tmp) | P2048o(tmp) | P2048e(tmp));
 +}
 +
 +/*
 + * omap_compare_ecc - This function compares two ECC's and indicates if there
 + * is an error. If the error can be corrected it will be corrected to the
 + * buffer
 + * @ecc_data1:  ecc code from nand spare area
 + * @ecc_data2:  ecc code from hardware register obtained from hardware ecc
 + * @page_data:  page data
 + */
 +static int omap_compare_ecc(u8 *ecc_data1,    /* read from NAND memory */
 +                          u8 *ecc_data2,      /* read from register */
 +                          u8 *page_data)
 +{
 +      uint    i;
 +      u8      tmp0_bit[8], tmp1_bit[8], tmp2_bit[8];
 +      u8      comp0_bit[8], comp1_bit[8], comp2_bit[8];
 +      u8      ecc_bit[24];
 +      u8      ecc_sum = 0;
 +      u8      find_bit = 0;
 +      uint    find_byte = 0;
 +      int     isEccFF;
 +
 +      isEccFF = ((*(u32 *)ecc_data1 & 0xFFFFFF) == 0xFFFFFF);
 +
 +      gen_true_ecc(ecc_data1);
 +      gen_true_ecc(ecc_data2);
 +
 +      for (i = 0; i <= 2; i++) {
 +              *(ecc_data1 + i) = ~(*(ecc_data1 + i));
 +              *(ecc_data2 + i) = ~(*(ecc_data2 + i));
 +      }
 +
 +      for (i = 0; i < 8; i++) {
 +              tmp0_bit[i]     = *ecc_data1 % 2;
 +              *ecc_data1      = *ecc_data1 / 2;
 +      }
 +
 +      for (i = 0; i < 8; i++) {
 +              tmp1_bit[i]      = *(ecc_data1 + 1) % 2;
 +              *(ecc_data1 + 1) = *(ecc_data1 + 1) / 2;
 +      }
 +
 +      for (i = 0; i < 8; i++) {
 +              tmp2_bit[i]      = *(ecc_data1 + 2) % 2;
 +              *(ecc_data1 + 2) = *(ecc_data1 + 2) / 2;
 +      }
 +
 +      for (i = 0; i < 8; i++) {
 +              comp0_bit[i]     = *ecc_data2 % 2;
 +              *ecc_data2       = *ecc_data2 / 2;
 +      }
 +
 +      for (i = 0; i < 8; i++) {
 +              comp1_bit[i]     = *(ecc_data2 + 1) % 2;
 +              *(ecc_data2 + 1) = *(ecc_data2 + 1) / 2;
 +      }
 +
 +      for (i = 0; i < 8; i++) {
 +              comp2_bit[i]     = *(ecc_data2 + 2) % 2;
 +              *(ecc_data2 + 2) = *(ecc_data2 + 2) / 2;
 +      }
 +
 +      for (i = 0; i < 6; i++)
 +              ecc_bit[i] = tmp2_bit[i + 2] ^ comp2_bit[i + 2];
 +
 +      for (i = 0; i < 8; i++)
 +              ecc_bit[i + 6] = tmp0_bit[i] ^ comp0_bit[i];
 +
 +      for (i = 0; i < 8; i++)
 +              ecc_bit[i + 14] = tmp1_bit[i] ^ comp1_bit[i];
 +
 +      ecc_bit[22] = tmp2_bit[0] ^ comp2_bit[0];
 +      ecc_bit[23] = tmp2_bit[1] ^ comp2_bit[1];
 +
 +      for (i = 0; i < 24; i++)
 +              ecc_sum += ecc_bit[i];
 +
 +      switch (ecc_sum) {
 +      case 0:
 +              /* Not reached because this function is not called if
 +               *  ECC values are equal
 +               */
 +              return 0;
 +
 +      case 1:
 +              /* Uncorrectable error */
 +              DEBUG(MTD_DEBUG_LEVEL0, "ECC UNCORRECTED_ERROR 1\n");
 +              return -1;
 +
 +      case 11:
 +              /* UN-Correctable error */
 +              DEBUG(MTD_DEBUG_LEVEL0, "ECC UNCORRECTED_ERROR B\n");
 +              return -1;
 +
 +      case 12:
 +              /* Correctable error */
 +              find_byte = (ecc_bit[23] << 8) +
 +                          (ecc_bit[21] << 7) +
 +                          (ecc_bit[19] << 6) +
 +                          (ecc_bit[17] << 5) +
 +                          (ecc_bit[15] << 4) +
 +                          (ecc_bit[13] << 3) +
 +                          (ecc_bit[11] << 2) +
 +                          (ecc_bit[9]  << 1) +
 +                          ecc_bit[7];
 +
 +              find_bit = (ecc_bit[5] << 2) + (ecc_bit[3] << 1) + ecc_bit[1];
 +
 +              DEBUG(MTD_DEBUG_LEVEL0, "Correcting single bit ECC error at "
 +                              "offset: %d, bit: %d\n", find_byte, find_bit);
 +
 +              page_data[find_byte] ^= (1 << find_bit);
 +
 +              return 0;
 +      default:
 +              if (isEccFF) {
 +                      if (ecc_data2[0] == 0 &&
 +                          ecc_data2[1] == 0 &&
 +                          ecc_data2[2] == 0)
 +                              return 0;
 +              }
 +              DEBUG(MTD_DEBUG_LEVEL0, "UNCORRECTED_ERROR default\n");
 +              return -1;
 +      }
 +}
 +
 +/*
 + * omap_correct_data - Compares the ecc read from nand spare area with ECC
 + * registers values and corrects one bit error if it has occured
 + * @mtd: MTD device structure
 + * @dat: page data
 + * @read_ecc: ecc read from nand flash
 + * @calc_ecc: ecc read from ECC registers
 + */
 +static int omap_correct_data(struct mtd_info *mtd, u_char * dat,
 +                              u_char * read_ecc, u_char * calc_ecc)
 +{
 +      struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 +                                                      mtd);
 +      int blockCnt = 0, i = 0, ret = 0;
 +
 +      /* Ex NAND_ECC_HW12_2048 */
 +      if ((info->nand.ecc.mode == NAND_ECC_HW) &&
 +                      (info->nand.ecc.size  == 2048))
 +              blockCnt = 4;
 +      else
 +              blockCnt = 1;
 +
 +      for (i = 0; i < blockCnt; i++) {
 +              if (memcmp(read_ecc, calc_ecc, 3) != 0) {
 +                      ret = omap_compare_ecc(read_ecc, calc_ecc, dat);
 +                      if (ret < 0) return ret;
 +              }
 +              read_ecc += 3;
 +              calc_ecc += 3;
 +              dat      += 512;
 +      }
 +      return 0;
 +}
 +
 +/*
 + * omap_calcuate_ecc - Generate non-inverted ECC bytes.
 + * Using noninverted ECC can be considered ugly since writing a blank
 + * page ie. padding will clear the ECC bytes. This is no problem as long
 + * nobody is trying to write data on the seemingly unused page. Reading
 + * an erased page will produce an ECC mismatch between generated and read
 + * ECC bytes that has to be dealt with separately.
 + * @mtd: MTD device structure
 + * @dat: The pointer to data on which ecc is computed
 + * @ecc_code: The ecc_code buffer
 + */
 +static int omap_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
 +                              u_char *ecc_code)
 +{
 +      struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 +                                                      mtd);
 +      unsigned long val = 0x0;
 +      unsigned long reg;
 +
 +      /* Start Reading from HW ECC1_Result = 0x200 */
 +      reg = (unsigned long)(info->gpmc_baseaddr + GPMC_ECC1_RESULT);
 +      val = __raw_readl(reg);
 +      *ecc_code++ = val;          /* P128e, ..., P1e */
 +      *ecc_code++ = val >> 16;    /* P128o, ..., P1o */
 +      /* P2048o, P1024o, P512o, P256o, P2048e, P1024e, P512e, P256e */
 +      *ecc_code++ = ((val >> 8) & 0x0f) | ((val >> 20) & 0xf0);
 +      reg += 4;
 +
 +      return 0;
 +}
 +
 +/*
 + * omap_enable_hwecc - This function enables the hardware ecc functionality
 + * @mtd: MTD device structure
 + * @mode: Read/Write mode
 + */
 +static void omap_enable_hwecc(struct mtd_info *mtd, int mode)
 +{
 +      struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 +                                                      mtd);
 +      register struct nand_chip *chip = mtd->priv;
 +      unsigned int dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0;
 +      unsigned long val = __raw_readl(info->gpmc_baseaddr + GPMC_ECC_CONFIG);
 +
 +      switch (mode) {
 +      case NAND_ECC_READ    :
 +              __raw_writel(0x101, info->gpmc_baseaddr + GPMC_ECC_CONTROL);
 +              /* (ECC 16 or 8 bit col) | ( CS  )  | ECC Enable */
 +              val = (dev_width << 7) | (info->gpmc_cs << 1) | (0x1);
 +              break;
 +      case NAND_ECC_READSYN :
 +               __raw_writel(0x100, info->gpmc_baseaddr + GPMC_ECC_CONTROL);
 +              /* (ECC 16 or 8 bit col) | ( CS  )  | ECC Enable */
 +              val = (dev_width << 7) | (info->gpmc_cs << 1) | (0x1);
 +              break;
 +      case NAND_ECC_WRITE   :
 +              __raw_writel(0x101, info->gpmc_baseaddr + GPMC_ECC_CONTROL);
 +              /* (ECC 16 or 8 bit col) | ( CS  )  | ECC Enable */
 +              val = (dev_width << 7) | (info->gpmc_cs << 1) | (0x1);
 +              break;
 +      default:
 +              DEBUG(MTD_DEBUG_LEVEL0, "Error: Unrecognized Mode[%d]!\n",
 +                                      mode);
 +              break;
 +      }
 +
 +      __raw_writel(val, info->gpmc_baseaddr + GPMC_ECC_CONFIG);
 +}
 +#endif
 +
 +/*
 + * omap_wait - Wait function is called during Program and erase
 + * operations and the way it is called from MTD layer, we should wait
 + * till the NAND chip is ready after the programming/erase operation
 + * has completed.
 + * @mtd: MTD device structure
 + * @chip: NAND Chip structure
 + */
 +static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip)
 +{
 +      register struct nand_chip *this = mtd->priv;
 +      struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 +                                                      mtd);
 +      int status = 0;
 +
 +      this->IO_ADDR_W = (void *) info->gpmc_cs_baseaddr +
 +                                              GPMC_CS_NAND_COMMAND;
 +      this->IO_ADDR_R = (void *) info->gpmc_cs_baseaddr + GPMC_CS_NAND_DATA;
 +
 +      while (!(status & 0x40)) {
 +               __raw_writeb(NAND_CMD_STATUS & 0xFF, this->IO_ADDR_W);
 +              status = __raw_readb(this->IO_ADDR_R);
 +      }
 +      return status;
 +}
 +
 +/*
 + * omap_dev_ready - calls the platform specific dev_ready function
 + * @mtd: MTD device structure
 + */
 +static int omap_dev_ready(struct mtd_info *mtd)
 +{
 +      struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 +                                                      mtd);
 +      unsigned int val = __raw_readl(info->gpmc_baseaddr + GPMC_IRQ_STATUS);
 +
 +      if ((val & 0x100) == 0x100) {
 +              /* Clear IRQ Interrupt */
 +              val |= 0x100;
 +              val &= ~(0x0);
 +              __raw_writel(val, info->gpmc_baseaddr + GPMC_IRQ_STATUS);
 +      } else {
 +              unsigned int cnt = 0;
 +              while (cnt++ < 0x1FF) {
 +                      if  ((val & 0x100) == 0x100)
 +                              return 0;
 +                      val = __raw_readl(info->gpmc_baseaddr +
 +                                                      GPMC_IRQ_STATUS);
 +              }
 +      }
 +
 +      return 1;
 +}
 +
 +static int __devinit omap_nand_probe(struct platform_device *pdev)
 +{
 +      struct omap_nand_info           *info;
 +      struct omap_nand_platform_data  *pdata;
 +      int                             err;
 +      unsigned long                   val;
 +
 +
 +      pdata = pdev->dev.platform_data;
 +      if (pdata == NULL) {
 +              dev_err(&pdev->dev, "platform data missing\n");
 +              return -ENODEV;
 +      }
 +
 +      info = kzalloc(sizeof(struct omap_nand_info), GFP_KERNEL);
 +      if (!info) return -ENOMEM;
 +
 +      platform_set_drvdata(pdev, info);
 +
 +      spin_lock_init(&info->controller.lock);
 +      init_waitqueue_head(&info->controller.wq);
 +
 +      info->pdev = pdev;
 +
 +      info->gpmc_cs           = pdata->cs;
 +      info->gpmc_baseaddr     = pdata->gpmc_baseaddr;
 +      info->gpmc_cs_baseaddr  = pdata->gpmc_cs_baseaddr;
 +
 +      info->mtd.priv          = &info->nand;
++      info->mtd.name          = dev_name(&pdev->dev);
 +      info->mtd.owner         = THIS_MODULE;
 +
 +      err = gpmc_cs_request(info->gpmc_cs, NAND_IO_SIZE, &info->phys_base);
 +      if (err < 0) {
 +              dev_err(&pdev->dev, "Cannot request GPMC CS\n");
 +              goto out_free_info;
 +      }
 +
 +      /* Enable RD PIN Monitoring Reg */
 +      if (pdata->dev_ready) {
 +              val  = gpmc_cs_read_reg(info->gpmc_cs, GPMC_CS_CONFIG1);
 +              val |= WR_RD_PIN_MONITORING;
 +              gpmc_cs_write_reg(info->gpmc_cs, GPMC_CS_CONFIG1, val);
 +      }
 +
 +      val  = gpmc_cs_read_reg(info->gpmc_cs, GPMC_CS_CONFIG7);
 +      val &= ~(0xf << 8);
 +      val |=  (0xc & 0xf) << 8;
 +      gpmc_cs_write_reg(info->gpmc_cs, GPMC_CS_CONFIG7, val);
 +
 +      /* NAND write protect off */
 +      omap_nand_wp(&info->mtd, NAND_WP_OFF);
 +
 +      if (!request_mem_region(info->phys_base, NAND_IO_SIZE,
 +                              pdev->dev.driver->name)) {
 +              err = -EBUSY;
 +              goto out_free_cs;
 +      }
 +
 +      info->nand.IO_ADDR_R = ioremap(info->phys_base, NAND_IO_SIZE);
 +      if (!info->nand.IO_ADDR_R) {
 +              err = -ENOMEM;
 +              goto out_release_mem_region;
 +      }
 +      info->nand.controller = &info->controller;
 +
 +      info->nand.IO_ADDR_W = info->nand.IO_ADDR_R;
 +      info->nand.cmd_ctrl  = omap_hwcontrol;
 +
 +      /* REVISIT:  only supports 16-bit NAND flash */
 +
 +      info->nand.read_buf   = omap_read_buf16;
 +      info->nand.write_buf  = omap_write_buf16;
 +      info->nand.verify_buf = omap_verify_buf;
 +
 +      /*
 +      * If RDY/BSY line is connected to OMAP then use the omap ready funcrtion
 +      * and the generic nand_wait function which reads the status register
 +      * after monitoring the RDY/BSY line.Otherwise use a standard chip delay
 +      * which is slightly more than tR (AC Timing) of the NAND device and read
 +      * status register until you get a failure or success
 +      */
 +      if (pdata->dev_ready) {
 +              info->nand.dev_ready = omap_dev_ready;
 +              info->nand.chip_delay = 0;
 +      } else {
 +              info->nand.waitfunc = omap_wait;
 +              info->nand.chip_delay = 50;
 +      }
 +
 +      info->nand.options  |= NAND_SKIP_BBTSCAN;
 +      if ((gpmc_cs_read_reg(info->gpmc_cs, GPMC_CS_CONFIG1) & 0x3000)
 +                                                              == 0x1000)
 +              info->nand.options  |= NAND_BUSWIDTH_16;
 +
 +#ifdef CONFIG_MTD_NAND_OMAP_HWECC
 +      info->nand.ecc.bytes            = 3;
 +      info->nand.ecc.size             = 512;
 +      info->nand.ecc.calculate        = omap_calculate_ecc;
 +      info->nand.ecc.hwctl            = omap_enable_hwecc;
 +      info->nand.ecc.correct          = omap_correct_data;
 +      info->nand.ecc.mode             = NAND_ECC_HW;
 +
 +      /* init HW ECC */
 +      omap_hwecc_init(&info->mtd);
 +#else
 +      info->nand.ecc.mode = NAND_ECC_SOFT;
 +#endif
 +
 +      /* DIP switches on some boards change between 8 and 16 bit
 +       * bus widths for flash.  Try the other width if the first try fails.
 +       */
 +      if (nand_scan(&info->mtd, 1)) {
 +              info->nand.options ^= NAND_BUSWIDTH_16;
 +              if (nand_scan(&info->mtd, 1)) {
 +                      err = -ENXIO;
 +                      goto out_release_mem_region;
 +              }
 +      }
 +
 +#ifdef CONFIG_MTD_PARTITIONS
 +      err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0);
 +      if (err > 0)
 +              add_mtd_partitions(&info->mtd, info->parts, err);
 +      else if (pdata->parts)
 +              add_mtd_partitions(&info->mtd, pdata->parts, pdata->nr_parts);
 +      else
 +#endif
 +              add_mtd_device(&info->mtd);
 +
 +      platform_set_drvdata(pdev, &info->mtd);
 +
 +      return 0;
 +
 +out_release_mem_region:
 +      release_mem_region(info->phys_base, NAND_IO_SIZE);
 +out_free_cs:
 +      gpmc_cs_free(info->gpmc_cs);
 +out_free_info:
 +      kfree(info);
 +
 +      return err;
 +}
 +
 +static int omap_nand_remove(struct platform_device *pdev)
 +{
 +      struct mtd_info *mtd = platform_get_drvdata(pdev);
 +      struct omap_nand_info *info = mtd->priv;
 +
 +      platform_set_drvdata(pdev, NULL);
 +      /* Release NAND device, its internal structures and partitions */
 +      nand_release(&info->mtd);
 +      iounmap(info->nand.IO_ADDR_R);
 +      kfree(&info->mtd);
 +      return 0;
 +}
 +
 +static struct platform_driver omap_nand_driver = {
 +      .probe          = omap_nand_probe,
 +      .remove         = omap_nand_remove,
 +      .driver         = {
 +              .name   = DRIVER_NAME,
 +              .owner  = THIS_MODULE,
 +      },
 +};
 +MODULE_ALIAS(DRIVER_NAME);
 +
 +static int __init omap_nand_init(void)
 +{
 +      printk(KERN_INFO "%s driver initializing\n", DRIVER_NAME);
 +      return platform_driver_register(&omap_nand_driver);
 +}
 +
 +static void __exit omap_nand_exit(void)
 +{
 +      platform_driver_unregister(&omap_nand_driver);
 +}
 +
 +module_init(omap_nand_init);
 +module_exit(omap_nand_exit);
 +
 +MODULE_LICENSE("GPL");
 +MODULE_DESCRIPTION("Glue layer for NAND flash on TI OMAP boards");
diff --combined drivers/net/smc91x.c
index 0a47bad4afeb4e88d8bf5038d01b305375218269,fdcbaf8dfa739618a5a8f25bc27f6c24222e8004..734bf1e82c4fb2b3a6e3867181fdb5fffd3136c4
@@@ -421,11 -421,6 +421,11 @@@ static inline void  smc_rcv(struct net_
                dev->name, packet_number, status,
                packet_len, packet_len);
  
 +      if (unlikely(packet_len == 0 && !(status & RS_ERRORS))) {
 +              printk(KERN_ERR "%s: bad memory timings: rxlen %u status %x\n",
 +                      dev->name, packet_len, status);
 +              status |= RS_TOOSHORT;
 +      }
        back:
        if (unlikely(packet_len < 6 || status & RS_ERRORS)) {
                if (status & RS_TOOLONG && packet_len <= (1514 + 4 + 6)) {
@@@ -1619,7 -1614,7 +1619,7 @@@ smc_ethtool_getdrvinfo(struct net_devic
  {
        strncpy(info->driver, CARDNAME, sizeof(info->driver));
        strncpy(info->version, version, sizeof(info->version));
-       strncpy(info->bus_info, dev->dev.parent->bus_id, sizeof(info->bus_info));
+       strncpy(info->bus_info, dev_name(dev->dev.parent), sizeof(info->bus_info));
  }
  
  static int smc_ethtool_nwayreset(struct net_device *dev)
@@@ -1648,6 -1643,117 +1648,117 @@@ static void smc_ethtool_setmsglevel(str
        lp->msg_enable = level;
  }
  
+ static int smc_write_eeprom_word(struct net_device *dev, u16 addr, u16 word)
+ {
+       u16 ctl;
+       struct smc_local *lp = netdev_priv(dev);
+       void __iomem *ioaddr = lp->base;
+       spin_lock_irq(&lp->lock);
+       /* load word into GP register */
+       SMC_SELECT_BANK(lp, 1);
+       SMC_SET_GP(lp, word);
+       /* set the address to put the data in EEPROM */
+       SMC_SELECT_BANK(lp, 2);
+       SMC_SET_PTR(lp, addr);
+       /* tell it to write */
+       SMC_SELECT_BANK(lp, 1);
+       ctl = SMC_GET_CTL(lp);
+       SMC_SET_CTL(lp, ctl | (CTL_EEPROM_SELECT | CTL_STORE));
+       /* wait for it to finish */
+       do {
+               udelay(1);
+       } while (SMC_GET_CTL(lp) & CTL_STORE);
+       /* clean up */
+       SMC_SET_CTL(lp, ctl);
+       SMC_SELECT_BANK(lp, 2);
+       spin_unlock_irq(&lp->lock);
+       return 0;
+ }
+ static int smc_read_eeprom_word(struct net_device *dev, u16 addr, u16 *word)
+ {
+       u16 ctl;
+       struct smc_local *lp = netdev_priv(dev);
+       void __iomem *ioaddr = lp->base;
+       spin_lock_irq(&lp->lock);
+       /* set the EEPROM address to get the data from */
+       SMC_SELECT_BANK(lp, 2);
+       SMC_SET_PTR(lp, addr | PTR_READ);
+       /* tell it to load */
+       SMC_SELECT_BANK(lp, 1);
+       SMC_SET_GP(lp, 0xffff); /* init to known */
+       ctl = SMC_GET_CTL(lp);
+       SMC_SET_CTL(lp, ctl | (CTL_EEPROM_SELECT | CTL_RELOAD));
+       /* wait for it to finish */
+       do {
+               udelay(1);
+       } while (SMC_GET_CTL(lp) & CTL_RELOAD);
+       /* read word from GP register */
+       *word = SMC_GET_GP(lp);
+       /* clean up */
+       SMC_SET_CTL(lp, ctl);
+       SMC_SELECT_BANK(lp, 2);
+       spin_unlock_irq(&lp->lock);
+       return 0;
+ }
+ static int smc_ethtool_geteeprom_len(struct net_device *dev)
+ {
+       return 0x23 * 2;
+ }
+ static int smc_ethtool_geteeprom(struct net_device *dev,
+               struct ethtool_eeprom *eeprom, u8 *data)
+ {
+       int i;
+       int imax;
+       DBG(1, "Reading %d bytes at %d(0x%x)\n",
+               eeprom->len, eeprom->offset, eeprom->offset);
+       imax = smc_ethtool_geteeprom_len(dev);
+       for (i = 0; i < eeprom->len; i += 2) {
+               int ret;
+               u16 wbuf;
+               int offset = i + eeprom->offset;
+               if (offset > imax)
+                       break;
+               ret = smc_read_eeprom_word(dev, offset >> 1, &wbuf);
+               if (ret != 0)
+                       return ret;
+               DBG(2, "Read 0x%x from 0x%x\n", wbuf, offset >> 1);
+               data[i] = (wbuf >> 8) & 0xff;
+               data[i+1] = wbuf & 0xff;
+       }
+       return 0;
+ }
+ static int smc_ethtool_seteeprom(struct net_device *dev,
+               struct ethtool_eeprom *eeprom, u8 *data)
+ {
+       int i;
+       int imax;
+       DBG(1, "Writing %d bytes to %d(0x%x)\n",
+                       eeprom->len, eeprom->offset, eeprom->offset);
+       imax = smc_ethtool_geteeprom_len(dev);
+       for (i = 0; i < eeprom->len; i += 2) {
+               int ret;
+               u16 wbuf;
+               int offset = i + eeprom->offset;
+               if (offset > imax)
+                       break;
+               wbuf = (data[i] << 8) | data[i + 1];
+               DBG(2, "Writing 0x%x to 0x%x\n", wbuf, offset >> 1);
+               ret = smc_write_eeprom_word(dev, offset >> 1, wbuf);
+               if (ret != 0)
+                       return ret;
+       }
+       return 0;
+ }
  static const struct ethtool_ops smc_ethtool_ops = {
        .get_settings   = smc_ethtool_getsettings,
        .set_settings   = smc_ethtool_setsettings,
        .set_msglevel   = smc_ethtool_setmsglevel,
        .nway_reset     = smc_ethtool_nwayreset,
        .get_link       = ethtool_op_get_link,
- //    .get_eeprom     = smc_ethtool_geteeprom,
- //    .set_eeprom     = smc_ethtool_seteeprom,
+       .get_eeprom_len = smc_ethtool_geteeprom_len,
+       .get_eeprom     = smc_ethtool_geteeprom,
+       .set_eeprom     = smc_ethtool_seteeprom,
+ };
+ static const struct net_device_ops smc_netdev_ops = {
+       .ndo_open               = smc_open,
+       .ndo_stop               = smc_close,
+       .ndo_start_xmit         = smc_hard_start_xmit,
+       .ndo_tx_timeout         = smc_timeout,
+       .ndo_set_multicast_list = smc_set_multicast_list,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+ #ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller    = smc_poll_controller,
+ #endif
  };
  
  /*
@@@ -1870,16 -1990,9 +1995,9 @@@ static int __devinit smc_probe(struct n
        /* Fill in the fields of the device structure with ethernet values. */
        ether_setup(dev);
  
-       dev->open = smc_open;
-       dev->stop = smc_close;
-       dev->hard_start_xmit = smc_hard_start_xmit;
-       dev->tx_timeout = smc_timeout;
        dev->watchdog_timeo = msecs_to_jiffies(watchdog);
-       dev->set_multicast_list = smc_set_multicast_list;
+       dev->netdev_ops = &smc_netdev_ops;
        dev->ethtool_ops = &smc_ethtool_ops;
- #ifdef CONFIG_NET_POLL_CONTROLLER
-       dev->poll_controller = smc_poll_controller;
- #endif
  
        tasklet_init(&lp->tx_task, smc_hardware_send_pkt, (unsigned long)dev);
        INIT_WORK(&lp->phy_configure, smc_phy_configure);
index aa93e462a33f8f945187316a29dc24b8efaf9090,d6d0c5d241ce1bcbcd9b68bc15caacbccb5f5be8..f2b4d329e1aa5f1c9e496597cd052da2c09e56f0
  
  /* per-register bitmasks: */
  
 -#define OMAP2_MCSPI_SYSCONFIG_AUTOIDLE        (1 << 0)
 -#define OMAP2_MCSPI_SYSCONFIG_SOFTRESET       (1 << 1)
 +#define OMAP2_MCSPI_SYSCONFIG_SMARTIDLE       BIT(4)
 +#define OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP       BIT(2)
 +#define OMAP2_MCSPI_SYSCONFIG_AUTOIDLE        BIT(0)
 +#define OMAP2_MCSPI_SYSCONFIG_SOFTRESET       BIT(1)
  
 -#define OMAP2_MCSPI_SYSSTATUS_RESETDONE       (1 << 0)
 +#define OMAP2_MCSPI_SYSSTATUS_RESETDONE       BIT(0)
  
 -#define OMAP2_MCSPI_MODULCTRL_SINGLE  (1 << 0)
 -#define OMAP2_MCSPI_MODULCTRL_MS      (1 << 2)
 -#define OMAP2_MCSPI_MODULCTRL_STEST   (1 << 3)
 +#define OMAP2_MCSPI_MODULCTRL_SINGLE  BIT(0)
 +#define OMAP2_MCSPI_MODULCTRL_MS      BIT(2)
 +#define OMAP2_MCSPI_MODULCTRL_STEST   BIT(3)
  
 -#define OMAP2_MCSPI_CHCONF_PHA                (1 << 0)
 -#define OMAP2_MCSPI_CHCONF_POL                (1 << 1)
 +#define OMAP2_MCSPI_CHCONF_PHA                BIT(0)
 +#define OMAP2_MCSPI_CHCONF_POL                BIT(1)
  #define OMAP2_MCSPI_CHCONF_CLKD_MASK  (0x0f << 2)
 -#define OMAP2_MCSPI_CHCONF_EPOL               (1 << 6)
 +#define OMAP2_MCSPI_CHCONF_EPOL               BIT(6)
  #define OMAP2_MCSPI_CHCONF_WL_MASK    (0x1f << 7)
 -#define OMAP2_MCSPI_CHCONF_TRM_RX_ONLY        (0x01 << 12)
 -#define OMAP2_MCSPI_CHCONF_TRM_TX_ONLY        (0x02 << 12)
 +#define OMAP2_MCSPI_CHCONF_TRM_RX_ONLY        BIT(12)
 +#define OMAP2_MCSPI_CHCONF_TRM_TX_ONLY        BIT(13)
  #define OMAP2_MCSPI_CHCONF_TRM_MASK   (0x03 << 12)
 -#define OMAP2_MCSPI_CHCONF_DMAW               (1 << 14)
 -#define OMAP2_MCSPI_CHCONF_DMAR               (1 << 15)
 -#define OMAP2_MCSPI_CHCONF_DPE0               (1 << 16)
 -#define OMAP2_MCSPI_CHCONF_DPE1               (1 << 17)
 -#define OMAP2_MCSPI_CHCONF_IS         (1 << 18)
 -#define OMAP2_MCSPI_CHCONF_TURBO      (1 << 19)
 -#define OMAP2_MCSPI_CHCONF_FORCE      (1 << 20)
 +#define OMAP2_MCSPI_CHCONF_DMAW               BIT(14)
 +#define OMAP2_MCSPI_CHCONF_DMAR               BIT(15)
 +#define OMAP2_MCSPI_CHCONF_DPE0               BIT(16)
 +#define OMAP2_MCSPI_CHCONF_DPE1               BIT(17)
 +#define OMAP2_MCSPI_CHCONF_IS         BIT(18)
 +#define OMAP2_MCSPI_CHCONF_TURBO      BIT(19)
 +#define OMAP2_MCSPI_CHCONF_FORCE      BIT(20)
  
 -#define OMAP2_MCSPI_CHSTAT_RXS                (1 << 0)
 -#define OMAP2_MCSPI_CHSTAT_TXS                (1 << 1)
 -#define OMAP2_MCSPI_CHSTAT_EOT                (1 << 2)
 +#define OMAP2_MCSPI_CHSTAT_RXS                BIT(0)
 +#define OMAP2_MCSPI_CHSTAT_TXS                BIT(1)
 +#define OMAP2_MCSPI_CHSTAT_EOT                BIT(2)
  
 -#define OMAP2_MCSPI_CHCTRL_EN         (1 << 0)
 +#define OMAP2_MCSPI_CHCTRL_EN         BIT(0)
  
 +#define OMAP2_MCSPI_WAKEUPENABLE_WKEN BIT(0)
  
  /* We have 2 DMA channels per CS, one for RX and one for TX */
  struct omap2_mcspi_dma {
@@@ -887,12 -884,8 +887,12 @@@ static int __init omap2_mcspi_reset(str
        } while (!(tmp & OMAP2_MCSPI_SYSSTATUS_RESETDONE));
  
        mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG,
 -                      /* (3 << 8) | (2 << 3) | */
 -                      OMAP2_MCSPI_SYSCONFIG_AUTOIDLE);
 +                      OMAP2_MCSPI_SYSCONFIG_AUTOIDLE |
 +                      OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP |
 +                      OMAP2_MCSPI_SYSCONFIG_SMARTIDLE);
 +
 +      mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE,
 +                      OMAP2_MCSPI_WAKEUPENABLE_WKEN);
  
        omap2_mcspi_set_master_mode(master);
  
@@@ -1010,7 -1003,7 +1010,7 @@@ static int __init omap2_mcspi_probe(str
                goto err1;
        }
        if (!request_mem_region(r->start, (r->end - r->start) + 1,
-                       pdev->dev.bus_id)) {
+                       dev_name(&pdev->dev))) {
                status = -EBUSY;
                goto err1;
        }
        spin_lock_init(&mcspi->lock);
        INIT_LIST_HEAD(&mcspi->msg_queue);
  
-       mcspi->ick = clk_get(&pdev->dev, "mcspi_ick");
+       mcspi->ick = clk_get(&pdev->dev, "ick");
        if (IS_ERR(mcspi->ick)) {
                dev_dbg(&pdev->dev, "can't get mcspi_ick\n");
                status = PTR_ERR(mcspi->ick);
                goto err1a;
        }
-       mcspi->fck = clk_get(&pdev->dev, "mcspi_fck");
+       mcspi->fck = clk_get(&pdev->dev, "fck");
        if (IS_ERR(mcspi->fck)) {
                dev_dbg(&pdev->dev, "can't get mcspi_fck\n");
                status = PTR_ERR(mcspi->fck);
diff --combined drivers/usb/Kconfig
index a1afd505dab711e9978cb483053c27cbbdf29150,c6c816b7ecb5d30cacf1dbfe4ca1115df3553788..7ba50d2135cde291af20ed1beb19bebd606b326e
@@@ -47,6 -47,7 +47,7 @@@ config USB_ARCH_HAS_OHC
        default y if CPU_SUBTYPE_SH7720
        default y if CPU_SUBTYPE_SH7721
        default y if CPU_SUBTYPE_SH7763
+       default y if CPU_SUBTYPE_SH7786
        # more:
        default PCI
  
@@@ -56,7 -57,6 +57,7 @@@ config USB_ARCH_HAS_EHC
        default y if PPC_83xx
        default y if SOC_AU1200
        default y if ARCH_IXP4XX
 +      default y if ARCH_OMAP34XX
        default PCI
  
  # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface.
diff --combined drivers/usb/host/Kconfig
index 02df7955799b87a0d699de4d7d69b398ab48045d,845479f7c70773cacff061d3a04c0f3ca0b21d86..1091358d12bdd611af8d96416bce6156db4f6241
@@@ -24,10 -24,7 +24,7 @@@ config USB_EHCI_HC
          The Enhanced Host Controller Interface (EHCI) is standard for USB 2.0
          "high speed" (480 Mbit/sec, 60 Mbyte/sec) host controller hardware.
          If your USB host controller supports USB 2.0, you will likely want to
-         configure this Host Controller Driver.  At the time of this writing, 
-         the primary implementation of EHCI is a chip from NEC, widely available
-         in add-on PCI cards, but implementations are in the works from other 
-         vendors including Intel and Philips.  Motherboard support is appearing.
+         configure this Host Controller Driver.
  
          EHCI controllers are packaged with "companion" host controllers (OHCI
          or UHCI) to handle USB 1.1 devices connected to root hub ports.  Ports
  
          To compile this driver as a module, choose M here: the
          module will be called ehci-hcd.
 +choice
 +      prompt "PHY/TLL mode"
 +      depends on USB_EHCI_HCD && EXPERIMENTAL && ARCH_OMAP34XX
 +      ---help---
 +      Choose PHY or TLL mode of operation
 +
 +config OMAP_EHCI_PHY_MODE
 +      bool "PHY mode: ISP1504 on Port1/2 (NEW 3430ES2.0)"
 +      depends on USB_EHCI_HCD && EXPERIMENTAL && ARCH_OMAP34XX
 +      ---help---
 +        EHCI PHY mode. Port1 and Port2 are connected to ISP1504 transcievers
 +
 +config OMAP_EHCI_TLL_MODE
 +      bool "TLL mode: (EXPERIMENTAL)"
 +      depends on USB_EHCI_HCD && EXPERIMENTAL && ARCH_OMAP34XX
 +      ---help---
 +      OMAP EHCI controller has TLL mode of operation for all 3 ports.
 +      Use this mode when no transciever is present
 +endchoice
  
  config USB_EHCI_ROOT_HUB_TT
        bool "Root Hub Transaction Translators"
@@@ -142,7 -120,7 +139,7 @@@ config USB_ISP116X_HC
  
  config USB_ISP1760_HCD
        tristate "ISP 1760 HCD support"
-       depends on USB && EXPERIMENTAL && (PCI || PPC_OF)
+       depends on USB && EXPERIMENTAL
        ---help---
          The ISP1760 chip is a USB 2.0 host controller.
  
index d832a94ee98b63ef7697145fc2933044e6ac9769,f2618d17710d248938632cee6278a2a3bb690a8b..8b84ac683dceb76c90eaf6b45441ddb9874fe738
@@@ -110,6 -110,42 +110,42 @@@ MODULE_PARM_DESC (ignore_oc, "ignore bo
  
  /*-------------------------------------------------------------------------*/
  
+ static void
+ timer_action(struct ehci_hcd *ehci, enum ehci_timer_action action)
+ {
+       /* Don't override timeouts which shrink or (later) disable
+        * the async ring; just the I/O watchdog.  Note that if a
+        * SHRINK were pending, OFF would never be requested.
+        */
+       if (timer_pending(&ehci->watchdog)
+                       && ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF))
+                               & ehci->actions))
+               return;
+       if (!test_and_set_bit(action, &ehci->actions)) {
+               unsigned long t;
+               switch (action) {
+               case TIMER_IO_WATCHDOG:
+                       t = EHCI_IO_JIFFIES;
+                       break;
+               case TIMER_ASYNC_OFF:
+                       t = EHCI_ASYNC_JIFFIES;
+                       break;
+               /* case TIMER_ASYNC_SHRINK: */
+               default:
+                       /* add a jiffie since we synch against the
+                        * 8 KHz uframe counter.
+                        */
+                       t = DIV_ROUND_UP(EHCI_SHRINK_FRAMES * HZ, 1000) + 1;
+                       break;
+               }
+               mod_timer(&ehci->watchdog, t + jiffies);
+       }
+ }
+ /*-------------------------------------------------------------------------*/
  /*
   * handshake - spin reading hc until handshake completes or fails
   * @ptr: address of hc register to be read
@@@ -1016,11 -1052,6 +1052,11 @@@ MODULE_LICENSE ("GPL")
  #define       PLATFORM_DRIVER         ehci_hcd_au1xxx_driver
  #endif
  
 +#ifdef CONFIG_ARCH_OMAP34XX
 +#include "ehci-omap.c"
 +#define       PLATFORM_DRIVER         ehci_hcd_omap_driver
 +#endif
 +
  #ifdef CONFIG_PPC_PS3
  #include "ehci-ps3.c"
  #define       PS3_SYSTEM_BUS_DRIVER   ps3_ehci_driver
index 3bb4247cc2e6441414aa53f73d5b29b290e3af5d,060d72fe57cb1f639861ae24cf10a6ed0babdb40..7617dd406a32332a838ff767966a6b9bac299424
@@@ -67,7 -67,6 +67,7 @@@ static struct caps_table_struct ctrl_ca
        { OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE, "pixel double window" },
        { OMAPFB_CAPS_WINDOW_SCALE,   "scale window" },
        { OMAPFB_CAPS_WINDOW_OVERLAY, "overlay window" },
 +      { OMAPFB_CAPS_WINDOW_ROTATE,  "rotate window" },
        { OMAPFB_CAPS_SET_BACKLIGHT,  "backlight setting" },
  };
  
@@@ -216,22 -215,13 +216,22 @@@ static int ctrl_change_mode(struct fb_i
                                 offset, var->xres_virtual,
                                 plane->info.pos_x, plane->info.pos_y,
                                 var->xres, var->yres, plane->color_mode);
 -      if (fbdev->ctrl->set_scale != NULL)
 +      if (r < 0)
 +              return r;
 +
 +      if (fbdev->ctrl->set_rotate != NULL)
 +              if((r = fbdev->ctrl->set_rotate(var->rotate)) < 0)
 +                      return r;
 +
 +      if ((fbdev->ctrl->set_scale != NULL) && (plane->idx > 0))
                r = fbdev->ctrl->set_scale(plane->idx,
                                   var->xres, var->yres,
                                   plane->info.out_width,
                                   plane->info.out_height);
 +      if (r < 0)
 +              return r;
  
 -      return r;
 +      return 0;
  }
  
  /*
@@@ -348,7 -338,7 +348,7 @@@ static int omapfb_blank(int blank, stru
  
        omapfb_rqueue_lock(fbdev);
        switch (blank) {
-       case VESA_NO_BLANKING:
+       case FB_BLANK_UNBLANK:
                if (fbdev->state == OMAPFB_SUSPENDED) {
                        if (fbdev->ctrl->resume)
                                fbdev->ctrl->resume();
                                do_update = 1;
                }
                break;
-       case VESA_POWERDOWN:
+       case FB_BLANK_POWERDOWN:
                if (fbdev->state == OMAPFB_ACTIVE) {
                        fbdev->panel->disable(fbdev->panel);
                        if (fbdev->ctrl->suspend)
@@@ -562,6 -552,7 +562,6 @@@ static int set_fb_var(struct fb_info *f
                var->xoffset = var->xres_virtual - var->xres;
        if (var->yres + var->yoffset > var->yres_virtual)
                var->yoffset = var->yres_virtual - var->yres;
 -      line_size = var->xres * bpp / 8;
  
        if (plane->color_mode == OMAPFB_COLOR_RGB444) {
                var->red.offset   = 8; var->red.length   = 4;
@@@ -607,7 -598,7 +607,7 @@@ static void omapfb_rotate(struct fb_inf
        struct omapfb_device *fbdev = plane->fbdev;
  
        omapfb_rqueue_lock(fbdev);
 -      if (cpu_is_omap15xx() && rotate != fbi->var.rotate) {
 +      if (rotate != fbi->var.rotate) {
                struct fb_var_screeninfo *new_var = &fbdev->new_var;
  
                memcpy(new_var, &fbi->var, sizeof(*new_var));
@@@ -714,42 -705,28 +714,42 @@@ int omapfb_update_window_async(struct f
                                void (*callback)(void *),
                                void *callback_data)
  {
 +      int xres, yres;
        struct omapfb_plane_struct *plane = fbi->par;
        struct omapfb_device *fbdev = plane->fbdev;
 -      struct fb_var_screeninfo *var;
 +      struct fb_var_screeninfo *var = &fbi->var;
 +
 +      switch (var->rotate) {
 +      case 0:
 +      case 180:
 +              xres = fbdev->panel->x_res;
 +              yres = fbdev->panel->y_res;
 +              break;
 +      case 90:
 +      case 270:
 +              xres = fbdev->panel->y_res;
 +              yres = fbdev->panel->x_res;
 +              break;
 +      default:
 +              return -EINVAL;
 +      }
  
 -      var = &fbi->var;
 -      if (win->x >= var->xres || win->y >= var->yres ||
 -          win->out_x > var->xres || win->out_y >= var->yres)
 +      if (win->x >= xres || win->y >= yres ||
 +          win->out_x > xres || win->out_y > yres)
                return -EINVAL;
  
        if (!fbdev->ctrl->update_window ||
            fbdev->ctrl->get_update_mode() != OMAPFB_MANUAL_UPDATE)
                return -ENODEV;
  
 -      if (win->x + win->width >= var->xres)
 -              win->width = var->xres - win->x;
 -      if (win->y + win->height >= var->yres)
 -              win->height = var->yres - win->y;
 -      /* The out sizes should be cropped to the LCD size */
 -      if (win->out_x + win->out_width > fbdev->panel->x_res)
 -              win->out_width = fbdev->panel->x_res - win->out_x;
 -      if (win->out_y + win->out_height > fbdev->panel->y_res)
 -              win->out_height = fbdev->panel->y_res - win->out_y;
 +      if (win->x + win->width > xres)
 +              win->width = xres - win->x;
 +      if (win->y + win->height > yres)
 +              win->height = yres - win->y;
 +      if (win->out_x + win->out_width > xres)
 +              win->out_width = xres - win->out_x;
 +      if (win->out_y + win->out_height > yres)
 +              win->out_height = yres - win->out_y;
        if (!win->width || !win->height || !win->out_width || !win->out_height)
                return 0;
  
@@@ -1718,8 -1695,8 +1718,8 @@@ static int omapfb_do_probe(struct platf
  
        pr_info("omapfb: configured for panel %s\n", fbdev->panel->name);
  
 -      def_vxres = def_vxres ? : fbdev->panel->x_res;
 -      def_vyres = def_vyres ? : fbdev->panel->y_res;
 +      def_vxres = def_vxres ? def_vxres : fbdev->panel->x_res;
 +      def_vyres = def_vyres ? def_vyres : fbdev->panel->y_res;
  
        init_state++;
  
@@@ -1841,8 -1818,8 +1841,8 @@@ static int omapfb_suspend(struct platfo
  {
        struct omapfb_device *fbdev = platform_get_drvdata(pdev);
  
 -      omapfb_blank(FB_BLANK_POWERDOWN, fbdev->fb_info[0]);
 -
 +      if (fbdev != NULL)
 +              omapfb_blank(VESA_POWERDOWN, fbdev->fb_info[0]);
        return 0;
  }
  
@@@ -1851,8 -1828,7 +1851,8 @@@ static int omapfb_resume(struct platfor
  {
        struct omapfb_device *fbdev = platform_get_drvdata(pdev);
  
 -      omapfb_blank(FB_BLANK_UNBLANK, fbdev->fb_info[0]);
 +      if (fbdev != NULL)
 +              omapfb_blank(VESA_NO_BLANKING, fbdev->fb_info[0]);
        return 0;
  }
  
index 12a2f5e313c706f0f2a97feeac0283a28d71481d,fc65d219d88c55759d734f6c6fbfb50fff9a7805..f8259c18d6159cce1c4dc625fe16113f16628df9
@@@ -36,8 -36,6 +36,8 @@@
  #define CN_VAL_CIFS                     0x1
  #define CN_W1_IDX                     0x3     /* w1 communication */
  #define CN_W1_VAL                     0x1
 +#define CN_IDX_SX1SND                 0x4
 +#define CN_VAL_SX1SND                 0x1
  #define CN_IDX_V86D                   0x4
  #define CN_VAL_V86D_UVESAFB           0x1
  #define CN_IDX_BB                     0x5     /* BlackBoard, from the TSP GPL sampling framework */
@@@ -111,6 -109,12 +111,12 @@@ struct cn_queue_dev 
        unsigned char name[CN_CBQ_NAMELEN];
  
        struct workqueue_struct *cn_queue;
+       /* Sent to kevent to create cn_queue only when needed */
+       struct work_struct wq_creation;
+       /* Tell if the wq_creation job is pending/completed */
+       atomic_t wq_requested;
+       /* Wait for cn_queue to be created */
+       wait_queue_head_t wq_created;
  
        struct list_head queue_list;
        spinlock_t queue_lock;
@@@ -166,6 -170,8 +172,8 @@@ int cn_netlink_send(struct cn_msg *, u3
  int cn_queue_add_callback(struct cn_queue_dev *dev, char *name, struct cb_id *id, void (*callback)(void *));
  void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id);
  
+ int queue_cn_work(struct cn_callback_entry *cbq, struct work_struct *work);
  struct cn_queue_dev *cn_queue_alloc_dev(char *name, struct sock *);
  void cn_queue_free_dev(struct cn_queue_dev *dev);
  
index 2efcd85f9b2a3df02b14df3ade3dc15fb93a7e29,1833bdbf9805474c729483e5abef53ffe99e120d..147c68730a5309c94c8916938b4c5fb3c5615a22
@@@ -31,7 -31,7 +31,7 @@@ config NF_CONNTRACK_PROC_COMPA
        default y
        help
          This option enables /proc and sysctl compatibility with the old
-         layer 3 dependant connection tracking. This is needed to keep
+         layer 3 dependent connection tracking. This is needed to keep
          old programs that have not been adapted to the new names working.
  
          If unsure, say Y.
@@@ -95,11 -95,11 +95,11 @@@ config IP_NF_MATCH_EC
  config IP_NF_MATCH_TTL
        tristate '"ttl" match support'
        depends on NETFILTER_ADVANCED
-       help
-         This adds CONFIG_IP_NF_MATCH_TTL option, which enabled the user
-         to match packets by their TTL value.
-         To compile it as a module, choose M here.  If unsure, say N.
+       select NETFILTER_XT_MATCH_HL
+       ---help---
+       This is a backwards-compat option for the user's convenience
+       (e.g. when running oldconfig). It selects
+       CONFIG_NETFILTER_XT_MATCH_HL.
  
  # `filter', generic and specific targets
  config IP_NF_FILTER
@@@ -202,19 -202,6 +202,19 @@@ config IP_NF_TARGET_REDIREC
          come to the local machine instead of passing through.  This is
          useful for transparent proxies.
  
 +        To compile it as a module, choose M here.  If unsure, say N.
 +
 +config IP_NF_TARGET_IDLETIMER
 +      tristate  "IDLETIMER target support"
 +      depends on IP_NF_IPTABLES
 +      help
 +        This option adds a `IDLETIMER' target. Each matching packet resets
 +        the timer associated with input and/or output interfaces. Timer
 +        expiry causes kobject uevent. Idle timer can be read via sysfs.
 +
 +        To compile it as a module, choose M here.  If unsure, say N.
 +
 +
          To compile it as a module, choose M here.  If unsure, say N.
  
  config NF_NAT_SNMP_BASIC
@@@ -336,19 -323,13 +336,13 @@@ config IP_NF_TARGET_EC
          To compile it as a module, choose M here.  If unsure, say N.
  
  config IP_NF_TARGET_TTL
-       tristate  'TTL target support'
-       depends on IP_NF_MANGLE
+       tristate '"TTL" target support'
        depends on NETFILTER_ADVANCED
-       help
-         This option adds a `TTL' target, which enables the user to modify
-         the TTL value of the IP header.
-         While it is safe to decrement/lower the TTL, this target also enables
-         functionality to increment and set the TTL value of the IP header to
-         arbitrary values.  This is EXTREMELY DANGEROUS since you can easily
-         create immortal packets that loop forever on the network.
-         To compile it as a module, choose M here.  If unsure, say N.
+       select NETFILTER_XT_TARGET_HL
+       ---help---
+       This is a backwards-compat option for the user's convenience
+       (e.g. when running oldconfig). It selects
+       CONFIG_NETFILTER_XT_TARGET_HL.
  
  # raw + specific targets
  config IP_NF_RAW
index a4da278adb0ac5ae01010e44517a6c266bc0f777,48111594ee9bf4921a64a09760b3423840c79d4c..60bdaf1abc4f6f34534962b796af94913e6ae4dc
@@@ -51,7 -51,6 +51,6 @@@ obj-$(CONFIG_IP_NF_SECURITY) += iptable
  obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
  obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
  obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
- obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
  
  # targets
  obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o
@@@ -61,8 -60,6 +60,7 @@@ obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) +
  obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
  obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
  obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
- obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
 +obj-$(CONFIG_IP_NF_TARGET_IDLETIMER) += ipt_IDLETIMER.o
  obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
  
  # generic ARP tables