]> nv-tegra.nvidia Code Review - linux-2.6.git/commitdiff
Merge branch 'for-linus' of git://gitserver.sunplusct.com/linux-2.6-score
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 23 Sep 2009 15:32:05 +0000 (08:32 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 23 Sep 2009 15:32:05 +0000 (08:32 -0700)
* 'for-linus' of git://gitserver.sunplusct.com/linux-2.6-score:
  score: update email address in MAINTAINERS.
  score: Cleanup linker script using new macros.
  score: Make THREAD_SIZE available to assembly files.
  score: Make PAGE_SIZE available to assembly.

354 files changed:
Documentation/ABI/testing/sysfs-gpio
Documentation/accounting/getdelays.c
Documentation/auxdisplay/cfag12864b-example.c
Documentation/fb/ep93xx-fb.txt [new file with mode: 0644]
Documentation/fb/matroxfb.txt
Documentation/filesystems/ncpfs.txt
Documentation/filesystems/proc.txt
Documentation/gpio.txt
Documentation/ia64/aliasing-test.c
Documentation/pcmcia/crc32hash.c
Documentation/powerpc/dts-bindings/fsl/esdhc.txt
Documentation/rtc.txt
Documentation/spi/spi-summary
Documentation/spi/spidev_test.c
Documentation/sysctl/kernel.txt
Documentation/video4linux/v4lgrab.c
Documentation/vm/page-types.c
Documentation/vm/slabinfo.c
Documentation/watchdog/src/watchdog-test.c
MAINTAINERS
arch/arm/configs/n770_defconfig
arch/arm/configs/omap3_beagle_defconfig
arch/arm/configs/omap_3430sdp_defconfig
arch/arm/configs/omap_ldp_defconfig
arch/arm/mach-at91/Kconfig
arch/arm/mach-at91/Makefile
arch/arm/mach-at91/at91sam9260_devices.c
arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c [new file with mode: 0644]
arch/arm/mach-at91/include/mach/board.h
arch/arm/mach-ep93xx/clock.c
arch/arm/mach-ep93xx/core.c
arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
arch/arm/mach-ep93xx/include/mach/fb.h [new file with mode: 0644]
arch/arm/mach-ep93xx/include/mach/platform.h
arch/arm/mach-omap2/board-rx51-peripherals.c
arch/arm/mach-omap2/devices.c
arch/arm/mach-omap2/mmc-twl4030.c
arch/arm/mach-omap2/mmc-twl4030.h
arch/arm/plat-mxc/include/mach/spi.h [new file with mode: 0644]
arch/arm/plat-omap/include/mach/irqs.h
arch/arm/plat-omap/include/mach/lcd_mipid.h
arch/arm/plat-omap/include/mach/mmc.h
arch/arm/plat-omap/include/mach/omapfb.h
arch/blackfin/include/asm/sections.h
arch/ia64/Kconfig
arch/ia64/mm/init.c
arch/mips/mm/init.c
arch/mn10300/kernel/setup.c
arch/powerpc/boot/dts/mpc8377_mds.dts
arch/powerpc/boot/dts/mpc8377_rdb.dts
arch/powerpc/boot/dts/mpc8377_wlan.dts
arch/powerpc/boot/dts/mpc8378_mds.dts
arch/powerpc/boot/dts/mpc8378_rdb.dts
arch/powerpc/boot/dts/mpc8379_mds.dts
arch/powerpc/boot/dts/mpc8379_rdb.dts
arch/powerpc/kernel/setup-common.c
arch/powerpc/mm/init_32.c
arch/powerpc/mm/init_64.c
arch/powerpc/mm/mem.c
arch/powerpc/platforms/pseries/hvCall_inst.c
arch/sh/mm/init.c
arch/sparc/include/asm/vio.h
arch/x86/Kconfig
arch/x86/include/asm/syscall.h
arch/x86/kernel/ptrace.c
arch/x86/mm/init_32.c
arch/x86/mm/init_64.c
drivers/block/DAC960.c
drivers/block/cciss.c
drivers/char/misc.c
drivers/char/tpm/tpm.c
drivers/char/tpm/tpm_bios.c
drivers/connector/cn_proc.c
drivers/gpio/Kconfig
drivers/gpio/Makefile
drivers/gpio/adp5520-gpio.c [new file with mode: 0644]
drivers/gpio/bt8xxgpio.c
drivers/gpio/gpiolib.c
drivers/gpio/langwell_gpio.c [new file with mode: 0644]
drivers/gpio/max7301.c
drivers/gpio/mc33880.c [new file with mode: 0644]
drivers/gpio/mcp23s08.c
drivers/gpio/pca953x.c
drivers/gpio/pcf857x.c
drivers/gpio/ucb1400_gpio.c [new file with mode: 0644]
drivers/hwmon/adcxx.c
drivers/hwmon/dme1737.c
drivers/hwmon/lis3lv02d_spi.c
drivers/hwmon/lm70.c
drivers/hwmon/max1111.c
drivers/infiniband/hw/ehca/ehca_mrmw.c
drivers/input/touchscreen/ad7877.c
drivers/input/touchscreen/ad7879.c
drivers/input/touchscreen/ads7846.c
drivers/isdn/capi/kcapi_proc.c
drivers/leds/leds-dac124s085.c
drivers/mfd/ezx-pcap.c
drivers/mfd/ucb1400_core.c
drivers/misc/eeprom/at25.c
drivers/misc/lkdtm.c
drivers/mmc/core/core.c
drivers/mmc/core/core.h
drivers/mmc/core/host.c
drivers/mmc/core/host.h
drivers/mmc/core/mmc.c
drivers/mmc/core/mmc_ops.c
drivers/mmc/core/mmc_ops.h
drivers/mmc/core/sd.c
drivers/mmc/core/sdio.c
drivers/mmc/core/sdio_bus.c
drivers/mmc/core/sdio_cis.c
drivers/mmc/core/sdio_io.c
drivers/mmc/host/Kconfig
drivers/mmc/host/Makefile
drivers/mmc/host/atmel-mci.c
drivers/mmc/host/mmc_spi.c
drivers/mmc/host/msm_sdcc.c [new file with mode: 0644]
drivers/mmc/host/msm_sdcc.h [new file with mode: 0644]
drivers/mmc/host/omap_hsmmc.c
drivers/mmc/host/sdhci-of.c
drivers/mmc/host/sdhci-pci.c
drivers/mmc/host/sdhci.c
drivers/mmc/host/sdhci.h
drivers/mtd/devices/mtd_dataflash.c
drivers/net/ehea/ehea_qmr.c
drivers/net/enc28j60.c
drivers/net/ks8851.c
drivers/net/niu.c
drivers/net/wireless/libertas/if_spi.c
drivers/net/wireless/p54/p54spi.c
drivers/net/wireless/wl12xx/wl1251_main.c
drivers/of/base.c
drivers/rtc/Kconfig
drivers/rtc/Makefile
drivers/rtc/rtc-at91rm9200.c
drivers/rtc/rtc-bfin.c
drivers/rtc/rtc-coh901331.c [new file with mode: 0644]
drivers/rtc/rtc-ds1305.c
drivers/rtc/rtc-ds1307.c
drivers/rtc/rtc-ds1390.c
drivers/rtc/rtc-ds3234.c
drivers/rtc/rtc-ep93xx.c
drivers/rtc/rtc-m41t94.c
drivers/rtc/rtc-max6902.c
drivers/rtc/rtc-mxc.c [new file with mode: 0644]
drivers/rtc/rtc-pcap.c [new file with mode: 0644]
drivers/rtc/rtc-pcf2123.c [new file with mode: 0644]
drivers/rtc/rtc-r9701.c
drivers/rtc/rtc-rs5c348.c
drivers/rtc/rtc-stmp3xxx.c [new file with mode: 0644]
drivers/rtc/rtc-sysfs.c
drivers/scsi/sg.c
drivers/serial/max3100.c
drivers/spi/Kconfig
drivers/spi/Makefile
drivers/spi/mxc_spi.c [new file with mode: 0644]
drivers/spi/omap2_mcspi.c
drivers/spi/pxa2xx_spi.c
drivers/spi/spi.c
drivers/spi/spi_imx.c [deleted file]
drivers/spi/spi_ppc4xx.c [new file with mode: 0644]
drivers/spi/spi_s3c24xx.c
drivers/spi/spi_stmp.c [new file with mode: 0644]
drivers/spi/spidev.c
drivers/spi/tle62x0.c
drivers/staging/stlc45xx/stlc45xx.c
drivers/video/Kconfig
drivers/video/Makefile
drivers/video/aty/atyfb_base.c
drivers/video/au1100fb.c
drivers/video/backlight/corgi_lcd.c
drivers/video/backlight/ltv350qv.c
drivers/video/backlight/tdo24m.c
drivers/video/backlight/tosa_lcd.c
drivers/video/backlight/vgg2432a4.c
drivers/video/console/bitblit.c
drivers/video/console/fbcon.c
drivers/video/console/newport_con.c
drivers/video/console/vgacon.c
drivers/video/da8xx-fb.c [new file with mode: 0644]
drivers/video/ep93xx-fb.c [new file with mode: 0644]
drivers/video/fbmem.c
drivers/video/matrox/g450_pll.c
drivers/video/matrox/g450_pll.h
drivers/video/matrox/i2c-matroxfb.c
drivers/video/matrox/matroxfb_DAC1064.c
drivers/video/matrox/matroxfb_DAC1064.h
drivers/video/matrox/matroxfb_Ti3026.c
drivers/video/matrox/matroxfb_accel.c
drivers/video/matrox/matroxfb_accel.h
drivers/video/matrox/matroxfb_base.c
drivers/video/matrox/matroxfb_base.h
drivers/video/matrox/matroxfb_crtc2.c
drivers/video/matrox/matroxfb_g450.c
drivers/video/matrox/matroxfb_g450.h
drivers/video/matrox/matroxfb_maven.c
drivers/video/matrox/matroxfb_misc.c
drivers/video/matrox/matroxfb_misc.h
drivers/video/msm/Makefile [new file with mode: 0644]
drivers/video/msm/mddi.c [new file with mode: 0644]
drivers/video/msm/mddi_client_dummy.c [new file with mode: 0644]
drivers/video/msm/mddi_client_nt35399.c [new file with mode: 0644]
drivers/video/msm/mddi_client_toshiba.c [new file with mode: 0644]
drivers/video/msm/mddi_hw.h [new file with mode: 0644]
drivers/video/msm/mdp.c [new file with mode: 0644]
drivers/video/msm/mdp_csc_table.h [new file with mode: 0644]
drivers/video/msm/mdp_hw.h [new file with mode: 0644]
drivers/video/msm/mdp_ppp.c [new file with mode: 0644]
drivers/video/msm/mdp_scale_tables.c [new file with mode: 0644]
drivers/video/msm/mdp_scale_tables.h [new file with mode: 0644]
drivers/video/msm/msm_fb.c [new file with mode: 0644]
drivers/video/omap/Kconfig
drivers/video/omap/Makefile
drivers/video/omap/blizzard.c
drivers/video/omap/dispc.c
drivers/video/omap/dispc.h
drivers/video/omap/hwa742.c
drivers/video/omap/lcd_2430sdp.c [new file with mode: 0644]
drivers/video/omap/lcd_ams_delta.c [new file with mode: 0644]
drivers/video/omap/lcd_apollon.c [new file with mode: 0644]
drivers/video/omap/lcd_ldp.c [new file with mode: 0644]
drivers/video/omap/lcd_mipid.c [new file with mode: 0644]
drivers/video/omap/lcd_omap2evm.c [new file with mode: 0644]
drivers/video/omap/lcd_omap3beagle.c [new file with mode: 0644]
drivers/video/omap/lcd_omap3evm.c [new file with mode: 0644]
drivers/video/omap/lcd_overo.c [new file with mode: 0644]
drivers/video/omap/omapfb_main.c
drivers/video/omap/rfbi.c
drivers/video/platinumfb.c
drivers/video/s3c-fb.c
drivers/video/s3c2410fb.c
drivers/video/sis/sis_main.c
drivers/video/sis/vstruct.h
drivers/video/tmiofb.c
drivers/video/via/accel.c
drivers/video/via/accel.h
drivers/video/via/chip.h
drivers/video/via/dvi.c
drivers/video/via/global.c
drivers/video/via/global.h
drivers/video/via/hw.c
drivers/video/via/hw.h
drivers/video/via/ioctl.h
drivers/video/via/lcd.c
drivers/video/via/share.h
drivers/video/via/via_i2c.c
drivers/video/via/viafbdev.c
drivers/video/via/viafbdev.h
drivers/video/via/viamode.c
drivers/video/via/viamode.h
drivers/video/via/vt1636.c
drivers/vlynq/vlynq.c
firmware/ihex2fw.c
fs/afs/proc.c
fs/aio.c
fs/anon_inodes.c
fs/buffer.c
fs/compat.c
fs/devpts/inode.c
fs/dlm/debug_fs.c
fs/eventfd.c
fs/exec.c
fs/ext2/namei.c
fs/hugetlbfs/inode.c
fs/inode.c
fs/jbd2/journal.c
fs/minix/dir.c
fs/ncpfs/dir.c
fs/ncpfs/ioctl.c
fs/nfs/client.c
fs/nfsd/export.c
fs/ntfs/file.c
fs/ocfs2/cluster/netdebug.c
fs/ocfs2/dlm/dlmdebug.c
fs/proc/array.c
fs/proc/base.c
fs/proc/kcore.c
fs/proc/nommu.c
fs/proc/task_mmu.c
fs/qnx4/Kconfig
fs/qnx4/Makefile
fs/qnx4/bitmap.c
fs/qnx4/dir.c
fs/qnx4/file.c [deleted file]
fs/qnx4/inode.c
fs/qnx4/namei.c
fs/qnx4/qnx4.h
fs/qnx4/truncate.c [deleted file]
fs/ramfs/inode.c
fs/select.c
fs/smbfs/proc.c
fs/sync.c
include/asm-generic/gpio.h
include/asm-generic/kmap_types.h
include/asm-generic/sections.h
include/asm-generic/syscall.h
include/linux/anon_inodes.h
include/linux/cn_proc.h
include/linux/cpumask.h
include/linux/eventfd.h
include/linux/gfp.h
include/linux/gpio.h
include/linux/ioport.h
include/linux/jbd.h
include/linux/kernel.h
include/linux/kmemcheck.h
include/linux/magic.h
include/linux/memory_hotplug.h
include/linux/mm.h
include/linux/mmc/card.h
include/linux/mmc/core.h
include/linux/mmc/host.h
include/linux/mmc/mmc.h
include/linux/mmc/sdio_func.h
include/linux/mod_devicetable.h
include/linux/nfsd/nfsd.h
include/linux/proc_fs.h
include/linux/sched.h
include/linux/spi/mc33880.h [new file with mode: 0644]
include/linux/spi/spi.h
include/linux/ucb1400.h
include/linux/virtio_config.h
include/video/da8xx-fb.h [new file with mode: 0644]
ipc/util.c
kernel/cgroup.c
kernel/exit.c
kernel/fork.c
kernel/kallsyms.c
kernel/kmod.c
kernel/kprobes.c
kernel/lockdep.c
kernel/lockdep_proc.c
kernel/printk.c
kernel/resource.c
kernel/smp.c
kernel/sys.c
kernel/sysctl.c
kernel/trace/ftrace.c
kernel/trace/trace.c
mm/Makefile
mm/memory_hotplug.c
mm/vmalloc.c
net/ipv6/ip6mr.c
net/socket.c
scripts/conmakehash.c
scripts/genksyms/genksyms.c
scripts/kallsyms.c
scripts/mod/file2alias.c
scripts/mod/modpost.c
scripts/selinux/mdp/mdp.c
security/integrity/ima/ima_fs.c
security/smack/smack_lsm.c
security/smack/smackfs.c
usr/gen_init_cpio.c

index 8aab8092ad35dd4bfc55188e22999651b572b24a..80f4c94c7befdc67e9ecfec2753238ee7811bc1b 100644 (file)
@@ -19,6 +19,7 @@ Description:
        /gpioN ... for each exported GPIO #N
            /value ... always readable, writes fail for input GPIOs
            /direction ... r/w as: in, out (default low); write: high, low
+           /edge ... r/w as: none, falling, rising, both
        /gpiochipN ... for each gpiochip; #N is its first GPIO
            /base ... (r/o) same as N
            /label ... (r/o) descriptive, not necessarily unique
index aa73e72fd793896cbb70fa85505d5f6a7b76d80a..6e25c2659e0af2ab38b1c2cd1d700b129a96a064 100644 (file)
@@ -116,7 +116,7 @@ error:
 }
 
 
-int send_cmd(int sd, __u16 nlmsg_type, __u32 nlmsg_pid,
+static int send_cmd(int sd, __u16 nlmsg_type, __u32 nlmsg_pid,
             __u8 genl_cmd, __u16 nla_type,
             void *nla_data, int nla_len)
 {
@@ -160,7 +160,7 @@ int send_cmd(int sd, __u16 nlmsg_type, __u32 nlmsg_pid,
  * Probe the controller in genetlink to find the family id
  * for the TASKSTATS family
  */
-int get_family_id(int sd)
+static int get_family_id(int sd)
 {
        struct {
                struct nlmsghdr n;
@@ -190,7 +190,7 @@ int get_family_id(int sd)
        return id;
 }
 
-void print_delayacct(struct taskstats *t)
+static void print_delayacct(struct taskstats *t)
 {
        printf("\n\nCPU   %15s%15s%15s%15s\n"
               "      %15llu%15llu%15llu%15llu\n"
@@ -216,7 +216,7 @@ void print_delayacct(struct taskstats *t)
               (unsigned long long)t->freepages_delay_total);
 }
 
-void task_context_switch_counts(struct taskstats *t)
+static void task_context_switch_counts(struct taskstats *t)
 {
        printf("\n\nTask   %15s%15s\n"
               "       %15llu%15llu\n",
@@ -224,7 +224,7 @@ void task_context_switch_counts(struct taskstats *t)
               (unsigned long long)t->nvcsw, (unsigned long long)t->nivcsw);
 }
 
-void print_cgroupstats(struct cgroupstats *c)
+static void print_cgroupstats(struct cgroupstats *c)
 {
        printf("sleeping %llu, blocked %llu, running %llu, stopped %llu, "
                "uninterruptible %llu\n", (unsigned long long)c->nr_sleeping,
@@ -235,7 +235,7 @@ void print_cgroupstats(struct cgroupstats *c)
 }
 
 
-void print_ioacct(struct taskstats *t)
+static void print_ioacct(struct taskstats *t)
 {
        printf("%s: read=%llu, write=%llu, cancelled_write=%llu\n",
                t->ac_comm,
index 2caeea5e49932e1c3e132a55794373c3fe65dbad..1d2c010bae120faacda9f7a40324a3bc3b57a308 100644 (file)
@@ -62,7 +62,7 @@ unsigned char cfag12864b_buffer[CFAG12864B_SIZE];
  * Unable to open: return = -1
  * Unable to mmap: return = -2
  */
-int cfag12864b_init(char *path)
+static int cfag12864b_init(char *path)
 {
        cfag12864b_fd = open(path, O_RDWR);
        if (cfag12864b_fd == -1)
@@ -81,7 +81,7 @@ int cfag12864b_init(char *path)
 /*
  * exit a cfag12864b framebuffer device
  */
-void cfag12864b_exit(void)
+static void cfag12864b_exit(void)
 {
        munmap(cfag12864b_mem, CFAG12864B_SIZE);
        close(cfag12864b_fd);
@@ -90,7 +90,7 @@ void cfag12864b_exit(void)
 /*
  * set (x, y) pixel
  */
-void cfag12864b_set(unsigned char x, unsigned char y)
+static void cfag12864b_set(unsigned char x, unsigned char y)
 {
        if (CFAG12864B_CHECK(x, y))
                cfag12864b_buffer[CFAG12864B_ADDRESS(x, y)] |=
@@ -100,7 +100,7 @@ void cfag12864b_set(unsigned char x, unsigned char y)
 /*
  * unset (x, y) pixel
  */
-void cfag12864b_unset(unsigned char x, unsigned char y)
+static void cfag12864b_unset(unsigned char x, unsigned char y)
 {
        if (CFAG12864B_CHECK(x, y))
                cfag12864b_buffer[CFAG12864B_ADDRESS(x, y)] &=
@@ -113,7 +113,7 @@ void cfag12864b_unset(unsigned char x, unsigned char y)
  * Pixel off: return = 0
  * Pixel on:  return = 1
  */
-unsigned char cfag12864b_isset(unsigned char x, unsigned char y)
+static unsigned char cfag12864b_isset(unsigned char x, unsigned char y)
 {
        if (CFAG12864B_CHECK(x, y))
                if (cfag12864b_buffer[CFAG12864B_ADDRESS(x, y)] &
@@ -126,7 +126,7 @@ unsigned char cfag12864b_isset(unsigned char x, unsigned char y)
 /*
  * not (x, y) pixel
  */
-void cfag12864b_not(unsigned char x, unsigned char y)
+static void cfag12864b_not(unsigned char x, unsigned char y)
 {
        if (cfag12864b_isset(x, y))
                cfag12864b_unset(x, y);
@@ -137,7 +137,7 @@ void cfag12864b_not(unsigned char x, unsigned char y)
 /*
  * fill (set all pixels)
  */
-void cfag12864b_fill(void)
+static void cfag12864b_fill(void)
 {
        unsigned short i;
 
@@ -148,7 +148,7 @@ void cfag12864b_fill(void)
 /*
  * clear (unset all pixels)
  */
-void cfag12864b_clear(void)
+static void cfag12864b_clear(void)
 {
        unsigned short i;
 
@@ -162,7 +162,7 @@ void cfag12864b_clear(void)
  * Pixel off: src[i] = 0
  * Pixel on:  src[i] > 0
  */
-void cfag12864b_format(unsigned char * matrix)
+static void cfag12864b_format(unsigned char * matrix)
 {
        unsigned char i, j, n;
 
@@ -182,7 +182,7 @@ void cfag12864b_format(unsigned char * matrix)
 /*
  * blit buffer to lcd
  */
-void cfag12864b_blit(void)
+static void cfag12864b_blit(void)
 {
        memcpy(cfag12864b_mem, cfag12864b_buffer, CFAG12864B_SIZE);
 }
@@ -198,7 +198,7 @@ void cfag12864b_blit(void)
 
 #define EXAMPLES       6
 
-void example(unsigned char n)
+static void example(unsigned char n)
 {
        unsigned short i, j;
        unsigned char matrix[CFAG12864B_WIDTH * CFAG12864B_HEIGHT];
diff --git a/Documentation/fb/ep93xx-fb.txt b/Documentation/fb/ep93xx-fb.txt
new file mode 100644 (file)
index 0000000..5af1bd9
--- /dev/null
@@ -0,0 +1,135 @@
+================================
+Driver for EP93xx LCD controller
+================================
+
+The EP93xx LCD controller can drive both standard desktop monitors and
+embedded LCD displays. If you have a standard desktop monitor then you
+can use the standard Linux video mode database. In your board file:
+
+       static struct ep93xxfb_mach_info some_board_fb_info = {
+               .num_modes      = EP93XXFB_USE_MODEDB,
+               .bpp            = 16,
+       };
+
+If you have an embedded LCD display then you need to define a video
+mode for it as follows:
+
+       static struct fb_videomode some_board_video_modes[] = {
+               {
+                       .name           = "some_lcd_name",
+                       /* Pixel clock, porches, etc */
+               },
+       };
+
+Note that the pixel clock value is in pico-seconds. You can use the
+KHZ2PICOS macro to convert the pixel clock value. Most other values
+are in pixel clocks. See Documentation/fb/framebuffer.txt for further
+details.
+
+The ep93xxfb_mach_info structure for your board should look like the
+following:
+
+       static struct ep93xxfb_mach_info some_board_fb_info = {
+               .num_modes      = ARRAY_SIZE(some_board_video_modes),
+               .modes          = some_board_video_modes,
+               .default_mode   = &some_board_video_modes[0],
+               .bpp            = 16,
+       };
+
+The framebuffer device can be registered by adding the following to
+your board initialisation function:
+
+       ep93xx_register_fb(&some_board_fb_info);
+
+=====================
+Video Attribute Flags
+=====================
+
+The ep93xxfb_mach_info structure has a flags field which can be used
+to configure the controller. The video attributes flags are fully
+documented in section 7 of the EP93xx users' guide. The following
+flags are available:
+
+EP93XXFB_PCLK_FALLING          Clock data on the falling edge of the
+                               pixel clock. The default is to clock
+                               data on the rising edge.
+
+EP93XXFB_SYNC_BLANK_HIGH       Blank signal is active high. By
+                               default the blank signal is active low.
+
+EP93XXFB_SYNC_HORIZ_HIGH       Horizontal sync is active high. By
+                               default the horizontal sync is active low.
+
+EP93XXFB_SYNC_VERT_HIGH                Vertical sync is active high. By
+                               default the vertical sync is active high.
+
+The physical address of the framebuffer can be controlled using the
+following flags:
+
+EP93XXFB_USE_SDCSN0            Use SDCSn[0] for the framebuffer. This
+                               is the default setting.
+
+EP93XXFB_USE_SDCSN1            Use SDCSn[1] for the framebuffer.
+
+EP93XXFB_USE_SDCSN2            Use SDCSn[2] for the framebuffer.
+
+EP93XXFB_USE_SDCSN3            Use SDCSn[3] for the framebuffer.
+
+==================
+Platform callbacks
+==================
+
+The EP93xx framebuffer driver supports three optional platform
+callbacks: setup, teardown and blank. The setup and teardown functions
+are called when the framebuffer driver is installed and removed
+respectively. The blank function is called whenever the display is
+blanked or unblanked.
+
+The setup and teardown devices pass the platform_device structure as
+an argument. The fb_info and ep93xxfb_mach_info structures can be
+obtained as follows:
+
+       static int some_board_fb_setup(struct platform_device *pdev)
+       {
+               struct ep93xxfb_mach_info *mach_info = pdev->dev.platform_data;
+               struct fb_info *fb_info = platform_get_drvdata(pdev);
+
+               /* Board specific framebuffer setup */
+       }
+
+======================
+Setting the video mode
+======================
+
+The video mode is set using the following syntax:
+
+       video=XRESxYRES[-BPP][@REFRESH]
+
+If the EP93xx video driver is built-in then the video mode is set on
+the Linux kernel command line, for example:
+
+       video=ep93xx-fb:800x600-16@60
+
+If the EP93xx video driver is built as a module then the video mode is
+set when the module is installed:
+
+       modprobe ep93xx-fb video=320x240
+
+==============
+Screenpage bug
+==============
+
+At least on the EP9315 there is a silicon bug which causes bit 27 of
+the VIDSCRNPAGE (framebuffer physical offset) to be tied low. There is
+an unofficial errata for this bug at:
+       http://marc.info/?l=linux-arm-kernel&m=110061245502000&w=2
+
+By default the EP93xx framebuffer driver checks if the allocated physical
+address has bit 27 set. If it does, then the memory is freed and an
+error is returned. The check can be disabled by adding the following
+option when loading the driver:
+
+      ep93xx-fb.check_screenpage_bug=0
+
+In some cases it may be possible to reconfigure your SDRAM layout to
+avoid this bug. See section 13 of the EP93xx users' guide for details.
index ad7a67707d622b36d4dad79c76ae27fd0406a607..e5ce8a1a978bf815654228c9d1a1e92625ffdb05 100644 (file)
@@ -186,9 +186,7 @@ noinverse - show true colors on screen. It is default.
 dev:X    - bind driver to device X. Driver numbers device from 0 up to N,
            where device 0 is first `known' device found, 1 second and so on.
           lspci lists devices in this order.
-          Default is `every' known device for driver with multihead support
-          and first working device (usually dev:0) for driver without
-          multihead support.
+          Default is `every' known device.
 nohwcursor - disables hardware cursor (use software cursor instead).
 hwcursor - enables hardware cursor. It is default. If you are using
            non-accelerated mode (`noaccel' or `fbset -accel false'), software
index f12c30c93f2fff8408a051446d7bf53cc94a4826..5af164f4b37b530fba1ffbb238d0dcd1331c2092 100644 (file)
@@ -7,6 +7,6 @@ ftp.gwdg.de/pub/linux/misc/ncpfs, but sunsite and its many mirrors
 will have it as well.
 
 Related products are linware and mars_nwe, which will give Linux partial
-NetWare server functionality.  Linware's home site is
-klokan.sh.cvut.cz/pub/linux/linware; mars_nwe can be found on
-ftp.gwdg.de/pub/linux/misc/ncpfs.
+NetWare server functionality.
+
+mars_nwe can be found on ftp.gwdg.de/pub/linux/misc/ncpfs.
index 75988ba26a517bdb9f593a9fa131fc9acb67fd59..b5aee7838a001755350d7510de1ebd02f000c95d 100644 (file)
@@ -176,6 +176,7 @@ read the file /proc/PID/status:
   CapBnd: ffffffffffffffff
   voluntary_ctxt_switches:        0
   nonvoluntary_ctxt_switches:     1
+  Stack usage:    12 kB
 
 This shows you nearly the same information you would get if you viewed it with
 the ps  command.  In  fact,  ps  uses  the  proc  file  system  to  obtain its
@@ -229,6 +230,7 @@ Table 1-2: Contents of the statm files (as of 2.6.30-rc7)
  Mems_allowed_list           Same as previous, but in "list format"
  voluntary_ctxt_switches     number of voluntary context switches
  nonvoluntary_ctxt_switches  number of non voluntary context switches
+ Stack usage:                stack usage high water mark (round up to page size)
 ..............................................................................
 
 Table 1-3: Contents of the statm files (as of 2.6.8-rc3)
@@ -307,7 +309,7 @@ address           perms offset  dev   inode      pathname
 08049000-0804a000 rw-p 00001000 03:00 8312       /opt/test
 0804a000-0806b000 rw-p 00000000 00:00 0          [heap]
 a7cb1000-a7cb2000 ---p 00000000 00:00 0
-a7cb2000-a7eb2000 rw-p 00000000 00:00 0
+a7cb2000-a7eb2000 rw-p 00000000 00:00 0          [threadstack:001ff4b4]
 a7eb2000-a7eb3000 ---p 00000000 00:00 0
 a7eb3000-a7ed5000 rw-p 00000000 00:00 0
 a7ed5000-a8008000 r-xp 00000000 03:00 4222       /lib/libc.so.6
@@ -343,6 +345,7 @@ is not associated with a file:
  [stack]                  = the stack of the main process
  [vdso]                   = the "virtual dynamic shared object",
                             the kernel system call handler
+ [threadstack:xxxxxxxx]   = the stack of the thread, xxxxxxxx is the stack size
 
  or if empty, the mapping is anonymous.
 
index e4b6985044a263249976cc0ca985529555007462..fa4dc077ae0eed46adf4a7312f5d033fec717fdf 100644 (file)
@@ -524,6 +524,13 @@ and have the following read/write attributes:
                is configured as an output, this value may be written;
                any nonzero value is treated as high.
 
+       "edge" ... reads as either "none", "rising", "falling", or
+               "both". Write these strings to select the signal edge(s)
+               that will make poll(2) on the "value" file return.
+
+               This file exists only if the pin can be configured as an
+               interrupt generating input pin.
+
 GPIO controllers have paths like /sys/class/gpio/chipchip42/ (for the
 controller implementing GPIOs starting at #42) and have the following
 read-only attributes:
@@ -555,6 +562,11 @@ requested using gpio_request():
        /* reverse gpio_export() */
        void gpio_unexport();
 
+       /* create a sysfs link to an exported GPIO node */
+       int gpio_export_link(struct device *dev, const char *name,
+               unsigned gpio)
+
+
 After a kernel driver requests a GPIO, it may only be made available in
 the sysfs interface by gpio_export().  The driver can control whether the
 signal direction may change.  This helps drivers prevent userspace code
@@ -563,3 +575,8 @@ from accidentally clobbering important system state.
 This explicit exporting can help with debugging (by making some kinds
 of experiments easier), or can provide an always-there interface that's
 suitable for documenting as part of a board support package.
+
+After the GPIO has been exported, gpio_export_link() allows creating
+symlinks from elsewhere in sysfs to the GPIO sysfs node.  Drivers can
+use this to provide the interface under their own device in sysfs with
+a descriptive name.
index d23610fb2ff9e0560580bf4332bc81ea0a249326..3dfb76ca6931dd302e7fe53c57339dd9742511df 100644 (file)
@@ -24,7 +24,7 @@
 
 int sum;
 
-int map_mem(char *path, off_t offset, size_t length, int touch)
+static int map_mem(char *path, off_t offset, size_t length, int touch)
 {
        int fd, rc;
        void *addr;
@@ -62,7 +62,7 @@ int map_mem(char *path, off_t offset, size_t length, int touch)
        return 0;
 }
 
-int scan_tree(char *path, char *file, off_t offset, size_t length, int touch)
+static int scan_tree(char *path, char *file, off_t offset, size_t length, int touch)
 {
        struct dirent **namelist;
        char *name, *path2;
@@ -119,7 +119,7 @@ skip:
 
 char buf[1024];
 
-int read_rom(char *path)
+static int read_rom(char *path)
 {
        int fd, rc;
        size_t size = 0;
@@ -146,7 +146,7 @@ int read_rom(char *path)
        return size;
 }
 
-int scan_rom(char *path, char *file)
+static int scan_rom(char *path, char *file)
 {
        struct dirent **namelist;
        char *name, *path2;
index 4210e5abab8a8b86de57770420ac0cfff96a4b38..44f8beea726040a332c3c9002ea2f1fa0a1f9512 100644 (file)
@@ -8,7 +8,7 @@ $ ./crc32hash "Dual Speed"
 #include <ctype.h>
 #include <stdlib.h>
 
-unsigned int crc32(unsigned char const *p, unsigned int len)
+static unsigned int crc32(unsigned char const *p, unsigned int len)
 {
        int i;
        unsigned int crc = 0;
index 3ed3797b50865fb374f3c36c88b82e03367244da..8a0040738969a222ad1b77527fb053196aff537c 100644 (file)
@@ -10,6 +10,8 @@ Required properties:
   - interrupts : should contain eSDHC interrupt.
   - interrupt-parent : interrupt source phandle.
   - clock-frequency : specifies eSDHC base clock frequency.
+  - sdhci,wp-inverted : (optional) specifies that eSDHC controller
+    reports inverted write-protect state;
   - sdhci,1-bit-only : (optional) specifies that a controller can
     only handle 1-bit data transfers.
 
index 8deffcd68cb8d3fc2737279e780a28bee3726f57..9104c10620840fcc45c47938a1b96dea48309aa7 100644 (file)
@@ -135,6 +135,30 @@ a high functionality RTC is integrated into the SOC.  That system might read
 the system clock from the discrete RTC, but use the integrated one for all
 other tasks, because of its greater functionality.
 
+SYSFS INTERFACE
+---------------
+
+The sysfs interface under /sys/class/rtc/rtcN provides access to various
+rtc attributes without requiring the use of ioctls. All dates and times
+are in the RTC's timezone, rather than in system time.
+
+date:                   RTC-provided date
+hctosys:        1 if the RTC provided the system time at boot via the
+                CONFIG_RTC_HCTOSYS kernel option, 0 otherwise
+max_user_freq:  The maximum interrupt rate an unprivileged user may request
+                from this RTC.
+name:           The name of the RTC corresponding to this sysfs directory
+since_epoch:    The number of seconds since the epoch according to the RTC
+time:           RTC-provided time
+wakealarm:      The time at which the clock will generate a system wakeup
+                event. This is a one shot wakeup event, so must be reset
+                after wake if a daily wakeup is required. Format is either
+                seconds since the epoch or, if there's a leading +, seconds
+                in the future.
+
+IOCTL INTERFACE
+---------------
+
 The ioctl() calls supported by /dev/rtc are also supported by the RTC class
 framework.  However, because the chips and systems are not standardized,
 some PC/AT functionality might not be provided.  And in the same way, some
@@ -185,6 +209,8 @@ driver returns ENOIOCTLCMD.  Some common examples:
        hardware in the irq_set_freq function.  If it isn't, return -EINVAL.  If
        you cannot actually change the frequency, do not define irq_set_freq.
 
+    *  RTC_PIE_ON, RTC_PIE_OFF: the irq_set_state function will be called.
+
 If all else fails, check out the rtc-test.c driver!
 
 
index 4a02d2508bc8b951402bf9ab74411f16da1e1b52..deab51ddc33e1482d65df238568202572b6e3220 100644 (file)
@@ -350,7 +350,7 @@ SPI protocol drivers somewhat resemble platform device drivers:
                .resume         = CHIP_resume,
        };
 
-The driver core will autmatically attempt to bind this driver to any SPI
+The driver core will automatically attempt to bind this driver to any SPI
 device whose board_info gave a modalias of "CHIP".  Your probe() code
 might look like this unless you're creating a device which is managing
 a bus (appearing under /sys/class/spi_master).
index c1a5aad3c75a905d470725fc5795775227c4a4fd..10abd3773e49122aab0dfad27f7cb2c91b8d5d08 100644 (file)
@@ -69,7 +69,7 @@ static void transfer(int fd)
        puts("");
 }
 
-void print_usage(const char *prog)
+static void print_usage(const char *prog)
 {
        printf("Usage: %s [-DsbdlHOLC3]\n", prog);
        puts("  -D --device   device to use (default /dev/spidev1.1)\n"
@@ -85,7 +85,7 @@ void print_usage(const char *prog)
        exit(1);
 }
 
-void parse_opts(int argc, char *argv[])
+static void parse_opts(int argc, char *argv[])
 {
        while (1) {
                static const struct option lopts[] = {
index 3e5b63ebb821b49f55595340aecb9a842ca1c079..b3d8b492274052c8fbb538b1fba96c16a4d64cff 100644 (file)
@@ -313,6 +313,14 @@ send before ratelimiting kicks in.
 
 ==============================================================
 
+printk_delay:
+
+Delay each printk message in printk_delay milliseconds
+
+Value from 0 - 10000 is allowed.
+
+==============================================================
+
 randomize-va-space:
 
 This option can be used to select the type of process address
index 05769cff100998a60ba991325f48f62fe80bc889..c8ded175796ea015a0daeb42416d8926c34f968c 100644 (file)
@@ -89,7 +89,7 @@
        }                                                               \
 }
 
-int get_brightness_adj(unsigned char *image, long size, int *brightness) {
+static int get_brightness_adj(unsigned char *image, long size, int *brightness) {
   long i, tot = 0;
   for (i=0;i<size*3;i++)
     tot += image[i];
index 0833f44ba16bf4b0a2c04f81dfffffb520f2bebb..3eda8ea00852ee7cbeb44ad39a17a74f0d73bcc4 100644 (file)
@@ -158,12 +158,12 @@ static uint64_t   page_flags[HASH_SIZE];
        type __min2 = (y);                      \
        __min1 < __min2 ? __min1 : __min2; })
 
-unsigned long pages2mb(unsigned long pages)
+static unsigned long pages2mb(unsigned long pages)
 {
        return (pages * page_size) >> 20;
 }
 
-void fatal(const char *x, ...)
+static void fatal(const char *x, ...)
 {
        va_list ap;
 
@@ -178,7 +178,7 @@ void fatal(const char *x, ...)
  * page flag names
  */
 
-char *page_flag_name(uint64_t flags)
+static char *page_flag_name(uint64_t flags)
 {
        static char buf[65];
        int present;
@@ -197,7 +197,7 @@ char *page_flag_name(uint64_t flags)
        return buf;
 }
 
-char *page_flag_longname(uint64_t flags)
+static char *page_flag_longname(uint64_t flags)
 {
        static char buf[1024];
        int i, n;
@@ -221,7 +221,7 @@ char *page_flag_longname(uint64_t flags)
  * page list and summary
  */
 
-void show_page_range(unsigned long offset, uint64_t flags)
+static void show_page_range(unsigned long offset, uint64_t flags)
 {
        static uint64_t      flags0;
        static unsigned long index;
@@ -241,12 +241,12 @@ void show_page_range(unsigned long offset, uint64_t flags)
        count  = 1;
 }
 
-void show_page(unsigned long offset, uint64_t flags)
+static void show_page(unsigned long offset, uint64_t flags)
 {
        printf("%lu\t%s\n", offset, page_flag_name(flags));
 }
 
-void show_summary(void)
+static void show_summary(void)
 {
        int i;
 
@@ -272,7 +272,7 @@ void show_summary(void)
  * page flag filters
  */
 
-int bit_mask_ok(uint64_t flags)
+static int bit_mask_ok(uint64_t flags)
 {
        int i;
 
@@ -289,7 +289,7 @@ int bit_mask_ok(uint64_t flags)
        return 1;
 }
 
-uint64_t expand_overloaded_flags(uint64_t flags)
+static uint64_t expand_overloaded_flags(uint64_t flags)
 {
        /* SLOB/SLUB overload several page flags */
        if (flags & BIT(SLAB)) {
@@ -308,7 +308,7 @@ uint64_t expand_overloaded_flags(uint64_t flags)
        return flags;
 }
 
-uint64_t well_known_flags(uint64_t flags)
+static uint64_t well_known_flags(uint64_t flags)
 {
        /* hide flags intended only for kernel hacker */
        flags &= ~KPF_HACKERS_BITS;
@@ -325,7 +325,7 @@ uint64_t well_known_flags(uint64_t flags)
  * page frame walker
  */
 
-int hash_slot(uint64_t flags)
+static int hash_slot(uint64_t flags)
 {
        int k = HASH_KEY(flags);
        int i;
@@ -352,7 +352,7 @@ int hash_slot(uint64_t flags)
        exit(EXIT_FAILURE);
 }
 
-void add_page(unsigned long offset, uint64_t flags)
+static void add_page(unsigned long offset, uint64_t flags)
 {
        flags = expand_overloaded_flags(flags);
 
@@ -371,7 +371,7 @@ void add_page(unsigned long offset, uint64_t flags)
        total_pages++;
 }
 
-void walk_pfn(unsigned long index, unsigned long count)
+static void walk_pfn(unsigned long index, unsigned long count)
 {
        unsigned long batch;
        unsigned long n;
@@ -404,7 +404,7 @@ void walk_pfn(unsigned long index, unsigned long count)
        }
 }
 
-void walk_addr_ranges(void)
+static void walk_addr_ranges(void)
 {
        int i;
 
@@ -428,7 +428,7 @@ void walk_addr_ranges(void)
  * user interface
  */
 
-const char *page_flag_type(uint64_t flag)
+static const char *page_flag_type(uint64_t flag)
 {
        if (flag & KPF_HACKERS_BITS)
                return "(r)";
@@ -437,7 +437,7 @@ const char *page_flag_type(uint64_t flag)
        return "   ";
 }
 
-void usage(void)
+static void usage(void)
 {
        int i, j;
 
@@ -482,7 +482,7 @@ void usage(void)
                "(r) raw mode bits  (o) overloaded bits\n");
 }
 
-unsigned long long parse_number(const char *str)
+static unsigned long long parse_number(const char *str)
 {
        unsigned long long n;
 
@@ -494,16 +494,16 @@ unsigned long long parse_number(const char *str)
        return n;
 }
 
-void parse_pid(const char *str)
+static void parse_pid(const char *str)
 {
        opt_pid = parse_number(str);
 }
 
-void parse_file(const char *name)
+static void parse_file(const char *name)
 {
 }
 
-void add_addr_range(unsigned long offset, unsigned long size)
+static void add_addr_range(unsigned long offset, unsigned long size)
 {
        if (nr_addr_ranges >= MAX_ADDR_RANGES)
                fatal("too much addr ranges\n");
@@ -513,7 +513,7 @@ void add_addr_range(unsigned long offset, unsigned long size)
        nr_addr_ranges++;
 }
 
-void parse_addr_range(const char *optarg)
+static void parse_addr_range(const char *optarg)
 {
        unsigned long offset;
        unsigned long size;
@@ -547,7 +547,7 @@ void parse_addr_range(const char *optarg)
        add_addr_range(offset, size);
 }
 
-void add_bits_filter(uint64_t mask, uint64_t bits)
+static void add_bits_filter(uint64_t mask, uint64_t bits)
 {
        if (nr_bit_filters >= MAX_BIT_FILTERS)
                fatal("too much bit filters\n");
@@ -557,7 +557,7 @@ void add_bits_filter(uint64_t mask, uint64_t bits)
        nr_bit_filters++;
 }
 
-uint64_t parse_flag_name(const char *str, int len)
+static uint64_t parse_flag_name(const char *str, int len)
 {
        int i;
 
@@ -577,7 +577,7 @@ uint64_t parse_flag_name(const char *str, int len)
        return parse_number(str);
 }
 
-uint64_t parse_flag_names(const char *str, int all)
+static uint64_t parse_flag_names(const char *str, int all)
 {
        const char *p    = str;
        uint64_t   flags = 0;
@@ -596,7 +596,7 @@ uint64_t parse_flag_names(const char *str, int all)
        return flags;
 }
 
-void parse_bits_mask(const char *optarg)
+static void parse_bits_mask(const char *optarg)
 {
        uint64_t mask;
        uint64_t bits;
@@ -621,7 +621,7 @@ void parse_bits_mask(const char *optarg)
 }
 
 
-struct option opts[] = {
+static struct option opts[] = {
        { "raw"       , 0, NULL, 'r' },
        { "pid"       , 1, NULL, 'p' },
        { "file"      , 1, NULL, 'f' },
index df3227605d59bf594c3a962a7bf08d9e8d5097a9..92e729f4b676e39851a06760626915950a561035 100644 (file)
@@ -87,7 +87,7 @@ int page_size;
 
 regex_t pattern;
 
-void fatal(const char *x, ...)
+static void fatal(const char *x, ...)
 {
        va_list ap;
 
@@ -97,7 +97,7 @@ void fatal(const char *x, ...)
        exit(EXIT_FAILURE);
 }
 
-void usage(void)
+static void usage(void)
 {
        printf("slabinfo 5/7/2007. (c) 2007 sgi.\n\n"
                "slabinfo [-ahnpvtsz] [-d debugopts] [slab-regexp]\n"
@@ -131,7 +131,7 @@ void usage(void)
        );
 }
 
-unsigned long read_obj(const char *name)
+static unsigned long read_obj(const char *name)
 {
        FILE *f = fopen(name, "r");
 
@@ -151,7 +151,7 @@ unsigned long read_obj(const char *name)
 /*
  * Get the contents of an attribute
  */
-unsigned long get_obj(const char *name)
+static unsigned long get_obj(const char *name)
 {
        if (!read_obj(name))
                return 0;
@@ -159,7 +159,7 @@ unsigned long get_obj(const char *name)
        return atol(buffer);
 }
 
-unsigned long get_obj_and_str(const char *name, char **x)
+static unsigned long get_obj_and_str(const char *name, char **x)
 {
        unsigned long result = 0;
        char *p;
@@ -178,7 +178,7 @@ unsigned long get_obj_and_str(const char *name, char **x)
        return result;
 }
 
-void set_obj(struct slabinfo *s, const char *name, int n)
+static void set_obj(struct slabinfo *s, const char *name, int n)
 {
        char x[100];
        FILE *f;
@@ -192,7 +192,7 @@ void set_obj(struct slabinfo *s, const char *name, int n)
        fclose(f);
 }
 
-unsigned long read_slab_obj(struct slabinfo *s, const char *name)
+static unsigned long read_slab_obj(struct slabinfo *s, const char *name)
 {
        char x[100];
        FILE *f;
@@ -215,7 +215,7 @@ unsigned long read_slab_obj(struct slabinfo *s, const char *name)
 /*
  * Put a size string together
  */
-int store_size(char *buffer, unsigned long value)
+static int store_size(char *buffer, unsigned long value)
 {
        unsigned long divisor = 1;
        char trailer = 0;
@@ -247,7 +247,7 @@ int store_size(char *buffer, unsigned long value)
        return n;
 }
 
-void decode_numa_list(int *numa, char *t)
+static void decode_numa_list(int *numa, char *t)
 {
        int node;
        int nr;
@@ -272,7 +272,7 @@ void decode_numa_list(int *numa, char *t)
        }
 }
 
-void slab_validate(struct slabinfo *s)
+static void slab_validate(struct slabinfo *s)
 {
        if (strcmp(s->name, "*") == 0)
                return;
@@ -280,7 +280,7 @@ void slab_validate(struct slabinfo *s)
        set_obj(s, "validate", 1);
 }
 
-void slab_shrink(struct slabinfo *s)
+static void slab_shrink(struct slabinfo *s)
 {
        if (strcmp(s->name, "*") == 0)
                return;
@@ -290,7 +290,7 @@ void slab_shrink(struct slabinfo *s)
 
 int line = 0;
 
-void first_line(void)
+static void first_line(void)
 {
        if (show_activity)
                printf("Name                   Objects      Alloc       Free   %%Fast Fallb O\n");
@@ -302,7 +302,7 @@ void first_line(void)
 /*
  * Find the shortest alias of a slab
  */
-struct aliasinfo *find_one_alias(struct slabinfo *find)
+static struct aliasinfo *find_one_alias(struct slabinfo *find)
 {
        struct aliasinfo *a;
        struct aliasinfo *best = NULL;
@@ -318,18 +318,18 @@ struct aliasinfo *find_one_alias(struct slabinfo *find)
        return best;
 }
 
-unsigned long slab_size(struct slabinfo *s)
+static unsigned long slab_size(struct slabinfo *s)
 {
        return  s->slabs * (page_size << s->order);
 }
 
-unsigned long slab_activity(struct slabinfo *s)
+static unsigned long slab_activity(struct slabinfo *s)
 {
        return  s->alloc_fastpath + s->free_fastpath +
                s->alloc_slowpath + s->free_slowpath;
 }
 
-void slab_numa(struct slabinfo *s, int mode)
+static void slab_numa(struct slabinfo *s, int mode)
 {
        int node;
 
@@ -374,7 +374,7 @@ void slab_numa(struct slabinfo *s, int mode)
        line++;
 }
 
-void show_tracking(struct slabinfo *s)
+static void show_tracking(struct slabinfo *s)
 {
        printf("\n%s: Kernel object allocation\n", s->name);
        printf("-----------------------------------------------------------------------\n");
@@ -392,7 +392,7 @@ void show_tracking(struct slabinfo *s)
 
 }
 
-void ops(struct slabinfo *s)
+static void ops(struct slabinfo *s)
 {
        if (strcmp(s->name, "*") == 0)
                return;
@@ -405,14 +405,14 @@ void ops(struct slabinfo *s)
                printf("\n%s has no kmem_cache operations\n", s->name);
 }
 
-const char *onoff(int x)
+static const char *onoff(int x)
 {
        if (x)
                return "On ";
        return "Off";
 }
 
-void slab_stats(struct slabinfo *s)
+static void slab_stats(struct slabinfo *s)
 {
        unsigned long total_alloc;
        unsigned long total_free;
@@ -477,7 +477,7 @@ void slab_stats(struct slabinfo *s)
                        s->deactivate_to_tail, (s->deactivate_to_tail * 100) / total);
 }
 
-void report(struct slabinfo *s)
+static void report(struct slabinfo *s)
 {
        if (strcmp(s->name, "*") == 0)
                return;
@@ -518,7 +518,7 @@ void report(struct slabinfo *s)
        slab_stats(s);
 }
 
-void slabcache(struct slabinfo *s)
+static void slabcache(struct slabinfo *s)
 {
        char size_str[20];
        char dist_str[40];
@@ -593,7 +593,7 @@ void slabcache(struct slabinfo *s)
 /*
  * Analyze debug options. Return false if something is amiss.
  */
-int debug_opt_scan(char *opt)
+static int debug_opt_scan(char *opt)
 {
        if (!opt || !opt[0] || strcmp(opt, "-") == 0)
                return 1;
@@ -642,7 +642,7 @@ int debug_opt_scan(char *opt)
        return 1;
 }
 
-int slab_empty(struct slabinfo *s)
+static int slab_empty(struct slabinfo *s)
 {
        if (s->objects > 0)
                return 0;
@@ -657,7 +657,7 @@ int slab_empty(struct slabinfo *s)
        return 1;
 }
 
-void slab_debug(struct slabinfo *s)
+static void slab_debug(struct slabinfo *s)
 {
        if (strcmp(s->name, "*") == 0)
                return;
@@ -717,7 +717,7 @@ void slab_debug(struct slabinfo *s)
                set_obj(s, "trace", 1);
 }
 
-void totals(void)
+static void totals(void)
 {
        struct slabinfo *s;
 
@@ -976,7 +976,7 @@ void totals(void)
                        b1,     b2,     b3);
 }
 
-void sort_slabs(void)
+static void sort_slabs(void)
 {
        struct slabinfo *s1,*s2;
 
@@ -1005,7 +1005,7 @@ void sort_slabs(void)
        }
 }
 
-void sort_aliases(void)
+static void sort_aliases(void)
 {
        struct aliasinfo *a1,*a2;
 
@@ -1030,7 +1030,7 @@ void sort_aliases(void)
        }
 }
 
-void link_slabs(void)
+static void link_slabs(void)
 {
        struct aliasinfo *a;
        struct slabinfo *s;
@@ -1048,7 +1048,7 @@ void link_slabs(void)
        }
 }
 
-void alias(void)
+static void alias(void)
 {
        struct aliasinfo *a;
        char *active = NULL;
@@ -1079,7 +1079,7 @@ void alias(void)
 }
 
 
-void rename_slabs(void)
+static void rename_slabs(void)
 {
        struct slabinfo *s;
        struct aliasinfo *a;
@@ -1102,12 +1102,12 @@ void rename_slabs(void)
        }
 }
 
-int slab_mismatch(char *slab)
+static int slab_mismatch(char *slab)
 {
        return regexec(&pattern, slab, 0, NULL, 0);
 }
 
-void read_slab_dir(void)
+static void read_slab_dir(void)
 {
        DIR *dir;
        struct dirent *de;
@@ -1209,7 +1209,7 @@ void read_slab_dir(void)
                fatal("Too many aliases\n");
 }
 
-void output_slabs(void)
+static void output_slabs(void)
 {
        struct slabinfo *slab;
 
index 65f6c19cb86575e7c43a4ecfabd61be11ccf720e..a750532ffcf8e36d8b5be5ce5324a13384546a7b 100644 (file)
@@ -18,7 +18,7 @@ int fd;
  * the PC Watchdog card to reset its internal timer so it doesn't trigger
  * a computer reset.
  */
-void keep_alive(void)
+static void keep_alive(void)
 {
     int dummy;
 
index 4467da2a4d7a39598cd90070a5c7336bbe9f2c00..ed6cd99a57badb6291c1f702f4446b3a9a4c0ed4 100644 (file)
@@ -3527,7 +3527,6 @@ F:        drivers/net/natsemi.c
 
 NCP FILESYSTEM
 M:     Petr Vandrovec <vandrove@vc.cvut.cz>
-L:     linware@sh.cvut.cz
 S:     Maintained
 F:     fs/ncpfs/
 
@@ -3769,7 +3768,13 @@ OMAP MMC SUPPORT
 M:     Jarkko Lavinen <jarkko.lavinen@nokia.com>
 L:     linux-omap@vger.kernel.org
 S:     Maintained
-F:     drivers/mmc/host/*omap*
+F:     drivers/mmc/host/omap.c
+
+OMAP HS MMC SUPPORT
+M:     Madhusudhan Chikkature <madhu.cr@ti.com>
+L:     linux-omap@vger.kernel.org
+S:     Maintained
+F:     drivers/mmc/host/omap_hsmmc.c
 
 OMAP RANDOM NUMBER GENERATOR SUPPORT
 M:     Deepak Saxena <dsaxena@plexity.net>
index 672f6db06a52d00bd3aac41b1cd9aa2e1b0b19ad..a1657b73683fb0ab56f53a522ce89c7a73ef1658 100644 (file)
@@ -875,7 +875,7 @@ CONFIG_FB_OMAP_LCDC_EXTERNAL=y
 CONFIG_FB_OMAP_LCDC_HWA742=y
 # CONFIG_FB_OMAP_LCDC_BLIZZARD is not set
 CONFIG_FB_OMAP_MANUAL_UPDATE=y
-# CONFIG_FB_OMAP_LCD_MIPID is not set
+CONFIG_FB_OMAP_LCD_MIPID=y
 # CONFIG_FB_OMAP_BOOTLOADER_INIT is not set
 CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE=2
 # CONFIG_FB_OMAP_DMA_TUNE is not set
index 51c0fa8897cd87ef0abcf0fcef46803dbcca061b..357d4021e2d0f50602c0545b8a63ee74e40257ca 100644 (file)
@@ -778,7 +778,33 @@ CONFIG_DAB=y
 #
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
-# CONFIG_FB is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_FB_OMAP=y
+# CONFIG_FB_OMAP_LCDC_EXTERNAL is not set
+# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set
+CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE=2
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -791,6 +817,25 @@ CONFIG_DAB=y
 #
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+# CONFIG_LOGO is not set
+
+#
+# Sound
+#
 # CONFIG_SOUND is not set
 # CONFIG_HID_SUPPORT is not set
 CONFIG_USB_SUPPORT=y
index 9a510eab75a6066498f7e1b690ae07ffce2d2f84..8a4a7e2ba87b8d7136810fbd4fce6482a3b2f1ed 100644 (file)
@@ -1313,8 +1313,33 @@ CONFIG_DVB_ISL6421=m
 # Graphics support
 #
 # CONFIG_VGASTATE is not set
-# CONFIG_VIDEO_OUTPUT_CONTROL is not set
-# CONFIG_FB is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_FB_OMAP=y
+# CONFIG_FB_OMAP_LCDC_EXTERNAL is not set
+# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set
+CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE=2
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -1331,6 +1356,16 @@ CONFIG_DISPLAY_SUPPORT=y
 #
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
 CONFIG_SOUND=y
 CONFIG_SOUND_OSS_CORE=y
 CONFIG_SND=y
index 679a4a3e265e8222f91c67a17ab58d838a1dddb0..b9c48919a68c95e0ed0d47b085d75b6890172255 100644 (file)
@@ -690,6 +690,7 @@ CONFIG_GPIOLIB=y
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+CONFIG_GPIO_TWL4030=y
 
 #
 # PCI GPIO expanders:
@@ -742,6 +743,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_EGPIO is not set
 # CONFIG_HTC_PASIC3 is not set
+CONFIG_TWL4030_CORE=y
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_T7L66XB is not set
 # CONFIG_MFD_TC6387XB is not set
@@ -767,8 +769,46 @@ CONFIG_DAB=y
 #
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
-# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+CONFIG_FB=y
+CONFIG_FIRMWARE_EDID=y
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+CONFIG_FB_OMAP=y
+CONFIG_FB_OMAP_LCD_VGA=y
+# CONFIG_FB_OMAP_LCDC_EXTERNAL is not set
+# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set
+CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE=4
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+# CONFIG_LCD_LTV350QV is not set
+# CONFIG_LCD_ILI9320 is not set
+# CONFIG_LCD_TDO24M is not set
+# CONFIG_LCD_VGG2432A4 is not set
+CONFIG_LCD_PLATFORM=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_CORGI is not set
+# CONFIG_BACKLIGHT_GENERIC is not set
 
 #
 # Display device support
@@ -780,6 +820,16 @@ CONFIG_VIDEO_OUTPUT_CONTROL=m
 #
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
 CONFIG_SOUND=y
 CONFIG_SND=y
 # CONFIG_SND_SEQUENCER is not set
index a24d824c428b3cf1e3aa45c31a7f53f8bb9a7d2d..e35d54d43e709d52a3d025165c17cee01da8fc69 100644 (file)
@@ -289,6 +289,13 @@ config MACH_NEOCORE926
        help
          Select this if you are using the Adeneo Neocore 926 board.
 
+config MACH_AT91SAM9G20EK_2MMC
+       bool "Atmel AT91SAM9G20-EK Evaluation Kit modified for 2 MMC Slots"
+       depends on ARCH_AT91SAM9G20
+       help
+         Select this if you are using an Atmel AT91SAM9G20-EK Evaluation Kit
+         Rev A or B modified for 2 MMC Slots.
+
 endif
 
 # ----------------------------------------------------------
index a6ed015d82edc9822f92a57a72ead4cf22760095..ada440aab0c5ab2a7597733ac529e26aea5c0c32 100644 (file)
@@ -59,6 +59,7 @@ obj-$(CONFIG_MACH_AT91SAM9RLEK)       += board-sam9rlek.o
 
 # AT91SAM9G20 board-specific support
 obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o
+obj-$(CONFIG_MACH_AT91SAM9G20EK_2MMC) += board-sam9g20ek-2slot-mmc.o
 obj-$(CONFIG_MACH_CPU9G20)     += board-cpu9krea.o
 
 # AT91SAM9G45 board-specific support
index ee4ea0e720cf14239dedbece059d24c9c20c0f54..07eb7b07e442a69c9499b71cf49387f6ecd240e6 100644 (file)
@@ -278,6 +278,102 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
 void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
 #endif
 
+/* --------------------------------------------------------------------
+ *  MMC / SD Slot for Atmel MCI Driver
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
+static u64 mmc_dmamask = DMA_BIT_MASK(32);
+static struct mci_platform_data mmc_data;
+
+static struct resource mmc_resources[] = {
+       [0] = {
+               .start  = AT91SAM9260_BASE_MCI,
+               .end    = AT91SAM9260_BASE_MCI + SZ_16K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = AT91SAM9260_ID_MCI,
+               .end    = AT91SAM9260_ID_MCI,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device at91sam9260_mmc_device = {
+       .name           = "atmel_mci",
+       .id             = -1,
+       .dev            = {
+                               .dma_mask               = &mmc_dmamask,
+                               .coherent_dma_mask      = DMA_BIT_MASK(32),
+                               .platform_data          = &mmc_data,
+       },
+       .resource       = mmc_resources,
+       .num_resources  = ARRAY_SIZE(mmc_resources),
+};
+
+void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data)
+{
+       unsigned int i;
+       unsigned int slot_count = 0;
+
+       if (!data)
+               return;
+
+       for (i = 0; i < ATMEL_MCI_MAX_NR_SLOTS; i++) {
+               if (data->slot[i].bus_width) {
+                       /* input/irq */
+                       if (data->slot[i].detect_pin) {
+                               at91_set_gpio_input(data->slot[i].detect_pin, 1);
+                               at91_set_deglitch(data->slot[i].detect_pin, 1);
+                       }
+                       if (data->slot[i].wp_pin)
+                               at91_set_gpio_input(data->slot[i].wp_pin, 1);
+
+                       switch (i) {
+                       case 0:
+                               /* CMD */
+                               at91_set_A_periph(AT91_PIN_PA7, 1);
+                               /* DAT0, maybe DAT1..DAT3 */
+                               at91_set_A_periph(AT91_PIN_PA6, 1);
+                               if (data->slot[i].bus_width == 4) {
+                                       at91_set_A_periph(AT91_PIN_PA9, 1);
+                                       at91_set_A_periph(AT91_PIN_PA10, 1);
+                                       at91_set_A_periph(AT91_PIN_PA11, 1);
+                               }
+                               slot_count++;
+                               break;
+                       case 1:
+                               /* CMD */
+                               at91_set_B_periph(AT91_PIN_PA1, 1);
+                               /* DAT0, maybe DAT1..DAT3 */
+                               at91_set_B_periph(AT91_PIN_PA0, 1);
+                               if (data->slot[i].bus_width == 4) {
+                                       at91_set_B_periph(AT91_PIN_PA5, 1);
+                                       at91_set_B_periph(AT91_PIN_PA4, 1);
+                                       at91_set_B_periph(AT91_PIN_PA3, 1);
+                               }
+                               slot_count++;
+                               break;
+                       default:
+                               printk(KERN_ERR
+                                       "AT91: SD/MMC slot %d not available\n", i);
+                               break;
+                       }
+               }
+       }
+
+       if (slot_count) {
+               /* CLK */
+               at91_set_A_periph(AT91_PIN_PA8, 0);
+
+               mmc_data = *data;
+               platform_device_register(&at91sam9260_mmc_device);
+       }
+}
+#else
+void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) {}
+#endif
+
 
 /* --------------------------------------------------------------------
  *  NAND / SmartMedia
diff --git a/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c b/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c
new file mode 100644 (file)
index 0000000..a28e53f
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+ *  Copyright (C) 2005 SAN People
+ *  Copyright (C) 2008 Atmel
+ *  Copyright (C) 2009 Rob Emanuele
+ *
+ * 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/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/at73c213.h>
+#include <linux/clk.h>
+
+#include <mach/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91sam9_smc.h>
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+
+static void __init ek_map_io(void)
+{
+       /* Initialize processor: 18.432 MHz crystal */
+       at91sam9260_initialize(18432000);
+
+       /* DGBU on ttyS0. (Rx & Tx only) */
+       at91_register_uart(0, 0, 0);
+
+       /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+       at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+                          | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
+                          | ATMEL_UART_RI);
+
+       /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */
+       at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+       /* set serial console to ttyS0 (ie, DBGU) */
+       at91_set_serial_console(0);
+}
+
+static void __init ek_init_irq(void)
+{
+       at91sam9260_init_interrupts(NULL);
+}
+
+
+/*
+ * USB Host port
+ */
+static struct at91_usbh_data __initdata ek_usbh_data = {
+       .ports          = 2,
+};
+
+/*
+ * USB Device port
+ */
+static struct at91_udc_data __initdata ek_udc_data = {
+       .vbus_pin       = AT91_PIN_PC5,
+       .pullup_pin     = 0,            /* pull-up driven by UDC */
+};
+
+
+/*
+ * SPI devices.
+ */
+static struct spi_board_info ek_spi_devices[] = {
+#if !defined(CONFIG_MMC_ATMELMCI)
+       {       /* DataFlash chip */
+               .modalias       = "mtd_dataflash",
+               .chip_select    = 1,
+               .max_speed_hz   = 15 * 1000 * 1000,
+               .bus_num        = 0,
+       },
+#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD)
+       {       /* DataFlash card */
+               .modalias       = "mtd_dataflash",
+               .chip_select    = 0,
+               .max_speed_hz   = 15 * 1000 * 1000,
+               .bus_num        = 0,
+       },
+#endif
+#endif
+};
+
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata ek_macb_data = {
+       .phy_irq_pin    = AT91_PIN_PC12,
+       .is_rmii        = 1,
+};
+
+
+/*
+ * NAND flash
+ */
+static struct mtd_partition __initdata ek_nand_partition[] = {
+       {
+               .name   = "Bootstrap",
+               .offset = 0,
+               .size   = 4 * SZ_1M,
+       },
+       {
+               .name   = "Partition 1",
+               .offset = MTDPART_OFS_NXTBLK,
+               .size   = 60 * SZ_1M,
+       },
+       {
+               .name   = "Partition 2",
+               .offset = MTDPART_OFS_NXTBLK,
+               .size   = MTDPART_SIZ_FULL,
+       },
+};
+
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
+{
+       *num_partitions = ARRAY_SIZE(ek_nand_partition);
+       return ek_nand_partition;
+}
+
+/* det_pin is not connected */
+static struct atmel_nand_data __initdata ek_nand_data = {
+       .ale            = 21,
+       .cle            = 22,
+       .rdy_pin        = AT91_PIN_PC13,
+       .enable_pin     = AT91_PIN_PC14,
+       .partition_info = nand_partitions,
+#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
+       .bus_width_16   = 1,
+#else
+       .bus_width_16   = 0,
+#endif
+};
+
+static struct sam9_smc_config __initdata ek_nand_smc_config = {
+       .ncs_read_setup         = 0,
+       .nrd_setup              = 2,
+       .ncs_write_setup        = 0,
+       .nwe_setup              = 2,
+
+       .ncs_read_pulse         = 4,
+       .nrd_pulse              = 4,
+       .ncs_write_pulse        = 4,
+       .nwe_pulse              = 4,
+
+       .read_cycle             = 7,
+       .write_cycle            = 7,
+
+       .mode                   = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE,
+       .tdf_cycles             = 3,
+};
+
+static void __init ek_add_device_nand(void)
+{
+       /* setup bus-width (8 or 16) */
+       if (ek_nand_data.bus_width_16)
+               ek_nand_smc_config.mode |= AT91_SMC_DBW_16;
+       else
+               ek_nand_smc_config.mode |= AT91_SMC_DBW_8;
+
+       /* configure chip-select 3 (NAND) */
+       sam9_smc_configure(3, &ek_nand_smc_config);
+
+       at91_add_device_nand(&ek_nand_data);
+}
+
+
+/*
+ * MCI (SD/MMC)
+ * det_pin and wp_pin are not connected
+ */
+#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
+static struct mci_platform_data __initdata ek_mmc_data = {
+       .slot[0] = {
+               .bus_width      = 4,
+               .detect_pin     = -ENODEV,
+               .wp_pin         = -ENODEV,
+       },
+       .slot[1] = {
+               .bus_width      = 4,
+               .detect_pin     = -ENODEV,
+               .wp_pin         = -ENODEV,
+       },
+
+};
+#else
+static struct amci_platform_data __initdata ek_mmc_data = {
+};
+#endif
+
+/*
+ * LEDs
+ */
+static struct gpio_led ek_leds[] = {
+       {       /* "bottom" led, green, userled1 to be defined */
+               .name                   = "ds5",
+               .gpio                   = AT91_PIN_PB12,
+               .active_low             = 1,
+               .default_trigger        = "none",
+       },
+       {       /* "power" led, yellow */
+               .name                   = "ds1",
+               .gpio                   = AT91_PIN_PB13,
+               .default_trigger        = "heartbeat",
+       }
+};
+
+static struct i2c_board_info __initdata ek_i2c_devices[] = {
+       {
+               I2C_BOARD_INFO("24c512", 0x50),
+       },
+};
+
+
+static void __init ek_board_init(void)
+{
+       /* Serial */
+       at91_add_device_serial();
+       /* USB Host */
+       at91_add_device_usbh(&ek_usbh_data);
+       /* USB Device */
+       at91_add_device_udc(&ek_udc_data);
+       /* SPI */
+       at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
+       /* NAND */
+       ek_add_device_nand();
+       /* Ethernet */
+       at91_add_device_eth(&ek_macb_data);
+       /* MMC */
+       at91_add_device_mci(0, &ek_mmc_data);
+       /* I2C */
+       at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices));
+       /* LEDs */
+       at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+       /* PCK0 provides MCLK to the WM8731 */
+       at91_set_B_periph(AT91_PIN_PC1, 0);
+       /* SSC (for WM8731) */
+       at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX);
+}
+
+MACHINE_START(AT91SAM9G20EK_2MMC, "Atmel AT91SAM9G20-EK 2 MMC Slot Mod")
+       /* Maintainer: Rob Emanuele */
+       .phys_io        = AT91_BASE_SYS,
+       .io_pg_offst    = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
+       .boot_params    = AT91_SDRAM_BASE + 0x100,
+       .timer          = &at91sam926x_timer,
+       .map_io         = ek_map_io,
+       .init_irq       = ek_init_irq,
+       .init_machine   = ek_board_init,
+MACHINE_END
index 13f27a4b882d10aef10df715f8f846dd06920d4d..583f38a38df708862c8cada64d743ed2c6dd4959 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/leds.h>
 #include <linux/spi/spi.h>
 #include <linux/usb/atmel_usba_udc.h>
+#include <linux/atmel-mci.h>
 #include <sound/atmel-ac97c.h>
 
  /* USB Device */
@@ -64,6 +65,7 @@ struct at91_cf_data {
 extern void __init at91_add_device_cf(struct at91_cf_data *data);
 
  /* MMC / SD */
+  /* at91_mci platform config */
 struct at91_mmc_data {
        u8              det_pin;        /* card detect IRQ */
        unsigned        slot_b:1;       /* uses Slot B */
@@ -73,6 +75,9 @@ struct at91_mmc_data {
 };
 extern void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data);
 
+  /* atmel-mci platform config */
+extern void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data);
+
  /* Ethernet (EMAC & MACB) */
 struct at91_eth_data {
        u32             phy_mask;
index 3dd0e2a23095c8c6b57ed493baf5e2655c7a6d63..dda19cd76194fd4334785dea7af869713d6db467 100644 (file)
@@ -37,7 +37,7 @@ struct clk {
 static unsigned long get_uart_rate(struct clk *clk);
 
 static int set_keytchclk_rate(struct clk *clk, unsigned long rate);
-
+static int set_div_rate(struct clk *clk, unsigned long rate);
 
 static struct clk clk_uart1 = {
        .sw_locked      = 1,
@@ -76,6 +76,13 @@ static struct clk clk_pwm = {
        .rate           = EP93XX_EXT_CLK_RATE,
 };
 
+static struct clk clk_video = {
+       .sw_locked      = 1,
+       .enable_reg     = EP93XX_SYSCON_VIDCLKDIV,
+       .enable_mask    = EP93XX_SYSCON_CLKDIV_ENABLE,
+       .set_rate       = set_div_rate,
+};
+
 /* DMA Clocks */
 static struct clk clk_m2p0 = {
        .enable_reg     = EP93XX_SYSCON_PWRCNT,
@@ -140,6 +147,7 @@ static struct clk_lookup clocks[] = {
        INIT_CK(NULL,                   "pll2",         &clk_pll2),
        INIT_CK("ep93xx-ohci",          NULL,           &clk_usb_host),
        INIT_CK("ep93xx-keypad",        NULL,           &clk_keypad),
+       INIT_CK("ep93xx-fb",            NULL,           &clk_video),
        INIT_CK(NULL,                   "pwm_clk",      &clk_pwm),
        INIT_CK(NULL,                   "m2p0",         &clk_m2p0),
        INIT_CK(NULL,                   "m2p1",         &clk_m2p1),
@@ -236,6 +244,84 @@ static int set_keytchclk_rate(struct clk *clk, unsigned long rate)
        return 0;
 }
 
+static unsigned long calc_clk_div(unsigned long rate, int *psel, int *esel,
+                                 int *pdiv, int *div)
+{
+       unsigned long max_rate, best_rate = 0,
+               actual_rate = 0, mclk_rate = 0, rate_err = -1;
+       int i, found = 0, __div = 0, __pdiv = 0;
+
+       /* Don't exceed the maximum rate */
+       max_rate = max(max(clk_pll1.rate / 4, clk_pll2.rate / 4),
+                      (unsigned long)EP93XX_EXT_CLK_RATE / 4);
+       rate = min(rate, max_rate);
+
+       /*
+        * Try the two pll's and the external clock
+        * Because the valid predividers are 2, 2.5 and 3, we multiply
+        * all the clocks by 2 to avoid floating point math.
+        *
+        * This is based on the algorithm in the ep93xx raster guide:
+        * http://be-a-maverick.com/en/pubs/appNote/AN269REV1.pdf
+        *
+        */
+       for (i = 0; i < 3; i++) {
+               if (i == 0)
+                       mclk_rate = EP93XX_EXT_CLK_RATE * 2;
+               else if (i == 1)
+                       mclk_rate = clk_pll1.rate * 2;
+               else if (i == 2)
+                       mclk_rate = clk_pll2.rate * 2;
+
+               /* Try each predivider value */
+               for (__pdiv = 4; __pdiv <= 6; __pdiv++) {
+                       __div = mclk_rate / (rate * __pdiv);
+                       if (__div < 2 || __div > 127)
+                               continue;
+
+                       actual_rate = mclk_rate / (__pdiv * __div);
+
+                       if (!found || abs(actual_rate - rate) < rate_err) {
+                               *pdiv = __pdiv - 3;
+                               *div = __div;
+                               *psel = (i == 2);
+                               *esel = (i != 0);
+                               best_rate = actual_rate;
+                               rate_err = abs(actual_rate - rate);
+                               found = 1;
+                       }
+               }
+       }
+
+       if (!found)
+               return 0;
+
+       return best_rate;
+}
+
+static int set_div_rate(struct clk *clk, unsigned long rate)
+{
+       unsigned long actual_rate;
+       int psel = 0, esel = 0, pdiv = 0, div = 0;
+       u32 val;
+
+       actual_rate = calc_clk_div(rate, &psel, &esel, &pdiv, &div);
+       if (actual_rate == 0)
+               return -EINVAL;
+       clk->rate = actual_rate;
+
+       /* Clear the esel, psel, pdiv and div bits */
+       val = __raw_readl(clk->enable_reg);
+       val &= ~0x7fff;
+
+       /* Set the new esel, psel, pdiv and div bits for the new clock rate */
+       val |= (esel ? EP93XX_SYSCON_CLKDIV_ESEL : 0) |
+               (psel ? EP93XX_SYSCON_CLKDIV_PSEL : 0) |
+               (pdiv << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | div;
+       ep93xx_syscon_swlocked_write(val, clk->enable_reg);
+       return 0;
+}
+
 int clk_set_rate(struct clk *clk, unsigned long rate)
 {
        if (clk->set_rate)
index 16b92c37ec99a7107ec29ef51103a67ba0c4c191..f7ebed942f662fda227c002a4998091f02616de4 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/i2c-gpio.h>
 
 #include <mach/hardware.h>
+#include <mach/fb.h>
 
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
@@ -682,6 +683,37 @@ void ep93xx_pwm_release_gpio(struct platform_device *pdev)
 EXPORT_SYMBOL(ep93xx_pwm_release_gpio);
 
 
+/*************************************************************************
+ * EP93xx video peripheral handling
+ *************************************************************************/
+static struct ep93xxfb_mach_info ep93xxfb_data;
+
+static struct resource ep93xx_fb_resource[] = {
+       {
+               .start          = EP93XX_RASTER_PHYS_BASE,
+               .end            = EP93XX_RASTER_PHYS_BASE + 0x800 - 1,
+               .flags          = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device ep93xx_fb_device = {
+       .name                   = "ep93xx-fb",
+       .id                     = -1,
+       .dev                    = {
+               .platform_data  = &ep93xxfb_data,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+               .dma_mask               = &ep93xx_fb_device.dev.coherent_dma_mask,
+       },
+       .num_resources          = ARRAY_SIZE(ep93xx_fb_resource),
+       .resource               = ep93xx_fb_resource,
+};
+
+void __init ep93xx_register_fb(struct ep93xxfb_mach_info *data)
+{
+       ep93xxfb_data = *data;
+       platform_device_register(&ep93xx_fb_device);
+}
+
 extern void ep93xx_gpio_init(void);
 
 void __init ep93xx_init_devices(void)
index ea78e908fc82cecc9bf7c32ccbf2fe597785bf2e..0fbf87b163385296ee932644d54a6875cfd7bdc3 100644 (file)
@@ -70,6 +70,7 @@
 #define EP93XX_USB_PHYS_BASE           (EP93XX_AHB_PHYS_BASE + 0x00020000)
 #define EP93XX_USB_BASE                        EP93XX_AHB_IOMEM(0x00020000)
 
+#define EP93XX_RASTER_PHYS_BASE                (EP93XX_AHB_PHYS_BASE + 0x00030000)
 #define EP93XX_RASTER_BASE             EP93XX_AHB_IOMEM(0x00030000)
 
 #define EP93XX_GRAPHICS_ACCEL_BASE     EP93XX_AHB_IOMEM(0x00040000)
 #define EP93XX_SYSCON_DEVCFG_ADCPD     (1<<2)
 #define EP93XX_SYSCON_DEVCFG_KEYS      (1<<1)
 #define EP93XX_SYSCON_DEVCFG_SHENA     (1<<0)
+#define EP93XX_SYSCON_VIDCLKDIV                EP93XX_SYSCON_REG(0x84)
+#define EP93XX_SYSCON_CLKDIV_ENABLE    (1<<15)
+#define EP93XX_SYSCON_CLKDIV_ESEL      (1<<14)
+#define EP93XX_SYSCON_CLKDIV_PSEL      (1<<13)
+#define EP93XX_SYSCON_CLKDIV_PDIV_SHIFT        8
 #define EP93XX_SYSCON_KEYTCHCLKDIV     EP93XX_SYSCON_REG(0x90)
 #define EP93XX_SYSCON_KEYTCHCLKDIV_TSEN        (1<<31)
 #define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV        (1<<16)
diff --git a/arch/arm/mach-ep93xx/include/mach/fb.h b/arch/arm/mach-ep93xx/include/mach/fb.h
new file mode 100644 (file)
index 0000000..d5ae11d
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * arch/arm/mach-ep93xx/include/mach/fb.h
+ */
+
+#ifndef __ASM_ARCH_EP93XXFB_H
+#define __ASM_ARCH_EP93XXFB_H
+
+struct platform_device;
+struct fb_videomode;
+struct fb_info;
+
+#define EP93XXFB_USE_MODEDB            0
+
+/* VideoAttributes flags */
+#define EP93XXFB_STATE_MACHINE_ENABLE  (1 << 0)
+#define EP93XXFB_PIXEL_CLOCK_ENABLE    (1 << 1)
+#define EP93XXFB_VSYNC_ENABLE          (1 << 2)
+#define EP93XXFB_PIXEL_DATA_ENABLE     (1 << 3)
+#define EP93XXFB_COMPOSITE_SYNC                (1 << 4)
+#define EP93XXFB_SYNC_VERT_HIGH                (1 << 5)
+#define EP93XXFB_SYNC_HORIZ_HIGH       (1 << 6)
+#define EP93XXFB_SYNC_BLANK_HIGH       (1 << 7)
+#define EP93XXFB_PCLK_FALLING          (1 << 8)
+#define EP93XXFB_ENABLE_AC             (1 << 9)
+#define EP93XXFB_ENABLE_LCD            (1 << 10)
+#define EP93XXFB_ENABLE_CCIR           (1 << 12)
+#define EP93XXFB_USE_PARALLEL_INTERFACE        (1 << 13)
+#define EP93XXFB_ENABLE_INTERRUPT      (1 << 14)
+#define EP93XXFB_USB_INTERLACE         (1 << 16)
+#define EP93XXFB_USE_EQUALIZATION      (1 << 17)
+#define EP93XXFB_USE_DOUBLE_HORZ       (1 << 18)
+#define EP93XXFB_USE_DOUBLE_VERT       (1 << 19)
+#define EP93XXFB_USE_BLANK_PIXEL       (1 << 20)
+#define EP93XXFB_USE_SDCSN0            (0 << 21)
+#define EP93XXFB_USE_SDCSN1            (1 << 21)
+#define EP93XXFB_USE_SDCSN2            (2 << 21)
+#define EP93XXFB_USE_SDCSN3            (3 << 21)
+
+#define EP93XXFB_ENABLE                        (EP93XXFB_STATE_MACHINE_ENABLE  | \
+                                        EP93XXFB_PIXEL_CLOCK_ENABLE    | \
+                                        EP93XXFB_VSYNC_ENABLE          | \
+                                        EP93XXFB_PIXEL_DATA_ENABLE)
+
+struct ep93xxfb_mach_info {
+       unsigned int                    num_modes;
+       const struct fb_videomode       *modes;
+       const struct fb_videomode       *default_mode;
+       int                             bpp;
+       unsigned int                    flags;
+
+       int     (*setup)(struct platform_device *pdev);
+       void    (*teardown)(struct platform_device *pdev);
+       void    (*blank)(int blank_mode, struct fb_info *info);
+};
+
+#endif /* __ASM_ARCH_EP93XXFB_H */
index 5f5fa6574d342c28eacf06dde9a4550575358a46..01a0f0838e5b3d012a1c7aa1e94e4a70011464ae 100644 (file)
@@ -6,6 +6,7 @@
 
 struct i2c_board_info;
 struct platform_device;
+struct ep93xxfb_mach_info;
 
 struct ep93xx_eth_data
 {
@@ -33,6 +34,7 @@ static inline void ep93xx_devcfg_clear_bits(unsigned int bits)
 
 void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr);
 void ep93xx_register_i2c(struct i2c_board_info *devices, int num);
+void ep93xx_register_fb(struct ep93xxfb_mach_info *data);
 void ep93xx_register_pwm(int pwm0, int pwm1);
 int ep93xx_pwm_acquire_gpio(struct platform_device *pdev);
 void ep93xx_pwm_release_gpio(struct platform_device *pdev);
index e70baa79901860d7b61b3ebec4ad02bfee45fe77..e6e8290b7828613fd631abd6556f531f2c27852e 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/delay.h>
 #include <linux/regulator/machine.h>
 #include <linux/gpio.h>
+#include <linux/mmc/host.h>
 
 #include <mach/mcspi.h>
 #include <mach/mux.h>
@@ -102,6 +103,7 @@ static struct twl4030_hsmmc_info mmc[] = {
                .cover_only     = true,
                .gpio_cd        = 160,
                .gpio_wp        = -EINVAL,
+               .power_saving   = true,
        },
        {
                .name           = "internal",
@@ -109,6 +111,8 @@ static struct twl4030_hsmmc_info mmc[] = {
                .wires          = 8,
                .gpio_cd        = -EINVAL,
                .gpio_wp        = -EINVAL,
+               .nonremovable   = true,
+               .power_saving   = true,
        },
        {}      /* Terminator */
 };
index a2e915639b7222851b7c80e054e7da42aee6078f..bcfcfc7fdb9bffe60d95a8865498cf72c7b5f0f3 100644 (file)
@@ -257,6 +257,11 @@ static inline void omap_init_sti(void) {}
 #define OMAP2_MCSPI3_BASE              0x480b8000
 #define OMAP2_MCSPI4_BASE              0x480ba000
 
+#define OMAP4_MCSPI1_BASE              0x48098100
+#define OMAP4_MCSPI2_BASE              0x4809a100
+#define OMAP4_MCSPI3_BASE              0x480b8100
+#define OMAP4_MCSPI4_BASE              0x480ba100
+
 static struct omap2_mcspi_platform_config omap2_mcspi1_config = {
        .num_cs         = 4,
 };
@@ -301,7 +306,8 @@ static struct platform_device omap2_mcspi2 = {
        },
 };
 
-#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3)
+#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \
+       defined(CONFIG_ARCH_OMAP4)
 static struct omap2_mcspi_platform_config omap2_mcspi3_config = {
        .num_cs         = 2,
 };
@@ -325,7 +331,7 @@ static struct platform_device omap2_mcspi3 = {
 };
 #endif
 
-#ifdef CONFIG_ARCH_OMAP3
+#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
 static struct omap2_mcspi_platform_config omap2_mcspi4_config = {
        .num_cs         = 1,
 };
@@ -351,14 +357,25 @@ static struct platform_device omap2_mcspi4 = {
 
 static void omap_init_mcspi(void)
 {
+       if (cpu_is_omap44xx()) {
+               omap2_mcspi1_resources[0].start = OMAP4_MCSPI1_BASE;
+               omap2_mcspi1_resources[0].end   = OMAP4_MCSPI1_BASE + 0xff;
+               omap2_mcspi2_resources[0].start = OMAP4_MCSPI2_BASE;
+               omap2_mcspi2_resources[0].end   = OMAP4_MCSPI2_BASE + 0xff;
+               omap2_mcspi3_resources[0].start = OMAP4_MCSPI3_BASE;
+               omap2_mcspi3_resources[0].end   = OMAP4_MCSPI3_BASE + 0xff;
+               omap2_mcspi4_resources[0].start = OMAP4_MCSPI4_BASE;
+               omap2_mcspi4_resources[0].end   = OMAP4_MCSPI4_BASE + 0xff;
+       }
        platform_device_register(&omap2_mcspi1);
        platform_device_register(&omap2_mcspi2);
-#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3)
-       if (cpu_is_omap2430() || cpu_is_omap343x())
+#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \
+       defined(CONFIG_ARCH_OMAP4)
+       if (cpu_is_omap2430() || cpu_is_omap343x() || cpu_is_omap44xx())
                platform_device_register(&omap2_mcspi3);
 #endif
-#ifdef CONFIG_ARCH_OMAP3
-       if (cpu_is_omap343x())
+#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
+       if (cpu_is_omap343x() || cpu_is_omap44xx())
                platform_device_register(&omap2_mcspi4);
 #endif
 }
@@ -397,7 +414,7 @@ static inline void omap_init_sha1_md5(void) { }
 
 /*-------------------------------------------------------------------------*/
 
-#ifdef CONFIG_ARCH_OMAP3
+#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
 
 #define MMCHS_SYSCONFIG                        0x0010
 #define MMCHS_SYSCONFIG_SWRESET                (1 << 1)
@@ -424,8 +441,8 @@ static struct platform_device dummy_pdev = {
  **/
 static void __init omap_hsmmc_reset(void)
 {
-       u32 i, nr_controllers = cpu_is_omap34xx() ? OMAP34XX_NR_MMC :
-               OMAP24XX_NR_MMC;
+       u32 i, nr_controllers = cpu_is_omap44xx() ? OMAP44XX_NR_MMC :
+               (cpu_is_omap34xx() ? OMAP34XX_NR_MMC : OMAP24XX_NR_MMC);
 
        for (i = 0; i < nr_controllers; i++) {
                u32 v, base = 0;
@@ -442,8 +459,21 @@ static void __init omap_hsmmc_reset(void)
                case 2:
                        base = OMAP3_MMC3_BASE;
                        break;
+               case 3:
+                       if (!cpu_is_omap44xx())
+                               return;
+                       base = OMAP4_MMC4_BASE;
+                       break;
+               case 4:
+                       if (!cpu_is_omap44xx())
+                               return;
+                       base = OMAP4_MMC5_BASE;
+                       break;
                }
 
+               if (cpu_is_omap44xx())
+                       base += OMAP4_MMC_REG_OFFSET;
+
                dummy_pdev.id = i;
                dev_set_name(&dummy_pdev.dev, "mmci-omap-hs.%d", i);
                iclk = clk_get(dev, "ick");
@@ -581,11 +611,23 @@ void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
                        irq = INT_24XX_MMC2_IRQ;
                        break;
                case 2:
-                       if (!cpu_is_omap34xx())
+                       if (!cpu_is_omap44xx() && !cpu_is_omap34xx())
                                return;
                        base = OMAP3_MMC3_BASE;
                        irq = INT_34XX_MMC3_IRQ;
                        break;
+               case 3:
+                       if (!cpu_is_omap44xx())
+                               return;
+                       base = OMAP4_MMC4_BASE + OMAP4_MMC_REG_OFFSET;
+                       irq = INT_44XX_MMC4_IRQ;
+                       break;
+               case 4:
+                       if (!cpu_is_omap44xx())
+                               return;
+                       base = OMAP4_MMC5_BASE + OMAP4_MMC_REG_OFFSET;
+                       irq = INT_44XX_MMC5_IRQ;
+                       break;
                default:
                        continue;
                }
@@ -593,8 +635,15 @@ void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
                if (cpu_is_omap2420()) {
                        size = OMAP2420_MMC_SIZE;
                        name = "mmci-omap";
+               } else if (cpu_is_omap44xx()) {
+                       if (i < 3) {
+                               base += OMAP4_MMC_REG_OFFSET;
+                               irq += IRQ_GIC_START;
+                       }
+                       size = OMAP4_HSMMC_SIZE;
+                       name = "mmci-omap-hs";
                } else {
-                       size = HSMMC_SIZE;
+                       size = OMAP3_HSMMC_SIZE;
                        name = "mmci-omap-hs";
                }
                omap_mmc_add(name, i, base, size, irq, mmc_data[i]);
index 3c04c2f1b23ff2faae92630600f7c20a4ed2b57b..c9c59a2db4e2f27e4d495160b0c4314bc0f01105 100644 (file)
@@ -198,6 +198,18 @@ static int twl_mmc_resume(struct device *dev, int slot)
 #define twl_mmc_resume NULL
 #endif
 
+#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
+
+static int twl4030_mmc_get_context_loss(struct device *dev)
+{
+       /* FIXME: PM DPS not implemented yet */
+       return 0;
+}
+
+#else
+#define twl4030_mmc_get_context_loss NULL
+#endif
+
 static int twl_mmc1_set_power(struct device *dev, int slot, int power_on,
                                int vdd)
 {
@@ -328,6 +340,61 @@ static int twl_mmc23_set_power(struct device *dev, int slot, int power_on, int v
        return ret;
 }
 
+static int twl_mmc1_set_sleep(struct device *dev, int slot, int sleep, int vdd,
+                             int cardsleep)
+{
+       struct twl_mmc_controller *c = &hsmmc[0];
+       int mode = sleep ? REGULATOR_MODE_STANDBY : REGULATOR_MODE_NORMAL;
+
+       return regulator_set_mode(c->vcc, mode);
+}
+
+static int twl_mmc23_set_sleep(struct device *dev, int slot, int sleep, int vdd,
+                              int cardsleep)
+{
+       struct twl_mmc_controller *c = NULL;
+       struct omap_mmc_platform_data *mmc = dev->platform_data;
+       int i, err, mode;
+
+       for (i = 1; i < ARRAY_SIZE(hsmmc); i++) {
+               if (mmc == hsmmc[i].mmc) {
+                       c = &hsmmc[i];
+                       break;
+               }
+       }
+
+       if (c == NULL)
+               return -ENODEV;
+
+       /*
+        * If we don't see a Vcc regulator, assume it's a fixed
+        * voltage always-on regulator.
+        */
+       if (!c->vcc)
+               return 0;
+
+       mode = sleep ? REGULATOR_MODE_STANDBY : REGULATOR_MODE_NORMAL;
+
+       if (!c->vcc_aux)
+               return regulator_set_mode(c->vcc, mode);
+
+       if (cardsleep) {
+               /* VCC can be turned off if card is asleep */
+               struct regulator *vcc_aux = c->vcc_aux;
+
+               c->vcc_aux = NULL;
+               if (sleep)
+                       err = twl_mmc23_set_power(dev, slot, 0, 0);
+               else
+                       err = twl_mmc23_set_power(dev, slot, 1, vdd);
+               c->vcc_aux = vcc_aux;
+       } else
+               err = regulator_set_mode(c->vcc, mode);
+       if (err)
+               return err;
+       return regulator_set_mode(c->vcc_aux, mode);
+}
+
 static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata;
 
 void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
@@ -390,6 +457,9 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
                } else
                        mmc->slots[0].switch_pin = -EINVAL;
 
+               mmc->get_context_loss_count =
+                               twl4030_mmc_get_context_loss;
+
                /* write protect normally uses an OMAP gpio */
                if (gpio_is_valid(c->gpio_wp)) {
                        gpio_request(c->gpio_wp, "mmc_wp");
@@ -400,6 +470,12 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
                } else
                        mmc->slots[0].gpio_wp = -EINVAL;
 
+               if (c->nonremovable)
+                       mmc->slots[0].nonremovable = 1;
+
+               if (c->power_saving)
+                       mmc->slots[0].power_saving = 1;
+
                /* NOTE:  MMC slots should have a Vcc regulator set up.
                 * This may be from a TWL4030-family chip, another
                 * controllable regulator, or a fixed supply.
@@ -412,6 +488,7 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
                case 1:
                        /* on-chip level shifting via PBIAS0/PBIAS1 */
                        mmc->slots[0].set_power = twl_mmc1_set_power;
+                       mmc->slots[0].set_sleep = twl_mmc1_set_sleep;
                        break;
                case 2:
                        if (c->ext_clock)
@@ -422,6 +499,7 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
                case 3:
                        /* off-chip level shifting, or none */
                        mmc->slots[0].set_power = twl_mmc23_set_power;
+                       mmc->slots[0].set_sleep = twl_mmc23_set_sleep;
                        break;
                default:
                        pr_err("MMC%d configuration not supported!\n", c->mmc);
index 3807c45c9a6ca4d8dc0a4534da1276af8a069ce3..a47e68563fb64e3085b734fd57f5ccf9b75caca5 100644 (file)
@@ -12,6 +12,8 @@ struct twl4030_hsmmc_info {
        bool    transceiver;    /* MMC-2 option */
        bool    ext_clock;      /* use external pin for input clock */
        bool    cover_only;     /* No card detect - just cover switch */
+       bool    nonremovable;   /* Nonremovable e.g. eMMC */
+       bool    power_saving;   /* Try to sleep or power off when possible */
        int     gpio_cd;        /* or -EINVAL */
        int     gpio_wp;        /* or -EINVAL */
        char    *name;          /* or NULL for default */
diff --git a/arch/arm/plat-mxc/include/mach/spi.h b/arch/arm/plat-mxc/include/mach/spi.h
new file mode 100644 (file)
index 0000000..08be445
--- /dev/null
@@ -0,0 +1,27 @@
+
+#ifndef __MACH_SPI_H_
+#define __MACH_SPI_H_
+
+/*
+ * struct spi_imx_master - device.platform_data for SPI controller devices.
+ * @chipselect: Array of chipselects for this master. Numbers >= 0 mean gpio
+ *              pins, numbers < 0 mean internal CSPI chipselects according
+ *              to MXC_SPI_CS(). Normally you want to use gpio based chip
+ *              selects as the CSPI module tries to be intelligent about
+ *              when to assert the chipselect: The CSPI module deasserts the
+ *              chipselect once it runs out of input data. The other problem
+ *              is that it is not possible to mix between high active and low
+ *              active chipselects on one single bus using the internal
+ *              chipselects. Unfortunately Freescale decided to put some
+ *              chipselects on dedicated pins which are not usable as gpios,
+ *              so we have to support the internal chipselects.
+ * @num_chipselect: ARRAY_SIZE(chipselect)
+ */
+struct spi_imx_master {
+       int     *chipselect;
+       int     num_chipselect;
+};
+
+#define MXC_SPI_CS(no) ((no) - 32)
+
+#endif /* __MACH_SPI_H_*/
index fb7cb7723990082141de476990b7619741ec65d1..28a165058b61d961a06d98488dbd43fdb60cb5bc 100644 (file)
 #define INT_44XX_FPKA_READY_IRQ        (50 + IRQ_GIC_START)
 #define INT_44XX_SHA1MD51_IRQ  (51 + IRQ_GIC_START)
 #define INT_44XX_RNG_IRQ       (52 + IRQ_GIC_START)
+#define INT_44XX_MMC5_IRQ      (59 + IRQ_GIC_START)
 #define INT_44XX_I2C3_IRQ      (61 + IRQ_GIC_START)
 #define INT_44XX_FPKA_ERROR_IRQ        (64 + IRQ_GIC_START)
 #define INT_44XX_PBIAS_IRQ     (75 + IRQ_GIC_START)
 #define INT_44XX_TLL_IRQ       (78 + IRQ_GIC_START)
 #define INT_44XX_PARTHASH_IRQ  (79 + IRQ_GIC_START)
 #define INT_44XX_MMC3_IRQ      (94 + IRQ_GIC_START)
+#define INT_44XX_MMC4_IRQ      (96 + IRQ_GIC_START)
 
 
 /* Max. 128 level 2 IRQs (OMAP1610), 192 GPIOs (OMAP730/850) and
index f8fbc4801e5256ee9d4424cc4fc5a2dd34547811..8e52c6572281792cdb703b2f9ea60c70dbd56559 100644 (file)
@@ -16,7 +16,12 @@ enum mipid_test_result {
 struct mipid_platform_data {
        int     nreset_gpio;
        int     data_lines;
+
        void    (*shutdown)(struct mipid_platform_data *pdata);
+       void    (*set_bklight_level)(struct mipid_platform_data *pdata,
+                                    int level);
+       int     (*get_bklight_level)(struct mipid_platform_data *pdata);
+       int     (*get_bklight_max)(struct mipid_platform_data *pdata);
 };
 
 #endif
index 81d5b36534b340680ffc36fde156e9cafbb70e2d..7229b959330171d72bf478df7f4f1146eb6a97ab 100644 (file)
 
 #define OMAP24XX_NR_MMC                2
 #define OMAP34XX_NR_MMC                3
+#define OMAP44XX_NR_MMC                5
 #define OMAP2420_MMC_SIZE      OMAP1_MMC_SIZE
-#define HSMMC_SIZE             0x200
+#define OMAP3_HSMMC_SIZE       0x200
+#define OMAP4_HSMMC_SIZE       0x1000
 #define OMAP2_MMC1_BASE                0x4809c000
 #define OMAP2_MMC2_BASE                0x480b4000
 #define OMAP3_MMC3_BASE                0x480ad000
+#define OMAP4_MMC4_BASE                0x480d1000
+#define OMAP4_MMC5_BASE                0x480d5000
+#define OMAP4_MMC_REG_OFFSET   0x100
+#define HSMMC5                 (1 << 4)
+#define HSMMC4                 (1 << 3)
 #define HSMMC3                 (1 << 2)
 #define HSMMC2                 (1 << 1)
 #define HSMMC1                 (1 << 0)
@@ -59,6 +66,9 @@ struct omap_mmc_platform_data {
        int (*suspend)(struct device *dev, int slot);
        int (*resume)(struct device *dev, int slot);
 
+       /* Return context loss count due to PM states changing */
+       int (*get_context_loss_count)(struct device *dev);
+
        u64 dma_mask;
 
        struct omap_mmc_slot_data {
@@ -80,12 +90,20 @@ struct omap_mmc_platform_data {
                /* use the internal clock */
                unsigned internal_clock:1;
 
+               /* nonremovable e.g. eMMC */
+               unsigned nonremovable:1;
+
+               /* Try to sleep or power off when possible */
+               unsigned power_saving:1;
+
                int switch_pin;                 /* gpio (card detect) */
                int gpio_wp;                    /* gpio (write protect) */
 
                int (* set_bus_mode)(struct device *dev, int slot, int bus_mode);
                int (* set_power)(struct device *dev, int slot, int power_on, int vdd);
                int (* get_ro)(struct device *dev, int slot);
+               int (*set_sleep)(struct device *dev, int slot, int sleep,
+                                int vdd, int cardsleep);
 
                /* return MMC cover switch state, can be NULL if not supported.
                 *
index 7b74d1255e0b93c7531e607a77188a148bda980b..b226bdf45739f6ef5b1f82812dbefbd7c67eda13 100644 (file)
@@ -276,8 +276,8 @@ typedef int (*omapfb_notifier_callback_t)(struct notifier_block *,
                                          void *fbi);
 
 struct omapfb_mem_region {
-       dma_addr_t      paddr;
-       void            *vaddr;
+       u32             paddr;
+       void __iomem    *vaddr;
        unsigned long   size;
        u8              type;           /* OMAPFB_PLANE_MEM_* */
        unsigned        alloc:1;        /* allocated by the driver */
index e7fd0ecd73f75de4d2a7df13b85a5049e046b7aa..ae4dae1e370b150a3df989bd2fd403a6e8e5ba24 100644 (file)
@@ -1,9 +1,6 @@
 #ifndef _BLACKFIN_SECTIONS_H
 #define _BLACKFIN_SECTIONS_H
 
-/* nothing to see, move along */
-#include <asm-generic/sections.h>
-
 /* only used when MTD_UCLINUX */
 extern unsigned long memory_mtd_start, memory_mtd_end, mtd_size;
 
@@ -15,4 +12,39 @@ extern char _stext_l1[], _etext_l1[], _sdata_l1[], _edata_l1[], _sbss_l1[],
        _stext_l2[], _etext_l2[], _sdata_l2[], _edata_l2[], _sbss_l2[],
        _ebss_l2[], _l2_lma_start[];
 
+#include <asm/mem_map.h>
+
+/* Blackfin systems have discontinuous memory map and no virtualized memory */
+static inline int arch_is_kernel_text(unsigned long addr)
+{
+       return
+               (L1_CODE_LENGTH &&
+                addr >= (unsigned long)_stext_l1 &&
+                addr <  (unsigned long)_etext_l1)
+               ||
+               (L2_LENGTH &&
+                addr >= (unsigned long)_stext_l2 &&
+                addr <  (unsigned long)_etext_l2);
+}
+#define arch_is_kernel_text(addr) arch_is_kernel_text(addr)
+
+static inline int arch_is_kernel_data(unsigned long addr)
+{
+       return
+               (L1_DATA_A_LENGTH &&
+                addr >= (unsigned long)_sdata_l1 &&
+                addr <  (unsigned long)_ebss_l1)
+               ||
+               (L1_DATA_B_LENGTH &&
+                addr >= (unsigned long)_sdata_b_l1 &&
+                addr <  (unsigned long)_ebss_b_l1)
+               ||
+               (L2_LENGTH &&
+                addr >= (unsigned long)_sdata_l2 &&
+                addr <  (unsigned long)_ebss_l2);
+}
+#define arch_is_kernel_data(addr) arch_is_kernel_data(addr)
+
+#include <asm-generic/sections.h>
+
 #endif
index 011a1cdf0eb53d4c97c39427bd1f0461690a6e79..6851e52ed5a23d924d3d536460e209092fd8d049 100644 (file)
@@ -500,6 +500,10 @@ config HAVE_ARCH_NODEDATA_EXTENSION
        def_bool y
        depends on NUMA
 
+config ARCH_PROC_KCORE_TEXT
+       def_bool y
+       depends on PROC_KCORE
+
 config IA32_SUPPORT
        bool "Support for Linux/x86 binaries"
        help
index 1d286244a56211c98846a75e232e93bcd4705030..1857766a63c1850d968320559471c22a851b6335 100644 (file)
@@ -617,7 +617,6 @@ mem_init (void)
        long reserved_pages, codesize, datasize, initsize;
        pg_data_t *pgdat;
        int i;
-       static struct kcore_list kcore_mem, kcore_vmem, kcore_kernel;
 
        BUG_ON(PTRS_PER_PGD * sizeof(pgd_t) != PAGE_SIZE);
        BUG_ON(PTRS_PER_PMD * sizeof(pmd_t) != PAGE_SIZE);
@@ -639,10 +638,6 @@ mem_init (void)
 
        high_memory = __va(max_low_pfn * PAGE_SIZE);
 
-       kclist_add(&kcore_mem, __va(0), max_low_pfn * PAGE_SIZE);
-       kclist_add(&kcore_vmem, (void *)VMALLOC_START, VMALLOC_END-VMALLOC_START);
-       kclist_add(&kcore_kernel, _stext, _end - _stext);
-
        for_each_online_pgdat(pgdat)
                if (pgdat->bdata->node_bootmem_map)
                        totalram_pages += free_all_bootmem_node(pgdat);
index 1f4ee4797a6ef2957c73aedc17c4b54e13102d02..15aa1902a788b4d83fa74833d9ca73a60ff879f7 100644 (file)
@@ -352,7 +352,6 @@ void __init paging_init(void)
        free_area_init_nodes(max_zone_pfns);
 }
 
-static struct kcore_list kcore_mem, kcore_vmalloc;
 #ifdef CONFIG_64BIT
 static struct kcore_list kcore_kseg0;
 #endif
@@ -409,11 +408,9 @@ void __init mem_init(void)
        if ((unsigned long) &_text > (unsigned long) CKSEG0)
                /* The -4 is a hack so that user tools don't have to handle
                   the overflow.  */
-               kclist_add(&kcore_kseg0, (void *) CKSEG0, 0x80000000 - 4);
+               kclist_add(&kcore_kseg0, (void *) CKSEG0,
+                               0x80000000 - 4, KCORE_TEXT);
 #endif
-       kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
-       kclist_add(&kcore_vmalloc, (void *)VMALLOC_START,
-                  VMALLOC_END-VMALLOC_START);
 
        printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, "
               "%ldk reserved, %ldk data, %ldk init, %ldk highmem)\n",
index 79890edfd67a6ce98389a009926c49243e2fb45d..3f24c298a3af1cb583f66a809598cfbbbdde6faa 100644 (file)
@@ -285,7 +285,7 @@ static void c_stop(struct seq_file *m, void *v)
 {
 }
 
-struct seq_operations cpuinfo_op = {
+const struct seq_operations cpuinfo_op = {
        .start  = c_start,
        .next   = c_next,
        .stop   = c_stop,
index f32c2811c6d9afa2cde60c2d8b3d77885cbf37a6..855782c5e5ecc4043329f6edfa50ccc6fea078c3 100644 (file)
                                reg = <0x2e000 0x1000>;
                                interrupts = <42 0x8>;
                                interrupt-parent = <&ipic>;
+                               sdhci,wp-inverted;
                                /* Filled in by U-Boot */
                                clock-frequency = <0>;
                        };
index 28e022ac41796fb83d057060d61c8728de4d238a..9e2264b100080b69e3a33e3d30b1ec33766ae3b9 100644 (file)
                                reg = <0x2e000 0x1000>;
                                interrupts = <42 0x8>;
                                interrupt-parent = <&ipic>;
+                               sdhci,wp-inverted;
                                /* Filled in by U-Boot */
                                clock-frequency = <111111111>;
                        };
index 3febc4e91b104b7c1d4426f9eb9e0aecdbaad3be..9a603695723be25eca0216d76f5bd077f6859585 100644 (file)
                                reg = <0x2e000 0x1000>;
                                interrupts = <42 0x8>;
                                interrupt-parent = <&ipic>;
+                               sdhci,wp-inverted;
                                clock-frequency = <133333333>;
                        };
                };
index f720ab9af30dcc474eb7c255b21b6ce1e08c02a5..f70cf6000839bee050e0808ccfdf65c5dc5d988c 100644 (file)
                                reg = <0x2e000 0x1000>;
                                interrupts = <42 0x8>;
                                interrupt-parent = <&ipic>;
+                               sdhci,wp-inverted;
                                /* Filled in by U-Boot */
                                clock-frequency = <0>;
                        };
index a11ead8214b4d699ef2e6e6740c19cbc08f4bb61..4e6a1a407bbd093bcf56cc553d0033c693b361bb 100644 (file)
                                reg = <0x2e000 0x1000>;
                                interrupts = <42 0x8>;
                                interrupt-parent = <&ipic>;
+                               sdhci,wp-inverted;
                                /* Filled in by U-Boot */
                                clock-frequency = <111111111>;
                        };
index 4fa221fd9bdc9d7f1236f08e61f1354517525904..645ec51cc6e1efe4579756acb727424e2dad20a6 100644 (file)
                                reg = <0x2e000 0x1000>;
                                interrupts = <42 0x8>;
                                interrupt-parent = <&ipic>;
+                               sdhci,wp-inverted;
                                /* Filled in by U-Boot */
                                clock-frequency = <0>;
                        };
index e35dfba587c8d33425d80eb940f0d63a3fe38ba2..72336d504528b284fd70e854b6141a55f38d68a1 100644 (file)
                                reg = <0x2e000 0x1000>;
                                interrupts = <42 0x8>;
                                interrupt-parent = <&ipic>;
+                               sdhci,wp-inverted;
                                /* Filled in by U-Boot */
                                clock-frequency = <111111111>;
                        };
index 02fed27af7f64ed72cfad7ed344955721c3d546b..1d5570a1e456abdc1c651dee6c443b2852b00680 100644 (file)
@@ -328,7 +328,7 @@ static void c_stop(struct seq_file *m, void *v)
 {
 }
 
-struct seq_operations cpuinfo_op = {
+const struct seq_operations cpuinfo_op = {
        .start =c_start,
        .next = c_next,
        .stop = c_stop,
index 3ef5084b90ca0357b002a9eaf8f004b10a223db1..9ddcfb4dc139f058f31a8df44668221bc0e1227b 100644 (file)
@@ -242,39 +242,3 @@ void free_initrd_mem(unsigned long start, unsigned long end)
 }
 #endif
 
-#ifdef CONFIG_PROC_KCORE
-static struct kcore_list kcore_vmem;
-
-static int __init setup_kcore(void)
-{
-       int i;
-
-       for (i = 0; i < lmb.memory.cnt; i++) {
-               unsigned long base;
-               unsigned long size;
-               struct kcore_list *kcore_mem;
-
-               base = lmb.memory.region[i].base;
-               size = lmb.memory.region[i].size;
-
-               kcore_mem = kmalloc(sizeof(struct kcore_list), GFP_ATOMIC);
-               if (!kcore_mem)
-                       panic("%s: kmalloc failed\n", __func__);
-
-               /* must stay under 32 bits */
-               if ( 0xfffffffful - (unsigned long)__va(base) < size) {
-                       size = 0xfffffffful - (unsigned long)(__va(base));
-                       printk(KERN_DEBUG "setup_kcore: restrict size=%lx\n",
-                                               size);
-               }
-
-               kclist_add(kcore_mem, __va(base), size);
-       }
-
-       kclist_add(&kcore_vmem, (void *)VMALLOC_START,
-               VMALLOC_END-VMALLOC_START);
-
-       return 0;
-}
-module_init(setup_kcore);
-#endif
index 31582329cd6778e0f3dc0b058635ab4015c8d6ad..335c578b9cc324261a29a3a435036ef5178e9f96 100644 (file)
@@ -109,35 +109,6 @@ void free_initrd_mem(unsigned long start, unsigned long end)
 }
 #endif
 
-#ifdef CONFIG_PROC_KCORE
-static struct kcore_list kcore_vmem;
-
-static int __init setup_kcore(void)
-{
-       int i;
-
-       for (i=0; i < lmb.memory.cnt; i++) {
-               unsigned long base, size;
-               struct kcore_list *kcore_mem;
-
-               base = lmb.memory.region[i].base;
-               size = lmb.memory.region[i].size;
-
-               /* GFP_ATOMIC to avoid might_sleep warnings during boot */
-               kcore_mem = kmalloc(sizeof(struct kcore_list), GFP_ATOMIC);
-               if (!kcore_mem)
-                       panic("%s: kmalloc failed\n", __func__);
-
-               kclist_add(kcore_mem, __va(base), size);
-       }
-
-       kclist_add(&kcore_vmem, (void *)VMALLOC_START, VMALLOC_END-VMALLOC_START);
-
-       return 0;
-}
-module_init(setup_kcore);
-#endif
-
 static void pgd_ctor(void *addr)
 {
        memset(addr, 0, PGD_TABLE_SIZE);
index 0e5c59b995efdec40231f8d6f5686d413cad5fd5..59736317bf0e87a1193910340dd338fb5e75c2ff 100644 (file)
@@ -143,8 +143,8 @@ int arch_add_memory(int nid, u64 start, u64 size)
  * memory regions, find holes and callback for contiguous regions.
  */
 int
-walk_memory_resource(unsigned long start_pfn, unsigned long nr_pages, void *arg,
-                       int (*func)(unsigned long, unsigned long, void *))
+walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages,
+               void *arg, int (*func)(unsigned long, unsigned long, void *))
 {
        struct lmb_property res;
        unsigned long pfn, len;
@@ -166,7 +166,7 @@ walk_memory_resource(unsigned long start_pfn, unsigned long nr_pages, void *arg,
        }
        return ret;
 }
-EXPORT_SYMBOL_GPL(walk_memory_resource);
+EXPORT_SYMBOL_GPL(walk_system_ram_range);
 
 /*
  * Initialize the bootmem system and give it all the memory we
index eae51ef9af2441c2b12660ad786e3a318e567436..3631a4f277eb2ab8aaf02676d7124d6a2a430e44 100644 (file)
@@ -71,7 +71,7 @@ static int hc_show(struct seq_file *m, void *p)
        return 0;
 }
 
-static struct seq_operations hcall_inst_seq_ops = {
+static const struct seq_operations hcall_inst_seq_ops = {
         .start = hc_start,
         .next  = hc_next,
         .stop  = hc_stop,
index fabb7c6f48d24a512415adff781137b4d7c8c859..8173e38afd38f4ecbf9e6c7a5bfae805a50cba48 100644 (file)
@@ -186,8 +186,6 @@ void __init paging_init(void)
        set_fixmap_nocache(FIX_UNCACHED, __pa(&__uncached_start));
 }
 
-static struct kcore_list kcore_mem, kcore_vmalloc;
-
 void __init mem_init(void)
 {
        int codesize, datasize, initsize;
@@ -226,10 +224,6 @@ void __init mem_init(void)
        datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
        initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
 
-       kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
-       kclist_add(&kcore_vmalloc, (void *)VMALLOC_START,
-                  VMALLOC_END - VMALLOC_START);
-
        printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, "
               "%dk data, %dk init)\n",
                nr_free_pages() << (PAGE_SHIFT-10),
index d4de32f0f8afdb849495f29aff26f3c0f004f7d3..6cdbf7e7351d2acae1bf34d209707e52496878e4 100644 (file)
@@ -258,7 +258,7 @@ static inline void *vio_dring_entry(struct vio_dring_state *dr,
 static inline u32 vio_dring_avail(struct vio_dring_state *dr,
                                  unsigned int ring_size)
 {
-       BUILD_BUG_ON(!is_power_of_2(ring_size));
+       MAYBE_BUILD_BUG_ON(!is_power_of_2(ring_size));
 
        return (dr->pending -
                ((dr->prod - dr->cons) & (ring_size - 1)));
index e4ff5d1280ca826bba1d0d640052acda2cb3ce92..7c7a54bed4a6e6cda3e2f82a14d484c86c59372f 100644 (file)
@@ -1204,6 +1204,10 @@ config ARCH_DISCONTIGMEM_DEFAULT
        def_bool y
        depends on NUMA && X86_32
 
+config ARCH_PROC_KCORE_TEXT
+       def_bool y
+       depends on X86_64 && PROC_KCORE
+
 config ARCH_SPARSEMEM_DEFAULT
        def_bool y
        depends on X86_64
index d82f39bb7905e8f14d3cbd1dc0365ba98f03eea6..8d33bc5462d1bd30af43bcb4156fec351149eaa6 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Access to user system call parameters and results
  *
- * Copyright (C) 2008 Red Hat, Inc.  All rights reserved.
+ * Copyright (C) 2008-2009 Red Hat, Inc.  All rights reserved.
  *
  * This copyrighted material is made available to anyone wishing to use,
  * modify, copy, or redistribute it subject to the terms and conditions
 #include <linux/sched.h>
 #include <linux/err.h>
 
-static inline long syscall_get_nr(struct task_struct *task,
-                                 struct pt_regs *regs)
+/*
+ * Only the low 32 bits of orig_ax are meaningful, so we return int.
+ * This importantly ignores the high bits on 64-bit, so comparisons
+ * sign-extend the low 32 bits.
+ */
+static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
 {
-       /*
-        * We always sign-extend a -1 value being set here,
-        * so this is always either -1L or a syscall number.
-        */
        return regs->orig_ax;
 }
 
index 8d7d5c9c1be31058b651101503edc68028e62351..7b058a2dc66afecdaeb58877102957dff77e7d81 100644 (file)
@@ -325,16 +325,6 @@ static int putreg(struct task_struct *child,
                return set_flags(child, value);
 
 #ifdef CONFIG_X86_64
-       /*
-        * Orig_ax is really just a flag with small positive and
-        * negative values, so make sure to always sign-extend it
-        * from 32 bits so that it works correctly regardless of
-        * whether we come from a 32-bit environment or not.
-        */
-       case offsetof(struct user_regs_struct, orig_ax):
-               value = (long) (s32) value;
-               break;
-
        case offsetof(struct user_regs_struct,fs_base):
                if (value >= TASK_SIZE_OF(child))
                        return -EIO;
@@ -1126,10 +1116,15 @@ static int putreg32(struct task_struct *child, unsigned regno, u32 value)
 
        case offsetof(struct user32, regs.orig_eax):
                /*
-                * Sign-extend the value so that orig_eax = -1
-                * causes (long)orig_ax < 0 tests to fire correctly.
+                * A 32-bit debugger setting orig_eax means to restore
+                * the state of the task restarting a 32-bit syscall.
+                * Make sure we interpret the -ERESTART* codes correctly
+                * in case the task is not actually still sitting at the
+                * exit from a 32-bit syscall with TS_COMPAT still set.
                 */
-               regs->orig_ax = (long) (s32) value;
+               regs->orig_ax = value;
+               if (syscall_get_nr(child, regs) >= 0)
+                       task_thread_info(child)->status |= TS_COMPAT;
                break;
 
        case offsetof(struct user32, regs.eflags):
index b49b4f67453dbf6c3843cff30e25a0e23661fa51..30938c1d8d5d554cd3819887dec0dc31f007a9aa 100644 (file)
@@ -857,8 +857,6 @@ static void __init test_wp_bit(void)
        }
 }
 
-static struct kcore_list kcore_mem, kcore_vmalloc;
-
 void __init mem_init(void)
 {
        int codesize, reservedpages, datasize, initsize;
@@ -886,10 +884,6 @@ void __init mem_init(void)
        datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
        initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
 
-       kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
-       kclist_add(&kcore_vmalloc, (void *)VMALLOC_START,
-                  VMALLOC_END-VMALLOC_START);
-
        printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, "
                        "%dk reserved, %dk data, %dk init, %ldk highmem)\n",
                nr_free_pages() << (PAGE_SHIFT-10),
index 810bd31e7f5f2d56df765bbc4971f7aa9dc5c4d2..5a4398a6006bcca5a0bce02e53f06601f399a09e 100644 (file)
@@ -647,8 +647,7 @@ EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
 
 #endif /* CONFIG_MEMORY_HOTPLUG */
 
-static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel,
-                        kcore_modules, kcore_vsyscall;
+static struct kcore_list kcore_vsyscall;
 
 void __init mem_init(void)
 {
@@ -677,13 +676,8 @@ void __init mem_init(void)
        initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
 
        /* Register memory areas for /proc/kcore */
-       kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
-       kclist_add(&kcore_vmalloc, (void *)VMALLOC_START,
-                  VMALLOC_END-VMALLOC_START);
-       kclist_add(&kcore_kernel, &_stext, _end - _stext);
-       kclist_add(&kcore_modules, (void *)MODULES_VADDR, MODULES_LEN);
        kclist_add(&kcore_vsyscall, (void *)VSYSCALL_START,
-                                VSYSCALL_END - VSYSCALL_START);
+                        VSYSCALL_END - VSYSCALL_START, KCORE_OTHER);
 
        printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, "
                         "%ldk absent, %ldk reserved, %ldk data, %ldk init)\n",
index c77b6f3c28ea47e16580e43d6f63a538c5e56bfe..6fa7b0fdbdfd172f2e10f27bc82660c9201f3234 100644 (file)
@@ -6562,7 +6562,7 @@ static int DAC960_ProcWriteUserCommand(struct file *file,
   if (copy_from_user(CommandBuffer, Buffer, Count)) return -EFAULT;
   CommandBuffer[Count] = '\0';
   Length = strlen(CommandBuffer);
-  if (CommandBuffer[Length-1] == '\n')
+  if (Length > 0 && CommandBuffer[Length-1] == '\n')
     CommandBuffer[--Length] = '\0';
   if (Controller->FirmwareType == DAC960_V1_Controller)
     return (DAC960_V1_ExecuteUserCommand(Controller, CommandBuffer)
index 4f19105f755c76e5f9ea56342b5915a8ead5924b..24c3e21ab263a6a685356f7d17ac5c0c097e60b6 100644 (file)
@@ -363,7 +363,7 @@ static void cciss_seq_stop(struct seq_file *seq, void *v)
        h->busy_configuring = 0;
 }
 
-static struct seq_operations cciss_seq_ops = {
+static const struct seq_operations cciss_seq_ops = {
        .start = cciss_seq_start,
        .show  = cciss_seq_show,
        .next  = cciss_seq_next,
index 1ee27cc23426d2f96de2000411cafadb06030c4a..07fa612a58d56efd23a24a3cb7f5ec61052b5190 100644 (file)
@@ -91,7 +91,7 @@ static int misc_seq_show(struct seq_file *seq, void *v)
 }
 
 
-static struct seq_operations misc_seq_ops = {
+static const struct seq_operations misc_seq_ops = {
        .start = misc_seq_start,
        .next  = misc_seq_next,
        .stop  = misc_seq_stop,
index b0603b2e56844e38e1e4082eaf20ed115d78b07e..32b957efa42047af3065b6e30c31827031e94159 100644 (file)
@@ -696,7 +696,7 @@ int __tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
 
        cmd.header.in = pcrread_header;
        cmd.params.pcrread_in.pcr_idx = cpu_to_be32(pcr_idx);
-       BUILD_BUG_ON(cmd.header.in.length > READ_PCR_RESULT_SIZE);
+       BUG_ON(cmd.header.in.length > READ_PCR_RESULT_SIZE);
        rc = transmit_cmd(chip, &cmd, cmd.header.in.length,
                          "attempting to read a pcr value");
 
@@ -760,7 +760,7 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
                return -ENODEV;
 
        cmd.header.in = pcrextend_header;
-       BUILD_BUG_ON(be32_to_cpu(cmd.header.in.length) > EXTEND_PCR_SIZE);
+       BUG_ON(be32_to_cpu(cmd.header.in.length) > EXTEND_PCR_SIZE);
        cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx);
        memcpy(cmd.params.pcrextend_in.hash, hash, TPM_DIGEST_SIZE);
        rc = transmit_cmd(chip, &cmd, cmd.header.in.length,
index 0c2f55a38b954d56a1eba026e8b9c65718af1286..bf2170fb1cdd7d1d01581aeb9b5abe129a42d32b 100644 (file)
@@ -343,14 +343,14 @@ static int tpm_ascii_bios_measurements_show(struct seq_file *m, void *v)
        return 0;
 }
 
-static struct seq_operations tpm_ascii_b_measurments_seqops = {
+static const struct seq_operations tpm_ascii_b_measurments_seqops = {
        .start = tpm_bios_measurements_start,
        .next = tpm_bios_measurements_next,
        .stop = tpm_bios_measurements_stop,
        .show = tpm_ascii_bios_measurements_show,
 };
 
-static struct seq_operations tpm_binary_b_measurments_seqops = {
+static const struct seq_operations tpm_binary_b_measurments_seqops = {
        .start = tpm_bios_measurements_start,
        .next = tpm_bios_measurements_next,
        .stop = tpm_bios_measurements_stop,
index 85e5dc0431fece279a7324df2a18c01e8808468f..abf4a2529f8011c6d4dbd87dc4412c8925dca41c 100644 (file)
@@ -139,6 +139,31 @@ void proc_id_connector(struct task_struct *task, int which_id)
        cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
 }
 
+void proc_sid_connector(struct task_struct *task)
+{
+       struct cn_msg *msg;
+       struct proc_event *ev;
+       struct timespec ts;
+       __u8 buffer[CN_PROC_MSG_SIZE];
+
+       if (atomic_read(&proc_event_num_listeners) < 1)
+               return;
+
+       msg = (struct cn_msg *)buffer;
+       ev = (struct proc_event *)msg->data;
+       get_seq(&msg->seq, &ev->cpu);
+       ktime_get_ts(&ts); /* get high res monotonic timestamp */
+       put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
+       ev->what = PROC_EVENT_SID;
+       ev->event_data.sid.process_pid = task->pid;
+       ev->event_data.sid.process_tgid = task->tgid;
+
+       memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
+       msg->ack = 0; /* not used */
+       msg->len = sizeof(*ev);
+       cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+}
+
 void proc_exit_connector(struct task_struct *task)
 {
        struct cn_msg *msg;
index 6b4c484a699a9f07ca4caa9a9dbfb2b5e9ab99df..2ad0128c63c6995ab11fa7f3e2896bad968fe9f3 100644 (file)
@@ -162,6 +162,16 @@ config GPIO_WM831X
          Say yes here to access the GPIO signals of WM831x power management
          chips from Wolfson Microelectronics.
 
+config GPIO_ADP5520
+       tristate "GPIO Support for ADP5520 PMIC"
+       depends on PMIC_ADP5520
+       help
+         This option enables support for on-chip GPIO found
+         on Analog Devices ADP5520 PMICs.
+
+         To compile this driver as a module, choose M here: the module will
+         be called adp5520-gpio.
+
 comment "PCI GPIO expanders:"
 
 config GPIO_BT8XX
@@ -180,6 +190,12 @@ config GPIO_BT8XX
 
          If unsure, say N.
 
+config GPIO_LANGWELL
+       bool "Intel Moorestown Platform Langwell GPIO support"
+       depends on PCI
+       help
+         Say Y here to support Intel Moorestown platform GPIO.
+
 comment "SPI GPIO expanders:"
 
 config GPIO_MAX7301
@@ -195,4 +211,23 @@ config GPIO_MCP23S08
          SPI driver for Microchip MCP23S08 I/O expander.  This provides
          a GPIO interface supporting inputs and outputs.
 
+config GPIO_MC33880
+       tristate "Freescale MC33880 high-side/low-side switch"
+       depends on SPI_MASTER
+       help
+         SPI driver for Freescale MC33880 high-side/low-side switch.
+         This provides GPIO interface supporting inputs and outputs.
+
+comment "AC97 GPIO expanders:"
+
+config GPIO_UCB1400
+       bool "Philips UCB1400 GPIO"
+       depends on UCB1400_CORE
+       help
+         This enables support for the Philips UCB1400 GPIO pins.
+         The UCB1400 is an AC97 audio codec.
+
+         To compile this driver as a module, choose M here: the
+         module will be called ucb1400_gpio.
+
 endif
index ea7c745f26a8066f3216e1bdd967ada09838574c..00a532c9a1e294afcf6c6224d1b32e6bdda8068e 100644 (file)
@@ -4,13 +4,17 @@ ccflags-$(CONFIG_DEBUG_GPIO)  += -DDEBUG
 
 obj-$(CONFIG_GPIOLIB)          += gpiolib.o
 
+obj-$(CONFIG_GPIO_ADP5520)     += adp5520-gpio.o
+obj-$(CONFIG_GPIO_LANGWELL)    += langwell_gpio.o
 obj-$(CONFIG_GPIO_MAX7301)     += max7301.o
 obj-$(CONFIG_GPIO_MAX732X)     += max732x.o
+obj-$(CONFIG_GPIO_MC33880)     += mc33880.o
 obj-$(CONFIG_GPIO_MCP23S08)    += mcp23s08.o
 obj-$(CONFIG_GPIO_PCA953X)     += pca953x.o
 obj-$(CONFIG_GPIO_PCF857X)     += pcf857x.o
 obj-$(CONFIG_GPIO_PL061)       += pl061.o
 obj-$(CONFIG_GPIO_TWL4030)     += twl4030-gpio.o
+obj-$(CONFIG_GPIO_UCB1400)     += ucb1400_gpio.o
 obj-$(CONFIG_GPIO_XILINX)      += xilinx_gpio.o
 obj-$(CONFIG_GPIO_BT8XX)       += bt8xxgpio.o
 obj-$(CONFIG_GPIO_VR41XX)      += vr41xx_giu.o
diff --git a/drivers/gpio/adp5520-gpio.c b/drivers/gpio/adp5520-gpio.c
new file mode 100644 (file)
index 0000000..ad05bbc
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * GPIO driver for Analog Devices ADP5520 MFD PMICs
+ *
+ * Copyright 2009 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/adp5520.h>
+
+#include <linux/gpio.h>
+
+struct adp5520_gpio {
+       struct device *master;
+       struct gpio_chip gpio_chip;
+       unsigned char lut[ADP5520_MAXGPIOS];
+       unsigned long output;
+};
+
+static int adp5520_gpio_get_value(struct gpio_chip *chip, unsigned off)
+{
+       struct adp5520_gpio *dev;
+       uint8_t reg_val;
+
+       dev = container_of(chip, struct adp5520_gpio, gpio_chip);
+
+       /*
+        * There are dedicated registers for GPIO IN/OUT.
+        * Make sure we return the right value, even when configured as output
+        */
+
+       if (test_bit(off, &dev->output))
+               adp5520_read(dev->master, GPIO_OUT, &reg_val);
+       else
+               adp5520_read(dev->master, GPIO_IN, &reg_val);
+
+       return !!(reg_val & dev->lut[off]);
+}
+
+static void adp5520_gpio_set_value(struct gpio_chip *chip,
+               unsigned off, int val)
+{
+       struct adp5520_gpio *dev;
+       dev = container_of(chip, struct adp5520_gpio, gpio_chip);
+
+       if (val)
+               adp5520_set_bits(dev->master, GPIO_OUT, dev->lut[off]);
+       else
+               adp5520_clr_bits(dev->master, GPIO_OUT, dev->lut[off]);
+}
+
+static int adp5520_gpio_direction_input(struct gpio_chip *chip, unsigned off)
+{
+       struct adp5520_gpio *dev;
+       dev = container_of(chip, struct adp5520_gpio, gpio_chip);
+
+       clear_bit(off, &dev->output);
+
+       return adp5520_clr_bits(dev->master, GPIO_CFG_2, dev->lut[off]);
+}
+
+static int adp5520_gpio_direction_output(struct gpio_chip *chip,
+               unsigned off, int val)
+{
+       struct adp5520_gpio *dev;
+       int ret = 0;
+       dev = container_of(chip, struct adp5520_gpio, gpio_chip);
+
+       set_bit(off, &dev->output);
+
+       if (val)
+               ret |= adp5520_set_bits(dev->master, GPIO_OUT, dev->lut[off]);
+       else
+               ret |= adp5520_clr_bits(dev->master, GPIO_OUT, dev->lut[off]);
+
+       ret |= adp5520_set_bits(dev->master, GPIO_CFG_2, dev->lut[off]);
+
+       return ret;
+}
+
+static int __devinit adp5520_gpio_probe(struct platform_device *pdev)
+{
+       struct adp5520_gpio_platfrom_data *pdata = pdev->dev.platform_data;
+       struct adp5520_gpio *dev;
+       struct gpio_chip *gc;
+       int ret, i, gpios;
+       unsigned char ctl_mask = 0;
+
+       if (pdata == NULL) {
+               dev_err(&pdev->dev, "missing platform data\n");
+               return -ENODEV;
+       }
+
+       if (pdev->id != ID_ADP5520) {
+               dev_err(&pdev->dev, "only ADP5520 supports GPIO\n");
+               return -ENODEV;
+       }
+
+       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+       if (dev == NULL) {
+               dev_err(&pdev->dev, "failed to alloc memory\n");
+               return -ENOMEM;
+       }
+
+       dev->master = pdev->dev.parent;
+
+       for (gpios = 0, i = 0; i < ADP5520_MAXGPIOS; i++)
+               if (pdata->gpio_en_mask & (1 << i))
+                       dev->lut[gpios++] = 1 << i;
+
+       if (gpios < 1) {
+               ret = -EINVAL;
+               goto err;
+       }
+
+       gc = &dev->gpio_chip;
+       gc->direction_input  = adp5520_gpio_direction_input;
+       gc->direction_output = adp5520_gpio_direction_output;
+       gc->get = adp5520_gpio_get_value;
+       gc->set = adp5520_gpio_set_value;
+       gc->can_sleep = 1;
+
+       gc->base = pdata->gpio_start;
+       gc->ngpio = gpios;
+       gc->label = pdev->name;
+       gc->owner = THIS_MODULE;
+
+       ret = adp5520_clr_bits(dev->master, GPIO_CFG_1,
+               pdata->gpio_en_mask);
+
+       if (pdata->gpio_en_mask & GPIO_C3)
+               ctl_mask |= C3_MODE;
+
+       if (pdata->gpio_en_mask & GPIO_R3)
+               ctl_mask |= R3_MODE;
+
+       if (ctl_mask)
+               ret = adp5520_set_bits(dev->master, LED_CONTROL,
+                       ctl_mask);
+
+       ret |= adp5520_set_bits(dev->master, GPIO_PULLUP,
+               pdata->gpio_pullup_mask);
+
+       if (ret) {
+               dev_err(&pdev->dev, "failed to write\n");
+               goto err;
+       }
+
+       ret = gpiochip_add(&dev->gpio_chip);
+       if (ret)
+               goto err;
+
+       platform_set_drvdata(pdev, dev);
+       return 0;
+
+err:
+       kfree(dev);
+       return ret;
+}
+
+static int __devexit adp5520_gpio_remove(struct platform_device *pdev)
+{
+       struct adp5520_gpio *dev;
+       int ret;
+
+       dev = platform_get_drvdata(pdev);
+       ret = gpiochip_remove(&dev->gpio_chip);
+       if (ret) {
+               dev_err(&pdev->dev, "%s failed, %d\n",
+                               "gpiochip_remove()", ret);
+               return ret;
+       }
+
+       kfree(dev);
+       return 0;
+}
+
+static struct platform_driver adp5520_gpio_driver = {
+       .driver = {
+               .name   = "adp5520-gpio",
+               .owner  = THIS_MODULE,
+       },
+       .probe          = adp5520_gpio_probe,
+       .remove         = __devexit_p(adp5520_gpio_remove),
+};
+
+static int __init adp5520_gpio_init(void)
+{
+       return platform_driver_register(&adp5520_gpio_driver);
+}
+module_init(adp5520_gpio_init);
+
+static void __exit adp5520_gpio_exit(void)
+{
+       platform_driver_unregister(&adp5520_gpio_driver);
+}
+module_exit(adp5520_gpio_exit);
+
+MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_DESCRIPTION("GPIO ADP5520 Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:adp5520-gpio");
index 55904140213bdd2ebc6b3f952787737b4f166c63..2559f2289409f13c431bd60d9ff95a503813b8b1 100644 (file)
@@ -46,8 +46,7 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/spinlock.h>
-
-#include <asm/gpio.h>
+#include <linux/gpio.h>
 
 /* Steal the hardware definitions from the bttv driver. */
 #include "../media/video/bt8xx/bt848.h"
index 51a8d4103be53beb3dd90bd1328d89935cf6573c..bb11a429394ab865f7e07cfc289d8a32330bd320 100644 (file)
@@ -1,5 +1,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/spinlock.h>
 #include <linux/device.h>
@@ -7,6 +8,7 @@
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
 #include <linux/gpio.h>
+#include <linux/idr.h>
 
 
 /* Optional implementation infrastructure for GPIO interfaces.
@@ -49,6 +51,13 @@ struct gpio_desc {
 #define FLAG_RESERVED  2
 #define FLAG_EXPORT    3       /* protected by sysfs_lock */
 #define FLAG_SYSFS     4       /* exported via /sys/class/gpio/control */
+#define FLAG_TRIG_FALL 5       /* trigger on falling edge */
+#define FLAG_TRIG_RISE 6       /* trigger on rising edge */
+
+#define PDESC_ID_SHIFT 16      /* add new flags before this one */
+
+#define GPIO_FLAGS_MASK                ((1 << PDESC_ID_SHIFT) - 1)
+#define GPIO_TRIGGER_MASK      (BIT(FLAG_TRIG_FALL) | BIT(FLAG_TRIG_RISE))
 
 #ifdef CONFIG_DEBUG_FS
        const char              *label;
@@ -56,6 +65,15 @@ struct gpio_desc {
 };
 static struct gpio_desc gpio_desc[ARCH_NR_GPIOS];
 
+#ifdef CONFIG_GPIO_SYSFS
+struct poll_desc {
+       struct work_struct      work;
+       struct sysfs_dirent     *value_sd;
+};
+
+static struct idr pdesc_idr;
+#endif
+
 static inline void desc_set_label(struct gpio_desc *d, const char *label)
 {
 #ifdef CONFIG_DEBUG_FS
@@ -188,10 +206,10 @@ static DEFINE_MUTEX(sysfs_lock);
  *   /value
  *      * always readable, subject to hardware behavior
  *      * may be writable, as zero/nonzero
- *
- * REVISIT there will likely be an attribute for configuring async
- * notifications, e.g. to specify polling interval or IRQ trigger type
- * that would for example trigger a poll() on the "value".
+ *   /edge
+ *      * configures behavior of poll(2) on /value
+ *      * available only if pin can generate IRQs on input
+ *      * is read/write as "none", "falling", "rising", or "both"
  */
 
 static ssize_t gpio_direction_show(struct device *dev,
@@ -288,6 +306,175 @@ static ssize_t gpio_value_store(struct device *dev,
 static /*const*/ DEVICE_ATTR(value, 0644,
                gpio_value_show, gpio_value_store);
 
+static irqreturn_t gpio_sysfs_irq(int irq, void *priv)
+{
+       struct work_struct      *work = priv;
+
+       schedule_work(work);
+       return IRQ_HANDLED;
+}
+
+static void gpio_notify_sysfs(struct work_struct *work)
+{
+       struct poll_desc        *pdesc;
+
+       pdesc = container_of(work, struct poll_desc, work);
+       sysfs_notify_dirent(pdesc->value_sd);
+}
+
+static int gpio_setup_irq(struct gpio_desc *desc, struct device *dev,
+               unsigned long gpio_flags)
+{
+       struct poll_desc        *pdesc;
+       unsigned long           irq_flags;
+       int                     ret, irq, id;
+
+       if ((desc->flags & GPIO_TRIGGER_MASK) == gpio_flags)
+               return 0;
+
+       irq = gpio_to_irq(desc - gpio_desc);
+       if (irq < 0)
+               return -EIO;
+
+       id = desc->flags >> PDESC_ID_SHIFT;
+       pdesc = idr_find(&pdesc_idr, id);
+       if (pdesc) {
+               free_irq(irq, &pdesc->work);
+               cancel_work_sync(&pdesc->work);
+       }
+
+       desc->flags &= ~GPIO_TRIGGER_MASK;
+
+       if (!gpio_flags) {
+               ret = 0;
+               goto free_sd;
+       }
+
+       irq_flags = IRQF_SHARED;
+       if (test_bit(FLAG_TRIG_FALL, &gpio_flags))
+               irq_flags |= IRQF_TRIGGER_FALLING;
+       if (test_bit(FLAG_TRIG_RISE, &gpio_flags))
+               irq_flags |= IRQF_TRIGGER_RISING;
+
+       if (!pdesc) {
+               pdesc = kmalloc(sizeof(*pdesc), GFP_KERNEL);
+               if (!pdesc) {
+                       ret = -ENOMEM;
+                       goto err_out;
+               }
+
+               do {
+                       ret = -ENOMEM;
+                       if (idr_pre_get(&pdesc_idr, GFP_KERNEL))
+                               ret = idr_get_new_above(&pdesc_idr,
+                                               pdesc, 1, &id);
+               } while (ret == -EAGAIN);
+
+               if (ret)
+                       goto free_mem;
+
+               desc->flags &= GPIO_FLAGS_MASK;
+               desc->flags |= (unsigned long)id << PDESC_ID_SHIFT;
+
+               if (desc->flags >> PDESC_ID_SHIFT != id) {
+                       ret = -ERANGE;
+                       goto free_id;
+               }
+
+               pdesc->value_sd = sysfs_get_dirent(dev->kobj.sd, "value");
+               if (!pdesc->value_sd) {
+                       ret = -ENODEV;
+                       goto free_id;
+               }
+               INIT_WORK(&pdesc->work, gpio_notify_sysfs);
+       }
+
+       ret = request_irq(irq, gpio_sysfs_irq, irq_flags,
+                       "gpiolib", &pdesc->work);
+       if (ret)
+               goto free_sd;
+
+       desc->flags |= gpio_flags;
+       return 0;
+
+free_sd:
+       sysfs_put(pdesc->value_sd);
+free_id:
+       idr_remove(&pdesc_idr, id);
+       desc->flags &= GPIO_FLAGS_MASK;
+free_mem:
+       kfree(pdesc);
+err_out:
+       return ret;
+}
+
+static const struct {
+       const char *name;
+       unsigned long flags;
+} trigger_types[] = {
+       { "none",    0 },
+       { "falling", BIT(FLAG_TRIG_FALL) },
+       { "rising",  BIT(FLAG_TRIG_RISE) },
+       { "both",    BIT(FLAG_TRIG_FALL) | BIT(FLAG_TRIG_RISE) },
+};
+
+static ssize_t gpio_edge_show(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       const struct gpio_desc  *desc = dev_get_drvdata(dev);
+       ssize_t                 status;
+
+       mutex_lock(&sysfs_lock);
+
+       if (!test_bit(FLAG_EXPORT, &desc->flags))
+               status = -EIO;
+       else {
+               int i;
+
+               status = 0;
+               for (i = 0; i < ARRAY_SIZE(trigger_types); i++)
+                       if ((desc->flags & GPIO_TRIGGER_MASK)
+                                       == trigger_types[i].flags) {
+                               status = sprintf(buf, "%s\n",
+                                                trigger_types[i].name);
+                               break;
+                       }
+       }
+
+       mutex_unlock(&sysfs_lock);
+       return status;
+}
+
+static ssize_t gpio_edge_store(struct device *dev,
+               struct device_attribute *attr, const char *buf, size_t size)
+{
+       struct gpio_desc        *desc = dev_get_drvdata(dev);
+       ssize_t                 status;
+       int                     i;
+
+       for (i = 0; i < ARRAY_SIZE(trigger_types); i++)
+               if (sysfs_streq(trigger_types[i].name, buf))
+                       goto found;
+       return -EINVAL;
+
+found:
+       mutex_lock(&sysfs_lock);
+
+       if (!test_bit(FLAG_EXPORT, &desc->flags))
+               status = -EIO;
+       else {
+               status = gpio_setup_irq(desc, dev, trigger_types[i].flags);
+               if (!status)
+                       status = size;
+       }
+
+       mutex_unlock(&sysfs_lock);
+
+       return status;
+}
+
+static DEVICE_ATTR(edge, 0644, gpio_edge_show, gpio_edge_store);
+
 static const struct attribute *gpio_attrs[] = {
        &dev_attr_direction.attr,
        &dev_attr_value.attr,
@@ -473,7 +660,7 @@ int gpio_export(unsigned gpio, bool direction_may_change)
                struct device   *dev;
 
                dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0),
-                                   desc, ioname ? ioname : "gpio%d", gpio);
+                               desc, ioname ? ioname : "gpio%d", gpio);
                if (dev) {
                        if (direction_may_change)
                                status = sysfs_create_group(&dev->kobj,
@@ -481,6 +668,14 @@ int gpio_export(unsigned gpio, bool direction_may_change)
                        else
                                status = device_create_file(dev,
                                                &dev_attr_value);
+
+                       if (!status && gpio_to_irq(gpio) >= 0
+                                       && (direction_may_change
+                                               || !test_bit(FLAG_IS_OUT,
+                                                       &desc->flags)))
+                               status = device_create_file(dev,
+                                               &dev_attr_edge);
+
                        if (status != 0)
                                device_unregister(dev);
                } else
@@ -504,6 +699,51 @@ static int match_export(struct device *dev, void *data)
        return dev_get_drvdata(dev) == data;
 }
 
+/**
+ * gpio_export_link - create a sysfs link to an exported GPIO node
+ * @dev: device under which to create symlink
+ * @name: name of the symlink
+ * @gpio: gpio to create symlink to, already exported
+ *
+ * Set up a symlink from /sys/.../dev/name to /sys/class/gpio/gpioN
+ * node. Caller is responsible for unlinking.
+ *
+ * Returns zero on success, else an error.
+ */
+int gpio_export_link(struct device *dev, const char *name, unsigned gpio)
+{
+       struct gpio_desc        *desc;
+       int                     status = -EINVAL;
+
+       if (!gpio_is_valid(gpio))
+               goto done;
+
+       mutex_lock(&sysfs_lock);
+
+       desc = &gpio_desc[gpio];
+
+       if (test_bit(FLAG_EXPORT, &desc->flags)) {
+               struct device *tdev;
+
+               tdev = class_find_device(&gpio_class, NULL, desc, match_export);
+               if (tdev != NULL) {
+                       status = sysfs_create_link(&dev->kobj, &tdev->kobj,
+                                               name);
+               } else {
+                       status = -ENODEV;
+               }
+       }
+
+       mutex_unlock(&sysfs_lock);
+
+done:
+       if (status)
+               pr_debug("%s: gpio%d status %d\n", __func__, gpio, status);
+
+       return status;
+}
+EXPORT_SYMBOL_GPL(gpio_export_link);
+
 /**
  * gpio_unexport - reverse effect of gpio_export()
  * @gpio: gpio to make unavailable
@@ -527,6 +767,7 @@ void gpio_unexport(unsigned gpio)
 
                dev = class_find_device(&gpio_class, NULL, desc, match_export);
                if (dev) {
+                       gpio_setup_irq(desc, dev, 0);
                        clear_bit(FLAG_EXPORT, &desc->flags);
                        put_device(dev);
                        device_unregister(dev);
@@ -611,6 +852,8 @@ static int __init gpiolib_sysfs_init(void)
        unsigned long   flags;
        unsigned        gpio;
 
+       idr_init(&pdesc_idr);
+
        status = class_register(&gpio_class);
        if (status < 0)
                return status;
diff --git a/drivers/gpio/langwell_gpio.c b/drivers/gpio/langwell_gpio.c
new file mode 100644 (file)
index 0000000..5711ce5
--- /dev/null
@@ -0,0 +1,297 @@
+/* langwell_gpio.c Moorestown platform Langwell chip GPIO driver
+ * Copyright (c) 2008 - 2009,  Intel Corporation.
+ *
+ * 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.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Supports:
+ * Moorestown platform Langwell chip.
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/stddef.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+struct lnw_gpio_register {
+       u32     GPLR[2];
+       u32     GPDR[2];
+       u32     GPSR[2];
+       u32     GPCR[2];
+       u32     GRER[2];
+       u32     GFER[2];
+       u32     GEDR[2];
+};
+
+struct lnw_gpio {
+       struct gpio_chip                chip;
+       struct lnw_gpio_register        *reg_base;
+       spinlock_t                      lock;
+       unsigned                        irq_base;
+};
+
+static int lnw_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+       struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip);
+       u8 reg = offset / 32;
+       void __iomem *gplr;
+
+       gplr = (void __iomem *)(&lnw->reg_base->GPLR[reg]);
+       return readl(gplr) & BIT(offset % 32);
+}
+
+static void lnw_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+       struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip);
+       u8 reg = offset / 32;
+       void __iomem *gpsr, *gpcr;
+
+       if (value) {
+               gpsr = (void __iomem *)(&lnw->reg_base->GPSR[reg]);
+               writel(BIT(offset % 32), gpsr);
+       } else {
+               gpcr = (void __iomem *)(&lnw->reg_base->GPCR[reg]);
+               writel(BIT(offset % 32), gpcr);
+       }
+}
+
+static int lnw_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+       struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip);
+       u8 reg = offset / 32;
+       u32 value;
+       unsigned long flags;
+       void __iomem *gpdr;
+
+       gpdr = (void __iomem *)(&lnw->reg_base->GPDR[reg]);
+       spin_lock_irqsave(&lnw->lock, flags);
+       value = readl(gpdr);
+       value &= ~BIT(offset % 32);
+       writel(value, gpdr);
+       spin_unlock_irqrestore(&lnw->lock, flags);
+       return 0;
+}
+
+static int lnw_gpio_direction_output(struct gpio_chip *chip,
+                       unsigned offset, int value)
+{
+       struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip);
+       u8 reg = offset / 32;
+       unsigned long flags;
+       void __iomem *gpdr;
+
+       lnw_gpio_set(chip, offset, value);
+       gpdr = (void __iomem *)(&lnw->reg_base->GPDR[reg]);
+       spin_lock_irqsave(&lnw->lock, flags);
+       value = readl(gpdr);
+       value |= BIT(offset % 32);;
+       writel(value, gpdr);
+       spin_unlock_irqrestore(&lnw->lock, flags);
+       return 0;
+}
+
+static int lnw_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+       struct lnw_gpio *lnw = container_of(chip, struct lnw_gpio, chip);
+       return lnw->irq_base + offset;
+}
+
+static int lnw_irq_type(unsigned irq, unsigned type)
+{
+       struct lnw_gpio *lnw = get_irq_chip_data(irq);
+       u32 gpio = irq - lnw->irq_base;
+       u8 reg = gpio / 32;
+       unsigned long flags;
+       u32 value;
+       void __iomem *grer = (void __iomem *)(&lnw->reg_base->GRER[reg]);
+       void __iomem *gfer = (void __iomem *)(&lnw->reg_base->GFER[reg]);
+
+       if (gpio < 0 || gpio > lnw->chip.ngpio)
+               return -EINVAL;
+       spin_lock_irqsave(&lnw->lock, flags);
+       if (type & IRQ_TYPE_EDGE_RISING)
+               value = readl(grer) | BIT(gpio % 32);
+       else
+               value = readl(grer) & (~BIT(gpio % 32));
+       writel(value, grer);
+
+       if (type & IRQ_TYPE_EDGE_FALLING)
+               value = readl(gfer) | BIT(gpio % 32);
+       else
+               value = readl(gfer) & (~BIT(gpio % 32));
+       writel(value, gfer);
+       spin_unlock_irqrestore(&lnw->lock, flags);
+
+       return 0;
+};
+
+static void lnw_irq_unmask(unsigned irq)
+{
+       struct lnw_gpio *lnw = get_irq_chip_data(irq);
+       u32 gpio = irq - lnw->irq_base;
+       u8 reg = gpio / 32;
+       void __iomem *gedr;
+
+       gedr = (void __iomem *)(&lnw->reg_base->GEDR[reg]);
+       writel(BIT(gpio % 32), gedr);
+};
+
+static void lnw_irq_mask(unsigned irq)
+{
+};
+
+static struct irq_chip lnw_irqchip = {
+       .name           = "LNW-GPIO",
+       .mask           = lnw_irq_mask,
+       .unmask         = lnw_irq_unmask,
+       .set_type       = lnw_irq_type,
+};
+
+static struct pci_device_id lnw_gpio_ids[] = {
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080f) },
+       { 0, }
+};
+MODULE_DEVICE_TABLE(pci, lnw_gpio_ids);
+
+static void lnw_irq_handler(unsigned irq, struct irq_desc *desc)
+{
+       struct lnw_gpio *lnw = (struct lnw_gpio *)get_irq_data(irq);
+       u32 reg, gpio;
+       void __iomem *gedr;
+       u32 gedr_v;
+
+       /* check GPIO controller to check which pin triggered the interrupt */
+       for (reg = 0; reg < lnw->chip.ngpio / 32; reg++) {
+               gedr = (void __iomem *)(&lnw->reg_base->GEDR[reg]);
+               gedr_v = readl(gedr);
+               if (!gedr_v)
+                       continue;
+               for (gpio = reg*32; gpio < reg*32+32; gpio++) {
+                       gedr_v = readl(gedr);
+                       if (gedr_v & BIT(gpio % 32)) {
+                               pr_debug("pin %d triggered\n", gpio);
+                               generic_handle_irq(lnw->irq_base + gpio);
+                       }
+               }
+               /* clear the edge detect status bit */
+               writel(gedr_v, gedr);
+       }
+       desc->chip->eoi(irq);
+}
+
+static int __devinit lnw_gpio_probe(struct pci_dev *pdev,
+                       const struct pci_device_id *id)
+{
+       void *base;
+       int i;
+       resource_size_t start, len;
+       struct lnw_gpio *lnw;
+       u32 irq_base;
+       u32 gpio_base;
+       int retval = 0;
+
+       retval = pci_enable_device(pdev);
+       if (retval)
+               goto done;
+
+       retval = pci_request_regions(pdev, "langwell_gpio");
+       if (retval) {
+               dev_err(&pdev->dev, "error requesting resources\n");
+               goto err2;
+       }
+       /* get the irq_base from bar1 */
+       start = pci_resource_start(pdev, 1);
+       len = pci_resource_len(pdev, 1);
+       base = ioremap_nocache(start, len);
+       if (!base) {
+               dev_err(&pdev->dev, "error mapping bar1\n");
+               goto err3;
+       }
+       irq_base = *(u32 *)base;
+       gpio_base = *((u32 *)base + 1);
+       /* release the IO mapping, since we already get the info from bar1 */
+       iounmap(base);
+       /* get the register base from bar0 */
+       start = pci_resource_start(pdev, 0);
+       len = pci_resource_len(pdev, 0);
+       base = ioremap_nocache(start, len);
+       if (!base) {
+               dev_err(&pdev->dev, "error mapping bar0\n");
+               retval = -EFAULT;
+               goto err3;
+       }
+
+       lnw = kzalloc(sizeof(struct lnw_gpio), GFP_KERNEL);
+       if (!lnw) {
+               dev_err(&pdev->dev, "can't allocate langwell_gpio chip data\n");
+               retval = -ENOMEM;
+               goto err4;
+       }
+       lnw->reg_base = base;
+       lnw->irq_base = irq_base;
+       lnw->chip.label = dev_name(&pdev->dev);
+       lnw->chip.direction_input = lnw_gpio_direction_input;
+       lnw->chip.direction_output = lnw_gpio_direction_output;
+       lnw->chip.get = lnw_gpio_get;
+       lnw->chip.set = lnw_gpio_set;
+       lnw->chip.to_irq = lnw_gpio_to_irq;
+       lnw->chip.base = gpio_base;
+       lnw->chip.ngpio = 64;
+       lnw->chip.can_sleep = 0;
+       pci_set_drvdata(pdev, lnw);
+       retval = gpiochip_add(&lnw->chip);
+       if (retval) {
+               dev_err(&pdev->dev, "langwell gpiochip_add error %d\n", retval);
+               goto err5;
+       }
+       set_irq_data(pdev->irq, lnw);
+       set_irq_chained_handler(pdev->irq, lnw_irq_handler);
+       for (i = 0; i < lnw->chip.ngpio; i++) {
+               set_irq_chip_and_handler_name(i + lnw->irq_base, &lnw_irqchip,
+                                       handle_simple_irq, "demux");
+               set_irq_chip_data(i + lnw->irq_base, lnw);
+       }
+
+       spin_lock_init(&lnw->lock);
+       goto done;
+err5:
+       kfree(lnw);
+err4:
+       iounmap(base);
+err3:
+       pci_release_regions(pdev);
+err2:
+       pci_disable_device(pdev);
+done:
+       return retval;
+}
+
+static struct pci_driver lnw_gpio_driver = {
+       .name           = "langwell_gpio",
+       .id_table       = lnw_gpio_ids,
+       .probe          = lnw_gpio_probe,
+};
+
+static int __init lnw_gpio_init(void)
+{
+       return pci_register_driver(&lnw_gpio_driver);
+}
+
+device_initcall(lnw_gpio_init);
index 7b82eaae26218c6edb6195b06fb414c790db2c44..480956f1ca50560c58f2c389b99bdbdf6036f38e 100644 (file)
@@ -339,3 +339,4 @@ module_exit(max7301_exit);
 MODULE_AUTHOR("Juergen Beisert");
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("MAX7301 SPI based GPIO-Expander");
+MODULE_ALIAS("spi:" DRIVER_NAME);
diff --git a/drivers/gpio/mc33880.c b/drivers/gpio/mc33880.c
new file mode 100644 (file)
index 0000000..e7d01bd
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * mc33880.c MC33880 high-side/low-side switch GPIO driver
+ * Copyright (c) 2009 Intel Corporation
+ *
+ * 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.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Supports:
+ * Freescale MC33880 high-side/low-side switch
+ */
+
+#include <linux/init.h>
+#include <linux/mutex.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/mc33880.h>
+#include <linux/gpio.h>
+
+#define DRIVER_NAME "mc33880"
+
+/*
+ * Pin configurations, see MAX7301 datasheet page 6
+ */
+#define PIN_CONFIG_MASK 0x03
+#define PIN_CONFIG_IN_PULLUP 0x03
+#define PIN_CONFIG_IN_WO_PULLUP 0x02
+#define PIN_CONFIG_OUT 0x01
+
+#define PIN_NUMBER 8
+
+
+/*
+ * Some registers must be read back to modify.
+ * To save time we cache them here in memory
+ */
+struct mc33880 {
+       struct mutex    lock;   /* protect from simultanous accesses */
+       u8              port_config;
+       struct gpio_chip chip;
+       struct spi_device *spi;
+};
+
+static int mc33880_write_config(struct mc33880 *mc)
+{
+       return spi_write(mc->spi, &mc->port_config, sizeof(mc->port_config));
+}
+
+
+static int __mc33880_set(struct mc33880 *mc, unsigned offset, int value)
+{
+       if (value)
+               mc->port_config |= 1 << offset;
+       else
+               mc->port_config &= ~(1 << offset);
+
+       return mc33880_write_config(mc);
+}
+
+
+static void mc33880_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+       struct mc33880 *mc = container_of(chip, struct mc33880, chip);
+
+       mutex_lock(&mc->lock);
+
+       __mc33880_set(mc, offset, value);
+
+       mutex_unlock(&mc->lock);
+}
+
+static int __devinit mc33880_probe(struct spi_device *spi)
+{
+       struct mc33880 *mc;
+       struct mc33880_platform_data *pdata;
+       int ret;
+
+       pdata = spi->dev.platform_data;
+       if (!pdata || !pdata->base) {
+               dev_dbg(&spi->dev, "incorrect or missing platform data\n");
+               return -EINVAL;
+       }
+
+       /*
+        * bits_per_word cannot be configured in platform data
+        */
+       spi->bits_per_word = 8;
+
+       ret = spi_setup(spi);
+       if (ret < 0)
+               return ret;
+
+       mc = kzalloc(sizeof(struct mc33880), GFP_KERNEL);
+       if (!mc)
+               return -ENOMEM;
+
+       mutex_init(&mc->lock);
+
+       dev_set_drvdata(&spi->dev, mc);
+
+       mc->spi = spi;
+
+       mc->chip.label = DRIVER_NAME,
+       mc->chip.set = mc33880_set;
+       mc->chip.base = pdata->base;
+       mc->chip.ngpio = PIN_NUMBER;
+       mc->chip.can_sleep = 1;
+       mc->chip.dev = &spi->dev;
+       mc->chip.owner = THIS_MODULE;
+
+       mc->port_config = 0x00;
+       /* write twice, because during initialisation the first setting
+        * is just for testing SPI communication, and the second is the
+        * "real" configuration
+        */
+       ret = mc33880_write_config(mc);
+       mc->port_config = 0x00;
+       if (!ret)
+               ret = mc33880_write_config(mc);
+
+       if (ret) {
+               printk(KERN_ERR "Failed writing to " DRIVER_NAME ": %d\n", ret);
+               goto exit_destroy;
+       }
+
+       ret = gpiochip_add(&mc->chip);
+       if (ret)
+               goto exit_destroy;
+
+       return ret;
+
+exit_destroy:
+       dev_set_drvdata(&spi->dev, NULL);
+       mutex_destroy(&mc->lock);
+       kfree(mc);
+       return ret;
+}
+
+static int mc33880_remove(struct spi_device *spi)
+{
+       struct mc33880 *mc;
+       int ret;
+
+       mc = dev_get_drvdata(&spi->dev);
+       if (mc == NULL)
+               return -ENODEV;
+
+       dev_set_drvdata(&spi->dev, NULL);
+
+       ret = gpiochip_remove(&mc->chip);
+       if (!ret) {
+               mutex_destroy(&mc->lock);
+               kfree(mc);
+       } else
+               dev_err(&spi->dev, "Failed to remove the GPIO controller: %d\n",
+                       ret);
+
+       return ret;
+}
+
+static struct spi_driver mc33880_driver = {
+       .driver = {
+               .name           = DRIVER_NAME,
+               .owner          = THIS_MODULE,
+       },
+       .probe          = mc33880_probe,
+       .remove         = __devexit_p(mc33880_remove),
+};
+
+static int __init mc33880_init(void)
+{
+       return spi_register_driver(&mc33880_driver);
+}
+/* register after spi postcore initcall and before
+ * subsys initcalls that may rely on these GPIOs
+ */
+subsys_initcall(mc33880_init);
+
+static void __exit mc33880_exit(void)
+{
+       spi_unregister_driver(&mc33880_driver);
+}
+module_exit(mc33880_exit);
+
+MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>");
+MODULE_LICENSE("GPL v2");
+
index f6fae0e50e654731e2fc235b6d562e2a669b3627..cd651ec8d0349e1621e0ef941dea3db489d86c0c 100644 (file)
@@ -6,12 +6,10 @@
 #include <linux/device.h>
 #include <linux/workqueue.h>
 #include <linux/mutex.h>
-
+#include <linux/gpio.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/mcp23s08.h>
 
-#include <asm/gpio.h>
-
 
 /* Registers are all 8 bits wide.
  *
@@ -433,3 +431,4 @@ static void __exit mcp23s08_exit(void)
 module_exit(mcp23s08_exit);
 
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("spi:mcp23s08");
index cdb6574d25a698a26fd7c428037ae836cc4929dd..6a2fb3fbb3d965bae1956b0bf9b3bc6f307b22c7 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/gpio.h>
 #include <linux/i2c.h>
 #include <linux/i2c/pca953x.h>
 #ifdef CONFIG_OF_GPIO
@@ -20,8 +21,6 @@
 #include <linux/of_gpio.h>
 #endif
 
-#include <asm/gpio.h>
-
 #define PCA953X_INPUT          0
 #define PCA953X_OUTPUT         1
 #define PCA953X_INVERT         2
@@ -40,6 +39,7 @@ static const struct i2c_device_id pca953x_id[] = {
        { "pca9557", 8, },
 
        { "max7310", 8, },
+       { "max7315", 8, },
        { "pca6107", 8, },
        { "tca6408", 8, },
        { "tca6416", 16, },
index 9525724be731d400f781a36e2354c76b8c5ff699..72f2449c1c8740e8e8cdcc9472da4921a0b5e839 100644 (file)
 
 #include <linux/kernel.h>
 #include <linux/slab.h>
+#include <linux/gpio.h>
 #include <linux/i2c.h>
 #include <linux/i2c/pcf857x.h>
 
-#include <asm/gpio.h>
-
 
 static const struct i2c_device_id pcf857x_id[] = {
        { "pcf8574", 8 },
diff --git a/drivers/gpio/ucb1400_gpio.c b/drivers/gpio/ucb1400_gpio.c
new file mode 100644 (file)
index 0000000..50e6bd1
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Philips UCB1400 GPIO driver
+ *
+ * Author: Marek Vasut <marek.vasut@gmail.com>
+ *
+ * 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/module.h>
+#include <linux/ucb1400.h>
+
+struct ucb1400_gpio_data *ucbdata;
+
+static int ucb1400_gpio_dir_in(struct gpio_chip *gc, unsigned off)
+{
+       struct ucb1400_gpio *gpio;
+       gpio = container_of(gc, struct ucb1400_gpio, gc);
+       ucb1400_gpio_set_direction(gpio->ac97, off, 0);
+       return 0;
+}
+
+static int ucb1400_gpio_dir_out(struct gpio_chip *gc, unsigned off, int val)
+{
+       struct ucb1400_gpio *gpio;
+       gpio = container_of(gc, struct ucb1400_gpio, gc);
+       ucb1400_gpio_set_direction(gpio->ac97, off, 1);
+       ucb1400_gpio_set_value(gpio->ac97, off, val);
+       return 0;
+}
+
+static int ucb1400_gpio_get(struct gpio_chip *gc, unsigned off)
+{
+       struct ucb1400_gpio *gpio;
+       gpio = container_of(gc, struct ucb1400_gpio, gc);
+       return ucb1400_gpio_get_value(gpio->ac97, off);
+}
+
+static void ucb1400_gpio_set(struct gpio_chip *gc, unsigned off, int val)
+{
+       struct ucb1400_gpio *gpio;
+       gpio = container_of(gc, struct ucb1400_gpio, gc);
+       ucb1400_gpio_set_value(gpio->ac97, off, val);
+}
+
+static int ucb1400_gpio_probe(struct platform_device *dev)
+{
+       struct ucb1400_gpio *ucb = dev->dev.platform_data;
+       int err = 0;
+
+       if (!(ucbdata && ucbdata->gpio_offset)) {
+               err = -EINVAL;
+               goto err;
+       }
+
+       platform_set_drvdata(dev, ucb);
+
+       ucb->gc.label = "ucb1400_gpio";
+       ucb->gc.base = ucbdata->gpio_offset;
+       ucb->gc.ngpio = 10;
+       ucb->gc.owner = THIS_MODULE;
+
+       ucb->gc.direction_input = ucb1400_gpio_dir_in;
+       ucb->gc.direction_output = ucb1400_gpio_dir_out;
+       ucb->gc.get = ucb1400_gpio_get;
+       ucb->gc.set = ucb1400_gpio_set;
+       ucb->gc.can_sleep = 1;
+
+       err = gpiochip_add(&ucb->gc);
+       if (err)
+               goto err;
+
+       if (ucbdata && ucbdata->gpio_setup)
+               err = ucbdata->gpio_setup(&dev->dev, ucb->gc.ngpio);
+
+err:
+       return err;
+
+}
+
+static int ucb1400_gpio_remove(struct platform_device *dev)
+{
+       int err = 0;
+       struct ucb1400_gpio *ucb = platform_get_drvdata(dev);
+
+       if (ucbdata && ucbdata->gpio_teardown) {
+               err = ucbdata->gpio_teardown(&dev->dev, ucb->gc.ngpio);
+               if (err)
+                       return err;
+       }
+
+       err = gpiochip_remove(&ucb->gc);
+       return err;
+}
+
+static struct platform_driver ucb1400_gpio_driver = {
+       .probe  = ucb1400_gpio_probe,
+       .remove = ucb1400_gpio_remove,
+       .driver = {
+               .name   = "ucb1400_gpio"
+       },
+};
+
+static int __init ucb1400_gpio_init(void)
+{
+       return platform_driver_register(&ucb1400_gpio_driver);
+}
+
+static void __exit ucb1400_gpio_exit(void)
+{
+       platform_driver_unregister(&ucb1400_gpio_driver);
+}
+
+void __init ucb1400_gpio_set_data(struct ucb1400_gpio_data *data)
+{
+       ucbdata = data;
+}
+
+module_init(ucb1400_gpio_init);
+module_exit(ucb1400_gpio_exit);
+
+MODULE_DESCRIPTION("Philips UCB1400 GPIO driver");
+MODULE_LICENSE("GPL");
index 242294db3db6b1d6bca65b9c4208f83f25456df7..5e9e095f11369cc14102ca510a4e0d5ca066d1da 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
 #include <linux/mutex.h>
+#include <linux/mod_devicetable.h>
 #include <linux/spi/spi.h>
 
 #define DRVNAME                "adcxx"
@@ -157,8 +158,9 @@ static struct sensor_device_attribute ad_input[] = {
 
 /*----------------------------------------------------------------------*/
 
-static int __devinit adcxx_probe(struct spi_device *spi, int channels)
+static int __devinit adcxx_probe(struct spi_device *spi)
 {
+       int channels = spi_get_device_id(spi)->driver_data;
        struct adcxx *adc;
        int status;
        int i;
@@ -204,26 +206,6 @@ out_err:
        return status;
 }
 
-static int __devinit adcxx1s_probe(struct spi_device *spi)
-{
-       return adcxx_probe(spi, 1);
-}
-
-static int __devinit adcxx2s_probe(struct spi_device *spi)
-{
-       return adcxx_probe(spi, 2);
-}
-
-static int __devinit adcxx4s_probe(struct spi_device *spi)
-{
-       return adcxx_probe(spi, 4);
-}
-
-static int __devinit adcxx8s_probe(struct spi_device *spi)
-{
-       return adcxx_probe(spi, 8);
-}
-
 static int __devexit adcxx_remove(struct spi_device *spi)
 {
        struct adcxx *adc = dev_get_drvdata(&spi->dev);
@@ -241,79 +223,33 @@ static int __devexit adcxx_remove(struct spi_device *spi)
        return 0;
 }
 
-static struct spi_driver adcxx1s_driver = {
-       .driver = {
-               .name   = "adcxx1s",
-               .owner  = THIS_MODULE,
-       },
-       .probe  = adcxx1s_probe,
-       .remove = __devexit_p(adcxx_remove),
+static const struct spi_device_id adcxx_ids[] = {
+       { "adcxx1s", 1 },
+       { "adcxx2s", 2 },
+       { "adcxx4s", 4 },
+       { "adcxx8s", 8 },
+       { },
 };
+MODULE_DEVICE_TABLE(spi, adcxx_ids);
 
-static struct spi_driver adcxx2s_driver = {
+static struct spi_driver adcxx_driver = {
        .driver = {
-               .name   = "adcxx2s",
+               .name   = "adcxx",
                .owner  = THIS_MODULE,
        },
-       .probe  = adcxx2s_probe,
-       .remove = __devexit_p(adcxx_remove),
-};
-
-static struct spi_driver adcxx4s_driver = {
-       .driver = {
-               .name   = "adcxx4s",
-               .owner  = THIS_MODULE,
-       },
-       .probe  = adcxx4s_probe,
-       .remove = __devexit_p(adcxx_remove),
-};
-
-static struct spi_driver adcxx8s_driver = {
-       .driver = {
-               .name   = "adcxx8s",
-               .owner  = THIS_MODULE,
-       },
-       .probe  = adcxx8s_probe,
+       .id_table = adcxx_ids,
+       .probe  = adcxx_probe,
        .remove = __devexit_p(adcxx_remove),
 };
 
 static int __init init_adcxx(void)
 {
-       int status;
-       status = spi_register_driver(&adcxx1s_driver);
-       if (status)
-               goto reg_1_failed;
-
-       status = spi_register_driver(&adcxx2s_driver);
-       if (status)
-               goto reg_2_failed;
-
-       status = spi_register_driver(&adcxx4s_driver);
-       if (status)
-               goto reg_4_failed;
-
-       status = spi_register_driver(&adcxx8s_driver);
-       if (status)
-               goto reg_8_failed;
-
-       return status;
-
-reg_8_failed:
-       spi_unregister_driver(&adcxx4s_driver);
-reg_4_failed:
-       spi_unregister_driver(&adcxx2s_driver);
-reg_2_failed:
-       spi_unregister_driver(&adcxx1s_driver);
-reg_1_failed:
-       return status;
+       return spi_register_driver(&adcxx_driver);
 }
 
 static void __exit exit_adcxx(void)
 {
-       spi_unregister_driver(&adcxx1s_driver);
-       spi_unregister_driver(&adcxx2s_driver);
-       spi_unregister_driver(&adcxx4s_driver);
-       spi_unregister_driver(&adcxx8s_driver);
+       spi_unregister_driver(&adcxx_driver);
 }
 
 module_init(init_adcxx);
@@ -322,8 +258,3 @@ module_exit(exit_adcxx);
 MODULE_AUTHOR("Marc Pignat");
 MODULE_DESCRIPTION("National Semiconductor adcxx8sxxx Linux driver");
 MODULE_LICENSE("GPL");
-
-MODULE_ALIAS("adcxx1s");
-MODULE_ALIAS("adcxx2s");
-MODULE_ALIAS("adcxx4s");
-MODULE_ALIAS("adcxx8s");
index 9814d51b3af42893b607a5106b2e4030b3b87ecf..2c2cb1ec94c5f1a22ea47a6607c8408a4fe588c7 100644 (file)
@@ -1134,7 +1134,7 @@ static ssize_t show_pwm(struct device *dev, struct device_attribute *attr,
                res = PWM_FREQ_FROM_REG(data->pwm_freq[ix]);
                break;
        case SYS_PWM_ENABLE:
-               if (ix > 3) {
+               if (ix >= 3) {
                        res = 1; /* pwm[5-6] hard-wired to manual mode */
                } else {
                        res = PWM_EN_FROM_REG(data->pwm_config[ix]);
index 82ebca5a699c7954d9f0a02aa19b47fb73bc2f4c..ecd739534f6a4a76c674fd5323daa8a30fcaf2a7 100644 (file)
@@ -139,4 +139,4 @@ module_exit(lis302dl_exit);
 MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
 MODULE_DESCRIPTION("lis3lv02d SPI glue layer");
 MODULE_LICENSE("GPL");
-
+MODULE_ALIAS("spi:" DRV_NAME);
index ae6204f33214d4ffa80a61417fe2e4ed669099a5..ab8a5d3c769048a1a15635c09648740bad64e9ef 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/sysfs.h>
 #include <linux/hwmon.h>
 #include <linux/mutex.h>
+#include <linux/mod_devicetable.h>
 #include <linux/spi/spi.h>
 
 
@@ -130,11 +131,20 @@ static DEVICE_ATTR(name, S_IRUGO, lm70_show_name, NULL);
 
 /*----------------------------------------------------------------------*/
 
-static int __devinit common_probe(struct spi_device *spi, int chip)
+static int __devinit lm70_probe(struct spi_device *spi)
 {
+       int chip = spi_get_device_id(spi)->driver_data;
        struct lm70 *p_lm70;
        int status;
 
+       /* signaling is SPI_MODE_0 for both LM70 and TMP121 */
+       if (spi->mode & (SPI_CPOL | SPI_CPHA))
+               return -EINVAL;
+
+       /* 3-wire link (shared SI/SO) for LM70 */
+       if (chip == LM70_CHIP_LM70 && !(spi->mode & SPI_3WIRE))
+               return -EINVAL;
+
        /* NOTE:  we assume 8-bit words, and convert to 16 bits manually */
 
        p_lm70 = kzalloc(sizeof *p_lm70, GFP_KERNEL);
@@ -170,24 +180,6 @@ out_dev_reg_failed:
        return status;
 }
 
-static int __devinit lm70_probe(struct spi_device *spi)
-{
-       /* signaling is SPI_MODE_0 on a 3-wire link (shared SI/SO) */
-       if ((spi->mode & (SPI_CPOL | SPI_CPHA)) || !(spi->mode & SPI_3WIRE))
-               return -EINVAL;
-
-       return common_probe(spi, LM70_CHIP_LM70);
-}
-
-static int __devinit tmp121_probe(struct spi_device *spi)
-{
-       /* signaling is SPI_MODE_0 with only MISO connected */
-       if (spi->mode & (SPI_CPOL | SPI_CPHA))
-               return -EINVAL;
-
-       return common_probe(spi, LM70_CHIP_TMP121);
-}
-
 static int __devexit lm70_remove(struct spi_device *spi)
 {
        struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev);
@@ -201,41 +193,32 @@ static int __devexit lm70_remove(struct spi_device *spi)
        return 0;
 }
 
-static struct spi_driver tmp121_driver = {
-       .driver = {
-               .name   = "tmp121",
-               .owner  = THIS_MODULE,
-       },
-       .probe  = tmp121_probe,
-       .remove = __devexit_p(lm70_remove),
+
+static const struct spi_device_id lm70_ids[] = {
+       { "lm70",   LM70_CHIP_LM70 },
+       { "tmp121", LM70_CHIP_TMP121 },
+       { },
 };
+MODULE_DEVICE_TABLE(spi, lm70_ids);
 
 static struct spi_driver lm70_driver = {
        .driver = {
                .name   = "lm70",
                .owner  = THIS_MODULE,
        },
+       .id_table = lm70_ids,
        .probe  = lm70_probe,
        .remove = __devexit_p(lm70_remove),
 };
 
 static int __init init_lm70(void)
 {
-       int ret = spi_register_driver(&lm70_driver);
-       if (ret)
-               return ret;
-
-       ret = spi_register_driver(&tmp121_driver);
-       if (ret)
-               spi_unregister_driver(&lm70_driver);
-
-       return ret;
+       return spi_register_driver(&lm70_driver);
 }
 
 static void __exit cleanup_lm70(void)
 {
        spi_unregister_driver(&lm70_driver);
-       spi_unregister_driver(&tmp121_driver);
 }
 
 module_init(init_lm70);
index bfaa665ccf324a25d9e40368135f24b876d0b8d6..9ac497271adfa06e160de4811fc8450b0ecf153b 100644 (file)
@@ -242,3 +242,4 @@ module_exit(max1111_exit);
 MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");
 MODULE_DESCRIPTION("MAX1111 ADC Driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("spi:max1111");
index 7663a2a9f130430c9ba80a8123d519ca9a1fbad9..7550a534005c9a6d002a8b77284125c9522d6ccd 100644 (file)
@@ -2463,7 +2463,7 @@ int ehca_create_busmap(void)
        int ret;
 
        ehca_mr_len = 0;
-       ret = walk_memory_resource(0, 1ULL << MAX_PHYSMEM_BITS, NULL,
+       ret = walk_system_ram_range(0, 1ULL << MAX_PHYSMEM_BITS, NULL,
                                   ehca_create_busmap_callback);
        return ret;
 }
index ecaeb7e8e75e169c58f0a9c9ef244244e70a38f9..eb83939c705e70141147619b4f550ea368c6b88f 100644 (file)
@@ -842,3 +842,4 @@ module_exit(ad7877_exit);
 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
 MODULE_DESCRIPTION("AD7877 touchscreen Driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("spi:ad7877");
index 5d8a703988077561894a26849a78594b810fc39e..19b4db7e974d75c42eb3f7e9e21e8c19ac8d782e 100644 (file)
@@ -779,3 +779,4 @@ module_exit(ad7879_exit);
 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
 MODULE_DESCRIPTION("AD7879(-1) touchscreen Driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("spi:ad7879");
index ba9d38c3f412a7a1526f028f5cf2a2c8863f1ed8..09c810999b924137576b8df59e10e5be8feb667b 100644 (file)
@@ -1256,3 +1256,4 @@ module_exit(ads7846_exit);
 
 MODULE_DESCRIPTION("ADS7846 TouchScreen Driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("spi:ads7846");
index 50ed778f63fc84cd3c31da19a15b1f6bd60f5754..09d4db764d22736e344085ce9d1b35d71791da5a 100644 (file)
@@ -89,14 +89,14 @@ static int contrstats_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations seq_controller_ops = {
+static const struct seq_operations seq_controller_ops = {
        .start  = controller_start,
        .next   = controller_next,
        .stop   = controller_stop,
        .show   = controller_show,
 };
 
-static struct seq_operations seq_contrstats_ops = {
+static const struct seq_operations seq_contrstats_ops = {
        .start  = controller_start,
        .next   = controller_next,
        .stop   = controller_stop,
@@ -194,14 +194,14 @@ applstats_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations seq_applications_ops = {
+static const struct seq_operations seq_applications_ops = {
        .start  = applications_start,
        .next   = applications_next,
        .stop   = applications_stop,
        .show   = applications_show,
 };
 
-static struct seq_operations seq_applstats_ops = {
+static const struct seq_operations seq_applstats_ops = {
        .start  = applications_start,
        .next   = applications_next,
        .stop   = applications_stop,
@@ -264,7 +264,7 @@ static int capi_driver_show(struct seq_file *seq, void *v)
        return 0;
 }
 
-static struct seq_operations seq_capi_driver_ops = {
+static const struct seq_operations seq_capi_driver_ops = {
        .start  = capi_driver_start,
        .next   = capi_driver_next,
        .stop   = capi_driver_stop,
index 098d9aae7259e1a7dc117c6143eb1be57a45b7fa..2913d76ad3d254f45d29a914dc40d8b177f20803 100644 (file)
@@ -148,3 +148,4 @@ module_exit(dac124s085_leds_exit);
 MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>");
 MODULE_DESCRIPTION("DAC124S085 LED driver");
 MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("spi:dac124s085");
index 016be4938e4c4baac63168e2c478f335ae162ed9..8762889179763eb2a019c7867a72b1cbecd9dbad 100644 (file)
@@ -548,3 +548,4 @@ module_exit(ezx_pcap_exit);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Daniel Ribeiro / Harald Welte");
 MODULE_DESCRIPTION("Motorola PCAP2 ASIC Driver");
+MODULE_ALIAS("spi:ezx-pcap");
index 78c2135c5de65f8717bb92bed2498429bc4df871..2afc08006e6d1db891f995445a351c59186165fd 100644 (file)
@@ -48,9 +48,11 @@ static int ucb1400_core_probe(struct device *dev)
        int err;
        struct ucb1400 *ucb;
        struct ucb1400_ts ucb_ts;
+       struct ucb1400_gpio ucb_gpio;
        struct snd_ac97 *ac97;
 
        memset(&ucb_ts, 0, sizeof(ucb_ts));
+       memset(&ucb_gpio, 0, sizeof(ucb_gpio));
 
        ucb = kzalloc(sizeof(struct ucb1400), GFP_KERNEL);
        if (!ucb) {
@@ -68,25 +70,44 @@ static int ucb1400_core_probe(struct device *dev)
                goto err0;
        }
 
+       /* GPIO */
+       ucb_gpio.ac97 = ac97;
+       ucb->ucb1400_gpio = platform_device_alloc("ucb1400_gpio", -1);
+       if (!ucb->ucb1400_gpio) {
+               err = -ENOMEM;
+               goto err0;
+       }
+       err = platform_device_add_data(ucb->ucb1400_gpio, &ucb_gpio,
+                                       sizeof(ucb_gpio));
+       if (err)
+               goto err1;
+       err = platform_device_add(ucb->ucb1400_gpio);
+       if (err)
+               goto err1;
+
        /* TOUCHSCREEN */
        ucb_ts.ac97 = ac97;
        ucb->ucb1400_ts = platform_device_alloc("ucb1400_ts", -1);
        if (!ucb->ucb1400_ts) {
                err = -ENOMEM;
-               goto err0;
+               goto err2;
        }
        err = platform_device_add_data(ucb->ucb1400_ts, &ucb_ts,
                                        sizeof(ucb_ts));
        if (err)
-               goto err1;
+               goto err3;
        err = platform_device_add(ucb->ucb1400_ts);
        if (err)
-               goto err1;
+               goto err3;
 
        return 0;
 
-err1:
+err3:
        platform_device_put(ucb->ucb1400_ts);
+err2:
+       platform_device_unregister(ucb->ucb1400_gpio);
+err1:
+       platform_device_put(ucb->ucb1400_gpio);
 err0:
        kfree(ucb);
 err:
@@ -98,6 +119,8 @@ static int ucb1400_core_remove(struct device *dev)
        struct ucb1400 *ucb = dev_get_drvdata(dev);
 
        platform_device_unregister(ucb->ucb1400_ts);
+       platform_device_unregister(ucb->ucb1400_gpio);
+
        kfree(ucb);
        return 0;
 }
index 2e535a0ccd5e274c1fc46b700a07a45953022ba8..d902d81dde397a2793f0709b0da9135922050f75 100644 (file)
@@ -417,4 +417,4 @@ module_exit(at25_exit);
 MODULE_DESCRIPTION("Driver for most SPI EEPROMs");
 MODULE_AUTHOR("David Brownell");
 MODULE_LICENSE("GPL");
-
+MODULE_ALIAS("spi:at25");
index 1bfe5d16963b9ece644b25c5bb81a411d2c1045f..3648b23d5c92bea5a7697b5a89e81f2cff85c9e6 100644 (file)
@@ -283,7 +283,7 @@ static int __init lkdtm_module_init(void)
 
        switch (cpoint) {
        case INT_HARDWARE_ENTRY:
-               lkdtm.kp.symbol_name = "__do_IRQ";
+               lkdtm.kp.symbol_name = "do_IRQ";
                lkdtm.entry = (kprobe_opcode_t*) jp_do_irq;
                break;
        case INT_HW_IRQ_EN:
index d84c880fac84f41a0d388540d74d22a4a7649705..7dab2e5f4bc9c87c53779a3d49cf2cb368114ef7 100644 (file)
@@ -343,6 +343,101 @@ unsigned int mmc_align_data_size(struct mmc_card *card, unsigned int sz)
 }
 EXPORT_SYMBOL(mmc_align_data_size);
 
+/**
+ *     mmc_host_enable - enable a host.
+ *     @host: mmc host to enable
+ *
+ *     Hosts that support power saving can use the 'enable' and 'disable'
+ *     methods to exit and enter power saving states. For more information
+ *     see comments for struct mmc_host_ops.
+ */
+int mmc_host_enable(struct mmc_host *host)
+{
+       if (!(host->caps & MMC_CAP_DISABLE))
+               return 0;
+
+       if (host->en_dis_recurs)
+               return 0;
+
+       if (host->nesting_cnt++)
+               return 0;
+
+       cancel_delayed_work_sync(&host->disable);
+
+       if (host->enabled)
+               return 0;
+
+       if (host->ops->enable) {
+               int err;
+
+               host->en_dis_recurs = 1;
+               err = host->ops->enable(host);
+               host->en_dis_recurs = 0;
+
+               if (err) {
+                       pr_debug("%s: enable error %d\n",
+                                mmc_hostname(host), err);
+                       return err;
+               }
+       }
+       host->enabled = 1;
+       return 0;
+}
+EXPORT_SYMBOL(mmc_host_enable);
+
+static int mmc_host_do_disable(struct mmc_host *host, int lazy)
+{
+       if (host->ops->disable) {
+               int err;
+
+               host->en_dis_recurs = 1;
+               err = host->ops->disable(host, lazy);
+               host->en_dis_recurs = 0;
+
+               if (err < 0) {
+                       pr_debug("%s: disable error %d\n",
+                                mmc_hostname(host), err);
+                       return err;
+               }
+               if (err > 0) {
+                       unsigned long delay = msecs_to_jiffies(err);
+
+                       mmc_schedule_delayed_work(&host->disable, delay);
+               }
+       }
+       host->enabled = 0;
+       return 0;
+}
+
+/**
+ *     mmc_host_disable - disable a host.
+ *     @host: mmc host to disable
+ *
+ *     Hosts that support power saving can use the 'enable' and 'disable'
+ *     methods to exit and enter power saving states. For more information
+ *     see comments for struct mmc_host_ops.
+ */
+int mmc_host_disable(struct mmc_host *host)
+{
+       int err;
+
+       if (!(host->caps & MMC_CAP_DISABLE))
+               return 0;
+
+       if (host->en_dis_recurs)
+               return 0;
+
+       if (--host->nesting_cnt)
+               return 0;
+
+       if (!host->enabled)
+               return 0;
+
+       err = mmc_host_do_disable(host, 0);
+       return err;
+}
+EXPORT_SYMBOL(mmc_host_disable);
+
 /**
  *     __mmc_claim_host - exclusively claim a host
  *     @host: mmc host to claim
@@ -366,24 +461,110 @@ int __mmc_claim_host(struct mmc_host *host, atomic_t *abort)
        while (1) {
                set_current_state(TASK_UNINTERRUPTIBLE);
                stop = abort ? atomic_read(abort) : 0;
-               if (stop || !host->claimed)
+               if (stop || !host->claimed || host->claimer == current)
                        break;
                spin_unlock_irqrestore(&host->lock, flags);
                schedule();
                spin_lock_irqsave(&host->lock, flags);
        }
        set_current_state(TASK_RUNNING);
-       if (!stop)
+       if (!stop) {
                host->claimed = 1;
-       else
+               host->claimer = current;
+               host->claim_cnt += 1;
+       } else
                wake_up(&host->wq);
        spin_unlock_irqrestore(&host->lock, flags);
        remove_wait_queue(&host->wq, &wait);
+       if (!stop)
+               mmc_host_enable(host);
        return stop;
 }
 
 EXPORT_SYMBOL(__mmc_claim_host);
 
+/**
+ *     mmc_try_claim_host - try exclusively to claim a host
+ *     @host: mmc host to claim
+ *
+ *     Returns %1 if the host is claimed, %0 otherwise.
+ */
+int mmc_try_claim_host(struct mmc_host *host)
+{
+       int claimed_host = 0;
+       unsigned long flags;
+
+       spin_lock_irqsave(&host->lock, flags);
+       if (!host->claimed || host->claimer == current) {
+               host->claimed = 1;
+               host->claimer = current;
+               host->claim_cnt += 1;
+               claimed_host = 1;
+       }
+       spin_unlock_irqrestore(&host->lock, flags);
+       return claimed_host;
+}
+EXPORT_SYMBOL(mmc_try_claim_host);
+
+static void mmc_do_release_host(struct mmc_host *host)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&host->lock, flags);
+       if (--host->claim_cnt) {
+               /* Release for nested claim */
+               spin_unlock_irqrestore(&host->lock, flags);
+       } else {
+               host->claimed = 0;
+               host->claimer = NULL;
+               spin_unlock_irqrestore(&host->lock, flags);
+               wake_up(&host->wq);
+       }
+}
+
+void mmc_host_deeper_disable(struct work_struct *work)
+{
+       struct mmc_host *host =
+               container_of(work, struct mmc_host, disable.work);
+
+       /* If the host is claimed then we do not want to disable it anymore */
+       if (!mmc_try_claim_host(host))
+               return;
+       mmc_host_do_disable(host, 1);
+       mmc_do_release_host(host);
+}
+
+/**
+ *     mmc_host_lazy_disable - lazily disable a host.
+ *     @host: mmc host to disable
+ *
+ *     Hosts that support power saving can use the 'enable' and 'disable'
+ *     methods to exit and enter power saving states. For more information
+ *     see comments for struct mmc_host_ops.
+ */
+int mmc_host_lazy_disable(struct mmc_host *host)
+{
+       if (!(host->caps & MMC_CAP_DISABLE))
+               return 0;
+
+       if (host->en_dis_recurs)
+               return 0;
+
+       if (--host->nesting_cnt)
+               return 0;
+
+       if (!host->enabled)
+               return 0;
+
+       if (host->disable_delay) {
+               mmc_schedule_delayed_work(&host->disable,
+                               msecs_to_jiffies(host->disable_delay));
+               return 0;
+       } else
+               return mmc_host_do_disable(host, 1);
+}
+EXPORT_SYMBOL(mmc_host_lazy_disable);
+
 /**
  *     mmc_release_host - release a host
  *     @host: mmc host to release
@@ -393,15 +574,11 @@ EXPORT_SYMBOL(__mmc_claim_host);
  */
 void mmc_release_host(struct mmc_host *host)
 {
-       unsigned long flags;
-
        WARN_ON(!host->claimed);
 
-       spin_lock_irqsave(&host->lock, flags);
-       host->claimed = 0;
-       spin_unlock_irqrestore(&host->lock, flags);
+       mmc_host_lazy_disable(host);
 
-       wake_up(&host->wq);
+       mmc_do_release_host(host);
 }
 
 EXPORT_SYMBOL(mmc_release_host);
@@ -687,7 +864,13 @@ void mmc_set_timing(struct mmc_host *host, unsigned int timing)
  */
 static void mmc_power_up(struct mmc_host *host)
 {
-       int bit = fls(host->ocr_avail) - 1;
+       int bit;
+
+       /* If ocr is set, we use it */
+       if (host->ocr)
+               bit = ffs(host->ocr) - 1;
+       else
+               bit = fls(host->ocr_avail) - 1;
 
        host->ios.vdd = bit;
        if (mmc_host_is_spi(host)) {
@@ -947,6 +1130,8 @@ void mmc_stop_host(struct mmc_host *host)
        spin_unlock_irqrestore(&host->lock, flags);
 #endif
 
+       if (host->caps & MMC_CAP_DISABLE)
+               cancel_delayed_work(&host->disable);
        cancel_delayed_work(&host->detect);
        mmc_flush_scheduled_work();
 
@@ -958,6 +1143,8 @@ void mmc_stop_host(struct mmc_host *host)
                mmc_claim_host(host);
                mmc_detach_bus(host);
                mmc_release_host(host);
+               mmc_bus_put(host);
+               return;
        }
        mmc_bus_put(host);
 
@@ -966,6 +1153,80 @@ void mmc_stop_host(struct mmc_host *host)
        mmc_power_off(host);
 }
 
+void mmc_power_save_host(struct mmc_host *host)
+{
+       mmc_bus_get(host);
+
+       if (!host->bus_ops || host->bus_dead || !host->bus_ops->power_restore) {
+               mmc_bus_put(host);
+               return;
+       }
+
+       if (host->bus_ops->power_save)
+               host->bus_ops->power_save(host);
+
+       mmc_bus_put(host);
+
+       mmc_power_off(host);
+}
+EXPORT_SYMBOL(mmc_power_save_host);
+
+void mmc_power_restore_host(struct mmc_host *host)
+{
+       mmc_bus_get(host);
+
+       if (!host->bus_ops || host->bus_dead || !host->bus_ops->power_restore) {
+               mmc_bus_put(host);
+               return;
+       }
+
+       mmc_power_up(host);
+       host->bus_ops->power_restore(host);
+
+       mmc_bus_put(host);
+}
+EXPORT_SYMBOL(mmc_power_restore_host);
+
+int mmc_card_awake(struct mmc_host *host)
+{
+       int err = -ENOSYS;
+
+       mmc_bus_get(host);
+
+       if (host->bus_ops && !host->bus_dead && host->bus_ops->awake)
+               err = host->bus_ops->awake(host);
+
+       mmc_bus_put(host);
+
+       return err;
+}
+EXPORT_SYMBOL(mmc_card_awake);
+
+int mmc_card_sleep(struct mmc_host *host)
+{
+       int err = -ENOSYS;
+
+       mmc_bus_get(host);
+
+       if (host->bus_ops && !host->bus_dead && host->bus_ops->awake)
+               err = host->bus_ops->sleep(host);
+
+       mmc_bus_put(host);
+
+       return err;
+}
+EXPORT_SYMBOL(mmc_card_sleep);
+
+int mmc_card_can_sleep(struct mmc_host *host)
+{
+       struct mmc_card *card = host->card;
+
+       if (card && mmc_card_mmc(card) && card->ext_csd.rev >= 3)
+               return 1;
+       return 0;
+}
+EXPORT_SYMBOL(mmc_card_can_sleep);
+
 #ifdef CONFIG_PM
 
 /**
@@ -975,27 +1236,36 @@ void mmc_stop_host(struct mmc_host *host)
  */
 int mmc_suspend_host(struct mmc_host *host, pm_message_t state)
 {
+       int err = 0;
+
+       if (host->caps & MMC_CAP_DISABLE)
+               cancel_delayed_work(&host->disable);
        cancel_delayed_work(&host->detect);
        mmc_flush_scheduled_work();
 
        mmc_bus_get(host);
        if (host->bus_ops && !host->bus_dead) {
                if (host->bus_ops->suspend)
-                       host->bus_ops->suspend(host);
-               if (!host->bus_ops->resume) {
+                       err = host->bus_ops->suspend(host);
+               if (err == -ENOSYS || !host->bus_ops->resume) {
+                       /*
+                        * We simply "remove" the card in this case.
+                        * It will be redetected on resume.
+                        */
                        if (host->bus_ops->remove)
                                host->bus_ops->remove(host);
-
                        mmc_claim_host(host);
                        mmc_detach_bus(host);
                        mmc_release_host(host);
+                       err = 0;
                }
        }
        mmc_bus_put(host);
 
-       mmc_power_off(host);
+       if (!err)
+               mmc_power_off(host);
 
-       return 0;
+       return err;
 }
 
 EXPORT_SYMBOL(mmc_suspend_host);
@@ -1006,12 +1276,26 @@ EXPORT_SYMBOL(mmc_suspend_host);
  */
 int mmc_resume_host(struct mmc_host *host)
 {
+       int err = 0;
+
        mmc_bus_get(host);
        if (host->bus_ops && !host->bus_dead) {
                mmc_power_up(host);
                mmc_select_voltage(host, host->ocr);
                BUG_ON(!host->bus_ops->resume);
-               host->bus_ops->resume(host);
+               err = host->bus_ops->resume(host);
+               if (err) {
+                       printk(KERN_WARNING "%s: error %d during resume "
+                                           "(card was removed?)\n",
+                                           mmc_hostname(host), err);
+                       if (host->bus_ops->remove)
+                               host->bus_ops->remove(host);
+                       mmc_claim_host(host);
+                       mmc_detach_bus(host);
+                       mmc_release_host(host);
+                       /* no need to bother upper layers */
+                       err = 0;
+               }
        }
        mmc_bus_put(host);
 
@@ -1021,7 +1305,7 @@ int mmc_resume_host(struct mmc_host *host)
         */
        mmc_detect_change(host, 1);
 
-       return 0;
+       return err;
 }
 
 EXPORT_SYMBOL(mmc_resume_host);
index c819effa1032c5ccebf896dff58d78f6e7ca13d5..67ae6abc4230928242109df7f5ab2c773f2971a3 100644 (file)
 #define MMC_CMD_RETRIES        3
 
 struct mmc_bus_ops {
+       int (*awake)(struct mmc_host *);
+       int (*sleep)(struct mmc_host *);
        void (*remove)(struct mmc_host *);
        void (*detect)(struct mmc_host *);
-       void (*suspend)(struct mmc_host *);
-       void (*resume)(struct mmc_host *);
+       int (*suspend)(struct mmc_host *);
+       int (*resume)(struct mmc_host *);
+       void (*power_save)(struct mmc_host *);
+       void (*power_restore)(struct mmc_host *);
 };
 
 void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops);
index 5e945e64ead7cb64aaf2b1043d53c0d745d66219..a268d12f1af0d0276787642ff4728060a1ab2624 100644 (file)
@@ -83,6 +83,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
        spin_lock_init(&host->lock);
        init_waitqueue_head(&host->wq);
        INIT_DELAYED_WORK(&host->detect, mmc_rescan);
+       INIT_DELAYED_WORK_DEFERRABLE(&host->disable, mmc_host_deeper_disable);
 
        /*
         * By default, hosts do not support SGIO or large requests.
index c2dc3d2d9f9ace67075146ded5f56d0c6273cd8f..8c87e1109a34322c88a341394ae152800ad950b4 100644 (file)
@@ -14,5 +14,7 @@
 int mmc_register_host_class(void);
 void mmc_unregister_host_class(void);
 
+void mmc_host_deeper_disable(struct work_struct *work);
+
 #endif
 
index 2fb9d5f271ea4e2a3eabf4ebdd8dd65021a5025b..bfefce365ae788ea93d73382298c915fba72288e 100644 (file)
@@ -160,7 +160,6 @@ static int mmc_read_ext_csd(struct mmc_card *card)
 {
        int err;
        u8 *ext_csd;
-       unsigned int ext_csd_struct;
 
        BUG_ON(!card);
 
@@ -180,11 +179,11 @@ static int mmc_read_ext_csd(struct mmc_card *card)
 
        err = mmc_send_ext_csd(card, ext_csd);
        if (err) {
-               /*
-                * We all hosts that cannot perform the command
-                * to fail more gracefully
-                */
-               if (err != -EINVAL)
+               /* If the host or the card can't do the switch,
+                * fail more gracefully. */
+               if ((err != -EINVAL)
+                && (err != -ENOSYS)
+                && (err != -EFAULT))
                        goto out;
 
                /*
@@ -207,16 +206,16 @@ static int mmc_read_ext_csd(struct mmc_card *card)
                goto out;
        }
 
-       ext_csd_struct = ext_csd[EXT_CSD_REV];
-       if (ext_csd_struct > 3) {
+       card->ext_csd.rev = ext_csd[EXT_CSD_REV];
+       if (card->ext_csd.rev > 3) {
                printk(KERN_ERR "%s: unrecognised EXT_CSD structure "
                        "version %d\n", mmc_hostname(card->host),
-                       ext_csd_struct);
+                       card->ext_csd.rev);
                err = -EINVAL;
                goto out;
        }
 
-       if (ext_csd_struct >= 2) {
+       if (card->ext_csd.rev >= 2) {
                card->ext_csd.sectors =
                        ext_csd[EXT_CSD_SEC_CNT + 0] << 0 |
                        ext_csd[EXT_CSD_SEC_CNT + 1] << 8 |
@@ -241,6 +240,15 @@ static int mmc_read_ext_csd(struct mmc_card *card)
                goto out;
        }
 
+       if (card->ext_csd.rev >= 3) {
+               u8 sa_shift = ext_csd[EXT_CSD_S_A_TIMEOUT];
+
+               /* Sleep / awake timeout in 100ns units */
+               if (sa_shift > 0 && sa_shift <= 0x17)
+                       card->ext_csd.sa_timeout =
+                                       1 << ext_csd[EXT_CSD_S_A_TIMEOUT];
+       }
+
 out:
        kfree(ext_csd);
 
@@ -408,12 +416,17 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
                (host->caps & MMC_CAP_MMC_HIGHSPEED)) {
                err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                        EXT_CSD_HS_TIMING, 1);
-               if (err)
+               if (err && err != -EBADMSG)
                        goto free_card;
 
-               mmc_card_set_highspeed(card);
-
-               mmc_set_timing(card->host, MMC_TIMING_MMC_HS);
+               if (err) {
+                       printk(KERN_WARNING "%s: switch to highspeed failed\n",
+                              mmc_hostname(card->host));
+                       err = 0;
+               } else {
+                       mmc_card_set_highspeed(card);
+                       mmc_set_timing(card->host, MMC_TIMING_MMC_HS);
+               }
        }
 
        /*
@@ -448,10 +461,17 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
                err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                                 EXT_CSD_BUS_WIDTH, ext_csd_bit);
 
-               if (err)
+               if (err && err != -EBADMSG)
                        goto free_card;
 
-               mmc_set_bus_width(card->host, bus_width);
+               if (err) {
+                       printk(KERN_WARNING "%s: switch to bus width %d "
+                              "failed\n", mmc_hostname(card->host),
+                              1 << bus_width);
+                       err = 0;
+               } else {
+                       mmc_set_bus_width(card->host, bus_width);
+               }
        }
 
        if (!oldcard)
@@ -507,12 +527,10 @@ static void mmc_detect(struct mmc_host *host)
        }
 }
 
-#ifdef CONFIG_MMC_UNSAFE_RESUME
-
 /*
  * Suspend callback from host.
  */
-static void mmc_suspend(struct mmc_host *host)
+static int mmc_suspend(struct mmc_host *host)
 {
        BUG_ON(!host);
        BUG_ON(!host->card);
@@ -522,6 +540,8 @@ static void mmc_suspend(struct mmc_host *host)
                mmc_deselect_cards(host);
        host->card->state &= ~MMC_STATE_HIGHSPEED;
        mmc_release_host(host);
+
+       return 0;
 }
 
 /*
@@ -530,7 +550,7 @@ static void mmc_suspend(struct mmc_host *host)
  * This function tries to determine if the same card is still present
  * and, if so, restore all state to it.
  */
-static void mmc_resume(struct mmc_host *host)
+static int mmc_resume(struct mmc_host *host)
 {
        int err;
 
@@ -541,30 +561,99 @@ static void mmc_resume(struct mmc_host *host)
        err = mmc_init_card(host, host->ocr, host->card);
        mmc_release_host(host);
 
-       if (err) {
-               mmc_remove(host);
+       return err;
+}
 
-               mmc_claim_host(host);
-               mmc_detach_bus(host);
-               mmc_release_host(host);
+static void mmc_power_restore(struct mmc_host *host)
+{
+       host->card->state &= ~MMC_STATE_HIGHSPEED;
+       mmc_claim_host(host);
+       mmc_init_card(host, host->ocr, host->card);
+       mmc_release_host(host);
+}
+
+static int mmc_sleep(struct mmc_host *host)
+{
+       struct mmc_card *card = host->card;
+       int err = -ENOSYS;
+
+       if (card && card->ext_csd.rev >= 3) {
+               err = mmc_card_sleepawake(host, 1);
+               if (err < 0)
+                       pr_debug("%s: Error %d while putting card into sleep",
+